Skip to content

Commit ba00de9

Browse files
committed
Add unit tests for new analyzer
1 parent b4bf0a3 commit ba00de9

File tree

2 files changed

+232
-9
lines changed

2 files changed

+232
-9
lines changed

components/DependencyPropertyGenerator/CommunityToolkit.DependencyPropertyGenerator.SourceGenerators/Diagnostics/Analyzers/InvalidPropertyDefaultValueCallbackTypeAnalyzer.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@ public static bool TryFindDefaultValueCallbackMethod(IPropertySymbol propertySym
108108

109109
foreach (ISymbol member in memberSymbols)
110110
{
111-
// We need methods which are static and with no parameters (and that is not explicitly implemented)
112-
if (member is not IMethodSymbol { IsStatic: true, Parameters: [], ExplicitInterfaceImplementations: [] } candidateSymbol)
111+
// Ignore all other member types
112+
if (member is not IMethodSymbol candidateSymbol)
113113
{
114114
continue;
115115
}
@@ -136,6 +136,12 @@ public static bool TryFindDefaultValueCallbackMethod(IPropertySymbol propertySym
136136
/// <returns>Whether <paramref name="methodSymbol"/> is a valid default value callback method for <paramref name="propertySymbol"/>.</returns>
137137
public static bool IsDefaultValueCallbackValid(IPropertySymbol propertySymbol, IMethodSymbol methodSymbol)
138138
{
139+
// We need methods which are static and with no parameters (and that are not explicitly implemented)
140+
if (methodSymbol is not { IsStatic: true, Parameters: [], ExplicitInterfaceImplementations: [] })
141+
{
142+
return false;
143+
}
144+
139145
// We have a candidate, now we need to match the return type. First,
140146
// we just check whether the return is 'object', or an exact match.
141147
if (methodSymbol.ReturnType.SpecialType is SpecialType.System_Object ||

components/DependencyPropertyGenerator/CommunityToolkit.DependencyPropertyGenerator.Tests/Test_Analyzers.cs

Lines changed: 224 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,7 @@ public partial class MyControl : Control
659659
[TestMethod]
660660
public async Task InvalidPropertyNonNullableDeclarationAnalyzer_NotNullableType_WithMaybeNullAttribute_DoesNotWarn()
661661
{
662-
string source = $$"""
662+
const string source = """
663663
using System.Diagnostics.CodeAnalysis;
664664
using CommunityToolkit.WinUI;
665665
using Windows.UI.Xaml.Controls;
@@ -682,7 +682,7 @@ public partial class MyControl : Control
682682
[TestMethod]
683683
public async Task InvalidPropertyNonNullableDeclarationAnalyzer_NotNullableType_Required_DoesNotWarn()
684684
{
685-
string source = $$"""
685+
const string source = """
686686
using CommunityToolkit.WinUI;
687687
using Windows.UI.Xaml.Controls;
688688
@@ -703,7 +703,7 @@ public partial class MyControl : Control
703703
[TestMethod]
704704
public async Task InvalidPropertyNonNullableDeclarationAnalyzer_NotNullableType_NullableDisabled_DoesNotWarn()
705705
{
706-
string source = $$"""
706+
const string source = """
707707
using CommunityToolkit.WinUI;
708708
using Windows.UI.Xaml.Controls;
709709
@@ -722,7 +722,7 @@ public partial class MyControl : Control
722722
[TestMethod]
723723
public async Task InvalidPropertyNonNullableDeclarationAnalyzer_NotNullableType_WithNonNullDefaultValue_DoesNotWarn()
724724
{
725-
string source = $$"""
725+
const string source = """
726726
using CommunityToolkit.WinUI;
727727
using Windows.UI.Xaml.Controls;
728728
@@ -743,7 +743,7 @@ public partial class MyControl : Control
743743
[TestMethod]
744744
public async Task InvalidPropertyNonNullableDeclarationAnalyzer_NotNullableType_Warns()
745745
{
746-
string source = $$"""
746+
const string source = """
747747
using CommunityToolkit.WinUI;
748748
using Windows.UI.Xaml.Controls;
749749
@@ -764,7 +764,7 @@ public partial class MyControl : Control
764764
[TestMethod]
765765
public async Task InvalidPropertyNonNullableDeclarationAnalyzer_NotNullableType_WithNullDefaultValue_Warns()
766766
{
767-
string source = $$"""
767+
const string source = """
768768
using CommunityToolkit.WinUI;
769769
using Windows.UI.Xaml.Controls;
770770
@@ -896,7 +896,7 @@ public partial class MyControl : Control
896896
[TestMethod]
897897
public async Task InvalidPropertyDefaultValueTypeAnalyzer_NullValue_NonNullable_Warns()
898898
{
899-
string source = $$"""
899+
const string source = """
900900
using CommunityToolkit.WinUI;
901901
using Windows.UI.Xaml.Controls;
902902
@@ -938,4 +938,221 @@ public partial class MyControl : Control
938938

939939
await CSharpAnalyzerTest<InvalidPropertyDefaultValueTypeAnalyzer>.VerifyAnalyzerAsync(source, LanguageVersion.CSharp13);
940940
}
941+
942+
[TestMethod]
943+
public async Task InvalidPropertyDefaultValueCallbackTypeAnalyzer_NoAttribute_DoesNotWarn()
944+
{
945+
const string source = """
946+
using Windows.UI.Xaml.Controls;
947+
948+
#nullable enable
949+
950+
namespace MyApp;
951+
952+
public partial class MyControl : Control
953+
{
954+
public partial string? {|CS9248:Name|} { get; set; }
955+
}
956+
""";
957+
958+
await CSharpAnalyzerTest<InvalidPropertyDefaultValueCallbackTypeAnalyzer>.VerifyAnalyzerAsync(source, LanguageVersion.CSharp13);
959+
}
960+
961+
[TestMethod]
962+
public async Task InvalidPropertyDefaultValueCallbackTypeAnalyzer_NoDefaultValueCallback1_DoesNotWarn()
963+
{
964+
const string source = """
965+
using CommunityToolkit.WinUI;
966+
using Windows.UI.Xaml.Controls;
967+
968+
#nullable enable
969+
970+
namespace MyApp;
971+
972+
public partial class MyControl : Control
973+
{
974+
[GeneratedDependencyProperty]
975+
public partial string? {|CS9248:Name|} { get; set; }
976+
}
977+
""";
978+
979+
await CSharpAnalyzerTest<InvalidPropertyDefaultValueCallbackTypeAnalyzer>.VerifyAnalyzerAsync(source, LanguageVersion.CSharp13);
980+
}
981+
982+
[TestMethod]
983+
public async Task InvalidPropertyDefaultValueCallbackTypeAnalyzer_NoDefaultValueCallback2_DoesNotWarn()
984+
{
985+
const string source = """
986+
using CommunityToolkit.WinUI;
987+
using Windows.UI.Xaml.Controls;
988+
989+
#nullable enable
990+
991+
namespace MyApp;
992+
993+
public partial class MyControl : Control
994+
{
995+
[GeneratedDependencyProperty(DefaultValue = "Bob")]
996+
public partial string? {|CS9248:Name|} { get; set; }
997+
}
998+
""";
999+
1000+
await CSharpAnalyzerTest<InvalidPropertyDefaultValueCallbackTypeAnalyzer>.VerifyAnalyzerAsync(source, LanguageVersion.CSharp13);
1001+
}
1002+
1003+
[TestMethod]
1004+
public async Task InvalidPropertyDefaultValueCallbackTypeAnalyzer_NullDefaultValueCallback_DoesNotWarn()
1005+
{
1006+
const string source = """
1007+
using CommunityToolkit.WinUI;
1008+
using Windows.UI.Xaml.Controls;
1009+
1010+
#nullable enable
1011+
1012+
namespace MyApp;
1013+
1014+
public partial class MyControl : Control
1015+
{
1016+
[GeneratedDependencyProperty(DefaultValueCallback = null)]
1017+
public partial string? {|CS9248:Name|} { get; set; }
1018+
}
1019+
""";
1020+
1021+
await CSharpAnalyzerTest<InvalidPropertyDefaultValueCallbackTypeAnalyzer>.VerifyAnalyzerAsync(source, LanguageVersion.CSharp13);
1022+
}
1023+
1024+
[TestMethod]
1025+
[DataRow("string", "string")]
1026+
[DataRow("string", "string?")]
1027+
[DataRow("string", "object")]
1028+
[DataRow("string", "object?")]
1029+
[DataRow("string?", "string")]
1030+
[DataRow("string?", "string?")]
1031+
[DataRow("int", "int")]
1032+
[DataRow("int", "object")]
1033+
[DataRow("int", "object?")]
1034+
[DataRow("int?", "int")]
1035+
[DataRow("int?", "int?")]
1036+
[DataRow("int?", "object")]
1037+
[DataRow("int?", "object?")]
1038+
public async Task InvalidPropertyDefaultValueCallbackTypeAnalyzer_ValidDefaultValueCallback_DoesNotWarn(string propertyType, string returnType)
1039+
{
1040+
string source = $$"""
1041+
using CommunityToolkit.WinUI;
1042+
using Windows.UI.Xaml.Controls;
1043+
1044+
#nullable enable
1045+
1046+
namespace MyApp;
1047+
1048+
public partial class MyControl : Control
1049+
{
1050+
[GeneratedDependencyProperty(DefaultValueCallback = nameof(GetDefaultValue))]
1051+
public partial {{propertyType}} {|CS9248:Value|} { get; set; }
1052+
1053+
private static {{returnType}} GetDefaultValue() => default!;
1054+
}
1055+
""";
1056+
1057+
await CSharpAnalyzerTest<InvalidPropertyDefaultValueCallbackTypeAnalyzer>.VerifyAnalyzerAsync(source, LanguageVersion.CSharp13);
1058+
}
1059+
1060+
[TestMethod]
1061+
public async Task InvalidPropertyDefaultValueCallbackTypeAnalyzer_BothDefaultValuePropertiesSet_Warns()
1062+
{
1063+
const string source = """
1064+
using CommunityToolkit.WinUI;
1065+
using Windows.UI.Xaml.Controls;
1066+
1067+
#nullable enable
1068+
1069+
namespace MyApp;
1070+
1071+
public partial class MyControl : Control
1072+
{
1073+
[{|WCTDP0013:GeneratedDependencyProperty(DefaultValue = "Bob", DefaultValueCallback = nameof(GetDefaultName))|}]
1074+
public partial string? {|CS9248:Name|} { get; set; }
1075+
1076+
private static string? GetDefaultName() => "Bob";
1077+
}
1078+
""";
1079+
1080+
await CSharpAnalyzerTest<InvalidPropertyDefaultValueCallbackTypeAnalyzer>.VerifyAnalyzerAsync(source, LanguageVersion.CSharp13);
1081+
}
1082+
1083+
[TestMethod]
1084+
public async Task InvalidPropertyDefaultValueCallbackTypeAnalyzer_MethodNotFound_Warns()
1085+
{
1086+
const string source = """
1087+
using CommunityToolkit.WinUI;
1088+
using Windows.UI.Xaml.Controls;
1089+
1090+
#nullable enable
1091+
1092+
namespace MyApp;
1093+
1094+
public partial class MyControl : Control
1095+
{
1096+
[{|WCTDP0014:GeneratedDependencyProperty(DefaultValueCallback = "MissingMethod")|}]
1097+
public partial string? {|CS9248:Name|} { get; set; }
1098+
}
1099+
""";
1100+
1101+
await CSharpAnalyzerTest<InvalidPropertyDefaultValueCallbackTypeAnalyzer>.VerifyAnalyzerAsync(source, LanguageVersion.CSharp13);
1102+
}
1103+
1104+
[TestMethod]
1105+
public async Task InvalidPropertyDefaultValueCallbackTypeAnalyzer_InvalidMethod_ExplicitlyImplemented_Warns()
1106+
{
1107+
const string source = """
1108+
using CommunityToolkit.WinUI;
1109+
using Windows.UI.Xaml.Controls;
1110+
1111+
#nullable enable
1112+
1113+
namespace MyApp;
1114+
1115+
public partial class MyControl : Control, IGetDefaultValue
1116+
{
1117+
[{|WCTDP0014:GeneratedDependencyProperty(DefaultValueCallback = "GetDefaultValue")|}]
1118+
public partial string? {|CS9248:Name|} { get; set; }
1119+
1120+
static string? IGetDefaultValue.GetDefaultValue() => "Bob";
1121+
}
1122+
1123+
public interface IGetDefaultValue
1124+
{
1125+
static abstract string? GetDefaultValue();
1126+
}
1127+
""";
1128+
1129+
await CSharpAnalyzerTest<InvalidPropertyDefaultValueCallbackTypeAnalyzer>.VerifyAnalyzerAsync(source, LanguageVersion.CSharp13);
1130+
}
1131+
1132+
[TestMethod]
1133+
[DataRow("private string? GetDefaultName()")]
1134+
[DataRow("private static string? GetDefaultName(int x)")]
1135+
[DataRow("private static int GetDefaultName()")]
1136+
[DataRow("private static int GetDefaultName(int x)")]
1137+
public async Task InvalidPropertyDefaultValueCallbackTypeAnalyzer_InvalidMethod_Warns(string methodSignature)
1138+
{
1139+
string source = $$"""
1140+
using CommunityToolkit.WinUI;
1141+
using Windows.UI.Xaml.Controls;
1142+
1143+
#nullable enable
1144+
1145+
namespace MyApp;
1146+
1147+
public partial class MyControl : Control
1148+
{
1149+
[{|WCTDP0015:GeneratedDependencyProperty(DefaultValueCallback = "GetDefaultName")|}]
1150+
public partial string? {|CS9248:Name|} { get; set; }
1151+
1152+
{{methodSignature}} => default!;
1153+
}
1154+
""";
1155+
1156+
await CSharpAnalyzerTest<InvalidPropertyDefaultValueCallbackTypeAnalyzer>.VerifyAnalyzerAsync(source, LanguageVersion.CSharp13);
1157+
}
9411158
}

0 commit comments

Comments
 (0)