def test_condition_on_event(self, evaluator): assert evaluator._evaluate_code( 'event.data[\'a\'] == 1', additional_context={'event': Event('test', a=1)}) assert evaluator._evaluate_code( 'event.name == \'test\'', additional_context={'event': Event('test')})
def test_trace(self, microwave, property_statechart): microwave.queue('door_opened') microwave.execute() call_list = [ MetaEvent('step started', time=0), MetaEvent('state entered', state='controller'), MetaEvent('state entered', state='door closed'), MetaEvent('state entered', state='closed without item'), MetaEvent('step ended'), MetaEvent('step started', time=0), MetaEvent('event consumed', event=Event('door_opened')), MetaEvent('state exited', state='closed without item'), MetaEvent('state exited', state='door closed'), MetaEvent('transition processed', source='closed without item', target='opened without item', event=Event('door_opened')), MetaEvent('state entered', state='door opened'), MetaEvent('state entered', state='opened without item'), MetaEvent('event sent', event=InternalEvent('lamp_switch_on')), MetaEvent('step ended') ] for i, call in enumerate(call_list): effective_call = property_statechart.queue.call_args_list[i][0][0] assert isinstance(effective_call, MetaEvent) assert call.name == effective_call.name for param in ['state', 'source', 'target', 'event']: if param in call.data: assert effective_call.data[param] == call.data[param]
def test_conflicting_transitions_2(self, interpreter): interpreter.queue(Event('nextA'), Event('nextB'), Event('conflict2')) interpreter.execute_once() interpreter.execute_once() with pytest.raises(ConflictingTransitionsError): interpreter.execute_once()
def test_name_order(self, interpreter): interpreter.queue( Event('next'), Event('click'), Event('next'), Event('next') ) interpreter.execute_once() interpreter.execute_once() interpreter.execute_once() assert interpreter.configuration == self.common_states + ['k1', 'k3', 'x', 'y'] step = interpreter.execute_once() assert step.exited_states.index('k1') < step.exited_states.index('k3') assert step.exited_states.index('k3') < step.exited_states.index('x') assert step.exited_states.index('x') < step.exited_states.index('y') assert interpreter.configuration == self.common_states + ['k1', 'x', 'y', 'z'] assert step.entered_states.index('k1') < step.entered_states.index('z') assert step.entered_states.index('z') < step.entered_states.index('x') assert step.entered_states.index('x') < step.entered_states.index('y') assert [t.source for t in step.transitions] == ['k1', 'k3', 'x', 'y'] step = interpreter.queue(Event('next')).execute_once() assert step.exited_states.index('k1') < step.exited_states.index('x') assert step.exited_states.index('x') < step.exited_states.index('y') assert step.exited_states.index('y') < step.exited_states.index('z') assert interpreter.configuration == self.common_states + ['k1', 'x', 'y', 'z'] assert step.entered_states.index('k1') < step.entered_states.index('x') assert step.entered_states.index('x') < step.entered_states.index('y') assert step.entered_states.index('y') < step.entered_states.index('z') assert [t.source for t in step.transitions] == ['k1', 'x', 'y', 'z']
def trace(self, mocker): macrostep = mocker.MagicMock() macrostep.entered_states = ['a', 'b', 'c'] macrostep.exited_states = ['x', 'y', 'z'] macrostep.sent_events = [Event('e1'), Event('e2'), Event('e3')] return [macrostep]
def test_memory(self, interpreter): interpreter.queue(Event('next')).execute_once() assert interpreter.configuration == ['root', 'loop', 's2'] step = interpreter.queue(Event('pause')).execute_once() assert step.exited_states == ['s2', 'loop'] assert interpreter.configuration == ['root', 'pause']
def test_simple_entered(self, interpreter): interpreter.queue(Event('goto s2')) assert interpreter.execute_once().entered_states == ['s2'] interpreter.queue(Event('goto final')) assert interpreter.execute_once().entered_states == ['s3'] assert interpreter.execute_once().entered_states == ['final'] assert interpreter.configuration == [] assert interpreter.final
def test_partial_parallel_order(self, interpreter): interpreter.queue(Event('next'), Event('click')) interpreter.execute_once() step = interpreter.execute_once() assert interpreter.configuration == self.common_states + ['j1', 'j3', 'k2', 'k4'] assert step.exited_states == ['j2', 'j4'] assert step.entered_states == ['k2', 'k4'] assert [t.source for t in step.transitions] == ['j2', 'j4']
def test_resume_memory(self, interpreter): interpreter.queue( Event('next'), Event('pause'), Event('continue') ) last_step = interpreter.execute()[-1] assert last_step.entered_states == ['loop', 'loop.H', 's2'] assert last_step.exited_states == ['pause', 'loop.H'] assert interpreter.configuration == ['root', 'loop', 's2']
def test_bind(self, interpreter): i1, i2 = interpreter i1.bind(i2) assert i2.queue in i1._bound i1._raise_event(InternalEvent('test')) assert i1._select_event(consume=False) == Event('test') assert isinstance(i1._select_event(consume=False), InternalEvent) assert i2._select_event(consume=False) == Event('test') assert not isinstance(i2._select_event(consume=False), InternalEvent)
def test_bind(self, interpreter): i1, i2 = interpreter x = i1.bind(i2) assert x in i1._listeners i1._raise_event(InternalEvent('test')) assert i1._select_event(consume=False) == Event('test') assert isinstance(i1._select_event(consume=False), InternalEvent) assert i2._select_event(consume=False) == Event('test') assert not isinstance(i2._select_event(consume=False), InternalEvent)
def test_delay(self, interpreter): interpreter.queue('test1', delay=1) interpreter.queue('test2', delay=-1) interpreter.queue('test3', delay=0) interpreter._time += 10 event = interpreter._select_event(consume=True) assert event == Event('test2', delay=-1) event = interpreter._select_event(consume=True) assert event == Event('test3', delay=0) event = interpreter._select_event(consume=True) assert event == Event('test1', delay=1)
def test_delay(self, interpreter): interpreter.queue(DelayedEvent('test1', delay=1)) interpreter.queue(DelayedEvent('test2', delay=-1)) interpreter.queue(DelayedEvent('test3', delay=0)) interpreter._time += 10 event = interpreter._select_event(consume=True) assert isinstance(event, DelayedEvent) and event == Event('test2') event = interpreter._select_event(consume=True) assert isinstance(event, DelayedEvent) and event == Event('test3') event = interpreter._select_event(consume=True) assert isinstance(event, DelayedEvent) and event == Event('test1')
def test_heating_on(self, microwave): microwave.execute_once() microwave.queue( Event('door_opened'), Event('item_placed'), Event('door_closed'), Event('timer_inc') ).execute() microwave.queue(Event('cooking_start')) steps = microwave.execute() assert testing.event_is_fired(steps, 'heating_on') assert testing.event_is_fired(steps, 'lamp_switch_on') assert testing.event_is_fired(steps, 'turntable_start')
def test_deep_memory(self, interpreter): interpreter.queue( Event('next1'), Event('next2') ).execute() assert set(interpreter.configuration) == {'active', 'concurrent_processes', 'process_1', 'process_2', 'root', 's12', 's22'} interpreter.queue(Event('error1')).execute() assert interpreter.configuration == ['root', 'pause'] assert set(interpreter._memory['active.H*']) == {'concurrent_processes', 'process_1', 'process_2', 's12', 's22'} interpreter.queue(Event('continue')).execute() assert set(interpreter.configuration) == {'active', 'concurrent_processes', 'process_1', 'process_2', 'root', 's12', 's22'}
def test_internal_first(self, interpreter): interpreter.queue(DelayedEvent('test1', delay=0)) interpreter._raise_event(InternalEvent('test2')) interpreter.queue(DelayedEvent('test3', delay=1)) event = interpreter._select_event(consume=True) assert isinstance(event, InternalEvent) and event == Event('test2') event = interpreter._select_event(consume=True) assert isinstance(event, DelayedEvent) and event == Event('test1') assert interpreter._select_event(consume=True) is None interpreter._time = 1 event = interpreter._select_event(consume=True) assert isinstance(event, DelayedEvent) and event == Event('test3')
def test_button_0_on_groundfloor(self, elevator, remote_elevator): assert elevator.context['current'] == 0 remote_elevator.queue(Event('button_0_pushed')).execute() elevator.execute() assert elevator.context['current'] == 0
def test_button(self, elevator, remote_elevator): assert elevator.context['current'] == 0 steps = remote_elevator.queue(Event('button_2_pushed')).execute() assert testing.event_is_fired(steps, 'floorSelected', {'floor': 2}) elevator.execute() assert elevator.context['current'] == 2
def test_state_invariant(elevator): elevator.statechart.state_for('movingUp').invariants.append('False') elevator.queue(Event('floorSelected', floor=4)) with pytest.raises(InvariantError) as e: elevator.execute() assert isinstance(e.value.obj, StateMixin)
def test_internal_before_external(self, interpreter): assert interpreter.queue(Event('not_next')).execute_once().event.name == 'next' step = interpreter.execute_once() assert step.event is None assert step.entered_states == ['s2'] assert interpreter.execute_once().event.name == 'not_next'
def test_state_postcondition(elevator): elevator.statechart.state_for('movingUp').postconditions.append('False') elevator.queue(Event('floorSelected', floor=4)) with pytest.raises(PostconditionError) as e: elevator.execute() assert isinstance(e.value.obj, StateMixin)
def test_floor_selection(self, elevator): # Stabilisation elevator.execute_once() elevator.queue(Event('floorSelected', floor=4)).execute_once() assert elevator.context['destination'] == 4 elevator.execute_once() assert set(elevator.configuration) == {'active', 'active', 'doorsClosed', 'floorListener', 'floorSelecting', 'movingElevator'}
def test_simple_configuration(self, interpreter): assert interpreter.execute_once() is None # Should do nothing! interpreter.queue(Event('goto s2')).execute_once() assert interpreter.configuration == ['root', 's2'] interpreter.execute_once() assert interpreter.configuration == ['root', 's3']
def test_partial_unnested_transition(self, interpreter): interpreter.queue(Event('next'), Event('reset')) interpreter.execute_once() step = interpreter.execute_once() assert interpreter.configuration == self.common_states + ['i1', 'i2', 'i3', 'i4'] assert step.exited_states.index('r2') < step.exited_states.index('r4') assert step.exited_states.index('p1') < step.exited_states.index('p2') assert step.exited_states.index('r2') < step.exited_states.index('p1') assert step.exited_states.index('r4') < step.exited_states.index('p2') assert step.entered_states.index('p1') < step.entered_states.index('p2') assert step.entered_states.index('p1') < step.entered_states.index('r1') assert step.entered_states.index('p1') < step.entered_states.index('r2') assert step.entered_states.index('r1') < step.entered_states.index('p2') assert step.entered_states.index('r2') < step.entered_states.index('p2') assert step.entered_states.index('p2') < step.entered_states.index('r3') assert step.entered_states.index('p2') < step.entered_states.index('r4') assert [t.source for t in step.transitions] == ['r2', 'r4']
def test_transition_postcondition(elevator): transitions = elevator.statechart.transitions_from('floorSelecting') transitions[0].postconditions.append('False') elevator.queue(Event('floorSelected', floor=4)) with pytest.raises(PostconditionError) as e: elevator.execute() assert isinstance(e.value.obj, Transition)
def test_event(self, interpreter): i1, i2 = interpreter i1.bind(i2.queue) with pytest.raises(ValueError): i1._raise_event(Event('test')) assert i1._select_event(consume=False) is None assert i2._select_event(consume=False) is None
def test_floor_selected_and_reached(self, elevator): # Stabilisation elevator.execute_once() elevator.queue(Event('floorSelected', floor=4)).execute() assert elevator.context['current'] == 4 elevator.clock.time += 10 elevator.execute() assert 'doorsOpen' in elevator.configuration assert elevator.context['current'] == 0
def test_internal_first(self, interpreter): interpreter.queue('test1', delay=0) interpreter._raise_event(InternalEvent('test2')) interpreter.queue('test3', delay=2) event = interpreter._select_event() assert isinstance(event, InternalEvent) and event == Event('test2') interpreter._time = 2 event = interpreter._select_event(consume=True) assert isinstance(event, InternalEvent) and event == Event('test2') interpreter._raise_event(InternalEvent('test4')) # Queue is (0, test1) ; (2, test3) ; (2, test4) but test4 is internal event = interpreter._select_event(consume=True) assert isinstance(event, InternalEvent) and event == Event('test4') event = interpreter._select_event(consume=True) assert event == Event('test1', delay=0) event = interpreter._select_event(consume=True) assert event == Event('test3', delay=2)
def test_queue(self, interpreter): interpreter.queue(Event('e1')) assert interpreter._select_event(consume=True) == Event('e1') with pytest.raises(ValueError): interpreter.queue(InternalEvent('e2')) interpreter.queue('e3') assert interpreter._select_event(consume=True) == Event('e3') interpreter.queue('e4').queue('e5') assert interpreter._select_event(consume=True) == Event('e4') assert interpreter._select_event(consume=True) == Event('e5') interpreter.queue('e6', 'e7', Event('e8')) assert interpreter._select_event(consume=True) == Event('e6') assert interpreter._select_event(consume=True) == Event('e7') assert interpreter._select_event(consume=True) == Event('e8')
def test_consume_order(self, interpreter): interpreter.queue(DelayedEvent('test3', delay=2)) interpreter.queue(DelayedEvent('test1', delay=0)) interpreter.queue(DelayedEvent('test2', delay=1)) interpreter.queue(DelayedEvent('test4', delay=2)) interpreter.queue(DelayedEvent('test5', delay=3)) event = interpreter._select_event(consume=True) assert isinstance(event, DelayedEvent) and event == Event('test1') assert interpreter._select_event(consume=True) is None interpreter._time = 1 event = interpreter._select_event(consume=True) assert isinstance(event, DelayedEvent) and event == Event('test2') assert interpreter._select_event(consume=True) is None interpreter._time = 2 event = interpreter._select_event(consume=True) assert isinstance(event, DelayedEvent) and event == Event('test3') event = interpreter._select_event(consume=True) assert isinstance(event, DelayedEvent) and event == Event('test4') assert interpreter._select_event(consume=True) is None