File: KeywordHighlighting\SwitchStatementHighlighterTests.cs
Web Access
Project: src\src\EditorFeatures\CSharpTest\Microsoft.CodeAnalysis.CSharp.EditorFeatures.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.EditorFeatures.UnitTests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
#nullable disable
 
using System;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp.KeywordHighlighting.KeywordHighlighters;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.KeywordHighlighting;
 
[Trait(Traits.Feature, Traits.Features.KeywordHighlighting)]
public class SwitchStatementHighlighterTests : AbstractCSharpKeywordHighlighterTests
{
    internal override Type GetHighlighterType()
        => typeof(SwitchStatementHighlighter);
 
    [Fact]
    public async Task TestExample1_OnSwitchKeyword()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    {|Cursor:[|switch|]|} (i)
                    {
                        [|case|] 0:
                            CaseZero();
                            [|break|];
                        [|case|] 1:
                            CaseOne();
                            [|break|];
                        [|default|]:
                            CaseOthers();
                            [|break|];
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestExample1_OnCaseKeyword()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    [|switch|] (i)
                    {
                        {|Cursor:[|case|]|} 0:
                            CaseZero();
                            [|break|];
                        [|case|] 1:
                            CaseOne();
                            [|break|];
                        [|default|]:
                            CaseOthers();
                            [|break|];
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestExample1_AfterCaseColon()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    [|switch|] (i)
                    {
                        [|case|] 0:{|Cursor:|}
                            CaseZero();
                            [|break|];
                        [|case|] 1:
                            CaseOne();
                            [|break|];
                        [|default|]:
                            CaseOthers();
                            [|break|];
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestExample1_NotOnCaseValue()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    switch (i)
                    {
                        case {|Cursor:0|}:
                            CaseZero();
                            break;
                        case 1:
                            CaseOne();
                            break;
                        default:
                            CaseOthers();
                            break;
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestExample1_OnBreakStatement()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    [|switch|] (i)
                    {
                        [|case|] 0:
                            CaseZero();
                            {|Cursor:[|break|];|}
                        [|case|] 1:
                            CaseOne();
                            [|break|];
                        [|default|]:
                            CaseOthers();
                            [|break|];
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestExample1_OnDefaultLabel()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    [|switch|] (i)
                    {
                        [|case|] 0:
                            CaseZero();
                            [|break|];
                        [|case|] 1:
                            CaseOne();
                            [|break|];
                        {|Cursor:[|default|]:|}
                            CaseOthers();
                            [|break|];
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestExample2_OnGotoCaseKeywords()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    [|switch|] (i)
                    {
                        [|case|] 0:
                            CaseZero();
                            {|Cursor:[|goto case|]|} 1;
                        [|case|] 1:
                            CaseOne();
                            [|goto default|];
                        [|default|]:
                            CaseOthers();
                            [|break|];
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestExample2_AfterGotoCaseSemicolon()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    [|switch|] (i)
                    {
                        [|case|] 0:
                            CaseZero();
                            [|goto case|] 1;{|Cursor:|}
                        [|case|] 1:
                            CaseOne();
                            [|goto default|];
                        [|default|]:
                            CaseOthers();
                            [|break|];
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestExample2_NotOnGotoCaseValue()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    switch (i)
                    {
                        case 0:
                            CaseZero();
                            goto case {|Cursor:1|};
                        case 1:
                            CaseOne();
                            goto default;
                        default:
                            CaseOthers();
                            break;
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestExample2_OnGotoDefaultStatement()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    [|switch|] (i)
                    {
                        [|case|] 0:
                            CaseZero();
                            [|goto case|] 1;
                        [|case|] 1:
                            CaseOne();
                            {|Cursor:[|goto default|];|}
                        [|default|]:
                            CaseOthers();
                            [|break|];
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestNestedExample1_OnSwitchKeyword()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    foreach (var a in x)
                    {
                        if (a)
                        {
                            break;
                        }
                        else
                        {
                            {|Cursor:[|switch|]|} (b)
                            {
                                [|case|] 0:
                                    while (true)
                                    {
                                        do
                                        {
                                            break;
                                        }
                                        while (false);
                                        break;
                                    }
 
                                    [|break|];
                            }
                        }
 
                        for (int i = 0; i < 10; i++)
                        {
                            break;
                        }
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestNestedExample1_OnCaseKeyword()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    foreach (var a in x)
                    {
                        if (a)
                        {
                            break;
                        }
                        else
                        {
                            [|switch|] (b)
                            {
                                {|Cursor:[|case|]|} 0:
                                    while (true)
                                    {
                                        do
                                        {
                                            break;
                                        }
                                        while (false);
                                        break;
                                    }
 
                                    [|break|];
                            }
                        }
 
                        for (int i = 0; i < 10; i++)
                        {
                            break;
                        }
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestNestedExample1_NotBeforeCaseValue()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    foreach (var a in x)
                    {
                        if (a)
                        {
                            break;
                        }
                        else
                        {
                            switch (b)
                            {
                                case {|Cursor:|}0:
                                    while (true)
                                    {
                                        do
                                        {
                                            break;
                                        }
                                        while (false);
                                        break;
                                    }
 
                                    break;
                            }
                        }
 
                        for (int i = 0; i < 10; i++)
                        {
                            break;
                        }
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestNestedExample1_AfterCaseColon()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    foreach (var a in x)
                    {
                        if (a)
                        {
                            break;
                        }
                        else
                        {
                            [|switch|] (b)
                            {
                                [|case|] 0:{|Cursor:|}
                                    while (true)
                                    {
                                        do
                                        {
                                            break;
                                        }
                                        while (false);
                                        break;
                                    }
 
                                    [|break|];
                            }
                        }
 
                        for (int i = 0; i < 10; i++)
                        {
                            break;
                        }
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestNestedExample1_OnBreakStatement()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    foreach (var a in x)
                    {
                        if (a)
                        {
                            break;
                        }
                        else
                        {
                            [|switch|] (b)
                            {
                                [|case|] 0:
                                    while (true)
                                    {
                                        do
                                        {
                                            break;
                                        }
                                        while (false);
                                        break;
                                    }
 
                                    {|Cursor:[|break|];|}
                            }
                        }
 
                        for (int i = 0; i < 10; i++)
                        {
                            break;
                        }
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task Bug3483()
    {
        await TestAsync(
            """
            class C
            {
                static void M()
                {
                    [|switch|] (2)
                    {
                        [|case|] 1:
                            {|Cursor:[|goto|]|}
                    }
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25039")]
    public async Task TestWithUnrelatedGotoStatement_OnGotoCaseGotoKeyword()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    label:
                    [|switch|] (i)
                    {
                        [|case|] 0:
                            CaseZero();
                            [|{|Cursor:goto|} case|] 1;
                        [|case|] 1:
                            CaseOne();
                            [|goto default|];
                        [|default|]:
                            CaseOthers();
                            goto label;
                    }
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25039")]
    public async Task TestWithUnrelatedGotoStatement_OnGotoDefaultGotoKeyword()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    label:
                    [|switch|] (i)
                    {
                        [|case|] 0:
                            CaseZero();
                            [|goto case|] 1;
                        [|case|] 1:
                            CaseOne();
                            [|{|Cursor:goto|} default|];
                        [|default|]:
                            CaseOthers();
                            goto label;
                    }
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25039")]
    public async Task TestWithUnrelatedGotoStatement_NotOnGotoLabelGotoKeyword()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    label:
                    switch (i)
                    {
                        case 0:
                            CaseZero();
                            goto case 1;
                        case 1:
                            CaseOne();
                            goto default;
                        default:
                            CaseOthers();
                            {|Cursor:goto|} label;
                    }
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25039")]
    public async Task TestWithNestedStatements_OnSwitchKeyword()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    {|Cursor:[|switch|]|} (i)
                    {
                        [|case|] 0:
                        {
                            CaseZero();
                            [|goto case|] 1;
                        }
                        [|case|] 1:
                        {
                            CaseOne();
                            [|goto default|];
                        }
                        [|default|]:
                        {
                            CaseOthers();
                            [|break|];
                        }
                    }
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25039")]
    public async Task TestWithNestedStatements_OnBreakKeyword()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    [|switch|] (i)
                    {
                        [|case|] 0:
                        {
                            CaseZero();
                            [|goto case|] 1;
                        }
                        [|case|] 1:
                        {
                            CaseOne();
                            [|goto default|];
                        }
                        [|default|]:
                        {
                            CaseOthers();
                            {|Cursor:[|break|]|};
                        }
                    }
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25039")]
    public async Task TestWithGotoCaseAndBreakInsideLoop_OnSwitchKeyword()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    {|Cursor:[|switch|]|} (true)
                    {
                        [|case|] true:
                            while (true)
                            {
                                [|goto case|] true;
                                break;
 
                                switch (true)
                                {
                                    case true:
                                        goto case true;
                                        break;
                                }
                            }
                    }
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25039")]
    public async Task TestWithGotoCaseAndBreakInsideLoop_OnGotoCaseGotoKeyword()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    [|switch|] (true)
                    {
                        [|case|] true:
                            while (true)
                            {
                                [|{|Cursor:goto|} case|] true;
                                break;
 
                                switch (true)
                                {
                                    case true:
                                        goto case true;
                                        break;
                                }
                            }
                    }
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/25039")]
    public async Task TestWithGotoCaseAndBreakInsideLoop_NotOnLoopBreakKeyword()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    switch (true)
                    {
                        case true:
                            while (true)
                            {
                                goto case true;
                                {|Cursor:break|};
 
                                switch (true)
                                {
                                    case true:
                                        goto case true;
                                        break;
                                }
                            }
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestWithWhenClauseAndPattern_OnSwitchKeyword()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    {|Cursor:[|switch|]|} (true)
                    {
                        [|case|] true when true:
                            [|break|];
                        [|case|] bool b:
                            [|break|];
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestWithWhenClauseAndPattern_NotOnWhenKeyword()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    switch (true)
                    {
                        case true {|Cursor:when|} true:
                            break;
                        case bool b:
                            break;
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestWithWhenClauseAndPattern_AfterWhenCaseColon()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    [|switch|] (true)
                    {
                        [|case|] true when true:{|Cursor:|}
                            [|break|];
                        [|case|] bool b:
                            [|break|];
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestWithWhenClauseAndPattern_AfterPatternCaseColon()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    [|switch|] (true)
                    {
                        [|case|] true when true:
                            [|break|];
                        [|case|] bool b:{|Cursor:|}
                            [|break|];
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestWithWhenClauseAndPattern_NotOnWhenValue()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    switch (true)
                    {
                        case true when {|Cursor:true|}:
                            break;
                        case bool b:
                            break;
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestWithWhenClauseAndPattern_NotOnPattern()
    {
        await TestAsync(
            """
            class C
            {
                void M()
                {
                    switch (true)
                    {
                        case true when true:
                            break;
                        case {|Cursor:bool b|}:
                            break;
                    }
                }
            }
            """);
    }
}