diff --git a/src/EditorFeatures/CSharpTest/CSharpEditorServicesTest.csproj b/src/EditorFeatures/CSharpTest/CSharpEditorServicesTest.csproj index 8ecca19b3b28fb2aefb978a6c3db2b39b77859dc..c94e0912cdfce1f6017e4d2069a02f1c5bae644b 100644 --- a/src/EditorFeatures/CSharpTest/CSharpEditorServicesTest.csproj +++ b/src/EditorFeatures/CSharpTest/CSharpEditorServicesTest.csproj @@ -338,6 +338,8 @@ + + diff --git a/src/EditorFeatures/CSharpTest/PopulateSwitch/PopulateSwitchTests.cs b/src/EditorFeatures/CSharpTest/PopulateSwitch/PopulateSwitchTests.cs new file mode 100644 index 0000000000000000000000000000000000000000..d5f5b0959bbd6afc939ee3fec557e2a850225d89 --- /dev/null +++ b/src/EditorFeatures/CSharpTest/PopulateSwitch/PopulateSwitchTests.cs @@ -0,0 +1,934 @@ +using System; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.PopulateSwitch; +using Roslyn.Test.Utilities; +using Xunit; + +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.PopulateSwitch +{ + public partial class PopulateSwitchTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest + { + internal override Tuple CreateDiagnosticProviderAndFixer(Workspace workspace) + { + return new Tuple( + new PopulateSwitchDiagnosticAnalyzer(), new PopulateSwitchCodeFixProvider()); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] + public async Task AllMembersAndDefaultExist() + { + await TestMissingAsync( + @" +namespace ConsoleApplication1 +{ + enum MyEnum + { + Fizz, Buzz, FizzBuzz + } + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + switch ([|e|]) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + default: + break; + } + } + } +} +"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] + public async Task AllMembersExist_NotDefault() + { + await TestAsync( + @" +namespace ConsoleApplication1 +{ + enum MyEnum + { + Fizz, Buzz, FizzBuzz + } + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + switch ([|e|]) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; + } + } + } +} +", + @" +namespace ConsoleApplication1 +{ + enum MyEnum + { + Fizz, Buzz, FizzBuzz + } + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + switch (e) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; + default: + break; + } + } + } +} +"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] + public async Task NotAllMembersExist_NotDefault() + { + await TestAsync( + @" +namespace ConsoleApplication1 +{ + enum MyEnum + { + Fizz, Buzz, FizzBuzz + } + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + switch ([|e|]) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + break; + } + } + } +} +", + @" +namespace ConsoleApplication1 +{ + enum MyEnum + { + Fizz, Buzz, FizzBuzz + } + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + switch (e) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + break; + case MyEnum.FizzBuzz: + break; + default: + break; + } + } + } +} +", index: 2); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] + public async Task NotAllMembersExist_WithDefault() + { + await TestAsync( + @" +namespace ConsoleApplication1 +{ + enum MyEnum + { + Fizz, Buzz, FizzBuzz + } + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + switch ([|e|]) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + break; + default: + break; + } + } + } +} +", + @" +namespace ConsoleApplication1 +{ + enum MyEnum + { + Fizz, Buzz, FizzBuzz + } + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + switch (e) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + break; + case MyEnum.FizzBuzz: + break; + default: + break; + } + } + } +} +"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] + public async Task NotAllMembersExist_NotDefault_EnumHasExplicitType() + { + await TestAsync( + @" +namespace ConsoleApplication1 +{ + enum MyEnum : long + { + Fizz, Buzz, FizzBuzz + } + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + switch ([|e|]) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + break; + } + } + } +} +", + @" +namespace ConsoleApplication1 +{ + enum MyEnum : long + { + Fizz, Buzz, FizzBuzz + } + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + switch (e) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + break; + case MyEnum.FizzBuzz: + break; + default: + break; + } + } + } +} +", index: 2); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] + public async Task NotAllMembersExist_WithMembersAndDefaultInSection_NewValuesAboveDefaultSection() + { + await TestAsync( + @" +namespace ConsoleApplication1 +{ + enum MyEnum + { + Fizz, Buzz, FizzBuzz + } + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + switch ([|e|]) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + default: + break; + } + } + } +} +", + @" +namespace ConsoleApplication1 +{ + enum MyEnum + { + Fizz, Buzz, FizzBuzz + } + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + switch (e) + { + case MyEnum.FizzBuzz: + break; + case MyEnum.Fizz: + case MyEnum.Buzz: + default: + break; + } + } + } +} +"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] + public async Task NotAllMembersExist_WithMembersAndDefaultInSection_AssumesDefaultIsInLastSection() + { + await TestAsync( + @" +namespace ConsoleApplication1 +{ + enum MyEnum + { + Fizz, Buzz, FizzBuzz + } + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + switch ([|e|]) + { + default: + break; + case MyEnum.Fizz: + case MyEnum.Buzz: + break; + } + } + } +} +", + @" +namespace ConsoleApplication1 +{ + enum MyEnum + { + Fizz, Buzz, FizzBuzz + } + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + switch (e) + { + default: + break; + case MyEnum.Fizz: + case MyEnum.Buzz: + break; + case MyEnum.FizzBuzz: + break; + } + } + } +} +"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] + public async Task NoMembersExist0() + { + await TestAsync( + @" +namespace ConsoleApplication1 +{ + enum MyEnum + { + Fizz, Buzz, FizzBuzz + } + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + switch ([|e|]) + { + } + } + } +} +", + @" +namespace ConsoleApplication1 +{ + enum MyEnum + { + Fizz, Buzz, FizzBuzz + } + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + switch (e) + { + case MyEnum.Fizz: + break; + case MyEnum.Buzz: + break; + case MyEnum.FizzBuzz: + break; + } + } + } +} +", index: 0); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] + public async Task NoMembersExist1() + { + await TestAsync( + @" +namespace ConsoleApplication1 +{ + enum MyEnum + { + Fizz, Buzz, FizzBuzz + } + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + switch ([|e|]) + { + } + } + } +} +", + @" +namespace ConsoleApplication1 +{ + enum MyEnum + { + Fizz, Buzz, FizzBuzz + } + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + switch (e) + { + default: + break; + } + } + } +} +", index: 1); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] + public async Task NoMembersExist2() + { + await TestAsync( + @" +namespace ConsoleApplication1 +{ + enum MyEnum + { + Fizz, Buzz, FizzBuzz + } + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + switch ([|e|]) + { + } + } + } +} +", + @" +namespace ConsoleApplication1 +{ + enum MyEnum + { + Fizz, Buzz, FizzBuzz + } + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + switch (e) + { + case MyEnum.Fizz: + break; + case MyEnum.Buzz: + break; + case MyEnum.FizzBuzz: + break; + default: + break; + } + } + } +} +", index: 2); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] + public async Task UsingStaticEnum_AllMembersExist() + { + await TestMissingAsync( + @" +using static System.IO.FileMode; +namespace ConsoleApplication1 +{ + class MyClass + { + void Method() + { + var e = Append; + switch ([|e|]) + { + case CreateNew: + break; + case Create: + break; + case Open: + break; + case OpenOrCreate: + break; + case Truncate: + break; + case Append: + break; + default: + break; + } + } + } +} +"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] + public async Task UsingStaticEnum_AllMembersExist_OutOfDefaultOrder() + { + await TestMissingAsync( + @" +using static System.IO.FileMode; +namespace ConsoleApplication1 +{ + class MyClass + { + void Method() + { + var e = Append; + switch ([|e|]) + { + case CreateNew: + break; + case OpenOrCreate: + break; + case Truncate: + break; + case Open: + break; + case Append: + break; + case Create: + break; + default: + break; + } + } + } +} +"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] + public async Task UsingStaticEnum_MembersExist() + { + await TestAsync( + @" +using static System.IO.FileMode; +namespace ConsoleApplication1 +{ + class MyClass + { + void Method() + { + var e = Append; + switch ([|e|]) + { + case CreateNew: + break; + case Create: + break; + case Open: + break; + case OpenOrCreate: + break; + default: + break; + } + } + } +} +", + @" +using static System.IO.FileMode; +namespace ConsoleApplication1 +{ + class MyClass + { + void Method() + { + var e = Append; + switch (e) + { + case CreateNew: + break; + case Create: + break; + case Open: + break; + case OpenOrCreate: + break; + case Truncate: + break; + case Append: + break; + default: + break; + } + } + } +} +"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] + public async Task UsingStaticEnum_NoMembersExist() + { + await TestAsync( + @" +using static System.IO.FileMode; +namespace ConsoleApplication1 +{ + class MyClass + { + void Method() + { + var e = Append; + switch ([|e|]) + { + } + } + } +} +", + @" +using static System.IO.FileMode; +namespace ConsoleApplication1 +{ + class MyClass + { + void Method() + { + var e = Append; + switch (e) + { + case CreateNew: + break; + case Create: + break; + case Open: + break; + case OpenOrCreate: + break; + case Truncate: + break; + case Append: + break; + default: + break; + } + } + } +} +", index: 2); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] + public async Task NotAllMembersExist_NotDefault_EnumHasNonFlagsAttribute() + { + await TestAsync( + @" +namespace ConsoleApplication1 +{ + [System.Obsolete] + enum MyEnum + { + Fizz, Buzz, FizzBuzz + } + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + switch ([|e|]) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + break; + } + } + } +} +", + @" +namespace ConsoleApplication1 +{ + [System.Obsolete] + enum MyEnum + { + Fizz, Buzz, FizzBuzz + } + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + switch (e) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + break; + case MyEnum.FizzBuzz: + break; + default: + break; + } + } + } +} +", index: 2); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] + public async Task NotAllMembersExist_NotDefault_EnumIsNested() + { + await TestAsync( + @" +namespace ConsoleApplication1 +{ + class MyClass + { + enum MyEnum + { + Fizz, Buzz, FizzBuzz + } + + void Method() + { + var e = MyEnum.Fizz; + switch ([|e|]) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + break; + } + } + } +} +", + @" +namespace ConsoleApplication1 +{ + class MyClass + { + enum MyEnum + { + Fizz, Buzz, FizzBuzz + } + + void Method() + { + var e = MyEnum.Fizz; + switch (e) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + break; + case MyEnum.FizzBuzz: + break; + default: + break; + } + } + } +} +", index: 2); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] + public async Task NotAllMembersExist_SwitchIsNotEnum() + { + await TestMissingAsync( + @" +using System; +namespace ConsoleApplication1 +{ + class MyClass + { + void Method() + { + var e = ""test""; + switch ([|e|]) + { + case ""test1"": + case ""test1"": + default: + break; + } + } + } +} +"); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] + public async Task NotAllMembersExist_NotDefault_UsingConstants() + { + await TestAsync( + @" + enum MyEnum + { + Fizz, Buzz, FizzBuzz + } + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + switch ([|e|]) + { + case (MyEnum)0: + case (MyEnum)1: + break; + } + } + } +", + @" + enum MyEnum + { + Fizz, Buzz, FizzBuzz + } + class MyClass + { + void Method() + { + var e = MyEnum.Fizz; + switch (e) + { + case (MyEnum)0: + case (MyEnum)1: + break; + case MyEnum.FizzBuzz: + break; + default: + break; + } + } + } +", index: 2); + } + + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] + public async Task AllMissingTokens() + { + await TestAsync( + @" +enum MyEnum +{ + Fizz +} +class MyClass +{ + void Method() + { + var e = MyEnum.Fizz; + switch ([|e|]) + } +} +", + @" +enum MyEnum +{ + Fizz +} +class MyClass +{ + void Method() + { + var e = MyEnum.Fizz; + switch (e) + { + case MyEnum.Fizz: + break; + } + } +"); + } + } +} \ No newline at end of file diff --git a/src/EditorFeatures/CSharpTest/PopulateSwitch/PopulateSwitchTests_FixAllTests.cs b/src/EditorFeatures/CSharpTest/PopulateSwitch/PopulateSwitchTests_FixAllTests.cs new file mode 100644 index 0000000000000000000000000000000000000000..753889979d01b7b102591f7b193739c3293a78d7 --- /dev/null +++ b/src/EditorFeatures/CSharpTest/PopulateSwitch/PopulateSwitchTests_FixAllTests.cs @@ -0,0 +1,491 @@ +using Roslyn.Test.Utilities; +using System.Threading.Tasks; +using Xunit; + +namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.PopulateSwitch +{ + public partial class PopulateSwitchTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest + { + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInDocument() + { + var input = @" + + + +namespace ConsoleApplication1 +{ + enum MyEnum + { + Fizz, Buzz, FizzBuzz + } + class MyClass1 + { + void Method() + { + var e = MyEnum.Fizz; + switch ({|FixAllInDocument:e|}) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; + } + switch (e) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; + } + } + } +} + + +namespace ConsoleApplication1 +{ + class MyClass2 + { + void Method() + { + var e = MyEnum.Fizz; + switch (e) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; + } + } + } +} + + + + +namespace ConsoleApplication1 +{ + class MyClass3 + { + void Method() + { + var e = MyEnum.Fizz; + switch (e) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; + } + } + } +} + + +"; + + var expected = @" + + + +namespace ConsoleApplication1 +{ + enum MyEnum + { + Fizz, Buzz, FizzBuzz + } + class MyClass1 + { + void Method() + { + var e = MyEnum.Fizz; + switch (e) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; + default: + break; + } + switch (e) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; + default: + break; + } + } + } +} + + +namespace ConsoleApplication1 +{ + class MyClass2 + { + void Method() + { + var e = MyEnum.Fizz; + switch (e) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; + } + } + } +} + + + + +namespace ConsoleApplication1 +{ + class MyClass3 + { + void Method() + { + var e = MyEnum.Fizz; + switch (e) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; + } + } + } +} + + +"; + + await TestAsync(input, expected, compareTokens: false); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInProject() + { + var input = @" + + + +namespace ConsoleApplication1 +{ + enum MyEnum + { + Fizz, Buzz, FizzBuzz + } + class MyClass1 + { + void Method() + { + var e = MyEnum.Fizz; + switch ({|FixAllInProject:e|}) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; + } + } + } +} + + +namespace ConsoleApplication1 +{ + class MyClass2 + { + void Method() + { + var e = MyEnum.Fizz; + switch (e) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; + } + } + } +} + + + + +namespace ConsoleApplication1 +{ + class MyClass3 + { + void Method() + { + var e = MyEnum.Fizz; + switch (e) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; + } + } + } +} + + +"; + + var expected = @" + + + +namespace ConsoleApplication1 +{ + enum MyEnum + { + Fizz, Buzz, FizzBuzz + } + class MyClass1 + { + void Method() + { + var e = MyEnum.Fizz; + switch (e) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; + default: + break; + } + } + } +} + + +namespace ConsoleApplication1 +{ + class MyClass2 + { + void Method() + { + var e = MyEnum.Fizz; + switch (e) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; + default: + break; + } + } + } +} + + + + +namespace ConsoleApplication1 +{ + class MyClass3 + { + void Method() + { + var e = MyEnum.Fizz; + switch (e) + { + case MyEnum.Fizz: + case MyEnum.Buzz: + case MyEnum.FizzBuzz: + break; + } + } + } +} + + +"; + + await TestAsync(input, expected, compareTokens: false); + } + + [Fact] + [Trait(Traits.Feature, Traits.Features.CodeActionsPopulateSwitch)] + [Trait(Traits.Feature, Traits.Features.CodeActionsFixAllOccurrences)] + public async Task TestFixAllInSolution() + { + var input = @" + + + +namespace ConsoleApplication1 +{ + enum MyEnum1 + { + Fizz, Buzz, FizzBuzz + } + class MyClass1 + { + void Method() + { + var e = MyEnum1.Fizz; + switch ({|FixAllInSolution:e|}) + { + case MyEnum1.Fizz: + case MyEnum1.Buzz: + case MyEnum1.FizzBuzz: + break; + } + } + } +} + + +namespace ConsoleApplication1 +{ + enum MyEnum2 + { + Fizz, Buzz, FizzBuzz + } + class MyClass2 + { + void Method() + { + var e = MyEnum2.Fizz; + switch (e) + { + case MyEnum2.Fizz: + case MyEnum2.Buzz: + case MyEnum2.FizzBuzz: + break; + } + } + } +} + + + + +namespace ConsoleApplication2 +{ + enum MyEnum3 + { + Fizz, Buzz, FizzBuzz + } + class MyClass3 + { + void Method() + { + var e = MyEnum3.Fizz; + switch (e) + { + case MyEnum3.Fizz: + case MyEnum3.Buzz: + case MyEnum3.FizzBuzz: + break; + } + } + } +} + + +"; + + var expected = @" + + + +namespace ConsoleApplication1 +{ + enum MyEnum1 + { + Fizz, Buzz, FizzBuzz + } + class MyClass1 + { + void Method() + { + var e = MyEnum1.Fizz; + switch (e) + { + case MyEnum1.Fizz: + case MyEnum1.Buzz: + case MyEnum1.FizzBuzz: + break; + default: + break; + } + } + } +} + + +namespace ConsoleApplication1 +{ + enum MyEnum2 + { + Fizz, Buzz, FizzBuzz + } + class MyClass2 + { + void Method() + { + var e = MyEnum2.Fizz; + switch (e) + { + case MyEnum2.Fizz: + case MyEnum2.Buzz: + case MyEnum2.FizzBuzz: + break; + default: + break; + } + } + } +} + + + + +namespace ConsoleApplication2 +{ + enum MyEnum3 + { + Fizz, Buzz, FizzBuzz + } + class MyClass3 + { + void Method() + { + var e = MyEnum3.Fizz; + switch (e) + { + case MyEnum3.Fizz: + case MyEnum3.Buzz: + case MyEnum3.FizzBuzz: + break; + default: + break; + } + } + } +} + + +"; + + await TestAsync(input, expected, compareTokens: false); + } + } +} diff --git a/src/EditorFeatures/VisualBasicTest/BasicEditorServicesTest.vbproj b/src/EditorFeatures/VisualBasicTest/BasicEditorServicesTest.vbproj index b67be1915ea3ba44d362bed4658c25ba5e46c127..25721ca71d6ea188f9a1a12db730c762c32597ee 100644 --- a/src/EditorFeatures/VisualBasicTest/BasicEditorServicesTest.vbproj +++ b/src/EditorFeatures/VisualBasicTest/BasicEditorServicesTest.vbproj @@ -329,6 +329,8 @@ + + diff --git a/src/EditorFeatures/VisualBasicTest/PopulateSwitch/PopulateSwitchTests.vb b/src/EditorFeatures/VisualBasicTest/PopulateSwitch/PopulateSwitchTests.vb new file mode 100644 index 0000000000000000000000000000000000000000..f007353cd8fc7b743f4471a8c6ca1a06f821020d --- /dev/null +++ b/src/EditorFeatures/VisualBasicTest/PopulateSwitch/PopulateSwitchTests.vb @@ -0,0 +1,660 @@ +Imports Microsoft.CodeAnalysis.CodeFixes +Imports Microsoft.CodeAnalysis.Diagnostics +Imports Microsoft.CodeAnalysis.PopulateSwitch + +Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics.PopulateSwitch + Partial Public Class PopulateSwitchTests + Inherits AbstractVisualBasicDiagnosticProviderBasedUserDiagnosticTest + + Friend Overrides Function CreateDiagnosticProviderAndFixer(workspace As Workspace) As Tuple(Of DiagnosticAnalyzer, CodeFixProvider) + Return New Tuple(Of DiagnosticAnalyzer, CodeFixProvider)( + New PopulateSwitchDiagnosticAnalyzer(), New PopulateSwitchCodeFixProvider()) + End Function + + + Public Async Function AllMembersAndElseExist() As Task + Dim markup = + +Enum MyEnum + Fizz + Buzz + FizzBuzz +End Enum +Class Foo + Sub Bar() + Dim e = MyEnum.Fizz + Select Case [|e|] + Case MyEnum.Fizz + Exit Select + Case MyEnum.Buzz + Exit Select + Case MyEnum.FizzBuzz + Exit Select + Case Else + Exit Select + End Select + End Sub +End Class + + + Await TestMissingAsync(markup) + End Function + + + Public Async Function AllMembersExist_NotElse() As Task + Dim markup = + +Enum MyEnum + Fizz + Buzz + FizzBuzz +End Enum +Class Foo + Sub Bar() + Dim e = MyEnum.Fizz + Select Case [|e|] + Case MyEnum.Fizz + Exit Select + Case MyEnum.Buzz + Exit Select + Case MyEnum.FizzBuzz + Exit Select + End Select + End Sub +End Class + + + Dim expected = + +Enum MyEnum + Fizz + Buzz + FizzBuzz +End Enum +Class Foo + Sub Bar() + Dim e = MyEnum.Fizz + Select Case e + Case MyEnum.Fizz + Exit Select + Case MyEnum.Buzz + Exit Select + Case MyEnum.FizzBuzz + Exit Select + Case Else + Exit Select + End Select + End Sub +End Class + + + Await TestAsync(markup, expected) + End Function + + + Public Async Function NotAllMembersExist_NotElse() As Task + Dim markup = + +Enum MyEnum + Fizz + Buzz + FizzBuzz +End Enum +Class Foo + Sub Bar() + Dim e = MyEnum.Fizz + Select Case [|e|] + Case MyEnum.Fizz + Exit Select + Case MyEnum.Buzz + Exit Select + End Select + End Sub +End Class + + + Dim expected = + +Enum MyEnum + Fizz + Buzz + FizzBuzz +End Enum +Class Foo + Sub Bar() + Dim e = MyEnum.Fizz + Select Case e + Case MyEnum.Fizz + Exit Select + Case MyEnum.Buzz + Exit Select + Case MyEnum.FizzBuzz + Exit Select + Case Else + Exit Select + End Select + End Sub +End Class + + + Await TestAsync(markup, expected, index:=2) + End Function + + + Public Async Function NotAllMembersExist_WithElse() As Task + Dim markup = + +Enum MyEnum + Fizz + Buzz + FizzBuzz +End Enum +Class Foo + Sub Bar() + Dim e = MyEnum.Fizz + Select Case [|e|] + Case MyEnum.Fizz + Exit Select + Case MyEnum.Buzz + Exit Select + Case Else + Exit Select + End Select + End Sub +End Class + + + Dim expected = + +Enum MyEnum + Fizz + Buzz + FizzBuzz +End Enum +Class Foo + Sub Bar() + Dim e = MyEnum.Fizz + Select Case e + Case MyEnum.Fizz + Exit Select + Case MyEnum.Buzz + Exit Select + Case MyEnum.FizzBuzz + Exit Select + Case Else + Exit Select + End Select + End Sub +End Class + + + Await TestAsync(markup, expected, compareTokens:=False) + End Function + + + Public Async Function NotAllMembersExist_NotElse_EnumHasExplicitType() As Task + Dim markup = + +Enum MyEnum As Long + Fizz + Buzz + FizzBuzz +End Enum +Class Foo + Sub Bar() + Dim e = MyEnum.Fizz + Select Case [|e|] + Case MyEnum.Fizz + Exit Select + Case MyEnum.Buzz + Exit Select + End Select + End Sub +End Class + + + Dim expected = + +Enum MyEnum As Long + Fizz + Buzz + FizzBuzz +End Enum +Class Foo + Sub Bar() + Dim e = MyEnum.Fizz + Select Case e + Case MyEnum.Fizz + Exit Select + Case MyEnum.Buzz + Exit Select + Case MyEnum.FizzBuzz + Exit Select + Case Else + Exit Select + End Select + End Sub +End Class + + + Await TestAsync(markup, expected, index:=2) + End Function + + + Public Async Function NotAllMembersExist_WithMembersAndElseInBlock_NewValuesAboveElseBlock() As Task + Dim markup = + +Enum MyEnum + Fizz + Buzz + FizzBuzz +End Enum +Class Foo + Sub Bar() + Dim e = MyEnum.Fizz + Select Case [|e|] + Case MyEnum.Fizz + Exit Select + Case MyEnum.Buzz ' not legal. VB does not allow fallthrough. + Case Else + Exit Select + End Select + End Sub +End Class + + + Dim expected = + +Enum MyEnum + Fizz + Buzz + FizzBuzz +End Enum +Class Foo + Sub Bar() + Dim e = MyEnum.Fizz + Select Case e + Case MyEnum.Fizz + Exit Select + Case MyEnum.Buzz ' not legal. VB does not allow fallthrough. + Case MyEnum.FizzBuzz + Exit Select + Case Else + Exit Select + End Select + End Sub +End Class + + + Await TestAsync(markup, expected, compareTokens:=False) + End Function + + + Public Async Function NoMembersExist() As Task + Dim markup = + +Enum MyEnum + Fizz + Buzz + FizzBuzz +End Enum +Class Foo + Sub Bar() + Dim e = MyEnum.Fizz + Select Case [|e|] + End Select + End Sub +End Class + + + Dim expected = + +Enum MyEnum + Fizz + Buzz + FizzBuzz +End Enum +Class Foo + Sub Bar() + Dim e = MyEnum.Fizz + Select Case e + Case MyEnum.Fizz + Exit Select + Case MyEnum.Buzz + Exit Select + Case MyEnum.FizzBuzz + Exit Select + Case Else + Exit Select + End Select + End Sub +End Class + + + Await TestAsync(markup, expected, index:=2) + End Function + + + Public Async Function ImportsEnum_AllMembersExist() As Task + Dim markup = + +Imports System.IO.FileMode +Enum MyEnum + Fizz + Buzz + FizzBuzz +End Enum +Class Foo + Sub Bar() + Dim e = CreateNew + Select Case [|e|] + Case CreateNew + Exit Select + Case Create + Exit Select + Case Open + Exit Select + Case OpenOrCreate + Exit Select + Case Truncate + Exit Select + Case Append + Exit Select + Case Else + Exit Select + End Select + End Sub +End Class + + + Await TestMissingAsync(markup) + End Function + + + Public Async Function ImportsEnum_AllMembersExist_OutOfDefaultOrder() As Task + Dim markup = + +Imports System.IO.FileMode +Enum MyEnum + Fizz + Buzz + FizzBuzz +End Enum +Class Foo + Sub Bar() + Dim e = CreateNew + Select Case [|e|] + Case Truncate + Exit Select + Case Append + Exit Select + Case CreateNew + Exit Select + Case Open + Exit Select + Case OpenOrCreate + Exit Select + Case Create + Exit Select + Case Else + Exit Select + End Select + End Sub +End Class + + + Await TestMissingAsync(markup) + End Function + + + Public Async Function ImportsEnum_NotAllMembersExist() As Task + Dim markup = + +Imports System.IO.FileMode +Enum MyEnum + Fizz + Buzz + FizzBuzz +End Enum +Class Foo + Sub Bar() + Dim e = CreateNew + Select Case [|e|] + Case CreateNew + Exit Select + Case Create + Exit Select + Case Open + Exit Select + Case Else + Exit Select + End Select + End Sub +End Class + + + Dim expected = + +Imports System.IO.FileMode +Enum MyEnum + Fizz + Buzz + FizzBuzz +End Enum +Class Foo + Sub Bar() + Dim e = CreateNew + Select Case e + Case CreateNew + Exit Select + Case Create + Exit Select + Case Open + Exit Select + Case OpenOrCreate + Exit Select + Case Truncate + Exit Select + Case Append + Exit Select + Case Else + Exit Select + End Select + End Sub +End Class + + + Await TestAsync(markup, expected, compareTokens:=False) + End Function + + + Public Async Function ImportsEnum_NoMembersExist() As Task + Dim markup = + +Imports System.IO.FileMode +Enum MyEnum + Fizz + Buzz + FizzBuzz +End Enum +Class Foo + Sub Bar() + Dim e = CreateNew + Select Case [|e|] + + End Select + End Sub +End Class + + + Dim expected = + +Imports System.IO.FileMode +Enum MyEnum + Fizz + Buzz + FizzBuzz +End Enum +Class Foo + Sub Bar() + Dim e = CreateNew + Select Case e + Case CreateNew + Exit Select + Case Create + Exit Select + Case Open + Exit Select + Case OpenOrCreate + Exit Select + Case Truncate + Exit Select + Case Append + Exit Select + Case Else + Exit Select + End Select + End Sub +End Class + + + Await TestAsync(markup, expected, index:=2) + End Function + + + Public Async Function NotAllMembersExist_EnumHasNonFlagsAttribute() As Task + Dim markup = + +<System.Obsolete> +Enum MyEnum + Fizz + Buzz + FizzBuzz +End Enum +Class Foo + Sub Bar() + Dim e = MyEnum.Fizz + Select Case [|e|] + Case MyEnum.Fizz + Exit Select + Case MyEnum.Buzz + Exit Select + End Select + End Sub +End Class + + + Dim expected = + +<System.Obsolete> +Enum MyEnum + Fizz + Buzz + FizzBuzz +End Enum +Class Foo + Sub Bar() + Dim e = MyEnum.Fizz + Select Case e + Case MyEnum.Fizz + Exit Select + Case MyEnum.Buzz + Exit Select + Case MyEnum.FizzBuzz + Exit Select + Case Else + Exit Select + End Select + End Sub +End Class + + + Await TestAsync(markup, expected, index:=2) + End Function + + + Public Async Function NotAllMembersExist_EnumIsNested() As Task + Dim markup = + +Class Foo + Enum MyEnum + Fizz + Buzz + FizzBuzz + End Enum + Sub Bar() + Dim e = MyEnum.Fizz + Select Case [|e|] + Case MyEnum.Fizz + Exit Select + Case MyEnum.Buzz + Exit Select + End Select + End Sub +End Class + + + Dim expected = + +Class Foo + Enum MyEnum + Fizz + Buzz + FizzBuzz + End Enum + Sub Bar() + Dim e = MyEnum.Fizz + Select Case e + Case MyEnum.Fizz + Exit Select + Case MyEnum.Buzz + Exit Select + Case MyEnum.FizzBuzz + Exit Select + Case Else + Exit Select + End Select + End Sub +End Class + + + Await TestAsync(markup, expected, index:=2) + End Function + + + Public Async Function NotAllMembersExist_SwitchIsNotEnum() As Task + Dim markup = + +Class Foo + Sub Bar() + Dim e = "Test" + Select Case [|e|] + Case "Fizz" + Exit Select + Case "Test" + Exit Select + End Select + End Sub +End Class + + Dim expected = + +Class Foo + Sub Bar() + Dim e = "Test" + Select Case e + Case "Fizz" + Exit Select + Case "Test" + Exit Select + Case Else + Exit Select + End Select + End Sub +End Class + + + Await TestAsync(markup, expected) + End Function + End Class +End Namespace \ No newline at end of file diff --git a/src/EditorFeatures/VisualBasicTest/PopulateSwitch/PopulateSwitchTests_FixAllTests.vb b/src/EditorFeatures/VisualBasicTest/PopulateSwitch/PopulateSwitchTests_FixAllTests.vb new file mode 100644 index 0000000000000000000000000000000000000000..fab9e7cbd8f4dc009b0ef44d42c00f7f69e1ea3d --- /dev/null +++ b/src/EditorFeatures/VisualBasicTest/PopulateSwitch/PopulateSwitchTests_FixAllTests.vb @@ -0,0 +1,460 @@ +Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics.PopulateSwitch + Partial Public Class PopulateSwitchTests + Inherits AbstractVisualBasicDiagnosticProviderBasedUserDiagnosticTest + + + + + Public Async Function TestFixAllInDocument() As Task + Dim input = + + + + + + + + Assembly1 + + + + .ToString() + + Dim expected = + + + + + + + + Assembly1 + + + + .ToString() + + Await TestAsync(input, expected, compareTokens:=False, fixAllActionEquivalenceKey:=Nothing) + End Function + + + + + Public Async Function TestFixAllInProject() As Task + Dim input = + + + + + + + + Assembly1 + + + + .ToString() + + Dim expected = + + + + + + + + Assembly1 + + + + .ToString() + + Await TestAsync(input, expected, compareTokens:=False, fixAllActionEquivalenceKey:=Nothing) + End Function + + + + + Public Async Function TestFixAllInSolution() As Task + Dim input = + + + + + + + + Assembly1 + + + + .ToString() + + Dim expected = + + + + + + + + Assembly1 + + + + .ToString() + + Await TestAsync(input, expected, compareTokens:=False, fixAllActionEquivalenceKey:=Nothing) + End Function + End Class +End Namespace \ No newline at end of file