File: Wrapping\BinaryExpressionWrappingTests.cs
Web Access
Project: src\src\Features\CSharpTest\Microsoft.CodeAnalysis.CSharp.Features.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.Features.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.CodeStyle;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Wrapping;
 
[Trait(Traits.Feature, Traits.Features.CodeActionsWrapping)]
public class BinaryExpressionWrappingTests : AbstractWrappingTests
{
    private TestParameters EndOfLine
        => new(options: Option(CodeStyleOptions2.OperatorPlacementWhenWrapping, OperatorPlacementWhenWrappingPreference.EndOfLine));
 
    private TestParameters BeginningOfLine
        => new(options: Option(CodeStyleOptions2.OperatorPlacementWhenWrapping, OperatorPlacementWhenWrappingPreference.BeginningOfLine));
 
    private Task TestEndOfLine(string markup, string expected)
        => TestInRegularAndScript1Async(markup, expected, EndOfLine);
 
    private Task TestBeginningOfLine(string markup, string expected)
        => TestInRegularAndScript1Async(markup, expected, BeginningOfLine);
 
    [Fact]
    public async Task TestMissingWithSyntaxError()
    {
        await TestMissingAsync(
            """
            class C {
                void Bar() {
                    if ([||]i && (j && )
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestMissingWithSelection()
    {
        await TestMissingAsync(
            """
            class C {
                void Bar() {
                    if ([|i|] && j) {
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestMissingBeforeExpr()
    {
        await TestMissingAsync(
            """
            class C {
                void Bar() {
                    [||]if (i && j) {
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestMissingWithSingleExpr()
    {
        await TestMissingAsync(
            """
            class C {
                void Bar() {
                    if ([||]i) {
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestMissingWithMultiLineExpression()
    {
        await TestMissingAsync(
            """
            class C {
                void Bar() {
                    if ([||]i && (j +
                        k)) {
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestMissingWithMultiLineExpr2()
    {
        await TestMissingAsync(
            """
            class C {
                void Bar() {
                    if ([||]i && @"
                    ") {
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestInIf()
    {
        await TestEndOfLine(
            """
            class C {
                void Bar() {
                    if ([||]i && j) {
                    }
                }
            }
            """,
            """
            class C {
                void Bar() {
                    if (i &&
                        j) {
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestInIf_IncludingOp()
    {
        await TestBeginningOfLine(
            """
            class C {
                void Bar() {
                    if ([||]i && j) {
                    }
                }
            }
            """,
            """
            class C {
                void Bar() {
                    if (i
                        && j) {
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestInIf2()
    {
        await TestEndOfLine(
            """
            class C {
                void Bar() {
                    if (i[||] && j) {
                    }
                }
            }
            """,
            """
            class C {
                void Bar() {
                    if (i &&
                        j) {
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestInIf3()
    {
        await TestEndOfLine(
            """
            class C {
                void Bar() {
                    if (i [||]&& j) {
                    }
                }
            }
            """,
            """
            class C {
                void Bar() {
                    if (i &&
                        j) {
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestInIf4()
    {
        await TestEndOfLine(
            """
            class C {
                void Bar() {
                    if (i &&[||] j) {
                    }
                }
            }
            """,
            """
            class C {
                void Bar() {
                    if (i &&
                        j) {
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestInIf5()
    {
        await TestEndOfLine(
            """
            class C {
                void Bar() {
                    if (i && [||]j) {
                    }
                }
            }
            """,
            """
            class C {
                void Bar() {
                    if (i &&
                        j) {
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestTwoExprWrappingCases_End()
    {
        await TestAllWrappingCasesAsync(
            """
            class C {
                void Bar() {
                    if ([||]i && j) {
                    }
                }
            }
            """,
EndOfLine,
"""
class C {
    void Bar() {
        if (i &&
            j) {
        }
    }
}
""");
    }
 
    [Fact]
    public async Task TestTwoExprWrappingCases_Beginning()
    {
        await TestAllWrappingCasesAsync(
            """
            class C {
                void Bar() {
                    if ([||]i && j) {
                    }
                }
            }
            """,
BeginningOfLine,
"""
class C {
    void Bar() {
        if (i
            && j) {
        }
    }
}
""");
    }
 
    [Fact]
    public async Task TestThreeExprWrappingCases_End()
    {
        await TestAllWrappingCasesAsync(
            """
            class C {
                void Bar() {
                    if ([||]i && j || k) {
                    }
                }
            }
            """,
EndOfLine,
"""
class C {
    void Bar() {
        if (i &&
            j ||
            k) {
        }
    }
}
""");
    }
 
    [Fact]
    public async Task TestThreeExprWrappingCases_Beginning()
    {
        await TestAllWrappingCasesAsync(
            """
            class C {
                void Bar() {
                    if ([||]i && j || k) {
                    }
                }
            }
            """,
BeginningOfLine,
"""
class C {
    void Bar() {
        if (i
            && j
            || k) {
        }
    }
}
""");
    }
 
    [Fact]
    public async Task Test_AllOptions_NoInitialMatches_End()
    {
        await TestAllWrappingCasesAsync(
            """
            class C {
                void Bar() {
                    if (
                        [||]i   &&
                            j
                             ||   k) {
                    }
                }
            }
            """,
EndOfLine,
"""
class C {
    void Bar() {
        if (
            i &&
            j ||
            k) {
        }
    }
}
""",
"""
class C {
    void Bar() {
        if (
            i && j || k) {
        }
    }
}
""");
    }
 
    [Fact]
    public async Task Test_AllOptions_NoInitialMatches_Beginning()
    {
        await TestAllWrappingCasesAsync(
            """
            class C {
                void Bar() {
                    if (
                        [||]i   &&
                            j
                             ||   k) {
                    }
                }
            }
            """,
BeginningOfLine,
"""
class C {
    void Bar() {
        if (
            i
            && j
            || k) {
        }
    }
}
""",
"""
class C {
    void Bar() {
        if (
            i && j || k) {
        }
    }
}
""");
    }
 
    [Fact]
    public async Task Test_DoNotOfferExistingOption1()
    {
        await TestAllWrappingCasesAsync(
            """
            class C {
                void Bar() {
                    if ([||]a &&
                        b) {
                    }
                }
            }
            """,
            """
            class C {
                void Bar() {
                    if (a
                        && b) {
                    }
                }
            }
            """,
            """
            class C {
                void Bar() {
                    if (a && b) {
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task Test_DoNotOfferExistingOption2_End()
    {
        await TestAllWrappingCasesAsync(
            """
            class C {
                void Bar() {
                    if ([||]a
                        && b) {
                    }
                }
            }
            """,
EndOfLine,
"""
class C {
    void Bar() {
        if (a &&
            b) {
        }
    }
}
""",
"""
class C {
    void Bar() {
        if (a && b) {
        }
    }
}
""");
    }
 
    [Fact]
    public async Task Test_DoNotOfferExistingOption2_Beginning()
    {
        await TestAllWrappingCasesAsync(
            """
            class C {
                void Bar() {
                    if ([||]a
                        && b) {
                    }
                }
            }
            """,
BeginningOfLine,
"""
class C {
    void Bar() {
        if (a && b) {
        }
    }
}
""");
    }
 
    [Fact]
    public async Task TestInLocalInitializer_Beginning()
    {
        await TestAllWrappingCasesAsync(
            """
            class C {
                void Goo() {
                    var v = [||]a && b && c;
                }
            }
            """,
BeginningOfLine,
"""
class C {
    void Goo() {
        var v = a
            && b
            && c;
    }
}
""",
"""
class C {
    void Goo() {
        var v = a
                && b
                && c;
    }
}
""");
    }
 
    [Fact]
    public async Task TestInLocalInitializer_End()
    {
        await TestAllWrappingCasesAsync(
            """
            class C {
                void Goo() {
                    var v = [||]a && b && c;
                }
            }
            """,
EndOfLine,
"""
class C {
    void Goo() {
        var v = a &&
            b &&
            c;
    }
}
""",
"""
class C {
    void Goo() {
        var v = a &&
                b &&
                c;
    }
}
""");
    }
 
    [Fact]
    public async Task TestInField_Beginning()
    {
        await TestAllWrappingCasesAsync(
            """
            class C {
                bool v = [||]a && b && c;
            }
            """,
BeginningOfLine,
"""
class C {
    bool v = a
        && b
        && c;
}
""",
"""
class C {
    bool v = a
             && b
             && c;
}
""");
    }
 
    [Fact]
    public async Task TestInField_End()
    {
        await TestAllWrappingCasesAsync(
            """
            class C {
                bool v = [||]a && b && c;
            }
            """,
EndOfLine,
"""
class C {
    bool v = a &&
        b &&
        c;
}
""",
"""
class C {
    bool v = a &&
             b &&
             c;
}
""");
    }
 
    [Fact]
    public async Task TestAddition_End()
    {
        await TestAllWrappingCasesAsync(
            """
            class C {
                void Bar() {
                    var goo = [||]"now" + "is" + "the" + "time";
                }
            }
            """,
EndOfLine,
"""
class C {
    void Bar() {
        var goo = "now" +
            "is" +
            "the" +
            "time";
    }
}
""",
"""
class C {
    void Bar() {
        var goo = "now" +
                  "is" +
                  "the" +
                  "time";
    }
}
""");
    }
 
    [Fact]
    public async Task TestAddition_Beginning()
    {
        await TestAllWrappingCasesAsync(
            """
            class C {
                void Bar() {
                    var goo = [||]"now" + "is" + "the" + "time";
                }
            }
            """,
BeginningOfLine,
"""
class C {
    void Bar() {
        var goo = "now"
            + "is"
            + "the"
            + "time";
    }
}
""",
"""
class C {
    void Bar() {
        var goo = "now"
                  + "is"
                  + "the"
                  + "time";
    }
}
""");
    }
 
    [Fact]
    public async Task TestUnderscoreName_End()
    {
        await TestEndOfLine(
            """
            class C {
                void Bar() {
                    if ([||]i is var _ && _ != null) {
                    }
                }
            }
            """,
            """
            class C {
                void Bar() {
                    if (i is var _ &&
                        _ != null) {
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestUnderscoreName_Beginning()
    {
        await TestBeginningOfLine(
            """
            class C {
                void Bar() {
                    if ([||]i is var _ && _ != null) {
                    }
                }
            }
            """,
            """
            class C {
                void Bar() {
                    if (i is var _
                        && _ != null) {
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestInField_Already_Wrapped_Beginning()
    {
        await TestAllWrappingCasesAsync(
            """
            class C {
                bool v =
                    [||]a && b && c;
            }
            """,
BeginningOfLine,
"""
class C {
    bool v =
        a
        && b
        && c;
}
""");
    }
 
    [Fact]
    public async Task TestInField_Already_Wrapped_End()
    {
        await TestAllWrappingCasesAsync(
            """
            class C {
                bool v =
                    [||]a && b && c;
            }
            """,
EndOfLine,
"""
class C {
    bool v =
        a &&
        b &&
        c;
}
""");
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/34127")]
    public async Task TestWrapLowerPrecedenceInLargeBinary()
    {
        await TestAllWrappingCasesAsync(
            """
            class C
            {
                bool v = [||]a + b + c + d == x * y * z;
            }
            """,
EndOfLine,
"""
class C
{
    bool v = a + b + c + d ==
        x * y * z;
}
""",
"""
class C
{
    bool v = a + b + c + d ==
             x * y * z;
}
""");
    }
}