public void SendSynchronously_should_not_hang_when_raising_BeginDispach_event()
        {
            var          finishedEvent = new AutoResetEvent(false);
            EventHandler onLoad        = ((sender, e) =>
            {
                using (var machine = new TestMachine <State, Event, EventArgs>())
                {
                    machine.AddTransition(State.S1, Event.S1_to_S2, State.S2);
                    machine.BeginDispatch += (sender1, e1) => { };
                    machine.Start(State.S1);
                    machine.SendSynchronously(Event.S1_to_S2);
                    finishedEvent.Set();
                }
            });
            Form form = null;

            ThreadPool.QueueUserWorkItem(state =>
            {
                // The form must be instantiated in the future ui thread.
                // Otherwise, a WindowsFormSynchronizationContext would be installed
                // on the test thread (which has no message-pump), and will cause hangups.
                form       = new Form();
                form.Load += onLoad;
                Application.Run(form);
            });
            var finished = finishedEvent.WaitOne(TimeSpan.FromSeconds(10));

            Assert.IsTrue(finished);
            form.Invoke((MethodInvoker)form.Dispose);
        }
        public void BeginDispach_event_should_raise_in_right_context()
        {
            TestMachine <State, Event, EventArgs> machine = null;
            var          loadedEvent      = new EventTester(TimeSpan.FromSeconds(1000));
            var          calledInUiThread = false;
            EventHandler onLoad           =
                (sender, e) =>
            {
                machine = new TestMachine <State, Event, EventArgs>();
                machine.AddTransition(State.S1, Event.S1_to_S2, State.S2);
                var uiThreadId = Thread.CurrentThread.ManagedThreadId;
                machine.BeginDispatch +=
                    (sender1, e1) => { calledInUiThread = Thread.CurrentThread.ManagedThreadId == uiThreadId; };
            };
            Form form = null;

            ThreadPool.QueueUserWorkItem(
                state =>
            {
                using (form = new Form())
                {
                    form.Load += onLoad;
                    form.Load += (sender, e) => loadedEvent.Set();
                    Application.Run(form);
                }
            });
            loadedEvent.AssertWasCalled("Form was not loaded.");
            Assert.IsNotNull(machine);
            machine.Start(State.S1);
            machine.Send(Event.S1_to_S2);
            machine.WaitForPendingEvents();
            Assert.IsTrue(calledInUiThread);
            form.Invoke((MethodInvoker)(() => form.Close()));
        }
 public void SimpleTransitionTest()
 {
     using (var machine = new TestMachine())
     {
         registerMachineEvents(machine);
         machine.Send(Event.S1_to_S2);
         machine.WaitForPendingEvents();
         assertMachineEvents(true, false, true, false);
         Assert.AreEqual(State.S2, machine.CurrentStateID);
     }
 }
 public void SimpleTransitionTest2()
 {
     using (var machine = new TestMachine <State, Event, EventArgs>())
     {
         machine.AddTransition(State.S1, Event.S1_to_S2, State.S2);
         registerMachineEvents(machine);
         machine.Start(State.S1);
         machine.Send(Event.S1_to_S2);
         machine.WaitForPendingEvents();
         assertMachineEvents(true, false, true, false);
         Assert.AreEqual(State.S2, machine.CurrentStateID);
     }
 }
 public void Test_machine_with_String_state_and_Int32_event_types()
 {
     using (var machine = new TestMachine <string, int, EventArgs>())
     {
         machine.AddTransition("S1", 12, "S2");
         registerMachineEvents(machine);
         machine.Start("S1");
         machine.Send(12);
         machine.WaitForPendingEvents();
         assertMachineEvents(true, false, true, false);
         Assert.AreEqual("S2", machine.CurrentStateID);
     }
 }
        public void TransitionCompleted_ThrowsError()
        {
            using (var machine = new TestMachine <State, Event, EventArgs>())
            {
                machine.AddTransition(State.S1, Event.S1_to_S2, State.S2);

                registerMachineEvents(machine);
                machine.TransitionCompleted += throwException;
                machine.Start(State.S1);
                machine.Send(Event.S1_to_S2);
                machine.WaitForPendingEvents();
                assertMachineEvents(true, false, true, true);
                Assert.AreEqual(State.S2, machine.CurrentStateID);
            }
        }
        public void TransitionDeclined()
        {
            using (var machine = new TestMachine <State, Event, EventArgs>())
            {
                machine[State.S1].ExitHandler += throwException;
                machine.AddTransition(State.S1, Event.S1_to_S2, State.S2);

                registerMachineEvents(machine);
                machine.Start(State.S1);
                machine.Send(Event.S2_to_S1);
                machine.WaitForPendingEvents();
                assertMachineEvents(true, true, false, false);
                Assert.AreEqual(State.S1, machine.CurrentStateID);
            }
        }
        public void GuardException_should_not_prevent_machine_from_checking_other_guards()
        {
            using (var machine = new TestMachine <State, Event, EventArgs>())
            {
                machine.AddTransition(State.S1, Event.S1_to_S2, guardException, State.S2);
                machine.AddTransition(State.S1, Event.S1_to_S2, delegate { return(true); }, State.S1_1);

                registerMachineEvents(machine);
                machine.Start(State.S1);
                machine.Send(Event.S1_to_S2);
                machine.WaitForPendingEvents();
                assertMachineEvents(true, false, true, true);
                Assert.AreEqual(State.S1_1, machine.CurrentStateID);
            }
        }
        public void GuardException()
        {
            using (var machine = new TestMachine <State, Event, EventArgs>())
            {
                machine.AddTransition(State.S1, Event.S1_to_S2, guardException, State.S2);

                registerMachineEvents(machine);
                machine.Start(State.S1);
                machine.Send(Event.S1_to_S2);
                machine.WaitForPendingEvents();
                assertMachineEvents(true, true, false, true);
                Assert.AreEqual(State.S1, machine.CurrentStateID);
                Assert.IsInstanceOf <GuardException>(m_lastException);
            }
        }
        public void EntryExceptionOnInit()
        {
            TransitionErrorEventArgs <State, Event, EventArgs> args;

            using (var machine = new TestMachine <State, Event, EventArgs>())
            {
                machine[State.S1].EntryHandler += throwException;
                machine.AddTransition(State.S1, Event.S1_to_S2, State.S2);
                registerMachineEvents(machine);
                args = null;
                machine.ExceptionThrown += (sender, e) => args = e;
                machine.Start(State.S1);
                machine.WaitForPendingEvents();
                assertMachineEvents(false, false, false, true);
                Assert.AreEqual(State.S1, machine.CurrentStateID);
            }
            Assert.AreEqual(false, args.MachineInitialized);
            Assert.IsInstanceOf <EntryException>(m_lastException);
        }
        public void Superstate_should_handle_event_when_guard_of_substate_does_not_pass()
        {
            using (var machine = new TestMachine <State, Event, EventArgs>())
            {
                machine.SetupSubstates(State.S1, HistoryType.None, State.S1_1, State.S1_2);
                machine.AddTransition(State.S1_1, Event.E1, State.S1_2);
                machine.AddTransition(State.S1_2, Event.E1, (sender, args) => false, State.S1_2);
                machine.AddTransition(State.S1, Event.E1, State.S2);

                IActiveStateMachine <State, Event, EventArgs> m = machine;
                registerMachineEvents(m);
                machine.Start(State.S1);
                m.SendSynchronously(Event.E1);
                Assert.AreEqual(State.S1_2, m.CurrentStateID);
                machine.SendSynchronously(Event.E1);
                Assert.AreEqual(State.S2, m.CurrentStateID);
                m.WaitForPendingEvents();
                assertMachineEvents(true, false, true, false);
            }
        }
        public void BeginDispatch()
        {
            using (var machine = new TestMachine <State, Event, int>())
            {
                machine.AddTransition(State.S1, Event.S1_to_S2, State.S2);
                machine.BeginDispatch += (sender, e) =>
                {
                    Assert.AreEqual(State.S1, machine.CurrentStateID);
                    Assert.AreEqual(Event.S1_to_S2, e.EventID);
                    Assert.AreEqual(State.S1, e.SourceStateID);
                    Assert.AreEqual(123, e.EventArgs);
                };

                registerMachineEvents(machine);
                machine.Start(State.S1);
                machine.Send(Event.S1_to_S2, 123);
                machine.WaitForPendingEvents();
                assertMachineEvents(true, false, true, false);
                Assert.AreEqual(State.S2, machine.CurrentStateID);
            }
        }
        public void EntryExceptionOnSend()
        {
            TransitionErrorEventArgs <State, Event, EventArgs> errorEventArgs;

            using (var machine = new TestMachine <State, Event, EventArgs>())
            {
                machine[State.S2].EntryHandler += throwException;
                machine.AddTransition(State.S1, Event.S1_to_S2, State.S2);
                errorEventArgs           = null;
                machine.ExceptionThrown += (sender, args) => errorEventArgs = args;
                registerMachineEvents(machine);
                machine.Start(State.S1);
                machine.Send(Event.S1_to_S2);
                machine.WaitForPendingEvents();
                assertMachineEvents(true, false, true, true);

                Assert.AreEqual(State.S1, errorEventArgs.SourceStateID);
                Assert.AreEqual(State.S2, machine.CurrentStateID);
            }
            Assert.AreEqual(Event.S1_to_S2, errorEventArgs.EventID);
            Assert.IsInstanceOf <EntryException>(m_lastException);
        }
        public void TransitionActions_ThrowsExceptionTwice()
        {
            using (var machine = new TestMachine <State, Event, EventArgs>())
            {
                var count = 0;
                EventHandler <TransitionEventArgs <State, Event, EventArgs> > actionHandler =
                    (sender, e) =>
                {
                    count++;
                    throwException(sender, e);
                };
                machine.AddTransition(State.S1, Event.S1_to_S2, State.S2, actionHandler, actionHandler);

                registerMachineEvents(machine);
                machine.Start(State.S1);
                machine.Send(Event.S1_to_S2);
                machine.WaitForPendingEvents();
                assertMachineEvents(true, false, true, true);
                Assert.AreEqual(State.S2, machine.CurrentStateID);
                Assert.AreEqual(2, count);
                Assert.IsInstanceOf <ActionException>(m_lastException);
            }
        }