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

from hypothesis import given
from hypothesis.strategies import (
    composite,
    integers,
    lists,
    sampled_from,
    text,
)

from src.parse import (
    NoteSkipper,
    ParseError,
    ParseErrorException,
    parse,
)
from src.syntax import SyntaxStream
from tests.test_syntax import draw_token_classified, draw_syntax_random


# Draws a random parse error
@composite
def draw_parse_error(draw):
    return draw(sampled_from(list(ParseError)))


# Draws a random parse error exception
@composite
def draw_parse_error_exception(draw):
    error = draw(draw_parse_error())
    syntax = draw(draw_syntax_random())
    expected = draw(text())
    return ParseErrorException(error, syntax, expected)


# Test parse error exception getters
@given(draw_parse_error(), draw_syntax_random(), text())
def test_parse_error_getters(error, syntax, expected):
    test = ParseErrorException(error, syntax, expected)
    assert test.error == error
    assert test.syntax == syntax
    assert test.expected == expected


# Test parse error exception equals
@given(draw_parse_error_exception(), draw_parse_error_exception())
def test_parse_error_equality(except1, except2):
    equals = (
        except1.error == except2.error
        and except1.syntax == except2.syntax
        and except1.expected == except2.expected
    )
    assert (except1 == except2) == equals


# Tests the parser wrapper works correctly
# We expect the following behaviour:
# - Notes to be removed from the tokens
@given(lists(draw_token_classified()))
def test_parse_fuzz(tokens):
    result = None
    try:
        stream = SyntaxStream(tokens.copy())
        result = NoteSkipper().clear_notes(stream)
    except ParseErrorException as e:
        result = e
    try:
        parsed = parse(tokens)
        assert parsed == result
    except ParseErrorException as e:
        assert e == result