File: SplitOrMergeIfStatements\MergeNestedIfStatementsTests_WithNested.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 Roslyn.Test.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.SplitOrMergeIfStatements;
 
public sealed partial class MergeNestedIfStatementsTests
{
    [Fact]
    public Task MergedOnOuterIf()
        => TestInRegularAndScriptAsync(
            """
            class C
            {
                void M(bool a, bool b)
                {
                    [||]if (a)
                    {
                        if (b)
                        {
                        }
                    }
                }
            }
            """,
            """
            class C
            {
                void M(bool a, bool b)
                {
                    if (a && b)
                    {
                    }
                }
            }
            """);
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/55563")]
    public Task MergedOnOuterIf_TopLevelStatements()
        => TestInRegularAndScriptAsync(
            """
            var a = true;
            var b = true;
 
            [||]if (a)
            {
                if (b)
                {
                }
            }
 
            """,
            """
            var a = true;
            var b = true;
 
            if (a && b)
            {
            }
 
            """);
 
    [Theory]
    [InlineData("[||]else if (a)")]
    [InlineData("el[||]se if (a)")]
    [InlineData("else[||] if (a)")]
    [InlineData("else [||]if (a)")]
    [InlineData("else i[||]f (a)")]
    [InlineData("else if[||] (a)")]
    [InlineData("else if [||](a)")]
    [InlineData("else if (a)[||]")]
    [InlineData("else [|if|] (a)")]
    [InlineData("else [|if (a)|]")]
    [InlineData("[|else if (a)|]")]
    public Task MergedOnOuterElseIfSpans(string elseIfLine)
        => TestInRegularAndScriptAsync(
            """
            class C
            {
                void M(bool a, bool b)
                {
                    if (true)
                    {
                    }
                    
            """ + elseIfLine + """
 
                    {
                        if (b)
                        {
                        }
                    }
                }
            }
            """,
            """
            class C
            {
                void M(bool a, bool b)
                {
                    if (true)
                    {
                    }
                    else if (a && b)
                    {
                    }
                }
            }
            """);
 
    [Fact]
    public Task MergedOnOuterElseIfExtendedHeaderSelection()
        => TestInRegularAndScriptAsync(
            """
            class C
            {
                void M(bool a, bool b)
                {
                    if (true)
                    {
                    }
            [|        else if (a)
            |]        {
                        if (b)
                        {
                        }
                    }
                }
            }
            """,
            """
            class C
            {
                void M(bool a, bool b)
                {
                    if (true)
                    {
                    }
                    else if (a && b)
                    {
                    }
                }
            }
            """);
 
    [Fact]
    public Task MergedOnOuterElseIfFullSelection()
        => TestInRegularAndScriptAsync(
            """
            class C
            {
                void M(bool a, bool b)
                {
                    if (true)
                    {
                    }
            [|        else if (a)
                    {
                        if (b)
                        {
                        }
                    }
            |]    }
            }
            """,
            """
            class C
            {
                void M(bool a, bool b)
                {
                    if (true)
                    {
                    }
                    else if (a && b)
                    {
                    }
                }
            }
            """);
 
    [Fact]
    public Task MergedOnOuterElseIfFullSelectionWithElseClause()
        => TestInRegularAndScriptAsync(
            """
            class C
            {
                void M(bool a, bool b)
                {
                    if (true)
                    {
                    }
                    [|else if (a)
                    {
                        if (b)
                        {
                        }
                        else
                        {
                        }
                    }
                    else
                    {
                    }|]
                }
            }
            """,
            """
            class C
            {
                void M(bool a, bool b)
                {
                    if (true)
                    {
                    }
                    else if (a && b)
                    {
                    }
                    else
                    {
                    }
                }
            }
            """);
 
    [Fact]
    public Task NotMergedOnOuterElseIfFullSelectionWithoutElseClause()
        => TestMissingInRegularAndScriptAsync(
            """
            class C
            {
                void M(bool a, bool b)
                {
                    if (true)
                    {
                    }
                    [|else if (a)
                    {
                        if (b)
                        {
                        }
                        else
                        {
                        }
                    }|]
                    else
                    {
                    }
                }
            }
            """);
 
    [Fact]
    public Task NotMergedOnOuterElseIfFullSelectionWithParentIf()
        => TestMissingInRegularAndScriptAsync(
            """
            class C
            {
                void M(bool a, bool b)
                {
                    [|if (true)
                    {
                    }
                    else if (a)
                    {
                        if (b)
                        {
                        }
                        else
                        {
                        }
                    }
                    else
                    {
                    }|]
                }
            }
            """);
 
    [Theory]
    [InlineData("else if ([||]a)")]
    [InlineData("[|el|]se if (a)")]
    [InlineData("[|else|] if (a)")]
    [InlineData("[|else if|] (a)")]
    [InlineData("else [|i|]f (a)")]
    [InlineData("else [|if (|]a)")]
    [InlineData("else if [|(|]a)")]
    [InlineData("else if (a[|)|]")]
    [InlineData("else if ([|a|])")]
    [InlineData("else if [|(a)|]")]
    public Task NotMergedOnOuterElseIfSpans(string elseIfLine)
        => TestMissingInRegularAndScriptAsync(
            """
            class C
            {
                void M(bool a, bool b)
                {
                    if (true)
                    {
                    }
                    
            """ + elseIfLine + """
 
                    {
                        if (b)
                        {
                        }
                    }
                }
            }
            """);
 
    [Fact]
    public Task NotMergedOnOuterElseIfOverreachingSelection1()
        => TestMissingInRegularAndScriptAsync(
            """
            class C
            {
                void M(bool a, bool b)
                {
                    if (true)
                    {
                    }
                    [|else if (a)
                    |]{
                        if (b)
                        {
                        }
                    }
                }
            }
            """);
 
    [Fact]
    public Task NotMergedOnOuterElseIfOverreachingSelection2()
        => TestMissingInRegularAndScriptAsync(
            """
            class C
            {
                void M(bool a, bool b)
                {
                    if (true)
                    {
                    }
                    [|else if (a)
                    {|]
                        if (b)
                        {
                        }
                    }
                }
            }
            """);
 
    [Fact]
    public Task NotMergedOnOuterElseIfBodySelection()
        => TestMissingInRegularAndScriptAsync(
            """
            class C
            {
                void M(bool a, bool b)
                {
                    if (true)
                    {
                    }
                    else if (a)
                    [|{
                        if (b)
                        {
                        }
                    }|]
                }
            }
            """);
 
    [Fact]
    public Task NotMergedOnOuterElseIfBodyCaret1()
        => TestMissingInRegularAndScriptAsync(
            """
            class C
            {
                void M(bool a, bool b)
                {
                    if (true)
                    {
                    }
                    else if (a)
                    [||]{
                        if (b)
                        {
                        }
                    }
                }
            }
            """);
 
    [Fact]
    public Task NotMergedOnOuterElseIfBodyCaret2()
        => TestMissingInRegularAndScriptAsync(
            """
            class C
            {
                void M(bool a, bool b)
                {
                    if (true)
                    {
                    }
                    else if (a)
                    {
                        if (b)
                        {
                        }
                    }[||]
                }
            }
            """);
 
    [Fact]
    public async Task MergedOnMiddleIfMergableWithNestedOnly()
    {
        const string Initial =
            """
            class C
            {
                void M(bool a, bool b, bool c)
                {
                    if (a)
                    {
                        [||]if (b)
                        {
                            if (c)
                            {
                                System.Console.WriteLine();
                            }
                        }
 
                        return;
                    }
                }
            }
            """;
        await TestActionCountAsync(Initial, 1);
        await TestInRegularAndScriptAsync(Initial, """
            class C
            {
                void M(bool a, bool b, bool c)
                {
                    if (a)
                    {
                        if (b && c)
                        {
                            System.Console.WriteLine();
                        }
 
                        return;
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task MergedOnMiddleIfMergableWithOuterOnly()
    {
        const string Initial =
            """
            class C
            {
                void M(bool a, bool b, bool c)
                {
                    if (a)
                    {
                        [||]if (b)
                        {
                            if (c)
                            {
                                System.Console.WriteLine();
                            }
 
                            return;
                        }
                    }
                }
            }
            """;
        await TestActionCountAsync(Initial, 1);
        await TestInRegularAndScriptAsync(Initial, """
            class C
            {
                void M(bool a, bool b, bool c)
                {
                    if (a && b)
                    {
                        if (c)
                        {
                            System.Console.WriteLine();
                        }
 
                        return;
                    }
                }
            }
            """);
    }
 
    [Fact]
    public async Task MergedOnMiddleIfMergableWithBoth()
    {
        const string Initial =
            """
            class C
            {
                void M(bool a, bool b, bool c)
                {
                    if (a)
                    {
                        [||]if (b)
                        {
                            if (c)
                            {
                                System.Console.WriteLine();
                            }
                        }
                    }
                }
            }
            """;
        await TestActionCountAsync(Initial, 2);
        await TestInRegularAndScriptAsync(Initial, """
            class C
            {
                void M(bool a, bool b, bool c)
                {
                    if (a && b)
                    {
                        if (c)
                        {
                            System.Console.WriteLine();
                        }
                    }
                }
            }
            """, index: 0);
        await TestInRegularAndScriptAsync(Initial, """
            class C
            {
                void M(bool a, bool b, bool c)
                {
                    if (a)
                    {
                        if (b && c)
                        {
                            System.Console.WriteLine();
                        }
                    }
                }
            }
            """, index: 1);
    }
}