def test_null_transition_constructor(self): source_state = State("source") event = Event("event") transition = NullTransition(source_state, event) assert transition.event == event assert transition.source_state == source_state assert transition.destination_state == source_state
def test_null_transition_with_valid_event(self): state_machine = StateMachine("sm") initial_state = State("initial_state") event = Event("event") state_machine.add_state(initial_state, initial_state=True) state_machine.add_event(event) assert state_machine.add_null_transition(initial_state, event) is not None
def test_transition_with_invalid_event(self): state_machine = StateMachine("sm") initial_state = State("initial_state") second_state = State("second_state") event = Event("event") state_machine.add_state(initial_state, initial_state=True) state_machine.add_state(second_state) assert state_machine.add_transition(initial_state, second_state, event) is None
def test_self_transition_no_condition(self): entry_callback = MagicMock() exit_callback = MagicMock() source_state = State("source") source_state.on_exit(exit_callback) source_state.on_entry(entry_callback) event = Event("event") transition = SelfTransition(source_state, event) transition("data") entry_callback.assert_called_once_with("data") exit_callback.assert_called_once_with("data")
def test_null_transition_action(self): source_state = State("source") event = Event("event") transition = NullTransition(source_state, event) condition_callback = MagicMock(return_value=True) action_callback = MagicMock() transition.add_condition(condition_callback) transition.add_action(action_callback) transition("data") condition_callback.assert_called_once_with("data") action_callback.assert_called_once_with("data")
def test_null_transition_condition_false(self): entry_callback = MagicMock() exit_callback = MagicMock() source_state = State("source") source_state.on_exit(exit_callback) source_state.on_entry(entry_callback) event = Event("event") transition = NullTransition(source_state, event) condition_callback = MagicMock(return_value=False) transition.add_condition(condition_callback) transition("data") entry_callback.assert_not_called() exit_callback.assert_not_called() condition_callback.assert_called_once_with("data")
def test_self_transition_condition_true(self): entry_callback = MagicMock() exit_callback = MagicMock() source_state = State("source") source_state.on_exit(exit_callback) source_state.on_entry(entry_callback) event = Event("event") transition = SelfTransition(source_state, event) condition_callback = MagicMock(return_value=True) transition.add_condition(condition_callback) transition("data") entry_callback.assert_called_once_with("data") exit_callback.assert_called_once_with("data") condition_callback.assert_called_once_with("data")
def test_exit_callback(self): exit_sm_cb = MagicMock() state_machine = StateMachine("sm") state_machine.on_exit(exit_sm_cb) initial_state = State("initial_state") second_state = State("second_state") exit_state_error = ExitState("Error") event = Event("event") error_event = Event("error") state_machine.add_state(initial_state, initial_state=True) state_machine.add_state(second_state) state_machine.add_state(exit_state_error) state_machine.add_event(event) state_machine.add_event(error_event) state_machine.add_transition(initial_state, second_state, event) state_machine.add_transition(second_state, exit_state_error, error_event) state_machine.start("data") assert state_machine.current_state == initial_state state_machine.trigger_event(event, "data") assert state_machine.current_state == second_state state_machine.trigger_event(error_event, "data") assert state_machine.current_state == exit_state_error exit_sm_cb.assert_called_once_with(exit_state_error, "data")
def create_child_fsm(): state_machine = StateMachine("child_sm") exit_cb = MagicMock() entry_cb = MagicMock() initial_state = State("child_initial_state") second_state = State("child_second_state") initial_state.on_exit(exit_cb) second_state.on_entry(entry_cb) event = Event("event") state_machine.add_state(initial_state, initial_state=True) state_machine.add_state(second_state) state_machine.add_event(event) state_machine.add_transition(initial_state, second_state, event) return state_machine
def test_event_trigger_no_initial_state(self): state_machine = StateMachine("sm") exit_cb = MagicMock() entry_cb = MagicMock() initial_state = State("initial_state") second_state = State("second_state") initial_state.on_exit(exit_cb) second_state.on_entry(entry_cb) event = Event("event") state_machine.add_state(initial_state) state_machine.add_state(second_state) state_machine.add_event(event) state_machine.add_transition(initial_state, second_state, event) with pytest.raises(ValueError): state_machine.trigger_event(event, "data")
def test_event_trigger(self): state_machine = StateMachine("sm") exit_cb = MagicMock() entry_cb = MagicMock() initial_state = State("initial_state") second_state = State("second_state") initial_state.on_exit(exit_cb) second_state.on_entry(entry_cb) event = Event("event") state_machine.add_state(initial_state, initial_state=True) state_machine.add_state(second_state) state_machine.add_event(event) state_machine.add_transition(initial_state, second_state, event) state_machine.start("data") exit_cb.assert_not_called() entry_cb.assert_not_called() state_machine.trigger_event(event, "data") exit_cb.assert_called_once_with("data") entry_cb.assert_called_once_with("data")
def test_event_trigger_propagate_but_no_child_sm(self): state_machine = StateMachine("sm") exit_cb = MagicMock() entry_cb = MagicMock() initial_state = State("initial_state") second_state = State("second_state") initial_state.on_exit(exit_cb) second_state.on_entry(entry_cb) event = Event("event") state_machine.add_state(initial_state, initial_state=True) state_machine.add_state(second_state) state_machine.add_event(event) state_machine.add_transition(initial_state, second_state, event) state_machine.start("data") exit_cb.assert_not_called() entry_cb.assert_not_called() state_machine.trigger_event(event, "data", propagate=True) # no child fsm in current state, so the event is caught in this fsm assert state_machine.current_state == second_state
def test_equality(self): event1 = Event("event") event2 = Event("event") assert event1 == event2
def test_event_constructor(self): event = Event("event") assert event.name == "event"