diff --git a/tests/parse/test_bool.py b/tests/parse/test_bool.py new file mode 100644 index 0000000..073e0ee --- /dev/null +++ b/tests/parse/test_bool.py @@ -0,0 +1,81 @@ +# SPDX-License-Identifier: LGPL-2.1-only +# Copyright 2022 Jookia + +from hypothesis import assume, given +from hypothesis.strategies import ( + booleans, + composite, +) + +from src.parse import ( + ParseError, + ParseErrorException, + Parser, +) +from src.syntax import Syntax, SyntaxStream, SyntaxType +from tests.test_syntax import ( + draw_token_bool, + draw_syntax_random, +) + + +# Draws tokens to make a valid boolean +@composite +def draw_syntax_bool_valid(draw): + token = draw(draw_token_bool()) + value = token.value == "True" + result = Syntax(value, token.location, SyntaxType.BOOL) + return (token, result) + + +# Tests parse_bool works correctly +# We expect the following behaviour: +# - Only the first token is parsed +# - The resulting boolean is True if the first token is True +# - The resulting boolean is False if the first token is False +# - The Syntax's value is the resulting token +# - The Syntax's type is SyntaxType.BOOL +# - The Syntax's location is the first token's location +@given(draw_syntax_random(), draw_syntax_bool_valid()) +def test_parse_bool_valid(canary, test_data): + (token, result) = test_data + stream = SyntaxStream([token] + [canary]) + parsed = Parser().parse_bool(stream) + assert parsed is not None + assert parsed == result + assert stream.pop() == canary + assert stream.pop() is None + + +# Generate an invalid boolean +# We expect the following behaviour: +# - Error if there isn't a token +# - Error if the token is not a SyntaxType.TOKEN +# - Error if the token is not True or False +@composite +def draw_syntax_bool_invalid(draw): + if draw(booleans()): + token = draw(draw_syntax_random()) + assume( + not (token.type == SyntaxType.TOKEN and token.value in ["True", "False"]) + ) + if token.type == SyntaxType.TOKEN: + error = ParseErrorException(ParseError.NOT_BOOL, token, None) + else: + error = ParseErrorException(ParseError.NOT_TOKEN, token, None) + return ([token], error) + else: + error = ParseErrorException(ParseError.NO_TOKEN, None, None) + return ([], error) + + +# Test that parse_bool errors in invalid cases +@given(draw_syntax_bool_invalid()) +def test_parse_bool_invalid(test_data): + (tokens, error) = test_data + stream = SyntaxStream(tokens) + try: + parsed = Parser().parse_bool(stream) + raise AssertionError("Parsed invalid data: %s" % (parsed)) + except ParseErrorException as e: + assert e == error diff --git a/tests/parse/test_parse.py b/tests/parse/test_parse.py index 14500b8..9db1818 100644 --- a/tests/parse/test_parse.py +++ b/tests/parse/test_parse.py @@ -21,7 +21,6 @@ ) from src.syntax import Syntax, SyntaxStream, SyntaxType from tests.test_syntax import ( - draw_token_bool, draw_token_by_value, draw_token_classified, draw_syntax_random, @@ -294,68 +293,6 @@ assert e == error -# Draws tokens to make a valid boolean -@composite -def draw_syntax_bool_valid(draw): - token = draw(draw_token_bool()) - value = token.value == "True" - result = Syntax(value, token.location, SyntaxType.BOOL) - return (token, result) - - -# Tests parse_bool works correctly -# We expect the following behaviour: -# - Only the first token is parsed -# - The resulting boolean is True if the first token is True -# - The resulting boolean is False if the first token is False -# - The Syntax's value is the resulting token -# - The Syntax's type is SyntaxType.BOOL -# - The Syntax's location is the first token's location -@given(draw_syntax_random(), draw_syntax_bool_valid()) -def test_parse_bool_valid(canary, test_data): - (token, result) = test_data - stream = SyntaxStream([token] + [canary]) - parsed = Parser().parse_bool(stream) - assert parsed is not None - assert parsed == result - assert stream.pop() == canary - assert stream.pop() is None - - -# Generate an invalid boolean -# We expect the following behaviour: -# - Error if there isn't a token -# - Error if the token is not a SyntaxType.TOKEN -# - Error if the token is not True or False -@composite -def draw_syntax_bool_invalid(draw): - if draw(booleans()): - token = draw(draw_syntax_random()) - assume( - not (token.type == SyntaxType.TOKEN and token.value in ["True", "False"]) - ) - if token.type == SyntaxType.TOKEN: - error = ParseErrorException(ParseError.NOT_BOOL, token, None) - else: - error = ParseErrorException(ParseError.NOT_TOKEN, token, None) - return ([token], error) - else: - error = ParseErrorException(ParseError.NO_TOKEN, None, None) - return ([], error) - - -# Test that parse_bool errors in invalid cases -@given(draw_syntax_bool_invalid()) -def test_parse_bool_invalid(test_data): - (tokens, error) = test_data - stream = SyntaxStream(tokens) - try: - parsed = Parser().parse_bool(stream) - raise AssertionError("Parsed invalid data: %s" % (parsed)) - except ParseErrorException as e: - assert e == error - - # Dummy parse_note implementation for testing note clearing # This redefines skip_note to skip the StartNote and not do anything else def clear_notes_skip_note_valid(stream):