Newer
Older
NewLang / tests / parse / templates.py
# SPDX-License-Identifier: LGPL-2.1-only
# Copyright 2022 Jookia <contact@jookia.org>

from hypothesis.strategies import composite, integers

from src.parse import ParseErrorException
from src.token import TokenStream
from tests.test_token import static_token_by_value


# Draws tokens with an element randomly between the first and last token
# Returns the new list and new token
@composite
def draw_random_within(draw, source, new):
    list = draw(source)
    data = static_token_by_value(new)
    pos = draw(integers(min_value=1, max_value=(len(list) - 1)))
    new_data = list[0:pos] + [data] + list[pos:]
    return (new_data, data)


# Tests that something parses correctly
# We expect the following behaviour:
# - The parse function generates the expected output
# - The parse function doesn't consume extra tokens
def template_test_valid(parser, tokens, expected):
    canary = static_token_by_value("CANARY")
    stream = TokenStream(tokens + [canary])
    parsed = parser(stream, None)
    if expected is None:
        assert parsed is None
    else:
        assert parsed is not None
        assert parsed == expected
    assert stream.pop() == canary
    assert stream.pop() is None


# Test that something parses incorrectly
# We expect the following behaviour:
# - The parse function generates the expected error
# - The parse function uses the parse context as a parent
def template_test_invalid(parser, context, tokens, expected):
    stream = TokenStream(tokens.copy())
    error = None
    try:
        parsed = parser(stream, context)
        raise AssertionError("Parsed invalid data: %s" % (parsed))
    except ParseErrorException as e:
        error = e
    assert error == expected