def test_with_different_subclasses(self): class SubState(State): pass s1 = State() s2 = SubState() assert not s1 == s2 s1 = SubState() s2 = SubState() assert s1 == s2 s1.states = { 'a': State({ 's': State(), 's2': State() }), 'b': State() } s2.states = { 'a': State({ 's': SubState(), 's2': State() }), 'b': State() } assert not s1 == s2 s1.states = { 'a': State({ 's': SubState(), 's2': State() }), 'b': State() } assert s1 == s2
def test_names(self): s1 = State() s1.name = 'asd' s2 = State() assert not s1 == s2 s2.name = 'asd' assert s1 == s2
def test_children_empty(self): s1 = State() s2 = State() s1.states = [] assert not s1 == s2 # s2 has {} s2.states = [] assert s1 == s2
def test_run(self, state_name, Event, foo_before, foo_expected, exp_responding_state, exp_transition_target): mock_hsm = MockHSM() mock_hsm.data.foo = foo_before state = get_state_by_sig((state_name,), self.hsm.flattened) tree = tree_from_state_set(set([state])) resps = get_responses(tree, Event(), self.hsm.trans, mock_hsm) if exp_responding_state is None: assert resps == [] else: assert len(resps) == 1 # no orthogonal regions in this HSM resp_subtrees, trans = zip(*resps) assert resp_subtrees[0][0].name == exp_responding_state tran = trans[0] if exp_transition_target is not None: assert State.sig_to_name(tran.target) == exp_transition_target else: assert tran.target is None tran.action(None, mock_hsm) # this call might change 'foo' value # event is not relevant if foo_expected != 'ignored': assert mock_hsm.data.foo == foo_expected
def test_children_list_nested(self): s1 = State() s2 = State() s1.states = [ State([State(), State()]), State([State(), State()]), ] s2.states = [ State([State()]), State([State(), State()]), ] assert not s1 == s2 s2.states = [ State([State(), State()]), State([State(), State()]), ] assert s1 == s2
def test_children_dict_nested(self): s1 = State() s2 = State() s1.states = { 'a': State({ 's': State(), 's2': State() }), 'b': State() } assert not s1 == s2 s2.states = { 'a': State({ 's': State(), 's2': State() }), 'b': State() } assert s1 == s2
def test_children_dict(self): s1 = State() s2 = State() s1.states = {1: 'a', 2: {}} s2.states = {1: 'a', 2: {}} assert s1 == s2 s1.states = {1: 'a', 2: {3: {}}} assert not s1 == s2 s1.states = [State(), State()] s2.states = [State(), State()] assert s1 == s2 s1.states = { 'a': State(), 'b': State() } s2.states = { 'a': State(), 'b': State() } assert s1 == s2
def test_find_invalid_choice_transitions(self): func = find_invalid_choice_transitions res = sorted((State.sig_to_name(sig), evt) for sig, evt in func(self.hsm.flattened, self.hsm.trans)) assert sorted(res) == sorted([ ('choice_placeholder_1', A), ('choice_placeholder_1', B), ('choice_placeholder_1', C), ('right_A', A), ('right_A', C), ('choice_test_1', Initial), #('right_A', Initial), # these two are valid Choices, but not #('right_B', Initial), # valid initial transitions ])
def test_children_list_different_order(self): s1 = State() s2 = State() s1.states = [leaf('1'), leaf('2'), leaf('3')] s2.states = [leaf('1'), leaf('2'), leaf('3')] assert s1 == s2 s2.states = [leaf('3'), leaf('1'), leaf('2')] assert s1 == s2 s2.states = [leaf('3'), leaf('999'), leaf('2')] assert not s1 == s2
def test_choice(self, states, event, exp_resp_states, exp_tran_targets): state_set = set([get_state_by_sig((name,), self.hsm.flattened) for name in states]) tree = tree_from_state_set(state_set) resps = get_responses(tree, event, self.hsm.trans, None) print resps if exp_resp_states or exp_tran_targets: resp_subtrees, trans = zip(*resps) assert len(resp_subtrees) == len(exp_resp_states) resp_names = set([st.name for st, _ in resp_subtrees]) assert resp_names == set(exp_resp_states) assert len(trans) == len(exp_tran_targets) target_ids = set([State.sig_to_name(tr.target) for tr in trans]) assert target_ids == set(exp_tran_targets) else: assert resps == []
def test_children_list_different_order_nested(self): s1 = State() s2 = State() s1.states = [ composite('A', [leaf('1'), leaf('2')]), composite('B', [leaf('3'), leaf('4')]), ] s2.states = [ composite('A', [leaf('2'), leaf('1')]), composite('B', [leaf('4'), leaf('3')]), ] assert s1 == s2 s2.states = [ composite('B', [leaf('4'), leaf('3')]), composite('A', [leaf('2'), leaf('1')]), ] assert s1 == s2 s2.states = [ composite('B', [leaf('4'), leaf('3')]), composite('A', [leaf('999'), leaf('1')]), ] assert not s1 == s2
def test_sig_to_name(self, sig, name): assert State.sig_to_name(sig) == name
def test_all_attribs(self): par1 = State() par1.name = 'parent' par2 = State() par2.name = 'parent' assert par1 == par2 # lambdas must be same instance action = lambda a, b: a + b s1 = State() s1.name = 'name' s1.parent = par1 s1.kind = 'leaf' s1.on_enter = action s1.on_exit = action s2 = State() assert not s1 == s2 s2.name = 'name' assert not s1 == s2 s2.parent = par1 assert not s1 == s2 s2.kind = 'leaf' assert not s1 == s2 s2.on_enter = action assert not s1 == s2 s2.on_exit = action assert s1 == s2 # now it's same
def clear_marquee_rect(evt, hsm): _, _, rect_id = hsm.data.canvas_marquee canvas.delete(rect_id) # define HSM state structure and transitions between states: states = { 'app': State({ 'select_tool_chosen': State({ 'select_tool_hovering': State(), 'dragging_marquee': State(on_enter=create_marquee_rect, on_exit=clear_marquee_rect), 'moving_elements': State(on_enter=select_under_cursor), }), 'draw_tool_chosen': State({ 'draw_tool_hovering': State(), 'drawing': State(), }) }) } transitions = { 'app': { Initial: T('draw_tool_chosen'), Tool_Changed: Choice({ Selection_tool: 'select_tool_chosen', Drawing_tool: 'draw_tool_chosen' }, default='select_tool_chosen', action=update_chosen_tool)
def test_name_to_sig(self, sig, name): assert State.name_to_sig(name) == sig
def test_name_to_sig_malformed(self, name): with pytest.raises(ValueError): res = State.name_to_sig(name) print res
def get_state(kind, name, states): st = State(states) st.name = name st.kind = kind return st