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

from hypothesis import given
from hypothesis.strategies import composite, integers

from src.parse import ParseErrorException, SyntaxStream
from tests.test_syntax import draw_syntax_random


# Inserts an element at a random place in a list
def insert_random(draw, list, data):
    pos = draw(integers(min_value=1, max_value=(len(list) - 1)))
    new_data = list[0:pos] + [data] + list[pos:]
    return new_data


# Tests that something parses correctly
# We expect the following behaviour:
# - Only the supplied tokens are parsed
# - The supplied tokens parse to the expected value
# - The Syntax's value is the expected value
# - The Syntax's type is expected type
# - The Syntax's location is the first token's location
def template_parse_valid(parser, draw):
    @given(draw_syntax_random(), draw)
    def do(canary, test_data):
        (tokens, expected) = test_data
        stream = SyntaxStream(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

    return lambda func: do


# Test that something parsers incorrectly
def template_parse_invalid(parser):
    def do(test_data):
        (tokens, error, context) = test_data
        stream = SyntaxStream(tokens)
        try:
            parsed = parser(stream, context)
            raise AssertionError("Parsed invalid data: %s" % (parsed))
        except ParseErrorException as e:
            assert e == error

    return lambda func: given(composite(func)())(do)