5
5
using System . Linq ;
6
6
using System . Runtime . InteropServices . ComTypes ;
7
7
using System . Threading ;
8
+ using System . Threading . Tasks ;
8
9
using Terminal . Gui ;
9
10
using Xunit ;
10
11
using Xunit . Sdk ;
@@ -33,28 +34,31 @@ public void AddIdle_Adds_And_Removes ()
33
34
ml . AddIdle ( fnTrue ) ;
34
35
ml . AddIdle ( fnFalse ) ;
35
36
36
- ml . RemoveIdle ( fnTrue ) ;
37
+ Assert . True ( ml . RemoveIdle ( fnTrue ) ) ;
37
38
38
- // BUGBUG: This doens't throw or indicate an error. Ideally RemoveIdle would either
39
- // trhow an exception in this case, or return an error.
40
- ml . RemoveIdle ( fnTrue ) ;
39
+ // BUGBUG: This doesn't throw or indicate an error. Ideally RemoveIdle would either
40
+ // throw an exception in this case, or return an error.
41
+ // No. Only need to return a boolean.
42
+ Assert . False ( ml . RemoveIdle ( fnTrue ) ) ;
41
43
42
- ml . RemoveIdle ( fnFalse ) ;
44
+ Assert . True ( ml . RemoveIdle ( fnFalse ) ) ;
43
45
44
46
// BUGBUG: This doesn't throw an exception or indicate an error. Ideally RemoveIdle would either
45
- // trhow an exception in this case, or return an error.
46
- ml . RemoveIdle ( fnFalse ) ;
47
+ // throw an exception in this case, or return an error.
48
+ // No. Only need to return a boolean.
49
+ Assert . False ( ml . RemoveIdle ( fnFalse ) ) ;
47
50
48
51
// Add again, but with dupe
49
52
ml . AddIdle ( fnTrue ) ;
50
53
ml . AddIdle ( fnTrue ) ;
51
54
52
- ml . RemoveIdle ( fnTrue ) ;
53
- ml . RemoveIdle ( fnTrue ) ;
55
+ Assert . True ( ml . RemoveIdle ( fnTrue ) ) ;
56
+ Assert . True ( ml . RemoveIdle ( fnTrue ) ) ;
54
57
55
58
// BUGBUG: This doesn't throw an exception or indicate an error. Ideally RemoveIdle would either
56
- // trhow an exception in this case, or return an error.
57
- ml . RemoveIdle ( fnTrue ) ;
59
+ // throw an exception in this case, or return an error.
60
+ // No. Only need to return a boolean.
61
+ Assert . False ( ml . RemoveIdle ( fnTrue ) ) ;
58
62
}
59
63
60
64
[ Fact ]
@@ -84,8 +88,7 @@ public void RemoveIdle_Function_NotCalled ()
84
88
return true ;
85
89
} ;
86
90
87
- functionCalled = 0 ;
88
- ml . RemoveIdle ( fn ) ;
91
+ Assert . False ( ml . RemoveIdle ( fn ) ) ;
89
92
ml . MainIteration ( ) ;
90
93
Assert . Equal ( 0 , functionCalled ) ;
91
94
}
@@ -101,9 +104,8 @@ public void AddThenRemoveIdle_Function_NotCalled ()
101
104
return true ;
102
105
} ;
103
106
104
- functionCalled = 0 ;
105
107
ml . AddIdle ( fn ) ;
106
- ml . RemoveIdle ( fn ) ;
108
+ Assert . True ( ml . RemoveIdle ( fn ) ) ;
107
109
ml . MainIteration ( ) ;
108
110
Assert . Equal ( 0 , functionCalled ) ;
109
111
}
@@ -119,21 +121,21 @@ public void AddTwice_Function_CalledTwice ()
119
121
return true ;
120
122
} ;
121
123
122
- functionCalled = 0 ;
123
124
ml . AddIdle ( fn ) ;
124
125
ml . AddIdle ( fn ) ;
125
126
ml . MainIteration ( ) ;
126
127
Assert . Equal ( 2 , functionCalled ) ;
127
128
128
129
functionCalled = 0 ;
129
- ml . RemoveIdle ( fn ) ;
130
+ Assert . True ( ml . RemoveIdle ( fn ) ) ;
130
131
ml . MainIteration ( ) ;
131
132
Assert . Equal ( 1 , functionCalled ) ;
132
133
133
134
functionCalled = 0 ;
134
- ml . RemoveIdle ( fn ) ;
135
+ Assert . True ( ml . RemoveIdle ( fn ) ) ;
135
136
ml . MainIteration ( ) ;
136
137
Assert . Equal ( 0 , functionCalled ) ;
138
+ Assert . False ( ml . RemoveIdle ( fn ) ) ;
137
139
}
138
140
139
141
[ Fact ]
@@ -163,10 +165,11 @@ public void False_Idle_Stops_It_Being_Called_Again ()
163
165
ml . AddIdle ( fnStop ) ;
164
166
ml . AddIdle ( fn1 ) ;
165
167
ml . Run ( ) ;
166
- ml . RemoveIdle ( fnStop ) ;
167
- ml . RemoveIdle ( fn1 ) ;
168
+ Assert . True ( ml . RemoveIdle ( fnStop ) ) ;
169
+ Assert . False ( ml . RemoveIdle ( fn1 ) ) ;
168
170
169
171
Assert . Equal ( 10 , functionCalled ) ;
172
+ Assert . Equal ( 20 , stopCount ) ;
170
173
}
171
174
172
175
[ Fact ]
@@ -194,9 +197,9 @@ public void AddIdle_Twice_Returns_False_Called_Twice ()
194
197
ml . AddIdle ( fn1 ) ;
195
198
ml . AddIdle ( fn1 ) ;
196
199
ml . Run ( ) ;
197
- ml . RemoveIdle ( fnStop ) ;
198
- ml . RemoveIdle ( fn1 ) ;
199
- ml . RemoveIdle ( fn1 ) ;
200
+ Assert . True ( ml . RemoveIdle ( fnStop ) ) ;
201
+ Assert . False ( ml . RemoveIdle ( fn1 ) ) ;
202
+ Assert . False ( ml . RemoveIdle ( fn1 ) ) ;
200
203
201
204
Assert . Equal ( 2 , functionCalled ) ;
202
205
}
@@ -217,7 +220,7 @@ public void Run_Runs_Idle_Stop_Stops_Idle ()
217
220
218
221
ml . AddIdle ( fn ) ;
219
222
ml . Run ( ) ;
220
- ml . RemoveIdle ( fn ) ;
223
+ Assert . True ( ml . RemoveIdle ( fn ) ) ;
221
224
222
225
Assert . Equal ( 10 , functionCalled ) ;
223
226
}
@@ -237,10 +240,11 @@ public void AddTimer_Adds_Removes_NoFaults ()
237
240
238
241
var token = ml . AddTimeout ( TimeSpan . FromMilliseconds ( ms ) , callback ) ;
239
242
240
- ml . RemoveTimeout ( token ) ;
243
+ Assert . True ( ml . RemoveTimeout ( token ) ) ;
241
244
242
245
// BUGBUG: This should probably fault?
243
- ml . RemoveTimeout ( token ) ;
246
+ // Must return a boolean.
247
+ Assert . False ( ml . RemoveTimeout ( token ) ) ;
244
248
}
245
249
246
250
[ Fact ]
@@ -258,11 +262,72 @@ public void AddTimer_Run_Called ()
258
262
259
263
var token = ml . AddTimeout ( TimeSpan . FromMilliseconds ( ms ) , callback ) ;
260
264
ml . Run ( ) ;
261
- ml . RemoveTimeout ( token ) ;
265
+ Assert . True ( ml . RemoveTimeout ( token ) ) ;
262
266
263
267
Assert . Equal ( 1 , callbackCount ) ;
264
268
}
265
269
270
+ [ Fact ]
271
+ public async Task AddTimer_Duplicate_Keys_Not_Allowed ( )
272
+ {
273
+ var ml = new MainLoop ( new FakeMainLoop ( ( ) => FakeConsole . ReadKey ( true ) ) ) ;
274
+ const int ms = 100 ;
275
+ object token1 = null , token2 = null ;
276
+
277
+ var callbackCount = 0 ;
278
+ Func < MainLoop , bool > callback = ( MainLoop loop ) => {
279
+ callbackCount ++ ;
280
+ if ( callbackCount == 2 ) {
281
+ ml . Stop ( ) ;
282
+ }
283
+ return true ;
284
+ } ;
285
+
286
+ var task1 = new Task ( ( ) => token1 = ml . AddTimeout ( TimeSpan . FromMilliseconds ( ms ) , callback ) ) ;
287
+ var task2 = new Task ( ( ) => token2 = ml . AddTimeout ( TimeSpan . FromMilliseconds ( ms ) , callback ) ) ;
288
+ Assert . Null ( token1 ) ;
289
+ Assert . Null ( token2 ) ;
290
+ task1 . Start ( ) ;
291
+ task2 . Start ( ) ;
292
+ ml . Run ( ) ;
293
+ Assert . NotNull ( token1 ) ;
294
+ Assert . NotNull ( token2 ) ;
295
+ await Task . WhenAll ( task1 , task2 ) ;
296
+ Assert . True ( ml . RemoveTimeout ( token1 ) ) ;
297
+ Assert . True ( ml . RemoveTimeout ( token2 ) ) ;
298
+
299
+ Assert . Equal ( 2 , callbackCount ) ;
300
+ }
301
+
302
+ [ Fact ]
303
+ public void AddTimer_In_Parallel_Wont_Throw ( )
304
+ {
305
+ var ml = new MainLoop ( new FakeMainLoop ( ( ) => FakeConsole . ReadKey ( true ) ) ) ;
306
+ const int ms = 100 ;
307
+ object token1 = null , token2 = null ;
308
+
309
+ var callbackCount = 0 ;
310
+ Func < MainLoop , bool > callback = ( MainLoop loop ) => {
311
+ callbackCount ++ ;
312
+ if ( callbackCount == 2 ) {
313
+ ml . Stop ( ) ;
314
+ }
315
+ return true ;
316
+ } ;
317
+
318
+ Parallel . Invoke (
319
+ ( ) => token1 = ml . AddTimeout ( TimeSpan . FromMilliseconds ( ms ) , callback ) ,
320
+ ( ) => token2 = ml . AddTimeout ( TimeSpan . FromMilliseconds ( ms ) , callback )
321
+ ) ;
322
+ ml . Run ( ) ;
323
+ Assert . NotNull ( token1 ) ;
324
+ Assert . NotNull ( token2 ) ;
325
+ Assert . True ( ml . RemoveTimeout ( token1 ) ) ;
326
+ Assert . True ( ml . RemoveTimeout ( token2 ) ) ;
327
+
328
+ Assert . Equal ( 2 , callbackCount ) ;
329
+ }
330
+
266
331
267
332
class MillisecondTolerance : IEqualityComparer < TimeSpan > {
268
333
int _tolerance = 0 ;
@@ -293,7 +358,7 @@ public void AddTimer_Run_CalledAtApproximatelyRightTime ()
293
358
// https://github.com/xunit/assert.xunit/pull/25
294
359
Assert . Equal < TimeSpan > ( ms * callbackCount , watch . Elapsed , new MillisecondTolerance ( 100 ) ) ;
295
360
296
- ml . RemoveTimeout ( token ) ;
361
+ Assert . True ( ml . RemoveTimeout ( token ) ) ;
297
362
Assert . Equal ( 1 , callbackCount ) ;
298
363
}
299
364
@@ -321,7 +386,7 @@ public void AddTimer_Run_CalledTwiceApproximatelyRightTime ()
321
386
// https://github.com/xunit/assert.xunit/pull/25
322
387
Assert . Equal < TimeSpan > ( ms * callbackCount , watch . Elapsed , new MillisecondTolerance ( 100 ) ) ;
323
388
324
- ml . RemoveTimeout ( token ) ;
389
+ Assert . True ( ml . RemoveTimeout ( token ) ) ;
325
390
Assert . Equal ( 2 , callbackCount ) ;
326
391
}
327
392
@@ -349,7 +414,7 @@ public void AddTimer_Remove_NotCalled ()
349
414
} ;
350
415
351
416
var token = ml . AddTimeout ( ms , callback ) ;
352
- ml . RemoveTimeout ( token ) ;
417
+ Assert . True ( ml . RemoveTimeout ( token ) ) ;
353
418
ml . Run ( ) ;
354
419
Assert . Equal ( 0 , callbackCount ) ;
355
420
}
@@ -363,7 +428,7 @@ public void AddTimer_ReturnFalse_StopsBeingCalled ()
363
428
// Force stop if 10 iterations
364
429
var stopCount = 0 ;
365
430
Func < bool > fnStop = ( ) => {
366
- Thread . Sleep ( 10 ) ; // Sleep to enable timeer to fire
431
+ Thread . Sleep ( 10 ) ; // Sleep to enable timer to fire
367
432
stopCount ++ ;
368
433
if ( stopCount == 10 ) {
369
434
ml . Stop ( ) ;
@@ -382,7 +447,7 @@ public void AddTimer_ReturnFalse_StopsBeingCalled ()
382
447
ml . Run ( ) ;
383
448
Assert . Equal ( 1 , callbackCount ) ;
384
449
Assert . Equal ( 10 , stopCount ) ;
385
- ml . RemoveTimeout ( token ) ;
450
+ Assert . False ( ml . RemoveTimeout ( token ) ) ;
386
451
}
387
452
388
453
// Invoke Tests
0 commit comments