# SPDX-License-Identifier: LGPL-2.1-only # Copyright 2022 Jookia <contact@jookia.org> # Parse error reporting consists of the following data structures: # # ParseTasks represent a task such as parsing a file or directive. # # ParseContexts represent a step during the parsing process for the purposes of # error reporting. # A context contains: # - A ParseTask specifying the step # - The Token the task started at (possibly None) # - A parent ParseContext (possibly None) if this task is a component # of another task # # ParseErrors represent an error encountered during a parsing task, such as an # unexpected token or invalid token. # # ParseErrorExceptions represent an error encounted during parsing. # An error exception contains: # - A ParseError detailing the error # - The Token the error is at (possibly None) # - An expected string (possibly None), used if the parser is expecting # a single, specific token such as a keyword # - A ParseContext detailing the current parsing task from hypothesis.strategies import composite, integers, sampled_from, text from src.parse import ( ParseContext, ParseError, ParseErrorException, ParseTask, ) from tests.templates import template_test_structure from tests.test_token import draw_token_random, static_token # # Helper functions # # Draws a strategy, with 25% of draws being None @composite def draw_maybe(draw, strategy): chance = draw(integers(min_value=1, max_value=4)) if chance == 1: return None else: return draw(strategy) # Draws a random parse task @composite def draw_parse_task(draw): return draw(sampled_from(list(ParseTask))) # Draws a random parse context without a parent @composite def draw_parse_context(draw): task = draw(draw_maybe(draw_parse_task())) token = draw(draw_maybe(draw_token_random())) context = draw(draw_maybe(draw_parse_context())) return ParseContext(task, token, context) # Static parse context def static_parse_context(): task = ParseTask.TEST_TASK token = static_token() return ParseContext(task, token, None) # 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()) token = draw(draw_maybe(draw_token_random())) expected = draw(draw_maybe(text())) context = draw(draw_parse_context()) return ParseErrorException(error, token, expected, context) # # Test functions # # Test parse context structure @template_test_structure( ParseContext, draw_parse_context(), task=draw_parse_task(), token=draw_maybe(draw_token_random()), parent=draw_maybe(draw_parse_context()), ) def test_parse_context_structure(): pass # Test parse error exception structure @template_test_structure( ParseErrorException, draw_parse_error_exception(), error=draw_parse_error(), token=draw_maybe(draw_token_random()), expected=draw_maybe(text()), context=draw_maybe(draw_parse_context()), ) def test_parse_error_exception_structure(): pass