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 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);
            }
        }