import pytest from core.builtin_concepts import ReturnValueConcept, ParserResultConcept, BuiltinConcepts from core.concept import Concept from core.sheerka import Sheerka, ExecutionContext from evaluators.ConceptEvaluator import ConceptEvaluator from parsers.BaseParser import BaseParser 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").set_prop("a", "4").set_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 == Concept(name="foo", where=1, pre=2, post=3).set_prop("a", 4).set_prop("b", 5).init_key() 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") .set_prop("a", "one") .set_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