File: BraceHighlighting\BraceHighlightingTests.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.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Editor.UnitTests.BraceHighlighting;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.BraceHighlighting;
 
[Trait(Traits.Feature, Traits.Features.BraceHighlighting)]
public class BraceHighlightingTests : AbstractBraceHighlightingTests
{
    protected override EditorTestWorkspace CreateWorkspace(string markup, ParseOptions options)
        => EditorTestWorkspace.CreateCSharp(markup, parseOptions: options);
 
    [WpfTheory]
    [InlineData("""
        public class C$$ {
        }
        """)]
    [InlineData("""
        public class C $$[|{|]
        [|}|]
        """)]
    [InlineData("""
        public class C {$$
        }
        """)]
    [InlineData("""
        public class C {
        $$}
        """)]
    [InlineData("""
        public class C [|{|]
        [|}|]$$
        """)]
    public async Task TestCurlies(string testCase)
    {
        await TestBraceHighlightingAsync(testCase);
    }
 
    [WpfTheory]
    [InlineData("""
        public class C $$[|{|]
          public void Goo(){}
        [|}|]
        """)]
    [InlineData("""
        public class C {$$
          public void Goo(){}
        }
        """)]
    [InlineData("""
        public class C {
          public void Goo$$[|(|][|)|]{}
        }
        """)]
    [InlineData("""
        public class C {
          public void Goo($$){}
        }
        """)]
    [InlineData("""
        public class C {
          public void Goo[|(|][|)|]$$[|{|][|}|]
        }
        """)]
    [InlineData("""
        public class C {
          public void Goo(){$$}
        }
        """)]
    [InlineData("""
        public class C {
          public void Goo()[|{|][|}|]$$
        }
        """)]
    public async Task TestTouchingItems(string testCase)
    {
        await TestBraceHighlightingAsync(testCase);
    }
 
    [WpfTheory]
    [InlineData("/// $$<summary>Goo</summary>")]
    [InlineData("/// <$$summary>Goo</summary>")]
    [InlineData("/// <summary$$>Goo</summary>")]
    [InlineData("/// <summary>$$Goo</summary>")]
    [InlineData("/// <summary>Goo$$</summary>")]
    [InlineData("/// <summary>Goo<$$/summary>")]
    [InlineData("/// <summary>Goo</$$summary>")]
    [InlineData("/// <summary>Goo</summary$$>")]
    [InlineData("/// <summary>Goo</summary>$$")]
 
    [InlineData("public class C$$[|<|]T[|>|] { }")]
    [InlineData("public class C<$$T> { }")]
    [InlineData("public class C<T$$> { }")]
    [InlineData("public class C[|<|]T[|>$$|] { }")]
 
    [InlineData("unsafe class C { delegate*$$[|<|] int, int[|>|] functionPointer; }")]
    [InlineData("unsafe class C { delegate*[|<|]int, int[|>$$|] functionPointer; }")]
    [InlineData("unsafe class C { delegate*<int, delegate*[|<|]int, int[|>|]$$> functionPointer; }")]
    public async Task TestAngles(string testCase)
    {
        await TestBraceHighlightingAsync(testCase);
    }
 
    [WpfFact]
    public async Task TestNoHighlightingOnOperators()
    {
        await TestBraceHighlightingAsync(
            """
            class C
            {
                void Goo()
                {
                    bool a = b $$< c;
                    bool d = e > f;
                }
            }
            """);
        await TestBraceHighlightingAsync(
            """
            class C
            {
                void Goo()
                {
                    bool a = b <$$ c;
                    bool d = e > f;
                }
            }
            """);
        await TestBraceHighlightingAsync(
            """
            class C
            {
                void Goo()
                {
                    bool a = b < c;
                    bool d = e $$> f;
                }
            }
            """);
        await TestBraceHighlightingAsync(
            """
            class C
            {
                void Goo()
                {
                    bool a = b < c;
                    bool d = e >$$ f;
                }
            }
            """);
    }
 
    [WpfFact]
    public async Task TestSwitch()
    {
        await TestBraceHighlightingAsync(
            """
            class C
            {
                void M(int variable)
                {
                    switch $$[|(|]variable[|)|]
                    {
                        case 0:
                            break;
                    }
                }
            }
            """);
        await TestBraceHighlightingAsync(
            """
            class C
            {
                void M(int variable)
                {
                    switch ($$variable)
                    {
                        case 0:
                            break;
                    }
                }
            }
            """);
        await TestBraceHighlightingAsync(
            """
            class C
            {
                void M(int variable)
                {
                    switch (variable$$)
                    {
                        case 0:
                            break;
                    }
                }
            }
            """);
        await TestBraceHighlightingAsync(
            """
            class C
            {
                void M(int variable)
                {
                    switch [|(|]variable[|)$$|]
                    {
                        case 0:
                            break;
                    }
                }
            }
            """);
        await TestBraceHighlightingAsync(
            """
            class C
            {
                void M(int variable)
                {
                    switch (variable)
                    $$[|{|]
                        case 0:
                            break;
                    [|}|]
                }
            }
            """);
        await TestBraceHighlightingAsync(
            """
            class C
            {
                void M(int variable)
                {
                    switch (variable)
                    {$$
                        case 0:
                            break;
                    }
                }
            }
            """);
        await TestBraceHighlightingAsync(
            """
            class C
            {
                void M(int variable)
                {
                    switch (variable)
                    {
                        case 0:
                            break;
                    $$}
                }
            }
            """);
        await TestBraceHighlightingAsync(
            """
            class C
            {
                void M(int variable)
                {
                    switch (variable)
                    [|{|]
                        case 0:
                            break;
                    [|}$$|]
                }
            }
            """);
    }
 
    [WpfFact]
    public async Task TestEOF()
    {
        await TestBraceHighlightingAsync("""
            public class C [|{|]
            [|}|]$$
            """);
        await TestBraceHighlightingAsync("""
            public class C [|{|]
             void Goo(){}[|}|]$$
            """);
    }
 
    [WpfFact]
    public async Task TestTuples()
    {
        await TestBraceHighlightingAsync(
            """
            class C
            {
                [|(|]int, int[|)$$|] x = (1, 2);
            }
            """, TestOptions.Regular);
        await TestBraceHighlightingAsync(
            """
            class C
            {
                (int, int) x = [|(|]1, 2[|)$$|];
            }
            """, TestOptions.Regular);
    }
 
    [WpfFact]
    public async Task TestNestedTuples()
    {
        await TestBraceHighlightingAsync(
            """
            class C
            {
                ([|(|]int, int[|)$$|], string) x = ((1, 2), "hello";
            }
            """, TestOptions.Regular);
        await TestBraceHighlightingAsync(
            """
            class C
            {
                ((int, int), string) x = ([|(|]1, 2[|)$$|], "hello";
            }
            """, TestOptions.Regular);
    }
 
    [WpfFact]
    public async Task TestTuplesWithGenerics()
    {
        await TestBraceHighlightingAsync(
            """
            class C
            {
                [|(|]Dictionary<int, string>, List<int>[|)$$|] x = (null, null);
            }
            """, TestOptions.Regular);
        await TestBraceHighlightingAsync(
            """
            class C
            {
                var x = [|(|]new Dictionary<int, string>(), new List<int>()[|)$$|];
            }
            """, TestOptions.Regular);
    }
 
    [WpfFact]
    public async Task TestRegexGroupBracket1()
    {
        var input = """
            using System.Text.RegularExpressions;
 
            class C
            {
                void Goo()
                {
                    var r = new Regex(@"$$[|(|]a[|)|]");
                }
            }
            """;
 
        await TestBraceHighlightingAsync(input);
    }
 
    [WpfFact]
    public async Task TestRegexGroupBracket2()
    {
        var input = """
            using System.Text.RegularExpressions;
 
            class C
            {
                void Goo()
                {
                    var r = new Regex(@"[|(|]a[|)|]$$");
                }
            }
            """;
 
        await TestBraceHighlightingAsync(input);
    }
 
    [WpfFact]
    public async Task TestRegexUnclosedGroupBracket1()
    {
        var input = """
            using System.Text.RegularExpressions;
 
            class C
            {
                void Goo()
                {
                    var r = new Regex(@"$$(a");
                }
            }
            """;
 
        await TestBraceHighlightingAsync(input);
    }
 
    [WpfFact]
    public async Task TestRegexCommentBracket1()
    {
        var input = """
            using System.Text.RegularExpressions;
 
            class C
            {
                void Goo()
                {
                    var r = new Regex(@"$$[|(|]?#a[|)|]");
                }
            }
            """;
 
        await TestBraceHighlightingAsync(input);
    }
 
    [WpfFact]
    public async Task TestRegexCommentBracket2()
    {
        var input = """
            using System.Text.RegularExpressions;
 
            class C
            {
                void Goo()
                {
                    var r = new Regex(@"[|(|]?#a[|)|]$$");
                }
            }
            """;
 
        await TestBraceHighlightingAsync(input);
    }
 
    [WpfFact]
    public async Task TestRegexUnclosedCommentBracket()
    {
        var input = """
            using System.Text.RegularExpressions;
 
            class C
            {
                void Goo()
                {
                    var r = new Regex(@"$$(?#a");
                }
            }
            """;
 
        await TestBraceHighlightingAsync(input);
    }
 
    [WpfFact]
    public async Task TestRegexCharacterClassBracket1()
    {
        var input = """
            using System.Text.RegularExpressions;
 
            class C
            {
                void Goo()
                {
                    var r = new Regex(@"$$[|<|]a[|>|]");
                }
            }
            """;
 
        await TestBraceHighlightingAsync(input, swapAnglesWithBrackets: true);
    }
 
    [WpfFact]
    public async Task TestRegexCharacterClassBracket2()
    {
        var input = """
            using System.Text.RegularExpressions;
 
            class C
            {
                void Goo()
                {
                    var r = new Regex(@"[|<|]a[|>|]$$");
                }
            }
            """;
        await TestBraceHighlightingAsync(input, swapAnglesWithBrackets: true);
    }
 
    [WpfFact]
    public async Task TestRegexUnclosedCharacterClassBracket1()
    {
        var input = """
            using System.Text.RegularExpressions;
 
            class C
            {
                void Goo()
                {
                    var r = new Regex(@"$$<a");
                }
            }
            """;
 
        await TestBraceHighlightingAsync(input, swapAnglesWithBrackets: true);
    }
 
    [WpfFact]
    public async Task TestRegexNegativeCharacterClassBracket1()
    {
        var input = """
            using System.Text.RegularExpressions;
 
            class C
            {
                void Goo()
                {
                    var r = new Regex(@"$$[|<|]^a[|>|]");
                }
            }
            """;
 
        await TestBraceHighlightingAsync(input, swapAnglesWithBrackets: true);
    }
 
    [WpfFact]
    public async Task TestRegexNegativeCharacterClassBracket2()
    {
        var input = """
            using System.Text.RegularExpressions;
 
            class C
            {
                void Goo()
                {
                    var r = new Regex(@"[|<|]^a[|>|]$$");
                }
            }
            """;
 
        await TestBraceHighlightingAsync(input, swapAnglesWithBrackets: true);
    }
 
    [WpfFact]
    public async Task TestJsonBracket1()
    {
        var input = """
            class C
            {
                void Goo()
                {
                    var r = /*lang=json*/ @"new Json[|$$(|]1, 2, 3[|)|]";
                }
            }
            """;
        await TestBraceHighlightingAsync(input);
    }
 
    [WpfFact]
    public async Task TestJsonBracket2()
    {
        var input = """
            class C
            {
                void Goo()
                {
                    var r = /*lang=json*/ @"new Json[|(|]1, 2, 3[|)|]$$";
                }
            }
            """;
        await TestBraceHighlightingAsync(input);
    }
 
    [WpfFact]
    public async Task TestJsonBracket_RawStrings()
    {
        var input = """"
            class C
            {
                void Goo()
                {
                    var r = /*lang=json*/ """new Json[|$$(|]1, 2, 3[|)|]""";
                }
            }
            """";
        await TestBraceHighlightingAsync(input);
    }
 
    [WpfFact]
    public async Task TestUnmatchedJsonBracket1()
    {
        var input = """
            class C
            {
                void Goo()
                {
                    var r = /*lang=json*/ @"new Json$$(1, 2, 3";
                }
            }
            """;
        await TestBraceHighlightingAsync(input);
    }
 
    [WpfFact]
    public async Task TestJsonBracket_NoComment_NotLikelyJson()
    {
        var input = """
            class C
            {
                void Goo()
                {
                    var r = @"$$[ 1, 2, 3 ]";
                }
            }
            """;
        await TestBraceHighlightingAsync(input);
    }
 
    [WpfFact]
    public async Task TestJsonBracket_NoComment_LikelyJson()
    {
        var input = """
            class C
            {
                void Goo()
                {
                    var r = @"[ { prop: 0 }, new Json[|$$(|]1, 2, 3[|)|], 3 ]";
                }
            }
            """;
        await TestBraceHighlightingAsync(input);
    }
 
    [WpfTheory, WorkItem("https://github.com/dotnet/roslyn/issues/32791")]
    [InlineData(@"$$ /* goo */ public class C { }")]
    [InlineData(@" $$[|/*|] goo [|*/|] public class C { }")]
    [InlineData(@" [|/$$*|] goo [|*/|] public class C { }")]
    [InlineData(@" /*$$ goo */ public class C { }")]
    [InlineData(@" /* $$goo */ public class C { }")]
    [InlineData(@" /* goo$$ */ public class C { }")]
    [InlineData(@" /* goo $$*/ public class C { }")]
    [InlineData(@" [|/*|] goo [|*$$/|] public class C { }")]
    [InlineData(@" [|/*|] goo [|*/|]$$ public class C { }")]
    [InlineData(@" /* goo */ $$public class C { }")]
    public async Task TestBlockComments(string input)
    {
        await TestBraceHighlightingAsync(input);
    }
 
    [WpfTheory, WorkItem("https://github.com/dotnet/roslyn/issues/32791")]
    [InlineData(@"$$ /** goo */ public class C { }")]
    [InlineData(@" $$[|/**|] goo [|*/|] public class C { }")]
    [InlineData(@" [|/$$**|] goo [|*/|] public class C { }")]
    [InlineData(@" [|/*$$*|] goo [|*/|] public class C { }")]
    [InlineData(@" /**$$ goo */ public class C { }")]
    [InlineData(@" /** $$goo */ public class C { }")]
    [InlineData(@" /** goo$$ */ public class C { }")]
    [InlineData(@" /** goo $$*/ public class C { }")]
    [InlineData(@" [|/**|] goo [|*$$/|] public class C { }")]
    [InlineData(@" [|/**|] goo [|*/|]$$ public class C { }")]
    [InlineData(@" /** goo */ $$public class C { }")]
    public async Task TestDocCommentBlockComments(string input)
    {
        await TestBraceHighlightingAsync(input);
    }
}