using System; using NUnit.Framework; namespace Chernobyl.Event { [TestFixture, Description("A TestFixture for testing the " + "WeakEventHandler and WeakEventHandler " + "types and the extension method(s) in the static Extensions class.")] public class WeakEventHandlerTests { [Test, Description("Tests to see if an event handler is properly invoked " + "when it is wrapped by a WeakEventHandler or " + "WeakEventHandler.")] public void EventHandlerInvoked() { SourceGeneric genericSource = new SourceGeneric(); Receiver genericReceiver = new Receiver(); Source source = new Source(); Receiver receiver = new Receiver(); genericSource.TheEvent += new WeakEventHandler(genericReceiver.TheEventHandler, eh => genericSource.TheEvent -= eh); source.TheEvent += new WeakEventHandler(receiver.TheEventHandler, eh => source.TheEvent -= eh); genericSource.InvokeEvent(); source.InvokeEvent(); Assert.That(genericReceiver.WasEventHandled == true, "Event should have been handled but it was not."); Assert.That(receiver.WasEventHandled == true, "Event should have been handled but it was not."); } [Test, Description("Tests to see if a target object is properly " + "garbage collected when a WeakEventHandler or " + "WeakEventHandler is registered to its event.")] public void TargetObjectCanBeGarbageCollected() { SourceGeneric genericSource = new SourceGeneric(); Receiver genericReceiver = new Receiver(); Source source = new Source(); Receiver receiver = new Receiver(); genericSource.TheEvent += new WeakEventHandler(genericReceiver.TheEventHandler, eh => genericSource.TheEvent -= eh); source.TheEvent += new WeakEventHandler(receiver.TheEventHandler, eh => source.TheEvent -= eh); WeakReference genericReceiverReference = new WeakReference(genericReceiver); WeakReference receiverReference = new WeakReference(receiver); genericReceiver = null; receiver = null; GC.Collect(); Assert.That(genericReceiverReference.IsAlive == false, "The target object " + "that was to receive the event was not properly garbage collected."); Assert.That(receiverReference.IsAlive == false, "The target object " + "that was to receive the event was not properly garbage collected."); } [Test, Description("Tests to see if an event handler is properly invoked " + "and the target object is properly garbage collected when the event " + "handler is wrapped by a WeakEventHandler or a " + "WeakEventHandler created by " + "Extensions.MakeWeak(UnregisterCallback) or " + "Extensions.MakeWeak(UnregisterCallback) respectively.")] public void MakeWeakWorksProperly() { SourceGeneric genericSource = new SourceGeneric(); Receiver genericReceiver = new Receiver(); Source source = new Source(); Receiver receiver = new Receiver(); genericSource.TheEvent += new EventHandler(genericReceiver.TheEventHandler).MakeWeak(eh => genericSource.TheEvent -= eh); source.TheEvent += new EventHandler(receiver.TheEventHandler).MakeWeak(eh => source.TheEvent -= eh); genericSource.InvokeEvent(); source.InvokeEvent(); Assert.That(genericReceiver.WasEventHandled == true, "Event should have been handled but it was not."); Assert.That(receiver.WasEventHandled == true, "Event should have been handled but it was not."); WeakReference genericReceiverReference = new WeakReference(genericReceiver); WeakReference receiverReference = new WeakReference(receiver); genericReceiver = null; receiver = null; GC.Collect(); Assert.That(genericReceiverReference.IsAlive == false, "The target object " + "that was to receive the event was not properly garbage collected."); Assert.That(receiverReference.IsAlive == false, "The target object " + "that was to receive the event was not properly garbage collected."); } protected class SourceGeneric { public event EventHandler TheEvent; public void InvokeEvent() { if(TheEvent != null) TheEvent(null, EventArgs.Empty); } } protected class Source { public event EventHandler TheEvent; public void InvokeEvent() { if (TheEvent != null) TheEvent(null, EventArgs.Empty); } } protected class Receiver { public void TheEventHandler(object sender, EventArgs e) { WasEventHandled = true; } public bool WasEventHandled { get; private set; } } } }