Files
Sheerka-Old/tests/parsers/test_ArithmericOperatorParser.py
T
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

130 lines
7.0 KiB
Python

import pytest
from core.sheerka.services.SheerkaExecute import ParserInput
from parsers.ArithmericOperatorParser import ArithmeticOperatorParser
from parsers.BaseExpressionParser import LeftPartNotFoundError, ParenthesisMismatchError, RightPartNotFoundError
from parsers.BaseParser import ErrorSink
from parsers.ExpressionParser import ExpressionParser
from parsers.FunctionParser import FunctionParser
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
from tests.parsers.parsers_utils import ADD, DIV, EXPR, FDIV, FN, LT, MOD, MULT, POW, SEQ, SUB, VAR, \
get_expr_node_from_test_node
class TestArithmeticOperatorParser(TestUsingMemoryBasedSheerka):
def init_parser(self, expr_parser=None, function_parser=None):
sheerka, context = self.init_concepts()
expr_parser = expr_parser or ExpressionParser(auto_compile=False)
parser = ArithmeticOperatorParser(expr_parser=expr_parser, function_parser=function_parser)
return sheerka, context, parser
@pytest.mark.parametrize("expression, expected", [
("one complicated expression", VAR("one complicated expression")),
("a + b", ADD(VAR("a"), VAR("b"))),
("a - b", SUB("a", "b")),
("a * b", MULT("a", "b")),
("a / b", DIV("a", "b")),
("a // b", FDIV("a", "b")),
("a % b", MOD("a", "b")),
("a ** b", POW("a", "b")),
("a + b * c", ADD("a", MULT("b", "c"))),
("a * b + c", ADD(MULT("a", "b"), "c")),
("a * b ** c", MULT("a", POW("b", "c"))),
("a ** b * c", MULT(POW("a", "b"), "c")),
("(a + b) * c", MULT(ADD("a", "b"), "c", source="(a + b) * c")),
("a * (b + c)", MULT("a", ADD("b", "c"), source="a * (b + c)")),
("func(a, b) * 3", MULT(FN(EXPR("func"), EXPR("a"), EXPR("b")), EXPR("3"))),
("3 * func(a, b)", MULT(EXPR("3"), FN(EXPR("func"), EXPR("a"), EXPR("b")))),
("a + b + c", ADD("a", "b", "c")),
("a - b - c", SUB("a", "b", "c")),
("a + b - c - d", SUB(ADD("a", "b"), "c", "d")),
("a * b * c + d + e + f", ADD(MULT("a", "b", "c"), "d", "e", "f")),
("a + b < c", ADD("a", LT("b", "c"))), # this is possible is function_parser is not set
("foo x + y", SEQ(EXPR("foo "), ADD("x", "y"))), # to manager concept call
("long name concept x + y + z", SEQ(EXPR("long name concept "), ADD("x", "y", "z"))),
("long name concept x + y - z", SEQ(EXPR("long name concept "), SUB(ADD("x", "y"), "z"))),
("long name concept x + y * z", SEQ(EXPR("long name concept "), ADD("x", MULT("y", "z")))),
("long name concept x * y + z", SEQ(EXPR("long name concept "), ADD(MULT("x", "y"), "z"))),
("(foo x) + y", ADD("foo x", "y", source="(foo x) + y")),
("a + foo x + y", ADD("a", SEQ(EXPR("foo "), ADD("x", "y")))),
("a + b * foo x * y + z", ADD("a", MULT("b", SEQ(EXPR("foo "), ADD(MULT("x", "y"), "z"))))),
("a + foo b + c + bar e + f", ADD("a", SEQ(EXPR("foo "), ADD("b", "c", SEQ(EXPR("bar "), ADD("e", "f")))))),
("a + foo x", ADD("a", "foo x")),
("a + x y bar + b - c", ADD("a", SEQ(EXPR("x y "), SUB(ADD("bar", "b"), "c")))),
("a + x + y bar + b - c", ADD("a", "x", SEQ(EXPR("y "), SUB(ADD("bar", "b"), "c")))),
("a + x ? y : z + b - c", ADD("a", SEQ(EXPR("x ? y : "), SUB(ADD("z", "b"), "c")))),
("twenty one + 3", SEQ(EXPR("twenty "), ADD("one", EXPR("3")))),
("(foo x) * (bar y)", MULT("foo x", "bar y", source="(foo x) * (bar y)"))
])
def test_i_can_parse_input_expression(self, expression, expected):
sheerka, context, parser = self.init_parser()
parser_input = ParserInput(expression).reset()
parser_input.next_token()
error_sink = ErrorSink()
expr = parser.parse_input(context, parser_input, error_sink)
assert not error_sink.has_error
expected = get_expr_node_from_test_node(expression, expected, default_expr_obj=VAR)
assert expr == expected
@pytest.mark.parametrize("expression, expected", [
("one complicated expression", VAR("one complicated expression")),
("a + b", ADD(VAR("a"), VAR("b"))),
("func(a, b) * 3", MULT(FN(EXPR("func"), EXPR("a"), EXPR("b")), EXPR("3"))),
("3 * func(a, b)", MULT(EXPR("3"), FN(EXPR("func"), EXPR("a"), EXPR("b")))),
("a + b < c", ADD("a", EXPR("b < c"))), # the comparison is no longer recognized
("foo x + y", SEQ(EXPR("foo "), ADD("x", "y"))), # to manager concept call
("long name concept x + y + z", SEQ(EXPR("long name concept "), ADD("x", "y", "z"))),
("long name concept x + y - z", SEQ(EXPR("long name concept "), SUB(ADD("x", "y"), "z"))),
("long name concept x + y * z", SEQ(EXPR("long name concept "), ADD("x", MULT("y", "z")))),
("long name concept x * y + z", SEQ(EXPR("long name concept "), ADD(MULT("x", "y"), "z"))),
("(foo x) + y", ADD("foo x", "y", source="(foo x) + y")),
("a + foo x + y", ADD("a", SEQ(EXPR("foo "), ADD("x", "y")))),
("a + b * foo x * y + z", ADD("a", MULT("b", SEQ(EXPR("foo "), ADD(MULT("x", "y"), "z"))))),
("a + foo b + c + bar e + f", ADD("a", SEQ(EXPR("foo "), ADD("b", "c", SEQ(EXPR("bar "), ADD("e", "f")))))),
("a + foo x", ADD("a", "foo x")),
("a + x y bar + b - c", ADD("a", SEQ(EXPR("x y "), SUB(ADD("bar", "b"), "c")))),
("a + x + y bar + b - c", ADD("a", "x", SEQ(EXPR("y "), SUB(ADD("bar", "b"), "c")))),
("a + x ? y : z + b - c", ADD("a", SEQ(EXPR("x ? y : "), SUB(ADD("z", "b"), "c")))),
("(foo x) * (bar y) + 2", ADD(MULT("foo x", "bar y", source="(foo x) * (bar y)"), EXPR("2"))),
])
def test_i_can_parse_input_when_function_parser_is_set(self, expression, expected):
sheerka, context, parser = self.init_parser(function_parser=FunctionParser())
parser_input = ParserInput(expression).reset()
parser_input.next_token()
error_sink = ErrorSink()
expr = parser.parse_input(context, parser_input, error_sink)
assert not error_sink.has_error
expected = get_expr_node_from_test_node(expression, expected, default_expr_obj=VAR)
assert expr == expected
@pytest.mark.parametrize("expression, expected_error, expr_is_none", [
("a +", [RightPartNotFoundError], False),
("+ a", [LeftPartNotFoundError], True),
("a ++ b", [RightPartNotFoundError], False),
("(a + b", [ParenthesisMismatchError], False),
# ("a + b)", [ParenthesisMismatchError], False), # only detected is strict is on
])
def test_i_can_detect_errors(self, expression, expected_error, expr_is_none):
sheerka, context, parser = self.init_parser()
parser_input = ParserInput(expression).reset()
parser_input.next_token()
error_sink = ErrorSink()
expr = parser.parse_input(context, parser_input, error_sink)
assert error_sink.has_error
assert (expr is None) == expr_is_none
resolved_errors = [type(e) for e in error_sink.sink]
assert resolved_errors == expected_error