예제 #1
0
 def test_first_cycle_transitions_to_initial(self):
     sm = StateMachine({"initial": "foobar"})
     sm.process(0.1)
     self.assertEqual(
         sm.state,
         "foobar",
         "StateMachine failed to transition into " "initial state on first cycle",
     )
예제 #2
0
    def test_can_transition_with_lambda(self):
        sm = StateMachine(
            {"initial": "foo", "transitions": {("foo", "bar"): lambda: True}}
        )

        self.assertIsNone(sm.state)
        sm.process(0.1)
        self.assertEqual(sm.state, "foo")
        sm.process(0.2)
        self.assertEqual(sm.state, "bar")
예제 #3
0
    def test_can_transition_with_lambda(self):
        sm = StateMachine({
            'initial': 'foo',
            'transitions': {
                ('foo', 'bar'): lambda: True
            }
        })

        self.assertIsNone(sm.state)
        sm.process(0.1)
        self.assertEqual(sm.state, 'foo')
        sm.process(0.2)
        self.assertEqual(sm.state, 'bar')
    def test_can_transition_with_lambda(self):
        sm = StateMachine({
            'initial': 'foo',
            'transitions': {
                ('foo', 'bar'): lambda: True
            }
        })

        self.assertIsNone(sm.state)
        sm.process(0.1)
        self.assertEqual(sm.state, 'foo')
        sm.process(0.2)
        self.assertEqual(sm.state, 'bar')
예제 #5
0
    def test_can_transition_with_callable(self):
        transition = Mock(return_value=True)
        sm = StateMachine(
            {"initial": "foo", "transitions": {("foo", "bar"): transition}}
        )

        transition.assert_not_called()
        self.assertIsNone(sm.state)
        sm.process(0.1)
        transition.assert_not_called()
        self.assertEqual(sm.state, "foo")
        sm.process(0.2)
        self.assertTrue(transition.called)
        self.assertEqual(sm.state, "bar")
예제 #6
0
    def test_can_transition_with_Transition(self, tr_call):
        transition = Transition()
        sm = StateMachine(
            {"initial": "foo", "transitions": {("foo", "bar"): transition}}
        )

        tr_call.assert_not_called()
        self.assertIsNone(sm.state)
        sm.process(0.1)
        tr_call.assert_not_called()
        self.assertEqual(sm.state, "foo")
        sm.process(0.2)
        self.assertTrue(tr_call.called)
        self.assertEqual(sm.state, "bar")
예제 #7
0
    def test_can_transition_with_Transition(self, tr_call):
        transition = Transition()
        sm = StateMachine({
            'initial': 'foo',
            'transitions': {
                ('foo', 'bar'): transition
            }
        })

        tr_call.assert_not_called()
        self.assertIsNone(sm.state)
        sm.process(0.1)
        tr_call.assert_not_called()
        self.assertEqual(sm.state, 'foo')
        sm.process(0.2)
        self.assertTrue(tr_call.called)
        self.assertEqual(sm.state, 'bar')
    def test_can_transition_with_Transition(self, tr_call):
        transition = Transition()
        sm = StateMachine({
            'initial': 'foo',
            'transitions': {
                ('foo', 'bar'): transition
            }
        })

        tr_call.assert_not_called()
        self.assertIsNone(sm.state)
        sm.process(0.1)
        tr_call.assert_not_called()
        self.assertEqual(sm.state, 'foo')
        sm.process(0.2)
        self.assertTrue(tr_call.called)
        self.assertEqual(sm.state, 'bar')
예제 #9
0
    def test_can_transition_with_callable(self):
        transition = Mock(return_value=True)
        sm = StateMachine({
            'initial': 'foo',
            'transitions': {
                ('foo', 'bar'): transition
            }
        })

        transition.assert_not_called()
        self.assertIsNone(sm.state)
        sm.process(0.1)
        transition.assert_not_called()
        self.assertEqual(sm.state, 'foo')
        sm.process(0.2)
        self.assertTrue(transition.called)
        self.assertEqual(sm.state, 'bar')
    def test_can_transition_with_callable(self):
        transition = Mock(return_value=True)
        sm = StateMachine({
            'initial': 'foo',
            'transitions': {
                ('foo', 'bar'): transition
            }
        })

        transition.assert_not_called()
        self.assertIsNone(sm.state)
        sm.process(0.1)
        transition.assert_not_called()
        self.assertEqual(sm.state, 'foo')
        sm.process(0.2)
        self.assertTrue(transition.called)
        self.assertEqual(sm.state, 'bar')
예제 #11
0
class SimulatedBearings(CanProcess, MagneticBearings):
    def __init__(self):
        super(SimulatedBearings, self).__init__()

        self._csm = StateMachine({
            'initial': 'resting',

            'transitions': {
                ('resting', 'levitating'): lambda: self._levitate,
                ('levitating', 'levitated'): self.levitationComplete,
                ('levitated', 'delevitating'): lambda: not self._levitate,
                ('delevitating', 'resting'): self.delevitationComplete,
            }
        })

        self._levitate = False

    def engage(self):
        self.levitate()

    def disengage(self):
        self.delevitate()

    def levitate(self):
        self._levitate = True

    def delevitate(self):
        self._levitate = False

    def levitationComplete(self):
        return True

    def delevitationComplete(self):
        return True

    def doProcess(self, dt):
        self._csm.process(dt)

    @property
    def ready(self):
        return self._csm.state == 'levitated' and self._levitate

    @property
    def idle(self):
        return self._csm.state == 'resting' and not self._levitate
예제 #12
0
class SimulatedBearings(CanProcess, MagneticBearings):
    def __init__(self):
        super(SimulatedBearings, self).__init__()

        self._csm = StateMachine({
            "initial": "resting",
            "transitions": {
                ("resting", "levitating"): lambda: self._levitate,
                ("levitating", "levitated"): self.levitationComplete,
                ("levitated", "delevitating"): lambda: not self._levitate,
                ("delevitating", "resting"): self.delevitationComplete,
            },
        })

        self._levitate = False

    def engage(self):
        self.levitate()

    def disengage(self):
        self.delevitate()

    def levitate(self):
        self._levitate = True

    def delevitate(self):
        self._levitate = False

    def levitationComplete(self):
        return True

    def delevitationComplete(self):
        return True

    def doProcess(self, dt):
        self._csm.process(dt)

    @property
    def ready(self):
        return self._csm.state == "levitated" and self._levitate

    @property
    def idle(self):
        return self._csm.state == "resting" and not self._levitate
예제 #13
0
class SimulatedBearings(CanProcess, MagneticBearings):
    def __init__(self):
        super(SimulatedBearings, self).__init__()

        self._csm = StateMachine({
            'initial': 'resting',
            'transitions': {
                ('resting', 'levitating'): lambda: self._levitate,
                ('levitating', 'levitated'): self.levitationComplete,
                ('levitated', 'delevitating'): lambda: not self._levitate,
                ('delevitating', 'resting'): self.delevitationComplete,
            }
        })

        self._levitate = False

    def engage(self):
        self.levitate()

    def disengage(self):
        self.delevitate()

    def levitate(self):
        self._levitate = True

    def delevitate(self):
        self._levitate = False

    def levitationComplete(self):
        return True

    def delevitationComplete(self):
        return True

    def doProcess(self, dt):
        self._csm.process(dt)

    @property
    def ready(self):
        return self._csm.state == 'levitated' and self._levitate

    @property
    def idle(self):
        return self._csm.state == 'resting' and not self._levitate
    def test_can(self):
        sm = StateMachine({
            'initial': 'init',
            'transitions': {
                ('init', 'foo'): lambda: True,
                ('foo', 'bar'): lambda: True,
                ('bar', 'foo'): lambda: True,
                ('bar', 'init'): lambda: True,
                ('bar', 'bar'): lambda: True
            }
        })

        self.assertEqual(sm.state, None)
        self.assertIs(sm.can('init'), True)
        self.assertIs(sm.can('foo'), False)
        self.assertIs(sm.can('bar'), False)
        self.assertIs(sm.can(None), False)

        sm.process()
        self.assertEqual(sm.state, 'init')
        self.assertIs(sm.can('foo'), True)
        self.assertIs(sm.can('bar'), False)
        self.assertIs(sm.can('init'), False)

        sm.process()
        self.assertEqual(sm.state, 'foo')
        self.assertIs(sm.can('bar'), True)
        self.assertIs(sm.can('init'), False)
        self.assertIs(sm.can('foo'), False)

        sm.process()
        self.assertEqual(sm.state, 'bar')
        self.assertIs(sm.can('foo'), True)
        self.assertIs(sm.can('init'), True)
        self.assertIs(sm.can('bar'), True)
    def test_bind_handlers_by_name_default_behaviour(self):
        target = Mock()
        sm = StateMachine({
            'initial': 'foo',
            'transitions': {
                ('foo', 'bar'): lambda: True
            }
        })
        sm.bind_handlers_by_name(target)

        # First cycle enters and executes initial state, but forces delta T to zero
        sm.process(1.0)
        target._on_entry_foo.assert_called_once_with(0)
        target._in_state_foo.assert_called_once_with(0)

        target._on_entry_foo.reset_mock()
        target._in_state_foo.reset_mock()

        # Second cycle transitions due to lambda: True above
        sm.process(2.0)
        target._on_exit_foo.assert_called_once_with(2.0)
        target._on_entry_bar.assert_called_once_with(2.0)
        target._in_state_bar.assert_called_once_with(2.0)

        target._on_exit_foo.reset_mock()
        target._on_entry_bar.reset_mock()
        target._in_state_bar.reset_mock()

        # Third cycle only does an in_state in bar
        sm.process(3.0)
        target._in_state_bar.assert_called_once_with(3.0)
        target._on_entry_bar.assert_not_called()
        target._on_exit_bar.assert_not_called()
    def test_can_specify_state_handlers_as_list(self):
        on_entry = Mock()
        in_state = Mock()
        on_exit = Mock()
        sm = StateMachine({
            'initial': 'foo',
            'states': {
                'foo': [on_entry, in_state, on_exit],
            },
            'transitions': {
                ('foo', 'bar'): lambda: True
            }
        })

        # First cycle enters and executes initial state, but forces delta T to zero
        sm.process(1.0)
        on_entry.assert_called_once_with(0)
        in_state.assert_called_once_with(0)

        on_entry.reset_mock()
        in_state.reset_mock()

        # Second cycle transitions due to lambda: True above
        sm.process(2.0)
        on_exit.assert_called_once_with(2.0)

        on_exit.reset_mock()

        # Third cycle only does an in_state in bar, shouldn't affect foo
        sm.process(3.0)
        on_entry.assert_not_called()
        in_state.assert_not_called()
        on_exit.assert_not_called()
예제 #17
0
    def test_can(self):
        sm = StateMachine({
            'initial': 'init',
            'transitions': {
                ('init', 'foo'): lambda: True,
                ('foo', 'bar'): lambda: True,
                ('bar', 'foo'): lambda: True,
                ('bar', 'init'): lambda: True,
                ('bar', 'bar'): lambda: True
            }
        })

        self.assertEqual(sm.state, None)
        self.assertIs(sm.can('init'), True)
        self.assertIs(sm.can('foo'), False)
        self.assertIs(sm.can('bar'), False)
        self.assertIs(sm.can(None), False)

        sm.process()
        self.assertEqual(sm.state, 'init')
        self.assertIs(sm.can('foo'), True)
        self.assertIs(sm.can('bar'), False)
        self.assertIs(sm.can('init'), False)

        sm.process()
        self.assertEqual(sm.state, 'foo')
        self.assertIs(sm.can('bar'), True)
        self.assertIs(sm.can('init'), False)
        self.assertIs(sm.can('foo'), False)

        sm.process()
        self.assertEqual(sm.state, 'bar')
        self.assertIs(sm.can('foo'), True)
        self.assertIs(sm.can('init'), True)
        self.assertIs(sm.can('bar'), True)
예제 #18
0
    def test_can_specify_state_handlers_as_list(self):
        on_entry = Mock()
        in_state = Mock()
        on_exit = Mock()
        sm = StateMachine({
            'initial': 'foo',
            'states': {
                'foo': [on_entry, in_state, on_exit],
            },
            'transitions': {
                ('foo', 'bar'): lambda: True
            }
        })

        # First cycle enters and executes initial state, but forces delta T to zero
        sm.process(1.0)
        on_entry.assert_called_once_with(0)
        in_state.assert_called_once_with(0)

        on_entry.reset_mock()
        in_state.reset_mock()

        # Second cycle transitions due to lambda: True above
        sm.process(2.0)
        on_exit.assert_called_once_with(2.0)

        on_exit.reset_mock()

        # Third cycle only does an in_state in bar, shouldn't affect foo
        sm.process(3.0)
        on_entry.assert_not_called()
        in_state.assert_not_called()
        on_exit.assert_not_called()
예제 #19
0
    def test_bind_handlers_by_name_default_behaviour(self):
        target = Mock()
        sm = StateMachine({
            'initial': 'foo',
            'transitions': {
                ('foo', 'bar'): lambda: True
            }
        })
        sm.bind_handlers_by_name(target)

        # First cycle enters and executes initial state, but forces delta T to zero
        sm.process(1.0)
        target._on_entry_foo.assert_called_once_with(0)
        target._in_state_foo.assert_called_once_with(0)

        target._on_entry_foo.reset_mock()
        target._in_state_foo.reset_mock()

        # Second cycle transitions due to lambda: True above
        sm.process(2.0)
        target._on_exit_foo.assert_called_once_with(2.0)
        target._on_entry_bar.assert_called_once_with(2.0)
        target._in_state_bar.assert_called_once_with(2.0)

        target._on_exit_foo.reset_mock()
        target._on_entry_bar.reset_mock()
        target._in_state_bar.reset_mock()

        # Third cycle only does an in_state in bar
        sm.process(3.0)
        target._in_state_bar.assert_called_once_with(3.0)
        target._on_entry_bar.assert_not_called()
        target._on_exit_bar.assert_not_called()
예제 #20
0
    def test_bind_handlers_by_name_override(self):
        # first target will accept any event call
        first = Mock()

        # second target will 'override' the events for bar
        second = Mock(spec=['_on_entry_bar', '_in_state_bar', '_on_exit_bar'])

        sm = StateMachine({
            'initial': 'foo',
            'transitions': {
                ('foo', 'bar'): lambda: True
            }
        })
        sm.bind_handlers_by_name(first)
        sm.bind_handlers_by_name(second, override=True)

        # First cycle enters and executes initial state, but forces delta T to zero
        sm.process(1.0)
        first._on_entry_foo.assert_called_once_with(0)
        first._in_state_foo.assert_called_once_with(0)

        first._on_entry_foo.reset_mock()
        first._in_state_foo.reset_mock()

        # Second cycle transitions due to lambda: True above
        sm.process(2.0)
        first._on_exit_foo.assert_called_once_with(2.0)
        second._on_entry_bar.assert_called_once_with(2.0)
        second._in_state_bar.assert_called_once_with(2.0)

        first._on_exit_foo.reset_mock()
        second._on_entry_bar.reset_mock()
        second._in_state_bar.reset_mock()

        # Third cycle only does an in_state in bar
        sm.process(3.0)
        second._in_state_bar.assert_called_once_with(3.0)
        second._on_entry_bar.assert_not_called()
        second._on_exit_bar.assert_not_called()

        # 'bar' events should not have been called on 'first'
        first._on_entry_bar.assert_not_called()
        first._in_state_bar.assert_not_called()
        first._on_exit_bar.assert_not_called()
    def test_bind_handlers_by_name_override(self):
        # first target will accept any event call
        first = Mock()

        # second target will 'override' the events for bar
        second = Mock(spec=['_on_entry_bar', '_in_state_bar', '_on_exit_bar'])

        sm = StateMachine({
            'initial': 'foo',
            'transitions': {
                ('foo', 'bar'): lambda: True
            }
        })
        sm.bind_handlers_by_name(first)
        sm.bind_handlers_by_name(second, override=True)

        # First cycle enters and executes initial state, but forces delta T to zero
        sm.process(1.0)
        first._on_entry_foo.assert_called_once_with(0)
        first._in_state_foo.assert_called_once_with(0)

        first._on_entry_foo.reset_mock()
        first._in_state_foo.reset_mock()

        # Second cycle transitions due to lambda: True above
        sm.process(2.0)
        first._on_exit_foo.assert_called_once_with(2.0)
        second._on_entry_bar.assert_called_once_with(2.0)
        second._in_state_bar.assert_called_once_with(2.0)

        first._on_exit_foo.reset_mock()
        second._on_entry_bar.reset_mock()
        second._in_state_bar.reset_mock()

        # Third cycle only does an in_state in bar
        sm.process(3.0)
        second._in_state_bar.assert_called_once_with(3.0)
        second._on_entry_bar.assert_not_called()
        second._on_exit_bar.assert_not_called()

        # 'bar' events should not have been called on 'first'
        first._on_entry_bar.assert_not_called()
        first._in_state_bar.assert_not_called()
        first._on_exit_bar.assert_not_called()
예제 #22
0
    def test_bind_handlers_by_name_custom_prefix(self):
        target = Mock()
        sm = StateMachine({
            'initial': 'foo',
            'transitions': {
                ('foo', 'bar'): lambda: True
            }
        })
        sm.bind_handlers_by_name(target,
                                 prefix={
                                     'on_entry': 'enter_',
                                     'in_state': 'do_',
                                     'on_exit': 'exit_',
                                 })

        # First cycle enters and executes initial state, but forces delta T to zero
        sm.process(1.0)
        target.enter_foo.assert_called_once_with(0)
        target.do_foo.assert_called_once_with(0)

        target.enter_foo.reset_mock()
        target.do_foo.reset_mock()

        # Second cycle transitions due to lambda: True above
        sm.process(2.0)
        target.exit_foo.assert_called_once_with(2.0)
        target.enter_bar.assert_called_once_with(2.0)
        target.do_bar.assert_called_once_with(2.0)

        target.exit_foo.reset_mock()
        target.enter_bar.reset_mock()
        target.do_bar.reset_mock()

        # Third cycle only does an in_state in bar
        sm.process(3.0)
        target.do_bar.assert_called_once_with(3.0)
        target.enter_bar.assert_not_called()
        target.exit_bar.assert_not_called()
예제 #23
0
    def test_can_specify_state_handlers_as_dict(self):
        on_entry = Mock()
        in_state = Mock()
        on_exit = Mock()
        sm = StateMachine(
            {
                "initial": "foo",
                "states": {
                    "foo": {
                        "on_entry": on_entry,
                        "in_state": in_state,
                        "on_exit": on_exit,
                    },
                },
                "transitions": {("foo", "bar"): lambda: True},
            }
        )

        # First cycle enters and executes initial state, but forces delta T to zero
        sm.process(1.0)
        on_entry.assert_called_once_with(0)
        in_state.assert_called_once_with(0)

        on_entry.reset_mock()
        in_state.reset_mock()

        # Second cycle transitions due to lambda: True above
        sm.process(2.0)
        on_exit.assert_called_once_with(2.0)

        on_exit.reset_mock()

        # Third cycle only does an in_state in bar, shouldn't affect foo
        sm.process(3.0)
        on_entry.assert_not_called()
        in_state.assert_not_called()
        on_exit.assert_not_called()
    def test_bind_handlers_by_name_custom_prefix(self):
        target = Mock()
        sm = StateMachine({
            'initial': 'foo',
            'transitions': {
                ('foo', 'bar'): lambda: True
            }
        })
        sm.bind_handlers_by_name(target, prefix={
            'on_entry': 'enter_',
            'in_state': 'do_',
            'on_exit': 'exit_',
        })

        # First cycle enters and executes initial state, but forces delta T to zero
        sm.process(1.0)
        target.enter_foo.assert_called_once_with(0)
        target.do_foo.assert_called_once_with(0)

        target.enter_foo.reset_mock()
        target.do_foo.reset_mock()

        # Second cycle transitions due to lambda: True above
        sm.process(2.0)
        target.exit_foo.assert_called_once_with(2.0)
        target.enter_bar.assert_called_once_with(2.0)
        target.do_bar.assert_called_once_with(2.0)

        target.exit_foo.reset_mock()
        target.enter_bar.reset_mock()
        target.do_bar.reset_mock()

        # Third cycle only does an in_state in bar
        sm.process(3.0)
        target.do_bar.assert_called_once_with(3.0)
        target.enter_bar.assert_not_called()
        target.exit_bar.assert_not_called()
예제 #25
0
    def test_can(self):
        sm = StateMachine(
            {
                "initial": "init",
                "transitions": {
                    ("init", "foo"): lambda: True,
                    ("foo", "bar"): lambda: True,
                    ("bar", "foo"): lambda: True,
                    ("bar", "init"): lambda: True,
                    ("bar", "bar"): lambda: True,
                },
            }
        )

        self.assertEqual(sm.state, None)
        self.assertIs(sm.can("init"), True)
        self.assertIs(sm.can("foo"), False)
        self.assertIs(sm.can("bar"), False)
        self.assertIs(sm.can(None), False)

        sm.process()
        self.assertEqual(sm.state, "init")
        self.assertIs(sm.can("foo"), True)
        self.assertIs(sm.can("bar"), False)
        self.assertIs(sm.can("init"), False)

        sm.process()
        self.assertEqual(sm.state, "foo")
        self.assertIs(sm.can("bar"), True)
        self.assertIs(sm.can("init"), False)
        self.assertIs(sm.can("foo"), False)

        sm.process()
        self.assertEqual(sm.state, "bar")
        self.assertIs(sm.can("foo"), True)
        self.assertIs(sm.can("init"), True)
        self.assertIs(sm.can("bar"), True)
예제 #26
0
    def test_can_specify_state_handlers_as_State(self, *_):
        foo = State()
        bar = State()
        sm = StateMachine({
            'initial': 'foo',
            'states': {
                'foo': foo,
                'bar': bar,
            },
            'transitions': {
                ('foo', 'bar'): lambda: True
            }
        })

        # First cycle enters and executes initial state, but forces delta T to zero
        sm.process(1.0)
        foo.on_entry.assert_called_once_with(0)
        foo.in_state.assert_called_once_with(0)

        foo.on_entry.reset_mock()
        foo.in_state.reset_mock()

        # Second cycle transitions due to lambda: True above
        sm.process(2.0)
        foo.on_exit.assert_called_once_with(2.0)
        bar.on_entry.assert_called_once_with(2.0)
        bar.in_state.assert_called_once_with(2.0)

        foo.on_exit.reset_mock()
        bar.on_entry.reset_mock()
        bar.in_state.reset_mock()

        # Third cycle only does an in_state in bar
        sm.process(3.0)
        bar.in_state.assert_called_once_with(3.0)
        bar.on_entry.assert_not_called()
        bar.on_exit.assert_not_called()
    def test_can_specify_state_handlers_as_State(self, *_):
        foo = State()
        bar = State()
        sm = StateMachine({
            'initial': 'foo',
            'states': {
                'foo': foo,
                'bar': bar,
            },
            'transitions': {
                ('foo', 'bar'): lambda: True
            }
        })

        # First cycle enters and executes initial state, but forces delta T to zero
        sm.process(1.0)
        foo.on_entry.assert_called_once_with(0)
        foo.in_state.assert_called_once_with(0)

        foo.on_entry.reset_mock()
        foo.in_state.reset_mock()

        # Second cycle transitions due to lambda: True above
        sm.process(2.0)
        foo.on_exit.assert_called_once_with(2.0)
        bar.on_entry.assert_called_once_with(2.0)
        bar.in_state.assert_called_once_with(2.0)

        foo.on_exit.reset_mock()
        bar.on_entry.reset_mock()
        bar.in_state.reset_mock()

        # Third cycle only does an in_state in bar
        sm.process(3.0)
        bar.in_state.assert_called_once_with(3.0)
        bar.on_entry.assert_not_called()
        bar.on_exit.assert_not_called()
예제 #28
0
    def test_bind_handlers_by_name_custom_prefix(self):
        target = Mock()
        sm = StateMachine(
            {"initial": "foo", "transitions": {("foo", "bar"): lambda: True}}
        )
        sm.bind_handlers_by_name(
            target,
            prefix={
                "on_entry": "enter_",
                "in_state": "do_",
                "on_exit": "exit_",
            },
        )

        # First cycle enters and executes initial state, but forces delta T to zero
        sm.process(1.0)
        target.enter_foo.assert_called_once_with(0)
        target.do_foo.assert_called_once_with(0)

        target.enter_foo.reset_mock()
        target.do_foo.reset_mock()

        # Second cycle transitions due to lambda: True above
        sm.process(2.0)
        target.exit_foo.assert_called_once_with(2.0)
        target.enter_bar.assert_called_once_with(2.0)
        target.do_bar.assert_called_once_with(2.0)

        target.exit_foo.reset_mock()
        target.enter_bar.reset_mock()
        target.do_bar.reset_mock()

        # Third cycle only does an in_state in bar
        sm.process(3.0)
        target.do_bar.assert_called_once_with(3.0)
        target.enter_bar.assert_not_called()
        target.exit_bar.assert_not_called()
 def test_first_cycle_transitions_to_initial(self):
     sm = StateMachine({'initial': 'foobar'})
     sm.process(0.1)
     self.assertEqual(sm.state, 'foobar', "StateMachine failed to transition into "
                                          "initial state on first cycle")