54e5681c5a
Fixed #110 : SheerkaDebugManager: add list_debug_settings Fixed #111 : SheerkaDebugManager: Implement ListDebugLogger Fixed #112 : SyaNodeParser: rewrite this parser Fixed #113 : Sheerka.: Add enable_parser_caching to disable parsers caching Fixed #114 : SyaNodeParser : Implement fast cache to resolve unrecognized tokens requests Fixed #115 : BnfNodeParser : Implement fast cache to resolve unrecognized tokens requests Fixed #116 : SequenceNodeParser : Implement fast cache to resolve unrecognized tokens requests Fixed #117 : ResolveMultiplePluralAmbiguityEvaluator: Resolve Multiple plural ambiguity
181 lines
7.6 KiB
Python
181 lines
7.6 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)
|
|
|
|
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
|