public static void Callback() { var queue = new ManualEventQueue(); var evnt = new TestEvent(); bool handled = false; queue.Enqueue( evnt, onHandled: e => { Assert.True(ReferenceEquals(e, evnt)); handled = true; }); // handled original event Assert.False(handled); Assert.True(queue.HandleNext()); Assert.False(handled); // handle second event, implicitly added Assert.True(queue.HandleNext()); Assert.True(handled); // no other events were added Assert.False(queue.HandleNext()); }
public static void StatelessHandler() { var queue = new ManualEventQueue(); // create subscriber TestEvent lastEventHandled = null; var subscriber = DelegateEventHandler.On <TestEvent>(evnt => lastEventHandled = evnt); queue.Subscribers.Add(subscriber); // enqueue and handle event queue.Enqueue(new TestEvent() { Value = 3 }); Assert.Null(lastEventHandled); Assert.True(queue.HandleNext()); // test subscriber Assert.NotNull(lastEventHandled); Assert.AreEqual(3, lastEventHandled.Value); // queue is empty again (no unhandled exceptions or anything else) Assert.False(queue.HandleNext()); }
public static void IsShutDown() { // initially open var queue = new ManualEventQueue(); Assert.False(queue.IsShutDown); // removing all subscribers does not shut down the queue queue.Subscribers.AddAll(new TestEventHandler(), weakRef: false); queue.Subscribers.Clear(); Assert.False(queue.IsShutDown); // adding the shutting down event is not enough queue.BeginShutdown(); Assert.False(queue.IsShutDown); // handling the shutting down event is not enough... queue.Subscribers.Add( DelegateEventHandler.OnShuttingDown( e => queue.Enqueue(new NamedEvent("shutting down event handler"))), weakRef: false); Assert.True(queue.HandleNext()); Assert.False(queue.IsShutDown); // handling the NamedEvent added in the ShuttingDownEvent handler, is not enough Assert.True(queue.HandleNext()); Assert.False(queue.IsShutDown); // ... but handling the ShutDownEvent is Assert.True(queue.HandleNext()); Assert.True(queue.IsShutDown); Assert.False(queue.HandleNext()); }
public static void HandleSupportsEventInheritance() { var queue = new ManualEventQueue(); var subscriber = new AncestorEventHandler(); queue.Subscribers.AddAll(subscriber); // subscriber does not handle events not in it's inheritance tree Assert.True(queue.Enqueue(new TestEvent())); Assert.True(queue.HandleNext()); Assert.Null(subscriber.LastEventHandled); // subscriber accepts event type it explicitly stated it would handle var namedEvent = new NamedEvent("name"); Assert.True(queue.Enqueue(namedEvent)); Assert.True(queue.HandleNext()); Assert.AreSame(namedEvent, subscriber.LastEventHandled); // subscriber accepts event that inherit what it declared it would handle var derivedEvent = new DescendantEvent(); Assert.True(queue.Enqueue(derivedEvent)); Assert.True(queue.HandleNext()); Assert.AreSame(derivedEvent, subscriber.LastEventHandled); }
public static void EnqueueReturnValue() { var queue = new ManualEventQueue(); var evnt = new TestEvent(); Assert.True(queue.Enqueue(evnt)); // adding the same event a second time Assert.False(queue.Enqueue(evnt)); // handling it and adding it again is fine however Assert.True(queue.HandleNext()); Assert.False(queue.HandleNext()); // verify that we only added it once Assert.True(queue.Enqueue(evnt)); // adding suspension queue.EventAdding.Suspend(); Assert.False(queue.Enqueue(new TestEvent())); queue.EventAdding.Resume(); Assert.True(queue.Enqueue(new TestEvent())); // handle all events while (queue.HandleNext()) { ; } // add and handle shutting down event Assert.True(queue.Enqueue(new ShuttingDownEvent())); Assert.False(queue.Enqueue(new ShuttingDownEvent())); // another shutting down event is already enqueued Assert.True(queue.HandleNext()); Assert.False(queue.Enqueue(new TestEvent())); // no more events of any kind can be added }
public static void ShutdownRequest_AfterShuttingDown() { // can not enqueue after shutting down event was enqueued var queue = new ManualEventQueue(); Assert.True(queue.BeginShutdown()); Assert.False(queue.Enqueue(new ShutdownRequestEvent())); // handling is skipped, if a shutting down event is enqueued beforehand queue = new ManualEventQueue(); bool requestDetected = false; queue.Subscribers.Add( DelegateEventHandler.OnShutdownRequest( e => requestDetected = true), weakRef: false); Assert.True(queue.Enqueue(new ShutdownRequestEvent())); // enqueueing succeeds Assert.True(queue.Enqueue(new ShuttingDownEvent())); // shutting down event added Assert.False(requestDetected); Assert.True(queue.HandleNext()); // the request was "handled" successfully Assert.False(requestDetected); // but the handler was not actually invoked // ensure there are no unexpected events in the queue, that could have shifted the position of the request event Assert.True(queue.HandleNext()); // shutting down event Assert.True(queue.HandleNext()); // shut down event Assert.False(queue.HandleNext()); Assert.True(queue.IsShutDown); }
public static void NullCallback() { var queue = new ManualEventQueue(); Assert.True(queue.Enqueue(new TestEvent(), onHandled: null)); // no exception, successful call Assert.True(queue.HandleNext()); Assert.False(queue.HandleNext()); // no secondary event added }
public static void NoNewSubscriptionsAfterShutdown() { var queue = new ManualEventQueue(); var handler = new TestEventHandler(); queue.Subscribers.AddAll(handler); queue.BeginShutdown(); Assert.True(queue.HandleNext()); // shutting down event Assert.True(queue.HandleNext()); // shut down event Assert.True(queue.IsShutDown); Assert.False(queue.Subscribers.RemoveAll(handler)); // a shutdown queue has no subscribers Assert.False(queue.Subscribers.AddAll(new TestEventHandler(), weakRef: false)); }
private static void Constructor(out ManualEventQueue queue) { // try to pass a null event queue Assert.Throws <ArgumentNullException>(() => TestApp.Initialize(null)); // try to pass an event queue that's already shut down var manualQueue = new ManualEventQueue(); manualQueue.BeginShutdown(); while (manualQueue.HandleNext()) { ; } Assert.Throws <ArgumentException>(() => TestApp.Initialize(manualQueue)); // pass a proper event queue manualQueue = new ManualEventQueue(); TestApp.Initialize(manualQueue); Assert.NotNull(AppBase.MainEventQueue); Assert.AreSame(manualQueue, AppBase.MainEventQueue.BaseEventQueue); Assert.AreSame(manualQueue.Subscribers, AppBase.MainEventQueue.Subscribers); Assert.AreSame(manualQueue.EventAdding, AppBase.MainEventQueue.EventAdding); Assert.AreSame(manualQueue.EventHandling, AppBase.MainEventQueue.EventHandling); Assert.AreSame(manualQueue.RaiseUnhandledEvents, AppBase.MainEventQueue.RaiseUnhandledEvents); Assert.AreEqual(AppState.Shutdown, AppBase.CurrentState); queue = manualQueue; }
private static void ShutdownEventTriggersShutdownState(ManualEventQueue manualQueue) { TestApp.MoveToState(AppState.Running); while (manualQueue.HandleNext()) { ; } manualQueue.BeginShutdown(); while (manualQueue.HandleNext()) { ; } Assert.True(manualQueue.IsShutDown); Assert.AreEqual(AppState.Shutdown, TestApp.CurrentState); }
public static void EventsCanNotBeEnqueuedTwice() { var queue = new ManualEventQueue(); var evnt = new TestEvent(); // the same instance twice won't work queue.Enqueue(evnt); queue.Enqueue(evnt); Assert.True(queue.HandleNext()); Assert.False(queue.HandleNext()); // .. but two separate instances of the same event are fine queue.Enqueue(new TestEvent()); queue.Enqueue(new TestEvent()); Assert.True(queue.HandleNext()); Assert.True(queue.HandleNext()); }
public static void EventsCanNotBeEnqueuedAfterShuttingDown() { var queue = new ManualEventQueue(); var testListener = new TestEventHandler(); queue.Subscribers.AddAll(testListener); queue.Subscribers.Add( DelegateEventHandler.OnShuttingDown( e => queue.Enqueue(new NamedEvent("shutting down event handler"))), weakRef: false); // enqueue shutting down event queue.BeginShutdown(); // can enqueue, after the shutting down event is enqueued, but before it is handled Assert.True(queue.Enqueue(new TestEvent() { Value = 1 })); // handle shutting down event Assert.True(queue.HandleNext()); Assert.Null(testListener.LastEventHandled); // try to enqueue another event, after the shutting down event is handled: // it should have no effect Assert.False(queue.Enqueue(new TestEvent() { Value = 2 })); // handle first test event Assert.True(queue.HandleNext()); Assert.AreEqual(1, ((TestEvent)testListener.LastEventHandled).Value); // handle the event added in the shutting down event handler Assert.True(queue.HandleNext()); Assert.IsInstanceOf <NamedEvent>(testListener.LastEventHandled); // false for null // handle shut down event Assert.True(queue.HandleNext(out var shutDownEvent)); Assert.IsInstanceOf <ShutDownEvent>(shutDownEvent); // nothing more to handle Assert.True(queue.IsShutDown); }
public static void ShuttingDownHandler() { var queue = new ManualEventQueue(); // create subscriber ShuttingDownEvent lastEventHandled = null; var subscriber = DelegateEventHandler.OnShuttingDown(evnt => lastEventHandled = evnt); queue.Subscribers.Add(subscriber); // enqueue and handle event queue.BeginShutdown(); Assert.Null(lastEventHandled); Assert.True(queue.HandleNext()); // shutting down event // test subscriber Assert.NotNull(lastEventHandled); Assert.True(queue.HandleNext()); // shut down event Assert.True(queue.IsShutDown); }
public static void StatefulHandler() { var queue = new ManualEventQueue(); // create subscriber TestEvent lastEventHandled = null; var subscriber = DelegateEventHandler.On( (int currentState, TestEvent evnt) => { lastEventHandled = evnt; evnt.Value += currentState; return(currentState + 1); }, initialState: 10); queue.Subscribers.Add(subscriber); // enqueue events queue.Enqueue(new TestEvent() { Value = 3 }); queue.Enqueue(new TestEvent() { Value = 4 }); Assert.Null(lastEventHandled); // handle first event Assert.True(queue.HandleNext()); Assert.NotNull(lastEventHandled); Assert.AreEqual(13, lastEventHandled.Value); // handle second event Assert.True(queue.HandleNext()); Assert.NotNull(lastEventHandled); Assert.AreEqual(15, lastEventHandled.Value); // queue is empty again (no unhandled exceptions or anything else) Assert.False(queue.HandleNext()); }
public static void HandleNextInvokesHandler() { var queue = new ManualEventQueue(); var evnt = new TestEvent(); var subscriber = new TestEventHandler(); // queue empty Assert.False(queue.HandleNext()); // enqueueing does not invoke handlers queue.Subscribers.AddAll(subscriber); Assert.True(queue.Enqueue(evnt)); Assert.Null(subscriber.LastEventHandled); // invoking handlers is successful Assert.True(queue.HandleNext()); Assert.AreSame(evnt, subscriber.LastEventHandled); // queue is empty again Assert.False(queue.HandleNext()); }
public static void ShutdownRequest_NotCancelled() { var queue = new ManualEventQueue(); bool shuttingDownDetected = false; queue.Subscribers.Add( DelegateEventHandler.OnShuttingDown( e => shuttingDownDetected = true), weakRef: false); // requests are granted by default (Cancel is false) Assert.True(queue.RequestShutdown()); Assert.True(queue.HandleNext()); // request event Assert.False(shuttingDownDetected); Assert.True(queue.HandleNext()); // shutting down event Assert.True(shuttingDownDetected); Assert.True(queue.HandleNext()); // shut down event Assert.False(queue.HandleNext()); Assert.True(queue.IsShutDown); }
public static void EventAddingSuspension() { var queue = new ManualEventQueue(); Assert.False(queue.EventHandling.IsSuspended); var testListener = new TestEventHandler(); queue.Subscribers.AddAll(testListener); var evnt = new TestEvent(); queue.EventAdding.Suspend(); Assert.False(queue.Enqueue(evnt)); Assert.False(queue.HandleNext()); Assert.Null(testListener.LastEventHandled); queue.EventAdding.Resume(); Assert.True(queue.Enqueue(evnt)); Assert.True(queue.HandleNext()); Assert.AreSame(evnt, testListener.LastEventHandled); }
public static void ExceptionHandler() { var queue = new ManualEventQueue(); // create subscriber UnhandledExceptionEvent lastEventHandled = null; var subscriber = DelegateEventHandler.OnException(evnt => lastEventHandled = evnt); queue.Subscribers.Add(subscriber); // enqueue and handle event queue.Enqueue(new UnhandledExceptionEvent(new UnauthorizedAccessException())); Assert.Null(lastEventHandled); Assert.True(queue.HandleNext()); // test subscriber Assert.NotNull(lastEventHandled); Test.OrdinalEquals(lastEventHandled.Type, typeof(UnauthorizedAccessException).ToString()); // queue is empty again (no unhandled exceptions or anything else) Assert.False(queue.HandleNext()); }
public static void ShutdownRequest_Cancelled() { var queue = new ManualEventQueue(); queue.Subscribers.Add( DelegateEventHandler.OnShutdownRequest( e => e.Cancel = true), weakRef: false); // you can only add one request at a time Assert.True(queue.RequestShutdown()); Assert.False(queue.RequestShutdown()); // cancel the request Assert.True(queue.HandleNext()); // no shutting down event Assert.False(queue.HandleNext()); // you can add another request, once the previous one is out of the queue Assert.True(queue.RequestShutdown()); Assert.True(queue.HandleNext()); Assert.False(queue.HandleNext()); }
private static void ChangeToSameState(ManualEventQueue manualQueue) { AppStateChangedEvent.Critical criticalEvent = null; var subscriber = DelegateEventHandler.On <AppStateChangedEvent.Critical>( e => { criticalEvent = e; }); TestApp.MainEventQueue.Subscribers.Add(subscriber); var currentState = TestApp.CurrentState; TestApp.MoveToState(currentState); Assert.AreEqual(currentState, TestApp.CurrentState); // no state change Assert.Null(criticalEvent); // no critical event Assert.False(manualQueue.HandleNext()); // no regular event TestApp.MainEventQueue.Subscribers.Remove(subscriber); }
public static void EventHandlerExceptions() { var queue = new ManualEventQueue(); queue.Subscribers.Add( DelegateEventHandler.On <TestEvent>( e => throw new ArgumentOutOfRangeException()), weakRef: false); queue.Subscribers.Add( DelegateEventHandler.On <TestEvent>( e => throw new MissingMemberException()), weakRef: false); bool argumentExceptionFound = false; bool memberExceptionFound = false; bool unhandledExceptionEventHandled = false; queue.Subscribers.Add( DelegateEventHandler.On <UnhandledExceptionEvent>( e => { unhandledExceptionEventHandled = true; if (e.Type.IndexOf(nameof(ArgumentOutOfRangeException), StringComparison.Ordinal) != -1) { argumentExceptionFound = true; } else if (e.Type.IndexOf(nameof(MissingMemberException), StringComparison.Ordinal) != -1) { memberExceptionFound = true; } }), weakRef: false); // unhandled exception events are generated by default queue.Enqueue(new TestEvent()); Assert.False(argumentExceptionFound); Assert.False(memberExceptionFound); Assert.False(unhandledExceptionEventHandled); Assert.True(queue.HandleNext()); // test event Assert.True(queue.HandleNext()); // argument exception Assert.True(queue.HandleNext()); // missing member exception Assert.True(argumentExceptionFound); Assert.True(memberExceptionFound); Assert.True(unhandledExceptionEventHandled); // unhandled exception event suppression queue.Enqueue(new TestEvent()); argumentExceptionFound = false; memberExceptionFound = false; unhandledExceptionEventHandled = false; queue.RaiseUnhandledEvents.Suspend(); Assert.True(queue.HandleNext()); Assert.False(queue.HandleNext()); queue.RaiseUnhandledEvents.Resume(); Assert.False(argumentExceptionFound); Assert.False(memberExceptionFound); Assert.False(unhandledExceptionEventHandled); // event addition suppression queue.Enqueue(new TestEvent()); queue.EventAdding.Suspend(); Assert.True(queue.HandleNext()); Assert.False(queue.HandleNext()); queue.EventAdding.Resume(); Assert.False(argumentExceptionFound); Assert.False(memberExceptionFound); Assert.False(unhandledExceptionEventHandled); }