Skip to content

Commit eb472bb

Browse files
henonKeboo
authored andcommitted
changed DialogHost to use a TaskCompletionSource (#1163)
* changed DialogHost to use a TaskCompletionSource to await the session end instead of a ManualResetEvent * DialogHost: expose a public getter for current DialogSession for more convenient programmatic dialog management * Removing old commented code. Moving TCS to DialogHost from DialogSession. * Fixing issue with TCS not being recreated * Adding unit tests for the DialogHost. Fixing issue that could occur if the DialogHost was opened with the static Show method and closed with its IsOpen
1 parent fad5b85 commit eb472bb

File tree

9 files changed

+230
-39
lines changed

9 files changed

+230
-39
lines changed
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
using System.Windows;
4+
using Xunit;
5+
6+
namespace MaterialDesignThemes.Wpf.Tests
7+
{
8+
public class DialogHostTests : IDisposable
9+
{
10+
private readonly DialogHost _dialogHost;
11+
12+
public DialogHostTests()
13+
{
14+
_dialogHost = new DialogHost();
15+
_dialogHost.RaiseEvent(new RoutedEventArgs(FrameworkElement.LoadedEvent));
16+
}
17+
18+
public void Dispose()
19+
{
20+
_dialogHost.RaiseEvent(new RoutedEventArgs(FrameworkElement.UnloadedEvent));
21+
}
22+
23+
[StaFact(Timeout = 500)]
24+
public void CanOpenAndCloseDialogWithIsOpen()
25+
{
26+
_dialogHost.IsOpen = true;
27+
DialogSession session = _dialogHost.CurrentSession;
28+
Assert.False(session.IsEnded);
29+
_dialogHost.IsOpen = false;
30+
31+
Assert.False(_dialogHost.IsOpen);
32+
Assert.Null(_dialogHost.CurrentSession);
33+
Assert.True(session.IsEnded);
34+
}
35+
36+
[StaFact(Timeout = 500)]
37+
public async Task CanOpenAndCloseDialogWithShowMethod()
38+
{
39+
var id = Guid.NewGuid();
40+
_dialogHost.Identifier = id;
41+
42+
object result = await DialogHost.Show("Content", id,
43+
new DialogOpenedEventHandler(((sender, args) => { args.Session.Close(42); })));
44+
45+
Assert.Equal(42, result);
46+
Assert.False(_dialogHost.IsOpen);
47+
}
48+
49+
[StaFact(Timeout = 500)]
50+
public async Task CanOpenDialogWithShowMethodAndCloseWithIsOpen()
51+
{
52+
var id = Guid.NewGuid();
53+
_dialogHost.Identifier = id;
54+
55+
object result = await DialogHost.Show("Content", id,
56+
new DialogOpenedEventHandler(((sender, args) => { _dialogHost.IsOpen = false; })));
57+
58+
Assert.Null(result);
59+
Assert.False(_dialogHost.IsOpen);
60+
}
61+
62+
[StaFact(Timeout = 500)]
63+
public async Task DialogHostExposesSessionAsProperty()
64+
{
65+
var id = Guid.NewGuid();
66+
_dialogHost.Identifier = id;
67+
68+
await DialogHost.Show("Content", id,
69+
new DialogOpenedEventHandler(((sender, args) =>
70+
{
71+
Assert.True(ReferenceEquals(args.Session, _dialogHost.CurrentSession));
72+
args.Session.Close();
73+
})));
74+
}
75+
76+
[StaFact(Timeout = 500)]
77+
public async Task CannotShowDialogWhileItIsAlreadyOpen()
78+
{
79+
var id = Guid.NewGuid();
80+
_dialogHost.Identifier = id;
81+
82+
await DialogHost.Show("Content", id,
83+
new DialogOpenedEventHandler((async (sender, args) =>
84+
{
85+
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => DialogHost.Show("Content", id));
86+
args.Session.Close();
87+
Assert.Equal("DialogHost is already open.", ex.Message);
88+
})));
89+
}
90+
91+
[StaFact(Timeout = 500)]
92+
public async Task WhenNoDialogsAreOpenItThrows()
93+
{
94+
var id = Guid.NewGuid();
95+
_dialogHost.RaiseEvent(new RoutedEventArgs(FrameworkElement.UnloadedEvent));
96+
97+
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => DialogHost.Show("Content", id));
98+
99+
Assert.Equal("No loaded DialogHost instances.", ex.Message);
100+
}
101+
102+
[StaFact(Timeout = 500)]
103+
public async Task WhenNoDialogsMatchIdentifierItThrows()
104+
{
105+
var id = Guid.NewGuid();
106+
107+
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => DialogHost.Show("Content", id));
108+
109+
Assert.Equal($"No loaded DialogHost have an {nameof(DialogHost.Identifier)} property matching dialogIdentifier argument.", ex.Message);
110+
}
111+
112+
[StaFact(Timeout = 500)]
113+
public async Task WhenMultipleDialogHostsHaveTheSameIdentifierItThrows()
114+
{
115+
var id = Guid.NewGuid();
116+
_dialogHost.Identifier = id;
117+
var otherDialogHost = new DialogHost { Identifier = id };
118+
otherDialogHost.RaiseEvent(new RoutedEventArgs(FrameworkElement.LoadedEvent));
119+
120+
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => DialogHost.Show("Content", id));
121+
122+
otherDialogHost.RaiseEvent(new RoutedEventArgs(FrameworkElement.UnloadedEvent));
123+
124+
125+
Assert.Equal("Multiple viable DialogHosts. Specify a unique Identifier on each DialogHost, especially where multiple Windows are a concern.", ex.Message);
126+
}
127+
128+
[StaFact(Timeout = 500)]
129+
public async Task WhenNoIdentifierIsSpecifiedItUsesSingleDialogHost()
130+
{
131+
bool isOpen = false;
132+
await DialogHost.Show("Content", new DialogOpenedEventHandler(((sender, args) =>
133+
{
134+
isOpen = _dialogHost.IsOpen;
135+
args.Session.Close();
136+
})));
137+
138+
Assert.True(isOpen);
139+
}
140+
141+
[StaFact(Timeout = 500)]
142+
public async Task WhenContentIsNullItThrows()
143+
{
144+
var ex = await Assert.ThrowsAsync<ArgumentNullException>(() => DialogHost.Show(null));
145+
146+
Assert.Equal("content", ex.ParamName);
147+
}
148+
}
149+
}

MaterialDesignThemes.Wpf.Tests/MaterialDesignThemes.Wpf.Tests.csproj

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
<WarningLevel>4</WarningLevel>
3232
</PropertyGroup>
3333
<ItemGroup>
34+
<Reference Include="PresentationCore" />
35+
<Reference Include="PresentationFramework" />
3436
<Reference Include="System" />
3537
<Reference Include="System.Core" />
3638
<Reference Include="System.Xml.Linq" />
@@ -41,6 +43,7 @@
4143
<Reference Include="System.Xml" />
4244
</ItemGroup>
4345
<ItemGroup>
46+
<Compile Include="DialogHostTests.cs" />
4447
<Compile Include="PaletteHelperFixture.cs" />
4548
<Compile Include="Properties\AssemblyInfo.cs" />
4649
</ItemGroup>
@@ -248,5 +251,37 @@
248251
</ItemGroup>
249252
</When>
250253
</Choose>
254+
<Choose>
255+
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5'">
256+
<ItemGroup>
257+
<Reference Include="System.Windows.Forms">
258+
<Paket>True</Paket>
259+
</Reference>
260+
<Reference Include="WindowsBase">
261+
<Paket>True</Paket>
262+
</Reference>
263+
<Reference Include="Xunit.StaFact">
264+
<HintPath>..\packages\Xunit.StaFact\lib\net45\Xunit.StaFact.dll</HintPath>
265+
<Private>True</Private>
266+
<Paket>True</Paket>
267+
</Reference>
268+
</ItemGroup>
269+
</When>
270+
<When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.5.2'">
271+
<ItemGroup>
272+
<Reference Include="System.Windows.Forms">
273+
<Paket>True</Paket>
274+
</Reference>
275+
<Reference Include="WindowsBase">
276+
<Paket>True</Paket>
277+
</Reference>
278+
<Reference Include="Xunit.StaFact">
279+
<HintPath>..\packages\Xunit.StaFact\lib\net452\Xunit.StaFact.dll</HintPath>
280+
<Private>True</Private>
281+
<Paket>True</Paket>
282+
</Reference>
283+
</ItemGroup>
284+
</When>
285+
</Choose>
251286
<Import Project="..\packages\xunit.core\build\xunit.core.targets" Condition="Exists('..\packages\xunit.core\build\xunit.core.targets')" Label="Paket" />
252287
</Project>

MaterialDesignThemes.Wpf.Tests/Properties/AssemblyInfo.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Reflection;
22
using System.Runtime.InteropServices;
3+
using Xunit;
34

45
// General Information about an assembly is controlled through the following
56
// set of attributes. Change these attribute values to modify the information
@@ -33,3 +34,5 @@
3334
// [assembly: AssemblyVersion("1.0.*")]
3435
[assembly: AssemblyVersion("1.0.0.0")]
3536
[assembly: AssemblyFileVersion("1.0.0.0")]
37+
38+
[assembly: CollectionBehavior(DisableTestParallelization = true)]

MaterialDesignThemes.Wpf.Tests/paket.references

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ NSubstitute
33
RhinoMocks
44
Shouldly
55
xunit
6-
xunit.runner.visualstudio
6+
xunit.runner.visualstudio
7+
Xunit.StaFact

0 commit comments

Comments
 (0)