示例#1
0
def test_event_propagate_enter_exit():
    data = []

    m = StateMachine('m')
    s0 = StateMachine('s0')
    s1 = StateMachine('s1')
    s2 = StateMachine('s2')
    s3 = StateMachine('s3')
    s4 = State('s4')

    def do(state, event):
        event.cargo['source_event'].cargo['data'].append(state)
        assert state == m.leaf_state

    def do_with_propagate(state, event):
        event.cargo['source_event'].cargo['data'].append(state)
        event.propagate = True
        assert state == m.leaf_state

    m.add_state(s0, initial=True)
    s0.add_state(s1, initial=True)
    s1.add_state(s2, initial=True)
    s2.add_state(s3, initial=True)
    s3.add_state(s4, initial=True)

    m.add_transition(s0, s0, events='a')

    for state in s0, s1, s2, s3, s4:
        state.handlers = {'enter': do, 'exit': do}

    m.initialize()

    m.dispatch(_e('a', data=data))
    assert data == [s4, s3, s2, s1, s0, s0, s1, s2, s3, s4]

    data = []
    s1.handlers = {}
    s3.handlers = {}
    m.dispatch(_e('a', data=data))
    assert data == [s4, s2, s0, s0, s2, s4]

    # Never propagate exit/enter events, even if propagate is set to True
    data = []
    s4.handlers = {'enter': do_with_propagate, 'exit': do_with_propagate}
    m.dispatch(_e('a', data=data))
    assert data == [s4, s2, s0, s0, s2, s4]
示例#2
0
def test_event_propagate_enter_exit():
    data = []

    def do(state, event):
        event.cargo['source_event'].cargo['data'].append(state)

    def do_with_propagate(state, event):
        event.cargo['source_event'].cargo['data'].append(state)
        event.propagate = True

    m = StateMachine('m')
    s0 = StateMachine('s0')
    s1 = StateMachine('s1')
    s2 = StateMachine('s2')
    s3 = StateMachine('s3')
    s4 = State('s4')

    m.add_state(s0, initial=True)
    s0.add_state(s1, initial=True)
    s1.add_state(s2, initial=True)
    s2.add_state(s3, initial=True)
    s3.add_state(s4, initial=True)

    m.add_transition(s0, s0, events='a')

    for state in s0, s1, s2, s3, s4:
        state.handlers = {'enter': do, 'exit': do}

    m.initialize()

    m.dispatch(_e('a', data=data))
    assert data == [s4, s3, s2, s1, s0, s0, s1, s2, s3, s4]

    data = []
    s1.handlers = {}
    s3.handlers = {}
    m.dispatch(_e('a', data=data))
    assert data == [s4, s2, s0, s0, s2, s4]

    # Never propagate exit/enter events, even if propagate is set to True
    data = []
    s4.handlers = {'enter': do_with_propagate, 'exit': do_with_propagate}
    m.dispatch(_e('a', data=data))
    assert data == [s4, s2, s0, s0, s2, s4]
示例#3
0
def test_state_instance_passed_to_an_event_handler():
    def on_enter(state, event):
        source_event = event.cargo['source_event']
        source_event.cargo['test_list'].append(('enter', state))

    def on_exit(state, event):
        source_event = event.cargo['source_event']
        source_event.cargo['test_list'].append(('exit', state))

    def before(state, event):
        assert state == s1

    def action(state, event):
        assert state == s1

    def after(state, event):
        assert state == s2

    def on_internal(state, event):
        assert state == s1

    def do(state, event):
        assert state == m

    def condition(state, event):
        assert state == s1
        return True

    m = StateMachine('m')
    s0 = StateMachine('s0')
    s1 = State('s1')
    s2 = State('s2')
    m.add_state(s0, initial=True)
    s0.add_state(s1, initial=True)
    s0.add_state(s2)

    m.add_transition(s0, s0, events='a')
    s0.add_transition(s1,
                      None,
                      events=['internal'],
                      before=on_internal,
                      action=on_internal,
                      after=on_internal)
    s0.add_transition(s1,
                      s2,
                      events='b',
                      before=before,
                      action=action,
                      after=after,
                      condition=condition)
    s0.add_transition(s2, s1, events='b')

    for state in [m, s0, s1, s2]:
        state.handlers = {'enter': on_enter, 'exit': on_exit}

    m.handlers = {'do': do}

    m.initialize()

    test_list = []
    m.dispatch(_e('a', test_list=test_list))
    assert test_list == [('exit', s1), ('exit', s0), ('enter', s0),
                         ('enter', s1)]

    m.dispatch(_e('b', test_list=test_list))
    m.dispatch(_e('do'))
    m.dispatch(_e('b', test_list=test_list))

    m.dispatch(_e('internal'))
示例#4
0
def test_event_propagate():
    data = []

    def do(state, event):
        event.cargo['data'].append(state)

    def do_with_propagate(state, event):
        event.cargo['data'].append(state)
        event.propagate = True

    m = StateMachine('m')
    s0 = StateMachine('s0')
    s1 = StateMachine('s1')
    s2 = StateMachine('s2')
    s3 = StateMachine('s3')
    s4 = State('s4')

    m.add_state(s0, initial=True)
    s0.add_state(s1, initial=True)
    s1.add_state(s2, initial=True)
    s2.add_state(s3, initial=True)
    s3.add_state(s4, initial=True)

    for state in s0, s1, s2, s3, s4:
        state.handlers = {'do': do}

    m.initialize()

    # No propagate by default
    m.dispatch(_e('do', data=data))
    assert data == [s4]

    # Should propagate only to the next state that can handle the event
    data = []
    s4.handlers = {'do': do_with_propagate}
    m.dispatch(_e('do', data=data))
    assert data == [s4, s3]

    data = []
    s4.handlers = {'do': do_with_propagate}
    s3.handlers = {}
    m.dispatch(_e('do', data=data))
    assert data == [s4, s2]

    data = []
    s4.handlers = {'do': do_with_propagate}
    s3.handlers = {'do': do}
    m.dispatch(_e('do', data=data))
    assert data == [s4, s3]

    data = []
    s4.handlers = {}
    s3.handlers = {}
    m.dispatch(_e('do', data=data))
    assert data == [s2]

    data = []
    s4.handlers = {}
    s3.handlers = {}
    s2.handlers = {'do': do_with_propagate}
    m.dispatch(_e('do', data=data))
    assert data == [s2, s1]
示例#5
0
def test_state_instance_passed_to_an_event_handler():
    m = StateMachine('m')
    s0 = StateMachine('s0')
    s1 = State('s1')
    s2 = State('s2')
    m.add_state(s0, initial=True)
    s0.add_state(s1, initial=True)
    s0.add_state(s2)

    def on_enter(state, event):
        source_event = event.cargo['source_event']
        source_event.cargo['test_list'].append(('enter', state))
        assert state == m.leaf_state

    def on_exit(state, event):
        source_event = event.cargo['source_event']
        source_event.cargo['test_list'].append(('exit', state))
        assert state == m.leaf_state

    def before(state, event):
        assert state == s1
        assert state == m.leaf_state

    def action(state, event):
        assert state == s1
        assert state == m.leaf_state

    def after(state, event):
        assert state == s2
        assert state == m.leaf_state

    def on_internal(state, event):
        assert state == s1
        assert state == m.leaf_state

    def do(state, event):
        # It's an action on the top machine, the `leaf_state` is NOT `state`
        assert state != m.leaf_state
        assert state == m

    def condition(state, event):
        assert state == s1
        assert state == m.leaf_state
        return True

    m.add_transition(s0, s0, events='a')
    s0.add_transition(s1, None, events=['internal'],
                      before=on_internal, action=on_internal, after=on_internal)
    s0.add_transition(s1, s2, events='b',
                      before=before, action=action, after=after, condition=condition)
    s0.add_transition(s2, s1, events='b')

    for state in [m, s0, s1, s2]:
        state.handlers = {'enter': on_enter, 'exit': on_exit}

    m.handlers = {'do': do}

    m.initialize()

    test_list = []
    m.dispatch(_e('a', test_list=test_list))
    assert test_list == [('exit', s1), ('exit', s0), ('enter', s0), ('enter', s1)]

    m.dispatch(_e('b', test_list=test_list))
    m.dispatch(_e('do'))
    m.dispatch(_e('b', test_list=test_list))

    m.dispatch(_e('internal'))
示例#6
0
def test_event_propagate():
    data = []

    def do(state, event):
        event.cargo['data'].append(state)

    def do_with_propagate(state, event):
        event.cargo['data'].append(state)
        event.propagate = True

    m = StateMachine('m')
    s0 = StateMachine('s0')
    s1 = StateMachine('s1')
    s2 = StateMachine('s2')
    s3 = StateMachine('s3')
    s4 = State('s4')

    m.add_state(s0, initial=True)
    s0.add_state(s1, initial=True)
    s1.add_state(s2, initial=True)
    s2.add_state(s3, initial=True)
    s3.add_state(s4, initial=True)

    for state in s0, s1, s2, s3, s4:
        state.handlers = {'do': do}

    m.initialize()

    # No propagate by default
    m.dispatch(_e('do', data=data))
    assert data == [s4]

    # Should propagate only to the next state that can handle the event
    data = []
    s4.handlers = {'do': do_with_propagate}
    m.dispatch(_e('do', data=data))
    assert data == [s4, s3]

    data = []
    s4.handlers = {'do': do_with_propagate}
    s3.handlers = {}
    m.dispatch(_e('do', data=data))
    assert data == [s4, s2]

    data = []
    s4.handlers = {'do': do_with_propagate}
    s3.handlers = {'do': do}
    m.dispatch(_e('do', data=data))
    assert data == [s4, s3]

    data = []
    s4.handlers = {}
    s3.handlers = {}
    m.dispatch(_e('do', data=data))
    assert data == [s2]

    data = []
    s4.handlers = {}
    s3.handlers = {}
    s2.handlers = {'do': do_with_propagate}
    m.dispatch(_e('do', data=data))
    assert data == [s2, s1]