示例#1
0
def test_storyerror_identify_unexpected_token(patch, storyerror):
    """
    Ensures that StoryError.identify can find the error code for unidentified
    token errors
    """
    patch.init(UnexpectedToken)
    patch.object(StoryError, 'unexpected_token_code')
    storyerror.error = UnexpectedToken('seq', 'lex', 0, 0)
    assert storyerror.identify() == storyerror.unexpected_token_code()
示例#2
0
def test_storyerror_unexpected_token_expected_block_after(patch, storyerror):
    patch.init(Intention)
    patch.object(storyerror, "get_line")
    patch.object(Intention, "assignment", return_value=False)
    patch.object(Intention, "unnecessary_colon", return_value=False)
    and_ = Token("and", "and")
    storyerror.error = UnexpectedToken(token=and_, expected=["_INDENT"])
    assert (
        storyerror.unexpected_token_code() == ErrorCodes.block_expected_after)
示例#3
0
def test_storyerror_unexpected_token_expected_block_after(patch, storyerror):
    patch.init(Intention)
    patch.object(storyerror, 'get_line')
    patch.object(Intention, 'assignment', return_value=False)
    patch.object(Intention, 'unnecessary_colon', return_value=False)
    and_ = Token('and', 'and')
    storyerror.error = UnexpectedToken(token=and_, expected=['_INDENT'])
    assert storyerror.unexpected_token_code() == \
        ErrorCodes.block_expected_after
示例#4
0
def test_parser_parser_unexpected_token(capsys, patch, magic, parser):
    patch.init(StoryError)
    patch.object(StoryError, 'message')
    patch.many(Parser, ['lark', 'transformer'])
    Parser.lark().parse.side_effect = UnexpectedToken(magic(), 'exp', 0, 1)
    with raises(SystemExit):
        parser.parse('source', debug=False)
    out, err = capsys.readouterr()
    assert out == '{}\n'.format(StoryError.message())
示例#5
0
def test_storyerror_hint_unexpected_token(
    patch,
    storyerror,
):
    expected = ['a', 'b', 'c']
    storyerror.error = UnexpectedToken(token='and', expected=expected)
    storyerror.error_tuple = ErrorCodes.unexpected_token
    storyerror._format = {'token': 'and', 'allowed': str(expected)}
    assert storyerror.hint() == ('`and` is not allowed here. '
                                 f'Allowed: {str(expected)}')
示例#6
0
def test_storyerror_hint_unexpected_token(
    patch,
    storyerror,
):
    expected = ["a", "b", "c"]
    storyerror.error = UnexpectedToken(token="and", expected=expected)
    storyerror.error_tuple = ErrorCodes.unexpected_token
    storyerror._format = {"token": "and", "allowed": str(expected)}
    assert storyerror.hint() == ("`and` is not allowed here. "
                                 f"Allowed: {str(expected)}")
示例#7
0
    def feed_token(self, token, is_end=False):
        state_stack = self.state_stack
        value_stack = self.value_stack
        states = self.parse_conf.states
        end_state = self.parse_conf.end_state
        callbacks = self.parse_conf.callbacks

        while True:
            state = state_stack[-1]
            try:
                action, arg = states[state][token.type]
            except KeyError:
                expected = {s for s in states[state].keys() if s.isupper()}
                raise UnexpectedToken(token,
                                      expected,
                                      state=self,
                                      interactive_parser=None)

            assert arg != end_state

            if action is Shift:
                # shift once and return
                assert not is_end
                state_stack.append(arg)
                value_stack.append(token if token.type not in
                                   callbacks else callbacks[token.type](token))
                return
            else:
                # reduce+shift as many times as necessary
                rule = arg
                size = len(rule.expansion)
                if size:
                    s = value_stack[-size:]
                    del state_stack[-size:]
                    del value_stack[-size:]
                else:
                    s = []

                value = callbacks[rule](s)

                _action, new_state = states[state_stack[-1]][rule.origin.name]
                assert _action is Shift
                state_stack.append(new_state)
                value_stack.append(value)

                if is_end and state_stack[-1] == end_state:
                    return value_stack[-1]
示例#8
0
def test_story_parse_debug(patch, story, parser):
    story.parse(parser=parser)
    parser.parse.assert_called_with(story.story)


def test_story_parse_lower(patch, story, parser):
    patch.object(Lowering, 'process')
    story.parse(parser=parser, lower=True)
    parser.parse.assert_called_with(story.story)
    Lowering.process.assert_called_with(Parser.parse())
    assert story.tree == Lowering.process(Lowering.process())


@mark.parametrize('error', [
    UnexpectedToken('token', 'expected'),
    UnexpectedInput('token', 'expected'),
    StorySyntaxError('test'),
])
def test_story_parse_error(patch, story, parser, error):
    """
    Ensures Story.parse uses Story.error for UnexpectedToken errors.
    """
    parser.parse.side_effect = error
    patch.object(Story, 'error')
    with raises(Exception):
        story.parse(parser=parser)
    Story.error.assert_called_with(error)


def test_story_modules(magic, story):
示例#9
0
def test_parser_parser_unexpected_token_debug(patch, magic, parser):
    patch.many(Parser, ['lark', 'transformer'])
    Parser.lark().parse.side_effect = UnexpectedToken(magic(), 'exp', 0, 1)
    with raises(UnexpectedToken):
        parser.parse('source', debug=True)
示例#10
0
def test_storyerror_identify_unexpected_token(patch, storyerror):
    patch.init(Intention)
    patch.object(Intention, 'assignment', return_value=True)
    patch.object(StoryError, 'get_line')
    storyerror.error = UnexpectedToken('token', 'expected')
    assert storyerror.identify() == ErrorCodes.assignment_incomplete