def test_examples(self): files = ['elevator', 'elevator_contract', 'microwave', 'tester_elevator_7th_floor_never_reached', 'tester_elevator_moves_after_10s', 'writer_options'] for filename in files: with self.subTest(filename=filename): with open(os.path.join('docs', 'examples', filename + '.yaml')) as f: io.import_from_yaml(f)
def test_yaml_tests(self): files = ['actions', 'composite', 'deep_history', 'infinite', 'internal', 'nested_parallel', 'nondeterministic', 'parallel', 'simple', 'timer'] for f in files: d = io.export_to_yaml(io.import_from_yaml(open(os.path.join('tests', 'yaml', f+'.yaml')))) # check io.import_from_yaml(d)
def test_examples(self): files = ['elevator', 'elevator_contract', 'microwave', 'tester_elevator_7th_floor_never_reached', 'tester_elevator_moves_after_10s', 'writer_options'] for f in files: d = io.export_to_yaml(io.import_from_yaml(open(os.path.join('docs', 'examples', f+'.yaml')))) # check io.import_from_yaml(d)
def test_yaml_tests(self): files = ['actions', 'composite', 'deep_history', 'infinite', 'internal', 'nested_parallel', 'nondeterministic', 'parallel', 'simple', 'timer'] for filename in files: with self.subTest(filename=filename): with open(os.path.join('tests', 'yaml', filename + '.yaml')) as f: io.import_from_yaml(f)
def __init__(self, master, statechart, contracts, properties): super().__init__(master) # Initialize widgets self.create_widgets() # Create a Stopwatch interpreter statechart = import_from_yaml(statechart) self.interpreter = Interpreter(statechart, ignore_contract=not contracts) # Bind interpreter events to the GUI self.interpreter.bind(self.event_handler) # Bind execution watchers self.watcher = ExecutionWatcher(self.interpreter) for prop in properties if properties else []: self.watcher.watch_with(import_from_yaml(prop), fails_fast=True) self.watcher.start() # Hide disabled widgets for widget_name in DISABLED_WIDGETS: widget = getattr(self, widget_name) widget.pack_forget() self.on_autotick() self.execute()
def test_elevator_moves_after_10s(self): stories = [ Story([Event('floorSelected', floor=4)]), Story([Event('floorSelected', floor=0)]), Story([Event('floorSelected', floor=4), Pause(10)]), Story([Event('floorSelected', floor=0), Pause(10)]), Story([Event('floorSelected', floor=4), Pause(9)]), Story([Event('floorSelected', floor=0), Pause(9)]), ] for story in stories: with self.subTest(story=story): # Reopen because we need to reset it with open('docs/examples/elevator.yaml') as f: sc = io.import_from_yaml(f) tested = Interpreter(sc) test_story = teststory_from_trace(story.tell(tested)) with open('docs/examples/tester_elevator_moves_after_10s.yaml' ) as f: tester = Interpreter(io.import_from_yaml(f)) test_story.tell(tester) self.assertFalse(tester.final)
def test_export_valid(self): for f, filename in self.files: with self.subTest(filename=filename): sc_1 = io.import_from_yaml(f) ex_1 = io.export_to_yaml(sc_1) sc_2 = io.import_from_yaml(ex_1) self.assertTrue(sc_2.validate())
def microwave(request): if request.param: sc = import_from_yaml( filepath='docs/examples/microwave/microwave_with_contracts.yaml') else: sc = import_from_yaml( filepath='docs/examples/microwave/microwave.yaml') return Interpreter(sc)
def setUp(self): with open('tests/yaml/simple.yaml') as f: self.sc1 = io.import_from_yaml(f) with open('tests/yaml/composite.yaml') as f: self.sc2 = io.import_from_yaml(f) for state in self.sc1.states: self.sc1.rename_state(state, 'sc1_' + state)
def elevator(request): if request.param: sc = import_from_yaml( filepath='docs/examples/elevator/elevator_contract.yaml') else: sc = import_from_yaml(filepath='docs/examples/elevator/elevator.yaml') return Interpreter(sc)
def test_7th_floor_never_reached_fails(self): tested = Interpreter(io.import_from_yaml(open('docs/examples/elevator.yaml'))) story = Story([Event('floorSelected', floor=4), Pause(2), Event('floorSelected', floor=7)]) trace = story.tell(tested).trace test_story = teststory_from_trace(trace) tester = Interpreter(io.import_from_yaml(open('docs/examples/tester_elevator_7th_floor_never_reached.yaml'))) self.assertFalse(test_story.tell(tester).final)
def setUp(self): with open('docs/examples/elevator.yaml') as f: elevator = io.import_from_yaml(f) with open('docs/examples/elevator_buttons.yaml') as f: buttons = io.import_from_yaml(f) self.elevator = Interpreter(elevator) self.buttons = Interpreter(buttons) self.buttons.bind(self.elevator)
def setUp(self): with open('docs/examples/elevator/elevator.yaml') as f: elevator = io.import_from_yaml(f) with open('docs/examples/elevator/elevator_buttons.yaml') as f: buttons = io.import_from_yaml(f) self.elevator = Interpreter(elevator) self.buttons = Interpreter(buttons) self.buttons.bind(self.elevator)
def test_examples(self): files = [ 'elevator', 'elevator_contract', 'microwave', 'tester_elevator_7th_floor_never_reached', 'tester_elevator_moves_after_10s', 'writer_options' ] for filename in files: with self.subTest(filename=filename): with open(os.path.join('docs', 'examples', filename + '.yaml')) as f: io.import_from_yaml(f)
def test_yaml_tests(self): files = [ 'actions', 'composite', 'deep_history', 'infinite', 'internal', 'nested_parallel', 'nondeterministic', 'parallel', 'simple', 'timer' ] for filename in files: with self.subTest(filename=filename): with open(os.path.join('tests', 'yaml', filename + '.yaml')) as f: io.import_from_yaml(f)
def test_remove_nested_states(self): with open('tests/yaml/composite.yaml') as f: self.sc = io.import_from_yaml(f) self.sc.remove_state('s1') self.assertFalse('s1a' in self.sc.states) self.sc.validate() with open('tests/yaml/composite.yaml') as f: self.sc = io.import_from_yaml(f) self.sc.remove_state('s1a') self.assertFalse('s1a' in self.sc.states) self.sc.validate()
def test_transitions_to_unknown_state(self): yaml = """ statechart: name: test root state: name: root initial: s1 states: - name: s1 transitions: - target: s2 """ with pytest.raises(StatechartError) as e: import_from_yaml(yaml) assert 'Unknown target state' in str(e.value)
def test_transitions_to_unknown_state(self): yaml = """ statechart: name: test root state: name: root initial: s1 states: - name: s1 transitions: - target: s2 """ with self.assertRaises(exceptions.StatechartError) as cm: io.import_from_yaml(yaml) self.assertIn('Unknown target state', str(cm.exception))
def test_EventFirstInterpreter(): interpreter = EventFirstInterpreter(import_from_yaml(statechart)) interpreter.execute() assert interpreter.configuration == ['root', 'A1', 'B1'] interpreter.queue('f', 'e').execute() assert interpreter.configuration == ['root', 'A1', 'F1'] interpreter = EventFirstInterpreter(import_from_yaml(statechart)) interpreter.execute() interpreter.queue('f').execute() assert interpreter.configuration == ['root', 'A1', 'G1'] interpreter.queue('e').execute() assert interpreter.configuration == ['root', 'A2', 'B2']
def test_order_constraints(self): """ test if the adding order of the constraints influences the coordinates of the statechart. """ with open("tests/elevator.yaml", 'r') as stream: statechart = io.import_from_yaml(stream) assert isinstance(statechart, sismic.model.Statechart) root_box = RootBox(statechart) root_box.add_constraint( Constraint(root_box.get_box_by_name('doorsClosed'), 'south', root_box.get_box_by_name('doorsOpen'))) root_box.add_constraint( Constraint(root_box.get_box_by_name('doorsClosed'), 'west', root_box.get_box_by_name('moving'))) root_box.transitions coordinates1 = root_box.coordinates set1 = root_box.constraints.copy() root_box.add_constraint( Constraint(root_box.get_box_by_name('doorsClosed'), 'north', root_box.get_box_by_name('doorsOpen'))) root_box.add_constraint( Constraint(root_box.get_box_by_name('doorsClosed'), 'east', root_box.get_box_by_name('moving'))) root_box.add_constraint( Constraint(root_box.get_box_by_name('doorsClosed'), 'west', root_box.get_box_by_name('moving'))) root_box.add_constraint( Constraint(root_box.get_box_by_name('doorsClosed'), 'south', root_box.get_box_by_name('doorsOpen'))) root_box.transitions coordinates2 = root_box.coordinates set2 = root_box.constraints.copy() self.assertEqual(set1, set2) for key in coordinates1.keys(): self.assertEqual(coordinates1[key], coordinates2[key], msg='the positions of ' + str(key) + ' are not equals')
def test_history_not_in_compound(self): yaml = """ statechart: name: test root state: name: root initial: s1 states: - name: s1 parallel states: - name: s2 type: shallow history """ with pytest.raises(StatechartError) as e: import_from_yaml(yaml) assert 'cannot be used as a parent for' in str(e.value)
def test_cli(self, capsys): filepath = 'docs/examples/elevator/elevator.yaml' statechart = import_from_yaml(filepath=filepath) # Check default parameters cli([filepath]) out, _ = capsys.readouterr() assert export_to_plantuml(statechart) == out.strip() # Check all parameters cli([ filepath, '--based-on', 'docs/examples/elevator/elevator.plantuml', '--show-description', '--show-preamble', '--show-state-contracts', '--show-transition-contracts', '--hide-state-action', '--hide-name', '--hide-transition-action' ]) out, _ = capsys.readouterr() export = export_to_plantuml( statechart, based_on_filepath='docs/examples/elevator/elevator.plantuml', statechart_description=True, statechart_preamble=True, state_contracts=True, transition_contracts=True, state_action=False, statechart_name=False, transition_action=False) assert export == out.strip()
def test_yaml_parser_types_handling(data): yaml = ('statechart:' '\n name: ' + str(data) + '\n preamble: Nothing' '\n root state:' '\n name: s1') item = import_from_yaml(yaml).name assert isinstance(item, str)
def setUp(self): with open('tests/yaml/nested_parallel.yaml') as f: sc = io.import_from_yaml(f) self.interpreter = Interpreter(sc) # Stabilization self.interpreter.execute_once() self.common_states = ['root', 's1', 'p1', 'p2', 'r1', 'r2', 'r3', 'r4']
def test_simple(self): with open('tests/yaml/simple.yaml') as f: sc = io.import_from_yaml(f) interpreter = Interpreter(sc) trace = Story([Pause(2), Event('goto s2'), Pause(3)]).tell(interpreter) story = teststory_from_trace(trace) expected = Story([ Event('execution started'), Pause(2), Event('step started'), Event('state entered', state='root'), Event('state entered', state='s1'), Event('step ended'), Event('step started'), Event('event consumed', event=Event('goto s2')), Event('state exited', state='s1'), Event('transition processed', source='s1', target='s2', event=Event('goto s2')), Event('state entered', state='s2'), Event('step ended'), Event('step started'), Event('state exited', state='s2'), Event('transition processed', source='s2', target='s3', event=None), Event('state entered', state='s3'), Event('step ended'), Event('execution stopped') ]) for a, b in zip(story, expected): self.assertEqual(a, b) if isinstance(a, Event): self.assertEqual(a.data.items(), b.data.items()) else: self.assertEqual(a.duration, b.duration)
def test_declare_both_states_and_parallel_states(self): yaml = """ statechart: name: test root state: name: root initial: s1 states: - name: s1 parallel states: - name: s2 """ with self.assertRaises(exceptions.StatechartError) as cm: io.import_from_yaml(yaml) self.assertIn('root cannot declare both a "states" and a "parallel states" property', str(cm.exception))
def test_history_not_in_compound(self): yaml = """ statechart: name: test root state: name: root initial: s1 states: - name: s1 parallel states: - name: s2 type: shallow history """ with self.assertRaises(exceptions.StatechartError) as cm: io.import_from_yaml(yaml) self.assertIn('cannot be used as a parent for', str(cm.exception))
def setUp(self): self.sc = import_from_yaml(""" statechart: name: test contract root state: name: root on entry: x = 1 initial: s0 states: - name: s0 initial: s1 transitions: - event: end target: root states: - name: s1 transitions: - target: s2 action: x = 2 event: e - name: s2 """) self.root = self.sc.state_for('root') # Will never be exited self.s0 = self.sc.state_for('s0') # Will be exited on "end" self.s1 = self.sc.state_for('s1') # Entered, and then exited on e. self.s2 = self.sc.state_for('s2') # Entered when e self.intp = Interpreter(self.sc)
def test_move_with_memory(self): with open('tests/yaml/history.yaml') as f: self.sc = io.import_from_yaml(f) self.sc.state_for('loop.H').memory = 's1' self.sc.move_state('s1', 's2') self.assertEqual(self.sc.state_for('loop.H').memory, None) self.sc.validate()
def test_rename_change_memory(self): with open('tests/yaml/history.yaml') as f: self.sc = io.import_from_yaml(f) self.sc.state_for('loop.H').memory = 's1' self.sc.rename_state('s1', 's4') self.assertEqual(self.sc.state_for('loop.H').memory, 's4') self.sc.validate()
def test_rename_change_state_name(self): with open('tests/yaml/composite.yaml') as f: self.sc = io.import_from_yaml(f) state = self.sc.state_for('s1') self.sc.rename_state('s1', 'new s1') self.assertEqual(state.name, 'new s1')
def test_rename_old_disappears(self): with open('tests/yaml/composite.yaml') as f: self.sc = io.import_from_yaml(f) self.sc.rename_state('s1', 'new s1') self.assertFalse('s1' in self.sc.states) self.assertNotEqual('s1', self.sc.parent_for('s1a')) self.assertFalse('s1' in self.sc.children_for('root')) with self.assertRaises(exceptions.StatechartError) as cm: self.sc.state_for('s1') self.assertIn('State', str(cm.exception)) self.assertIn('does not exist', str(cm.exception)) with self.assertRaises(exceptions.StatechartError) as cm: self.sc.children_for('s1') self.assertIn('State', str(cm.exception)) self.assertIn('does not exist', str(cm.exception)) with self.assertRaises(exceptions.StatechartError) as cm: self.sc.parent_for('s1') self.assertIn('State', str(cm.exception)) self.assertIn('does not exist', str(cm.exception)) self.sc.validate()
def test_statechart_postcondition(self): sc = io.import_from_yaml(open('tests/yaml/simple.yaml')) sc.postconditions.append('False') interpreter = Interpreter(sc) interpreter.send(Event('goto s2')).send(Event('goto final')) with self.assertRaises(PostconditionFailed) as cm: interpreter.execute() self.assertTrue(isinstance(cm.exception.obj, StateChart))
def test_declare_both_states_and_parallel_states(self): yaml = """ statechart: name: test root state: name: root initial: s1 states: - name: s1 parallel states: - name: s2 """ with pytest.raises(StatechartError) as e: import_from_yaml(yaml) assert 'root cannot declare both a "states" and a "parallel states" property' in str( e.value)
def test_run_in_background(self): sc = io.import_from_yaml(open('tests/yaml/simple.yaml')) intp = Interpreter(sc) task = run_in_background(intp, 0.001) intp.send(Event('goto s2')) intp.send(Event('goto final')) task.join() self.assertTrue(intp.final)
def setUp(self): files_t = ['actions', 'composite', 'deep_history', 'infinite', 'internal', 'nested_parallel', 'nondeterministic', 'parallel', 'simple', 'timer'] self.files = [] for filename in files_t: with open(os.path.join('tests', 'yaml', filename + '.yaml')) as f: self.files.append((filename, io.import_from_yaml(f)))
def test_floor_selection(self): sc = io.import_from_yaml(open('docs/examples/elevator.yaml')) interpreter = Interpreter(sc) interpreter.send(Event('floorSelected', floor=4)).execute_once() self.assertEqual(interpreter._evaluator.context['destination'], 4) interpreter.execute_once() self.assertEqual(sorted(interpreter.configuration), ['active', 'doorsClosed', 'floorListener', 'floorSelecting', 'movingElevator'])
def __init__(self): with open('statecharts/state_machine.yaml') as f: self.statechart = import_from_yaml(f) assert isinstance(self.statechart, Statechart) self.interpreter = Interpreter(self.statechart) self.interpreter.execute_once()
def test_EventFirstInterpreter_does_not_consume_event(): interpreter = EventFirstInterpreter(import_from_yaml(statechart)) interpreter.execute() assert interpreter.configuration == ['root', 'A1', 'B1'] interpreter.queue('f', 'f').execute() assert interpreter.configuration == ['root', 'A1', 'H1']
def load_statechart(context, path): with open(path) as f: context._statechart = import_from_yaml(f) context._interpreter = Interpreter(context._statechart) context._steps = [] context._events = [] context._automatic_execution = True context._interpreter.bind(context._events.append)
def check_type(self, name): yaml = ('statechart:' '\n name: ' + str(name) + '\n preamble: Nothing' '\n root state:' '\n name: s1') item = io.import_from_yaml(yaml).name self.assertIsInstance(item, str, msg=type(item))
def test_tell(self): story = Story([Event('goto s2'), Pause(5), Event('goto final')]) sc = io.import_from_yaml(open('tests/yaml/simple.yaml')) interpreter = Interpreter(sc) story.tell(interpreter) self.assertTrue(interpreter.final) self.assertEqual(interpreter.time, 5) self.assertEqual(len(interpreter.trace), 4)
def test_history_memory_not_child(self): with open('tests/yaml/history.yaml') as f: statechart = io.import_from_yaml(f) statechart.state_for('loop.H').memory = 'pause' with self.assertRaises(exceptions.StatechartError) as cm: statechart._validate_historystate_memory() self.assertIn('Initial memory', str(cm.exception)) self.assertIn('must be a parent\'s child', str(cm.exception))
def test_run_in_background(self): with open('tests/yaml/simple.yaml') as f: sc = io.import_from_yaml(f) interpreter = Interpreter(sc) task = run_in_background(interpreter, 0.001) interpreter.queue(Event('goto s2')) interpreter.queue(Event('goto final')) task.join() self.assertTrue(interpreter.final)
def test_nondeterminism(self): with open('tests/yaml/nondeterministic.yaml') as f: sc = io.import_from_yaml(f) interpreter = Interpreter(sc, evaluator_klass=DummyEvaluator) # Stabilization interpreter.execute_once() with self.assertRaises(exceptions.NonDeterminismError): interpreter.execute_once()
def test_history_memory_self(self): with open('tests/yaml/history.yaml') as f: statechart = io.import_from_yaml(f) statechart.state_for('loop.H').memory = 'loop.H' with self.assertRaises(exceptions.StatechartError) as cm: statechart._validate_historystate_memory() self.assertIn('Initial memory', str(cm.exception)) self.assertIn('cannot target itself', str(cm.exception))
def test_compound_initial_not_child(self): with open('tests/yaml/composite.yaml') as f: statechart = io.import_from_yaml(f) statechart.state_for('s1b').initial = 's1' with self.assertRaises(exceptions.StatechartError) as cm: statechart._validate_compoundstate_initial() self.assertIn('Initial state', str(cm.exception)) self.assertIn('must be a child state', str(cm.exception))