mirror of
https://github.com/CommunityToolkit/dotnet.git
synced 2026-10-19 05:31:42 +08:00
287 lines
10 KiB
C#
287 lines
10 KiB
C#
// 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 CommunityToolkit.Mvvm.ComponentModel;
|
|
using Microsoft.CodeAnalysis.Testing;
|
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
using CSharpCodeFixTest = Microsoft.CodeAnalysis.CSharp.Testing.CSharpCodeFixTest<
|
|
CommunityToolkit.Mvvm.SourceGenerators.FieldReferenceForObservablePropertyFieldAnalyzer,
|
|
CommunityToolkit.Mvvm.CodeFixers.FieldReferenceForObservablePropertyFieldCodeFixer,
|
|
Microsoft.CodeAnalysis.Testing.Verifiers.MSTestVerifier>;
|
|
using CSharpCodeFixVerifier = Microsoft.CodeAnalysis.CSharp.Testing.CSharpCodeFixVerifier<
|
|
CommunityToolkit.Mvvm.SourceGenerators.FieldReferenceForObservablePropertyFieldAnalyzer,
|
|
CommunityToolkit.Mvvm.CodeFixers.FieldReferenceForObservablePropertyFieldCodeFixer,
|
|
Microsoft.CodeAnalysis.Testing.Verifiers.MSTestVerifier>;
|
|
|
|
namespace CommunityToolkit.Mvvm.SourceGenerators.Roslyn401.UnitTests;
|
|
|
|
[TestClass]
|
|
public class Test_FieldReferenceForObservablePropertyFieldCodeFixer
|
|
{
|
|
[TestMethod]
|
|
public async Task SimpleMemberAccess()
|
|
{
|
|
string original = """
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
|
|
class C : ObservableObject
|
|
{
|
|
[ObservableProperty]
|
|
private int i;
|
|
|
|
void M()
|
|
{
|
|
_ = i;
|
|
i = 1;
|
|
}
|
|
}
|
|
""";
|
|
|
|
string @fixed = """
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
|
|
class C : ObservableObject
|
|
{
|
|
[ObservableProperty]
|
|
private int i;
|
|
|
|
void M()
|
|
{
|
|
_ = I;
|
|
I = 1;
|
|
}
|
|
}
|
|
""";
|
|
|
|
CSharpCodeFixTest test = new()
|
|
{
|
|
TestCode = original,
|
|
FixedCode = @fixed,
|
|
ReferenceAssemblies = ReferenceAssemblies.Net.Net60
|
|
};
|
|
|
|
test.TestState.AdditionalReferences.Add(typeof(ObservableObject).Assembly);
|
|
test.ExpectedDiagnostics.AddRange(new[]
|
|
{
|
|
// /0/Test0.cs(10,13): warning MVVMTK0034: The field C.i is annotated with [ObservableProperty] and should not be directly referenced (use the generated property instead)
|
|
CSharpCodeFixVerifier.Diagnostic().WithSpan(10, 13, 10, 14).WithArguments("C.i"),
|
|
|
|
// /0/Test0.cs(11,9): warning MVVMTK0034: The field C.i is annotated with [ObservableProperty] and should not be directly referenced (use the generated property instead)
|
|
CSharpCodeFixVerifier.Diagnostic().WithSpan(11, 9, 11, 10).WithArguments("C.i")
|
|
});
|
|
|
|
test.FixedState.ExpectedDiagnostics.AddRange(new[]
|
|
{
|
|
// /0/Test0.cs(10,13): error CS0103: The name 'I' does not exist in the current context
|
|
DiagnosticResult.CompilerError("CS0103").WithSpan(10, 13, 10, 14).WithArguments("I"),
|
|
|
|
// /0/Test0.cs(11,9): error CS0103: The name 'I' does not exist in the current context
|
|
DiagnosticResult.CompilerError("CS0103").WithSpan(11, 9, 11, 10).WithArguments("I"),
|
|
});
|
|
|
|
await test.RunAsync();
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task QualifiedMemberAccess()
|
|
{
|
|
string original = """
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
|
|
class C : ObservableObject
|
|
{
|
|
[ObservableProperty]
|
|
private int i;
|
|
|
|
void M()
|
|
{
|
|
_ = this.i;
|
|
this.i = 1;
|
|
}
|
|
}
|
|
""";
|
|
|
|
string @fixed = """
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
|
|
class C : ObservableObject
|
|
{
|
|
[ObservableProperty]
|
|
private int i;
|
|
|
|
void M()
|
|
{
|
|
_ = this.I;
|
|
this.I = 1;
|
|
}
|
|
}
|
|
""";
|
|
|
|
CSharpCodeFixTest test = new()
|
|
{
|
|
TestCode = original,
|
|
FixedCode = @fixed,
|
|
ReferenceAssemblies = ReferenceAssemblies.Net.Net60
|
|
};
|
|
|
|
test.TestState.AdditionalReferences.Add(typeof(ObservableObject).Assembly);
|
|
test.ExpectedDiagnostics.AddRange(new[]
|
|
{
|
|
// /0/Test0.cs(10,13): warning MVVMTK0034: The field C.i is annotated with [ObservableProperty] and should not be directly referenced (use the generated property instead)
|
|
CSharpCodeFixVerifier.Diagnostic().WithSpan(10, 13, 10, 19).WithArguments("C.i"),
|
|
|
|
// /0/Test0.cs(11,9): warning MVVMTK0034: The field C.i is annotated with [ObservableProperty] and should not be directly referenced (use the generated property instead)
|
|
CSharpCodeFixVerifier.Diagnostic().WithSpan(11, 9, 11, 15).WithArguments("C.i"),
|
|
});
|
|
|
|
test.FixedState.ExpectedDiagnostics.AddRange(new[]
|
|
{
|
|
// /0/Test0.cs(10,18): error CS1061: 'C' does not contain a definition for 'I' and no accessible extension method 'I' accepting a first argument of type 'C' could be found (are you missing a using directive or an assembly reference?)
|
|
DiagnosticResult.CompilerError("CS1061").WithSpan(10, 18, 10, 19).WithArguments("C", "I"),
|
|
|
|
// /0/Test0.cs(11,14): error CS1061: 'C' does not contain a definition for 'I' and no accessible extension method 'I' accepting a first argument of type 'C' could be found (are you missing a using directive or an assembly reference?)
|
|
DiagnosticResult.CompilerError("CS1061").WithSpan(11, 14, 11, 15).WithArguments("C", "I"),
|
|
});
|
|
|
|
await test.RunAsync();
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task ExternalQualifiedMemberAccess()
|
|
{
|
|
string original = """
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
|
|
class C : ObservableObject
|
|
{
|
|
[ObservableProperty]
|
|
public int i;
|
|
}
|
|
|
|
class D
|
|
{
|
|
void M()
|
|
{
|
|
var c = new C();
|
|
c.i = 1;
|
|
_ = c.i;
|
|
}
|
|
}
|
|
""";
|
|
|
|
string @fixed = """
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
|
|
class C : ObservableObject
|
|
{
|
|
[ObservableProperty]
|
|
public int i;
|
|
}
|
|
|
|
class D
|
|
{
|
|
void M()
|
|
{
|
|
var c = new C();
|
|
c.I = 1;
|
|
_ = c.I;
|
|
}
|
|
}
|
|
""";
|
|
|
|
CSharpCodeFixTest test = new()
|
|
{
|
|
TestCode = original,
|
|
FixedCode = @fixed,
|
|
ReferenceAssemblies = ReferenceAssemblies.Net.Net60
|
|
};
|
|
|
|
test.TestState.AdditionalReferences.Add(typeof(ObservableObject).Assembly);
|
|
test.ExpectedDiagnostics.AddRange(new[]
|
|
{
|
|
// /0/Test0.cs(14,9): warning MVVMTK0034: The field C.i is annotated with [ObservableProperty] and should not be directly referenced (use the generated property instead)
|
|
CSharpCodeFixVerifier.Diagnostic().WithSpan(14, 9, 14, 12).WithArguments("C.i"),
|
|
|
|
// /0/Test0.cs(15,13): warning MVVMTK0034: The field C.i is annotated with [ObservableProperty] and should not be directly referenced (use the generated property instead)
|
|
CSharpCodeFixVerifier.Diagnostic().WithSpan(15, 13, 15, 16).WithArguments("C.i"),
|
|
});
|
|
|
|
test.FixedState.ExpectedDiagnostics.AddRange(new[]
|
|
{
|
|
// /0/Test0.cs(14,11): error CS1061: 'C' does not contain a definition for 'I' and no accessible extension method 'I' accepting a first argument of type 'C' could be found (are you missing a using directive or an assembly reference?)
|
|
DiagnosticResult.CompilerError("CS1061").WithSpan(14, 11, 14, 12).WithArguments("C", "I"),
|
|
|
|
// /0/Test0.cs(15,15): error CS1061: 'C' does not contain a definition for 'I' and no accessible extension method 'I' accepting a first argument of type 'C' could be found (are you missing a using directive or an assembly reference?)
|
|
DiagnosticResult.CompilerError("CS1061").WithSpan(15, 15, 15, 16).WithArguments("C", "I"),
|
|
});
|
|
|
|
await test.RunAsync();
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task ExternalConditionalMemberAccess()
|
|
{
|
|
string original = """
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
|
|
class C : ObservableObject
|
|
{
|
|
[ObservableProperty]
|
|
public int i;
|
|
}
|
|
|
|
class D
|
|
{
|
|
void M()
|
|
{
|
|
var c = new C();
|
|
_ = c?.i;
|
|
}
|
|
}
|
|
""";
|
|
|
|
string @fixed = """
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
|
|
class C : ObservableObject
|
|
{
|
|
[ObservableProperty]
|
|
public int i;
|
|
}
|
|
|
|
class D
|
|
{
|
|
void M()
|
|
{
|
|
var c = new C();
|
|
_ = c?.I;
|
|
}
|
|
}
|
|
""";
|
|
|
|
CSharpCodeFixTest test = new()
|
|
{
|
|
TestCode = original,
|
|
FixedCode = @fixed,
|
|
ReferenceAssemblies = ReferenceAssemblies.Net.Net60
|
|
};
|
|
|
|
test.TestState.AdditionalReferences.Add(typeof(ObservableObject).Assembly);
|
|
test.ExpectedDiagnostics.AddRange(new[]
|
|
{
|
|
// /0/Test0.cs(14,15): warning MVVMTK0034: The field C.i is annotated with [ObservableProperty] and should not be directly referenced (use the generated property instead)
|
|
CSharpCodeFixVerifier.Diagnostic().WithSpan(14, 15, 14, 17).WithArguments("C.i"),
|
|
});
|
|
|
|
test.FixedState.ExpectedDiagnostics.AddRange(new[]
|
|
{
|
|
// /0/Test0.cs(14,15): error CS1061: 'C' does not contain a definition for 'I' and no accessible extension method 'I' accepting a first argument of type 'C' could be found (are you missing a using directive or an assembly reference?)
|
|
DiagnosticResult.CompilerError("CS1061").WithSpan(14, 15, 14, 17).WithArguments("C", "I"),
|
|
});
|
|
|
|
await test.RunAsync();
|
|
}
|
|
}
|