コード例 #1
0
def test_comments():
    input = '''
// comment 0
/some_name
// comment 1
off
  @BUTTON_PRESS -> on // comment 2
  @TIMEOUT -> off
    // comment 3
  not_really_off
  // comment 4
    @SOME_EVENT -> ../off
    @THIRD_EVENT -> not_really_off/what // comment 5
    what
  really_off
    @OTHER_EVENT -> ../on/what
on
  @TIMEOUT
    ["i==3"] -> on/what
    [else] -> off/not_really_off/what
  what
    @OTHER -> ../off/really_off

 // comment 6
// comment 7
'''
    parse(input)
コード例 #2
0
def test_internal_transition_without_action():
    input = '''
/some_name
off
  #init
    "doSomething()"
  @TIMEOUT
    ["count == 3"] -> on
  @OTHER
    ["count == 6"] --
      "set(6)"
    ["count == 4"] -> off
    [else] --
      "set(7)"
  yes
    #init
      "start()"
      "stop()"
    #exit
      "stop()"
      "start()"
    @TO_OTHER -> other
    @OTHER --
      "restart()"
  other

on
  #exit
    "doSomethingElse()"
  @SOME --
  @TIMEOUT -> off
'''
    with pytest.raises(ParsingError):
        parse(input)
コード例 #3
0
def test_composite_state_names_not_unique():
    input = '''
/some_name
off
  @BUTTON_PRESS -> on
  @TIMEOUT -> off
  not_really_off
    @SOME_EVENT -> ../off
    @EVENT -> really_off
    @THIRD_EVENT -> not_really_off/what
    what
  really_off
    @OTHER_EVENT -> ../on/what
  not_really_off
    @OTHER -> ../on
on
  @TIMEOUT
    ["i==3"] -> off/really_off
    [else] -> off/not_really_off/what
  what
    @OTHER -> ../on
'''
    with pytest.raises(DefinitionError) as exc:
        parse(input)
    assert 'state name not unique in state "off"' in str(exc.value)
コード例 #4
0
def test_invalid_event_name():
    input = '''
/some_name
off
  @BUTTON_PRESS -> on
  @TIMEOUT -> off

on
  @_TIMEOUT -> off
'''
    with pytest.raises(ParsingError):
        parse(input)
コード例 #5
0
def test_wrong_indentation():
    input = '''
/some_name
off
  @BUTTON_PRESS -> on
    @TIMEOUT -> off

on
  @TIMEOUT -> off
'''
    with pytest.raises(ParsingError):
        parse(input)
コード例 #6
0
def test_only_else_guard():
    input = '''
/some_name
off
  @BUTTON_PRESS -> on
  @TIMEOUT
    [else] -> on

on
  @TIMEOUT -> off
'''
    with pytest.raises(ParsingError):
        parse(input)
コード例 #7
0
def test_invalid_target_name():
    input = '''
/some_name
off
  @BUTTON_PRESS -> on
  @TIMEOUT -> off

on
  @TIMEOUT -> offf
'''
    with pytest.raises(DefinitionError) as exc:
        parse(input)
    assert 'invalid transition target "offf" in state "on"' in str(exc.value)
コード例 #8
0
def test_unreachable_state():
    input = '''
/some_name
off
  @BUTTON_PRESS -> off
  @TIMEOUT -> off

on
  @TIMEOUT -> off
'''
    with pytest.raises(DefinitionError) as exc:
        parse(input)
    assert 'state "on" is unreachable' in str(exc.value)
コード例 #9
0
def test_event_handlers_not_unique():
    input = '''
/some_name
off
  @BUTTON_PRESS -> on
  @TIMEOUT -> off
  @BUTTON_PRESS -> off

on
  @TIMEOUT -> off
'''
    with pytest.raises(DefinitionError) as exc:
        parse(input)
    assert 'event handler not unique in state "off"' in str(exc.value)
コード例 #10
0
def test_else_guard_not_unique():
    input = '''
/some_name
off
  @BUTTON_PRESS -> on
  @TIMEOUT
    ["count == 3"] -> off
    [else] -> on
    [else] -> off

on
  @TIMEOUT -> off
'''
    with pytest.raises(ParsingError):
        parse(input)
コード例 #11
0
def test_states_to_ancestor():
    input = '''
/some_name
off
  @BUTTON_PRESS -> on
  @TIMEOUT -> off
  not_really_off
    @SOME_EVENT -> really_off
    what
  really_off
    @OTHER_EVENT -> not_really_off
    what
      @EVENT->final
    final
on
  @TIMEOUT -> off
'''
    sc = parse(input)
    assert sc.states[0].states[0].states_to_ancestor(sc) == [sc.states[0]]
    assert sc.states[0].states[0].states[0].states_to_ancestor(sc) == [
        sc.states[0].states[0], sc.states[0]
    ]
    assert sc.states[0].states[1].states[1].states_to_ancestor(sc) == [
        sc.states[0].states[1], sc.states[0]
    ]
    assert sc.states[0].states[1].states[0].states_to_ancestor(sc) == [
        sc.states[0].states[1], sc.states[0]
    ]
    assert sc.states[0].states[0].states_to_ancestor(sc.states[0]) == []
    assert sc.states[0].states[0].states_to_ancestor(
        sc.states[0].states[0]) == []
コード例 #12
0
def test_composite():
    input = '''
/some_name
off
  @BUTTON_PRESS -> on
  @TIMEOUT -> off
  not_really_off
    @SOME_EVENT -> really_off
  really_off
    @OTHER_EVENT -> not_really_off
on
  @TIMEOUT -> off
'''
    sc = parse(input)
    assert sc.is_root
    assert sc.states[0].states[0].name == 'not_really_off'
    assert sc.states[0].states[1].name == 'really_off'
    assert not sc.states[0].is_root
    assert not sc.states[0].states[1].is_root
    assert sc.states[0].is_initial
    assert not sc.states[1].is_initial
    assert sc.states[1].is_atomic
    assert not sc.states[0].is_atomic
    assert sc.states[0].states[0].is_initial
    assert sc.states[0].states[0].is_atomic
コード例 #13
0
def test_guard_not_unique():
    input = '''
/some_name
off
  @BUTTON_PRESS -> on
  @TIMEOUT
    ["count == 3"] -> off
    ["count == 3"] -> on
    [else] -> off

on
  @TIMEOUT -> off
'''
    with pytest.raises(DefinitionError) as exc:
        parse(input)
    assert 'guard not unique for event "TIMEOUT"' in str(exc.value)
コード例 #14
0
def test_state_names_not_unique():
    input = '''
/some_name
off
  @BUTTON_PRESS -> on
  @TIMEOUT -> off

on
  @TIMEOUT -> off

off
  @TIMEOUT -> on
'''
    with pytest.raises(DefinitionError) as exc:
        parse(input)
    assert 'state name not unique in state "some_name"' in str(exc.value)
コード例 #15
0
def test_transient_state_with_guard_not_unique():
    input = '''
/some_name
<>off
  ["count == 3"] -> on
  ["count == 4"] -> on
  ["count == 4"] -> on
  [else] -> on

on
  @TIMEOUT -> off
'''
    with pytest.raises(DefinitionError) as exc:
        parse(input)

    assert 'guard not unique for event "None"' in str(exc.value)
コード例 #16
0
def test_composite_reachable_state():
    input = '''
/some_name
off
  @BUTTON_PRESS -> on
  @TIMEOUT -> off
  not_really_off
    @SOME_EVENT -> ../off
    @THIRD_EVENT -> not_really_off/what
    what
  really_off
    @OTHER_EVENT -> ../on/what
on
  @TIMEOUT
    ["i==3"] -> on/what
    [else] -> off/not_really_off/what
  what
    @OTHER -> ../off/really_off
'''
    parse(input)
コード例 #17
0
def test_composite_unreachable_state():
    input = '''
/some_name
off
  @BUTTON_PRESS -> on
  @TIMEOUT -> off
  not_really_off
    @SOME_EVENT -> ../off
    @THIRD_EVENT -> not_really_off/what
    what
  really_off
    @OTHER_EVENT -> ../on/what
on
  @TIMEOUT
    ["i==3"] -> on/what
    [else] -> off/not_really_off/what
  what
    @OTHER -> ../off
'''
    with pytest.raises(DefinitionError) as exc:
        parse(input)
    assert 'state "really_off" is unreachable' in str(exc.value)
コード例 #18
0
def test_guard():
    input = '''
/some_name
off
  @BUTTON_PRESS -> on
  @TIMEOUT
    ["count == 3"] -> off

on
  @TIMEOUT -> off
'''
    sc = parse(input)
    assert sc.states[0].event_handlers[1].transitions[0].guard == 'count == 3'
コード例 #19
0
def test_transient_state():
    input = '''
/some_name
<>off
  ["true"] -> on
  [else] -> off

on
  @TIMEOUT -> off
'''
    sc = parse(input)
    assert sc.initial.is_transient
    assert not sc.is_transient
    assert not sc.states[1].is_transient
コード例 #20
0
def test_simplest():
    input = '''
/simplest
off
  @BUTTON_PRESS -> on
  @TIMEOUT -> off

on
  @TIMEOUT -> off
'''

    sc = parse(input)
    assert sc.name == 'simplest'
    assert len(sc.states) == 2
    assert sc.states[0].name == 'off'
    assert sc.states[1].event_handlers[0].event == 'TIMEOUT'
コード例 #21
0
def test_multiple_guards():
    input = '''
/some_name
off
  @BUTTON_PRESS -> on
  @TIMEOUT
    ["count == 3"] -> off
    ["count == 4"] -> on
    [else] -> on

on
  @TIMEOUT -> off
'''
    sc = parse(input)
    assert sc.states[0].event_handlers[1].transitions[0].guard == 'count == 3'
    assert sc.states[0].event_handlers[1].transitions[1].guard == 'count == 4'
    assert not sc.states[0].event_handlers[1].transitions[1].is_else_guard
    assert sc.states[0].event_handlers[1].transitions[2].is_else_guard
コード例 #22
0
def test_path():
    input = '''
/some_name
off
  @BUTTON_PRESS -> on
  @TIMEOUT -> off
  not_really_off
    @SOME_EVENT -> really_off
    what
  really_off
    @OTHER_EVENT -> not_really_off
on
  @TIMEOUT -> off
'''
    sc = parse(input)
    assert sc.states[0].path == 'some_name/off'
    assert sc.states[0].states[1].path == 'some_name/off/really_off'
    assert sc.states[0].states[0].states[
        0].path == 'some_name/off/not_really_off/what'
コード例 #23
0
def test_all_states():
    input = '''
/some_name
off
  @BUTTON_PRESS -> on
  @TIMEOUT -> off
  not_really_off
    @SOME_EVENT -> really_off
    what
  really_off
    @OTHER_EVENT -> not_really_off
on
  @TIMEOUT -> off
'''
    sc = parse(input)
    assert sc.all_states == [
        sc, sc.states[0], sc.states[0].states[0],
        sc.states[0].states[0].states[0], sc.states[0].states[1], sc.states[1]
    ]
コード例 #24
0
def test_internal_external_transition():
    input = '''
/some_name
off
  #init
    "doSomething()"
  @TIMEOUT
    ["count == 3"] -> on
  @OTHER
    ["count == 6"] --
      "set(6)"
    ["count == 4"] -> off
    [else] --
      "set(7)"
  yes
    #init
      "start()"
      "stop()"
    #exit
      "stop()"
      "start()"
    @TO_OTHER -> other
    @WHAT --
      "restart()"
  other

on
  #exit
    "doSomethingElse()"
  @SOME --
    "wait()"
  @TIMEOUT -> off
'''
    sc = parse(input)
    assert sc.states[0].transitions[1].is_internal
    assert sc.states[0].transitions[1].actions == ['set(6)']
    assert not sc.states[0].transitions[2].is_internal
    assert sc.states[0].transitions[3].is_internal
    assert sc.states[0].states[0].transitions[1].is_internal
    assert sc.states[0].states[0].transitions[1].actions == ['restart()']
    assert sc.states[1].transitions[0].is_internal
コード例 #25
0
def test_actions():
    input = '''
/some_name
#init
  "bonjour()"
#exit
  "auRevoir()"
off
  #init
    "doSomething()"
  @TIMEOUT
    ["count == 3"] -> on
  <>half_off
    ["count == 6"] -> other
      "set(6)"
    [else] -> yes
      "set(7)"
  yes
    #init
      "start()"
      "stop()"
    #exit
      "stop()"
      "start()"
  other

on
  #exit
    "doSomethingElse()"
  @TIMEOUT -> off
'''
    sc = parse(input)
    assert sc.init_actions == ['bonjour()']
    assert sc.exit_actions == ['auRevoir()']
    assert sc.states[0].init_actions == ['doSomething()']
    assert sc.states[0].states[0].transitions[0].actions == ['set(6)']
    assert sc.states[0].states[0].transitions[1].actions == ['set(7)']
    assert sc.states[1].exit_actions == ['doSomethingElse()']
    assert sc.states[0].states[1].init_actions == ['start()', 'stop()']
    assert sc.states[0].states[1].exit_actions == ['stop()', 'start()']
コード例 #26
0
def test_common_ancestor():
    input = '''
/some_name
off
  @BUTTON_PRESS -> on
  @TIMEOUT -> off
  not_really_off
    @SOME_EVENT -> really_off
    what
  really_off
    @OTHER_EVENT -> not_really_off
on
  @TIMEOUT -> off
'''
    sc = parse(input)
    assert sc.common_ancestor(sc) is sc
    assert sc.states[0].states[0].common_ancestor(
        sc.states[0].states[0]) is sc.states[0].states[0]
    assert sc.states[0].states[0].common_ancestor(
        sc.states[0].states[1]) is sc.states[0]
    assert sc.states[0].states[1].common_ancestor(
        sc.states[0].states[0].states[0]) is sc.states[0]
コード例 #27
0
def test_state_paths():
    input = '''
/some_name
off
  @BUTTON_PRESS -> on
  @TIMEOUT -> off
  not_really_off
    @SOME_EVENT -> really_off
    what
  really_off
    @OTHER_EVENT -> not_really_off
on
  @TIMEOUT -> off
'''
    sc = parse(input)
    assert list(sc.state_paths.values()) == list(sc.all_states)
    assert list(sc.state_paths.keys()) == [
        'some_name', 'some_name/off', 'some_name/off/not_really_off',
        'some_name/off/not_really_off/what', 'some_name/off/really_off',
        'some_name/on'
    ]
    assert sc.state_paths is sc.states[0].state_paths
コード例 #28
0
def test_path_elements():
    input = '''
/some_name
off
  @BUTTON_PRESS -> on
  @TIMEOUT -> off
  not_really_off
    @SOME_EVENT -> really_off
    what
  really_off
    @OTHER_EVENT -> not_really_off
on
  @TIMEOUT -> off
'''
    sc = parse(input)
    assert sc.states[0].path_elements == ['some_name', 'off']
    assert sc.states[0].states[1].path_elements == [
        'some_name', 'off', 'really_off'
    ]
    assert sc.states[0].states[0].states[0].path_elements == [
        'some_name', 'off', 'not_really_off', 'what'
    ]
コード例 #29
0
def test_composite_valid_target_path():
    input = '''
/some_name
off
  @BUTTON_PRESS -> on
  @TIMEOUT -> off
  not_really_off
    @SOME_EVENT -> ../off
    @EVENT -> really_off
    @THIRD_EVENT -> not_really_off/what
    what
  really_off
    @OTHER_EVENT -> ../on/what
on
  @TIMEOUT
    ["i==3"] -> off/really_off
    [else] -> off/not_really_off/what
  what
    @OTHER -> ../on
'''
    sc = parse(input)
    assert sc.states[0].states[0].transitions[
        2].target.path == 'some_name/off/not_really_off/what'
コード例 #30
0
def test_event_names(input, events):
    sc = parse(input)
    assert sc.event_names == set(events)