89e1f20975
Fixed #130 : ArithmeticOperatorParser Fixed #129 : python_wrapper : create_namespace Fixed #128 : ExpressionParser: Cannot parse func(x) infixed concept 'xxx'
191 lines
8.4 KiB
Python
191 lines
8.4 KiB
Python
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)
|
|
|
|
@pytest.mark.parametrize("expression, expected_generator", [
|
|
("[x for x in ['a', 'b'] if x == 'a']", [(("x", 1), "['a', 'b']", "x == 'a'")]),
|
|
("[x for x in ('a', 'b') if x == 'a']", [(("x", 1), "('a', 'b')", "x == 'a'")]),
|
|
("[x for x in {'a', 'b'} if x == 'a']", [(("x", 1), "{'a', 'b'}", "x == 'a'")]),
|
|
("(x for x in ['a', 'b'] if x == 'a')", [(("x", 1), "['a', 'b']", "x == 'a'")]),
|
|
("(x for x in ('a', 'b') if x == 'a')", [(("x", 1), "('a', 'b')", "x == 'a'")]),
|
|
("(x for x in {'a', 'b'} if x == 'a')", [(("x", 1), "{'a', 'b'}", "x == 'a'")]),
|
|
("{x for x in ['a', 'b'] if x == 'a'}", [(("x", 1), "['a', 'b']", "x == 'a'")]),
|
|
("{x for x in ('a', 'b') if x == 'a'}", [(("x", 1), "('a', 'b')", "x == 'a'")]),
|
|
("{x for x in {'a', 'b'} if x == 'a'}", [(("x", 1), "{'a', 'b'}", "x == 'a'")]),
|
|
])
|
|
def test_i_can_parse_a_simple_expression(self, expression, expected_generator):
|
|
sheerka, context, parser = self.init_parser()
|
|
|
|
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 "), expected_generator, 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
|