Skip to content

Commit 2613c56

Browse files
committed
Improved test coverage
1 parent 603e9d8 commit 2613c56

File tree

4 files changed

+285
-4
lines changed

4 files changed

+285
-4
lines changed
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System;
6+
using System.Diagnostics.CodeAnalysis;
7+
using System.Threading.Tasks;
8+
using Microsoft.Toolkit.Mvvm.Input;
9+
using Microsoft.VisualStudio.TestTools.UnitTesting;
10+
11+
namespace UnitTests.Mvvm
12+
{
13+
[TestClass]
14+
[SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649", Justification = "Generic type")]
15+
public class Test_AsyncRelayCommandOfT
16+
{
17+
[TestCategory("Mvvm")]
18+
[TestMethod]
19+
public async Task Test_AsyncRelayCommandOfT_AlwaysEnabled()
20+
{
21+
int ticks = 0;
22+
23+
var command = new AsyncRelayCommand<string>(async s =>
24+
{
25+
await Task.Delay(1000);
26+
ticks = int.Parse(s);
27+
await Task.Delay(1000);
28+
});
29+
30+
Assert.IsTrue(command.CanExecute(null));
31+
Assert.IsTrue(command.CanExecute("1"));
32+
33+
(object, EventArgs) args = default;
34+
35+
command.CanExecuteChanged += (s, e) => args = (s, e);
36+
37+
command.NotifyCanExecuteChanged();
38+
39+
Assert.AreSame(args.Item1, command);
40+
Assert.AreSame(args.Item2, EventArgs.Empty);
41+
42+
Assert.IsNull(command.ExecutionTask);
43+
Assert.IsFalse(command.IsRunning);
44+
45+
Task task = command.ExecuteAsync((object)"42");
46+
47+
Assert.IsNotNull(command.ExecutionTask);
48+
Assert.AreSame(command.ExecutionTask, task);
49+
Assert.IsTrue(command.IsRunning);
50+
51+
await task;
52+
53+
Assert.IsFalse(command.IsRunning);
54+
55+
Assert.AreEqual(ticks, 42);
56+
57+
command.Execute("2");
58+
59+
await command.ExecutionTask!;
60+
61+
Assert.AreEqual(ticks, 2);
62+
63+
Assert.ThrowsException<InvalidCastException>(() => command.Execute(new object()));
64+
}
65+
66+
[TestCategory("Mvvm")]
67+
[TestMethod]
68+
public void Test_AsyncRelayCommandOfT_WithCanExecuteFunctionTrue()
69+
{
70+
int ticks = 0;
71+
72+
var command = new AsyncRelayCommand<string>(
73+
s =>
74+
{
75+
ticks = int.Parse(s);
76+
return Task.CompletedTask;
77+
}, s => true);
78+
79+
Assert.IsTrue(command.CanExecute(null));
80+
Assert.IsTrue(command.CanExecute("1"));
81+
82+
command.Execute("42");
83+
84+
Assert.AreEqual(ticks, 42);
85+
86+
command.Execute("2");
87+
88+
Assert.AreEqual(ticks, 2);
89+
}
90+
91+
[TestCategory("Mvvm")]
92+
[TestMethod]
93+
public void Test_AsyncRelayCommandOfT_WithCanExecuteFunctionFalse()
94+
{
95+
int ticks = 0;
96+
97+
var command = new AsyncRelayCommand<string>(
98+
s =>
99+
{
100+
ticks = int.Parse(s);
101+
return Task.CompletedTask;
102+
}, s => false);
103+
104+
Assert.IsFalse(command.CanExecute(null));
105+
Assert.IsFalse(command.CanExecute("1"));
106+
107+
command.Execute("2");
108+
109+
Assert.AreEqual(ticks, 0);
110+
111+
command.Execute("42");
112+
113+
Assert.AreEqual(ticks, 0);
114+
}
115+
116+
[TestCategory("Mvvm")]
117+
[TestMethod]
118+
public void Test_AsyncRelayCommandOfT_NullWithValueType()
119+
{
120+
int n = 0;
121+
122+
var command = new AsyncRelayCommand<int>(i =>
123+
{
124+
n = i;
125+
return Task.CompletedTask;
126+
});
127+
128+
// Special case for null value types
129+
Assert.IsTrue(command.CanExecute(null));
130+
131+
command = new AsyncRelayCommand<int>(
132+
i =>
133+
{
134+
n = i;
135+
return Task.CompletedTask;
136+
}, i => i > 0);
137+
138+
Assert.ThrowsException<NullReferenceException>(() => command.CanExecute(null));
139+
}
140+
}
141+
}

UnitTests/UnitTests.Shared/Mvvm/Test_Messenger.cs

Lines changed: 125 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// See the LICENSE file in the project root for more information.
44

55
using System;
6+
using System.Linq;
7+
using System.Reflection;
68
using Microsoft.Toolkit.Mvvm.Messaging;
79
using Microsoft.VisualStudio.TestTools.UnitTesting;
810

@@ -390,13 +392,134 @@ void Test()
390392
Assert.AreEqual(!isWeak, weakRecipient.IsAlive);
391393
}
392394

395+
[TestCategory("Mvvm")]
396+
[TestMethod]
397+
[DataRow(typeof(Messenger))]
398+
[DataRow(typeof(WeakRefMessenger))]
399+
public void Test_Messenger_Reset(Type type)
400+
{
401+
var messenger = (IMessenger)Activator.CreateInstance(type);
402+
var recipient = new RecipientWithSomeMessages();
403+
404+
messenger.RegisterAll(recipient);
405+
406+
Assert.IsTrue(messenger.IsRegistered<MessageA>(recipient));
407+
Assert.IsTrue(messenger.IsRegistered<MessageB>(recipient));
408+
409+
messenger.Reset();
410+
411+
Assert.IsFalse(messenger.IsRegistered<MessageA>(recipient));
412+
Assert.IsFalse(messenger.IsRegistered<MessageB>(recipient));
413+
}
414+
415+
[TestCategory("Mvvm")]
416+
[TestMethod]
417+
[DataRow(typeof(Messenger))]
418+
[DataRow(typeof(WeakRefMessenger))]
419+
public void Test_Messenger_Default(Type type)
420+
{
421+
PropertyInfo defaultInfo = type.GetProperty("Default");
422+
423+
var default1 = defaultInfo!.GetValue(null);
424+
var default2 = defaultInfo!.GetValue(null);
425+
426+
Assert.IsNotNull(default1);
427+
Assert.IsNotNull(default2);
428+
Assert.AreSame(default1, default2);
429+
}
430+
431+
[TestCategory("Mvvm")]
432+
[TestMethod]
433+
[DataRow(typeof(Messenger))]
434+
[DataRow(typeof(WeakRefMessenger))]
435+
public void Test_Messenger_Cleanup(Type type)
436+
{
437+
var messenger = (IMessenger)Activator.CreateInstance(type);
438+
var recipient = new RecipientWithSomeMessages();
439+
440+
messenger.Register<MessageA>(recipient);
441+
442+
Assert.IsTrue(messenger.IsRegistered<MessageA>(recipient));
443+
444+
void Test()
445+
{
446+
var recipient2 = new RecipientWithSomeMessages();
447+
448+
messenger.Register<MessageB>(recipient2);
449+
450+
Assert.IsTrue(messenger.IsRegistered<MessageB>(recipient2));
451+
452+
GC.KeepAlive(recipient2);
453+
}
454+
455+
Test();
456+
457+
GC.Collect();
458+
459+
// Here we just check that calling Cleanup doesn't alter the state
460+
// of the messenger. This method shouldn't really do anything visible
461+
// to consumers, it's just a way for messengers to compact their data.
462+
messenger.Cleanup();
463+
464+
Assert.IsTrue(messenger.IsRegistered<MessageA>(recipient));
465+
}
466+
467+
[TestCategory("Mvvm")]
468+
[TestMethod]
469+
[DataRow(typeof(Messenger))]
470+
[DataRow(typeof(WeakRefMessenger))]
471+
public void Test_Messenger_ManyRecipients(Type type)
472+
{
473+
var messenger = (IMessenger)Activator.CreateInstance(type);
474+
475+
void Test()
476+
{
477+
var recipients = Enumerable.Range(0, 512).Select(_ => new RecipientWithSomeMessages()).ToArray();
478+
479+
foreach (var recipient in recipients)
480+
{
481+
messenger.RegisterAll(recipient);
482+
}
483+
484+
foreach (var recipient in recipients)
485+
{
486+
Assert.IsTrue(messenger.IsRegistered<MessageA>(recipient));
487+
Assert.IsTrue(messenger.IsRegistered<MessageB>(recipient));
488+
}
489+
490+
messenger.Send<MessageA>();
491+
messenger.Send<MessageB>();
492+
messenger.Send<MessageB>();
493+
494+
foreach (var recipient in recipients)
495+
{
496+
Assert.AreEqual(recipient.As, 1);
497+
Assert.AreEqual(recipient.Bs, 2);
498+
}
499+
500+
foreach (ref var recipient in recipients.AsSpan())
501+
{
502+
recipient = null;
503+
}
504+
}
505+
506+
Test();
507+
508+
GC.Collect();
509+
510+
// Just invoke a final cleanup to improve coverage, this is unrelated to this test in particular
511+
messenger.Cleanup();
512+
}
513+
393514
public sealed class RecipientWithNoMessages
394515
{
395516
public int Number { get; set; }
396517
}
397518

398-
public sealed class RecipientWithSomeMessages
399-
: IRecipient<MessageA>, ICloneable, IRecipient<MessageB>
519+
public sealed class RecipientWithSomeMessages :
520+
IRecipient<MessageA>,
521+
IRecipient<MessageB>,
522+
ICloneable
400523
{
401524
public int As { get; private set; }
402525

UnitTests/UnitTests.Shared/Mvvm/Test_RelayCommand{T}.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public void Test_RelayCommandOfT_AlwaysEnabled()
3535
Assert.AreSame(args.Item1, command);
3636
Assert.AreSame(args.Item2, EventArgs.Empty);
3737

38-
command.Execute("Hello");
38+
command.Execute((object)"Hello");
3939

4040
Assert.AreEqual(text, "Hello");
4141

@@ -57,13 +57,29 @@ public void Test_RelayCommand_WithCanExecuteFunction()
5757

5858
Assert.ThrowsException<InvalidCastException>(() => command.CanExecute(new object()));
5959

60-
command.Execute("Hello");
60+
command.Execute((object)"Hello");
6161

6262
Assert.AreEqual(text, "Hello");
6363

6464
command.Execute(null);
6565

6666
Assert.AreEqual(text, "Hello");
6767
}
68+
69+
[TestCategory("Mvvm")]
70+
[TestMethod]
71+
public void Test_RelayCommand_NullWithValueType()
72+
{
73+
int n = 0;
74+
75+
var command = new RelayCommand<int>(i => n = i);
76+
77+
// Special case for null value types
78+
Assert.IsTrue(command.CanExecute(null));
79+
80+
command = new RelayCommand<int>(i => n = i, i => i > 0);
81+
82+
Assert.ThrowsException<NullReferenceException>(() => command.CanExecute(null));
83+
}
6884
}
6985
}

UnitTests/UnitTests.Shared/UnitTests.Shared.projitems

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
<Compile Include="$(MSBuildThisFileDirectory)Extensions\Test_ArrayExtensions.cs" />
2424
<Compile Include="$(MSBuildThisFileDirectory)Extensions\Test_TypeExtensions.cs" />
2525
<Compile Include="$(MSBuildThisFileDirectory)Extensions\Test_ValueTypeExtensions.cs" />
26+
<Compile Include="$(MSBuildThisFileDirectory)Mvvm\Test_AsyncRelayCommand{T}.cs" />
2627
<Compile Include="$(MSBuildThisFileDirectory)Mvvm\Test_Ioc.cs" />
2728
<Compile Include="$(MSBuildThisFileDirectory)Mvvm\Test_Messenger.Request.cs" />
2829
<Compile Include="$(MSBuildThisFileDirectory)Mvvm\Test_Messenger.cs" />

0 commit comments

Comments
 (0)