Files
Sheerka-Old/tests/parsers/test_ExpressionParser.py
T
kodjo 7dcaa9c111 Fixed #29: Parsers: Implement parsing memoization
Fixed #77 : Parser: ShortTermMemoryParser should be called separately
Fixed #78 : Remove VariableNode usage
Fixed #79 : ConceptManager: Implement compile caching
Fixed #80 : SheerkaExecute : parsers_key is not correctly computed
Fixed #81 : ValidateConceptEvaluator : Validate concept's where and pre clauses right after the parsing
Fixed #82 : SheerkaIsAManager: isa() failed when the set as a body
Fixed #83 : ValidateConceptEvaluator : Support BNF and SYA Concepts
Fixed #84 : ExpressionParser: Implement the parser as a standard parser
Fixed #85 : Services: Give order to services
Fixed #86 : cannot manage smart_get_attr(the short, color)
2021-06-07 21:14:03 +02:00

128 lines
5.8 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 VariableNode, ComparisonNode, ExprNode
from parsers.BaseParser import ErrorSink, BaseParser
from parsers.ExpressionParser import ExpressionParser
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
from tests.parsers.parsers_utils import get_expr_node_from_test_node, VAR, EXPR, FN, AND, NOT, OR, GT, GTE, LT, LTE, EQ, \
NEQ, IN, NIN
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", EXPR("var1 + 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"), EXPR("var2.attr2, var3.attr3"))),
("var1 not in (var2.attr2, var3.attr3)", NIN(VAR("var1"), EXPR("var2.attr2, var3.attr3"))),
("var1 < var2 and var3 > var4", AND(LT(VAR("var1"), VAR("var2")), GT(VAR("var3"), VAR("var4")))),
("func1(one, 1 + 2, func2(3))", FN("func1(", (")", 1), [(VAR("one"), ", "),
(EXPR("1 + 2"), ", "),
FN("func2(", ")", [EXPR("3")])])),
("func(var.attr)", FN("func(", ")", [VAR("var.attr")])),
("func(var1.attr1 and var2.attr2)", FN("func(", ")", [AND(VAR("var1.attr1"), VAR("var2.attr2"))])),
("func(var1.attr1 > var2.attr2)", FN("func(", ")", [GT(VAR("var1.attr1"), VAR("var2.attr2"))])),
("func1(var1) and func2(var2)", AND(FN("func1(", ")", [VAR("var1")]), FN("func2(", (")", 1), [VAR("var2")]))),
("__ret", VAR("__ret")),
# ("func1().func2()", [])
])
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, EXPR("var1 + var2"))
@pytest.mark.parametrize("expression, expected", [
("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_compile(self):
sheerka, context, parser = self.init_parser()
text = ParserInput("a > b and c < d")
res = parser.parse(context, text)
assert res.who == BaseParser.PREFIX + ExpressionParser.NAME
assert res.status
assert sheerka.isinstance(res.body, BuiltinConcepts.PARSER_RESULT)
assert isinstance(res.body.body, ExprNode)
assert res.body.body.compiled is not None