Skip to content

Commit ea014da

Browse files
committed
Add C# 14 partial property tests and fix formatting
Introduces new unit tests for ObservableProperty with value types on partial properties using C# 14 and Roslyn 5.0.0 or greater. Also updates formatting in diagnostics tests for consistency and readability.
1 parent dffc56d commit ea014da

File tree

2 files changed

+131
-29
lines changed

2 files changed

+131
-29
lines changed

tests/CommunityToolkit.Mvvm.SourceGenerators.Roslyn4120.UnitTests/Test_SourceGeneratorsCodegen.cs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,82 @@ partial int Number
9191
VerifyGenerateSources(source, new[] { new ObservablePropertyGenerator() }, LanguageVersion.Preview, ("MyApp.MyViewModel.g.cs", result));
9292
}
9393

94+
#if ROSLYN_5_0_0_OR_GREATER
95+
[TestMethod]
96+
public void ObservablePropertyWithValueType_OnPartialProperty_WithNoModifiers_CSharp14_WorksCorrectly()
97+
{
98+
string source = """
99+
using CommunityToolkit.Mvvm.ComponentModel;
100+
101+
namespace MyApp;
102+
103+
partial class MyViewModel : ObservableObject
104+
{
105+
[ObservableProperty]
106+
partial int Number { get; set; }
107+
}
108+
""";
109+
110+
string result = """
111+
// <auto-generated/>
112+
#pragma warning disable
113+
#nullable enable
114+
namespace MyApp
115+
{
116+
/// <inheritdoc/>
117+
partial class MyViewModel
118+
{
119+
/// <inheritdoc/>
120+
[global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", <ASSEMBLY_VERSION>)]
121+
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
122+
partial int Number
123+
{
124+
get => field;
125+
set
126+
{
127+
if (!global::System.Collections.Generic.EqualityComparer<int>.Default.Equals(field, value))
128+
{
129+
OnNumberChanging(value);
130+
OnNumberChanging(default, value);
131+
OnPropertyChanging(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangingArgs.Number);
132+
field = value;
133+
OnNumberChanged(value);
134+
OnNumberChanged(default, value);
135+
OnPropertyChanged(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedArgs.Number);
136+
}
137+
}
138+
}
139+
140+
/// <summary>Executes the logic for when <see cref="Number"/> is changing.</summary>
141+
/// <param name="value">The new property value being set.</param>
142+
/// <remarks>This method is invoked right before the value of <see cref="Number"/> is changed.</remarks>
143+
[global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", <ASSEMBLY_VERSION>)]
144+
partial void OnNumberChanging(int value);
145+
/// <summary>Executes the logic for when <see cref="Number"/> is changing.</summary>
146+
/// <param name="oldValue">The previous property value that is being replaced.</param>
147+
/// <param name="newValue">The new property value being set.</param>
148+
/// <remarks>This method is invoked right before the value of <see cref="Number"/> is changed.</remarks>
149+
[global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", <ASSEMBLY_VERSION>)]
150+
partial void OnNumberChanging(int oldValue, int newValue);
151+
/// <summary>Executes the logic for when <see cref="Number"/> just changed.</summary>
152+
/// <param name="value">The new property value that was set.</param>
153+
/// <remarks>This method is invoked right after the value of <see cref="Number"/> is changed.</remarks>
154+
[global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", <ASSEMBLY_VERSION>)]
155+
partial void OnNumberChanged(int value);
156+
/// <summary>Executes the logic for when <see cref="Number"/> just changed.</summary>
157+
/// <param name="oldValue">The previous property value that was replaced.</param>
158+
/// <param name="newValue">The new property value that was set.</param>
159+
/// <remarks>This method is invoked right after the value of <see cref="Number"/> is changed.</remarks>
160+
[global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", <ASSEMBLY_VERSION>)]
161+
partial void OnNumberChanged(int oldValue, int newValue);
162+
}
163+
}
164+
""";
165+
166+
VerifyGenerateSources(source, new[] { new ObservablePropertyGenerator() }, LanguageVersion.CSharp14, ("MyApp.MyViewModel.g.cs", result));
167+
}
168+
#endif
169+
94170
// See https://github.com/CommunityToolkit/dotnet/issues/969
95171
[TestMethod]
96172
public void ObservablePropertyWithValueType_OnPartialProperty_RequiredProperty_WorksCorrectly()

tests/CommunityToolkit.Mvvm.SourceGenerators.Roslyn4120.UnitTests/Test_SourceGeneratorsDiagnostics.cs

Lines changed: 55 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ namespace MyApp
2222
{
2323
public partial class SampleViewModel : ObservableObject
2424
{
25-
[ObservableProperty]
25+
[ObservableProperty]
2626
public string Name { get; set; }
2727
}
2828
}
@@ -41,7 +41,7 @@ namespace MyApp
4141
{
4242
public partial class SampleViewModel : ObservableObject
4343
{
44-
[{|MVVMTK0041:ObservableProperty|}]
44+
[{|MVVMTK0041:ObservableProperty|}]
4545
public partial string Name { get; set; }
4646
}
4747
}
@@ -67,7 +67,7 @@ namespace MyApp
6767
{
6868
public partial class SampleViewModel : ObservableObject
6969
{
70-
[{|MVVMTK0041:ObservableProperty|}]
70+
[{|MVVMTK0041:ObservableProperty|}]
7171
public partial string Name { get; set; }
7272
}
7373
}
@@ -81,6 +81,32 @@ await CSharpAnalyzerWithLanguageVersionTest<RequiresCSharpLanguageVersion14OrPre
8181
DiagnosticResult.CompilerError("CS9248").WithSpan(8, 31, 8, 35).WithArguments("MyApp.SampleViewModel.Name"));
8282
}
8383

84+
#if ROSLYN_5_0_0_OR_GREATER
85+
[TestMethod]
86+
public async Task RequireCSharpLanguageVersionPreviewAnalyzer_LanguageVersionIsNotPreview_CSharp14_Partial_DoesNotWarn()
87+
{
88+
const string source = """
89+
using CommunityToolkit.Mvvm.ComponentModel;
90+
91+
namespace MyApp
92+
{
93+
public partial class SampleViewModel : ObservableObject
94+
{
95+
[ObservableProperty]
96+
public partial string Name { get; set; }
97+
}
98+
}
99+
""";
100+
101+
await CSharpAnalyzerWithLanguageVersionTest<RequiresCSharpLanguageVersion14OrPreviewAnalyzer>.VerifyAnalyzerAsync(
102+
source,
103+
LanguageVersion.Preview,
104+
105+
// /0/Test0.cs(8,31): error CS9248: Partial property 'SampleViewModel.Name' must have an implementation part.
106+
DiagnosticResult.CompilerError("CS9248").WithSpan(8, 31, 8, 35).WithArguments("MyApp.SampleViewModel.Name"));
107+
}
108+
#endif
109+
84110
[TestMethod]
85111
public async Task RequireCSharpLanguageVersionPreviewAnalyzer_LanguageVersionIsPreview_DoesNotWarn()
86112
{
@@ -91,7 +117,7 @@ namespace MyApp
91117
{
92118
public partial class SampleViewModel : ObservableObject
93119
{
94-
[ObservableProperty]
120+
[ObservableProperty]
95121
public string Name { get; set; }
96122
}
97123
}
@@ -110,7 +136,7 @@ namespace MyApp
110136
{
111137
public partial class SampleViewModel : ObservableObject
112138
{
113-
[ObservableProperty]
139+
[ObservableProperty]
114140
public partial string Name { get; set; }
115141
}
116142
}
@@ -134,7 +160,7 @@ namespace MyApp
134160
{
135161
public partial class SampleViewModel : ObservableObject
136162
{
137-
[ObservableProperty]
163+
[ObservableProperty]
138164
private string name;
139165
}
140166
}
@@ -153,7 +179,7 @@ namespace MyApp
153179
{
154180
public partial class SampleViewModel : ObservableObject
155181
{
156-
[ObservableProperty]
182+
[ObservableProperty]
157183
private string {|MVVMTK0042:name|};
158184
}
159185
}
@@ -172,7 +198,7 @@ namespace MyApp
172198
{
173199
public partial class SampleViewModel : ObservableObject
174200
{
175-
[ObservableProperty]
201+
[ObservableProperty]
176202
public string Name { get; set; }
177203
}
178204
}
@@ -191,7 +217,7 @@ namespace MyApp
191217
{
192218
public partial class SampleViewModel : ObservableObject
193219
{
194-
[ObservableProperty]
220+
[ObservableProperty]
195221
public partial string {|CS9248:Name|} { get; set; }
196222
}
197223
}
@@ -210,7 +236,7 @@ namespace MyApp
210236
{
211237
public partial class SampleViewModel : ObservableObject
212238
{
213-
[ObservableProperty]
239+
[ObservableProperty]
214240
internal partial string {|CS9248:Name|} { get; private set; }
215241
}
216242
}
@@ -229,7 +255,7 @@ namespace MyApp
229255
{
230256
public partial class SampleViewModel : ObservableObject
231257
{
232-
[ObservableProperty]
258+
[ObservableProperty]
233259
protected internal partial string {|CS9248:Name|} { get; private protected set; }
234260
}
235261
}
@@ -248,7 +274,7 @@ namespace MyApp
248274
{
249275
public partial class SampleViewModel : ObservableObject
250276
{
251-
[{|MVVMTK0043:ObservableProperty|}]
277+
[{|MVVMTK0043:ObservableProperty|}]
252278
public string Name { get; set; }
253279
}
254280
}
@@ -267,7 +293,7 @@ namespace MyApp
267293
{
268294
public partial class SampleViewModel : ObservableObject
269295
{
270-
[{|MVVMTK0043:ObservableProperty|}]
296+
[{|MVVMTK0043:ObservableProperty|}]
271297
public static partial string {|CS9248:Name|} { get; set; }
272298
}
273299
}
@@ -286,7 +312,7 @@ namespace MyApp
286312
{
287313
public partial class SampleViewModel : ObservableObject
288314
{
289-
[{|MVVMTK0043:ObservableProperty|}]
315+
[{|MVVMTK0043:ObservableProperty|}]
290316
public partial string {|CS9248:Name|} { get; }
291317
}
292318
}
@@ -305,7 +331,7 @@ namespace MyApp
305331
{
306332
public partial class SampleViewModel : ObservableObject
307333
{
308-
[{|MVVMTK0043:ObservableProperty|}]
334+
[{|MVVMTK0043:ObservableProperty|}]
309335
public partial string {|CS9248:Name|} { set; }
310336
}
311337
}
@@ -325,7 +351,7 @@ namespace MyApp
325351
{
326352
public partial class SampleViewModel : ObservableObject
327353
{
328-
[{|MVVMTK0043:ObservableProperty|}]
354+
[{|MVVMTK0043:ObservableProperty|}]
329355
public partial string {|CS9248:Name|} { get; init; }
330356
}
331357
}
@@ -358,7 +384,7 @@ namespace MyApp
358384
{
359385
public partial class SampleViewModel : ObservableObject
360386
{
361-
[ObservableProperty]
387+
[ObservableProperty]
362388
private static string name;
363389
}
364390
}
@@ -377,7 +403,7 @@ namespace MyApp
377403
{
378404
public partial class SampleViewModel : ObservableObject
379405
{
380-
[ObservableProperty]
406+
[ObservableProperty]
381407
private static string name;
382408
}
383409
}
@@ -399,7 +425,7 @@ namespace MyApp
399425
{
400426
public partial class SampleViewModel : ObservableObject
401427
{
402-
[ObservableProperty]
428+
[ObservableProperty]
403429
private string name;
404430
}
405431
}
@@ -421,7 +447,7 @@ namespace MyApp
421447
{
422448
public partial class SampleViewModel : ObservableObject
423449
{
424-
[ObservableProperty]
450+
[ObservableProperty]
425451
private string name;
426452
}
427453
}
@@ -443,7 +469,7 @@ namespace MyApp
443469
{
444470
public partial class SampleViewModel : ObservableObject
445471
{
446-
[ObservableProperty]
472+
[ObservableProperty]
447473
private string name;
448474
}
449475
}
@@ -465,7 +491,7 @@ namespace MyApp
465491
{
466492
public partial class SampleViewModel : ObservableObject
467493
{
468-
[ObservableProperty]
494+
[ObservableProperty]
469495
private string {|MVVMTK0045:name|};
470496
}
471497
}
@@ -565,7 +591,7 @@ namespace MyApp
565591
{
566592
public partial class SampleViewModel : ObservableObject
567593
{
568-
[ObservableProperty]
594+
[ObservableProperty]
569595
private string name;
570596
}
571597
}
@@ -587,7 +613,7 @@ namespace MyApp
587613
{
588614
public partial class SampleViewModel : ObservableObject
589615
{
590-
[ObservableProperty]
616+
[ObservableProperty]
591617
private string {|MVVMTK0045:name|};
592618
}
593619
}
@@ -609,7 +635,7 @@ namespace MyApp
609635
{
610636
public partial class SampleViewModel : ObservableObject
611637
{
612-
[ObservableProperty]
638+
[ObservableProperty]
613639
private string {|MVVMTK0045:name|};
614640
}
615641
}
@@ -631,7 +657,7 @@ namespace MyApp
631657
{
632658
public partial class SampleViewModel : ObservableObject
633659
{
634-
[ObservableProperty]
660+
[ObservableProperty]
635661
private string {|MVVMTK0045:name|};
636662
}
637663
}
@@ -658,7 +684,7 @@ namespace MyApp
658684
{
659685
public partial class SampleViewModel : ObservableObject
660686
{
661-
[ObservableProperty]
687+
[ObservableProperty]
662688
private string {|MVVMTK0045:name|};
663689
}
664690
}
@@ -1016,7 +1042,7 @@ namespace MyApp
10161042
{
10171043
public partial class SampleViewModel : ObservableObject
10181044
{
1019-
[ObservableProperty]
1045+
[ObservableProperty]
10201046
public partial string {|CS9248:Name|} { get; set; }
10211047
}
10221048
}
@@ -1060,7 +1086,7 @@ namespace MyApp
10601086
{
10611087
public partial class SampleViewModel : ObservableObject
10621088
{
1063-
[ObservableProperty]
1089+
[ObservableProperty]
10641090
public partial string Name { get; set; }
10651091
10661092
[GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "1.0.0")]

0 commit comments

Comments
 (0)