Files
Sheerka-Old/tests/parsers/test_ExpressionParser.py
kodjo 89e1f20975 Fixed #131 : Implement ExprToConditions
Fixed #130 : ArithmeticOperatorParser
Fixed #129 : python_wrapper : create_namespace
Fixed #128 : ExpressionParser: Cannot parse func(x) infixed concept 'xxx'
2021-10-13 16:06:57 +02:00

131 lines
6.1 KiB
Python

import pytest
from core.builtin_concepts_ids import BuiltinConcepts
from core.sheerka.services.SheerkaExecute import ParserInput
from core.tokenizer import Tokenizer
from parsers.BaseExpressionParser import ComparisonNode, SequenceNode, VariableNode
from parsers.BaseParser import ErrorSink
from parsers.ExpressionParser import ExpressionParser
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
from tests.parsers.parsers_utils import ADD, AND, EQ, EXPR, FN, GT, GTE, IN, LT, LTE, L_EXPR, MULT, NEQ, NIN, NOT, OR, \
VAR, get_expr_node_from_test_node
class TestExpressionParser(TestUsingMemoryBasedSheerka):
def init_parser(self):
sheerka, context = self.init_concepts()
parser = ExpressionParser()
return sheerka, context, parser
def init_parser_with_source(self, source):
sheerka, context, parser = self.init_parser()
error_sink = ErrorSink()
parser_input = ParserInput(source)
parser.reset_parser_input(parser_input, error_sink)
return sheerka, context, parser, parser_input, error_sink
def test_i_can_detect_empty_expression(self):
sheerka, context, parser = self.init_parser()
res = parser.parse(context, ParserInput(""))
assert not res.status
assert sheerka.isinstance(res.body, BuiltinConcepts.IS_EMPTY)
@pytest.mark.parametrize("expression, expected", [
("var1 + var2", ADD(VAR("var1"), VAR("var2"))),
("variable", VAR("variable")),
("var.attr", VAR("var.attr")),
("var1 and var2", AND(VAR("var1"), VAR("var2"))),
("var1 or var2", OR(VAR("var1"), VAR("var2"))),
("not var", NOT(VAR("var"))),
("var1 > var2", GT(VAR("var1"), VAR("var2"))),
("var1 >= var2", GTE(VAR("var1"), VAR("var2"))),
("var1 < var2", LT(VAR("var1"), VAR("var2"))),
("var1 <= var2", LTE(VAR("var1"), VAR("var2"))),
("var1 = var2", EQ(VAR("var1"), VAR("var2"))),
("var1 == var2", EQ(VAR("var1"), VAR("var2"))),
("var1 != var2", NEQ(VAR("var1"), VAR("var2"))),
("var1 in (var2.attr2, var3.attr3)", IN(VAR("var1"), L_EXPR("(", ")", "var2.attr2", "var3.attr3"))),
("var1 not in (var2.attr2, var3.attr3)", NIN(VAR("var1"), L_EXPR("(", ")", "var2.attr2", "var3.attr3"))),
("var1 < var2 and var3 > var4", AND(LT(VAR("var1"), VAR("var2")), GT(VAR("var3"), VAR("var4")))),
("var1 < var2 + var3", LT(VAR("var1"), ADD(VAR("var2"), VAR("var3")))),
("func1(one, 1 + 2, func2(3))", FN("func1", "one", "1 + 2", "func2(3)")),
("func(var.attr)", FN("func", "var.attr")),
("func(var1.attr1 and var2.attr2)", FN("func", "var1.attr1 and var2.attr2")),
("func(var1.attr1 > var2.attr2)", FN("func", "var1.attr1 > var2.attr2")),
("__ret", VAR("__ret")),
("f(x) is another b(y)", EXPR("f(x) is another b(y)")),
("var1 + var2 * var3", ADD(VAR("var1"), MULT(VAR("var2"), VAR("var3")))),
("(a) + (b)", ADD(VAR("a"), VAR("b"), source="(a) + (b)")),
("(a + b) < (c + d)", LT(ADD(VAR("a"), VAR("b")), ADD(VAR("c"), VAR("d")), source="(a + b) < (c + d)")),
("(a, b, c)", L_EXPR("(", ")", VAR("a"), VAR("b"), VAR("c"))),
("[a, b, c]", L_EXPR("[", "]", VAR("a"), VAR("b"), VAR("c"))),
("{a, b, c}", L_EXPR("{", "}", VAR("a"), VAR("b"), VAR("c"))),
])
def test_i_can_parse_input(self, expression, expected):
sheerka, context, parser, parser_input, error_sink = self.init_parser_with_source(expression)
expected = get_expr_node_from_test_node(expression, expected)
parsed = parser.parse_input(context, parser_input, error_sink)
assert not error_sink.has_error
assert parsed == expected
@pytest.mark.parametrize("expression", [
"var.attr1.attr2",
"var . attr1 . attr2",
])
def test_i_can_parse_input_variable(self, expression):
sheerka, context, parser, parser_input, error_sink = self.init_parser_with_source(expression)
parsed = parser.parse_input(context, parser_input, error_sink)
assert not error_sink.has_error
assert isinstance(parsed, VariableNode)
assert parsed.name == "var"
assert parsed.attributes == ["attr1", "attr2"]
def test_i_can_parse_input_sub_tokens(self):
sheerka, context, parser = self.init_parser()
expression = "do not care var1 + var2 do not care either"
parser_input = ParserInput("text", list(Tokenizer(expression, yield_eof=False)), start=6, end=10)
error_sink = ErrorSink()
parser.reset_parser_input(parser_input, error_sink)
parsed = parser.parse_input(context, parser_input, error_sink)
assert not error_sink.has_error
assert parsed == get_expr_node_from_test_node(expression, ADD("var1", "var2"), default_expr_obj=VAR)
@pytest.mark.parametrize("expression, expected", [
("ret.status in ('a', 1 , func())", "new_var in ('a', 1 , func())"),
("ret.status in ['a', 1 , func()]", "new_var in ['a', 1 , func()]"),
("ret.status not in ('a', 1 , func())", "new_var not in ('a', 1 , func())"),
("ret.status == 10", "new_var == 10"),
("ret.status == 'a'", "new_var == 'a'"),
])
def test_i_can_rebuild_source(self, expression, expected):
sheerka, context, parser, parser_input, error_sink = self.init_parser_with_source(expression)
parsed = parser.parse_input(context, parser_input, error_sink)
new_source = ComparisonNode.rebuild_source("new_var", parsed.comp, parsed.right.get_source())
assert new_source == expected
def test_i_cannot_parse_empty_string(self):
sheerka, context, parser = self.init_parser()
res = parser.parse(context, ParserInput(""))
assert not res.status
assert sheerka.isinstance(res.body, BuiltinConcepts.IS_EMPTY)
def test_i_can_clone(self):
sheerka, context, parser, parser_input, error_sink = self.init_parser_with_source("foo x + 1")
expr = parser.parse_input(context, parser_input, error_sink)
assert isinstance(expr, SequenceNode)
clone = expr.clone()
assert expr == clone