Files
Sheerka-Old/tests/parsers/test_DefFormatRuleParser.py
T
2021-01-11 15:36:03 +01:00

144 lines
5.7 KiB
Python

import pytest
from core.builtin_concepts import BuiltinConcepts
from core.concept import Concept
from core.sheerka.services.SheerkaExecute import ParserInput
from core.sheerka.services.SheerkaRuleManager import FormatAstRawText, RulePredicate, FormatAstVariable
from core.tokenizer import Keywords, Tokenizer
from parsers.BaseCustomGrammarParser import KeywordNotFound
from parsers.DefFormatRuleParser import DefFormatRuleParser, FormatRuleNode
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
cmap = {
"is a": Concept("x is a y").def_var("x").def_var("y"),
"is a question": Concept("x is a y", pre="is_question()").def_var("x").def_var("y"),
"a is good": Concept("a is good").def_var("a"),
"b is good": Concept("b is good").def_var("b"),
}
class TestDefFormatRuleParser(TestUsingMemoryBasedSheerka):
shared_ontology = None
@classmethod
def setup_class(cls):
init_test_helper = cls().init_test(cache_only=False, ontology="#TestDefFormatRuleParser#")
sheerka, context, *updated = init_test_helper.with_concepts(*cmap.values(), create_new=True).unpack()
for i, concept_name in enumerate(cmap):
cmap[concept_name] = updated[i]
cls.shared_ontology = sheerka.get_ontology(context)
sheerka.pop_ontology()
def init_parser(self, my_concepts_map=None, **kwargs):
if my_concepts_map is None:
sheerka, context = self.init_test().unpack()
sheerka.add_ontology(context, self.shared_ontology)
else:
sheerka, context, *updated = self.init_test().with_concepts(*my_concepts_map.values(), **kwargs).unpack()
for i, pair in enumerate(my_concepts_map):
my_concepts_map[pair] = updated[i]
parser = DefFormatRuleParser()
return sheerka, context, parser
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)
def test_input_must_be_a_parser_input(self):
sheerka, context, parser = self.init_parser()
parser.parse(context, "not a parser input") is None
def test_i_can_parse_a_simple_rule(self):
sheerka, context, parser = self.init_parser()
text = "when isinstance(last_value(), Concept) print hello world!"
res = parser.parse(context, ParserInput(text))
parser_result = res.body
format_rule = res.body.body
rules = format_rule.rule
format_ast = format_rule.format_ast
assert res.status
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
assert isinstance(format_rule, FormatRuleNode)
assert self.dump_tokens(format_rule.tokens[Keywords.WHEN][1:]) == self.dump_tokens(
Tokenizer("isinstance(last_value(), Concept)", False))
assert self.dump_tokens(format_rule.tokens[Keywords.PRINT][1:]) == self.dump_tokens(
Tokenizer("hello world!", False))
assert len(rules) == 1
assert isinstance(rules[0], RulePredicate)
assert format_ast == FormatAstRawText("hello world!")
def test_when_is_parsed_in_the_context_of_a_question(self):
sheerka, context, parser = self.init_parser()
text = "when foo is a bar print hello world"
res = parser.parse(context, ParserInput(text))
format_rule = res.body.body
rules = format_rule.rule
assert res.status
assert len(rules) == 1
assert isinstance(rules[0], RulePredicate)
assert rules[0].predicate.body.body.get_metadata().pre == "is_question()"
def test_when_can_support_multiple_possibilities(self):
sheerka, context, parser = self.init_parser()
text = "when foo is good print hello world"
res = parser.parse(context, ParserInput(text))
format_rule = res.body.body
rules = format_rule.rule
assert res.status
assert len(rules) == 2
assert rules[0].predicate.body.body.get_metadata().name == "a is good"
assert rules[1].predicate.body.body.get_metadata().name == "b is good"
@pytest.mark.parametrize("text, error", [
("hello world", [KeywordNotFound(None, keywords=['when', 'print'])]),
("when True", [KeywordNotFound([], keywords=['print'])]),
("print True", [KeywordNotFound([], keywords=['when'])]),
])
def test_cannot_parse_when_not_for_me(self, text, error):
sheerka, context, parser = self.init_parser()
res = parser.parse(context, ParserInput(text))
not_for_me = res.body
assert not res.status
assert sheerka.isinstance(not_for_me, BuiltinConcepts.NOT_FOR_ME)
assert not_for_me.reason == error
@pytest.mark.parametrize("text, expected_error", [
("when a b print hello world!", BuiltinConcepts.TOO_MANY_ERRORS),
])
def test_i_cannot_parse_invalid_predicates(self, text, expected_error):
sheerka, context, parser = self.init_parser()
res = parser.parse(context, ParserInput(text))
assert not res.status
assert sheerka.isinstance(res.body, expected_error)
@pytest.mark.parametrize("expr, expected", [
("hello world", FormatAstRawText("hello world")),
("{id}", FormatAstVariable("id")),
])
def test_i_can_parse_valid_print_expression(self, expr, expected):
sheerka, context, parser = self.init_parser()
text = "when True print " + expr
res = parser.parse(context, ParserInput(text))
format_rule = res.body.body
format_ast = format_rule.format_ast
assert res.status
assert format_ast == expected