class Test_simple_two_state_door_machine: def setup_class(self): self.eb = EventBus() hsmdata = { 'initial': 0, 'closed_enter': 0, 'closed_exit': 0, 'opened_enter': 0, 'opened_exit': 0, 'trans_opening': 0, 'trans_closing': 0, } self.states = { 'top': State({ 'closed': Closed(), 'opened': Opened(), }) } self.trans = { 'top': { Initial: T('closed', action=get_callback('initial')), }, 'closed': { OpenDoor: T('opened', action=get_callback('trans_opening')) }, 'opened': { CloseDoor: T('closed', action=get_callback('trans_closing')) } } self.hsm = HSM(self.states, self.trans) self.hsm.data = hsmdata def test_doesnt_respond_to_events_before_starting(self): assert all([v == 0 for v in self.hsm.data.values()]) self.eb.dispatch(OpenDoor()) self.eb.dispatch(CloseDoor()) assert all([v == 0 for v in self.hsm.data.values()]) def test_in_closed_state_after_starting(self): self.hsm.start(self.eb) assert_curr_state(self.hsm, 'closed') assert self.hsm.data['initial'] == 1 assert self.hsm.data['closed_enter'] == 1 assert self.hsm.data.values().count(0) == 5 def test_ignores_close_while_closed(self): self.eb.dispatch(CloseDoor()) assert_curr_state(self.hsm, 'closed') assert self.hsm.data['initial'] == 1 assert self.hsm.data['closed_enter'] == 1 assert self.hsm.data.values().count(0) == 5 def test_transition_to_opened(self): self.eb.dispatch(OpenDoor()) assert_curr_state(self.hsm, 'opened') assert self.hsm.data['initial'] == 1 assert self.hsm.data['closed_enter'] == 1 assert self.hsm.data['closed_exit'] == 1 # changed assert self.hsm.data['opened_enter'] == 1 # changed assert self.hsm.data['opened_exit'] == 0 assert self.hsm.data['trans_opening'] == 1 # changed assert self.hsm.data['trans_closing'] == 0 def test_ignores_open_while_opened(self): self.eb.dispatch(OpenDoor()) assert_curr_state(self.hsm, 'opened') assert self.hsm.data['closed_enter'] == 1 assert self.hsm.data['closed_exit'] == 1 assert self.hsm.data['opened_enter'] == 1 assert self.hsm.data['opened_exit'] == 0 assert self.hsm.data['trans_opening'] == 1 assert self.hsm.data['trans_closing'] == 0 def test_transition_to_closed(self): self.eb.dispatch(CloseDoor()) assert_curr_state(self.hsm, 'closed') assert self.hsm.data['closed_enter'] == 2 # changed assert self.hsm.data['closed_exit'] == 1 assert self.hsm.data['opened_enter'] == 1 assert self.hsm.data['opened_exit'] == 1 # changed assert self.hsm.data['trans_opening'] == 1 assert self.hsm.data['trans_closing'] == 1 # changed def test_ignores_close_while_closed_again(self): self.eb.dispatch(CloseDoor()) assert_curr_state(self.hsm, 'closed') assert self.hsm.data['closed_enter'] == 2 assert self.hsm.data['closed_exit'] == 1 assert self.hsm.data['opened_enter'] == 1 assert self.hsm.data['opened_exit'] == 1 assert self.hsm.data['trans_opening'] == 1 assert self.hsm.data['trans_closing'] == 1 def test_transition_to_opened_again(self): self.eb.dispatch(OpenDoor()) assert_curr_state(self.hsm, 'opened') assert self.hsm.data['closed_enter'] == 2 assert self.hsm.data['closed_exit'] == 2 # changed assert self.hsm.data['opened_enter'] == 2 # changed assert self.hsm.data['opened_exit'] == 1 assert self.hsm.data['trans_opening'] == 2 # changed assert self.hsm.data['trans_closing'] == 1 def test_transition_to_closed_again(self): self.eb.dispatch(CloseDoor()) assert_curr_state(self.hsm, 'closed') assert self.hsm.data['initial'] == 1 assert self.hsm.data['closed_enter'] == 3 # changed assert self.hsm.data['closed_exit'] == 2 assert self.hsm.data['opened_enter'] == 2 assert self.hsm.data['opened_exit'] == 2 # changed assert self.hsm.data['trans_opening'] == 2 assert self.hsm.data['trans_closing'] == 2 # changed def test_doesnt_respond_to_events_after_stopping(self): self.hsm.stop() self.eb.dispatch(CloseDoor()) self.eb.dispatch(OpenDoor()) assert self.hsm.data['initial'] == 1 assert self.hsm.data['closed_enter'] == 3 # changed assert self.hsm.data['closed_exit'] == 2 assert self.hsm.data['opened_enter'] == 2 assert self.hsm.data['opened_exit'] == 2 # changed assert self.hsm.data['trans_opening'] == 2 assert self.hsm.data['trans_closing'] == 2 # changed
class Test_loops_and_multiple_paths_machine(): def setup_class(self): self.eb = EventBus() hsmdata = { 'initial': 0, 'start_enter': 0, 'start_exit': 0, 'goal_enter': 0, 'goal_exit': 0, 'trans_left': 0, 'trans_right': 0, 'trans_loop': 0, 'trans_restart': 0, } self.start = Start() self.goal = Goal() self.states = { 'top': State({ 'start': self.start, 'goal': self.goal, }) } self.trans = { 'top': { Initial: T('start', action=get_callback('initial')), }, 'start': { MoveLeft: T('goal', action=get_callback('trans_left')), MoveRight: T('goal', action=get_callback('trans_right')), }, 'goal': { Loop: T('goal', action=get_callback('trans_loop')), Restart: T('top', action=get_callback('trans_restart')), } } self.hsm = HSM(self.states, self.trans) self.hsm.data = hsmdata def test_doesnt_respond_to_events_before_starting(self): assert all([v == 0 for v in self.hsm.data.values()]) self.eb.dispatch(MoveLeft()) self.eb.dispatch(MoveRight()) self.eb.dispatch(Loop()) self.eb.dispatch(Restart()) assert all([v == 0 for v in self.hsm.data.values()]) def test_in_start_state_after_starting(self): self.hsm.start(self.eb) assert_curr_state(self.hsm, 'start') assert self.hsm.data['initial'] == 1 assert self.hsm.data['start_enter'] == 1 assert self.hsm.data.values().count(0) == 7 def test_ignore_loop_and_restart_events_while_in_start(self): self.eb.dispatch(Loop()) self.eb.dispatch(Restart()) assert_curr_state(self.hsm, 'start') assert self.hsm.data['initial'] == 1 assert self.hsm.data['start_enter'] == 1 assert self.hsm.data.values().count(0) == 7 def test_transition_to_goal_via_right(self): self.eb.dispatch(MoveRight()) assert_curr_state(self.hsm, 'goal') assert self.hsm.data['start_enter'] == 1 assert self.hsm.data['start_exit'] == 1 # changed assert self.hsm.data['goal_enter'] == 1 # changed assert self.hsm.data['goal_exit'] == 0 assert self.hsm.data['trans_left'] == 0 assert self.hsm.data['trans_right'] == 1 # changed assert self.hsm.data['trans_loop'] == 0 assert self.hsm.data['trans_restart'] == 0 def test_ignore_left_and_right_events_while_in_goal(self): self.eb.dispatch(MoveLeft()) self.eb.dispatch(MoveRight()) assert_curr_state(self.hsm, 'goal') assert self.hsm.data['start_enter'] == 1 assert self.hsm.data['start_exit'] == 1 assert self.hsm.data['goal_enter'] == 1 assert self.hsm.data['goal_exit'] == 0 assert self.hsm.data['trans_left'] == 0 assert self.hsm.data['trans_right'] == 1 assert self.hsm.data['trans_loop'] == 0 assert self.hsm.data['trans_restart'] == 0 def test_loop_in_goal(self): self.eb.dispatch(Loop()) assert_curr_state(self.hsm, 'goal') assert self.hsm.data['start_enter'] == 1 assert self.hsm.data['start_exit'] == 1 assert self.hsm.data['goal_enter'] == 2 # changed assert self.hsm.data['goal_exit'] == 1 # changed assert self.hsm.data['trans_left'] == 0 assert self.hsm.data['trans_right'] == 1 assert self.hsm.data['trans_loop'] == 1 # changed assert self.hsm.data['trans_restart'] == 0 self.eb.dispatch(Loop()) assert_curr_state(self.hsm, 'goal') assert self.hsm.data['start_enter'] == 1 assert self.hsm.data['start_exit'] == 1 assert self.hsm.data['goal_enter'] == 3 # changed assert self.hsm.data['goal_exit'] == 2 # changed assert self.hsm.data['trans_left'] == 0 assert self.hsm.data['trans_right'] == 1 assert self.hsm.data['trans_loop'] == 2 # changed assert self.hsm.data['trans_restart'] == 0 self.eb.dispatch(Loop()) assert_curr_state(self.hsm, 'goal') assert self.hsm.data['start_enter'] == 1 assert self.hsm.data['start_exit'] == 1 assert self.hsm.data['goal_enter'] == 4 # changed assert self.hsm.data['goal_exit'] == 3 # changed assert self.hsm.data['trans_left'] == 0 assert self.hsm.data['trans_right'] == 1 assert self.hsm.data['trans_loop'] == 3 # changed assert self.hsm.data['trans_restart'] == 0 def test_restart(self): assert self.hsm.data['initial'] == 1 self.eb.dispatch(Restart()) assert_curr_state(self.hsm, 'start') assert self.hsm.data['initial'] == 2 # changed assert self.hsm.data['start_enter'] == 2 # changed assert self.hsm.data['start_exit'] == 1 assert self.hsm.data['goal_enter'] == 4 assert self.hsm.data['goal_exit'] == 4 # changed assert self.hsm.data['trans_left'] == 0 assert self.hsm.data['trans_right'] == 1 assert self.hsm.data['trans_loop'] == 3 assert self.hsm.data['trans_restart'] == 1 # changed def test_ignore_loop_and_restart_events_while_in_start_2(self): self.eb.dispatch(Loop()) self.eb.dispatch(Restart()) assert self.hsm.data['initial'] == 2 assert self.hsm.data['start_enter'] == 2 assert self.hsm.data['start_exit'] == 1 assert self.hsm.data['goal_enter'] == 4 assert self.hsm.data['goal_exit'] == 4 assert self.hsm.data['trans_left'] == 0 assert self.hsm.data['trans_right'] == 1 assert self.hsm.data['trans_loop'] == 3 assert self.hsm.data['trans_restart'] == 1 def test_transition_to_goal_via_left(self): self.eb.dispatch(MoveLeft()) assert_curr_state(self.hsm, 'goal') assert self.hsm.data['start_enter'] == 2 assert self.hsm.data['start_exit'] == 2 # changed assert self.hsm.data['goal_enter'] == 5 # changed assert self.hsm.data['goal_exit'] == 4 assert self.hsm.data['trans_left'] == 1 # changed assert self.hsm.data['trans_right'] == 1 assert self.hsm.data['trans_loop'] == 3 assert self.hsm.data['trans_restart'] == 1 def test_doesnt_respond_to_events_after_stopping(self): self.hsm.stop() self.eb.dispatch(MoveLeft()) self.eb.dispatch(MoveRight()) self.eb.dispatch(Loop()) self.eb.dispatch(Restart()) assert self.hsm.data['initial'] == 2 assert self.hsm.data['start_enter'] == 2 assert self.hsm.data['start_exit'] == 2 assert self.hsm.data['goal_enter'] == 5 assert self.hsm.data['goal_exit'] == 4 assert self.hsm.data['trans_left'] == 1 assert self.hsm.data['trans_right'] == 1 assert self.hsm.data['trans_loop'] == 3 assert self.hsm.data['trans_restart'] == 1