File: CodeActions\InitializeParameter\InitializeMemberFromParameterTests.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.
 
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeRefactorings;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.Formatting;
using Microsoft.CodeAnalysis.CSharp.InitializeParameter;
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings;
using Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics.NamingStyles;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.InitializeParameter;
 
[Trait(Traits.Feature, Traits.Features.CodeActionsInitializeParameter)]
public partial class InitializeMemberFromParameterTests : AbstractCSharpCodeActionTest
{
    protected override CodeRefactoringProvider CreateCodeRefactoringProvider(EditorTestWorkspace workspace, TestParameters parameters)
        => new CSharpInitializeMemberFromParameterCodeRefactoringProvider();
 
    private readonly NamingStylesTestOptionSets options = new NamingStylesTestOptionSets(LanguageNames.CSharp);
 
    [Fact]
    public async Task TestInitializeFieldWithSameName()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private string s;
 
                public C([||]string s)
                {
                }
            }
            """,
            """
            class C
            {
                private string s;
 
                public C(string s)
                {
                    this.s = s;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestEndOfParameter1()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private string s;
 
                public C(string s[||])
                {
                }
            }
            """,
            """
            class C
            {
                private string s;
 
                public C(string s)
                {
                    this.s = s;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestEndOfParameter2()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private string s;
 
                public C(string s[||], string t)
                {
                }
            }
            """,
            """
            class C
            {
                private string s;
 
                public C(string s, string t)
                {
                    this.s = s;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestInitializeFieldWithUnderscoreName()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private string _s;
 
                public C([||]string s)
                {
                }
            }
            """,
            """
            class C
            {
                private string _s;
 
                public C(string s)
                {
                    _s = s;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestInitializeWritableProperty()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private string S { get; }
 
                public C([||]string s)
                {
                }
            }
            """,
            """
            class C
            {
                private string S { get; }
 
                public C(string s)
                {
                    S = s;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestInitializeFieldWithDifferentName()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                private string t;
 
                public C([||]string s)
                {
                }
            }
            """,
            """
            class C
            {
                private string t;
 
                public C(string s)
                {
                    S = s;
                }
 
                public string S { get; }
            }
            """);
    }
 
    [Fact]
    public async Task TestInitializeNonWritableProperty()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private string S => null;
 
                public C([||]string s)
                {
                }
            }
            """,
            """
            class C
            {
                private string S => null;
 
                public string S1 { get; }
 
                public C(string s)
                {
                    S1 = s;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestInitializeDoesNotUsePropertyWithUnrelatedName()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                private string T { get; }
 
                public C([||]string s)
                {
                }
            }
            """,
            """
            class C
            {
                private string T { get; }
                public string S { get; }
 
                public C(string s)
                {
                    S = s;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestInitializeFieldWithWrongType1()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private int s;
 
                public C([||]string s)
                {
                }
            }
            """,
            """
            class C
            {
                private int s;
 
                public C(string s)
                {
                    S = s;
                }
 
                public string S { get; }
            }
            """);
    }
 
    [Fact]
    public async Task TestInitializeFieldWithWrongType2()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private int s;
 
                public C([||]string s)
                {
                }
            }
            """,
            """
            class C
            {
                private readonly string s1;
                private int s;
 
                public C(string s)
                {
                    s1 = s;
                }
            }
            """, index: 1);
    }
 
    [Fact]
    public async Task TestInitializeFieldWithConvertibleType()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                private object s;
 
                public C([||]string s)
                {
                }
            }
            """,
            """
            class C
            {
                private object s;
 
                public C(string s)
                {
                    this.s = s;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestWhenAlreadyInitialized1()
    {
        await TestMissingInRegularAndScriptAsync(
            """
            class C
            {
                private int s;
                private int x;
 
                public C([||]string s)
                {
                    x = s;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestWhenAlreadyInitialized2()
    {
        await TestMissingInRegularAndScriptAsync(
            """
            class C
            {
                private int s;
                private int x;
 
                public C([||]string s)
                {
                    x = s ?? throw new Exception();
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestWhenAlreadyInitialized3()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private int s;
 
                public C([||]string s)
                {
                    s = 0;
                }
            }
            """,
 
            """
            class C
            {
                private int s;
 
                public C([||]string s)
                {
                    s = 0;
                    S = s;
                }
 
                public string S { get; }
            }
            """);
    }
 
    [Fact]
    public async Task TestInsertionLocation1()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private string s;
                private string t;
 
                public C([||]string s, string t)
                {
                    this.t = t;   
                }
            }
            """,
            """
            class C
            {
                private string s;
                private string t;
 
                public C(string s, string t)
                {
                    this.s = s;
                    this.t = t;   
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestInsertionLocation2()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private string s;
                private string t;
 
                public C(string s, [||]string t)
                {
                    this.s = s;   
                }
            }
            """,
            """
            class C
            {
                private string s;
                private string t;
 
                public C(string s, string t)
                {
                    this.s = s;
                    this.t = t;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestInsertionLocation3()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private string s;
 
                public C([||]string s)
                {
                    if (true) { } 
                }
            }
            """,
            """
            class C
            {
                private string s;
 
                public C(string s)
                {
                    if (true) { }
 
                    this.s = s;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestNotInMethod()
    {
        await TestMissingInRegularAndScriptAsync(
            """
            class C
            {
                private string s;
 
                public void M([||]string s)
                {
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestInsertionLocation4()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private string s;
                private string t;
 
                public C(string s, [||]string t)
                    => this.s = s;   
            }
            """,
            """
            class C
            {
                private string s;
                private string t;
 
                public C(string s, string t)
                {
                    this.s = s;
                    this.t = t;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestInsertionLocation5()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private string s;
                private string t;
 
                public C([||]string s, string t)
                    => this.t = t;   
            }
            """,
            """
            class C
            {
                private string s;
                private string t;
 
                public C(string s, string t)
                {
                    this.s = s;
                    this.t = t;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestInsertionLocation6()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                public C(string s, [||]string t)
                {
                    S = s;   
                }
 
                public string S { get; }
            }
            """,
            """
            class C
            {
                public C(string s, string t)
                {
                    S = s;
                    T = t;
                }
 
                public string S { get; }
                public string T { get; }
            }
            """);
    }
 
    [Fact]
    public async Task TestInsertionLocation7()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                public C([||]string s, string t)
                {
                    T = t;   
                }
 
                public string T { get; }
            }
            """,
            """
            class C
            {
                public C(string s, string t)
                {
                    S = s;
                    T = t;   
                }
 
                public string S { get; }
                public string T { get; }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/19956")]
    public async Task TestNoBlock()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private string s;
 
                public C(string s[||])
            }
            """,
            """
            class C
            {
                private string s;
 
                public C(string s)
                {
                    this.s = s;
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29190")]
    public async Task TestInitializeFieldWithParameterNameSelected1()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private string s;
 
                public C(string [|s|])
                {
                }
            }
            """,
            """
            class C
            {
                private string s;
 
                public C(string s)
                {
                    this.s = s;
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/29190")]
    public async Task TestInitializeField_ParameterNameSelected2()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private string s;
 
                public C(string [|s|], int i)
                {
                }
            }
            """,
            """
            class C
            {
                private string s;
 
                public C(string s, int i)
                {
                    this.s = s;
                }
            }
            """);
    }
 
    [Fact]
    public async Task TestInitializeClassProperty_RequiredAccessibilityOmitIfDefault()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                readonly int test = 5;
 
                public C(int test, int [|test2|])
                {
                }
            }
            """,
            """
            class C
            {
                readonly int test = 5;
 
                public C(int test, int test2)
                {
                    Test2 = test2;
                }
 
                public int Test2 { get; }
            }
            """, index: 0, parameters: OmitIfDefault_Warning);
    }
 
    [Fact]
    public async Task TestInitializeClassProperty_RequiredAccessibilityNever()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                readonly int test = 5;
 
                public C(int test, int [|test2|])
                {
                }
            }
            """,
            """
            class C
            {
                readonly int test = 5;
 
                public C(int test, int test2)
                {
                    Test2 = test2;
                }
 
                public int Test2 { get; }
            }
            """, index: 0, parameters: Never_Warning);
    }
 
    [Fact]
    public async Task TestInitializeClassProperty_RequiredAccessibilityAlways()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                readonly int test = 5;
 
                public C(int test, int [|test2|])
                {
                }
            }
            """,
            """
            class C
            {
                readonly int test = 5;
 
                public C(int test, int test2)
                {
                    Test2 = test2;
                }
 
                public int Test2 { get; }
            }
            """, index: 0, parameters: Always_Warning);
    }
 
    [Fact]
    public async Task TestInitializeClassField_RequiredAccessibilityOmitIfDefault()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                readonly int test = 5;
 
                public C(int test, int [|test2|])
                {
                }
            }
            """,
            """
            class C
            {
                readonly int test = 5;
                readonly int test2;
 
                public C(int test, int test2)
                {
                    this.test2 = test2;
                }
            }
            """, index: 1, parameters: OmitIfDefault_Warning);
    }
 
    [Fact]
    public async Task TestInitializeClassField_RequiredAccessibilityNever()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                readonly int test = 5;
 
                public C(int test, int [|test2|])
                {
                }
            }
            """,
            """
            class C
            {
                readonly int test = 5;
                readonly int test2;
 
                public C(int test, int test2)
                {
                    this.test2 = test2;
                }
            }
            """, index: 1, parameters: Never_Warning);
    }
 
    [Fact]
    public async Task TestInitializeClassField_RequiredAccessibilityAlways()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                readonly int test = 5;
 
                public C(int test, int [|test2|])
                {
                }
            }
            """,
            """
            class C
            {
                readonly int test = 5;
                private readonly int test2;
 
                public C(int test, int test2)
                {
                    this.test2 = test2;
                }
            }
            """, index: 1, parameters: Always_Warning);
    }
 
    [Fact]
    public async Task TestInitializeStructProperty_RequiredAccessibilityOmitIfDefault()
    {
        await TestInRegularAndScript1Async(
            """
            struct S
            {
                public Test(int [|test|])
                {
                }
            }
            """,
            """
            struct S
            {
                public Test(int test)
                {
                    Test = test;
                }
 
                public int Test { get; }
            }
            """, index: 0, parameters: OmitIfDefault_Warning);
    }
 
    [Fact]
    public async Task TestInitializeStructProperty_RequiredAccessibilityNever()
    {
        await TestInRegularAndScript1Async(
            """
            struct S
            {
                public Test(int [|test|])
                {
                }
            }
            """,
            """
            struct S
            {
                public Test(int test)
                {
                    Test = test;
                }
 
                public int Test { get; }
            }
            """, index: 0, parameters: Never_Warning);
    }
 
    [Fact]
    public async Task TestInitializeStructProperty_RequiredAccessibilityAlways()
    {
        await TestInRegularAndScript1Async(
            """
            struct S
            {
                public Test(int [|test|])
                {
                }
            }
            """,
            """
            struct S
            {
                public Test(int test)
                {
                    Test = test;
                }
 
                public int Test { get; }
            }
            """, index: 0, parameters: Always_Warning);
    }
 
    [Fact]
    public async Task TestInitializeStructField_RequiredAccessibilityOmitIfDefault()
    {
        await TestInRegularAndScript1Async(
            """
            struct S
            {
                public Test(int [|test|])
                {
                }
            }
            """,
            """
            struct S
            {
                readonly int test;
 
                public Test(int test)
                {
                    this.test = test;
                }
            }
            """, index: 1, parameters: OmitIfDefault_Warning);
    }
 
    [Fact]
    public async Task TestInitializeStructField_RequiredAccessibilityNever()
    {
        await TestInRegularAndScript1Async(
            """
            struct S
            {
                public Test(int [|test|])
                {
                }
            }
            """,
            """
            struct S
            {
                readonly int test;
 
                public Test(int test)
                {
                    this.test = test;
                }
            }
            """, index: 1, parameters: Never_Warning);
    }
 
    [Fact]
    public async Task TestInitializeStructField_RequiredAccessibilityAlways()
    {
        await TestInRegularAndScript1Async(
            """
            struct S
            {
                public Test(int [|test|])
                {
                }
            }
            """,
            """
            struct S
            {
                private readonly int test;
 
                public Test(int test)
                {
                    this.test = test;
                }
            }
            """, index: 1, parameters: Always_Warning);
    }
 
    [Fact]
    public async Task TestNoParameterNamingStyle_CreateAndInitField()
    {
        await TestInRegularAndScript1Async(
"""
class C
{
    public C([||]string s)
    {
    }
}
""",
"""
class C
{
    private readonly string _s;
 
    public C(string s)
    {
        _s = s;
    }
}
""", index: 1, parameters: new TestParameters(options: options.FieldNamesAreCamelCaseWithUnderscorePrefix));
    }
 
    [Fact]
    public async Task TestCommonParameterNamingStyle_CreateAndInitField()
    {
        await TestInRegularAndScript1Async(
"""
class C
{
    public C([||]string t_s)
    {
    }
}
""",
"""
class C
{
    private readonly string _s;
 
    public C(string t_s)
    {
        _s = t_s;
    }
}
""", index: 1, parameters: new TestParameters(options: options.FieldNamesAreCamelCaseWithUnderscorePrefix));
    }
 
    [Fact]
    public async Task TestSpecifiedParameterNamingStyle_CreateAndInitField()
    {
        await TestInRegularAndScript1Async(
"""
class C
{
    public C([||]string p_s_End)
    {
    }
}
""",
"""
class C
{
    private readonly string _s;
 
    public C(string p_s_End)
    {
        _s = p_s_End;
    }
}
""", index: 1, parameters: new TestParameters(options: options.MergeStyles(options.FieldNamesAreCamelCaseWithUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix)));
    }
 
    [Fact]
    public async Task TestCommonAndSpecifiedParameterNamingStyle_CreateAndInitField()
    {
        await TestInRegularAndScript1Async(
"""
class C
{
    public C([||]string t_p_s_End)
    {
    }
}
""",
"""
class C
{
    private readonly string _s;
 
    public C(string t_p_s_End)
    {
        _s = t_p_s_End;
    }
}
""", index: 1, parameters: new TestParameters(options: options.MergeStyles(options.FieldNamesAreCamelCaseWithUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix)));
    }
 
    [Fact]
    public async Task TestCommonAndSpecifiedParameterNamingStyle2_CreateAndInitField()
    {
        await TestInRegularAndScript1Async(
"""
class C
{
    public C([||]string p_t_s)
    {
    }
}
""",
    """
    class C
    {
        private readonly string _s;
 
        public C([||]string p_t_s)
        {
            _s = p_t_s;
        }
    }
    """, index: 1, parameters: new TestParameters(options: options.MergeStyles(options.FieldNamesAreCamelCaseWithUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefix)));
    }
 
    [Fact]
    public async Task TestNoParameterNamingStyle_CreateAndInitProperty()
    {
        await TestInRegularAndScript1Async(
"""
class C
{
    public C([||]string s)
    {
    }
}
""",
"""
class C
{
    public C(string s)
    {
        S = s;
    }
 
    public string S { get; }
}
""", parameters: new TestParameters(options: options.PropertyNamesArePascalCase));
    }
 
    [Fact]
    public async Task TestCommonParameterNamingStyle_CreateAndInitProperty()
    {
        await TestInRegularAndScript1Async(
"""
class C
{
    public C([||]string t_s)
    {
    }
}
""",
"""
class C
{
    public C(string t_s)
    {
        S = t_s;
    }
 
    public string S { get; }
}
""", parameters: new TestParameters(options: options.PropertyNamesArePascalCase));
    }
 
    [Fact]
    public async Task TestSpecifiedParameterNamingStyle_CreateAndInitProperty()
    {
        await TestInRegularAndScript1Async(
"""
class C
{
    public C([||]string p_s_End)
    {
    }
}
""",
"""
class C
{
    public C(string p_s_End)
    {
        S = p_s_End;
    }
 
    public string S { get; }
}
""", parameters: new TestParameters(options: options.MergeStyles(options.PropertyNamesArePascalCase, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix)));
    }
 
    [Fact]
    public async Task TestCommonAndSpecifiedParameterNamingStyle_CreateAndInitProperty()
    {
        await TestInRegularAndScript1Async(
"""
class C
{
    public C([||]string t_p_s_End)
    {
    }
}
""",
"""
class C
{
    public C(string t_p_s_End)
    {
        S = t_p_s_End;
    }
 
    public string S { get; }
}
""", parameters: new TestParameters(options: options.MergeStyles(options.PropertyNamesArePascalCase, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix)));
    }
 
    [Fact]
    public async Task TestCommonAndSpecifiedParameterNamingStyle2_CreateAndInitProperty()
    {
        await TestInRegularAndScript1Async(
"""
class C
{
    public C([||]string p_t_s_End)
    {
    }
}
""",
    """
    class C
    {
        public C([||]string p_t_s_End)
        {
            S = p_t_s_End;
        }
 
        public string S { get; }
    }
    """, parameters: new TestParameters(options: options.MergeStyles(options.PropertyNamesArePascalCase, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix)));
    }
 
    [Fact]
    public async Task TestNoParameterNamingStyle_InitializeField()
    {
        await TestInRegularAndScript1Async(
"""
class C
{
    private readonly string _s;
 
    public C([||]string s)
    {
    }
}
""",
"""
class C
{
    private readonly string _s;
 
    public C(string s)
    {
        _s = s;
    }
}
""", index: 0, parameters: new TestParameters(options: options.FieldNamesAreCamelCaseWithUnderscorePrefix));
    }
 
    [Fact]
    public async Task TestCommonParameterNamingStyle_InitializeField()
    {
        await TestInRegularAndScript1Async(
"""
class C
{
    private readonly string _s;
 
    public C([||]string t_s)
    {
    }
}
""",
"""
class C
{
    private readonly string _s;
 
    public C(string t_s)
    {
        _s = t_s;
    }
}
""", index: 0, parameters: new TestParameters(options: options.FieldNamesAreCamelCaseWithUnderscorePrefix));
    }
 
    [Fact]
    public async Task TestSpecifiedParameterNamingStyle_InitializeField()
    {
        await TestInRegularAndScript1Async(
"""
class C
{
    private readonly string _s;
 
    public C([||]string p_s_End)
    {
    }
}
""",
"""
class C
{
    private readonly string _s;
 
    public C(string p_s_End)
    {
        _s = p_s_End;
    }
}
""", index: 0, parameters: new TestParameters(options: options.MergeStyles(options.FieldNamesAreCamelCaseWithUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix)));
    }
 
    [Fact]
    public async Task TestCommonAndSpecifiedParameterNamingStyle_InitializeField()
    {
        await TestInRegularAndScript1Async(
"""
class C
{
    private readonly string _s;
 
    public C([||]string t_p_s_End)
    {
    }
}
""",
"""
class C
{
    private readonly string _s;
 
    public C(string t_p_s_End)
    {
        _s = t_p_s_End;
    }
}
""", index: 0, parameters: new TestParameters(options: options.MergeStyles(options.FieldNamesAreCamelCaseWithUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix)));
    }
 
    [Fact]
    public async Task TestCommonAndSpecifiedParameterNamingStyle2_InitializeField()
    {
        await TestInRegularAndScript1Async(
"""
class C
{
    private readonly string _s;
 
    public C([||]string p_t_s_End)
    {
    }
}
""",
    """
    class C
    {
        private readonly string _s;
 
        public C([||]string p_t_s_End)
        {
            _s = p_t_s_End;
        }
    }
    """, index: 0, parameters: new TestParameters(options: options.MergeStyles(options.FieldNamesAreCamelCaseWithUnderscorePrefix, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix)));
    }
 
    [Fact]
    public async Task TestNoParameterNamingStyle_InitializeProperty()
    {
        await TestInRegularAndScript1Async(
"""
class C
{
    public C([||]string s)
    {
    }
 
    public string S { get; }
}
""",
"""
class C
{
    public C(string s)
    {
        S = s;
    }
 
    public string S { get; }
}
""", parameters: new TestParameters(options: options.PropertyNamesArePascalCase));
    }
 
    [Fact]
    public async Task TestCommonParameterNamingStyle_InitializeProperty()
    {
        await TestInRegularAndScript1Async(
"""
class C
{
    public C([||]string t_s)
    {
    }
 
    public string S { get; }
}
""",
"""
class C
{
    public C(string t_s)
    {
        S = t_s;
    }
 
    public string S { get; }
}
""", parameters: new TestParameters(options: options.PropertyNamesArePascalCase));
    }
 
    [Fact]
    public async Task TestSpecifiedParameterNamingStyle_InitializeProperty()
    {
        await TestInRegularAndScript1Async(
"""
class C
{
    public C([||]string p_s_End)
    {
    }
 
    public string S { get; }
}
""",
"""
class C
{
    public C(string p_s_End)
    {
        S = p_s_End;
    }
 
    public string S { get; }
}
""", parameters: new TestParameters(options: options.MergeStyles(options.PropertyNamesArePascalCase, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix)));
    }
 
    [Fact]
    public async Task TestCommonAndSpecifiedParameterNamingStyle_InitializeProperty()
    {
        await TestInRegularAndScript1Async(
"""
class C
{
    public C([||]string t_p_s_End)
    {
    }
 
    public string S { get; }
}
""",
"""
class C
{
    public C(string t_p_s_End)
    {
        S = t_p_s_End;
    }
 
    public string S { get; }
}
""", parameters: new TestParameters(options: options.MergeStyles(options.PropertyNamesArePascalCase, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix)));
    }
 
    [Fact]
    public async Task TestCommonAndSpecifiedParameterNamingStyle2_InitializeProperty()
    {
        await TestInRegularAndScript1Async(
"""
class C
{
    public C([||]string p_t_s_End)
    {
    }
 
    public string S { get; }
}
""",
    """
    class C
    {
        public C([||]string p_t_s_End)
        {
            S = p_t_s_End;
        }
 
        public string S { get; }
    }
    """, parameters: new TestParameters(options: options.MergeStyles(options.PropertyNamesArePascalCase, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix)));
    }
 
    [Fact]
    public async Task TestBaseNameEmpty()
    {
        await TestMissingAsync(
"""
class C
{
    public C([||]string p__End)
    {
    }
 
    public string S { get; }
}
""", parameters: new TestParameters(options: options.MergeStyles(options.PropertyNamesArePascalCase, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix)));
    }
 
    [Fact]
    public async Task TestSomeBaseNamesEmpty()
    {
        // Currently, this case does not offer a refactoring because selecting multiple parameters 
        // is not supported. If multiple parameters are supported in the future, this case should 
        // be updated to verify that only the parameter name that does not have an empty base is offered.
        await TestMissingAsync(
"""
class C
{
    public C([|string p__End, string p_test_t|])
    {
    }
}
""", parameters: new TestParameters(options: options.MergeStyles(options.PropertyNamesArePascalCase, options.ParameterNamesAreCamelCaseWithPUnderscorePrefixAndUnderscoreEndSuffix)));
    }
 
    private TestParameters OmitIfDefault_Warning => new TestParameters(options: Option(CodeStyleOptions2.AccessibilityModifiersRequired, AccessibilityModifiersRequired.OmitIfDefault, NotificationOption2.Warning));
    private TestParameters Never_Warning => new TestParameters(options: Option(CodeStyleOptions2.AccessibilityModifiersRequired, AccessibilityModifiersRequired.Never, NotificationOption2.Warning));
    private TestParameters Always_Warning => new TestParameters(options: Option(CodeStyleOptions2.AccessibilityModifiersRequired, AccessibilityModifiersRequired.Always, NotificationOption2.Warning));
 
    [Fact]
    public async Task TestCreateFieldWithTopLevelNullability()
    {
        await TestInRegularAndScript1Async(
"""
#nullable enable
class C
{
    public C([||]string? s)
    {
    }
}
""",
"""
#nullable enable
class C
{
    private readonly string? _s;
 
    public C(string? s)
    {
        _s = s;
    }
}
""", index: 1, parameters: new TestParameters(options: options.FieldNamesAreCamelCaseWithUnderscorePrefix));
    }
 
    [Fact]
    public async Task TestCreatePropertyWithTopLevelNullability()
    {
        await TestInRegularAndScript1Async(
"""
#nullable enable
class C
{
    public C([||]string? s)
    {
    }
}
""",
"""
#nullable enable
class C
{
    public C(string? s)
    {
        S = s;
    }
 
    public string? S { get; }
}
""", parameters: new TestParameters(options: options.PropertyNamesArePascalCase));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24526")]
    public async Task TestSingleLineBlock_BraceOnNextLine()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                public C([||]string s) { }
            }
            """,
            """
            class C
            {
                public C(string s)
                {
                    S = s;
                }
 
                public string S { get; }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/24526")]
    public async Task TestSingleLineBlock_BraceOnSameLine()
    {
        await TestInRegularAndScriptAsync(
            """
            class C
            {
                public C([||]string s) { }
            }
            """,
            """
            class C
            {
                public C(string s) {
                    S = s;
                }
 
                public string S { get; }
            }
            """, options: this.Option(CSharpFormattingOptions2.NewLineBeforeOpenBrace, NewLineBeforeOpenBracePlacement.All & ~NewLineBeforeOpenBracePlacement.Methods));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23308")]
    public async Task TestGenerateFieldIfParameterFollowsExistingFieldAssignment()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private readonly string s;
 
                public C(string s, [||]int i)
                {
                    this.s = s;
                }
            }
            """,
            """
            class C
            {
                private readonly string s;
                private readonly int i;
 
                public C(string s, int i)
                {
                    this.s = s;
                    this.i = i;
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23308")]
    public async Task TestGenerateFieldIfParameterPrecedesExistingFieldAssignment()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private readonly string s;
 
                public C([||]int i, string s)
                {
                    this.s = s;
                }
            }
            """,
            """
            class C
            {
                private readonly int i;
                private readonly string s;
 
                public C(int i, string s)
                {
                    this.i = i;
                    this.s = s;
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23308")]
    public async Task TestGenerateFieldIfParameterFollowsExistingFieldAssignment_TupleAssignment1()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private readonly string s;
                private readonly string t;
 
                public C(string s, string t, [||]int i)
                {
                    (this.s, this.t) = (s, t);
                }
            }
            """,
            """
            class C
            {
                private readonly string s;
                private readonly string t;
                private readonly int i;
 
                public C(string s, string t, int i)
                {
                    (this.s, this.t, this.i) = (s, t, i);
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23308")]
    public async Task TestGenerateFieldIfParameterFollowsExistingFieldAssignment_TupleAssignment2()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private readonly string s;
                private readonly string t;
 
                public C(string s, string t, [||]int i) =>
                    (this.s, this.t) = (s, t);
            }
            """,
            """
            class C
            {
                private readonly string s;
                private readonly string t;
                private readonly int i;
 
                public C(string s, string t, int i) =>
                    (this.s, this.t, this.i) = (s, t, i);
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23308")]
    public async Task TestGenerateFieldIfParameterFollowsExistingFieldAssignment_TupleAssignment3()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private readonly string s;
                private readonly string t;
 
                public C(string s, string t, [||]int i)
                {
                    if (s is null) throw new ArgumentNullException();
                    (this.s, this.t) = (s, t);
                }
            }
            """,
            """
            class C
            {
                private readonly string s;
                private readonly string t;
                private readonly int i;
 
                public C(string s, string t, int i)
                {
                    if (s is null) throw new ArgumentNullException();
                    (this.s, this.t, this.i) = (s, t, i);
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23308")]
    public async Task TestGenerateFieldIfParameterPrecedesExistingFieldAssignment_TupleAssignment1()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private readonly string s;
                private readonly string t;
 
                public C([||]int i, string s, string t)
                {
                    (this.s, this.t) = (s, t);
                }
            }
            """,
            """
            class C
            {
                private readonly int i;
                private readonly string s;
                private readonly string t;
 
                public C(int i, string s, string t)
                {
                    (this.i, this.s, this.t) = (i, s, t);
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23308")]
    public async Task TestGenerateFieldIfParameterPrecedesExistingFieldAssignment_TupleAssignment2()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private readonly string s;
                private readonly string t;
 
                public C([||]int i, string s, string t) =>
                    (this.s, this.t) = (s, t);
            }
            """,
            """
            class C
            {
                private readonly int i;
                private readonly string s;
                private readonly string t;
 
                public C(int i, string s, string t) =>
                    (this.i, this.s, this.t) = (i, s, t);
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23308")]
    public async Task TestGenerateFieldIfParameterInMiddleOfExistingFieldAssignment_TupleAssignment1()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private readonly string s;
                private readonly string t;
 
                public C(string s, [||]int i, string t)
                {
                    (this.s, this.t) = (s, t);
                }
            }
            """,
            """
            class C
            {
                private readonly string s;
                private readonly int i;
                private readonly string t;
 
                public C(string s, int i, string t)
                {
                    (this.s, this.i, this.t) = (s, i, t);
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23308")]
    public async Task TestGenerateFieldIfParameterInMiddleOfExistingFieldAssignment_TupleAssignment2()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private readonly string s;
                private readonly string t;
 
                public C(string s, [||]int i, string t) =>
                    (this.s, this.t) = (s, t);
            }
            """,
            """
            class C
            {
                private readonly string s;
                private readonly int i;
                private readonly string t;
 
                public C(string s, int i, string t) =>
                    (this.s, this.i, this.t) = (s, i, t);
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/23308")]
    public async Task TestGeneratePropertyIfParameterFollowsExistingPropertyAssignment_TupleAssignment1()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                public string S { get; }
                public string T { get; }
 
                public C(string s, string t, [||]int i)
                {
                    (S, T) = (s, t);
                }
            }
            """,
            """
            class C
            {
                public string S { get; }
                public string T { get; }
                public int I { get; }
 
                public C(string s, string t, int i)
                {
                    (S, T, I) = (s, t, i);
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/41824")]
    public async Task TestMissingInArgList()
    {
        await TestMissingInRegularAndScriptAsync(
            """
            class C
            {
                private static void M()
                {
                    M2(__arglist(1, 2, 3, 5, 6));
                }
 
                public static void M2([||]__arglist)
                {
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35665")]
    public async Task TestGenerateRemainingFields1()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                public C([||]int i, int j, int k)
                {
                }
            }
            """,
            """
            class C
            {
                private readonly int i;
                private readonly int j;
                private readonly int k;
 
                public C(int i, int j, int k)
                {
                    this.i = i;
                    this.j = j;
                    this.k = k;
                }
            }
            """, index: 3);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35665")]
    public async Task TestGenerateRemainingFields2()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private readonly int i;
 
                public C(int i, [||]int j, int k)
                {
                    this.i = i;
                }
            }
            """,
            """
            class C
            {
                private readonly int i;
                private readonly int j;
                private readonly int k;
 
                public C(int i, int j, int k)
                {
                    this.i = i;
                    this.j = j;
                    this.k = k;
                }
            }
            """, index: 2);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35665")]
    public async Task TestGenerateRemainingFields3()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private readonly int j;
 
                public C([||]int i, int j, int k)
                {
                    this.j = j;
                }
            }
            """,
            """
            class C
            {
                private readonly int i;
                private readonly int j;
                private readonly int k;
 
                public C(int i, int j, int k)
                {
                    this.i = i;
                    this.j = j;
                    this.k = k;
                }
            }
            """, index: 2);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35665")]
    public async Task TestGenerateRemainingFields4()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private readonly int k;
 
                public C([||]int i, int j, int k)
                {
                    this.k = k;
                }
            }
            """,
            """
            class C
            {
                private readonly int i;
                private readonly int j;
                private readonly int k;
 
                public C(int i, int j, int k)
                {
                    this.i = i;
                    this.j = j;
                    this.k = k;
                }
            }
            """, index: 2);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35665")]
    public async Task TestGenerateRemainingProperties1()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                public C([||]int i, int j, int k)
                {
                }
            }
            """,
            """
            class C
            {
                public C(int i, int j, int k)
                {
                    I = i;
                    J = j;
                    K = k;
                }
 
                public int I { get; }
                public int J { get; }
                public int K { get; }
            }
            """, index: 2);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35665")]
    public async Task TestGenerateRemainingProperties2()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private readonly int i;
 
                public C(int i, [||]int j, int k)
                {
                    this.i = i;
                }
            }
            """,
            """
            class C
            {
                private readonly int i;
 
                public C(int i, int j, int k)
                {
                    this.i = i;
                    J = j;
                    K = k;
                }
 
                public int J { get; }
                public int K { get; }
            }
            """, index: 3);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35665")]
    public async Task TestGenerateRemainingProperties3()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private readonly int j;
 
                public C([||]int i, int j, int k)
                {
                    this.j = j;
                }
            }
            """,
            """
            class C
            {
                private readonly int j;
 
                public C(int i, int j, int k)
                {
                    I = i;
                    this.j = j;
                    K = k;
                }
 
                public int I { get; }
                public int K { get; }
            }
            """, index: 3);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/35665")]
    public async Task TestGenerateRemainingProperties4()
    {
        await TestInRegularAndScript1Async(
            """
            class C
            {
                private readonly int k;
 
                public C([||]int i, int j, int k)
                {
                    this.k = k;
                }
            }
            """,
            """
            class C
            {
                private readonly int k;
 
                public C(int i, int j, int k)
                {
                    I = i;
                    J = j;
                    this.k = k;
                }
 
                public int I { get; }
                public int J { get; }
            }
            """, index: 3);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/53467")]
    public async Task TestMissingWhenTypeNotInCompilation()
    {
        await TestMissingInRegularAndScriptAsync(
            """
            <Workspace>
                <Project Language="C#" AssemblyName="Assembly1">
                    <Document>
            public class Goo
            {
                public Goo(int prop1)
                {
                    Prop1 = prop1;
                }
 
                public int Prop1 { get; }
            }
 
            public class Bar : Goo
            {
                public Bar(int prop1, int [||]prop2) : base(prop1) { }
            }
                    </Document>
                </Project>
            </Workspace>
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36998")]
    public async Task TestInitializeThrowingProperty1()
    {
        await TestInRegularAndScript1Async(
            """
            using System;
 
            class C
            {
                private string S => throw new NotImplementedException();
 
                public C([||]string s)
                {
                }
            }
            """,
            """
            using System;
 
            class C
            {
                private string S { get; }
 
                public C(string s)
                {
                    S = s;
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36998")]
    public async Task TestInitializeThrowingProperty2()
    {
        await TestInRegularAndScript1Async(
            """
            using System;
 
            class C
            {
                private string S
                {
                    get => throw new NotImplementedException();
                }
 
                public C([||]string s)
                {
                }
            }
            """,
            """
            using System;
 
            class C
            {
                private string S
                {
                    get;
                }
 
                public C(string s)
                {
                    S = s;
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36998")]
    public async Task TestInitializeThrowingProperty3()
    {
        await TestInRegularAndScript1Async(
            """
            using System;
 
            class C
            {
                private string S
                {
                    get { throw new NotImplementedException(); }
                }
 
                public C([||]string s)
                {
                }
            }
            """,
            """
            using System;
 
            class C
            {
                private string S
                {
                    get;
                }
 
                public C(string s)
                {
                    S = s;
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36998")]
    public async Task TestInitializeThrowingProperty4()
    {
        await TestInRegularAndScript1Async(
            """
            using System;
 
            class C
            {
                private string S
                {
                    get => throw new NotImplementedException();
                    set => throw new NotImplementedException();
                }
 
                public C([||]string s)
                {
                }
            }
            """,
            """
            using System;
 
            class C
            {
                private string S
                {
                    get;
                    set;
                }
 
                public C(string s)
                {
                    S = s;
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36998")]
    public async Task TestInitializeThrowingProperty5()
    {
        await TestInRegularAndScript1Async(
            """
            using System;
 
            class C
            {
                private string S
                {
                    get { throw new NotImplementedException(); }
                    set { throw new NotImplementedException(); }
                }
 
                public C([||]string s)
                {
                }
            }
            """,
            """
            using System;
 
            class C
            {
                private string S
                {
                    get;
                    set;
                }
 
                public C(string s)
                {
                    S = s;
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36998")]
    public async Task TestInitializeThrowingProperty6()
    {
        await TestInRegularAndScript1Async(
            """
            using System;
 
            class C
            {
                private string S => throw new InvalidOperationException();
 
                public C([||]string s)
                {
                }
            }
            """,
            """
            using System;
 
            class C
            {
                private string S => throw new InvalidOperationException();
 
                public string S1 { get; }
 
                public C(string s)
                {
                    S1 = s;
                }
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/36998")]
    public async Task TestInitializeThrowingProperty_DifferentFile1()
    {
        await TestInRegularAndScriptAsync(
            """
            <Workspace>
                <Project Language="C#" AssemblyName="Assembly1" CommonReferences="true">
                    <Document>
            public partial class Goo
            {
                public Goo(string [||]name)
                {
                }
            }
                    </Document>
                    <Document>
            using System;
            public partial class Goo
            {
                public string Name => throw new NotImplementedException();
            }
                    </Document>
                </Project>
            </Workspace>
            """,
            """
            <Workspace>
                <Project Language="C#" AssemblyName="Assembly1" CommonReferences="true">
                    <Document>
            public partial class Goo
            {
                public Goo(string name)
                {
                    Name = name;
                }
            }
                    </Document>
                    <Document>
            using System;
            public partial class Goo
            {
                public string Name { get; }
            }
                    </Document>
                </Project>
            </Workspace>
            """);
    }
}