示例#1
0
class TestFactory(TestCase):

    def setUp(self):
        self.factory = MachineFactory()

    def test_mixins(self):
        machine_cls = self.factory.get_predefined()
        self.assertFalse(hasattr(machine_cls, 'set_edge_state'))

        graph_cls = self.factory.get_predefined(graph=True)
        self.assertTrue(hasattr(graph_cls, 'set_edge_state'))
        nested_cls = self.factory.get_predefined(nested=True)
        self.assertFalse(hasattr(nested_cls, 'set_edge_state'))
        self.assertTrue(hasattr(nested_cls, 'traverse'))

        locked_cls = self.factory.get_predefined(locked=True)
        self.assertFalse(hasattr(locked_cls, 'set_edge_state'))
        self.assertFalse(hasattr(locked_cls, 'traverse'))
        self.assertTrue('__getattribute__' in locked_cls.__dict__)

        locked_nested_cls = self.factory.get_predefined(nested=True, locked=True)
        self.assertFalse(hasattr(locked_nested_cls, 'set_edge_state'))
        self.assertTrue(hasattr(locked_nested_cls, 'traverse'))
        self.assertEqual(locked_nested_cls.__getattribute__, locked_cls.__getattribute__)
        self.assertNotEqual(machine_cls.__getattribute__, locked_cls.__getattribute__)

        graph_locked_cls = self.factory.get_predefined(graph=True, locked=True)
        self.assertTrue(hasattr(graph_locked_cls, 'set_edge_state'))
        self.assertEqual(graph_locked_cls.__getattribute__, locked_cls.__getattribute__)

        graph_nested_cls = self.factory.get_predefined(graph=True, nested=True)
        self.assertNotEqual(nested_cls._create_transition, graph_nested_cls._create_transition)

        locked_nested_graph_cls = self.factory.get_predefined(nested=True, locked=True, graph=True)
        self.assertNotEqual(locked_nested_graph_cls._create_event, graph_cls._create_event)
示例#2
0
    def setUp(self):
        self.states = [
            'A', 'B', {
                'name': 'C',
                'children':
                ['1', '2', {
                    'name': '3',
                    'children': ['a', 'b', 'c']
                }]
            }
        ]

        self.transitions = [{
            'trigger': 'walk',
            'source': 'A',
            'dest': 'C_1'
        }, {
            'trigger': 'run',
            'source': 'C_1',
            'dest': 'C_3_a'
        }, {
            'trigger': 'sprint',
            'source': 'C',
            'dest': 'B'
        }]

        self.machine_cls = MachineFactory.get_predefined(nested=True,
                                                         graph=True)
        self.num_trans = len(self.transitions)
        self.num_auto = len(self.states) * 9
示例#3
0
    def test_ordered_with_graph(self):
        GraphMachine = MachineFactory.get_predefined(graph=True, nested=True)

        states = [
            'A', 'B', {
                'name': 'C',
                'children':
                ['1', '2', {
                    'name': '3',
                    'children': ['a', 'b', 'c']
                }]
            }, 'D', 'E', 'F'
        ]

        State.separator = '/'
        machine = GraphMachine('self',
                               states,
                               initial='A',
                               auto_transitions=False,
                               ignore_invalid_triggers=True)
        machine.add_ordered_transitions(trigger='next_state')
        machine.next_state()
        self.assertEqual(machine.state, 'B')
        target = tempfile.NamedTemporaryFile()
        machine.get_graph().draw(target.name, prog='dot')
        self.assertTrue(getsize(target.name) > 0)
        target.close()
示例#4
0
 def setUp(self):
     NestedState.separator = '_'
     states = ['A', 'B', {'name': 'C', 'children': ['1', '2', {'name': '3', 'children': ['a', 'b', 'c']}]},
       'D', 'E', 'F']
     self.stuff = Stuff(states, machine_cls=MachineFactory.get_predefined(locked=True, graph=True, nested=True))
     self.stuff.heavy_processing = heavy_processing
     self.stuff.machine.add_transition('forward', '*', 'B', before='heavy_processing')
示例#5
0
    def setUp(self):
        State.separator = state_separator
        states = ['A', 'B', {'name': 'C', 'children': ['1', '2', {'name': '3', 'children': ['a', 'b', 'c']}]},
                  'D', 'E', 'F']

        machine_cls = MachineFactory.get_predefined(graph=True, nested=True)
        self.stuff = Stuff(states, machine_cls)
示例#6
0
    def test_agraph_diagram(self):
        states = ['A', 'B', 'C', 'D']
        transitions = [
            {'trigger': 'walk', 'source': 'A', 'dest': 'B'},
            {'trigger': 'run', 'source': 'B', 'dest': 'C'},
            {'trigger': 'sprint', 'source': 'C', 'dest': 'D', 'conditions': 'is_fast'},
            {'trigger': 'sprint', 'source': 'C', 'dest': 'B'}
        ]

        machine_cls = MachineFactory.get_predefined(graph=True)
        m = machine_cls(states=states, transitions=transitions, initial='A', auto_transitions=False, title='a test')
        graph = m.get_graph()
        self.assertIsNotNone(graph)
        self.assertTrue("digraph" in str(graph))

        # Test that graph properties match the Machine
        self.assertEqual(
            set(m.states.keys()), set([n.name for n in graph.nodes()]))
        triggers = set([n.attr['label'] for n in graph.edges()])
        for t in triggers:
            t = edge_label_from_transition_label(t)
            self.assertIsNotNone(getattr(m, t))

        self.assertEqual(len(graph.edges()), len(transitions))
        # check for a valid pygraphviz diagram

        # write diagram to temp file
        target = tempfile.NamedTemporaryFile()
        graph.draw(target.name, prog='dot')
        self.assertTrue(os.path.getsize(target.name) > 0)

        # cleanup temp file
        target.close()
        print(graph)
 def setUp(self):
     class States(enum.Enum):
         RED = 1
         YELLOW = 2
         GREEN = 3
     self.machine_cls = MachineFactory.get_predefined()
     self.States = States
示例#8
0
class TestNestedStateEnums(TestEnumsAsStates):

    machine_cls = MachineFactory.get_predefined(nested=True)

    def test_root_enums(self):
        states = [
            self.States.RED, self.States.YELLOW, {
                'name': self.States.GREEN,
                'children': ['tick', 'tock'],
                'initial': 'tick'
            }
        ]
        m = self.machine_cls(states=states, initial=self.States.GREEN)
        self.assertTrue(m.is_GREEN(allow_substates=True))
        self.assertTrue(m.is_GREEN_tick())
        m.to_RED()
        self.assertTrue(m.state is self.States.RED)
        # self.assertEqual(m.state, self.States.GREEN)

    def test_nested_enums(self):
        # Nested enums are currently not support since model.state does not contain any information about parents
        # and nesting
        states = [
            'A', 'B', {
                'name': 'C',
                'children': self.States,
                'initial': self.States.GREEN
            }
        ]
        with self.assertRaises(AttributeError):
            # NestedState will raise an error when parent is not None and state name is an enum
            # Initializing this would actually work but `m.to_A()` would raise an error in get_state(m.state)
            # as Machine is not aware of the location of States.GREEN
            m = self.machine_cls(states=states, initial='C')
示例#9
0
    def test_nested_agraph_diagram(self):
        ''' Same as above, but with nested states. '''
        states = ['A', 'B', {'name': 'C', 'children': ['1', '2', '3']}, 'D']
        transitions = [
            {
                'trigger': 'walk',
                'source': 'A',
                'dest': 'B'
            },  # 1 edge
            {
                'trigger': 'run',
                'source': 'B',
                'dest': 'C'
            },  # + 1 edge
            {
                'trigger': 'sprint',
                'source': 'C',
                'dest': 'D',  # + 1 edges
                'conditions': 'is_fast'
            },
            {
                'trigger': 'sprint',
                'source': 'C',
                'dest': 'B'
            }  # + 1 edges = 4 edges
        ]

        hsm_graph_cls = MachineFactory.get_predefined(graph=True, nested=True)
        m = hsm_graph_cls(states=states,
                          transitions=transitions,
                          initial='A',
                          auto_transitions=False,
                          title='A test',
                          show_conditions=True)
        graph = m.get_graph()
        self.assertIsNotNone(graph)
        self.assertTrue("digraph" in str(graph))

        # Test that graph properties match the Machine
        # print((set(m.states.keys()), )
        node_names = set([n.name for n in graph.nodes()])
        self.assertEqual(set(m.states.keys()) - set('C'), node_names)

        triggers = set([n.attr['label'] for n in graph.edges()])
        for t in triggers:
            t = edge_label_from_transition_label(t)
            self.assertIsNotNone(getattr(m, t))

        self.assertEqual(len(graph.edges()), 4)  # see above

        m.walk()
        m.run()

        # write diagram to temp file
        target = tempfile.NamedTemporaryFile()
        graph.draw(target.name, prog='dot')
        self.assertTrue(os.path.getsize(target.name) > 0)

        # cleanup temp file
        target.close()
示例#10
0
    def test_ordered_with_graph(self):
        GraphMachine = MachineFactory.get_predefined(graph=True, nested=True)

        class CustomHierarchicalGraphMachine(GraphMachine):
            state_cls = self.state_cls

        states = [
            'A', 'B', {
                'name': 'C',
                'children':
                ['1', '2', {
                    'name': '3',
                    'children': ['a', 'b', 'c']
                }]
            }, 'D', 'E', 'F'
        ]

        machine = CustomHierarchicalGraphMachine('self',
                                                 states,
                                                 initial='A',
                                                 auto_transitions=False,
                                                 ignore_invalid_triggers=True,
                                                 use_pygraphviz=False)
        machine.add_ordered_transitions(trigger='next_state')
        machine.next_state()
        self.assertEqual(machine.state, 'B')
        target = tempfile.NamedTemporaryFile(suffix='.png', delete=False)
        machine.get_graph().draw(target.name, prog='dot')
        self.assertTrue(getsize(target.name) > 0)
        target.close()
        unlink(target.name)
示例#11
0
 def setUp(self):
     super(TestAsync, self).setUp()
     self.machine_cls = MachineFactory.get_predefined(nested=True,
                                                      asyncio=True)
     self.machine = self.machine_cls(states=['A', 'B', 'C'],
                                     transitions=[['go', 'A', 'B']],
                                     initial='A')
示例#12
0
    def test_add_custom_state(self):
        states = ['A', 'B', 'C', 'D']
        transitions = [{
            'trigger': 'walk',
            'source': 'A',
            'dest': 'B'
        }, {
            'trigger': 'run',
            'source': 'B',
            'dest': 'C'
        }, {
            'trigger': 'sprint',
            'source': 'C',
            'dest': 'D',
            'conditions': 'is_fast'
        }, {
            'trigger': 'sprint',
            'source': 'C',
            'dest': 'B'
        }]

        machine_cls = MachineFactory.get_predefined(graph=True)
        m = machine_cls(states=states,
                        transitions=transitions,
                        initial='A',
                        auto_transitions=False,
                        title='a test')
        m.add_state('X')
        m.add_transition('foo', '*', 'X')
        m.foo()
示例#13
0
    def test_context_managers(self):
        class CounterContext(object):
            def __init__(self):
                self.counter = 0
                self.level = 0
                self.max = 0
                super(CounterContext, self).__init__()

            def __enter__(self):
                self.counter += 1
                self.level += 1
                self.max = max(self.level, self.max)

            def __exit__(self, *exc):
                self.level -= 1

        M = MachineFactory.get_predefined(locked=True)
        c = CounterContext()
        m = M(states=['A', 'B', 'C', 'D'],
              transitions=[['reset', '*', 'A']],
              initial='A',
              machine_context=c)
        m.get_triggers('A')
        self.assertEqual(c.max, 1)  # was 3 before
        self.assertEqual(c.counter, 4)  # was 72 (!) before
示例#14
0
    def setUp(self):
        State.separator = state_separator
        states = ['A', 'B', {'name': 'C', 'children': ['1', '2', {'name': '3', 'children': ['a', 'b', 'c']}]},
                  'D', 'E', 'F']

        machine_cls = MachineFactory.get_predefined(graph=True, nested=True)
        self.stuff = Stuff(states, machine_cls)
示例#15
0
    def test_agraph_diagram(self):
        states = ['A', 'B', 'C', 'D']
        transitions = [
            {'trigger': 'walk', 'source': 'A', 'dest': 'B'},
            {'trigger': 'run', 'source': 'B', 'dest': 'C'},
            {'trigger': 'sprint', 'source': 'C', 'dest': 'D', 'conditions': 'is_fast'},
            {'trigger': 'sprint', 'source': 'C', 'dest': 'B'}
        ]

        machine_cls = MachineFactory.get_predefined(graph=True)
        m = machine_cls(states=states, transitions=transitions, initial='A', auto_transitions=False, title='a test')
        graph = m.get_graph()
        self.assertIsNotNone(graph)
        self.assertTrue("digraph" in str(graph))

        # Test that graph properties match the Machine
        self.assertEqual(
            set(m.states.keys()), set([n.name for n in graph.nodes()]))
        triggers = set([n.attr['label'] for n in graph.edges()])
        for t in triggers:
            self.assertIsNotNone(getattr(m, t))

        self.assertEqual(len(graph.edges()), len(transitions))
        # check for a valid pygraphviz diagram

        # write diagram to temp file
        target = tempfile.NamedTemporaryFile()
        graph.draw(target.name, prog='dot')
        self.assertTrue(os.path.getsize(target.name) > 0)

        # cleanup temp file
        target.close()
        print(graph)
示例#16
0
 def setUp(self):
     self.machine_cls = MachineFactory.get_predefined(locked=True)
     self.stuff = Stuff(machine_cls=self.machine_cls)
     self.stuff.heavy_processing = heavy_processing
     self.stuff.machine.add_transition('forward',
                                       'A',
                                       'B',
                                       before='heavy_processing')
示例#17
0
    def setUp(self):
        self.machine_cls = MachineFactory.get_predefined(graph=True)

        self.states = ['A', 'B', 'C', 'D']
        self.transitions = [
            {'trigger': 'walk', 'source': 'A', 'dest': 'B'},
            {'trigger': 'run', 'source': 'B', 'dest': 'C'},
            {'trigger': 'sprint', 'source': 'C', 'dest': 'D', 'conditions': 'is_fast'},
            {'trigger': 'sprint', 'source': 'C', 'dest': 'B'}
        ]
示例#18
0
    def setUp(self):

        machine_cls = MachineFactory.get_predefined(locked=True, nested=True, graph=True)

        @add_state_features(Error, Timeout, Volatile)
        class CustomMachine(machine_cls):
            pass

        super(TestStatesDiagramsLockedNested, self).setUp()
        self.machine_cls = CustomMachine
示例#19
0
 def get_wf_graph(self):
     """Get the graph for this machine."""
     diagram_cls = MachineFactory.get_predefined(graph=True, nested=True)
     self.machine = diagram_cls(
         model=self,
         auto_transitions=False,
         title=type(self).__name__,
         **self.status_class.get_kwargs()  # noqa: C815
     )
     return self.machine.get_graph()
示例#20
0
    def setUp(self):
        self.machine_cls = MachineFactory.get_predefined(graph=True)

        self.states = ['A', 'B', 'C', 'D']
        self.transitions = [
            {'trigger': 'walk', 'source': 'A', 'dest': 'B'},
            {'trigger': 'run', 'source': 'B', 'dest': 'C'},
            {'trigger': 'sprint', 'source': 'C', 'dest': 'D', 'conditions': 'is_fast'},
            {'trigger': 'sprint', 'source': 'C', 'dest': 'B'}
        ]
示例#21
0
    def test_store_nested_agraph_diagram(self):
        ''' Same as above, but with nested states. '''
        states = [
            'standing', 'walking', {
                'name': 'caffeinated',
                'children': ['dithering', 'running']
            }
        ]
        transitions = [
            ['walk', 'standing', 'walking'],  #   1 edge
            ['go', 'standing',
             'walking'],  # (edge will be merged with previous edge)
            ['stop', 'walking', 'standing'],  # + 1 edge
            ['drink', '*', 'caffeinated_dithering'],  # + 4 edges
            ['walk', 'caffeinated_dithering',
             'caffeinated_running'],  # + 1 edge
            ['relax', 'caffeinated', 'standing']  # + 1 edge = 8 edges
        ]

        hsm_graph_cls = MachineFactory.get_predefined(graph=True, nested=True)
        m = hsm_graph_cls(states=states,
                          transitions=transitions,
                          initial='standing',
                          auto_transitions=False)
        graph = m.get_graph()
        self.assertIsNotNone(graph)
        self.assertTrue("digraph" in str(graph))

        # Test that graph properties match the Machine
        # print((set(m.states.keys()), )
        node_names = set([n.name for n in graph.nodes()])
        node_names.add('caffeinated')
        self.assertEqual(set(m.states.keys()), node_names)

        triggers = set([n.attr['label'] for n in graph.edges()])
        for t in triggers:
            t = edge_label_from_transition_label(t)
            self.assertIsNotNone(getattr(m, t))

        self.assertEqual(len(graph.edges()), 8)  # see above

        # Force a new
        graph2 = m.get_graph(title="Second Graph", force_new=True)
        self.assertIsNotNone(graph)
        self.assertTrue("digraph" in str(graph))

        self.assertFalse(graph == graph2)

        # write diagram to temp file
        target = tempfile.NamedTemporaryFile()
        graph.draw(target.name, prog='dot')
        self.assertTrue(os.path.getsize(target.name) > 0)

        # cleanup temp file
        target.close()
示例#22
0
 def setUp(self):
     self.machine_cls = MachineFactory.get_predefined(graph=True, nested=True)
     self.states = ['A', 'B',
                    {'name': 'C', 'children': [{'name': '1', 'children': ['a', 'b', 'c']},
                                               '2', '3']}, 'D']
     self.transitions = [
         {'trigger': 'walk', 'source': 'A', 'dest': 'B'},     # 1 edge
         {'trigger': 'run', 'source': 'B', 'dest': 'C'},      # + 1 edge
         {'trigger': 'sprint', 'source': 'C', 'dest': 'D',    # + 1 edge
          'conditions': 'is_fast'},
         {'trigger': 'sprint', 'source': 'C', 'dest': 'B'},   # + 1 edge
         {'trigger': 'reset', 'source': '*', 'dest': 'A'}]    # + 8 edges = 12
示例#23
0
 def setUp(self):
     self.machine_cls = MachineFactory.get_predefined(graph=True, nested=True)
     self.states = ['A', 'B',
                    {'name': 'C', 'children': [{'name': '1', 'children': ['a', 'b', 'c']},
                                               '2', '3']}, 'D']
     self.transitions = [
         {'trigger': 'walk', 'source': 'A', 'dest': 'B'},     # 1 edge
         {'trigger': 'run', 'source': 'B', 'dest': 'C'},      # + 1 edge
         {'trigger': 'sprint', 'source': 'C', 'dest': 'D',    # + 1 edge
          'conditions': 'is_fast'},
         {'trigger': 'sprint', 'source': 'C', 'dest': 'B'},   # + 1 edge
         {'trigger': 'reset', 'source': '*', 'dest': 'A'}]    # + 8 edges = 12
示例#24
0
    def setUp(self):
        self.event_list = []

        self.c1 = self.TestContext(event_list=self.event_list)
        self.c2 = self.TestContext(event_list=self.event_list)

        self.stuff = Stuff(
            machine_cls=MachineFactory.get_predefined(locked=True),
            extra_kwargs={'context': [self.c1, self.c2]})
        del self.event_list[:]

        self.stuff.machine.add_transition('forward', 'A', 'B')
示例#25
0
 def test_multiple_models(self):
     class Model(object):
         pass
     s1, s2 = Model(), Model()
     m = MachineFactory.get_predefined(nested=True)(model=[s1, s2], states=['A', 'B', 'C'],
                                                    initial='A')
     self.assertEquals(len(m.models), 2)
     m.add_transition('advance', 'A', 'B')
     self.assertNotEqual(s1.advance, s2.advance)
     s1.advance()
     self.assertEquals(s1.state, 'B')
     self.assertEquals(s2.state, 'A')
示例#26
0
 def test_multiple_models(self):
     class Model(object):
         pass
     s1, s2 = Model(), Model()
     m = MachineFactory.get_predefined(nested=True)(model=[s1, s2], states=['A', 'B', 'C'],
                                                    initial='A')
     self.assertEquals(len(m.models), 2)
     m.add_transition('advance', 'A', 'B')
     self.assertNotEqual(s1.advance, s2.advance)
     s1.advance()
     self.assertEquals(s1.state, 'B')
     self.assertEquals(s2.state, 'A')
示例#27
0
 def setUp(self):
     self.states = [
         'A', 'B', {
             'name': 'C',
             'children':
             ['1', '2', {
                 'name': '3',
                 'children': ['a', 'b', 'c']
             }]
         }, 'D', 'E', 'F'
     ]
     self.machine_cls = MachineFactory.get_predefined(nested=True)
     self.state_cls = NestedState
     self.stuff = Stuff(self.states, self.machine_cls)
示例#28
0
 def test_reuse_machine_config(self):
     simple_config = {
         "name": "Child",
         "states": ["1", "2"],
         "transitions": [['go', '1', '2']],
         "initial": "1"
     }
     simple_cls = MachineFactory.get_predefined()
     simple = simple_cls(**simple_config)
     self.assertTrue(simple.is_1())
     self.assertTrue(simple.go())
     self.assertTrue(simple.is_2())
     machine = self.machine_cls(states=['A', simple_config], initial='A')
     machine.to_Child()
     machine.go()
     self.assertTrue(machine.is_Child_2())
示例#29
0
    def setUp(self):
        self.event_list = []

        self.s1 = DummyModel()

        self.c1 = TestContext(event_list=self.event_list)
        self.c2 = TestContext(event_list=self.event_list)
        self.c3 = TestContext(event_list=self.event_list)
        self.c4 = TestContext(event_list=self.event_list)

        self.stuff = Stuff(
            machine_cls=MachineFactory.get_predefined(locked=True),
            extra_kwargs={'machine_context': [self.c1, self.c2]})
        self.stuff.machine.add_model(self.s1, model_context=[self.c3, self.c4])
        del self.event_list[:]

        self.stuff.machine.add_transition('forward', 'A', 'B')
示例#30
0
    def test_ordered_with_graph(self):
        GraphMachine = MachineFactory.get_predefined(graph=True, nested=True)

        states = ['A', 'B', {'name': 'C', 'children': ['1', '2',
                                                       {'name': '3', 'children': ['a', 'b', 'c']}]}, 'D', 'E', 'F']

        State.separator = '/'
        machine = GraphMachine('self', states, initial='A',
                               auto_transitions=False,
                               ignore_invalid_triggers=True)
        machine.add_ordered_transitions(trigger='next_state')
        machine.next_state()
        self.assertEqual(machine.state, 'B')
        target = tempfile.NamedTemporaryFile()
        machine.get_graph().draw(target.name, prog='dot')
        self.assertTrue(getsize(target.name) > 0)
        target.close()
示例#31
0
    def setUp(self):
        self.event_list = []

        self.s1 = DummyModel()

        self.c1 = TestContext(event_list=self.event_list)
        self.c2 = TestContext(event_list=self.event_list)
        self.c3 = TestContext(event_list=self.event_list)
        self.c4 = TestContext(event_list=self.event_list)

        self.stuff = Stuff(machine_cls=MachineFactory.get_predefined(locked=True), extra_kwargs={
            'machine_context': [self.c1, self.c2]
        })
        self.stuff.machine.add_model(self.s1, model_context=[self.c3, self.c4])
        del self.event_list[:]

        self.stuff.machine.add_transition('forward', 'A', 'B')
示例#32
0
    def test_store_nested_agraph_diagram(self):
        ''' Same as above, but with nested states. '''
        states = ['A', 'B', {'name': 'C', 'children': ['1', '2', '3']}, 'D']
        transitions = [
            {'trigger': 'walk', 'source': 'A', 'dest': 'B'},   # 1 edge
            {'trigger': 'run', 'source': 'B', 'dest': 'C'},    # + 1 edge
            {'trigger': 'sprint', 'source': 'C', 'dest': 'D',  # + 1 edges
             'conditions': 'is_fast'},
            {'trigger': 'sprint', 'source': 'C', 'dest': 'B'}  # + 1 edges = 4 edges
        ]

        hsm_graph_cls = MachineFactory.get_predefined(graph=True, nested=True)
        m = hsm_graph_cls(states=states, transitions=transitions, initial='A', auto_transitions=False)
        graph = m.get_graph()
        self.assertIsNotNone(graph)
        self.assertTrue("digraph" in str(graph))

        # Test that graph properties match the Machine
        # print((set(m.states.keys()), )
        node_names = set([n.name for n in graph.nodes()])
        self.assertEqual(set(m.states.keys()) - set('C'), node_names)

        triggers = set([n.attr['label'] for n in graph.edges()])
        for t in triggers:
            t = edge_label_from_transition_label(t)
            self.assertIsNotNone(getattr(m, t))

        self.assertEqual(len(graph.edges()), 4)  # see above

        # Force a new
        graph2 = m.get_graph(title="Second Graph", force_new=True)
        self.assertIsNotNone(graph)
        self.assertTrue("digraph" in str(graph))

        self.assertFalse(graph == graph2)

        # write diagram to temp file
        target = tempfile.NamedTemporaryFile()
        graph.draw(target.name, prog='dot')
        self.assertTrue(os.path.getsize(target.name) > 0)

        # cleanup temp file
        target.close()
示例#33
0
    def setUp(self):
        states = [
            'A', 'B', {
                'name': 'C',
                'children':
                ['1', '2', {
                    'name': '3',
                    'children': ['a', 'b', 'c']
                }]
            }, 'D', 'E', 'F'
        ]

        machine_cls = MachineFactory.get_predefined(nested=True, async=True)

        class AsyncCompatibilityEventClass(AsyncNestedEvent):
            def trigger(self, model, *args, **kwargs):
                loop = asyncio.get_event_loop()
                return loop.run_until_complete(super().trigger(
                    model, *args, **kwargs))

        machine_cls.event_cls = AsyncCompatibilityEventClass
        self.stuff = Stuff(states, machine_cls)
示例#34
0
    def test_if_multiple_edges_are_supported(self):
        transitions = [
            ['event_0', 'a', 'b'],
            ['event_1', 'a', 'b'],
            ['event_2', 'a', 'b'],
            ['event_3', 'a', 'b'],
        ]

        machine_cls = MachineFactory.get_predefined(graph=True)
        m = machine_cls(
            states=['a', 'b'],
            transitions=transitions,
            initial='a',
            auto_transitions=False,
        )

        graph = m.get_graph()
        self.assertIsNotNone(graph)
        self.assertTrue("digraph" in str(graph))

        triggers = [transition[0] for transition in transitions]
        for trigger in triggers:
            self.assertTrue(trigger in str(graph))
示例#35
0
    def test_context_managers(self):

        class CounterContext(object):
            def __init__(self):
                self.counter = 0
                self.level = 0
                self.max = 0
                super(CounterContext, self).__init__()

            def __enter__(self):
                self.counter += 1
                self.level += 1
                self.max = max(self.level, self.max)

            def __exit__(self, *exc):
                self.level -= 1

        M = MachineFactory.get_predefined(locked=True)
        c = CounterContext()
        m = M(states=['A', 'B', 'C', 'D'], transitions=[['reset', '*', 'A']], initial='A', machine_context=c)
        m.get_triggers('A')
        self.assertEqual(c.max, 1)  # was 3 before
        self.assertEqual(c.counter, 4)  # was 72 (!) before
示例#36
0
 class CustomMachine(MachineFactory.get_predefined(nested=True)):
     state_cls = CustomState
示例#37
0
 def setUp(self):
     self.factory = MachineFactory()
示例#38
0
 def setUp(self):
     self.stuff = Stuff(machine_cls=MachineFactory.get_predefined(locked=True))
     self.stuff.heavy_processing = heavy_processing
     self.stuff.machine.add_transition('process', '*', 'B', before='heavy_processing')
示例#39
0
文件: fsm.py 项目: bibi21000/janitoo
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Janitoo is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Janitoo. If not, see <http://www.gnu.org/licenses/>.

"""
__author__ = 'Sébastien GALLET aka bibi21000'
__email__ = '*****@*****.**'
__copyright__ = "Copyright © 2013-2014-2015-2016 Sébastien GALLET aka bibi21000"

import logging
logger = logging.getLogger(__name__)

from transitions import State
from transitions.extensions import MachineFactory

def show_graph(self,fname='state.png', prog='dot', title=None):
    self.graph.draw(fname, prog=prog)

Machine = MachineFactory.get_predefined(graph=True)
Machine.show_graph = show_graph

HierarchicalMachine = MachineFactory.get_predefined(graph=True, nested=True)
HierarchicalMachine.show_graph = show_graph