import pytest from core.builtin_concepts import ReturnValueConcept, ParserResultConcept, BuiltinConcepts from core.concept import Concept, ConceptParts from core.sheerka import Sheerka, ExecutionContext from evaluators.ConceptEvaluator import ConceptEvaluator from parsers.ExactConceptParser import ExactConceptParser from sdp.sheerkaDataProvider import Event def get_context(): sheerka = Sheerka(skip_builtins_in_db=True) sheerka.initialize("mem://") return ExecutionContext("test", Event(), sheerka) def get_return_value(concept, source=None): return ReturnValueConcept( "some_name", True, ParserResultConcept(parser=ExactConceptParser(), source=source or concept.name, value=concept, try_parsed=concept)) @pytest.mark.parametrize("ret_val, expected", [ (ReturnValueConcept("some_name", True, ParserResultConcept(value=Concept())), True), (ReturnValueConcept("some_name", False, ParserResultConcept(value=Concept())), False), (ReturnValueConcept("some_name", True, ParserResultConcept(value="Not a concept")), False), (ReturnValueConcept("some_name", True, Concept()), False), ]) def test_i_can_match(ret_val, expected): context = get_context() assert ConceptEvaluator().matches(context, ret_val) == expected def test_i_can_evaluate_concept(): context = get_context() concept = Concept(name="foo", where="1", pre="2", post="3").def_prop("a", "4").def_prop("b", "5") evaluator = ConceptEvaluator() item = get_return_value(concept) result = evaluator.eval(context, item) assert result.who == evaluator.name assert result.status assert result.value.name == "foo" assert result.value.get_metadata_value(ConceptParts.WHERE) == 1 assert result.value.get_metadata_value(ConceptParts.PRE) == 2 assert result.value.get_metadata_value(ConceptParts.POST) == 3 assert result.value.get_prop("a") == 4 assert result.value.get_prop("b") == 5 assert result.value.key == "foo" assert result.parents == [item] def test_body_is_returned_when_defined_and_requested(): context = get_context() concept = Concept(name="foo", body="'I have a value'", where="1", pre="2", post="3").set_prop("a", "4").set_prop("b", "5") evaluator = ConceptEvaluator(return_body=True) item = get_return_value(concept) result = evaluator.eval(context, item) assert result.who == evaluator.name assert result.status assert result.value == "I have a value" assert result.parents == [item] def test_body_is_not_returned_if_not_requested(): context = get_context() concept = Concept(name="foo", body="'I have a value'", where="1", pre="2", post="3").set_prop("a", "4").set_prop("b", "5") evaluator = ConceptEvaluator(return_body=False) # which is the default behaviour item = get_return_value(concept) result = evaluator.eval(context, item) assert result.who == evaluator.name assert result.status assert result.value == concept assert result.parents == [item] def test_i_can_eval_if_with_the_same_name_is_defined_in_the_context(): # If we evaluate Concept("foo", body="a").set_prop("a", "'property_a'") # ConceptEvaluator will be called to resolve 'a' while we know that 'a' refers to the string 'property_a' context = get_context() context.obj = Concept("other").set_prop("foo", "'some_other_value'") concept = Concept(name="foo") item = get_return_value(concept) result = ConceptEvaluator().eval(context, item) assert result.status assert result.value == "'some_other_value'" def test_i_cannot_recognize_a_concept_if_one_of_the_prop_is_unknown(): context = get_context() context.sheerka.add_in_cache(Concept(name="one").init_key()) concept_plus = context.sheerka.add_in_cache(Concept(name="a plus b") .def_prop("a", "one") .def_prop("b", "two").init_key()) evaluator = ConceptEvaluator() item = get_return_value(concept_plus) result = evaluator.eval(context, item) assert not result.status assert context.sheerka.isinstance(result.value, BuiltinConcepts.CONCEPT_EVAL_ERROR) assert result.value.property_name == "b" assert context.sheerka.isinstance(result.value.error, BuiltinConcepts.TOO_MANY_ERRORS) assert result.value.concept == concept_plus def test_that_error_concepts_are_transformed_into_errors_only_if_the_key_is_different(): context = get_context() error_concept = context.sheerka.new(BuiltinConcepts.ERROR) item = get_return_value(error_concept) result = ConceptEvaluator().eval(context, item) assert not context.sheerka.is_success(error_concept) # it's indeed an error assert result.status assert result.value == error_concept