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 from parsers.BaseParser import UnexpectedEofParsingError, UnexpectedTokenParsingError from parsers.ListComprehensionParser import ElementNotFound, FailedToParse, ForNotFound, LeadingParenthesisNotFound, \ ListComprehensionParser from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka from tests.parsers.parsers_utils import LC, L_EXPR, get_expr_node_from_test_node class TestListComprehensionParser(TestUsingMemoryBasedSheerka): def init_parser(self): sheerka, context = self.init_concepts() parser = ListComprehensionParser(auto_compile=False) return sheerka, context, parser @pytest.mark.parametrize("text, reason", [ ("foo", LeadingParenthesisNotFound()), ("[]", ForNotFound()), ("[ x ]", ForNotFound()), ("[ x for]", FailedToParse("target", 5)), ("[ x for x]", UnexpectedEofParsingError("while parsing comprehension")), ("[ x for x in ]", UnexpectedEofParsingError("while parsing comprehension")), ("[ x for x in lst for]", FailedToParse("target", 13)), ("[", UnexpectedEofParsingError("when start parsing")), ("[]", ForNotFound()), ("[ for x in z ]", ElementNotFound()), ("[ x for in z ]", FailedToParse("target", 6)), ("[ x for x in ]", UnexpectedEofParsingError("while parsing comprehension")), ("[ x for x in z if ]", UnexpectedEofParsingError("while parsing comprehension")), ("[ x for x in z", ParenthesisMismatchError(Token(TokenKind.RBRACKET, "]", -1, -1, -1))), ("[ x for x in z if t", ParenthesisMismatchError(Token(TokenKind.RBRACKET, "]", -1, -1, -1))), ("zzz [ x for x in z if t ]", LeadingParenthesisNotFound()), ("[ x for x in z )", ParenthesisMismatchError(Token(TokenKind.RBRACKET, "]", -1, -1, -1))), ("[ x for x in z if t )", ParenthesisMismatchError(Token(TokenKind.RBRACKET, "]", -1, -1, -1))), ]) def test_i_cannot_parse_when_not_for_me(self, text, reason): sheerka, context, parser = self.init_parser() res = parser.parse(context, ParserInput(text)) assert not res.status assert sheerka.isinstance(res.body, BuiltinConcepts.NOT_FOR_ME) assert res.body.reason == [reason] def test_i_cannot_parse_when_trailing_elements(self): sheerka, context, parser = self.init_parser() text = "[ x for x in z if t ] zzz" res = parser.parse(context, ParserInput(text)) assert not res.status assert sheerka.isinstance(res.body, BuiltinConcepts.ERROR) assert len(res.body.body) == 1 error = res.body.body[0] assert isinstance(error, UnexpectedTokenParsingError) def test_i_can_parse_a_simple_expression(self): sheerka, context, parser = self.init_parser() expression = "[x for x in ['a', 'b'] if x == 'a']" res = parser.parse(context, ParserInput(expression)) wrapper = res.body lc_node = res.body.body assert res.status assert sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT) expected = LC(L_EXPR(None, None, "x", source="x "), [(("x", 1), "['a', 'b']", "x == 'a'")], source=expression) to_compare_to = get_expr_node_from_test_node(expression, expected) assert lc_node == to_compare_to def test_i_can_parse_when_no_if(self): sheerka, context, parser = self.init_parser() expression = "[x for x in ['a', 'b']]" res = parser.parse(context, ParserInput(expression)) wrapper = res.body lc_node = res.body.body assert res.status assert sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT) expected = LC(L_EXPR(None, None, "x", source="x "), [(("x", 1), "['a', 'b']", None)], source=expression) to_compare_to = get_expr_node_from_test_node(expression, expected) assert lc_node == to_compare_to def test_i_can_parse_when_element_is_a_tuple(self): sheerka, context, parser = self.init_parser() expression = "[(x + 1, x + 2) for x in [1, 2]]" res = parser.parse(context, ParserInput(expression)) wrapper = res.body lc_node = res.body.body assert res.status assert sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT) elt = L_EXPR("(", ")", "x + 1", "x + 2") expected = LC(elt, [(("x", 2), "[1, 2]", None)], source=expression) to_compare_to = get_expr_node_from_test_node(expression, expected) assert lc_node == to_compare_to def test_i_can_parse_when_element_is_a_tuple_with_missing_parenthesis(self): sheerka, context, parser = self.init_parser() expression = "[x + 1, x + 2 for x in [1, 2]]" res = parser.parse(context, ParserInput(expression)) wrapper = res.body lc_node = res.body.body assert res.status assert sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT) elt = L_EXPR(None, None, "x + 1", "x + 2", source="x + 1, x + 2 ") expected = LC(elt, [(("x", 2), "[1, 2]", None)], source=expression) to_compare_to = get_expr_node_from_test_node(expression, expected) assert lc_node == to_compare_to def test_i_can_parse_when_element_is_a_context_that_contains_for(self): sheerka, context, parser = self.init_parser() expression = "[handle x for me and for you for x in [1, 2]]" res = parser.parse(context, ParserInput(expression)) wrapper = res.body lc_node = res.body.body assert res.status assert sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT) elt = L_EXPR(None, None, "handle x for me and for you", source="handle x for me and for you ") expected = LC(elt, [(("x", 1), "[1, 2]", None)], source=expression) to_compare_to = get_expr_node_from_test_node(expression, expected) assert lc_node == to_compare_to def test_i_can_parse_when_multiple_generators(self): sheerka, context, parser = self.init_parser() expression = "[(x, y) for x in ['a', 'b'] if x == 'a' for y in ['c', 'd'] if y == 'c']" res = parser.parse(context, ParserInput(expression)) wrapper = res.body lc_node = res.body.body assert res.status assert sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT) elt = L_EXPR("(", ")", "x", "y") expected = LC(elt, [(("x", 1), "['a', 'b']", "x == 'a'"), (("y", 1), "['c', 'd']", "y == 'c'")], source=expression) to_compare_to = get_expr_node_from_test_node(expression, expected) assert lc_node == to_compare_to def test_i_can_parse_when_multiple_generators_when_no_if(self): sheerka, context, parser = self.init_parser() expression = "[x, y for x in ['a', 'b'] for y in ['c', 'd'] if y == 'c']" res = parser.parse(context, ParserInput(expression)) wrapper = res.body lc_node = res.body.body assert res.status assert sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT) elt = L_EXPR(None, None, "x", "y", source="x, y ") expected = LC(elt, [(("x", 1), "['a', 'b']", None), (("y", 1), "['c', 'd']", "y == 'c'")], source=expression) to_compare_to = get_expr_node_from_test_node(expression, expected) assert lc_node == to_compare_to