From b48503711c3cd8d190c7ab2d0fff163576fd4b85 Mon Sep 17 00:00:00 2001 From: David Poeschl Date: Wed, 29 Mar 2017 10:35:25 -0700 Subject: [PATCH] Port the rename integration tests --- .../IntegrationTests/CSharp/CSharpRename.cs | 447 ++++++++++++++++++ .../VisualBasic/BasicRename.cs | 195 ++++++++ .../VisualStudioIntegrationTests.csproj | 2 + .../TestUtilities/InProcess/Editor_InProc.cs | 21 + .../InProcess/SolutionExplorer_InProc.cs | 31 ++ .../OutOfProcess/Editor_OutOfProc.cs | 22 + .../InlineRenameDialog_OutOfProc.cs | 43 ++ .../SolutionExplorer_OutOfProc.cs | 3 + .../TestUtilities/VisualStudioInstance.cs | 3 + ...isualStudioIntegrationTestUtilities.csproj | 1 + 10 files changed, 768 insertions(+) create mode 100644 src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpRename.cs create mode 100644 src/VisualStudio/IntegrationTest/IntegrationTests/VisualBasic/BasicRename.cs create mode 100644 src/VisualStudio/IntegrationTest/TestUtilities/OutOfProcess/InlineRenameDialog_OutOfProc.cs diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpRename.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpRename.cs new file mode 100644 index 00000000000..ba4a327b831 --- /dev/null +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/CSharp/CSharpRename.cs @@ -0,0 +1,447 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Immutable; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Shared.TestHooks; +using Microsoft.CodeAnalysis.Text; +using Microsoft.VisualStudio.IntegrationTest.Utilities; +using Microsoft.VisualStudio.IntegrationTest.Utilities.Input; +using Microsoft.VisualStudio.IntegrationTest.Utilities.OutOfProcess; +using Roslyn.Test.Utilities; +using Roslyn.VisualStudio.IntegrationTests.Extensions; +using Roslyn.VisualStudio.IntegrationTests.Extensions.Editor; +using Xunit; + +namespace Roslyn.VisualStudio.IntegrationTests.CSharp +{ + [Collection(nameof(SharedIntegrationHostFixture))] + public class CSharpRename : AbstractEditorTest + { + protected override string LanguageName => LanguageNames.CSharp; + + private InlineRenameDialog_OutOfProc InlineRenameDialog => VisualStudio.Instance.InlineRenameDialog; + + public CSharpRename(VisualStudioInstanceFactory instanceFactory) + : base(instanceFactory, nameof(CSharpRename)) + { + } + + [Fact, Trait(Traits.Feature, Traits.Features.Rename)] + public void VerifyLocalVariableRename() + { + var markup = @" +using System; +using System.Collections.Generic; +using System.Linq; + +class Program +{ + static void Main(string[] args) + { + int [|x|]$$ = 0; + [|x|] = 5; + TestMethod([|x|]); + } + + static void TestMethod(int y) + { + + } +}"; + SetUpEditor(markup); + InlineRenameDialog.Invoke(); + + MarkupTestFile.GetSpans(markup, out var _, out ImmutableArray renameSpans); + var tags = Editor.GetTagSpans(InlineRenameDialog.ValidRenameTag); + AssertEx.SetEqual(renameSpans, tags); + + Editor.SendKeys(VirtualKey.Y, VirtualKey.Enter); + this.VerifyTextContains(@" +using System; +using System.Collections.Generic; +using System.Linq; + +class Program +{ + static void Main(string[] args) + { + int y = 0; + y = 5; + TestMethod(y); + } + + static void TestMethod(int y) + { + + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.Rename)] + public void VerifyLocalVariableRenameWithCommentsUpdated() + { + // "variable" is intentionally misspelled as "varixable" and "this" is misspelled as + // "thix" below to ensure we don't change instances of "x" in comments that are part of + // larger words + var markup = @" +using System; +using System.Collections.Generic; +using System.Linq; + +class Program +{ + /// + /// creates a varixable named [|x|] xx + /// + /// + static void Main(string[] args) + { + // thix varixable is named [|x|] xx + int [|x|]$$ = 0; + [|x|] = 5; + TestMethod([|x|]); + } + + static void TestMethod(int y) + { + /* + * [|x|] + * xx + */ + } +}"; + SetUpEditor(markup); + InlineRenameDialog.Invoke(); + InlineRenameDialog.ToggleIncludeComments(); + + MarkupTestFile.GetSpans(markup, out var _, out ImmutableArray renameSpans); + var tags = Editor.GetTagSpans(InlineRenameDialog.ValidRenameTag); + AssertEx.SetEqual(renameSpans, tags); + + Editor.SendKeys(VirtualKey.Y, VirtualKey.Enter); + this.VerifyTextContains(@" +using System; +using System.Collections.Generic; +using System.Linq; + +class Program +{ + /// + /// creates a varixable named y xx + /// + /// + static void Main(string[] args) + { + // thix varixable is named y xx + int y = 0; + y = 5; + TestMethod(y); + } + + static void TestMethod(int y) + { + /* + * y + * xx + */ + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.Rename)] + public void VerifyLocalVariableRenameWithStringsUpdated() + { + var markup = @" +class Program +{ + static void Main(string[] args) + { + int [|x|]$$ = 0; + [|x|] = 5; + var s = ""[|x|] xx [|x|]""; + var sLiteral = + @"" + [|x|] + xx + [|x|] + ""; + char c = 'x'; + char cUnit = '\u0078'; + } +}"; + SetUpEditor(markup); + + InlineRenameDialog.Invoke(); + InlineRenameDialog.ToggleIncludeStrings(); + + MarkupTestFile.GetSpans(markup, out var _, out ImmutableArray renameSpans); + var tags = Editor.GetTagSpans(InlineRenameDialog.ValidRenameTag); + AssertEx.SetEqual(renameSpans, tags); + + Editor.SendKeys(VirtualKey.Y, VirtualKey.Enter); + this.VerifyTextContains(@" +class Program +{ + static void Main(string[] args) + { + int y = 0; + y = 5; + var s = ""y xx y""; + var sLiteral = + @"" + y + xx + y + ""; + char c = 'x'; + char cUnit = '\u0078'; + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.Rename)] + public void VerifyOverloadsUpdated() + { + var markup = @" +interface I +{ + void [|TestMethod|]$$(int y); + void [|TestMethod|](string y); +} + +class B : I +{ + public virtual void [|TestMethod|](int y) + { } + + public virtual void [|TestMethod|](string y) + { } +}"; + SetUpEditor(markup); + + InlineRenameDialog.Invoke(); + InlineRenameDialog.ToggleIncludeOverloads(); + + MarkupTestFile.GetSpans(markup, out var _, out ImmutableArray renameSpans); + var tags = Editor.GetTagSpans(InlineRenameDialog.ValidRenameTag); + AssertEx.SetEqual(renameSpans, tags); + + Editor.SendKeys(VirtualKey.Y, VirtualKey.Enter); + this.VerifyTextContains(@" +interface I +{ + void y(int y); + void y(string y); +} + +class B : I +{ + public virtual void y(int y) + { } + + public virtual void y(string y) + { } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.Rename)] + public void VerifyMultiFileRename() + { + SetUpEditor(@" +class $$Program +{ +}"); + + VisualStudio.Instance.SolutionExplorer.AddFile(ProjectName, "Class2.cs", @""); + VisualStudio.Instance.SolutionExplorer.OpenFile(ProjectName, "Class2.cs"); + + const string class2Markup = @" +class SomeOtherClass +{ + void M() + { + [|Program|] p = new [|Program|](); + } +}"; + MarkupTestFile.GetSpans(class2Markup, out var code, out ImmutableArray renameSpans); + + Editor.SetText(code); + this.PlaceCaret("Program"); + + InlineRenameDialog.Invoke(); + + var tags = Editor.GetTagSpans(InlineRenameDialog.ValidRenameTag); + AssertEx.SetEqual(renameSpans, tags); + + Editor.SendKeys(VirtualKey.Y, VirtualKey.Enter); + this.VerifyTextContains(@" +class SomeOtherClass +{ + void M() + { + y p = new y(); + } +}"); + + VisualStudio.Instance.SolutionExplorer.OpenFile(ProjectName, "Class1.cs"); + this.VerifyTextContains(@" +class y +{ +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.Rename)] + public void VerifyRenameCancellation() + { + SetUpEditor(@" +class $$Program +{ +}"); + + VisualStudio.Instance.SolutionExplorer.AddFile(ProjectName, "Class2.cs", @""); + VisualStudio.Instance.SolutionExplorer.OpenFile(ProjectName, "Class2.cs"); + Editor.SetText(@" +class SomeOtherClass +{ + void M() + { + Program p = new Program(); + } +}"); + this.PlaceCaret("Program"); + + InlineRenameDialog.Invoke(); + + Editor.SendKeys(VirtualKey.Y); + this.VerifyTextContains(@"class SomeOtherClass +{ + void M() + { + y p = new y(); + } +}"); + + VisualStudio.Instance.SolutionExplorer.OpenFile(ProjectName, "Class1.cs"); + this.VerifyTextContains(@" +class y +{ +}"); + + Editor.SendKeys(VirtualKey.Escape); + this.WaitForAsyncOperations(FeatureAttribute.Rename); + + this.VerifyTextContains(@" +class Program +{ +}"); + + VisualStudio.Instance.SolutionExplorer.OpenFile(ProjectName, "Class2.cs"); + this.VerifyTextContains(@" +class SomeOtherClass +{ + void M() + { + Program p = new Program(); + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.Rename)] + public void VerifyCrossProjectRename() + { + SetUpEditor(@" +$$class RenameRocks +{ + static void Main(string[] args) + { + Class2 c = null; + c.ToString(); + } +}"); + + VisualStudio.Instance.SolutionExplorer.AddProject("Project2", WellKnownProjectTemplates.ClassLibrary, LanguageName); + VisualStudio.Instance.SolutionExplorer.AddProjectReference(fromProjectName: ProjectName, toProjectName: "Project2"); + + VisualStudio.Instance.SolutionExplorer.AddFile("Project2", "Class2.cs", @""); + VisualStudio.Instance.SolutionExplorer.OpenFile("Project2", "Class2.cs"); + + + Editor.SetText(@" +public class Class2 { static void Main(string [] args) { } }"); + + VisualStudio.Instance.SolutionExplorer.OpenFile(ProjectName, "Class1.cs"); + this.PlaceCaret("Class2"); + + InlineRenameDialog.Invoke(); + Editor.SendKeys(VirtualKey.Y, VirtualKey.Enter); + + this.VerifyTextContains(@" +class RenameRocks +{ + static void Main(string[] args) + { + y c = null; + c.ToString(); + } +}"); + + VisualStudio.Instance.SolutionExplorer.OpenFile("Project2", "Class2.cs"); + this.VerifyTextContains(@" +public class y { static void Main(string [] args) { } }"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.Rename)] + public void VerifyRenameUndo() + { + VerifyCrossProjectRename(); + + Editor.SendKeys(Ctrl(VirtualKey.Z)); + + this.VerifyTextContains(@" +public class Class2 { static void Main(string [] args) { } }"); + + VisualStudio.Instance.SolutionExplorer.OpenFile(ProjectName, "Class1.cs"); + this.VerifyTextContains(@" +class RenameRocks +{ + static void Main(string[] args) + { + Class2 c = null; + c.ToString(); + } +}"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.Rename)] + public void VerifyRenameInStandaloneFiles() + { + VisualStudio.Instance.SolutionExplorer.CloseSolution(); + VisualStudio.Instance.SolutionExplorer.AddStandaloneFile("StandaloneFile1.cs"); + Editor.SetText(@" +class Program +{ + void Foo() + { + var ids = 1; + ids = 2; + } +}"); + this.PlaceCaret("ids"); + + InlineRenameDialog.Invoke(); + + Editor.SendKeys(VirtualKey.Y, VirtualKey.Enter); + + this.VerifyTextContains(@" +class Program +{ + void Foo() + { + var y = 1; + y = 2; + } +}"); + } + } +} diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/VisualBasic/BasicRename.cs b/src/VisualStudio/IntegrationTest/IntegrationTests/VisualBasic/BasicRename.cs new file mode 100644 index 00000000000..9de7e34b875 --- /dev/null +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/VisualBasic/BasicRename.cs @@ -0,0 +1,195 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Immutable; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Text; +using Microsoft.VisualStudio.IntegrationTest.Utilities; +using Microsoft.VisualStudio.IntegrationTest.Utilities.Input; +using Microsoft.VisualStudio.IntegrationTest.Utilities.OutOfProcess; +using Roslyn.Test.Utilities; +using Roslyn.VisualStudio.IntegrationTests.Extensions.Editor; +using Xunit; + +namespace Roslyn.VisualStudio.IntegrationTests.VisualBasic +{ + [Collection(nameof(SharedIntegrationHostFixture))] + public class BasicRename : AbstractEditorTest + { + protected override string LanguageName => LanguageNames.VisualBasic; + + private InlineRenameDialog_OutOfProc InlineRenameDialog => VisualStudio.Instance.InlineRenameDialog; + + public BasicRename(VisualStudioInstanceFactory instanceFactory) + : base(instanceFactory, nameof(BasicRename)) + { + } + + [Fact, Trait(Traits.Feature, Traits.Features.Rename)] + public void VerifyLocalVariableRename() + { + var markup = @" +Imports System +Imports System.Collections.Generic +Imports System.Linq + +Module Program + Sub Main(args As String()) + Dim [|x|]$$ As Integer = 0 + [|x|] = 5 + TestMethod([|x|]) + End Sub + Sub TestMethod(y As Integer) + + End Sub +End Module"; + SetUpEditor(markup); + InlineRenameDialog.Invoke(); + + MarkupTestFile.GetSpans(markup, out var _, out ImmutableArray renameSpans); + var tags = Editor.GetTagSpans(InlineRenameDialog.ValidRenameTag); + AssertEx.SetEqual(renameSpans, tags); + + Editor.SendKeys(VirtualKey.Y, VirtualKey.Enter); + this.VerifyTextContains(@" +Imports System +Imports System.Collections.Generic +Imports System.Linq + +Module Program + Sub Main(args As String()) + Dim y As Integer = 0 + y = 5 + TestMethod(y) + End Sub + Sub TestMethod(y As Integer) + + End Sub +End Module"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.Rename)] + public void VerifyLocalVariableRenameWithCommentsUpdated() + { + // "variable" is intentionally misspelled as "varixable" and "this" is misspelled as + // "thix" below to ensure we don't change instances of "x" in comments that are part of + // larger words + var markup = @" +Imports System +Imports System.Collections.Generic +Imports System.Linq + +Module Program + ''' + ''' creates a varixable named [|x|] xx + ''' + ''' + Sub Main(args As String()) + ' thix varixable is named [|x|] xx + Dim [|x|]$$ As Integer = 0 + [|x|] = 5 + TestMethod([|x|]) +End Module"; + SetUpEditor(markup); + InlineRenameDialog.Invoke(); + InlineRenameDialog.ToggleIncludeComments(); + + MarkupTestFile.GetSpans(markup, out var _, out ImmutableArray renameSpans); + var tags = Editor.GetTagSpans(InlineRenameDialog.ValidRenameTag); + AssertEx.SetEqual(renameSpans, tags); + + Editor.SendKeys(VirtualKey.Y, VirtualKey.Enter); + this.VerifyTextContains(@" +Imports System +Imports System.Collections.Generic +Imports System.Linq + +Module Program + ''' + ''' creates a varixable named y xx + ''' + ''' + Sub Main(args As String()) + ' thix varixable is named y xx + Dim y As Integer = 0 + y = 5 + TestMethod(y) +End Module"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.Rename)] + public void VerifyLocalVariableRenameWithStringsUpdated() + { + var markup = @" +Imports System +Imports System.Collections.Generic +Imports System.Linq + +Module Program + Sub Main(args As String()) + Dim [|x|]$$ As Integer = 0 + [|x|] = 5 + Dim s = ""[|x|] xx [|x|]"" + End Sub +End Module"; + SetUpEditor(markup); + + InlineRenameDialog.Invoke(); + InlineRenameDialog.ToggleIncludeStrings(); + + MarkupTestFile.GetSpans(markup, out var _, out ImmutableArray renameSpans); + var tags = Editor.GetTagSpans(InlineRenameDialog.ValidRenameTag); + AssertEx.SetEqual(renameSpans, tags); + + Editor.SendKeys(VirtualKey.Y, VirtualKey.Enter); + this.VerifyTextContains(@" +Imports System +Imports System.Collections.Generic +Imports System.Linq + +Module Program + Sub Main(args As String()) + Dim y As Integer = 0 + y = 5 + Dim s = ""y xx y"" + End Sub +End Module"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.Rename)] + public void VerifyOverloadsUpdated() + { + var markup = @" +Interface I + Sub [|TestMethod|]$$(y As Integer) + Sub [|TestMethod|](y As String) +End Interface + +Public MustInherit Class A + Implements I + Public MustOverride Sub [|TestMethod|](y As Integer) Implements I.[|TestMethod|] + Public MustOverride Sub [|TestMethod|](y As String) Implements I.[|TestMethod|] +End Class"; + SetUpEditor(markup); + + InlineRenameDialog.Invoke(); + InlineRenameDialog.ToggleIncludeOverloads(); + + MarkupTestFile.GetSpans(markup, out var _, out ImmutableArray renameSpans); + var tags = Editor.GetTagSpans(InlineRenameDialog.ValidRenameTag); + AssertEx.SetEqual(renameSpans, tags); + + Editor.SendKeys(VirtualKey.Y, VirtualKey.Enter); + this.VerifyTextContains(@" +Interface I + Sub y(y As Integer) + Sub y(y As String) +End Interface + +Public MustInherit Class A + Implements I + Public MustOverride Sub y(y As Integer) Implements I.y + Public MustOverride Sub y(y As String) Implements I.y +End Class"); + } + } +} diff --git a/src/VisualStudio/IntegrationTest/IntegrationTests/VisualStudioIntegrationTests.csproj b/src/VisualStudio/IntegrationTest/IntegrationTests/VisualStudioIntegrationTests.csproj index 2a931ea49a7..f15580f3f7b 100644 --- a/src/VisualStudio/IntegrationTest/IntegrationTests/VisualStudioIntegrationTests.csproj +++ b/src/VisualStudio/IntegrationTest/IntegrationTests/VisualStudioIntegrationTests.csproj @@ -53,6 +53,7 @@ + @@ -92,6 +93,7 @@ + diff --git a/src/VisualStudio/IntegrationTest/TestUtilities/InProcess/Editor_InProc.cs b/src/VisualStudio/IntegrationTest/TestUtilities/InProcess/Editor_InProc.cs index a97ecb65c0d..60e0a637070 100644 --- a/src/VisualStudio/IntegrationTest/TestUtilities/InProcess/Editor_InProc.cs +++ b/src/VisualStudio/IntegrationTest/TestUtilities/InProcess/Editor_InProc.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.ComponentModel; using System.ComponentModel.Design; using System.Linq; @@ -11,11 +12,13 @@ using System.Windows.Forms; using Microsoft.CodeAnalysis.Editor.Implementation.Highlighting; using Microsoft.CodeAnalysis.Editor.Shared.Extensions; +using Microsoft.CodeAnalysis.Text; using Microsoft.VisualStudio.IntegrationTest.Utilities.Common; using Microsoft.VisualStudio.Language.Intellisense; using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Text; using Microsoft.VisualStudio.Text.Editor; +using Microsoft.VisualStudio.Text.Operations; using Microsoft.VisualStudio.Text.Tagging; using Microsoft.VisualStudio.TextManager.Interop; @@ -537,5 +540,23 @@ public void GoToDefinition() public void GoToImplementation() => GetDTE().ExecuteCommand("Edit.GoToImplementation"); + + /// + /// Gets the spans where a particular tag appears in the active text view. + /// + /// + /// Given a list of tag spans [s1, s2, ...], returns a decomposed array for serialization: + /// [s1.Start, s1.Length, s2.Start, s2.Length, ...] + /// + public int[] GetTagSpans(string tagId) + => InvokeOnUIThread(() => + { + var view = GetActiveTextView(); + var tagAggregatorFactory = GetComponentModel().GetService(); + var tagAggregator = tagAggregatorFactory.CreateTagAggregator(view); + var matchingTags = tagAggregator.GetTags(new SnapshotSpan(view.TextSnapshot, 0, view.TextSnapshot.Length)).Where(t => t.Tag.Type == tagId); + + return matchingTags.Select(t => t.Span.GetSpans(view.TextBuffer).Single().Span.ToTextSpan()).SelectMany(t => new List { t.Start, t.Length }).ToArray(); + }); } } diff --git a/src/VisualStudio/IntegrationTest/TestUtilities/InProcess/SolutionExplorer_InProc.cs b/src/VisualStudio/IntegrationTest/TestUtilities/InProcess/SolutionExplorer_InProc.cs index f652a526913..5a69cc40cb0 100644 --- a/src/VisualStudio/IntegrationTest/TestUtilities/InProcess/SolutionExplorer_InProc.cs +++ b/src/VisualStudio/IntegrationTest/TestUtilities/InProcess/SolutionExplorer_InProc.cs @@ -414,6 +414,37 @@ public void AddFile(string projectName, string fileName, string contents = null, } } + /// + /// Adds a new standalone file to the Miscellaneous Files workspace. + /// + /// The name of the file to add. + public void AddStandaloneFile(string fileName) + { + string itemTemplate; + + var extension = Path.GetExtension(fileName).ToLowerInvariant(); + switch (extension) + { + case ".cs": + itemTemplate = @"General\Visual C# Class"; + break; + case ".csx": + itemTemplate = @"Script\Visual C# Script"; + break; + case ".vb": + itemTemplate = @"General\Visual Basic Class"; + break; + case ".txt": + itemTemplate = @"General\Text File"; + break; + default: + throw new NotSupportedException($"File type '{extension}' is not yet supported."); + } + + GetDTE().ItemOperations.NewFile(itemTemplate, fileName); + } + + public void SetFileContents(string projectName, string relativeFilePath, string contents) { var project = GetProject(projectName); diff --git a/src/VisualStudio/IntegrationTest/TestUtilities/OutOfProcess/Editor_OutOfProc.cs b/src/VisualStudio/IntegrationTest/TestUtilities/OutOfProcess/Editor_OutOfProc.cs index 51b9d859b2c..17aecd5c315 100644 --- a/src/VisualStudio/IntegrationTest/TestUtilities/OutOfProcess/Editor_OutOfProc.cs +++ b/src/VisualStudio/IntegrationTest/TestUtilities/OutOfProcess/Editor_OutOfProc.cs @@ -5,6 +5,10 @@ using System.Windows.Automation; using System.Collections.Generic; using Microsoft.CodeAnalysis.Shared.TestHooks; +using System.Collections.Immutable; +using System.Linq; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Text; using Microsoft.VisualStudio.IntegrationTest.Utilities.Common; using Microsoft.VisualStudio.IntegrationTest.Utilities.InProcess; @@ -58,6 +62,24 @@ public string GetLineTextAfterCaret() public void MoveCaret(int position) => _editorInProc.MoveCaret(position); + public ImmutableArray GetTagSpans(string tagId) + { + var tagInfo = _editorInProc.GetTagSpans(tagId).ToList(); + + // The spans are returned in an array: + // [s1.Start, s1.Length, s2.Start, s2.Length, ...] + // Reconstruct the spans from their component parts + + var builder = ArrayBuilder.GetInstance(); + + for (int i = 0; i < tagInfo.Count; i += 2) + { + builder.Add(new TextSpan(tagInfo[i], tagInfo[i + 1])); + } + + return builder.ToImmutableAndFree(); + } + public string GetCurrentCompletionItem() { WaitForCompletionSet(); diff --git a/src/VisualStudio/IntegrationTest/TestUtilities/OutOfProcess/InlineRenameDialog_OutOfProc.cs b/src/VisualStudio/IntegrationTest/TestUtilities/OutOfProcess/InlineRenameDialog_OutOfProc.cs new file mode 100644 index 00000000000..300b4707a0f --- /dev/null +++ b/src/VisualStudio/IntegrationTest/TestUtilities/OutOfProcess/InlineRenameDialog_OutOfProc.cs @@ -0,0 +1,43 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.CodeAnalysis.Shared.TestHooks; +using Microsoft.VisualStudio.IntegrationTest.Utilities.Input; + +namespace Microsoft.VisualStudio.IntegrationTest.Utilities.OutOfProcess +{ + public class InlineRenameDialog_OutOfProc : OutOfProcComponent + { + private const string ChangeSignatureDialogAutomationId = "InlineRenameDialog"; + + public string ValidRenameTag => "RoslynRenameValidTag"; + + public InlineRenameDialog_OutOfProc(VisualStudioInstance visualStudioInstance) + : base(visualStudioInstance) + { + } + + public void Invoke() + { + VisualStudioInstance.ExecuteCommand("Refactor.Rename"); + VisualStudioInstance.VisualStudioWorkspace.WaitForAsyncOperations(FeatureAttribute.Rename); + } + + public void ToggleIncludeComments() + { + VisualStudioInstance.Editor.SendKeys(new KeyPress(VirtualKey.C, ShiftState.Alt)); + VisualStudioInstance.VisualStudioWorkspace.WaitForAsyncOperations(FeatureAttribute.Rename); + } + + public void ToggleIncludeStrings() + { + VisualStudioInstance.Editor.SendKeys(new KeyPress(VirtualKey.S, ShiftState.Alt)); + VisualStudioInstance.VisualStudioWorkspace.WaitForAsyncOperations(FeatureAttribute.Rename); + } + + public void ToggleIncludeOverloads() + { + VisualStudioInstance.Editor.SendKeys(new KeyPress(VirtualKey.O, ShiftState.Alt)); + VisualStudioInstance.VisualStudioWorkspace.WaitForAsyncOperations(FeatureAttribute.Rename); + } + } +} diff --git a/src/VisualStudio/IntegrationTest/TestUtilities/OutOfProcess/SolutionExplorer_OutOfProc.cs b/src/VisualStudio/IntegrationTest/TestUtilities/OutOfProcess/SolutionExplorer_OutOfProc.cs index d4c0e3825ec..e3e29623b9f 100644 --- a/src/VisualStudio/IntegrationTest/TestUtilities/OutOfProcess/SolutionExplorer_OutOfProc.cs +++ b/src/VisualStudio/IntegrationTest/TestUtilities/OutOfProcess/SolutionExplorer_OutOfProc.cs @@ -128,5 +128,8 @@ public void WaitForBuildToFinish() public void EditProjectFile(ProjectUtils.Project project) => _inProc.EditProjectFile(project.Name); + + public void AddStandaloneFile(string fileName) + => _inProc.AddStandaloneFile(fileName); } } \ No newline at end of file diff --git a/src/VisualStudio/IntegrationTest/TestUtilities/VisualStudioInstance.cs b/src/VisualStudio/IntegrationTest/TestUtilities/VisualStudioInstance.cs index 7624dc665b2..d9ded8843a8 100644 --- a/src/VisualStudio/IntegrationTest/TestUtilities/VisualStudioInstance.cs +++ b/src/VisualStudio/IntegrationTest/TestUtilities/VisualStudioInstance.cs @@ -35,6 +35,8 @@ public class VisualStudioInstance public GenerateTypeDialog_OutOfProc GenerateTypeDialog { get; } + public InlineRenameDialog_OutOfProc InlineRenameDialog { get; set; } + public PreviewChangesDialog_OutOfProc PreviewChangesDialog { get; } public SendKeys SendKeys { get; } @@ -92,6 +94,7 @@ public VisualStudioInstance(Process hostProcess, DTE dte, ImmutableHashSet + -- GitLab