コード例 #1
0
ファイル: test_StateMachine.py プロジェクト: tacaswell/lewis
    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()
コード例 #2
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",
     )
コード例 #3
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()
コード例 #4
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')
コード例 #5
0
    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
コード例 #6
0
    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
コード例 #7
0
ファイル: test_StateMachine.py プロジェクト: tacaswell/lewis
    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()
コード例 #8
0
    def __init__(
        self,
        override_states=None,
        override_transitions=None,
        override_initial_state=None,
        override_initial_data=None,
    ):
        super(StateMachineDevice, self).__init__()

        self.log.info("Creating device, setting up state machine")

        self._initialize_data()
        self._override_data(override_initial_data)

        state_handlers = self._get_final_state_handlers(override_states)
        initial = override_initial_state or self._get_initial_state()

        if initial not in state_handlers:
            raise RuntimeError(
                "Initial state '{}' is not a valid state.".format(initial))

        self._csm = StateMachine(
            {
                "initial":
                initial,
                "states":
                state_handlers,
                "transitions":
                self._get_final_transition_handlers(override_transitions),
            },
            context=self,
        )

        self.add_processor(self._csm)
コード例 #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')
コード例 #10
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')
コード例 #11
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()
コード例 #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
    def test_Transition_receives_Context(self):
        transition = Transition()
        context = object()
        StateMachine(
            {"initial": "foo", "transitions": {("foo", "bar"): transition}},
            context=context,
        )

        self.assertEqual(transition._context, context)
コード例 #14
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
コード例 #15
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
コード例 #16
0
ファイル: test_StateMachine.py プロジェクト: tacaswell/lewis
    def test_State_receives_Context(self):
        state = State()
        context = object()
        StateMachine({
            'initial': 'foo',
            'states': {
                'foo': state
            }
        },
                     context=context)

        self.assertEqual(state._context, context)
コード例 #17
0
ファイル: test_StateMachine.py プロジェクト: tacaswell/lewis
    def test_Transition_receives_Context(self):
        transition = Transition()
        context = object()
        StateMachine(
            {
                'initial': 'foo',
                'transitions': {
                    ('foo', 'bar'): transition
                }
            },
            context=context)

        self.assertEqual(transition._context, context)
コード例 #18
0
ファイル: test_StateMachine.py プロジェクト: tacaswell/lewis
    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()
コード例 #19
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()
コード例 #20
0
    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
コード例 #21
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")
コード例 #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
ファイル: test_StateMachine.py プロジェクト: tacaswell/lewis
    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')
コード例 #24
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")
コード例 #25
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")
コード例 #26
0
ファイル: test_StateMachine.py プロジェクト: tacaswell/lewis
    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()
コード例 #27
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()
コード例 #28
0
ファイル: test_StateMachine.py プロジェクト: tacaswell/lewis
    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')
コード例 #29
0
ファイル: test_StateMachine.py プロジェクト: tacaswell/lewis
    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')
コード例 #30
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()
コード例 #31
0
    def test_State_receives_Context(self):
        state = State()
        context = object()
        StateMachine({"initial": "foo", "states": {"foo": state}}, context=context)

        self.assertEqual(state._context, context)
コード例 #32
0
ファイル: test_StateMachine.py プロジェクト: tacaswell/lewis
    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)
コード例 #33
0
ファイル: test_StateMachine.py プロジェクト: tacaswell/lewis
 def test_state_machine_starts_in_None(self):
     sm = StateMachine({'initial': 'foobar'})
     self.assertIsNone(sm.state,
                       "StateMachine should start in the 'None' non-state")
コード例 #34
0
ファイル: test_StateMachine.py プロジェクト: tacaswell/lewis
    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()
コード例 #35
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()
コード例 #36
0
ファイル: test_StateMachine.py プロジェクト: tacaswell/lewis
    def test_initial_state_is_required(self):
        with self.assertRaises(StateMachineException) as context:
            StateMachine({})

        self.assertTrue("must include 'initial'" in str(context.exception))
コード例 #37
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)
コード例 #38
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)
コード例 #39
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")