|
// 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(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>
""");
}
}
|