import pytest from core.builtin_concepts_ids import BuiltinConcepts from core.sheerka.services.SheerkaExecute import ParserInput from core.tokenizer import Token, TokenKind from parsers.BaseExpressionParser import ParenthesisMismatchError, end_parenthesis_mapping from parsers.BaseParser import ErrorSink from parsers.ListParser import ListParser from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka from tests.parsers.parsers_utils import EXPR, L_EXPR, get_expr_node_from_test_node semi_colon = Token(TokenKind.SEMICOLON, ";", -1, -1, -1) or_token = Token(TokenKind.IDENTIFIER, "or", -1, -1, -1) class TestListParser(TestUsingMemoryBasedSheerka): def init_parser(self, strict=True, sep=None): sheerka, context = self.init_concepts() parser = ListParser(strict, sep) return sheerka, context, parser @pytest.mark.parametrize("expression, sep, expected", [ ("()", None, L_EXPR("(", ")")), ("(x , foo y,z)", None, L_EXPR("(", ")", EXPR("x"), EXPR("foo y"), EXPR("z"), source="(x , foo y,z)")), ("x , foo y,z", None, L_EXPR(None, None, EXPR("x"), EXPR("foo y"), EXPR("z"), source="x , foo y,z")), ("x", None, L_EXPR(None, None, EXPR("x"))), ("[x, foo y, z]", None, L_EXPR("[", "]", EXPR("x"), EXPR("foo y"), EXPR("z"))), ("{x, foo y, z}", None, L_EXPR("{", "}", EXPR("x"), EXPR("foo y"), EXPR("z"))), ("(x; y; z)", semi_colon, L_EXPR("(", ")", "x", "y", "z", sep=semi_colon, source="(x; y; z)")), ("x; y; z", semi_colon, L_EXPR(None, None, EXPR("x"), EXPR("y"), EXPR("z"), sep=semi_colon, source="x; y; z")), ("x or y or z", or_token, L_EXPR(None, None, EXPR("x"), EXPR("y"), EXPR("z"), sep=or_token, source="x or y or z")), ]) def test_i_can_parse_expression(self, expression, sep, expected): sheerka, context, parser = self.init_parser(strict=False, sep=sep) expected = get_expr_node_from_test_node(expression, expected) res = parser.parse(context, ParserInput(expression)) wrapper = res.body expressions = res.body.body assert res.status assert sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT) assert expressions == expected @pytest.mark.parametrize("expression, expected", [ ("()", L_EXPR("(", ")")), ("(a, b)", L_EXPR("(", ")", EXPR("a"), EXPR("b"))), ("a, b", None), ]) def test_parenthesis_are_mandatory_when_strict(self, expression, expected): sheerka, context, parser = self.init_parser(strict=True) res = parser.parse(context, ParserInput(expression)) if expected: expected = get_expr_node_from_test_node(expression, expected) assert res.status assert sheerka.isinstance(res.body, BuiltinConcepts.PARSER_RESULT) assert res.body.body == expected else: assert not res.status assert sheerka.isinstance(res.body, BuiltinConcepts.NOT_FOR_ME) @pytest.mark.parametrize("expression, starting", [ ("(", TokenKind.LPAR), ("(x, y", TokenKind.LPAR), ("{x, y", TokenKind.LBRACE), ("[x, y", TokenKind.LBRACKET), ]) def test_i_cannot_parse_when_missing_trailing_parenthesis(self, expression, starting): sheerka, context, parser = self.init_parser() res = parser.parse(context, ParserInput(expression)) assert not res.status assert sheerka.isinstance(res.body, BuiltinConcepts.ERROR) assert res.body.body == [ParenthesisMismatchError(end_parenthesis_mapping[starting])] def test_none_is_return_when_empty_parser_input(self): sheerka, context, parser = self.init_parser() parser_input = ParserInput(" ").reset() parser_input.next_token() error_sink = ErrorSink() parsed = parser.parse_input(context, parser_input, error_sink) assert parsed is None