4
4
using CommunityToolkit . Maui . UnitTests . Views ;
5
5
using CommunityToolkit . Maui . Views ;
6
6
using FluentAssertions ;
7
+ using Microsoft . Maui . Dispatching ;
7
8
using Xunit ;
8
9
9
10
namespace CommunityToolkit . Maui . UnitTests ;
@@ -13,23 +14,16 @@ public class PopupServiceTests : BaseHandlerTest
13
14
public PopupServiceTests ( )
14
15
{
15
16
var page = new MockPage ( new MockPageViewModel ( ) ) ;
16
- var serviceCollection = new ServiceCollection ( ) ;
17
- PopupService . AddPopup < MockPopup , MockPageViewModel > ( serviceCollection , ServiceLifetime . Transient ) ;
18
- CreateViewHandler < MockPageHandler > ( page ) ;
19
-
20
17
Assert . NotNull ( Application . Current ) ;
21
18
Application . Current . Windows [ 0 ] . Page = page ;
22
19
}
23
20
24
21
[ Fact ]
25
- public async Task ShowPopupAsyncWithNullOnPresentingShouldThrowArgumentNullException ( )
22
+ public async Task ShowPopupAsyncWithNotRegisteredServiceShouldThrowInvalidOperationException ( )
26
23
{
27
24
var popupService = ServiceProvider . GetRequiredService < IPopupService > ( ) ;
28
25
29
- #pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
30
- await Assert . ThrowsAsync < ArgumentNullException > ( ( ) =>
31
- popupService . ShowPopupAsync < INotifyPropertyChanged > ( new PopupOptions ( ) , CancellationToken . None ) ) ;
32
- #pragma warning restore CS8625 // Cannot convert null literal to non-nullable reference type.
26
+ await Assert . ThrowsAsync < InvalidOperationException > ( ( ) => popupService . ShowPopupAsync ( new PopupOptions < INotifyPropertyChanged > ( ) , CancellationToken . None ) ) ;
33
27
}
34
28
35
29
[ Fact ( Timeout = ( int ) TestDuration . Short ) ]
@@ -42,7 +36,7 @@ public async Task ShowPopupAsync_CancellationTokenExpired()
42
36
// Ensure CancellationToken has expired
43
37
await Task . Delay ( 100 , CancellationToken . None ) ;
44
38
45
- await Assert . ThrowsAsync < TaskCanceledException > ( ( ) => popupService . ShowPopupAsync < MockPageViewModel > ( new PopupOptions ( ) , cts . Token ) ) ;
39
+ await Assert . ThrowsAsync < TaskCanceledException > ( ( ) => popupService . ShowPopupAsync ( new PopupOptions < MockPageViewModel > ( ) , cts . Token ) ) ;
46
40
}
47
41
48
42
[ Fact ( Timeout = ( int ) TestDuration . Short ) ]
@@ -55,7 +49,7 @@ public async Task ShowPopupAsync_CancellationTokenCanceled()
55
49
// Ensure CancellationToken has expired
56
50
await cts . CancelAsync ( ) ;
57
51
58
- await Assert . ThrowsAsync < TaskCanceledException > ( ( ) => popupService . ShowPopupAsync < MockPageViewModel > ( new PopupOptions ( ) , cts . Token ) ) ;
52
+ await Assert . ThrowsAsync < TaskCanceledException > ( ( ) => popupService . ShowPopupAsync ( new PopupOptions < MockPageViewModel > ( ) , cts . Token ) ) ;
59
53
}
60
54
61
55
[ Fact ( Timeout = ( int ) TestDuration . Medium ) ]
@@ -65,7 +59,7 @@ public async Task ShowPopupAsyncShouldValidateProperBindingContext()
65
59
var popupInstance = ServiceProvider . GetRequiredService < MockSelfClosingPopup > ( ) ;
66
60
var popupViewModel = ServiceProvider . GetRequiredService < MockPageViewModel > ( ) ;
67
61
68
- await popupService . ShowPopupAsync < MockPageViewModel > ( new PopupOptions ( ) , CancellationToken . None ) ;
62
+ await popupService . ShowPopupAsync ( new PopupOptions < MockPageViewModel > ( ) , CancellationToken . None ) ;
69
63
70
64
Assert . Same ( popupInstance . BindingContext , popupViewModel ) ;
71
65
}
@@ -86,7 +80,7 @@ public async Task ShowPopupAsyncWithOnPresenting_CancellationTokenExpired()
86
80
// Ensure CancellationToken has expired
87
81
await Task . Delay ( 100 , CancellationToken . None ) ;
88
82
89
- await Assert . ThrowsAsync < TaskCanceledException > ( ( ) => popupService . ShowPopupAsync < MockPageViewModel > ( new PopupOptions < MockPageViewModel > ( ) { OnOpened = viewModel => viewModel . HasLoaded = true } , cts . Token ) ) ;
83
+ await Assert . ThrowsAsync < TaskCanceledException > ( ( ) => popupService . ShowPopupAsync ( new PopupOptions < MockPageViewModel > ( ) { OnOpened = viewModel => viewModel . HasLoaded = true } , cts . Token ) ) ;
90
84
}
91
85
92
86
[ Fact ( Timeout = ( int ) TestDuration . Short ) ]
@@ -99,7 +93,7 @@ public async Task ShowPopupAsyncWithOnPresenting_CancellationTokenCanceled()
99
93
// Ensure CancellationToken has expired
100
94
await cts . CancelAsync ( ) ;
101
95
102
- await Assert . ThrowsAsync < TaskCanceledException > ( ( ) => popupService . ShowPopupAsync < MockPageViewModel > ( new PopupOptions < MockPageViewModel > ( ) { OnOpened = viewModel => viewModel . HasLoaded = true } , cts . Token ) ) ;
96
+ await Assert . ThrowsAsync < TaskCanceledException > ( ( ) => popupService . ShowPopupAsync ( new PopupOptions < MockPageViewModel > ( ) { OnOpened = viewModel => viewModel . HasLoaded = true } , cts . Token ) ) ;
103
97
}
104
98
105
99
[ Fact ( Timeout = ( int ) TestDuration . Medium ) ]
@@ -108,7 +102,10 @@ public async Task ShowPopupAsyncWithOnPresentingShouldBeInvoked()
108
102
var popupService = ServiceProvider . GetRequiredService < IPopupService > ( ) ;
109
103
var popupViewModel = ServiceProvider . GetRequiredService < MockPageViewModel > ( ) ;
110
104
111
- await popupService . ShowPopupAsync < MockPageViewModel > ( new PopupOptions < MockPageViewModel > ( ) { OnOpened = viewModel => viewModel . HasLoaded = true } , CancellationToken . None ) ;
105
+ await popupService . ShowPopupAsync ( new PopupOptions < MockPageViewModel > ( )
106
+ {
107
+ OnOpened = viewModel => viewModel . HasLoaded = true
108
+ } , CancellationToken . None ) ;
112
109
113
110
Assert . True ( popupViewModel . HasLoaded ) ;
114
111
}
@@ -119,9 +116,9 @@ public async Task ShowPopupAsyncShouldReturnResultOnceClosed()
119
116
var mockPopup = ServiceProvider . GetRequiredService < MockSelfClosingPopup > ( ) ;
120
117
var popupService = ServiceProvider . GetRequiredService < IPopupService > ( ) ;
121
118
122
- var result = await popupService . ShowPopupAsync < MockPageViewModel > ( new PopupOptions ( ) , CancellationToken . None ) ;
119
+ var result = await popupService . ShowPopupAsync < MockPageViewModel , object > ( new PopupOptions < MockPageViewModel > ( ) , CancellationToken . None ) ;
123
120
124
- Assert . Same ( mockPopup . Result , result ) ;
121
+ Assert . Same ( mockPopup . Result , result . Result ) ;
125
122
}
126
123
127
124
[ Fact ]
@@ -130,19 +127,50 @@ public void ShowPopupWithOnPresentingShouldBeInvoked()
130
127
var popupService = ServiceProvider . GetRequiredService < IPopupService > ( ) ;
131
128
var popupViewModel = ServiceProvider . GetRequiredService < MockPageViewModel > ( ) ;
132
129
133
- popupService . ShowPopupAsync < MockPageViewModel > ( new PopupOptions < MockPageViewModel > ( ) { OnOpened = viewModel => viewModel . HasLoaded = true } , CancellationToken . None ) ;
130
+ popupService . ShowPopupAsync ( new PopupOptions < MockPageViewModel > ( ) { OnOpened = viewModel => viewModel . HasLoaded = true } , CancellationToken . None ) ;
134
131
135
132
Assert . True ( popupViewModel . HasLoaded ) ;
136
133
}
137
134
}
138
135
139
- sealed class MockSelfClosingPopup : Popup
136
+ sealed class MockSelfClosingPopup : Popup < object ? >
140
137
{
141
138
public MockSelfClosingPopup ( MockPageViewModel viewModel , object ? result = null )
142
139
{
143
140
BindingContext = viewModel ;
144
141
Result = result ;
142
+ OnOpened += MockSelfClosingPopup_OnOpened ;
145
143
}
146
144
147
- public new object ? Result { get ; }
145
+ void MockSelfClosingPopup_OnOpened ( object ? sender , EventArgs e )
146
+ {
147
+ var timer = Dispatcher . CreateTimer ( ) ;
148
+ timer . Interval = TimeSpan . FromMilliseconds ( 500 ) ;
149
+ timer . Tick += ( s , e ) => Close ( Result ) ;
150
+ timer . Start ( ) ;
151
+ }
152
+
153
+ public object ? Result { get ; }
154
+ }
155
+
156
+ public class MockPopup : Popup
157
+ {
158
+ }
159
+
160
+ class PopupViewModel : INotifyPropertyChanged
161
+ {
162
+ public event PropertyChangedEventHandler ? PropertyChanged ;
163
+
164
+ public Color ? Color
165
+ {
166
+ get ;
167
+ set
168
+ {
169
+ if ( ! Equals ( value , field ) )
170
+ {
171
+ field = value ;
172
+ PropertyChanged ? . Invoke ( this , new PropertyChangedEventArgs ( nameof ( Color ) ) ) ;
173
+ }
174
+ }
175
+ } = new ( ) ;
148
176
}
0 commit comments