-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
/
Copy pathAssertEx.cs
79 lines (67 loc) · 2.97 KB
/
AssertEx.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
using System;
using System.Threading.Tasks;
using Xunit.Sdk;
using Nito.AsyncEx;
using System.Threading;
namespace CefSharp.Test
{
internal static class AssertEx
{
/// <summary>
/// Verifies that a event with the exact event args (and not a derived type) is raised
/// This method differs from <see cref="Xunit.Assert.RaisesAsync{T}(Action{EventHandler{T}}, Action{EventHandler{T}}, Func{Task})"/>
/// in that it waits for the event to be raised before returning (or is cancelled).
/// </summary>
/// <typeparam name="T">The type of the event arguments to expect</typeparam>
/// <param name="cancelAfter">number of miliseconds to wait before the timeout</param>
/// <param name="attach">Code to attach the event handler</param>
/// <param name="detach">Code to detach the event handler</param>
/// <param name="testCode">A delegate to the code to be tested</param>
/// <returns>The event sender and arguments wrapped in an object</returns>
/// <exception cref="RaisesException">Thrown when the expected event was not raised.</exception>
public static async Task<Xunit.Assert.RaisedEvent<T>> RaisesAsync<T>(
int cancelAfter,
Action<EventHandler<T>> attach,
Action<EventHandler<T>> detach,
Action testCode) where T : EventArgs
{
var raisedEvent = await RaisesAsyncInternal(cancelAfter, attach, detach, testCode);
if (raisedEvent == null)
throw new RaisesException(typeof(T));
if (raisedEvent.Arguments != null && !raisedEvent.Arguments.GetType().Equals(typeof(T)))
throw new RaisesException(typeof(T), raisedEvent.Arguments.GetType());
return raisedEvent;
}
private static async Task<Xunit.Assert.RaisedEvent<T>> RaisesAsyncInternal<T>(
int cancelAfter,
Action<EventHandler<T>> attach,
Action<EventHandler<T>> detach,
Action testCode) where T : EventArgs
{
GuardArgumentNotNull(nameof(attach), attach);
GuardArgumentNotNull(nameof(detach), detach);
GuardArgumentNotNull(nameof(testCode), testCode);
using var cts = new CancellationTokenSource();
var manualResetEvent = new AsyncManualResetEvent();
cts.CancelAfter(cancelAfter);
Xunit.Assert.RaisedEvent<T> raisedEvent = null;
attach(Handler);
testCode();
await manualResetEvent.WaitAsync(cts.Token);
detach(Handler);
return raisedEvent;
void Handler(object s, T args)
{
raisedEvent = new Xunit.Assert.RaisedEvent<T>(s, args);
manualResetEvent.Set();
}
}
internal static void GuardArgumentNotNull(string argName, object argValue)
{
if (argValue == null)
{
throw new ArgumentNullException(argName);
}
}
}
}