Refactored to use a single implementation for concept evaluation

This commit is contained in:
2019-12-21 15:08:06 +01:00
parent b24b858b81
commit 41e0885486
17 changed files with 920 additions and 644 deletions
+39 -130
View File
@@ -35,9 +35,12 @@ def test_i_can_match(ret_val, expected):
assert ConceptEvaluator().matches(context, ret_val) == expected
def test_concept_is_returned_when_no_body():
def test_i_can_evaluate_concept():
context = get_context()
concept = Concept(name="one").init_key()
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)
@@ -45,13 +48,20 @@ def test_concept_is_returned_when_no_body():
assert result.who == evaluator.name
assert result.status
assert result.value == concept
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_evaluated_when_python_body():
def test_body_is_returned_when_defined():
context = get_context()
concept = Concept(name="one", body="1").init_key()
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()
item = get_return_value(concept)
@@ -59,136 +69,23 @@ def test_body_is_evaluated_when_python_body():
assert result.who == evaluator.name
assert result.status
assert result.value == 1
assert result.value == "I have a value"
assert result.parents == [item]
def test_body_is_evaluated_when_concept_body():
def test_i_cannot_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()
concept_one = Concept(name="one").init_key()
context.sheerka.add_in_cache(concept_one)
concept_un = Concept(name="un", body="one").init_key()
context.obj = Concept("other").set_prop("foo", "'some_other_value'")
concept = Concept(name="foo")
evaluator = ConceptEvaluator()
item = get_return_value(concept_un)
result = evaluator.eval(context, item)
item = get_return_value(concept)
result = ConceptEvaluator().eval(context, item)
assert result.who == evaluator.name
assert result.status
assert result.value == concept_one
assert result.parents == [item]
def test_body_is_evaluated_when_concept_body_with_a_body():
"""
The concept refers to another concept which has a body
:return:
"""
context = get_context()
concept_one = Concept(name="one", body="1").init_key()
context.sheerka.add_in_cache(concept_one)
concept_un = Concept(name="un", body="one").init_key()
evaluator = ConceptEvaluator()
item = get_return_value(concept_un)
result = evaluator.eval(context, item)
assert result.who == evaluator.name
assert result.status
assert result.value == 1
assert result.parents == [item]
def test_i_can_evaluate_longer_chains():
context = get_context()
context.sheerka.add_in_cache(Concept(name="a", body="'a'").init_key())
context.sheerka.add_in_cache(Concept(name="b", body="a").init_key())
context.sheerka.add_in_cache(Concept(name="c", body="b").init_key())
concept_d = context.sheerka.add_in_cache(Concept(name="d", body="c").init_key())
evaluator = ConceptEvaluator()
item = get_return_value(concept_d)
result = evaluator.eval(context, item)
assert result.status
assert result.value == 'a'
def test_i_can_evaluate_longer_chains_2():
context = get_context()
concept_a = context.sheerka.add_in_cache(Concept(name="a").init_key())
context.sheerka.add_in_cache(Concept(name="b", body="a").init_key())
context.sheerka.add_in_cache(Concept(name="c", body="b").init_key())
concept_d = context.sheerka.add_in_cache(Concept(name="d", body="c").init_key())
evaluator = ConceptEvaluator()
item = get_return_value(concept_d)
result = evaluator.eval(context, item)
assert result.status
assert result.value == concept_a
def test_i_can_recognize_concept_properties():
"""
The concept 'plus' has some properties.
Let's check if they are recognized as concepts
:return:
"""
context = get_context()
concept_one = context.sheerka.add_in_cache(Concept(name="one").init_key())
concept_two = context.sheerka.add_in_cache(Concept(name="two").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 result.status
assert context.sheerka.isinstance(result.value, concept_plus)
assert result.value.props["a"].value == concept_one
assert result.value.props["b"].value == concept_two
def test_i_can_recognize_concept_properties_with_body():
"""
The concept 'plus' has some properties.
Let's check if they are recognized as concepts with Python code
:return:
"""
context = get_context()
context.sheerka.add_in_cache(Concept(name="one", body="1").init_key())
context.sheerka.add_in_cache(Concept(name="two", body="2").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 result.status
assert context.sheerka.isinstance(result.value, concept_plus)
assert result.value.props["a"].value == 1
assert result.value.props["b"].value == 2
def test_i_can_recognize_concept_properties_with_body_when_concept_has_a_body():
context = get_context()
context.sheerka.add_in_cache(Concept(name="one", body="1").init_key())
context.sheerka.add_in_cache(Concept(name="two", body="2").init_key())
concept_plus = context.sheerka.add_in_cache(Concept(name="a plus b", body="a + 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 result.status
assert result.value == 3
assert not result.status
assert context.sheerka.isinstance(result.value, BuiltinConcepts.NOT_FOR_ME)
def test_i_cannot_recognize_a_concept_if_one_of_the_prop_is_unknown():
@@ -203,7 +100,19 @@ def test_i_cannot_recognize_a_concept_if_one_of_the_prop_is_unknown():
result = evaluator.eval(context, item)
assert not result.status
assert context.sheerka.isinstance(result.value, BuiltinConcepts.PROPERTY_EVAL_ERROR)
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