Skip to content

Commit 6e734ef

Browse files
committed
Add unit tests
1 parent 4bb6067 commit 6e734ef

File tree

1 file changed

+117
-0
lines changed

1 file changed

+117
-0
lines changed

tests/CommunityToolkit.Mvvm.UnitTests/Test_ObservablePropertyAttribute.cs

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,105 @@ private void Test_AlsoBroadcastChange_Test<T>(Func<IMessenger, T> factory, Actio
418418
Assert.AreEqual(propertyName, messages[0].Message.PropertyName);
419419
}
420420

421+
#if NET6_0_OR_GREATER
422+
// See https://github.com/CommunityToolkit/dotnet/issues/155
423+
[TestMethod]
424+
public void Test_ObservableProperty_NullabilityAnnotations_Simple()
425+
{
426+
// List<string?>?
427+
NullabilityInfoContext context = new();
428+
NullabilityInfo info = context.Create(typeof(NullableRepro).GetProperty(nameof(NullableRepro.NullableList))!);
429+
430+
Assert.AreEqual(typeof(List<string>), info.Type);
431+
Assert.AreEqual(NullabilityState.Nullable, info.ReadState);
432+
Assert.AreEqual(NullabilityState.Nullable, info.WriteState);
433+
Assert.AreEqual(1, info.GenericTypeArguments.Length);
434+
435+
NullabilityInfo elementInfo = info.GenericTypeArguments[0];
436+
437+
Assert.AreEqual(typeof(string), elementInfo.Type);
438+
Assert.AreEqual(NullabilityState.Nullable, elementInfo.ReadState);
439+
Assert.AreEqual(NullabilityState.Nullable, elementInfo.WriteState);
440+
}
441+
442+
// See https://github.com/CommunityToolkit/dotnet/issues/155
443+
[TestMethod]
444+
public void Test_ObservableProperty_NullabilityAnnotations_Complex()
445+
{
446+
// Foo<Foo<string?, int>.Bar<object?>?, StrongBox<Foo<int, string?>.Bar<object>?>?>?
447+
NullabilityInfoContext context = new();
448+
NullabilityInfo info = context.Create(typeof(NullableRepro).GetProperty(nameof(NullableRepro.NullableMess))!);
449+
450+
Assert.AreEqual(typeof(Foo<Foo<string?, int>.Bar<object?>?, StrongBox<Foo<int, string?>.Bar<object>?>?>), info.Type);
451+
Assert.AreEqual(NullabilityState.Nullable, info.ReadState);
452+
Assert.AreEqual(NullabilityState.Nullable, info.WriteState);
453+
Assert.AreEqual(2, info.GenericTypeArguments.Length);
454+
455+
NullabilityInfo leftInfo = info.GenericTypeArguments[0];
456+
457+
Assert.AreEqual(typeof(Foo<string?, int>.Bar<object?>), leftInfo.Type);
458+
Assert.AreEqual(NullabilityState.Nullable, leftInfo.ReadState);
459+
Assert.AreEqual(NullabilityState.Nullable, leftInfo.WriteState);
460+
Assert.AreEqual(3, leftInfo.GenericTypeArguments.Length);
461+
462+
NullabilityInfo leftInfo0 = leftInfo.GenericTypeArguments[0];
463+
464+
Assert.AreEqual(typeof(string), leftInfo0.Type);
465+
Assert.AreEqual(NullabilityState.Nullable, leftInfo0.ReadState);
466+
Assert.AreEqual(NullabilityState.Nullable, leftInfo0.WriteState);
467+
468+
NullabilityInfo leftInfo1 = leftInfo.GenericTypeArguments[1];
469+
470+
Assert.AreEqual(typeof(int), leftInfo1.Type);
471+
Assert.AreEqual(NullabilityState.NotNull, leftInfo1.ReadState);
472+
Assert.AreEqual(NullabilityState.NotNull, leftInfo1.WriteState);
473+
474+
NullabilityInfo leftInfo2 = leftInfo.GenericTypeArguments[2];
475+
476+
Assert.AreEqual(typeof(object), leftInfo2.Type);
477+
Assert.AreEqual(NullabilityState.Nullable, leftInfo2.ReadState);
478+
Assert.AreEqual(NullabilityState.Nullable, leftInfo2.WriteState);
479+
480+
NullabilityInfo rightInfo = info.GenericTypeArguments[1];
481+
482+
Assert.AreEqual(typeof(StrongBox<Foo<int, string?>.Bar<object>?>), rightInfo.Type);
483+
Assert.AreEqual(NullabilityState.Nullable, rightInfo.ReadState);
484+
Assert.AreEqual(NullabilityState.Nullable, rightInfo.WriteState);
485+
Assert.AreEqual(1, rightInfo.GenericTypeArguments.Length);
486+
487+
NullabilityInfo rightInnerInfo = rightInfo.GenericTypeArguments[0];
488+
489+
Assert.AreEqual(typeof(Foo<int, string?>.Bar<object>), rightInnerInfo.Type);
490+
Assert.AreEqual(NullabilityState.Nullable, rightInnerInfo.ReadState);
491+
Assert.AreEqual(NullabilityState.Nullable, rightInnerInfo.WriteState);
492+
Assert.AreEqual(3, rightInnerInfo.GenericTypeArguments.Length);
493+
494+
NullabilityInfo rightInfo0 = rightInnerInfo.GenericTypeArguments[0];
495+
496+
Assert.AreEqual(typeof(int), rightInfo0.Type);
497+
Assert.AreEqual(NullabilityState.NotNull, rightInfo0.ReadState);
498+
Assert.AreEqual(NullabilityState.NotNull, rightInfo0.WriteState);
499+
500+
NullabilityInfo rightInfo1 = rightInnerInfo.GenericTypeArguments[1];
501+
502+
Assert.AreEqual(typeof(string), rightInfo1.Type);
503+
Assert.AreEqual(NullabilityState.Nullable, rightInfo1.ReadState);
504+
Assert.AreEqual(NullabilityState.Nullable, rightInfo1.WriteState);
505+
506+
NullabilityInfo rightInfo2 = rightInnerInfo.GenericTypeArguments[2];
507+
508+
Assert.AreEqual(typeof(object), rightInfo2.Type);
509+
//Assert.AreEqual(NullabilityState.NotNull, rightInfo2.ReadState);
510+
//Assert.AreEqual(NullabilityState.NotNull, rightInfo2.WriteState);
511+
512+
// The commented out lines are to work around a weird behavior of the NullabilityInfo API there.
513+
// Arguably we're pushing them a bit far here, but it's fine. Even with those cases commented out,
514+
// the test is already more than enough, plus we can also double check the behavior by looking at
515+
// the generated code. Thoe lines can be uncommented once the behavior is either clarified, or if
516+
// it happens to be a bug which is then fixed in a future version of .NET, once we upgrade as well.
517+
}
518+
#endif
519+
421520
public partial class SampleModel : ObservableObject
422521
{
423522
/// <summary>
@@ -705,4 +804,22 @@ public BroadcastingViewModelWithInheritedAttribute(IMessenger messenger)
705804
[AlsoBroadcastChange]
706805
private string? name2;
707806
}
807+
808+
#if NET6_0_OR_GREATER
809+
private partial class NullableRepro : ObservableObject
810+
{
811+
[ObservableProperty]
812+
private List<string?>? nullableList;
813+
814+
[ObservableProperty]
815+
private Foo<Foo<string?, int>.Bar<object?>?, StrongBox<Foo<int, string?>.Bar<object>?>?>? nullableMess;
816+
}
817+
818+
private class Foo<T1, T2>
819+
{
820+
public class Bar<T>
821+
{
822+
}
823+
}
824+
#endif
708825
}

0 commit comments

Comments
 (0)