First implementation of questions management
This commit is contained in:
@@ -284,6 +284,49 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
assert evaluated.get_value("prop") == 2
|
||||
|
||||
def test_i_can_evaluate_when_body_is_a_concept_with_its_own_variables(self):
|
||||
sheerka, context, plus, add = self.init_concepts(
|
||||
Concept("a plus b", body="a + b").def_var("a").def_var("b"),
|
||||
Concept("add a b", body="a plus b").def_var("a").def_var("b"),
|
||||
eval_body=True)
|
||||
|
||||
add_instance = self.get_concept_instance(sheerka, add, a="1", b="2")
|
||||
|
||||
evaluated = sheerka.evaluate_concept(context, add_instance)
|
||||
|
||||
assert evaluated.key == add_instance.key
|
||||
assert evaluated.metadata.is_evaluated
|
||||
assert sheerka.objvalue(evaluated) == 3
|
||||
|
||||
def test_i_can_evaluate_when_body_is_a_concept_with_its_own_variables_and_different_names(self):
|
||||
sheerka, context, plus, add = self.init_concepts(
|
||||
Concept("a plus b", body="a + b").def_var("a").def_var("b"),
|
||||
Concept("add x y", body="x plus y").def_var("x").def_var("y"),
|
||||
eval_body=True)
|
||||
|
||||
add_instance = self.get_concept_instance(sheerka, add, x="1", y="2")
|
||||
|
||||
evaluated = sheerka.evaluate_concept(context, add_instance)
|
||||
|
||||
assert evaluated.key == add_instance.key
|
||||
assert evaluated.metadata.is_evaluated
|
||||
assert sheerka.objvalue(evaluated) == 3
|
||||
|
||||
def test_i_can_evaluate_when_body_is_a_concept_with_its_own_variables_multiple_levels(self):
|
||||
sheerka, context, plus, add, inc = self.init_concepts(
|
||||
Concept("a plus b", body="a + b").def_var("a").def_var("b"),
|
||||
Concept("add x y", body="x plus y").def_var("x").def_var("y"),
|
||||
Concept("inc number", body="add number 1").def_var("number"),
|
||||
eval_body=True)
|
||||
|
||||
inc_instance = self.get_concept_instance(sheerka, inc, number="1")
|
||||
|
||||
evaluated = sheerka.evaluate_concept(context, inc_instance)
|
||||
|
||||
assert evaluated.key == inc_instance.key
|
||||
assert evaluated.metadata.is_evaluated
|
||||
assert sheerka.objvalue(evaluated) == 2
|
||||
|
||||
def test_i_can_reference_sheerka(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
@@ -354,21 +397,24 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert evaluated.key == concept.init_key().key
|
||||
|
||||
@pytest.mark.parametrize("where_clause, expected, expected_body", [
|
||||
("True", True, BuiltinConcepts.NOT_INITIALIZED),
|
||||
("False", False, BuiltinConcepts.NOT_INITIALIZED),
|
||||
("self < 10", False, 10),
|
||||
("self < 11", True, 10),
|
||||
("a < 20", False, BuiltinConcepts.NOT_INITIALIZED),
|
||||
("a > 19", True, BuiltinConcepts.NOT_INITIALIZED),
|
||||
("a + self > 20", True, 10),
|
||||
@pytest.mark.parametrize("where_clause, expected, expected_prop, expected_body", [
|
||||
("True", True, None, BuiltinConcepts.NOT_INITIALIZED),
|
||||
("False", False, ConceptParts.WHERE, BuiltinConcepts.NOT_INITIALIZED),
|
||||
("self < 10", False, ConceptParts.WHERE, 10),
|
||||
("self < 11", True, None, 10),
|
||||
("a < 20", False, "a", BuiltinConcepts.NOT_INITIALIZED),
|
||||
("a > 19", True, None, BuiltinConcepts.NOT_INITIALIZED),
|
||||
("a + self > 20", True, None, 10),
|
||||
("a + self < 20", False, ConceptParts.WHERE, 10),
|
||||
])
|
||||
def test_i_can_evaluate_simple_where(self, where_clause, expected, expected_body):
|
||||
def test_i_can_evaluate_simple_where(self, where_clause, expected, expected_prop, expected_body):
|
||||
# We check that the WHERE condition is correctly evaluated
|
||||
# We also check that the body is evaluated only when it's mandatory
|
||||
|
||||
sheerka, context, concept = self.init_concepts(
|
||||
Concept("foo", body="10", where=where_clause).def_var("a", "20"),
|
||||
eval_body=False, # to check when the evaluation is forced
|
||||
eval_where=True,
|
||||
)
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, False, True), concept, eval_body=False)
|
||||
@@ -380,7 +426,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CONDITION_FAILED)
|
||||
assert evaluated.body == where_clause
|
||||
assert evaluated.concept == concept
|
||||
assert evaluated.prop == ConceptParts.WHERE
|
||||
assert evaluated.prop == expected_prop
|
||||
assert concept.body == expected_body
|
||||
|
||||
def test_i_can_evaluate_where_when_using_other_concept(self):
|
||||
@@ -402,6 +448,116 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, False, False), concept)
|
||||
assert evaluated.key == concept.key
|
||||
|
||||
def test_i_can_apply_intermediate_where_condition_using_python(self):
|
||||
sheerka, context, one_1, one_str, plus = self.init_concepts(
|
||||
Concept("one", body="1"),
|
||||
Concept("one", body="'one'"),
|
||||
Concept("a plus b", body="a + b", where="isinstance(a, int)").def_var("a", "one").def_var("b", "2"),
|
||||
eval_body=True,
|
||||
eval_where=True,
|
||||
)
|
||||
|
||||
evaluated = sheerka.evaluate_concept(context, plus)
|
||||
assert evaluated.key == plus.key
|
||||
assert evaluated.body == 3
|
||||
|
||||
def test_i_can_apply_intermediate_where_condition_when_multiple_variables_using_python(self):
|
||||
sheerka, context, one_1, one_str, two_2, two_str, plus = self.init_concepts(
|
||||
Concept("one", body="1"),
|
||||
Concept("one", body="'one'"),
|
||||
Concept("two", body="2"),
|
||||
Concept("two", body="'two'"),
|
||||
Concept("a plus b",
|
||||
body="a + b",
|
||||
where="isinstance(a, int) and isinstance(b, int)").def_var("a", "one").def_var("b", "two"),
|
||||
eval_body=True,
|
||||
eval_where=True,
|
||||
)
|
||||
|
||||
evaluated = sheerka.evaluate_concept(context, plus)
|
||||
assert evaluated.key == plus.key
|
||||
assert evaluated.body == 3
|
||||
|
||||
def test_i_can_apply_intermediate_where_condition_using_other_concepts(self):
|
||||
sheerka, context, one_1, one_str, is_an_int, plus = self.init_concepts(
|
||||
Concept("one", body="1"),
|
||||
Concept("one", body="'one'"),
|
||||
Concept("x is an int", body="isinstance(x, int)").def_var("x"),
|
||||
Concept("a plus b", body="a + b", where="a is an int").def_var("a", "one").def_var("b", "2"),
|
||||
eval_body=True,
|
||||
eval_where=True,
|
||||
)
|
||||
|
||||
evaluated = sheerka.evaluate_concept(context, plus)
|
||||
assert evaluated.key == plus.key
|
||||
assert evaluated.body == 3
|
||||
|
||||
def test_i_can_apply_intermediate_where_condition_when_multiple_levels(self):
|
||||
sheerka, context, one_1, one_str, is_an_int, is_an_integer, plus = self.init_concepts(
|
||||
Concept("one", body="1"),
|
||||
Concept("one", body="'one'"),
|
||||
Concept("x is an int", body="isinstance(x, int)").def_var("x"),
|
||||
Concept("y is an integer", body="y is an int").def_var("y"),
|
||||
Concept("a plus b", body="a + b", where="a is an integer").def_var("a", "one").def_var("b", "2"),
|
||||
eval_body=True,
|
||||
eval_where=True,
|
||||
)
|
||||
|
||||
evaluated = sheerka.evaluate_concept(context, plus)
|
||||
assert evaluated.key == plus.key
|
||||
assert evaluated.body == 3
|
||||
|
||||
def test_i_can_apply_intermediate_where_condition_choosing_the_correct_where_concept(self):
|
||||
# in this test, there are two where conditions with the same name
|
||||
# We need to use the 'PRE' condition to select the correct one
|
||||
sheerka, context, one_1, one_str, is_an_int, is_an_integer, plus = self.init_concepts(
|
||||
Concept("one", body="1"),
|
||||
Concept("one", body="'one'"),
|
||||
Concept("x is an int",
|
||||
body="isinstance(x, int)",
|
||||
pre="in_context(BuiltinConcepts.EVAL_QUESTION_REQUESTED)").def_var("x"),
|
||||
Concept("x is an int", body="False").def_var("x"),
|
||||
Concept("a plus b", body="a + b", where="a is an int").def_var("a", "one").def_var("b", "2"),
|
||||
eval_body=True,
|
||||
eval_where=True,
|
||||
)
|
||||
|
||||
evaluated = sheerka.evaluate_concept(context, plus)
|
||||
assert evaluated.key == plus.key
|
||||
assert evaluated.body == 3
|
||||
|
||||
@pytest.mark.skip("Not ready for that")
|
||||
def test_i_can_apply_intermediate_where_condition_when_multiple_variables(self):
|
||||
sheerka, context, one_1, one_str, two_2, two_str, is_an_int, plus = self.init_concepts(
|
||||
Concept("one", body="1"),
|
||||
Concept("one", body="'one'"),
|
||||
Concept("two", body="2"),
|
||||
Concept("two", body="'two'"),
|
||||
Concept("x is an int", body="isinstance(x, int)").def_var("x"),
|
||||
Concept("a plus b",
|
||||
body="a + b",
|
||||
where="a is an int and isinstance(b, int)").def_var("a", "one").def_var("b", "two"),
|
||||
eval_body=True,
|
||||
eval_where=True,
|
||||
)
|
||||
|
||||
evaluated = sheerka.evaluate_concept(context, plus)
|
||||
assert evaluated.key == plus.key
|
||||
assert evaluated.body == 3
|
||||
|
||||
def test_i_cannot_evaluate_when_intermediate_where_condition_fails(self):
|
||||
sheerka, context, one_1, is_an_int, plus = self.init_concepts(
|
||||
Concept("one", body="'one'"),
|
||||
Concept("x is an int", body="isinstance(x, int)").def_var("x"),
|
||||
Concept("a plus b", body="a + b", where="a is an int").def_var("a", "one").def_var("b", "2"),
|
||||
eval_body=True,
|
||||
eval_where=True,
|
||||
)
|
||||
|
||||
evaluated = sheerka.evaluate_concept(context, plus)
|
||||
assert evaluated.key == BuiltinConcepts.CONDITION_FAILED
|
||||
assert evaluated.body == "a is an int"
|
||||
|
||||
def test_i_can_enable_disable_where_clause_evaluation(self):
|
||||
sheerka, context, concept = self.init_concepts(
|
||||
Concept("foo", body="10", where="a > 10").def_var("a", None),
|
||||
@@ -409,7 +565,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
evaluated = sheerka.evaluate_concept(context, concept)
|
||||
assert evaluated.key == concept.key
|
||||
|
||||
context.local_hints.add(BuiltinConcepts.EVAL_WHERE_REQUESTED)
|
||||
context.protected_hints.add(BuiltinConcepts.EVAL_WHERE_REQUESTED)
|
||||
evaluated = sheerka.evaluate_concept(context, concept)
|
||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CONCEPT_EVAL_ERROR)
|
||||
|
||||
@@ -495,6 +651,16 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
|
||||
assert evaluated.body == {foo}
|
||||
|
||||
# def test_i_can_detect_auto_recursion_when_evaluating_another_concept(self):
|
||||
# sheerka, context, one_1, one_str, plus = self.init_concepts(
|
||||
# Concept("one", body="1"),
|
||||
# Concept("one", body="one"),
|
||||
# Concept("a plus b", body="a + b", where="isinstance(a, int)").def_var("a", "one").def_var("b", "2")
|
||||
# )
|
||||
#
|
||||
# evaluated = sheerka.evaluate_concept(context, plus, eval_body=True)
|
||||
# sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
|
||||
|
||||
def test_i_can_manage_auto_recursion_when_constant(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
@@ -566,7 +732,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
assert captured.out == ""
|
||||
|
||||
def test_python_builtin_function_are_forbidden_in_where_pre_post_ret(self, capsys):
|
||||
# I do the test only for PRE, as it will be the same for the other CounceptPart
|
||||
# I do the test only for PRE, as it will be the same for the other ConceptPart
|
||||
sheerka, context, foo, bar = self.init_concepts(
|
||||
Concept("foo", body="print('10')"), # print will be executed
|
||||
Concept("bar", pre="print('10')"), # print won't be executed
|
||||
@@ -658,8 +824,8 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
sheerka, context, concept = self.init_concepts(
|
||||
Concept("foo", pre="'pre'", post="'post'", ret="'ret'", where="'where'", body="'body'").def_var("a", "'a'")
|
||||
)
|
||||
context.local_hints.add(BuiltinConcepts.EVAL_WHERE_REQUESTED) # to prove that we do not care
|
||||
context.local_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED) # to prove that we do not care
|
||||
context.protected_hints.add(BuiltinConcepts.EVAL_WHERE_REQUESTED) # to prove that we do not care
|
||||
context.protected_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED) # to prove that we do not care
|
||||
|
||||
evaluated = sheerka.evaluate_concept(context, concept, metadata=['pre'])
|
||||
assert evaluated.values == {"a": Property("a", NotInit), ConceptParts.PRE: Property(ConceptParts.PRE, 'pre')}
|
||||
|
||||
Reference in New Issue
Block a user