Fixed #55 : DefConceptParser: failed to recognize concept
Fixed #62 : DefConceptParser: parsing error Fixed #64 : DefConceptParser: Failed to parse when too many concept keyword Fixed #65 : DefConceptParser : Add auto_eval keyword Fixed #66 : DefConceptParser : Add def_var keyword Fixed #67 : Add get_errors()
This commit is contained in:
+2
-2
@@ -45,7 +45,7 @@ class InitTestHelper:
|
||||
c.get_metadata().definition_type = DEFINITION_TYPE_BNF
|
||||
else:
|
||||
raise Exception(f"Error in bnf definition '{c.get_metadata().definition}'",
|
||||
self.sheerka.get_error(res))
|
||||
self.sheerka.get_errors(res))
|
||||
|
||||
if create_new:
|
||||
self.sheerka.create_new_concept(self.context, c)
|
||||
@@ -89,7 +89,7 @@ class InitTestHelper:
|
||||
res = self.sheerka.create_new_rule(self.context, rule)
|
||||
if not res.status:
|
||||
raise Exception(f"Error in rule definition '{res.body}'",
|
||||
self.sheerka.get_error(res))
|
||||
self.sheerka.get_errors(res))
|
||||
self.items.append(res.body.body)
|
||||
else:
|
||||
self.items.append(rule)
|
||||
|
||||
+136
-2
@@ -3,13 +3,14 @@ import os
|
||||
import pytest
|
||||
|
||||
from conftest import SHEERKA_TEST_FOLDER
|
||||
from core.builtin_concepts import BuiltinConcepts, ReturnValueConcept, UserInputConcept
|
||||
from core.builtin_concepts import BuiltinConcepts, ReturnValueConcept, UserInputConcept, UnknownConcept
|
||||
from core.builtin_concepts_ids import AllBuiltinConcepts
|
||||
from core.concept import Concept, PROPERTIES_TO_SERIALIZE, ConceptParts, get_concept_attrs
|
||||
from core.global_symbols import NotInit
|
||||
from core.sheerka.Sheerka import Sheerka, BASE_NODE_PARSER_CLASS
|
||||
from core.sheerka.services.SheerkaConceptManager import SheerkaConceptManager
|
||||
from core.sheerka.services.SheerkaConceptManager import SheerkaConceptManager, ValueNotFound
|
||||
from core.tokenizer import Token, TokenKind
|
||||
from parsers.PythonParser import PythonErrorNode
|
||||
from tests.TestUsingFileBasedSheerka import TestUsingFileBasedSheerka
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
@@ -425,6 +426,139 @@ class TestSheerkaUsingMemoryBasedSheerka(TestUsingMemoryBasedSheerka):
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.ONTOLOGY_ALREADY_DEFINED)
|
||||
|
||||
@pytest.mark.parametrize("obj, expected", [
|
||||
("a string", []),
|
||||
(True, []),
|
||||
(False, []),
|
||||
(Concept("foo"), []),
|
||||
(Concept("foo", body=False).auto_init(), []),
|
||||
(UnknownConcept(), [UnknownConcept()]),
|
||||
(Concept("foo", body=UnknownConcept()).auto_init(), [UnknownConcept()]),
|
||||
(PythonErrorNode("msg", None), [PythonErrorNode("msg", None)])
|
||||
])
|
||||
def test_i_can_get_error_for_simple_objects(self, obj, expected):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
assert sheerka.get_errors(obj) == expected
|
||||
|
||||
def test_i_can_get_error_when_builtin_concept_in_error(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
obj = sheerka.new(BuiltinConcepts.ONTOLOGY_ALREADY_DEFINED)
|
||||
assert sheerka.get_errors(obj) == [obj]
|
||||
|
||||
def test_i_can_get_error_when_return_value(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
error = sheerka.err("an error")
|
||||
ret_val = ReturnValueConcept("Test", False, sheerka.err("an error"))
|
||||
assert sheerka.get_errors(ret_val) == [error]
|
||||
|
||||
def test_i_can_get_inner_error(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
error = sheerka.err("an error")
|
||||
ret_val = ReturnValueConcept("Test", False, sheerka.err("an error"))
|
||||
assert sheerka.get_errors(ret_val) == [error]
|
||||
|
||||
def test_i_can_get_error_when_embedded_errors(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
concept_eval_error = sheerka.new(BuiltinConcepts.CONCEPT_EVAL_ERROR)
|
||||
unknown_concept = sheerka.new(BuiltinConcepts.UNKNOWN_CONCEPT)
|
||||
not_an_error = sheerka.new(BuiltinConcepts.AUTO_EVAL)
|
||||
error = sheerka.err([concept_eval_error, unknown_concept, not_an_error])
|
||||
|
||||
ret_val = ReturnValueConcept("Test", False, error)
|
||||
errors_found = sheerka.get_errors(ret_val)
|
||||
|
||||
assert errors_found == [error, concept_eval_error, unknown_concept]
|
||||
|
||||
def test_i_can_get_error_from_list(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
concept_eval_error = sheerka.new(BuiltinConcepts.CONCEPT_EVAL_ERROR)
|
||||
unknown_concept = sheerka.new(BuiltinConcepts.UNKNOWN_CONCEPT)
|
||||
not_an_error = sheerka.new(BuiltinConcepts.AUTO_EVAL)
|
||||
error = sheerka.err([concept_eval_error, unknown_concept, not_an_error])
|
||||
ret_val_1 = ReturnValueConcept("Test", False, error)
|
||||
|
||||
python_error = PythonErrorNode("msg", Exception())
|
||||
value_not_found = ValueNotFound("item", "value")
|
||||
multiple_error = sheerka.new(BuiltinConcepts.MULTIPLE_ERRORS, body=[python_error, value_not_found])
|
||||
ret_val_2 = ReturnValueConcept("Test", False, multiple_error)
|
||||
|
||||
errors_found = sheerka.get_errors([ret_val_1, ret_val_2])
|
||||
|
||||
assert errors_found == [error, concept_eval_error, unknown_concept,
|
||||
multiple_error, python_error, value_not_found]
|
||||
|
||||
def test_i_can_filter_error_by_concept_key(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
concept_eval_error = sheerka.new(BuiltinConcepts.CONCEPT_EVAL_ERROR)
|
||||
unknown_concept = sheerka.new(BuiltinConcepts.UNKNOWN_CONCEPT)
|
||||
python_error = PythonErrorNode("msg", Exception())
|
||||
error = sheerka.err([concept_eval_error, unknown_concept, python_error])
|
||||
ret_val = ReturnValueConcept("Test", False, error)
|
||||
|
||||
errors_found = sheerka.get_errors(ret_val, __type=BuiltinConcepts.CONCEPT_EVAL_ERROR)
|
||||
assert errors_found == [concept_eval_error]
|
||||
|
||||
def test_i_can_filter_error_by_class_name(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
concept_eval_error = sheerka.new(BuiltinConcepts.CONCEPT_EVAL_ERROR)
|
||||
unknown_concept = sheerka.new(BuiltinConcepts.UNKNOWN_CONCEPT)
|
||||
python_error = PythonErrorNode("msg", Exception())
|
||||
error = sheerka.err([concept_eval_error, unknown_concept, python_error])
|
||||
ret_val = ReturnValueConcept("Test", False, error)
|
||||
|
||||
errors_found = sheerka.get_errors(ret_val, __type="PythonErrorNode")
|
||||
assert errors_found == [python_error]
|
||||
|
||||
def test_i_can_filter_error_by_concept_attribute(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
concept_eval_error = sheerka.new(BuiltinConcepts.CONCEPT_EVAL_ERROR)
|
||||
unknown_concept = sheerka.new(BuiltinConcepts.UNKNOWN_CONCEPT, concept_ref="a_concept_ref")
|
||||
python_error = PythonErrorNode("msg", Exception())
|
||||
error = sheerka.err([concept_eval_error, unknown_concept, python_error])
|
||||
ret_val = ReturnValueConcept("Test", False, error)
|
||||
|
||||
errors_found = sheerka.get_errors(ret_val, concept_ref="a_concept_ref")
|
||||
assert errors_found == [unknown_concept]
|
||||
|
||||
def test_i_can_filter_error_by_class_attribute(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
concept_eval_error = sheerka.new(BuiltinConcepts.CONCEPT_EVAL_ERROR)
|
||||
unknown_concept = sheerka.new(BuiltinConcepts.UNKNOWN_CONCEPT, concept_ref="a_concept_ref")
|
||||
python_error = PythonErrorNode("error source", Exception())
|
||||
error = sheerka.err([concept_eval_error, unknown_concept, python_error])
|
||||
ret_val = ReturnValueConcept("Test", False, error)
|
||||
|
||||
errors_found = sheerka.get_errors(ret_val, source="error source")
|
||||
assert errors_found == [python_error]
|
||||
|
||||
def test_i_can_filter_error_on_multiple_criteria(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
concept_eval_error = sheerka.new(BuiltinConcepts.CONCEPT_EVAL_ERROR)
|
||||
unknown_concept = sheerka.new(BuiltinConcepts.UNKNOWN_CONCEPT, concept_ref="a_concept_ref")
|
||||
value_not_found = ValueNotFound("an_item", "a value")
|
||||
error = sheerka.err([concept_eval_error, unknown_concept, value_not_found])
|
||||
ret_val = ReturnValueConcept("Test", False, error)
|
||||
|
||||
errors_found = sheerka.get_errors(ret_val, __type="ValueNotFound", item="an_item", value="a value")
|
||||
assert errors_found == [value_not_found]
|
||||
|
||||
def test_i_cannot_get_error_when_return_value_s_status_is_true(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
ret_val = ReturnValueConcept("Test", True, sheerka.err("an error"))
|
||||
assert sheerka.get_errors(ret_val) == []
|
||||
|
||||
|
||||
class TestSheerkaUsingFileBasedSheerka(TestUsingFileBasedSheerka):
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ from core.concept import VARIABLE_PREFIX, Concept, DEFINITION_TYPE_BNF, DEFINITI
|
||||
from core.sheerka.services.SheerkaConceptManager import NoFirstTokenError
|
||||
from core.sheerka.services.SheerkaExecute import ParserInput
|
||||
from core.tokenizer import Tokenizer
|
||||
from evaluators.DefConceptEvaluator import DefConceptEvaluator
|
||||
from evaluators.DefConceptEvaluator import DefConceptEvaluator, PossibleVariable, CertainVariable
|
||||
from parsers.BaseParser import BaseParser
|
||||
from parsers.BnfDefinitionParser import BnfDefinitionParser
|
||||
from parsers.BnfNodeParser import Sequence, StrMatch, ZeroOrMore, ConceptExpression, VariableExpression
|
||||
@@ -144,20 +144,112 @@ class TestDefConceptEvaluator(TestUsingMemoryBasedSheerka):
|
||||
assert created_concept.get_metadata().definition == "hello a"
|
||||
assert created_concept.get_metadata().definition_type == "def"
|
||||
|
||||
def test_i_can_add_concept_with_the_correct_variables_when_referencing_other_concepts(self):
|
||||
@pytest.mark.parametrize("expression, name, expected", [
|
||||
("isinstance(a, str)", "a b", {"a"}),
|
||||
("a.location = b", "a is in b", {"a", "b"}),
|
||||
("a.location = b", "'a' is in b", {"b"}),
|
||||
("date.today()", "what is the date", set()),
|
||||
("a.location", "where is a", {"a"})
|
||||
])
|
||||
def test_i_can_get_variables_from_python_node_when_long_name(self, expression, name, expected):
|
||||
ret_val = self.get_concept_part(expression)
|
||||
context = self.get_context()
|
||||
def_concept_return_value = self.get_def_concept(
|
||||
name="x plus y",
|
||||
where=self.pretval(Concept("u is a v").def_var("u").def_var("v"), source="x is a number"),
|
||||
body=self.pretval(Concept("add a b").def_var("a").def_var("b"), source="add x y"), )
|
||||
|
||||
evaluated = DefConceptEvaluator().eval(context, def_concept_return_value)
|
||||
resolved_expected = [PossibleVariable(e) for e in expected]
|
||||
assert DefConceptEvaluator.get_variables(context, ret_val, name.split()) == resolved_expected
|
||||
|
||||
def test_i_can_get_variables_when_keywords(self):
|
||||
sheerka, context = self.init_concepts()
|
||||
|
||||
def_concept = self.get_def_concept("condition pre").value.value
|
||||
name_to_use = DefConceptEvaluator.get_name_to_use(def_concept)
|
||||
concept_part = self.get_concept_part("pre")
|
||||
|
||||
assert DefConceptEvaluator.get_variables(context, concept_part, name_to_use) == [PossibleVariable("pre")]
|
||||
|
||||
def test_i_can_get_variable_when_rule_is_defined(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
def_concept_parser = DefConceptParser()
|
||||
|
||||
parsed_ret_val = def_concept_parser.parse(context, ParserInput("def concept rule x as r:|x:"))
|
||||
assert parsed_ret_val.status # sanity check
|
||||
|
||||
evaluated = DefConceptEvaluator().eval(context, parsed_ret_val)
|
||||
assert evaluated.status
|
||||
assert evaluated.body.body.key == "rule __var__0"
|
||||
assert evaluated.body.body.get_metadata().variables == [("x", None)]
|
||||
|
||||
def test_i_cannot_get_variables_from_python_node_when_name_has_only_one_token(self):
|
||||
ret_val = self.get_concept_part("isinstance(a, str)")
|
||||
context = self.get_context()
|
||||
|
||||
assert DefConceptEvaluator.get_variables(context, ret_val, ["a"]) == []
|
||||
|
||||
def test_i_can_get_variables_from_definition(self):
|
||||
parsing_expression = Sequence(ConceptExpression('mult'),
|
||||
ZeroOrMore(Sequence(StrMatch("+"), ConceptExpression("add"))))
|
||||
ret_val = self.get_return_value("mult (('+'|'-') add)?", parsing_expression)
|
||||
|
||||
expected = [CertainVariable("mult"), CertainVariable("add")]
|
||||
assert DefConceptEvaluator.get_variables(self.get_context(), ret_val, []) == expected
|
||||
|
||||
def test_i_can_get_variable_from_bnf_definition_2(self):
|
||||
sheerka, context, one, two = self.init_concepts("one", "two")
|
||||
|
||||
text = "def concept twenties from bnf 'twenty' (one|two)=unit as 20 + unit"
|
||||
def_ret_val = DefConceptParser().parse(context, ParserInput(text))
|
||||
concept_definition = def_ret_val.value.body.definition
|
||||
|
||||
expected = [CertainVariable("unit"), CertainVariable("one"), CertainVariable("two")]
|
||||
assert DefConceptEvaluator.get_variables(context, concept_definition, []) == expected
|
||||
|
||||
def test_i_can_recognize_variables_when_referencing_other_concepts(self):
|
||||
sheerka, context, isa_concept = self.init_concepts(Concept("x is an y").def_var("x").def_var("y"))
|
||||
|
||||
text = "def concept what x is y pre is_question() where x is an adjective as get_attr(x, y)"
|
||||
def_ret_val = DefConceptParser().parse(context, ParserInput(text))
|
||||
evaluated = DefConceptEvaluator().eval(context, def_ret_val)
|
||||
new_concept = evaluated.body.body
|
||||
|
||||
assert evaluated.status
|
||||
assert context.sheerka.isinstance(evaluated.body, BuiltinConcepts.NEW_CONCEPT)
|
||||
assert new_concept.get_metadata().variables == [('x', None), ('y', None)]
|
||||
|
||||
created_concept = evaluated.body.body
|
||||
assert created_concept.get_metadata().variables == [("x", None), ("y", None)]
|
||||
def test_i_can_recognize_variables_when_given_in_concept_definition(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
text = "def concept a plus b as a + b def_var plus"
|
||||
def_ret_val = DefConceptParser().parse(context, ParserInput(text))
|
||||
evaluated = DefConceptEvaluator().eval(context, def_ret_val)
|
||||
new_concept = evaluated.body.body
|
||||
|
||||
assert evaluated.status
|
||||
assert new_concept.get_metadata().variables == [('plus', None)]
|
||||
|
||||
def test_i_can_recognize_variables_when_referencing_other_concepts_with_variable_mapping(self):
|
||||
sheerka, context, number, isa, add = self.init_concepts(
|
||||
"number",
|
||||
Concept("u is a v").def_var("u").def_var("v"),
|
||||
Concept("add a b").def_var("a").def_var("b")
|
||||
)
|
||||
|
||||
text = "def concept x plus y where x is a number as add x y"
|
||||
def_ret_val = DefConceptParser().parse(context, ParserInput(text))
|
||||
evaluated = DefConceptEvaluator().eval(context, def_ret_val)
|
||||
new_concept = evaluated.body.body
|
||||
|
||||
assert evaluated.status
|
||||
assert new_concept.get_metadata().variables == [('x', None), ('y', None)]
|
||||
|
||||
def test_i_do_no_mixed_up_concept_and_variable_name(self):
|
||||
sheerka, context, activate_debug = self.init_concepts(Concept("activate debug"))
|
||||
|
||||
text = "def concept debug on as activate debug"
|
||||
def_ret_val = DefConceptParser().parse(context, ParserInput(text))
|
||||
evaluated = DefConceptEvaluator().eval(context, def_ret_val)
|
||||
new_concept = evaluated.body.body
|
||||
|
||||
assert evaluated.status
|
||||
assert new_concept.get_metadata().variables == []
|
||||
|
||||
def test_other_concepts_are_not_variables(self):
|
||||
sheerka, context, *concepts = self.init_test().with_concepts("little", "size", create_new=True).unpack()
|
||||
@@ -166,7 +258,7 @@ class TestDefConceptEvaluator(TestUsingMemoryBasedSheerka):
|
||||
name_to_use = DefConceptEvaluator.get_name_to_use(def_concept_node)
|
||||
concept_part = self.get_concept_part("set_attr(x, size, little)")
|
||||
|
||||
assert DefConceptEvaluator.get_variables(context, concept_part, name_to_use) == {"x"}
|
||||
assert DefConceptEvaluator.get_variables(context, concept_part, name_to_use) == [PossibleVariable("x")]
|
||||
|
||||
def test_that_the_new_concept_is_correctly_saved_in_db(self):
|
||||
context = self.get_context()
|
||||
@@ -199,41 +291,6 @@ class TestDefConceptEvaluator(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert from_db.get_compiled() == {} # ast is not saved in db
|
||||
|
||||
@pytest.mark.parametrize("expression, name, expected", [
|
||||
("isinstance(a, str)", "a b", {"a"}),
|
||||
("a.location = b", "a is in b", {"a", "b"}),
|
||||
("a.location = b", "'a' is in b", {"b"}),
|
||||
("date.today()", "what is the date", set()),
|
||||
("a.location", "where is a", {"a"})
|
||||
])
|
||||
def test_i_can_get_variables_from_python_node_when_long_name(self, expression, name, expected):
|
||||
ret_val = self.get_concept_part(expression)
|
||||
context = self.get_context()
|
||||
|
||||
assert DefConceptEvaluator.get_variables(context, ret_val, name.split()) == expected
|
||||
|
||||
def test_i_can_get_variables_when_keywords(self):
|
||||
sheerka, context = self.init_concepts()
|
||||
|
||||
def_concept = self.get_def_concept("condition pre").value.value
|
||||
name_to_use = DefConceptEvaluator.get_name_to_use(def_concept)
|
||||
concept_part = self.get_concept_part("pre")
|
||||
|
||||
assert DefConceptEvaluator.get_variables(context, concept_part, name_to_use) == {"pre"}
|
||||
|
||||
def test_i_cannot_get_variables_from_python_node_when_name_has_only_one_token(self):
|
||||
ret_val = self.get_concept_part("isinstance(a, str)")
|
||||
context = self.get_context()
|
||||
|
||||
assert DefConceptEvaluator.get_variables(context, ret_val, ["a"]) == set()
|
||||
|
||||
def test_i_can_get_variables_from_definition(self):
|
||||
parsing_expression = Sequence(ConceptExpression('mult'),
|
||||
ZeroOrMore(Sequence(StrMatch("+"), ConceptExpression("add"))))
|
||||
ret_val = self.get_return_value("mult (('+'|'-') add)?", parsing_expression)
|
||||
|
||||
assert DefConceptEvaluator.get_variables(self.get_context(), ret_val, []) == {"add", "mult"}
|
||||
|
||||
def test_concept_that_references_itself_is_correctly_created(self):
|
||||
context = self.get_context()
|
||||
def_concept_as_return_value = self.get_def_concept("foo", body="foo")
|
||||
@@ -247,18 +304,6 @@ class TestDefConceptEvaluator(TestUsingMemoryBasedSheerka):
|
||||
assert new_concept.values() == {}
|
||||
assert new_concept.get_metadata().variables == []
|
||||
|
||||
def test_i_can_get_variable_when_rule_is_defined(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
def_concept_parser = DefConceptParser()
|
||||
|
||||
parsed_ret_val = def_concept_parser.parse(context, ParserInput("def concept rule x as r:|x:"))
|
||||
assert parsed_ret_val.status # sanity check
|
||||
|
||||
evaluated = DefConceptEvaluator().eval(context, parsed_ret_val)
|
||||
assert evaluated.status
|
||||
assert evaluated.body.body.key == "rule __var__0"
|
||||
assert evaluated.body.body.get_metadata().variables == [("x", None)]
|
||||
|
||||
def test_i_can_recognize_variable_when_keyword_argument(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
def_concept_parser = DefConceptParser()
|
||||
@@ -309,7 +354,19 @@ class TestDefConceptEvaluator(TestUsingMemoryBasedSheerka):
|
||||
assert created_concept.get_metadata().variables == [("x", None)]
|
||||
assert created_concept._bnf == Sequence(StrMatch("hello"), VariableExpression("x"))
|
||||
|
||||
def test_i_can_eval_when_auto_eval_is_true(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
def_ret_val = DefConceptParser().parse(context, ParserInput("def concept foo auto_eval True"))
|
||||
evaluated = DefConceptEvaluator().eval(context, def_ret_val)
|
||||
|
||||
assert evaluated.status
|
||||
assert context.sheerka.isinstance(evaluated.body, BuiltinConcepts.NEW_CONCEPT)
|
||||
created_concept = evaluated.body.body
|
||||
|
||||
assert sheerka.get_property(created_concept, BuiltinConcepts.ISA) == {sheerka.new(BuiltinConcepts.AUTO_EVAL)}
|
||||
|
||||
def test_i_cannot_eval_bnf_concept_with_unknown_variable(self):
|
||||
# testing MandatoryVariable
|
||||
context = self.get_context()
|
||||
def_ret_val = DefConceptParser().parse(context, ParserInput("def concept name from bnf unknown foo"))
|
||||
evaluated = DefConceptEvaluator().eval(context, def_ret_val)
|
||||
|
||||
@@ -683,12 +683,12 @@ as:
|
||||
assert len(res) == 1
|
||||
assert not res[0].status
|
||||
assert sheerka.isinstance(res[0].body, BuiltinConcepts.MULTIPLE_ERRORS)
|
||||
assert str(BuiltinConcepts.CONDITION_FAILED) in [error.key for error in sheerka.get_error(res[0].body.body)]
|
||||
assert str(BuiltinConcepts.CONDITION_FAILED) in [error.key for error in sheerka.get_errors(res[0].body.body)]
|
||||
|
||||
res = sheerka.evaluate_user_input("eval twenty three")
|
||||
assert len(res) == 1
|
||||
assert not res[0].status
|
||||
assert str(BuiltinConcepts.CONDITION_FAILED) in [error.key for error in sheerka.get_error(res[0].body.body)]
|
||||
assert str(BuiltinConcepts.CONDITION_FAILED) in [error.key for error in sheerka.get_errors(res[0].body.body)]
|
||||
|
||||
def test_i_can_manage_some_type_of_infinite_recursion(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
@@ -7,14 +7,23 @@ from parsers.BaseParser import UnexpectedEofParsingError, UnexpectedTokenParsing
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
def get_tokens(items):
|
||||
return [list(Tokenizer(item, yield_eof=False))[0] for item in items]
|
||||
|
||||
|
||||
class TestBaseCustomGrammarParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
@staticmethod
|
||||
def compare_results(actual, expected, compare_str=False):
|
||||
resolved_expected = {}
|
||||
for k, v in expected.items():
|
||||
tokens = list(Tokenizer(v, yield_eof=False))
|
||||
resolved_expected[k] = [tokens[0]] + tokens[2:]
|
||||
if isinstance(v, str):
|
||||
# case like {Keywords.DEF_VAR: "def_var var1 def_var var2"}
|
||||
tokens = list(Tokenizer(v, yield_eof=False))
|
||||
resolved_expected[k] = [tokens[0]] + tokens[2:]
|
||||
else:
|
||||
# case like {Keywords.DEF_VAR: get_tokens(["def_var", "var1", "var2"])}
|
||||
resolved_expected[k] = v
|
||||
|
||||
def get_better_representation(value):
|
||||
better_repr = {}
|
||||
@@ -23,6 +32,7 @@ class TestBaseCustomGrammarParser(TestUsingMemoryBasedSheerka):
|
||||
better_repr[k] = [tokens[0].repr_value, value]
|
||||
return better_repr
|
||||
|
||||
# it's easier to compare two list of string
|
||||
actual_to_compare = get_better_representation(actual)
|
||||
expected_to_compare = get_better_representation(resolved_expected)
|
||||
|
||||
@@ -67,6 +77,20 @@ func(a)
|
||||
res = parser.get_parts(["when"])
|
||||
self.compare_results(res, expected)
|
||||
|
||||
@pytest.mark.parametrize("text, allow_multiple, expected", [
|
||||
("def_var var1 def_var var2", {}, {Keywords.DEF_VAR: "def_var var1 def_var var2"}),
|
||||
("def_var var1 def_var var2", {"def_var"}, {Keywords.DEF_VAR: get_tokens(["def_var", "var1", "var2"])}),
|
||||
("def_var x y z def_var var2", {"def_var"}, {Keywords.DEF_VAR: get_tokens(["def_var", "'x y z'", "var2"])}),
|
||||
("def_var 'x y z' def_var var2", {"def_var"}, {Keywords.DEF_VAR: get_tokens(["def_var", "'x y z'", "var2"])}),
|
||||
("def_var var1 def_var x y z def_var var2", {"def_var"},
|
||||
{Keywords.DEF_VAR: get_tokens(["def_var", "var1", "'x y z'", "var2"])}),
|
||||
])
|
||||
def test_i_can_get_parts_when_allow_multiple_is_set(self, text, allow_multiple, expected):
|
||||
sheerka, context, parser = self.init_parser(text)
|
||||
|
||||
res = parser.get_parts(["def_var"], allow_multiple=allow_multiple)
|
||||
self.compare_results(res, expected)
|
||||
|
||||
@pytest.mark.parametrize("text", [
|
||||
"",
|
||||
"no keyword",
|
||||
@@ -88,14 +112,6 @@ func(a)
|
||||
"when",
|
||||
[Keywords.PRINT])]
|
||||
|
||||
def test_i_can_detect_when_a_keyword_appears_several_times(self):
|
||||
sheerka, context, parser = self.init_parser("print hello when True print True")
|
||||
|
||||
parser.get_parts(["print"])
|
||||
assert len(parser.error_sink) == 1
|
||||
assert isinstance(parser.error_sink[0], SyntaxErrorNode)
|
||||
assert parser.error_sink[0].message == "Too many 'print' declarations."
|
||||
|
||||
@pytest.mark.parametrize("text", [
|
||||
"print",
|
||||
"print ",
|
||||
|
||||
@@ -12,7 +12,7 @@ from parsers.BaseParser import UnexpectedEofParsingError
|
||||
from parsers.BnfDefinitionParser import BnfDefinitionParser
|
||||
from parsers.BnfNodeParser import OrderedChoice, ConceptExpression, StrMatch, Sequence, RegExMatch, OneOrMore, \
|
||||
VariableExpression
|
||||
from parsers.DefConceptParser import DefConceptParser, NameNode, SyntaxErrorNode
|
||||
from parsers.DefConceptParser import DefConceptParser, NameNode, SyntaxErrorNode, CannotHandleParsingError
|
||||
from parsers.DefConceptParser import UnexpectedTokenParsingError, DefConceptNode
|
||||
from parsers.FunctionParser import FunctionParser
|
||||
from parsers.PythonParser import PythonParser, PythonNode
|
||||
@@ -636,3 +636,77 @@ from give me the date !
|
||||
assert res.value.source == text
|
||||
assert isinstance(res.value, ParserResultConcept)
|
||||
assert node == expected
|
||||
|
||||
def test_i_can_parse_when_multiple_keyword_and_no_ambiguity(self):
|
||||
sheerka, context, parser, *concepts = self.init_parser()
|
||||
res = parser.parse(context, ParserInput("def concept x is a concept"))
|
||||
|
||||
assert res.status
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("def concept foo auto_eval True", True),
|
||||
("def concept foo auto_eval true", True),
|
||||
("def concept foo auto_eval False", False),
|
||||
("def concept foo auto_eval false", False),
|
||||
])
|
||||
def test_i_can_parse_auto_eval(self, text, expected):
|
||||
sheerka, context, parser, *concepts = self.init_parser()
|
||||
res = parser.parse(context, ParserInput(text))
|
||||
def_concept_node = res.value.value
|
||||
|
||||
assert res.status
|
||||
assert res.who == parser.name
|
||||
assert res.value.source == text
|
||||
assert isinstance(res.value, ParserResultConcept)
|
||||
|
||||
assert def_concept_node.auto_eval == expected
|
||||
|
||||
@pytest.mark.parametrize("text", [
|
||||
"def concept foo auto_eval",
|
||||
"def concept foo auto_eval as 1"
|
||||
])
|
||||
def test_i_cannot_parse_when_missing_auto_eval_value(self, text):
|
||||
sheerka, context, parser, *concepts = self.init_parser()
|
||||
res = parser.parse(context, ParserInput(text))
|
||||
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(res.value, BuiltinConcepts.ERROR)
|
||||
assert sheerka.has_error(res, __type="SyntaxErrorNode", message="Empty 'auto_eval' declaration.")
|
||||
|
||||
def test_i_cannot_parse_when_wrong_auto_eval_value(self):
|
||||
sheerka, context, parser, *concepts = self.init_parser()
|
||||
text = "def concept foo auto_eval wrong_value"
|
||||
res = parser.parse(context, ParserInput(text))
|
||||
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(res.value, BuiltinConcepts.ERROR)
|
||||
assert isinstance(res.value.body[0], CannotHandleParsingError)
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("def concept foo def_var var", ["var"]),
|
||||
("def concept foo def_var var1 def_var var2", ["var1", "var2"]),
|
||||
("def concept foo def_var var1 def_var long var name def_var var2", ["var1", "long var name", "var2"]),
|
||||
])
|
||||
def test_i_can_parse_variable_definition(self, text, expected):
|
||||
sheerka, context, parser, *concepts = self.init_parser()
|
||||
res = parser.parse(context, ParserInput(text))
|
||||
def_concept_node = res.value.value
|
||||
|
||||
assert res.status
|
||||
assert res.who == parser.name
|
||||
assert res.value.source == text
|
||||
assert isinstance(res.value, ParserResultConcept)
|
||||
|
||||
assert def_concept_node.variables == expected
|
||||
|
||||
@pytest.mark.parametrize("text", [
|
||||
"def concept foo def_var",
|
||||
"def concept foo def_var as 1"
|
||||
])
|
||||
def test_i_cannot_parse_variable_definition_when_missing_value(self, text):
|
||||
sheerka, context, parser, *concepts = self.init_parser()
|
||||
res = parser.parse(context, ParserInput(text))
|
||||
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(res.value, BuiltinConcepts.ERROR)
|
||||
assert sheerka.has_error(res, __type="SyntaxErrorNode", message="Empty 'def_var' declaration.")
|
||||
|
||||
Reference in New Issue
Block a user