using System; using NUnit.Framework; using Assert = ModestTree.Assert; namespace Zenject.Tests.Signals { [TestFixture] public class TestSignalsAdvanced : ZenjectUnitTestFixture { [SetUp] public void CommonInstall() { ZenjectManagersInstaller.Install(Container); SignalBusInstaller.Install(Container); Container.Inject(this); } [Test] public void TestSubscribeDeterministicOrder() { Container.DeclareSignal(); var signalBus = Container.Resolve(); int count = 1; int order1 = 0; Action handler1 = () => order1 = count++; int order2 = 0; Action handler2 = () => order2 = count++; int order3 = 0; Action handler3 = () => order3 = count++; signalBus.Subscribe(handler1); signalBus.Subscribe(handler2); signalBus.Subscribe(handler3); signalBus.Fire(); Assert.IsEqual(order1, 1); Assert.IsEqual(order2, 2); Assert.IsEqual(order3, 3); } [Test] public void TestSubscribeUnsubscribeInsideHandler() { Container.DeclareSignal(); var signalBus = Container.Resolve(); bool received = false; Action handler2 = () => received = true; Action handler = () => { signalBus.Subscribe(handler2); }; Action handler3 = () => { signalBus.Unsubscribe(handler2); }; signalBus.Subscribe(handler); Assert.That(!received); signalBus.Fire(); Assert.That(!received); // handler2 is subscribed now signalBus.Unsubscribe(handler); Assert.That(!received); signalBus.Fire(); Assert.That(received); received = false; signalBus.Subscribe(handler3); Assert.That(!received); signalBus.Fire(); // Should be called before handler 3 so should receive it Assert.That(received); received = false; signalBus.Unsubscribe(handler3); Assert.That(!received); signalBus.Fire(); Assert.That(!received); received = false; Assert.IsEqual(signalBus.NumSubscribers, 0); // Now test unsubscribing ourself in our own handler Action handler4 = null; handler4 = () => { received = true; signalBus.Unsubscribe(handler4); }; signalBus.Subscribe(handler4); Assert.That(!received); signalBus.Fire(); Assert.That(received); received = false; signalBus.Fire(); Assert.That(!received); } [Test] public void TestSubcontainers1() { Container.DeclareSignal(); var signalBus1 = Container.Resolve(); var subContainer = Container.CreateSubContainer(); var signalBus2 = subContainer.Resolve(); bool received = false; Action callback = () => received = true; signalBus2.Subscribe(callback); Assert.That(!received); signalBus1.Fire(); Assert.That(received); subContainer.Resolve().LateDispose(); // Signal should unregister automatically when the subcontainer is disposed received = false; signalBus1.Fire(); Assert.That(!received); } [Test] public void TestSignalDeclarationSettingsRequireHandlerMissing() { Container.DeclareSignal(); var signalBus = Container.Resolve(); signalBus.Fire(); } [Test] public void TestSignalDeclarationSettingsRequireHandler() { Container.DeclareSignal().RequireSubscriber(); var signalBus = Container.Resolve(); Assert.Throws(() => signalBus.Fire()); } [Test] public void TestSignalDeclarationSettingsRunAsync1() { Container.DeclareSignal().RunAsync(); Container.ResolveRoots(); Container.Resolve().Initialize(); var signalBus = Container.Resolve(); bool received = false; signalBus.Subscribe(() => received = true); Assert.That(!received); signalBus.Fire(); Assert.That(!received); Container.Resolve().Update(); Assert.That(received); } [Test] public void TestIsDeclared1() { Container.DeclareSignal(); Container.ResolveRoots(); var signalBus = Container.Resolve(); Assert.That(signalBus.IsSignalDeclared()); } [Test] public void TestIsDeclared2() { Container.ResolveRoots(); var signalBus = Container.Resolve(); Assert.That(!signalBus.IsSignalDeclared()); } [Test] public void TestSignalDeclarationSettingsRunAsync2() { Container.DeclareSignal().RunAsync(); Container.ResolveRoots(); Container.Resolve().Initialize(); var signalBus = Container.Resolve(); int callCount = 0; Action handler = () => { callCount++; signalBus.Fire(); }; signalBus.Subscribe(handler); Assert.IsEqual(callCount, 0); signalBus.Fire(); Assert.IsEqual(callCount, 0); Container.Resolve().Update(); Assert.IsEqual(callCount, 1); Container.Resolve().Update(); Assert.IsEqual(callCount, 2); } public class FooSignal { } public class BarSignal { public string Value; } } }