Fixed #125: SheerkaErrorManager
Fixed #135: Change services service priorities Fixed #136: ErrorManager: Implement recognize_error Fixed #137: BNFNodeParser : Error when parsing regex with sub parsers Fixed #138: get_last_errors(): real errors sources are lost Fixed #139: OneError return value removes the origin of the error Fixed #140: Concept variables are not correctly handled when parsing sub expression Fixed #143: Implement has_unknown_concepts()
This commit is contained in:
+15
-6
@@ -48,7 +48,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_errors(self.context, res))
|
||||
self.sheerka.get_obj_errors(self.context, res))
|
||||
|
||||
self._update_concept_parameters(c)
|
||||
if create_new:
|
||||
@@ -92,8 +92,7 @@ class InitTestHelper:
|
||||
if create_new:
|
||||
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_errors(res))
|
||||
raise Exception(f"Error in rule definition '{res.body}'", self.sheerka.get_obj_errors(res))
|
||||
self.items.append(res.body.body)
|
||||
else:
|
||||
self.items.append(rule)
|
||||
@@ -294,16 +293,26 @@ class BaseTest:
|
||||
return [ret_val for ret_val in return_values if ret_val.status]
|
||||
|
||||
@staticmethod
|
||||
def activate_debug(context, pattern="Sya.*.*"):
|
||||
def activate_debug(context, pattern="Sya.*.*", debug_var=True, debug_concept=False, debug_rule=False):
|
||||
sheerka = context.sheerka
|
||||
sheerka.set_debug(context, True)
|
||||
sheerka.set_debug_logger_definition(ListDebugLogger)
|
||||
|
||||
if isinstance(pattern, list):
|
||||
for p in pattern:
|
||||
sheerka.set_debug_var(context, p)
|
||||
if debug_var:
|
||||
sheerka.set_debug_var(context, p)
|
||||
if debug_concept:
|
||||
sheerka.set_debug_concept(context, p)
|
||||
if debug_rule:
|
||||
sheerka.set_debug_rule(context, p)
|
||||
else:
|
||||
sheerka.set_debug_var(context, pattern)
|
||||
if debug_var:
|
||||
sheerka.set_debug_var(context, pattern)
|
||||
if debug_concept:
|
||||
sheerka.set_debug_concept(context, pattern)
|
||||
if debug_rule:
|
||||
sheerka.set_debug_rule(context, pattern)
|
||||
|
||||
# the see the logs, do not forget to add
|
||||
# logs = sheerka.get_debugger_logs()
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import shutil
|
||||
from os import path
|
||||
|
||||
from conftest import SHEERKA_TEST_FOLDER
|
||||
from core.global_symbols import EVENT_ONTOLOGY_CREATED
|
||||
from core.sheerka.Sheerka import Sheerka
|
||||
from core.sheerka.SheerkaOntologyManager import SheerkaOntologyManager
|
||||
|
||||
from tests.BaseTest import BaseTest
|
||||
|
||||
|
||||
@@ -45,3 +47,18 @@ class TestUsingFileBasedSheerka(BaseTest):
|
||||
|
||||
self.sheerka.push_ontology(self.context, ontology_name, cache_only=cache_only)
|
||||
return TestUsingFileBasedSheerka.sheerka
|
||||
|
||||
@staticmethod
|
||||
def commit(context):
|
||||
sheerka = context.sheerka
|
||||
event = context.event
|
||||
sheerka.om.save_event(event)
|
||||
|
||||
if sheerka.om.is_dirty():
|
||||
sheerka.om.commit(context)
|
||||
|
||||
@staticmethod
|
||||
def reset_hard_test_env():
|
||||
if path.exists(SHEERKA_TEST_FOLDER):
|
||||
shutil.rmtree(SHEERKA_TEST_FOLDER)
|
||||
TestUsingFileBasedSheerka.sheerka = None
|
||||
|
||||
@@ -0,0 +1,463 @@
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import ReturnValueConcept, UnknownConcept
|
||||
from core.builtin_concepts_ids import BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from core.sheerka.services.SheerkaConceptManager import ValueNotFound
|
||||
from core.sheerka.services.SheerkaErrorManager import LAST_UNKNOWN_CONCEPTS, SheerkaErrorManager
|
||||
from core.sheerka.services.SheerkaExecute import ParserInput
|
||||
from core.sheerka.services.SheerkaRuleManager import NoConditionFound
|
||||
from evaluators.PythonEvaluator import PythonEvaluator
|
||||
from parsers.BaseParser import ParsingError, UnexpectedEofParsingError
|
||||
from parsers.BnfNodeParser import BnfNodeParser
|
||||
from parsers.ExactConceptParser import ExactConceptParser
|
||||
from parsers.PythonParser import PythonErrorNode, PythonParser
|
||||
from tests.TestUsingFileBasedSheerka import TestUsingFileBasedSheerka
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
def inner_errors(lst):
|
||||
return [e.error for e in lst]
|
||||
|
||||
|
||||
class TestSheerkaErrorManger(TestUsingMemoryBasedSheerka):
|
||||
|
||||
@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_obj_errors(context, 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_obj_errors(context, 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_obj_errors(context, 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_obj_errors(context, 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_obj_errors(context, ret_val)
|
||||
|
||||
assert errors_found == [error, concept_eval_error, unknown_concept]
|
||||
|
||||
def test_i_can_get_embedded_errors_from_get_error_method(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
embedded_error = NotImplementedError()
|
||||
error = sheerka.new(BuiltinConcepts.NOT_FOR_ME, body="some text", reason=embedded_error)
|
||||
ret_val = ReturnValueConcept("Test", False, error)
|
||||
errors_found = sheerka.get_obj_errors(context, ret_val)
|
||||
|
||||
assert errors_found == [error, embedded_error]
|
||||
|
||||
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_obj_errors(context, [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_obj_errors(context, 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_obj_errors(context, 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_obj_errors(context, 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_obj_errors(context, ret_val, source="error source")
|
||||
assert errors_found == [python_error]
|
||||
|
||||
def test_i_can_filter_error_by_exception_name_and_type(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
from evaluators.PythonEvaluator import PythonEvalError
|
||||
name_error = NameError("foo")
|
||||
python_eval_error = PythonEvalError(name_error, "foo", None, None)
|
||||
error = sheerka.err([python_eval_error])
|
||||
ret_val = ReturnValueConcept("Test", False, error)
|
||||
|
||||
errors_found = sheerka.get_obj_errors(context, ret_val, __type="NameError")
|
||||
assert errors_found == [name_error]
|
||||
|
||||
errors_found = sheerka.get_obj_errors(context, ret_val, __type=NameError)
|
||||
assert errors_found == [name_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_obj_errors(context, 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_obj_errors(context, ret_val) == []
|
||||
|
||||
def test_i_can_get_error_items(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
service = sheerka.services[SheerkaErrorManager.NAME]
|
||||
|
||||
simple_error = sheerka.new(BuiltinConcepts.UNKNOWN_CONCEPT, body=Concept("foo"))
|
||||
ret1 = sheerka.ret("Test1", False, simple_error)
|
||||
|
||||
sub_error_is_an_exception = sheerka.new(BuiltinConcepts.NOT_FOR_ME, reason=NotImplementedError())
|
||||
ret2 = sheerka.ret("Test2", False, sub_error_is_an_exception)
|
||||
|
||||
inner_error = sheerka.err([ParsingError(), UnexpectedEofParsingError("EOF", 0)])
|
||||
sub_error_is_an_error = sheerka.new(BuiltinConcepts.NOT_FOR_ME, reason=inner_error)
|
||||
ret3 = sheerka.ret("Test3", False, sub_error_is_an_error)
|
||||
|
||||
parsing_error = sheerka.new(BuiltinConcepts.PARSER_RESULT,
|
||||
parser=PythonParser(),
|
||||
source="not a valid source",
|
||||
body="Not totally valid parsing")
|
||||
ret4 = sheerka.ret("Test4", False, parsing_error)
|
||||
|
||||
multiple_level_errors1 = sheerka.err("Err1")
|
||||
multiple_level_errors2 = sheerka.err(multiple_level_errors1)
|
||||
multiple_level_errors3 = sheerka.err(multiple_level_errors2)
|
||||
ret5 = sheerka.ret("Test5", False, multiple_level_errors3)
|
||||
|
||||
filtered = sheerka.new(BuiltinConcepts.FILTERED, reason="not really given")
|
||||
ret6 = sheerka.ret("Test6", False, filtered)
|
||||
|
||||
ret7 = sheerka.ret("Test5", True, None)
|
||||
|
||||
error_items = list(service.get_errors_items([ret1, ret2, ret3, ret4, ret5, ret6, ret7]))
|
||||
assert len(error_items) == 6
|
||||
|
||||
# ret1 : simple_error
|
||||
assert len(error_items[0].children) == 0
|
||||
|
||||
# ret2 : sub_error_is_an_exception
|
||||
assert len(error_items[1].children) == 1
|
||||
assert len(error_items[1].children[0].children) == 0
|
||||
|
||||
# ret3 : inner_error
|
||||
assert len(error_items[2].children) == 1
|
||||
assert len(error_items[2].children[0].children) == 2
|
||||
assert len(error_items[2].children[0].children[0].children) == 0
|
||||
assert len(error_items[2].children[0].children[1].children) == 0
|
||||
|
||||
# ret4 : parsing_error
|
||||
assert len(error_items[3].children) == 0
|
||||
|
||||
# ret5 : multiple_level_errors
|
||||
assert len(error_items[4].children) == 1
|
||||
assert len(error_items[4].children[0].children) == 1
|
||||
assert len(error_items[4].children[0].children[0].children) == 0
|
||||
|
||||
# ret6 Filtered without a real reason
|
||||
assert len(error_items[5].children) == 0
|
||||
|
||||
def test_i_can_get_all_error_items(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
service = sheerka.services[SheerkaErrorManager.NAME]
|
||||
|
||||
simple_error = sheerka.new(BuiltinConcepts.UNKNOWN_CONCEPT, body=Concept("foo"))
|
||||
ret1 = sheerka.ret("Test1", False, simple_error)
|
||||
|
||||
inner_error = sheerka.err([ParsingError(), UnexpectedEofParsingError("EOF", 0)])
|
||||
sub_error_is_an_error = sheerka.new(BuiltinConcepts.NOT_FOR_ME, reason=inner_error)
|
||||
ret2 = sheerka.ret("Test3", False, sub_error_is_an_error)
|
||||
|
||||
multiple_level_errors1 = sheerka.err("Err1")
|
||||
multiple_level_errors2 = sheerka.err(multiple_level_errors1)
|
||||
multiple_level_errors3 = sheerka.err(multiple_level_errors2)
|
||||
ret3 = sheerka.ret("Test5", False, multiple_level_errors3)
|
||||
|
||||
all_error_items = list(service.get_all_error_items([ret1, ret2, ret3]))
|
||||
|
||||
assert len(all_error_items) == 8
|
||||
|
||||
def test_i_can_keep_the_correct_error_source(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
service = sheerka.services[SheerkaErrorManager.NAME]
|
||||
|
||||
simple_error = sheerka.new(BuiltinConcepts.UNKNOWN_CONCEPT, body=Concept("foo"))
|
||||
ret1 = sheerka.ret("Source1", False, simple_error)
|
||||
|
||||
sub_error_is_an_exception = sheerka.new(BuiltinConcepts.NOT_FOR_ME, reason=NotImplementedError())
|
||||
ret2 = sheerka.ret("Source2", False, sub_error_is_an_exception)
|
||||
|
||||
multiple_errors = sheerka.new(BuiltinConcepts.MULTIPLE_ERRORS, body=[ret1, ret2])
|
||||
ret3 = sheerka.ret("Source3", False, multiple_errors)
|
||||
|
||||
error_items = list(service.get_errors_items([ret3]))
|
||||
assert len(error_items) == 1
|
||||
assert error_items[0].source == "Source3"
|
||||
assert error_items[0].children[0].source == "Source1"
|
||||
assert error_items[0].children[1].source == "Source2"
|
||||
|
||||
def test_i_can_get_filtered_error_explanation(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
service = sheerka.services[SheerkaErrorManager.NAME]
|
||||
|
||||
simple_error = sheerka.new(BuiltinConcepts.UNKNOWN_CONCEPT, body=Concept("foo"))
|
||||
ret1 = sheerka.ret("Test1", False, simple_error)
|
||||
|
||||
sub_error_is_an_exception = sheerka.new(BuiltinConcepts.NOT_FOR_ME, reason=NotImplementedError())
|
||||
ret2 = sheerka.ret("Test2", False, sub_error_is_an_exception)
|
||||
context.add_values(return_values=[ret1, ret2])
|
||||
service.on_user_input_evaluated(context)
|
||||
|
||||
res = sheerka.get_last_errors(context)
|
||||
assert sheerka.isinstance(res, BuiltinConcepts.EXPLANATION)
|
||||
assert len(res.body) == 3
|
||||
|
||||
res = sheerka.get_last_errors(context, __type=BuiltinConcepts.UNKNOWN_CONCEPT)
|
||||
assert sheerka.isinstance(res, BuiltinConcepts.EXPLANATION)
|
||||
assert len(res.body) == 1
|
||||
|
||||
def test_i_cannot_recognize_error_when_no_error(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
res = sheerka.recognize_error(context, "Some error")
|
||||
assert sheerka.isinstance(res, BuiltinConcepts.NOT_FOUND)
|
||||
|
||||
def test_i_can_recognized_error_when_error_is_a_builtin_concept(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
service = sheerka.services[SheerkaErrorManager.NAME]
|
||||
|
||||
simple_error = sheerka.new(BuiltinConcepts.UNKNOWN_CONCEPT, body=Concept("foo"))
|
||||
ret1 = sheerka.ret("Test1", False, simple_error)
|
||||
context.add_values(return_values=[ret1])
|
||||
service.on_user_input_evaluated(context)
|
||||
|
||||
assert sheerka.recognize_error(context, __type=BuiltinConcepts.UNKNOWN_CONCEPT)
|
||||
assert sheerka.recognize_error(context, __type=UnknownConcept)
|
||||
assert sheerka.recognize_error(context, __type="UnknownConcept")
|
||||
assert sheerka.recognize_error(context, BuiltinConcepts.UNKNOWN_CONCEPT)
|
||||
assert sheerka.recognize_error(context, UnknownConcept)
|
||||
assert sheerka.recognize_error(context, "UnknownConcept")
|
||||
assert sheerka.recognize_error(context, f"self.name == '{BuiltinConcepts.UNKNOWN_CONCEPT}'")
|
||||
assert sheerka.recognize_error(context, f"get_type(self) == '{BuiltinConcepts.UNKNOWN_CONCEPT}'")
|
||||
|
||||
def test_i_can_recognized_error_when_error_is_a_error_ErrorObj(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
service = sheerka.services[SheerkaErrorManager.NAME]
|
||||
|
||||
simple_error = sheerka.new(BuiltinConcepts.ERROR, body=NoConditionFound())
|
||||
ret1 = sheerka.ret("Test1", False, simple_error)
|
||||
context.add_values(return_values=[ret1])
|
||||
service.on_user_input_evaluated(context)
|
||||
|
||||
assert sheerka.recognize_error(context, __type=NoConditionFound)
|
||||
assert sheerka.recognize_error(context, __type="NoConditionFound")
|
||||
|
||||
def test_i_cannot_recognize_unknown_concept_when_no_error(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
res = sheerka.has_unknown_concepts(context)
|
||||
assert sheerka.isinstance(res, BuiltinConcepts.NOT_FOUND)
|
||||
|
||||
def test_i_can_manage_direct_unknown_concept(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
service = sheerka.services[SheerkaErrorManager.NAME]
|
||||
exact_concept_parser = ExactConceptParser()
|
||||
|
||||
# a simple unknown concept
|
||||
ret = exact_concept_parser.parse(context, ParserInput("foo bar"))
|
||||
context.add_values(return_values=[ret])
|
||||
service.on_user_input_evaluated(context)
|
||||
|
||||
assert sheerka.has_unknown_concepts(context)
|
||||
assert sheerka.get_from_memory(context, LAST_UNKNOWN_CONCEPTS).obj == "foo bar"
|
||||
|
||||
def test_i_can_manage_multiple_direct_unknown_concept(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
service = sheerka.services[SheerkaErrorManager.NAME]
|
||||
exact_concept_parser = ExactConceptParser()
|
||||
|
||||
# a simple unknown concept
|
||||
ret1 = exact_concept_parser.parse(context, ParserInput("foo"))
|
||||
ret2 = exact_concept_parser.parse(context, ParserInput("bar"))
|
||||
context.add_values(return_values=[ret1, ret2])
|
||||
service.on_user_input_evaluated(context)
|
||||
|
||||
assert sheerka.has_unknown_concepts(context)
|
||||
assert sheerka.get_from_memory(context, LAST_UNKNOWN_CONCEPTS).obj == {"foo", "bar"}
|
||||
|
||||
@pytest.mark.parametrize("source, expected", [
|
||||
("foo bar", "foo"),
|
||||
("bar foo", "foo"),
|
||||
("foo bar baz", {"foo", "baz"}),
|
||||
("my foo bar my baz", {"my foo", "my baz"}),
|
||||
])
|
||||
def test_i_can_manage_unknown_concept_when_parts_are_recognized(self, source, expected):
|
||||
sheerka, context, foo = self.init_concepts("bar")
|
||||
service = sheerka.services[SheerkaErrorManager.NAME]
|
||||
exact_concept_parser = ExactConceptParser()
|
||||
|
||||
ret1 = exact_concept_parser.parse(context, ParserInput(source))
|
||||
context.add_values(return_values=[ret1])
|
||||
service.on_user_input_evaluated(context)
|
||||
|
||||
assert sheerka.has_unknown_concepts(context)
|
||||
assert sheerka.get_from_memory(context, LAST_UNKNOWN_CONCEPTS).obj == expected
|
||||
|
||||
def test_i_can_manage_multiple_unknown_concept_when_parts_are_recognized(self):
|
||||
sheerka, context, foo = self.init_concepts("bar")
|
||||
service = sheerka.services[SheerkaErrorManager.NAME]
|
||||
exact_concept_parser = ExactConceptParser()
|
||||
|
||||
ret1 = exact_concept_parser.parse(context, ParserInput("foo bar"))
|
||||
ret2 = exact_concept_parser.parse(context, ParserInput("my foo bar my baz"))
|
||||
context.add_values(return_values=[ret1, ret2])
|
||||
service.on_user_input_evaluated(context)
|
||||
|
||||
assert sheerka.has_unknown_concepts(context)
|
||||
assert sheerka.get_from_memory(context, LAST_UNKNOWN_CONCEPTS).obj == {"foo", "my foo", "my baz"}
|
||||
|
||||
def test_i_can_manage_unknown_concept_from_name_error(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
service = sheerka.services[SheerkaErrorManager.NAME]
|
||||
python_parser = PythonParser()
|
||||
python_evaluator = PythonEvaluator()
|
||||
|
||||
#
|
||||
ret = python_parser.parse(context, ParserInput("foo"))
|
||||
ret = python_evaluator.eval(context, ret)
|
||||
context.add_values(return_values=[ret])
|
||||
service.on_user_input_evaluated(context)
|
||||
|
||||
assert sheerka.has_unknown_concepts(context)
|
||||
assert sheerka.get_from_memory(context, LAST_UNKNOWN_CONCEPTS).obj == "foo"
|
||||
|
||||
def test_i_can_manage_unknown_concept_from_bnf_error(self):
|
||||
sheerka, context, quantify_x = self.init_concepts(
|
||||
Concept("quantify x", definition="('one' | 'two')=unit x").def_var("x"),
|
||||
create_new=True
|
||||
)
|
||||
service = sheerka.services[SheerkaErrorManager.NAME]
|
||||
bnf_node_parser = BnfNodeParser()
|
||||
|
||||
# a simple unknown concept
|
||||
ret = bnf_node_parser.parse(context, ParserInput("one foo"))
|
||||
|
||||
context.add_values(return_values=[ret])
|
||||
service.on_user_input_evaluated(context)
|
||||
|
||||
assert sheerka.has_unknown_concepts(context)
|
||||
assert sheerka.get_from_memory(context, LAST_UNKNOWN_CONCEPTS).obj == "foo"
|
||||
|
||||
|
||||
class TestFileBasedSheerkaErrorManger(TestUsingFileBasedSheerka):
|
||||
def test_i_can_remember_last_error(self):
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(message="TestingErrorManagement::get_last_errors()")
|
||||
service = sheerka.services[SheerkaErrorManager.NAME]
|
||||
|
||||
simple_error = sheerka.new(BuiltinConcepts.UNKNOWN_CONCEPT, body=Concept("foo"))
|
||||
ret1 = sheerka.ret("Test1", False, simple_error)
|
||||
|
||||
sub_error_is_an_exception = sheerka.new(BuiltinConcepts.NOT_FOR_ME, reason=NotImplementedError())
|
||||
ret2 = sheerka.ret("Test2", False, sub_error_is_an_exception)
|
||||
|
||||
context.add_values(return_values=[ret1, ret2])
|
||||
service.on_user_input_evaluated(context)
|
||||
new_context = self.get_context(sheerka)
|
||||
explanations = sheerka.get_last_errors(new_context)
|
||||
self.commit(context)
|
||||
|
||||
assert sheerka.isinstance(explanations, BuiltinConcepts.EXPLANATION)
|
||||
assert len(explanations.body) == 3
|
||||
assert service.last_detected_errors_event_id == context.event.get_digest()
|
||||
assert service.last_detected_errors_event_message == context.event.message
|
||||
assert service.current_errors_event_id == context.event.get_digest()
|
||||
assert service.current_errors_event_message == context.event.message
|
||||
|
||||
sheerka = self.new_sheerka_instance()
|
||||
service = sheerka.services[SheerkaErrorManager.NAME]
|
||||
assert service.last_detected_errors_event_id == context.event.get_digest()
|
||||
assert service.last_detected_errors_event_message == context.event.message
|
||||
assert service.current_errors_event_id == context.event.get_digest()
|
||||
assert service.current_errors_event_message == context.event.message
|
||||
|
||||
self.reset_hard_test_env()
|
||||
@@ -21,7 +21,9 @@ class TestSheerkaHistoryManager(TestUsingFileBasedSheerka):
|
||||
sheerka.evaluate_user_input("five")
|
||||
|
||||
h = list(service.history(-1)) # all
|
||||
assert h == [
|
||||
transformed_h = [hist(item.event.message, item.status) for item in h]
|
||||
|
||||
assert transformed_h == [
|
||||
hist("five", True),
|
||||
hist("def concept five as 5", True),
|
||||
hist("four", True),
|
||||
@@ -37,13 +39,15 @@ class TestSheerkaHistoryManager(TestUsingFileBasedSheerka):
|
||||
]
|
||||
|
||||
h = list(service.history(2))
|
||||
assert h == [
|
||||
transformed_h = [hist(item.event.message, item.status) for item in h]
|
||||
assert transformed_h == [
|
||||
hist("five", True),
|
||||
hist("def concept five as 5", True)
|
||||
]
|
||||
|
||||
h = list(service.history(2, 2))
|
||||
assert h == [
|
||||
transformed_h = [hist(item.event.message, item.status) for item in h]
|
||||
assert transformed_h == [
|
||||
hist("four", True),
|
||||
hist("def concept four as 4", True),
|
||||
]
|
||||
|
||||
@@ -3,11 +3,10 @@ from core.builtin_helpers import ensure_evaluated
|
||||
from core.concept import Concept
|
||||
from core.global_symbols import NotFound
|
||||
from core.sheerka.ExecutionContext import ExecutionContext
|
||||
from core.sheerka.services.SheerkaMemory import SheerkaMemory, MemoryObject
|
||||
|
||||
from core.sheerka.services.SheerkaMemory import MemoryObject, SheerkaMemory
|
||||
from tests.TestUsingFileBasedSheerka import TestUsingFileBasedSheerka
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
from tests.parsers.parsers_utils import CV, compare_with_test_object, CB
|
||||
from tests.parsers.parsers_utils import CB, CV, compare_with_test_object
|
||||
|
||||
|
||||
class TestSheerkaMemory(TestUsingMemoryBasedSheerka):
|
||||
@@ -92,6 +91,33 @@ class TestSheerkaMemory(TestUsingMemoryBasedSheerka):
|
||||
foo)}
|
||||
assert id(sheerka.get_from_memory(context, "a").obj) == id(foo)
|
||||
|
||||
# another object is appended
|
||||
bar = Concept("bar")
|
||||
sheerka.add_to_memory(context, "a", bar)
|
||||
assert sheerka.om.copy(SheerkaMemory.OBJECTS_ENTRY) == {
|
||||
"a": [
|
||||
MemoryObject(context.event.get_digest(), context.event.date.timestamp(), foo),
|
||||
MemoryObject(context.event.get_digest(), context.event.date.timestamp(), bar)
|
||||
]}
|
||||
|
||||
def test_i_can_set_and_retrieve_from_memory(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
assert sheerka.get_from_memory(context, "a") is NotFound
|
||||
|
||||
foo = Concept("foo")
|
||||
sheerka.set_in_memory(context, "a", foo)
|
||||
assert sheerka.om.copy(SheerkaMemory.OBJECTS_ENTRY) == {"a": MemoryObject(context.event.get_digest(),
|
||||
context.event.date.timestamp(),
|
||||
foo)}
|
||||
assert id(sheerka.get_from_memory(context, "a").obj) == id(foo)
|
||||
|
||||
# another object replace the first one
|
||||
sheerka.set_in_memory(context, "a", "foo")
|
||||
assert sheerka.om.copy(SheerkaMemory.OBJECTS_ENTRY) == {"a": MemoryObject(context.event.get_digest(),
|
||||
context.event.date.timestamp(),
|
||||
"foo")}
|
||||
|
||||
def test_i_can_use_memory_with_a_string(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ from dataclasses import dataclass
|
||||
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import NotFoundConcept
|
||||
from core.builtin_concepts_ids import BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
@@ -143,6 +144,28 @@ class TestSheerkaQueryManager(TestUsingMemoryBasedSheerka):
|
||||
res = sheerka.filter_objects(context, lst, mapping=lambda o: o.prop1, predicate="self is a concept")
|
||||
assert res == [lst[1], lst[3]]
|
||||
|
||||
def test_i_can_filter_objects_by_type(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
lst = [A("a11", "a12"), Concept("foo"), NotImplementedError(), NotFoundConcept()]
|
||||
|
||||
assert sheerka.filter_objects(context, lst, __type="A") == [lst[0]]
|
||||
assert sheerka.filter_objects(context, lst, __type="foo") == [lst[1]]
|
||||
|
||||
assert sheerka.filter_objects(context, lst, __type="NotImplementedError") == [lst[2]]
|
||||
assert sheerka.filter_objects(context, lst, __type=NotImplementedError) == [lst[2]]
|
||||
|
||||
assert sheerka.filter_objects(context, lst, __type=BuiltinConcepts.NOT_FOUND) == [lst[3]]
|
||||
assert sheerka.filter_objects(context, lst, __type=NotFoundConcept) == [lst[3]]
|
||||
assert sheerka.filter_objects(context, lst, __type="NotFoundConcept") == [lst[3]]
|
||||
|
||||
def test_empty_list_is_returned_when_nothing_is_found(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
lst = [A("a11", "a12")]
|
||||
|
||||
assert sheerka.filter_objects(context, lst, __type="foo") == []
|
||||
assert sheerka.filter_objects(context, [], __type="foo") == []
|
||||
assert sheerka.filter_objects(context, lst, predicate="self.name == 'bar'") == []
|
||||
|
||||
def test_i_must_select_object_property_using_string(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
|
||||
@@ -345,23 +345,23 @@ class TestSheerkaRuleManager(TestUsingMemoryBasedSheerka):
|
||||
("not __ret.status", "__ret", [NEGCOND("#__x_00__|__name__|'__ret.status'")]),
|
||||
("__ret and not __ret.status", "__ret",
|
||||
["#__x_00__|__name__|'__ret'", NEGCOND("#__x_01__|__name__|'__ret.status'")]),
|
||||
("not recognize(__ret.body, hello sheerka)", "__ret", ["#__x_00__|__name__|'__ret'",
|
||||
NCCOND(["#__x_00__|body|#__x_01__",
|
||||
"#__x_01__|__is_concept__|True",
|
||||
"#__x_01__|key|'hello __var__0'",
|
||||
"#__x_01__|a|'__sheerka__'"])]),
|
||||
("__ret and not __error", "__ret", ["#__x_00__|__name__|'__ret'", NEGCOND("#__x_01__|__name__|'__error'")]),
|
||||
("not recognize(self, hello sheerka)", "__ret", ["#__x_00__|__name__|'self'",
|
||||
NCCOND(["#__x_00__|__is_concept__|True",
|
||||
"#__x_00__|key|'hello __var__0'",
|
||||
"#__x_00__|a|'__sheerka__'"])]),
|
||||
# ("not recognize(__ret.body, hello sheerka)", "__ret", ["#__x_00__|__name__|'__ret'",
|
||||
# NCCOND(["#__x_00__|body|#__x_01__",
|
||||
# "#__x_01__|__is_concept__|True",
|
||||
# "#__x_01__|key|'hello __var__0'",
|
||||
# "#__x_01__|a|'__sheerka__'"])]),
|
||||
# ("not recognize(self, hello sheerka)", "__ret", ["#__x_00__|__name__|'self'",
|
||||
# NCCOND(["#__x_00__|__is_concept__|True",
|
||||
# "#__x_00__|key|'hello __var__0'",
|
||||
# "#__x_00__|a|'__sheerka__'"])]),
|
||||
])
|
||||
def test_i_can_get_rete_using_not(self, expression, bag_key, expected):
|
||||
sheerka, context, greetings, foo = self.init_test().with_concepts(
|
||||
Concept("greetings", definition="hello a", definition_type=DEFINITION_TYPE_DEF).def_var("a"),
|
||||
Concept("foo"),
|
||||
).unpack()
|
||||
parser = ExpressionParser(old_style=True)
|
||||
parser = ExpressionParser()
|
||||
expected_conditions = get_rete_conditions(*expected)
|
||||
|
||||
error_sink = ErrorSink()
|
||||
|
||||
@@ -25,7 +25,7 @@ class BaseTestSheerkaRuleManagerRulesCompilation(TestUsingMemoryBasedSheerka):
|
||||
|
||||
@staticmethod
|
||||
def get_conditions(context, expression):
|
||||
parser = ExpressionParser(old_style=True)
|
||||
parser = ExpressionParser()
|
||||
error_sink = ErrorSink()
|
||||
parser_input = ParserInput(expression)
|
||||
parser.reset_parser_input(parser_input, error_sink)
|
||||
@@ -927,7 +927,7 @@ class TestSheerkaRuleManagerRulesCompilationRecognizeConcept(BaseTestSheerkaRule
|
||||
Concept("my best friend"),
|
||||
create_new=True
|
||||
).unpack()
|
||||
parser = ExpressionParser(old_style=True)
|
||||
parser = ExpressionParser()
|
||||
expected = get_rete_conditions(*expected_as_list_of_str)
|
||||
|
||||
error_sink = ErrorSink()
|
||||
|
||||
+15
-156
@@ -3,14 +3,13 @@ import os
|
||||
import pytest
|
||||
|
||||
from conftest import SHEERKA_TEST_FOLDER
|
||||
from core.builtin_concepts import BuiltinConcepts, ReturnValueConcept, UnknownConcept, UserInputConcept
|
||||
from core.builtin_concepts import BuiltinConcepts, ReturnValueConcept, UserInputConcept
|
||||
from core.builtin_concepts_ids import AllBuiltinConcepts
|
||||
from core.concept import Concept, ConceptParts, PROPERTIES_TO_SERIALIZE, get_concept_attrs
|
||||
from core.global_symbols import NotInit
|
||||
from core.sheerka.Sheerka import BASE_NODE_PARSER_CLASS, Sheerka
|
||||
from core.sheerka.services.SheerkaConceptManager import SheerkaConceptManager, ValueNotFound
|
||||
from core.sheerka.services.SheerkaConceptManager import SheerkaConceptManager
|
||||
from core.tokenizer import Token, TokenKind
|
||||
from parsers.PythonParser import PythonErrorNode
|
||||
from tests.TestUsingFileBasedSheerka import TestUsingFileBasedSheerka
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
@@ -44,21 +43,25 @@ class TestSheerkaUsingMemoryBasedSheerka(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def test_i_can_list_builtin_concepts(self):
|
||||
sheerka = self.get_sheerka()
|
||||
builtins = list(sheerka.get_builtins_classes_as_dict())
|
||||
builtins, _ = sheerka.get_builtins_classes_as_dict()
|
||||
|
||||
assert str(BuiltinConcepts.ERROR) in builtins
|
||||
assert str(BuiltinConcepts.RETURN_VALUE) in builtins
|
||||
assert BuiltinConcepts.ERROR in builtins
|
||||
assert BuiltinConcepts.RETURN_VALUE in builtins
|
||||
|
||||
def test_i_can_get_a_builtin_concept_by_their_enum_or_the_string(self):
|
||||
"""
|
||||
Checks that a concept can be found its name
|
||||
even when there are variables in the name (ex 'hello + a' or 'a + b' )
|
||||
Also returns the mapping between concept name and specific class name
|
||||
:return:
|
||||
"""
|
||||
sheerka = self.get_sheerka()
|
||||
for key in sheerka.get_builtins_classes_as_dict():
|
||||
builtins_by_key, builtins_by_class_name = sheerka.get_builtins_classes_as_dict()
|
||||
for key in builtins_by_key:
|
||||
assert sheerka.get_by_key(key) is not None
|
||||
assert sheerka.get_by_key(str(key)) is not None
|
||||
|
||||
for k, v in builtins_by_class_name.items():
|
||||
assert type(sheerka.get_by_key(v)).__name__ == k
|
||||
|
||||
def test_i_cannot_get_when_key_is_none(self):
|
||||
sheerka = self.get_sheerka()
|
||||
@@ -98,7 +101,8 @@ class TestSheerkaUsingMemoryBasedSheerka(TestUsingMemoryBasedSheerka):
|
||||
assert ret.value == "value"
|
||||
|
||||
# check the others
|
||||
for key, concept_class in sheerka.get_builtins_classes_as_dict().items():
|
||||
builtins_by_key, _ = sheerka.get_builtins_classes_as_dict()
|
||||
for key, concept_class in builtins_by_key.items():
|
||||
assert isinstance(sheerka.get_by_key(key), concept_class)
|
||||
|
||||
def test_i_can_instantiate_a_builtin_concept_when_no_specific_class(self):
|
||||
@@ -426,151 +430,6 @@ 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(context, 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(context, 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(context, 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(context, 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(context, 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(context, [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(context, 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(context, 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(context, 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(context, ret_val, source="error source")
|
||||
assert errors_found == [python_error]
|
||||
|
||||
def test_i_can_filter_error_by_exception_name(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
from evaluators.PythonEvaluator import PythonEvalError
|
||||
name_error = NameError("foo")
|
||||
python_eval_error = PythonEvalError(name_error, "foo", None, None)
|
||||
error = sheerka.err([python_eval_error])
|
||||
ret_val = ReturnValueConcept("Test", False, error)
|
||||
|
||||
errors_found = sheerka.get_errors(context, ret_val, __type="NameError")
|
||||
assert errors_found == [name_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(context, 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(context, ret_val) == []
|
||||
|
||||
def test_i_can_add_and_remove_global_context_hints(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
@@ -592,7 +451,7 @@ class TestSheerkaUsingMemoryBasedSheerka(TestUsingMemoryBasedSheerka):
|
||||
).unpack()
|
||||
|
||||
res = sheerka.evaluate_user_input("eval foo", "testing_user")
|
||||
assert sheerka.isinstance(res[0].value, BuiltinConcepts.CONDITION_FAILED) # sanity check
|
||||
assert sheerka.isinstance(res[0].value.value, BuiltinConcepts.CONDITION_FAILED) # sanity check
|
||||
|
||||
sheerka.add_to_context(BuiltinConcepts.EVAL_GLOBAL_TRUTH_REQUESTED)
|
||||
res = sheerka.evaluate_user_input("eval foo", "testing_user")
|
||||
@@ -600,7 +459,7 @@ class TestSheerkaUsingMemoryBasedSheerka(TestUsingMemoryBasedSheerka):
|
||||
|
||||
sheerka.remove_fom_context(BuiltinConcepts.EVAL_GLOBAL_TRUTH_REQUESTED)
|
||||
res = sheerka.evaluate_user_input("eval foo", "testing_user")
|
||||
assert sheerka.isinstance(res[0].value, BuiltinConcepts.CONDITION_FAILED)
|
||||
assert sheerka.isinstance(res[0].value.value, BuiltinConcepts.CONDITION_FAILED)
|
||||
|
||||
|
||||
class TestSheerkaUsingFileBasedSheerka(TestUsingFileBasedSheerka):
|
||||
|
||||
@@ -1316,11 +1316,11 @@ class TestSheerkaOntology(TestUsingMemoryBasedSheerka):
|
||||
sheerka.create_new_rule(context, Rule(ACTION_TYPE_EXEC, "rule3", "id3.attr3 == 'value'", "True"))
|
||||
|
||||
sheerka.pop_ontology(context)
|
||||
assert rules_by_ontology_from_cache() == {'#unit_test#': {'10'}}
|
||||
assert ontologies_from_cache() == {'10': '#unit_test#'}
|
||||
assert rules_by_ontology_from_cache() == {'#unit_test#': {'11'}}
|
||||
assert ontologies_from_cache() == {'11': '#unit_test#'}
|
||||
|
||||
# check that the 'rule is deleted' events are raised
|
||||
assert events_raised == {'11', '12'}
|
||||
assert events_raised == {'12', '13'}
|
||||
|
||||
# def test_i_can_list_by_key_when_dictionaries(self):
|
||||
# sheerka = self.get_sheerka(cache_only=False)
|
||||
@@ -1664,6 +1664,6 @@ class TestSheerkaOntologyWithFileBasedSheerka(TestUsingFileBasedSheerka):
|
||||
rules_from_db = sheerka.om.self_cache_manager.sdp.get(SheerkaOntologyManager.RULES_BY_ONTOLOGY_ENTRY)
|
||||
del rules_from_db["__default__"]
|
||||
assert rules_from_db == {
|
||||
'#unit_test#': {'10'},
|
||||
'another ontology': {'13'},
|
||||
'new ontology': {'12'}}
|
||||
'#unit_test#': {'11'},
|
||||
'another ontology': {'14'},
|
||||
'new ontology': {'13'}}
|
||||
|
||||
@@ -49,7 +49,8 @@ class TestOneErrorEvaluator(TestUsingMemoryBasedSheerka):
|
||||
res = evaluator.eval(context, return_values)
|
||||
|
||||
assert not res.status
|
||||
assert res.body == "evaluators.one error"
|
||||
assert context.sheerka.isinstance(res.body, BuiltinConcepts.RETURN_VALUE)
|
||||
assert res.body.body == "evaluators.one error"
|
||||
assert len(res.parents) == 4
|
||||
|
||||
def test_unwanted_return_values_are_not_eaten(self):
|
||||
@@ -71,7 +72,8 @@ class TestOneErrorEvaluator(TestUsingMemoryBasedSheerka):
|
||||
res = evaluator.eval(context, return_values)
|
||||
|
||||
assert not res.status
|
||||
assert res.body == "evaluators.one error"
|
||||
assert context.sheerka.isinstance(res.body, BuiltinConcepts.RETURN_VALUE)
|
||||
assert res.body.body == "evaluators.one error"
|
||||
assert len(res.parents) == 4
|
||||
|
||||
assert a_successful_concept not in res.parents
|
||||
@@ -89,7 +91,7 @@ class TestOneErrorEvaluator(TestUsingMemoryBasedSheerka):
|
||||
assert evaluator.matches(context, return_values)
|
||||
res = evaluator.eval(context, return_values)
|
||||
assert not res.status
|
||||
assert res.body == false_1.body
|
||||
assert res.body.body == false_1.body
|
||||
assert res.parents == return_values
|
||||
|
||||
evaluator.reset()
|
||||
@@ -97,7 +99,7 @@ class TestOneErrorEvaluator(TestUsingMemoryBasedSheerka):
|
||||
assert evaluator.matches(context, return_values)
|
||||
res = evaluator.eval(context, return_values)
|
||||
assert not res.status
|
||||
assert res.body == filtered
|
||||
assert res.body.body == filtered
|
||||
assert res.parents == return_values
|
||||
|
||||
evaluator.reset()
|
||||
@@ -105,5 +107,5 @@ class TestOneErrorEvaluator(TestUsingMemoryBasedSheerka):
|
||||
assert evaluator.matches(context, return_values)
|
||||
res = evaluator.eval(context, return_values)
|
||||
assert not res.status
|
||||
assert res.body == false_1.body
|
||||
assert res.body.body == false_1.body
|
||||
assert res.parents == return_values
|
||||
|
||||
@@ -11,7 +11,7 @@ from core.sheerka.services.SheerkaExecute import ParserInput
|
||||
from core.tokenizer import Tokenizer
|
||||
from evaluators.PythonEvaluator import PythonEvaluator, PythonEvalError
|
||||
from parsers.BaseNodeParser import SourceCodeNode, SourceCodeWithConceptNode
|
||||
from parsers.FunctionParserOld import FunctionParserOld
|
||||
from parsers.FunctionParser import FunctionParser
|
||||
from parsers.PythonParser import PythonNode, PythonParser
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
from tests.parsers.parsers_utils import CB, compare_with_test_object
|
||||
@@ -318,7 +318,7 @@ class TestPythonEvaluator(TestUsingMemoryBasedSheerka):
|
||||
context = self.get_context()
|
||||
context.add_to_short_term_memory("get_obj_name", get_obj_name)
|
||||
|
||||
parsed = FunctionParserOld().parse(context, ParserInput("get_obj_name(r:|1:)"))
|
||||
parsed = FunctionParser().parse(context, ParserInput("get_obj_name(r:|1:)"))
|
||||
python_evaluator = PythonEvaluator()
|
||||
evaluated = python_evaluator.eval(context, parsed)
|
||||
|
||||
@@ -344,7 +344,7 @@ class TestPythonEvaluator(TestUsingMemoryBasedSheerka):
|
||||
context = self.get_context()
|
||||
context.add_to_short_term_memory("return_return_value", return_return_value)
|
||||
|
||||
parsed = FunctionParserOld().parse(context, ParserInput(method))
|
||||
parsed = FunctionParser().parse(context, ParserInput(method))
|
||||
python_evaluator = PythonEvaluator()
|
||||
evaluated = python_evaluator.eval(context, parsed)
|
||||
ret_val = return_return_value(expected_status)
|
||||
@@ -371,9 +371,9 @@ class TestPythonEvaluator(TestUsingMemoryBasedSheerka):
|
||||
|
||||
@pytest.mark.parametrize("parser, value", [
|
||||
(PythonParser(), "3"),
|
||||
(FunctionParserOld(), "3"),
|
||||
(FunctionParser(), "3"),
|
||||
(PythonParser(), 3),
|
||||
(FunctionParserOld(), 3),
|
||||
(FunctionParser(), 3),
|
||||
])
|
||||
def test_i_can_eval_unresolved_rules(self, parser, value):
|
||||
context = self.get_context()
|
||||
|
||||
@@ -9,6 +9,7 @@ from evaluators.ValidateConceptEvaluator import ValidateConceptEvaluator
|
||||
from parsers.BaseNodeParser import ConceptNode
|
||||
from parsers.BaseParser import BaseParser
|
||||
from parsers.BnfNodeParser import BnfNodeParser
|
||||
from parsers.ExactConceptParser import ExactConceptParser
|
||||
from parsers.SyaNodeParser import SyaNodeParser
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
from tests.evaluators.EvaluatorTestsUtils import p_ret_val, pr_ret_val, ret_val
|
||||
@@ -185,3 +186,15 @@ class TestValidateConceptEvaluator(TestUsingMemoryBasedSheerka):
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.FILTERED)
|
||||
assert res.body.body == ret_val.body.body
|
||||
|
||||
def test_i_can_eval_exact_parser_concepts(self):
|
||||
sheerka, context, explain_x = self.init_concepts(
|
||||
Concept("explain x", where="isinstance(x, int)").def_var("x")
|
||||
)
|
||||
evaluator = ValidateConceptEvaluator()
|
||||
|
||||
ret_val = ExactConceptParser().parse(context, ParserInput("explain 1"))[0]
|
||||
|
||||
assert evaluator.matches(context, ret_val)
|
||||
res = evaluator.eval(context, ret_val)
|
||||
assert sheerka.isinstance(res.body.body, explain_x)
|
||||
|
||||
@@ -166,7 +166,7 @@ as:
|
||||
|
||||
assert len(res) == 1
|
||||
assert not res[0].status
|
||||
assert sheerka.isinstance(res[0].value, BuiltinConcepts.CONCEPT_ALREADY_DEFINED)
|
||||
assert sheerka.isinstance(res[0].value.value, BuiltinConcepts.CONCEPT_ALREADY_DEFINED)
|
||||
|
||||
@pytest.mark.parametrize("text", [
|
||||
"",
|
||||
@@ -740,7 +740,7 @@ as:
|
||||
res = sheerka.evaluate_user_input("eval foobar") # where clause is forced
|
||||
assert len(res) == 1 # error
|
||||
assert not res[0].status
|
||||
assert sheerka.isinstance(res[0].body, BuiltinConcepts.CONDITION_FAILED)
|
||||
assert sheerka.isinstance(res[0].body.value, BuiltinConcepts.CONDITION_FAILED)
|
||||
|
||||
@pytest.mark.skip("Not ready for that")
|
||||
def test_i_can_manage_missing_variables_from_bnf_parsing(self):
|
||||
@@ -921,15 +921,15 @@ as:
|
||||
res = sheerka.evaluate_user_input("eval foo plus one")
|
||||
|
||||
assert not res[0].status
|
||||
assert context.sheerka.isinstance(res[0].body, BuiltinConcepts.CONCEPT_EVAL_ERROR)
|
||||
assert context.sheerka.isinstance(res[0].body.body, BuiltinConcepts.ERROR)
|
||||
assert context.sheerka.isinstance(res[0].body.body, BuiltinConcepts.CONCEPT_EVAL_ERROR)
|
||||
assert context.sheerka.isinstance(res[0].body.body.body, BuiltinConcepts.ERROR)
|
||||
|
||||
error0 = res[0].body.body.body[0]
|
||||
error0 = res[0].body.body.body.body[0]
|
||||
assert isinstance(error0, PythonEvalError)
|
||||
assert isinstance(error0.error, TypeError)
|
||||
assert error0.error.args[0] == "unsupported operand type(s) for +: 'Concept' and 'int'"
|
||||
|
||||
error1 = res[0].body.body.body[1]
|
||||
error1 = res[0].body.body.body.body[1]
|
||||
assert isinstance(error1, PythonEvalError)
|
||||
assert isinstance(error1.error, TypeError)
|
||||
assert error1.error.args[0] == 'can only concatenate str (not "int") to str'
|
||||
|
||||
@@ -123,7 +123,7 @@ class TestSheerkaNonRegMemory2(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert len(res) == 1
|
||||
assert not res[0].status
|
||||
assert isinstance(res[0].body, ConceptEvalError)
|
||||
assert isinstance(res[0].body.body, ConceptEvalError)
|
||||
|
||||
def test_74_keyword_parameters_are_no_longer_recognized_when_a_concept_that_redefines_equality_is_created(self):
|
||||
init = [
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
from core.builtin_concepts_ids import BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from core.sheerka.services.SheerkaErrorManager import SheerkaErrorManager
|
||||
from core.utils import no_color_str
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
@@ -200,4 +204,39 @@ two: (1002)two
|
||||
assert captured.out == """DebugItem(type=vars, setting=Sya.parsers.*, context_id=45, debug_id=None, context_children=False, debug_children=False (enabled=True))
|
||||
DebugItem(type=concepts, setting=c:|1015.*.*, context_id=13, debug_id=None, context_children=True, debug_children=False (enabled=True))
|
||||
DebugItem(type=rules, setting=Out.*.*, context_id=None, debug_id=None, context_children=False, debug_children=False (enabled=True))
|
||||
"""
|
||||
|
||||
def test_i_can_display_errors(self, capsys):
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(message="xxxTESTxxx::get_last_errors()")
|
||||
service = sheerka.services[SheerkaErrorManager.NAME]
|
||||
|
||||
simple_error = sheerka.new(BuiltinConcepts.UNKNOWN_CONCEPT, body=Concept("foo"))
|
||||
ret1 = sheerka.ret("Test1", False, simple_error)
|
||||
|
||||
multiple_level_errors1 = sheerka.err("Err1")
|
||||
multiple_level_errors2 = sheerka.err(multiple_level_errors1)
|
||||
multiple_level_errors3 = sheerka.err(multiple_level_errors2)
|
||||
ret2 = sheerka.ret("Test5", False, multiple_level_errors3)
|
||||
|
||||
context.add_values(return_values=[ret1, ret2])
|
||||
service.on_user_input_evaluated(context)
|
||||
|
||||
sheerka.enable_process_return_values = True
|
||||
sheerka.evaluate_user_input("get_last_errors(level=0)")
|
||||
|
||||
captured = capsys.readouterr()
|
||||
colorless_captured = no_color_str(captured.out)
|
||||
assert colorless_captured == """xxx : xxxTESTxxx::get_last_errors()
|
||||
[ 0] Test1 (47)__UNKNOWN_CONCEPT: (None)foo
|
||||
[ 1] Test5 (46)__ERROR: (46)__ERROR: (46)__ERROR: Err1
|
||||
"""
|
||||
|
||||
sheerka.evaluate_user_input("get_last_errors(id=1, depth=3)")
|
||||
captured = capsys.readouterr()
|
||||
colorless_captured = no_color_str(captured.out)
|
||||
assert colorless_captured == """xxx : xxxTESTxxx::get_last_errors()
|
||||
[ 1] Test5 (46)__ERROR: (46)__ERROR: (46)__ERROR: Err1
|
||||
[ 2] Test5 (46)__ERROR: (46)__ERROR: Err1
|
||||
[ 3] Test5 (46)__ERROR: Err1
|
||||
"""
|
||||
|
||||
@@ -10,12 +10,10 @@ from core.tokenizer import Token, TokenKind, Tokenizer
|
||||
from core.utils import get_text_from_tokens, str_concept, tokens_index
|
||||
from parsers.BaseExpressionParser import AndNode, BinaryNode, ComparisonNode, ComparisonType, Comprehension, \
|
||||
FunctionNode, \
|
||||
FunctionParameter, \
|
||||
ListComprehensionNode, ListNode, NameExprNode, \
|
||||
NotNode, OrNode, SequenceNode, VariableNode, t_comma
|
||||
from parsers.BaseNodeParser import ConceptNode, RuleNode, SourceCodeNode, SourceCodeWithConceptNode, \
|
||||
UnrecognizedTokensNode
|
||||
from parsers.FunctionParserOld import FunctionNodeOld
|
||||
from parsers.PythonParser import PythonNode
|
||||
from sheerkapython.python_wrapper import sheerka_globals
|
||||
from sheerkarete.common import V
|
||||
@@ -387,99 +385,6 @@ class LC(ExprTestObj): # for List Comprehension node
|
||||
return ListComprehensionNode(start, end, full_text_as_tokens[start: end + 1], element, comprehensions)
|
||||
|
||||
|
||||
class FNOld(ExprTestObj):
|
||||
"""
|
||||
Test class only
|
||||
It matches with FunctionNodeOld but with less constraints
|
||||
|
||||
Thereby,
|
||||
FNOld("first", "last", ["param1," ...]) can be compared to
|
||||
FunctionNodeOld(NameExprNode("first"), NameExprNode("second"), [FunctionParameter(NamesNodes("param1"), NamesNodes(", ")])
|
||||
|
||||
Note that FunctionParameter can easily be defined with a single string
|
||||
* "param" -> FunctionParameter(NameExprNode("param"), None)
|
||||
* "param, " -> FunctionParameter(NameExprNode("param"), NameExprNode(", "))
|
||||
For more complicated situations, you can use a tuple (value, sep) to define the value part and the separator part
|
||||
"""
|
||||
|
||||
def __init__(self, first, last, parameters):
|
||||
self.first = first
|
||||
self.last = last
|
||||
self.parameters = []
|
||||
for param in parameters:
|
||||
if isinstance(param, tuple):
|
||||
self.parameters.append(param)
|
||||
elif isinstance(param, str) and (pos := param.find(",")) != -1:
|
||||
self.parameters.append((param[:pos], param[pos:]))
|
||||
else:
|
||||
self.parameters.append((param, None))
|
||||
|
||||
def __repr__(self):
|
||||
res = self.first
|
||||
for param in self.parameters:
|
||||
if param[1]:
|
||||
res += f"{param[0]}{param[1]} "
|
||||
else:
|
||||
res += f"{param[0]}"
|
||||
return res + self.last
|
||||
|
||||
def __eq__(self, other):
|
||||
if id(self) == id(other):
|
||||
return True
|
||||
|
||||
if isinstance(other, FNOld):
|
||||
return self.first == other.first and self.last == other.last and self.parameters == other.parameters
|
||||
|
||||
return False
|
||||
|
||||
def __hash__(self):
|
||||
return hash((self.first, self.last, self.parameters))
|
||||
|
||||
def transform_real_obj(self, other, get_test_obj_delegate):
|
||||
if isinstance(other, FNOld):
|
||||
return other
|
||||
|
||||
if isinstance(other, FunctionNodeOld):
|
||||
params = []
|
||||
for self_parameter, other_parameter in zip(self.parameters, other.parameters):
|
||||
if isinstance(self_parameter[0], str):
|
||||
value = other_parameter.value.value
|
||||
else:
|
||||
value = get_test_obj_delegate(other_parameter.value, self_parameter[0])
|
||||
sep = other_parameter.separator.value if other_parameter.separator else None
|
||||
params.append((value, sep))
|
||||
|
||||
return FNOld(other.first.value, other.last.value, params)
|
||||
|
||||
raise Exception(f"Expecting FunctionNodeOld but received {other=}")
|
||||
|
||||
def get_expr_node(self, full_text_as_tokens, default_expr_obj):
|
||||
start, end = self.get_pos_from_source(self.first, full_text_as_tokens)
|
||||
first = NameExprNode(start, end, full_text_as_tokens[start: end + 1])
|
||||
start, end = self.get_pos_from_source(self.last, full_text_as_tokens)
|
||||
last = NameExprNode(start, end, full_text_as_tokens[start: end + 1])
|
||||
parameters = []
|
||||
for param_value, sep in self.parameters:
|
||||
if isinstance(param_value, str):
|
||||
start, end = self.get_pos_from_source(param_value, full_text_as_tokens)
|
||||
param_as_expr_node = NameExprNode(start, end, full_text_as_tokens[start: end + 1])
|
||||
else:
|
||||
param_as_expr_node = param_value.get_expr_node(full_text_as_tokens, default_expr_obj)
|
||||
|
||||
if sep:
|
||||
sep_tokens = Tokenizer(sep, yield_eof=False)
|
||||
start = param_as_expr_node.end + 1
|
||||
end = start + len(list(sep_tokens)) - 1
|
||||
sep_as_expr_node = NameExprNode(start, end, full_text_as_tokens[start: end + 1])
|
||||
else:
|
||||
sep_as_expr_node = None
|
||||
|
||||
parameters.append(FunctionParameter(param_as_expr_node, sep_as_expr_node))
|
||||
|
||||
start, end = first.start, last.end
|
||||
return FunctionNodeOld(start, end, full_text_as_tokens[start: end + 1], first, last, parameters)
|
||||
|
||||
|
||||
class HelperWithPos:
|
||||
def __init__(self, start=None, end=None):
|
||||
self.start = start
|
||||
|
||||
@@ -9,6 +9,7 @@ from core.global_symbols import NotInit
|
||||
from core.sheerka.services.SheerkaConceptManager import SheerkaConceptManager
|
||||
from core.sheerka.services.SheerkaExecute import ParserInput
|
||||
from core.sheerka.services.SheerkaIsAManager import SheerkaIsAManager
|
||||
from core.tokenizer import Tokenizer
|
||||
from parsers.BaseNodeParser import NoMatchingTokenError
|
||||
from parsers.BnfDefinitionParser import BnfDefinitionParser
|
||||
from parsers.BnfNodeParser import BnfNodeFirstTokenVisitor, BnfNodeParser, ConceptExpression, Match, NonTerminalNode, \
|
||||
@@ -1075,6 +1076,44 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
expected = [CNC("foo", "one onyx", x=CC("one"))]
|
||||
self.validate_get_concepts_sequences(my_map, text, expected)
|
||||
|
||||
def test_i_can_match_regex_when_sub_parser_input(self):
|
||||
my_map = {
|
||||
"foo": self.bnf_concept("foo", RegExMatch("[a-f0-9]{4}")),
|
||||
}
|
||||
text = "begin 0af0 end"
|
||||
parser_input = ParserInput(text).reset()
|
||||
sub_parser = parser_input.sub_part(2, 3)
|
||||
|
||||
sheerka, context, parser = self.init_parser(my_map)
|
||||
|
||||
res = parser.parse(context, sub_parser)
|
||||
|
||||
assert res.status
|
||||
concept_nodes = res.body.body
|
||||
|
||||
expected = [CN("foo", "0af0")]
|
||||
actual, expected = tests.parsers.parsers_utils.prepare_nodes_comparison(my_map, text, concept_nodes, expected)
|
||||
assert actual == expected
|
||||
|
||||
def test_i_can_match_regex_when_from_tokens(self):
|
||||
my_map = {
|
||||
"foo": self.bnf_concept("foo", RegExMatch("[a-f0-9]{4}")),
|
||||
}
|
||||
text = "begin 0af0 end"
|
||||
tokens = list(Tokenizer(text))
|
||||
parser_input = ParserInput(None, tokens[2:4]).reset()
|
||||
|
||||
sheerka, context, parser = self.init_parser(my_map)
|
||||
|
||||
res = parser.parse(context, parser_input)
|
||||
|
||||
assert res.status
|
||||
concept_nodes = res.body.body
|
||||
|
||||
expected = [CN("foo", "0af0")]
|
||||
actual, expected = tests.parsers.parsers_utils.prepare_nodes_comparison(my_map, "0af0", concept_nodes, expected)
|
||||
assert actual == expected
|
||||
|
||||
def test_i_can_reuse_the_same_variable(self):
|
||||
# in this test, the variable appears several times, but only once in concept.compiled
|
||||
my_map = {
|
||||
@@ -1831,7 +1870,7 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.NOT_FOR_ME)
|
||||
assert res.body.reason == [NoMatchingTokenError(4)]
|
||||
assert res.body.reason == [NoMatchingTokenError(4, concept=foo)]
|
||||
|
||||
@pytest.mark.parametrize("text", [
|
||||
"one",
|
||||
@@ -1852,7 +1891,7 @@ class TestBnfNodeParser(TestUsingMemoryBasedSheerka):
|
||||
(Sequence(StrMatch("foo"), VariableExpression("x")), "foo one"),
|
||||
(Sequence(StrMatch("foo"), VariableExpression("x"), StrMatch("bar")), "foo one bar"),
|
||||
])
|
||||
def test_i_cannot_parse_variable_when_unrecognized_nodes(self, bnf, text):
|
||||
def test_i_cannot_parse_variable_when_unrecognized_nodes(self, bnf, text):
|
||||
sheerka, context, foo = self.init_test().with_concepts(
|
||||
self.bnf_concept("foo", Sequence(VariableExpression("x"), StrMatch("shoe")))
|
||||
).unpack()
|
||||
|
||||
@@ -16,7 +16,7 @@ from parsers.BnfNodeParser import OrderedChoice, ConceptExpression, StrMatch, Se
|
||||
from parsers.DefConceptParser import DefConceptParser, NameNode, SyntaxErrorNode, CannotHandleParsingError
|
||||
from parsers.DefConceptParser import UnexpectedTokenParsingError, DefConceptNode
|
||||
from parsers.ExpressionParser import ExpressionParser
|
||||
from parsers.FunctionParserOld import FunctionParserOld
|
||||
from parsers.FunctionParser import FunctionParser
|
||||
from parsers.PythonParser import PythonParser, PythonNode
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
from tests.parsers.parsers_utils import compute_expected_array, SCWC, compare_with_test_object, CIO
|
||||
@@ -77,7 +77,7 @@ def get_concept_part(part, use_expression=False):
|
||||
status=True,
|
||||
value=ParserResultConcept(
|
||||
source=part.source,
|
||||
parser=FunctionParserOld(),
|
||||
parser=FunctionParser(),
|
||||
value=nodes[0],
|
||||
try_parsed=nodes[0]))
|
||||
|
||||
|
||||
@@ -1,249 +0,0 @@
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from core.sheerka.services.SheerkaExecute import ParserInput
|
||||
from parsers.BaseNodeParser import SourceCodeWithConceptNode
|
||||
from parsers.BaseParser import ErrorSink
|
||||
from parsers.FunctionParserOld import FunctionParserOld
|
||||
from parsers.PythonParser import PythonErrorNode
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
from tests.parsers.parsers_utils import compute_expected_array, SCN, SCWC, CN, UTN, CNC, RN, FNOld, get_test_obj, \
|
||||
get_expr_node_from_test_node
|
||||
|
||||
cmap = {
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_var("unit"),
|
||||
"plus": Concept("a plus b").def_var("a").def_var("b"),
|
||||
}
|
||||
|
||||
|
||||
class TestFunctionParserOld(TestUsingMemoryBasedSheerka):
|
||||
shared_ontology = None
|
||||
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
init_test_helper = cls().init_test(cache_only=False, ontology="#TestFunctionParserOld#")
|
||||
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(context)
|
||||
|
||||
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 = FunctionParserOld()
|
||||
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)
|
||||
|
||||
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_cannot_parse_when_not_a_function(self):
|
||||
sheerka, context, parser = self.init_parser()
|
||||
res = parser.parse(context, ParserInput("not a function"))
|
||||
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.NOT_FOR_ME)
|
||||
|
||||
@pytest.mark.parametrize("expression, expected", [
|
||||
("func()", FNOld("func(", ")", [])),
|
||||
("concept(one)", FNOld("concept(", ")", ["one"])),
|
||||
("func(one)", FNOld("func(", ")", ["one"])),
|
||||
("func(a long two, 'three', ;:$*)", FNOld("func(", ")", ["a long two, ", "'three', ", ";:$*"])),
|
||||
("func(func1(one), two, func2(func3(), func4(three)))", FNOld("func(", (")", 4), [
|
||||
(FNOld("func1(", ")", ["one"]), ", "),
|
||||
"two, ",
|
||||
(FNOld("func2(", (")", 3), [
|
||||
(FNOld("func3(", (")", 1), []), ", "),
|
||||
(FNOld("func4(", (")", 2), ["three"]), None),
|
||||
]), None)
|
||||
])),
|
||||
("func(r:|1:)", FNOld("func(", ")", ["r:|1:"]))
|
||||
])
|
||||
def test_i_can_parse_function(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("text, expected", [
|
||||
("func()", SCN("func()")),
|
||||
(" func()", SCN("func()")),
|
||||
("func(one)", SCWC("func(", ")", CN("one"))),
|
||||
("func(one, unknown, two)", SCWC("func(", ")", CN("one"), ", ", UTN("unknown"), (", ", 1), CN("two"))),
|
||||
("func(one, twenty two)", SCWC("func(", ")", "one", ", ", CN("twenties", "twenty two"))),
|
||||
("func(one plus two, three)", SCWC("func(", ")", CNC("plus", a="one", b="two"), ", ", UTN("three"))),
|
||||
("func(func1(one), two)", SCWC("func(", (")", 1), SCWC("func1(", ")", "one"), ", ", "two"))
|
||||
])
|
||||
def test_i_can_parse(self, text, expected):
|
||||
sheerka, context, parser = self.init_parser()
|
||||
resolved_expected = compute_expected_array(cmap, text, [expected])[0]
|
||||
res = parser.parse(context, ParserInput(text))
|
||||
parser_result = res.body
|
||||
expression = res.body.body
|
||||
|
||||
assert res.status
|
||||
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
|
||||
transformed_expression = get_test_obj(expression, resolved_expected)
|
||||
assert transformed_expression == resolved_expected
|
||||
assert expression.python_node is not None
|
||||
assert expression.return_value is not None
|
||||
|
||||
def test_i_can_parse_when_multiple_results_when_requested(self):
|
||||
# the previous output was
|
||||
# [
|
||||
# SCWC("func(", ")", "one", ", ", "twenty ", "two"),
|
||||
# SCWC("func(", ")", "one", ", ", CN("twenties", "twenty two"))
|
||||
# ]
|
||||
# But the first one is now filtered out, as it's not a valid python function call
|
||||
sheerka, context, parser = self.init_parser()
|
||||
parser.longest_concepts_only = False
|
||||
text = "func(one, twenty two)"
|
||||
expected = [SCWC("func(", ")", "one", ", ", CN("twenties", "twenty two"))]
|
||||
resolved_expected = compute_expected_array(cmap, text, expected)
|
||||
|
||||
results = parser.parse(context, ParserInput(text))
|
||||
|
||||
assert len(results) == 2
|
||||
|
||||
res = results[0]
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.ERROR)
|
||||
assert len(res.body.body) == 1
|
||||
assert (res.body.body[0], PythonErrorNode)
|
||||
|
||||
res = results[1]
|
||||
parser_result = res.body
|
||||
expressions = res.body.body
|
||||
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
|
||||
transformed_expressions = get_test_obj(expressions, resolved_expected[0])
|
||||
assert transformed_expressions == resolved_expected[0]
|
||||
|
||||
def test_i_can_parse_when_the_parameter_is_not_a_concept(self):
|
||||
"""
|
||||
It's not a concept, but it can be a valid short term memory object
|
||||
:return:
|
||||
"""
|
||||
sheerka, context, parser = self.init_parser()
|
||||
text = "func(unknown_concept)"
|
||||
|
||||
res = parser.parse(context, ParserInput(text))
|
||||
expected = [SCWC("func(", ")", "unknown_concept")]
|
||||
resolved_expected = compute_expected_array(cmap, text, expected)
|
||||
|
||||
assert res.status
|
||||
parsed = res.body.body
|
||||
transformed_parsed = get_test_obj([parsed], resolved_expected)
|
||||
assert transformed_parsed == resolved_expected
|
||||
|
||||
def test_i_can_parse_when_the_concept_is_not_found(self):
|
||||
"""
|
||||
We do not check yet if it's a valid concept
|
||||
If you find a cheap way to do so, simply remove this test
|
||||
:return:
|
||||
"""
|
||||
sheerka, context, parser = self.init_parser()
|
||||
text = "func(c:|xxx:)"
|
||||
|
||||
res = parser.parse(context, ParserInput(text))
|
||||
|
||||
assert res.status
|
||||
|
||||
def test_i_can_parse_when_rules(self):
|
||||
sheerka, context, parser = self.init_parser()
|
||||
text = "func(r:|1:)"
|
||||
expected = SCWC("func(", ")", RN("1"))
|
||||
resolved_expected = compute_expected_array(cmap, text, [expected])[0]
|
||||
|
||||
res = parser.parse(context, ParserInput(text))
|
||||
parser_result = res.body
|
||||
expression = res.body.body
|
||||
transformed_expression = get_test_obj(expression, resolved_expected)
|
||||
|
||||
assert res.status
|
||||
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
|
||||
assert transformed_expression == resolved_expected
|
||||
assert expression.python_node is not None
|
||||
assert expression.return_value is not None
|
||||
|
||||
def test_i_can_parse_when_the_parameter_is_a_dynamic_concept(self):
|
||||
sheerka, context, parser = self.init_parser()
|
||||
|
||||
text = "func(ones)"
|
||||
res = parser.parse(context, ParserInput(text))
|
||||
|
||||
assert res.status
|
||||
assert isinstance(res.body.body, SourceCodeWithConceptNode)
|
||||
assert res.body.body.python_node.source == 'func(__C__ones__1001___PLURAL__C__)'
|
||||
assert "__C__ones__1001___PLURAL__C__" in res.body.body.python_node.objects
|
||||
|
||||
@pytest.mark.parametrize("text, expected_error_type", [
|
||||
("one", BuiltinConcepts.NOT_FOR_ME), # no function found
|
||||
("$*!", BuiltinConcepts.NOT_FOR_ME), # no function found
|
||||
("func(", BuiltinConcepts.ERROR), # function found, but incomplete
|
||||
("func(one", BuiltinConcepts.ERROR), # function found, but incomplete
|
||||
("func(one, two, ", BuiltinConcepts.ERROR), # function found, but incomplete
|
||||
("func(one) and func(two)", BuiltinConcepts.ERROR), # to many function
|
||||
("one func(one)", BuiltinConcepts.NOT_FOR_ME), # function not found ! (as it is not the first)
|
||||
("func(a=b, c)", BuiltinConcepts.ERROR), # function found, but cannot be parsed
|
||||
("func(one two)", BuiltinConcepts.ERROR), # function found, but cannot be parsed
|
||||
])
|
||||
def test_i_cannot_parse(self, text, expected_error_type):
|
||||
sheerka, context, parser = self.init_parser()
|
||||
|
||||
res = parser.parse(context, ParserInput(text))
|
||||
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(res.body, expected_error_type)
|
||||
|
||||
@pytest.mark.parametrize("sequence, expected", [
|
||||
(None, None),
|
||||
([["a"]], [["a"]]),
|
||||
([["a"], ["b", "c"]], [["a"]]),
|
||||
([["b", "c"], ["a"]], [["a"]]),
|
||||
([["b", "c"], ["a"], ["d", "e"], ["f"]], [["a"], ["f"]]),
|
||||
])
|
||||
def test_i_can_get_the_longest_concept_sequence(self, sequence, expected):
|
||||
assert FunctionParserOld.get_longest_concepts(sequence) == expected
|
||||
|
||||
def test_concepts_found_are_fully_initialized(self):
|
||||
sheerka, context, parser = self.init_parser()
|
||||
|
||||
res = parser.parse(context, ParserInput("func(one plus three)"))
|
||||
concept = res.body.body.nodes[0].concept
|
||||
|
||||
assert res.status
|
||||
assert isinstance(concept.get_compiled()["a"], Concept)
|
||||
|
||||
# three is not recognized,
|
||||
# so it will be transformed into list of ReturnValueConcept that indicate how to recognized it
|
||||
assert isinstance(concept.get_compiled()["b"], list)
|
||||
for item in concept.get_compiled()["b"]:
|
||||
assert sheerka.isinstance(item, BuiltinConcepts.RETURN_VALUE)
|
||||
@@ -9,8 +9,7 @@ from core.sheerka.Sheerka import RECOGNIZED_BY_KEY
|
||||
from core.sheerka.services.SheerkaExecute import ParserInput
|
||||
from core.tokenizer import Token, TokenKind, Tokenizer, comparable_tokens
|
||||
from core.utils import get_text_from_tokens
|
||||
from parsers.BaseExpressionParser import BinaryNode, FunctionNode, FunctionNodeOld, FunctionParameter, ListNode, \
|
||||
NameExprNode, VariableNode
|
||||
from parsers.BaseExpressionParser import BinaryNode, FunctionNode, ListNode, NameExprNode, VariableNode
|
||||
from parsers.BaseNodeParser import ConceptNode, SourceCodeNode, UnrecognizedTokensNode
|
||||
from parsers.PythonParser import PythonNode
|
||||
from parsers.SyaNodeParser import FunctionDetected, NoSyaConceptFound, NotEnoughParameters, SyaConceptParser, \
|
||||
@@ -1564,33 +1563,6 @@ class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
_stack, _expected = prepare_nodes_comparison(concepts_map, text, lexer_nodes, expected)
|
||||
assert _stack == _expected
|
||||
|
||||
def test_i_can_parse_when_function_old_style_expr_tokens(self):
|
||||
sheerka, context, parser = self.init_parser()
|
||||
|
||||
text = "one plus func(twenty two)"
|
||||
tokens = list(Tokenizer(text, yield_eof=False))
|
||||
fun_token = tokens[4]
|
||||
expr = FunctionNodeOld(4, 9, tokens[4:10],
|
||||
NameExprNode(4, 5, tokens[4:6]),
|
||||
NameExprNode(9, 9, tokens[9:10]),
|
||||
[FunctionParameter(NameExprNode(6, 8, tokens[6:9]), None)])
|
||||
tokens[4:] = [Token(TokenKind.EXPR, expr, fun_token.index, fun_token.line, fun_token.column)]
|
||||
res = parser.parse(context, ParserInput(None, tokens=tokens))
|
||||
wrapper = res.body
|
||||
lexer_nodes = res.body.body
|
||||
|
||||
assert res.status
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
|
||||
expected_ret_val = RETVAL("func(twenty two)", objects={"__o_00__": CIO("twenties", source="twenty two")})
|
||||
expected = [CNC("plus", a=CC("one"), b=[expected_ret_val], source=text)]
|
||||
_stack, _expected = prepare_nodes_comparison(cmap, text, lexer_nodes, expected)
|
||||
assert _stack == _expected
|
||||
|
||||
# check the metadata
|
||||
expected_concept = lexer_nodes[0].concept
|
||||
assert expected_concept.get_metadata().variables == [("a", "one"), ("b", "func(twenty two)")]
|
||||
|
||||
def test_i_can_parse_when_function_style_expr_tokens(self):
|
||||
sheerka, context, parser = self.init_parser()
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
from core.concept import Concept, ConceptParts
|
||||
from core.global_symbols import NotInit
|
||||
from core.rule import Rule, ACTION_TYPE_EXEC
|
||||
from core.rule import ACTION_TYPE_EXEC, Rule
|
||||
from core.sheerka.services.SheerkaExecute import ParserInput
|
||||
from parsers.BaseNodeParser import RuleNode
|
||||
from parsers.BnfNodeParser import BnfNodeParser
|
||||
from parsers.FunctionParserOld import FunctionParserOld
|
||||
from parsers.FunctionParser import FunctionParser
|
||||
from parsers.SyaNodeParser import SyaNodeParser
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
from tests.parsers.parsers_utils import get_test_obj, CNC, CC, CN, SCN, SCWC, UTN, RN, CB
|
||||
from tests.parsers.parsers_utils import CB, CC, CN, CNC, RN, SCN, get_test_obj
|
||||
|
||||
|
||||
class TestParsersUtils(TestUsingMemoryBasedSheerka):
|
||||
@@ -133,7 +133,7 @@ class TestParsersUtils(TestUsingMemoryBasedSheerka):
|
||||
def test_i_can_get_test_obj_when_SCN(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
parser = FunctionParserOld()
|
||||
parser = FunctionParser()
|
||||
scn = parser.parse(context, ParserInput("test()")).body.body
|
||||
|
||||
scn_res = get_test_obj(scn, SCN("", start=0, end=1))
|
||||
@@ -145,29 +145,6 @@ class TestParsersUtils(TestUsingMemoryBasedSheerka):
|
||||
assert isinstance(scn_res, SCN)
|
||||
assert scn_res == SCN("test()", start=None, end=None)
|
||||
|
||||
def test_i_can_get_test_obj_when_SCWC(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
parser = FunctionParserOld()
|
||||
scwc = parser.parse(context, ParserInput("test(param1, test2())")).body.body
|
||||
|
||||
scwc_res = get_test_obj(scwc, SCWC(UTN(""), UTN(""), UTN(""), UTN(""), SCN("", None, 0, 0)))
|
||||
assert isinstance(scwc_res, SCWC)
|
||||
expected = SCWC(UTN("test(", 0, 1),
|
||||
UTN(")", 8, 8),
|
||||
UTN("param1", 2, 2),
|
||||
UTN(", ", 3, 4),
|
||||
SCN("test2()", None, 5, 7))
|
||||
expected.start = 0
|
||||
expected.end = 8
|
||||
assert scwc_res == expected
|
||||
|
||||
assert isinstance(scwc_res.first, UTN)
|
||||
assert isinstance(scwc_res.last, UTN)
|
||||
assert isinstance(scwc_res.content[0], UTN)
|
||||
assert isinstance(scwc_res.content[1], UTN)
|
||||
assert isinstance(scwc_res.content[2], SCN)
|
||||
|
||||
def test_i_can_get_test_obj_when_RN(self):
|
||||
rule = Rule(ACTION_TYPE_EXEC, "test_rule", "True", "True")
|
||||
rn = RuleNode(rule, 1, 1, source="r:|xxx:")
|
||||
|
||||
@@ -87,7 +87,7 @@ class TestExprToConditionsVisitor(TestUsingMemoryBasedSheerka):
|
||||
|
||||
@staticmethod
|
||||
def get_conditions_from_expression(context, expression, parser=None):
|
||||
parser = parser or ExpressionParser(old_style=False)
|
||||
parser = parser or ExpressionParser()
|
||||
error_sink = ErrorSink()
|
||||
parser_input = ParserInput(expression)
|
||||
parser.reset_parser_input(parser_input, error_sink)
|
||||
@@ -293,6 +293,21 @@ class TestExprToConditionsVisitor(TestUsingMemoryBasedSheerka):
|
||||
resolved_expected_objects = {k: cmap[v].id for k, v in {"__o_00__": "two"}.items()}
|
||||
assert resolved_objects == resolved_expected_objects
|
||||
|
||||
def test_i_can_manage_possible_variable_indication(self):
|
||||
my_map = {
|
||||
"isa": Concept("x is an int").def_var("x") # no pre condition
|
||||
}
|
||||
sheerka, context = self.initialize_test(my_map)
|
||||
parser = ExpressionParser(known_variables={"x"})
|
||||
conditions = self.get_conditions_from_expression(context, "x is an int", parser)
|
||||
|
||||
python_source = conditions[0].return_value.body.body.source
|
||||
assert python_source == "call_concept(__o_00__, x=x)"
|
||||
|
||||
resolved_objects = {k: v.id for k, v in conditions[0].objects.items()}
|
||||
resolved_expected_objects = {k: my_map[v].id for k, v in {"__o_00__": "isa"}.items()}
|
||||
assert resolved_objects == resolved_expected_objects
|
||||
|
||||
def test_i_can_parse_when_variables_are_missing(self):
|
||||
sheerka, context = self.initialize_test()
|
||||
expression = "x equals 1"
|
||||
|
||||
@@ -17,7 +17,7 @@ class TestPythonExprVisitor(TestUsingMemoryBasedSheerka):
|
||||
|
||||
@staticmethod
|
||||
def get_expr_node(context, expression, parser=None):
|
||||
parser = parser or ExpressionParser(old_style=False)
|
||||
parser = parser or ExpressionParser()
|
||||
error_sink = ErrorSink()
|
||||
parser_input = ParserInput(expression)
|
||||
parser.reset_parser_input(parser_input, error_sink)
|
||||
|
||||
Reference in New Issue
Block a user