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)
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
import pytest
|
||||
|
||||
from core.tokenizer import Token, TokenKind
|
||||
from parsers.FormatRuleActionParser import FormatAstSequence, FormatAstRawText, FormatAstVariable, FormatAstFunction, \
|
||||
FormatAstList, FormatAstColor, FormatAstDict, FormatAstMulti, FormatRuleActionParser, UnexpectedEof, \
|
||||
FormatRuleSyntaxError
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
seq = FormatAstSequence
|
||||
raw = FormatAstRawText
|
||||
var = FormatAstVariable
|
||||
func = FormatAstFunction
|
||||
lst = FormatAstList
|
||||
|
||||
|
||||
class TestFormatRuleActionParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("", FormatAstRawText("")),
|
||||
(" ", FormatAstRawText(" ")),
|
||||
(" raw text ", FormatAstRawText(" raw text ")),
|
||||
("{variable}", FormatAstVariable("variable")),
|
||||
("{ variable }", FormatAstVariable("variable")),
|
||||
(" xy {v} z", seq([raw(" xy "), var("v"), raw(" z")])),
|
||||
(r"\{variable}", FormatAstRawText("{variable}")),
|
||||
(r"\\{variable}", seq([raw("\\"), var("variable")])),
|
||||
(r"\\\{variable}", FormatAstRawText(r"\{variable}")),
|
||||
(r"{var1}{var2}", seq([var("var1"), var("var2")])),
|
||||
("func()", FormatAstFunction("func", [], {})),
|
||||
("func(a, 'string value', c)", FormatAstFunction("func", ["a", "'string value'", "c"], {})),
|
||||
("func(a=10, b='string value')", FormatAstFunction("func", [], {"a": "10", "b": "'string value'"})),
|
||||
("func('string value'='another string value')", func("func", [], {"'string value'": "'another string value'"})),
|
||||
("red(' xy {v}')", FormatAstColor("red", seq([raw(" xy "), var("v")]))),
|
||||
('blue(" xy {v}")', FormatAstColor("blue", seq([raw(" xy "), var("v")]))),
|
||||
('green( xy )', FormatAstColor("green", var("xy"))),
|
||||
('green()', FormatAstColor("green", raw(""))),
|
||||
('green("")', FormatAstColor("green", raw(""))),
|
||||
("list(var_name, 2, 'children')", FormatAstList("var_name", recurse_on="children", recursion_depth=2)),
|
||||
("list(var_name, recursion_depth=2, recurse_on='children')", FormatAstList("var_name",
|
||||
recurse_on="children",
|
||||
recursion_depth=2)),
|
||||
("list(var_name, recursion_depth=2, 'children')", FormatAstList("var_name", recursion_depth=2)),
|
||||
("list(var_name, 'children', recursion_depth=2)", FormatAstList("var_name", recursion_depth=2)),
|
||||
("list(var_name)", FormatAstList("var_name")),
|
||||
("{obj.prop1.prop2[0].prop3['value']}", FormatAstVariable("obj.prop1.prop2[0].prop3['value']")),
|
||||
("[{id}]", seq([raw("["), var("id"), raw("]")])),
|
||||
("{variable:format}", FormatAstVariable("variable", "format")),
|
||||
("{variable:3}", FormatAstVariable("variable", "3")),
|
||||
(r"\not_a_function(a={var})", seq([raw("not_a_function(a="), var("var"), raw(")")])),
|
||||
("dict(var_name)", FormatAstDict("var_name")),
|
||||
("dict(var_name, items_prop='props')", FormatAstDict("var_name", items_prop='props')),
|
||||
("dict(var_name, debug=True)", FormatAstDict("var_name", debug=True, prefix="{", suffix="}")),
|
||||
("multi(var_name)", FormatAstMulti("var_name")),
|
||||
])
|
||||
def test_i_can_parse_format_rule(self, text, expected):
|
||||
assert FormatRuleActionParser(text).parse() == expected
|
||||
|
||||
@pytest.mark.parametrize("text, expected_error", [
|
||||
("{", UnexpectedEof("while parsing variable", Token(TokenKind.LBRACE, "{", 0, 1, 1))),
|
||||
("{var_name", UnexpectedEof("while parsing variable", Token(TokenKind.LBRACE, "{", 0, 1, 1))),
|
||||
("{}", FormatRuleSyntaxError("variable name not found", None)),
|
||||
("func(", UnexpectedEof("while parsing function", Token(TokenKind.IDENTIFIER, "func", 0, 1, 1))),
|
||||
("func(a,b,c", UnexpectedEof("while parsing function", Token(TokenKind.IDENTIFIER, "func", 0, 1, 1))),
|
||||
("func(a,,c", FormatRuleSyntaxError("no parameter found", Token(TokenKind.COMMA, ",", 7, 1, 8))),
|
||||
("func(a,,c)", FormatRuleSyntaxError("no parameter found", Token(TokenKind.COMMA, ",", 7, 1, 8))),
|
||||
("red(a,b)", FormatRuleSyntaxError("only one parameter supported", Token(TokenKind.IDENTIFIER, "b", 6, 1, 7))),
|
||||
("red(a=b)", FormatRuleSyntaxError("keyword arguments are not supported", None)),
|
||||
("red(xy {v})", FormatRuleSyntaxError("Invalid identifier", None)),
|
||||
("list()", FormatRuleSyntaxError("variable name not found", None)),
|
||||
("list(recursion_depth=2)", FormatRuleSyntaxError("variable name not found", None)),
|
||||
("list(a,b,c,d,e)", FormatRuleSyntaxError("too many positional arguments",
|
||||
Token(TokenKind.IDENTIFIER, "e", 13, 1, 14))),
|
||||
("list(a, recursion_depth=hello)", FormatRuleSyntaxError("'hello' is not numeric", None)),
|
||||
("list(a, recursion_depth='hello')", FormatRuleSyntaxError("'recursion_depth' must be an integer", None)),
|
||||
("dict()", FormatRuleSyntaxError("variable name not found", None)),
|
||||
])
|
||||
def test_i_cannot_parse_invalid_format(self, text, expected_error):
|
||||
parser = FormatRuleActionParser(text)
|
||||
parser.parse()
|
||||
|
||||
assert parser.error_sink == expected_error
|
||||
Reference in New Issue
Block a user