Skip to content

Commit

Permalink
Add unit tests for new analyzer
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergio0694 committed Dec 7, 2024
1 parent b4bf0a3 commit ba00de9
Show file tree
Hide file tree
Showing 2 changed files with 232 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ public static bool TryFindDefaultValueCallbackMethod(IPropertySymbol propertySym

foreach (ISymbol member in memberSymbols)
{
// We need methods which are static and with no parameters (and that is not explicitly implemented)
if (member is not IMethodSymbol { IsStatic: true, Parameters: [], ExplicitInterfaceImplementations: [] } candidateSymbol)
// Ignore all other member types
if (member is not IMethodSymbol candidateSymbol)
{
continue;
}
Expand All @@ -136,6 +136,12 @@ public static bool TryFindDefaultValueCallbackMethod(IPropertySymbol propertySym
/// <returns>Whether <paramref name="methodSymbol"/> is a valid default value callback method for <paramref name="propertySymbol"/>.</returns>
public static bool IsDefaultValueCallbackValid(IPropertySymbol propertySymbol, IMethodSymbol methodSymbol)
{
// We need methods which are static and with no parameters (and that are not explicitly implemented)
if (methodSymbol is not { IsStatic: true, Parameters: [], ExplicitInterfaceImplementations: [] })
{
return false;
}

// We have a candidate, now we need to match the return type. First,
// we just check whether the return is 'object', or an exact match.
if (methodSymbol.ReturnType.SpecialType is SpecialType.System_Object ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,7 @@ public partial class MyControl : Control
[TestMethod]
public async Task InvalidPropertyNonNullableDeclarationAnalyzer_NotNullableType_WithMaybeNullAttribute_DoesNotWarn()
{
string source = $$"""
const string source = """
using System.Diagnostics.CodeAnalysis;
using CommunityToolkit.WinUI;
using Windows.UI.Xaml.Controls;
Expand All @@ -682,7 +682,7 @@ public partial class MyControl : Control
[TestMethod]
public async Task InvalidPropertyNonNullableDeclarationAnalyzer_NotNullableType_Required_DoesNotWarn()
{
string source = $$"""
const string source = """
using CommunityToolkit.WinUI;
using Windows.UI.Xaml.Controls;
Expand All @@ -703,7 +703,7 @@ public partial class MyControl : Control
[TestMethod]
public async Task InvalidPropertyNonNullableDeclarationAnalyzer_NotNullableType_NullableDisabled_DoesNotWarn()
{
string source = $$"""
const string source = """
using CommunityToolkit.WinUI;
using Windows.UI.Xaml.Controls;
Expand All @@ -722,7 +722,7 @@ public partial class MyControl : Control
[TestMethod]
public async Task InvalidPropertyNonNullableDeclarationAnalyzer_NotNullableType_WithNonNullDefaultValue_DoesNotWarn()
{
string source = $$"""
const string source = """
using CommunityToolkit.WinUI;
using Windows.UI.Xaml.Controls;
Expand All @@ -743,7 +743,7 @@ public partial class MyControl : Control
[TestMethod]
public async Task InvalidPropertyNonNullableDeclarationAnalyzer_NotNullableType_Warns()
{
string source = $$"""
const string source = """
using CommunityToolkit.WinUI;
using Windows.UI.Xaml.Controls;
Expand All @@ -764,7 +764,7 @@ public partial class MyControl : Control
[TestMethod]
public async Task InvalidPropertyNonNullableDeclarationAnalyzer_NotNullableType_WithNullDefaultValue_Warns()
{
string source = $$"""
const string source = """
using CommunityToolkit.WinUI;
using Windows.UI.Xaml.Controls;
Expand Down Expand Up @@ -896,7 +896,7 @@ public partial class MyControl : Control
[TestMethod]
public async Task InvalidPropertyDefaultValueTypeAnalyzer_NullValue_NonNullable_Warns()
{
string source = $$"""
const string source = """
using CommunityToolkit.WinUI;
using Windows.UI.Xaml.Controls;
Expand Down Expand Up @@ -938,4 +938,221 @@ public partial class MyControl : Control

await CSharpAnalyzerTest<InvalidPropertyDefaultValueTypeAnalyzer>.VerifyAnalyzerAsync(source, LanguageVersion.CSharp13);
}

[TestMethod]
public async Task InvalidPropertyDefaultValueCallbackTypeAnalyzer_NoAttribute_DoesNotWarn()
{
const string source = """
using Windows.UI.Xaml.Controls;
#nullable enable
namespace MyApp;
public partial class MyControl : Control
{
public partial string? {|CS9248:Name|} { get; set; }
}
""";

await CSharpAnalyzerTest<InvalidPropertyDefaultValueCallbackTypeAnalyzer>.VerifyAnalyzerAsync(source, LanguageVersion.CSharp13);
}

[TestMethod]
public async Task InvalidPropertyDefaultValueCallbackTypeAnalyzer_NoDefaultValueCallback1_DoesNotWarn()
{
const string source = """
using CommunityToolkit.WinUI;
using Windows.UI.Xaml.Controls;
#nullable enable
namespace MyApp;
public partial class MyControl : Control
{
[GeneratedDependencyProperty]
public partial string? {|CS9248:Name|} { get; set; }
}
""";

await CSharpAnalyzerTest<InvalidPropertyDefaultValueCallbackTypeAnalyzer>.VerifyAnalyzerAsync(source, LanguageVersion.CSharp13);
}

[TestMethod]
public async Task InvalidPropertyDefaultValueCallbackTypeAnalyzer_NoDefaultValueCallback2_DoesNotWarn()
{
const string source = """
using CommunityToolkit.WinUI;
using Windows.UI.Xaml.Controls;
#nullable enable
namespace MyApp;
public partial class MyControl : Control
{
[GeneratedDependencyProperty(DefaultValue = "Bob")]
public partial string? {|CS9248:Name|} { get; set; }
}
""";

await CSharpAnalyzerTest<InvalidPropertyDefaultValueCallbackTypeAnalyzer>.VerifyAnalyzerAsync(source, LanguageVersion.CSharp13);
}

[TestMethod]
public async Task InvalidPropertyDefaultValueCallbackTypeAnalyzer_NullDefaultValueCallback_DoesNotWarn()
{
const string source = """
using CommunityToolkit.WinUI;
using Windows.UI.Xaml.Controls;
#nullable enable
namespace MyApp;
public partial class MyControl : Control
{
[GeneratedDependencyProperty(DefaultValueCallback = null)]
public partial string? {|CS9248:Name|} { get; set; }
}
""";

await CSharpAnalyzerTest<InvalidPropertyDefaultValueCallbackTypeAnalyzer>.VerifyAnalyzerAsync(source, LanguageVersion.CSharp13);
}

[TestMethod]
[DataRow("string", "string")]
[DataRow("string", "string?")]
[DataRow("string", "object")]
[DataRow("string", "object?")]
[DataRow("string?", "string")]
[DataRow("string?", "string?")]
[DataRow("int", "int")]
[DataRow("int", "object")]
[DataRow("int", "object?")]
[DataRow("int?", "int")]
[DataRow("int?", "int?")]
[DataRow("int?", "object")]
[DataRow("int?", "object?")]
public async Task InvalidPropertyDefaultValueCallbackTypeAnalyzer_ValidDefaultValueCallback_DoesNotWarn(string propertyType, string returnType)
{
string source = $$"""
using CommunityToolkit.WinUI;
using Windows.UI.Xaml.Controls;
#nullable enable
namespace MyApp;
public partial class MyControl : Control
{
[GeneratedDependencyProperty(DefaultValueCallback = nameof(GetDefaultValue))]
public partial {{propertyType}} {|CS9248:Value|} { get; set; }
private static {{returnType}} GetDefaultValue() => default!;
}
""";

await CSharpAnalyzerTest<InvalidPropertyDefaultValueCallbackTypeAnalyzer>.VerifyAnalyzerAsync(source, LanguageVersion.CSharp13);
}

[TestMethod]
public async Task InvalidPropertyDefaultValueCallbackTypeAnalyzer_BothDefaultValuePropertiesSet_Warns()
{
const string source = """
using CommunityToolkit.WinUI;
using Windows.UI.Xaml.Controls;
#nullable enable
namespace MyApp;
public partial class MyControl : Control
{
[{|WCTDP0013:GeneratedDependencyProperty(DefaultValue = "Bob", DefaultValueCallback = nameof(GetDefaultName))|}]
public partial string? {|CS9248:Name|} { get; set; }
private static string? GetDefaultName() => "Bob";
}
""";

await CSharpAnalyzerTest<InvalidPropertyDefaultValueCallbackTypeAnalyzer>.VerifyAnalyzerAsync(source, LanguageVersion.CSharp13);
}

[TestMethod]
public async Task InvalidPropertyDefaultValueCallbackTypeAnalyzer_MethodNotFound_Warns()
{
const string source = """
using CommunityToolkit.WinUI;
using Windows.UI.Xaml.Controls;
#nullable enable
namespace MyApp;
public partial class MyControl : Control
{
[{|WCTDP0014:GeneratedDependencyProperty(DefaultValueCallback = "MissingMethod")|}]
public partial string? {|CS9248:Name|} { get; set; }
}
""";

await CSharpAnalyzerTest<InvalidPropertyDefaultValueCallbackTypeAnalyzer>.VerifyAnalyzerAsync(source, LanguageVersion.CSharp13);
}

[TestMethod]
public async Task InvalidPropertyDefaultValueCallbackTypeAnalyzer_InvalidMethod_ExplicitlyImplemented_Warns()
{
const string source = """
using CommunityToolkit.WinUI;
using Windows.UI.Xaml.Controls;
#nullable enable
namespace MyApp;
public partial class MyControl : Control, IGetDefaultValue
{
[{|WCTDP0014:GeneratedDependencyProperty(DefaultValueCallback = "GetDefaultValue")|}]
public partial string? {|CS9248:Name|} { get; set; }
static string? IGetDefaultValue.GetDefaultValue() => "Bob";
}
public interface IGetDefaultValue
{
static abstract string? GetDefaultValue();
}
""";

await CSharpAnalyzerTest<InvalidPropertyDefaultValueCallbackTypeAnalyzer>.VerifyAnalyzerAsync(source, LanguageVersion.CSharp13);
}

[TestMethod]
[DataRow("private string? GetDefaultName()")]
[DataRow("private static string? GetDefaultName(int x)")]
[DataRow("private static int GetDefaultName()")]
[DataRow("private static int GetDefaultName(int x)")]
public async Task InvalidPropertyDefaultValueCallbackTypeAnalyzer_InvalidMethod_Warns(string methodSignature)
{
string source = $$"""
using CommunityToolkit.WinUI;
using Windows.UI.Xaml.Controls;
#nullable enable
namespace MyApp;
public partial class MyControl : Control
{
[{|WCTDP0015:GeneratedDependencyProperty(DefaultValueCallback = "GetDefaultName")|}]
public partial string? {|CS9248:Name|} { get; set; }
{{methodSignature}} => default!;
}
""";

await CSharpAnalyzerTest<InvalidPropertyDefaultValueCallbackTypeAnalyzer>.VerifyAnalyzerAsync(source, LanguageVersion.CSharp13);
}
}

0 comments on commit ba00de9

Please sign in to comment.