File: MakeLocalFunctionStatic\PassInCapturedVariablesAsArgumentsCodeFixProviderTests.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.
 
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.MakeLocalFunctionStatic;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
using Xunit.Abstractions;
 
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.MakeLocalFunctionStatic;
 
[Trait(Traits.Feature, Traits.Features.CodeActionsMakeLocalFunctionStatic)]
public class PassInCapturedVariablesAsArgumentsCodeFixProviderTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest_NoEditor
{
    public PassInCapturedVariablesAsArgumentsCodeFixProviderTests(ITestOutputHelper logger)
      : base(logger)
    {
    }
 
    internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace)
        => (null, new PassInCapturedVariablesAsArgumentsCodeFixProvider());
 
    private static readonly ParseOptions CSharp72ParseOptions = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7_2);
    private static readonly ParseOptions CSharp8ParseOptions = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8);
 
    [Fact]
    public async Task TestMissingInCSharp7()
    {
        await TestMissingAsync(
            """
            class C
            {
                int N(int x)
                {
                    return AddLocal();
 
                    static int AddLocal()
                    {
                        return [||]x + 1;
                    }        
                }
            }
            """, parameters: new TestParameters(parseOptions: CSharp72ParseOptions));
    }
 
    [Fact]
    public async Task TestMissingIfNoDiagnostic()
    {
        await TestMissingAsync(
            """
            class C
            {
                int N(int x)
                {
                    return AddLocal();
 
                    int AddLocal()
                    {
                        return [||]x + 1;
                    }        
                }
            }
            """, parameters: new TestParameters(parseOptions: CSharp8ParseOptions));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/38734")]
    public async Task TestAvailableIfCapturesThisParameter1()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int y = 0;
 
                int N(int x)
                {
                    return AddLocal();
 
                    static int AddLocal()
                    {
                        return [||]x + y;
                    }
                }
            }
            """,
            """
            class C
            {
                int y = 0;
 
                int N(int x)
                {
                    return AddLocal(this, x);
 
                    static int AddLocal(C @this, int x)
                    {
                        return x + @this.y;
                    }
                }
            }
            """, parseOptions: CSharp8ParseOptions);
    }
 
    [Fact]
    public async Task ShouldTriggerForCSharp8()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int N(int x)
                {
                    return AddLocal();
 
                    static int AddLocal()
                    {
                        return [||]x + 1;
                    }
                }  
            }
            """,
            """
            class C
            {
                int N(int x)
                {
                    return AddLocal(x);
 
                    static int AddLocal(int x)
                    {
                        return x + 1;
                    }
                }  
            }
            """,
parseOptions: CSharp8ParseOptions);
    }
 
    [Fact]
    public async Task TestMultipleVariables()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int N(int x)
                {
                    int y = 10;
                    return AddLocal();
 
                    static int AddLocal()
                    {
                        return x + [||]y;
                    }
                }
            }
            """,
            """
            class C
            {
                int N(int x)
                {
                    int y = 10;
                    return AddLocal(x, y);
 
                    static int AddLocal(int x, int y)
                    {
                        return x + y;
                    }
                }
            }
            """, parseOptions: CSharp8ParseOptions);
    }
 
    [Fact]
    public async Task TestMultipleCalls()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int N(int x)
                {
                    int y = 10;
                    return AddLocal() + AddLocal();
 
                    static int AddLocal()
                    {
                        return [||]x + y;
                    }
                }
            }
            """,
            """
            class C
            {
                int N(int x)
                {
                    int y = 10;
                    return AddLocal(x, y) + AddLocal(x, y);
 
                    static int AddLocal(int x, int y)
                    {
                        return x + y;
                    }
                }
            }
            """
, parseOptions: CSharp8ParseOptions);
    }
 
    [Fact]
    public async Task TestMultipleCallsWithExistingParameters()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int N(int x)
                {
                    int y = 10;
                    var m = AddLocal(1, 2);
                    return AddLocal(m, m);
 
                    static int AddLocal(int a, int b)
                    {
                        return a + b + [||]x + y;
                    }
                }
            }
            """,
            """
            class C
            {
                int N(int x)
                {
                    int y = 10;
                    var m = AddLocal(1, 2, x, y);
                    return AddLocal(m, m, x, y);
 
                    static int AddLocal(int a, int b, int x, int y)
                    {
                        return a + b + x + y;
                    }
                }
            }
            """
, parseOptions: CSharp8ParseOptions);
    }
 
    [Fact]
    public async Task TestRecursiveCall()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int N(int x)
                {
                    int y = 10;
                    var m = AddLocal(1, 2);
                    return AddLocal(m, m);
 
                    static int AddLocal(int a, int b)
                    {
                        return AddLocal(a, b) + [||]x + y;
                    }
                }
            }
            """,
            """
            class C
            {
                int N(int x)
                {
                    int y = 10;
                    var m = AddLocal(1, 2, x, y);
                    return AddLocal(m, m, x, y);
 
                    static int AddLocal(int a, int b, int x, int y)
                    {
                        return AddLocal(a, b, x, y) + x + y;
                    }
                }
            }
            """, parseOptions: CSharp8ParseOptions);
    }
 
    [Fact]
    public async Task TestCallInArgumentList()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int N(int x)
                {
                    int y = 10;
                    return AddLocal(AddLocal(1, 2), AddLocal(3, 4));
 
                    static int AddLocal(int a, int b)
                    {
                        return AddLocal(a, b) + [||]x + y;
                    }
                }
            }
            """,
            """
            class C
            {
                int N(int x)
                {
                    int y = 10;
                    return AddLocal(AddLocal(1, 2, x, y), AddLocal(3, 4, x, y), x, y);
 
                    static int AddLocal(int a, int b, int x, int y)
                    {
                        return AddLocal(a, b, x, y) + x + y;
                    }
                }
            }
            """, parseOptions: CSharp8ParseOptions);
    }
 
    [Fact]
    public async Task TestCallsWithNamedArguments()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int N(int x)
                {
                    int y = 10;
                    var m = AddLocal(1, b: 2);
                    return AddLocal(b: m, a: m);
 
                    static int AddLocal(int a, int b)
                    {
                        return a + b + [||]x + y;
                    }
                }
            }
            """,
            """
            class C
            {
                int N(int x)
                {
                    int y = 10;
                    var m = AddLocal(1, b: 2, x: x, y: y);
                    return AddLocal(b: m, a: m, x: x, y: y);
 
                    static int AddLocal(int a, int b, int x, int y)
                    {
                        return a + b + x + y;
                    }
                }
            }
            """
, parseOptions: CSharp8ParseOptions);
    }
 
    [Fact]
    public async Task TestCallsWithDafaultValue()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int N(int x)
                {
                    string y = ";
                    var m = AddLocal(1);
                    return AddLocal(b: m);
 
                    static int AddLocal(int a = 0, int b = 0)
                    {
                        return a + b + x + [||]y.Length;
                    }
                }
            }
            """,
            """
            class C
            {
                int N(int x)
                {
                    string y = ";
                    var m = AddLocal(1, x: x, y: y);
                    return AddLocal(b: m, x: x, y: y);
 
                    static int AddLocal(int a = 0, int b = 0, int x = 0, string y = null)
                    {
                        return a + b + x + y.Length;
                    }
                }
            }
            """
, parseOptions: CSharp8ParseOptions);
    }
 
    [Fact]
    public async Task TestWarningAnnotation()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                void N(int x)
                {
                    Func<int> del = AddLocal;
 
                    static int AddLocal()
                    {
                        return [||]x + 1;
                    }
                }  
            }
            """,
            """
            class C
            {
                void N(int x)
                {
                    Func<int> del = AddLocal;
 
                    {|Warning:static int AddLocal(int x)
                    {
                        return x + 1;
                    }|}
                }  
            }
            """,
parseOptions: CSharp8ParseOptions);
    }
 
    [Fact]
    public async Task TestNonCamelCaseCapture()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int N(int x)
                {
                    int Static = 0;
                    return AddLocal();
 
                    static int AddLocal()
                    {
                        return [||]Static + 1;
                    }
                }  
            }
            """,
            """
            class C
            {
                int N(int x)
                {
                    int Static = 0;
                    return AddLocal(Static);
 
                    static int AddLocal(int @static)
                    {
                        return @static + 1;
                    }
                }  
            }
            """,
parseOptions: CSharp8ParseOptions);
    }
 
    [Fact]
    public async Task TestFixAll()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                int M(int x)
                {
                    int y = 10;
                    var m = AddLocal(1, 2);
                    return AddLocal(m, m);
 
                    static int AddLocal(int a, int b)
                    {
                        return a + b + x + y;
                    }
                }
 
                int N(int x)
                {
                    int y = 10;
                    return AddLocal(AddLocal(1, 2), AddLocal(3, 4));
 
                    static int AddLocal(int a, int b)
                    {
                        return AddLocal(a, b) + {|FixAllInDocument:|}x + y;
                    }
                }
            }
            """,
            """
            class C
            {
                int M(int x)
                {
                    int y = 10;
                    var m = AddLocal(1, 2, x, y);
                    return AddLocal(m, m, x, y);
 
                    static int AddLocal(int a, int b, int x, int y)
                    {
                        return a + b + x + y;
                    }
                }
 
                int N(int x)
                {
                    int y = 10;
                    return AddLocal(AddLocal(1, 2, x, y), AddLocal(3, 4, x, y), x, y);
 
                    static int AddLocal(int a, int b, int x, int y)
                    {
                        return AddLocal(a, b, x, y) + x + y;
                    }
                }
            }
            """, parseOptions: CSharp8ParseOptions);
    }
}