Concepts bodies are now evaluated on demand
This commit is contained in:
@@ -15,7 +15,7 @@ class TestSheerkaNonReg(TestUsingFileBasedSheerka):
|
||||
("1 + 1", 2),
|
||||
("sheerka.test()", 'I have access to Sheerka !')
|
||||
])
|
||||
def test_i_can_eval_python_expressions_with_no_variable(self, text, expected):
|
||||
def test_i_can_evaluate_python_expressions_with_no_variable(self, text, expected):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
res = sheerka.evaluate_user_input(text)
|
||||
@@ -24,7 +24,7 @@ class TestSheerkaNonReg(TestUsingFileBasedSheerka):
|
||||
assert res[0].status
|
||||
assert res[0].value == expected
|
||||
|
||||
def test_i_can_eval_concept_with_python_body(self):
|
||||
def test_i_can_recognize_concept_with_python_body(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept = Concept(name="one", body="1")
|
||||
sheerka.add_in_cache(concept)
|
||||
@@ -33,9 +33,13 @@ class TestSheerkaNonReg(TestUsingFileBasedSheerka):
|
||||
res = sheerka.evaluate_user_input(text)
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].value == simplec("one", 1) # by default, the concept is returned
|
||||
assert res[0].value == concept
|
||||
|
||||
def test_i_can_eval_concept_with_concept_body(self):
|
||||
# sanity check
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(), res[0].value, True)
|
||||
assert evaluated == simplec("one", 1)
|
||||
|
||||
def test_i_can_recognize_concept_with_concept_body(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept_one = Concept(name="one")
|
||||
concept_un = Concept(name="un", body="one")
|
||||
@@ -46,9 +50,13 @@ class TestSheerkaNonReg(TestUsingFileBasedSheerka):
|
||||
return_value = res[0].value
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert return_value == simplec("un", simplec("one", None))
|
||||
assert return_value == concept_un
|
||||
|
||||
def test_i_can_eval_concept_with_no_body(self):
|
||||
# sanity check
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(), return_value, True)
|
||||
assert evaluated == simplec("un", simplec("one", None))
|
||||
|
||||
def test_i_can_recognize_concept_with_no_body(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept = Concept(name="one")
|
||||
sheerka.add_in_cache(concept)
|
||||
@@ -72,7 +80,7 @@ class TestSheerkaNonReg(TestUsingFileBasedSheerka):
|
||||
assert res[0].value == concept
|
||||
assert id(res[0].value) == id(concept)
|
||||
|
||||
def test_i_can_eval_def_concept_request(self):
|
||||
def test_i_can_evaluate_def_concept_request(self):
|
||||
text = """
|
||||
def concept a + b
|
||||
where isinstance(a, int) and isinstance(b, int)
|
||||
@@ -107,7 +115,7 @@ as:
|
||||
assert sheerka.sdp.io.exists(
|
||||
sheerka.sdp.io.get_obj_path(SheerkaDataProvider.ObjectsFolder, concept_saved.get_origin()))
|
||||
|
||||
def test_i_can_eval_def_concept_part_when_one_part_is_a_ref_of_another_concept(self):
|
||||
def test_i_can_evaluate_def_concept_part_when_one_part_is_a_ref_of_another_concept(self):
|
||||
"""
|
||||
In this test, we test that the properties of 'concept a xx b' (which are 'a' and 'b')
|
||||
are correctly detected, thanks to the source code 'a plus b' in its body
|
||||
@@ -137,7 +145,7 @@ as:
|
||||
assert sheerka.sdp.io.exists(
|
||||
sheerka.sdp.io.get_obj_path(SheerkaDataProvider.ObjectsFolder, concept_saved.get_origin()))
|
||||
|
||||
def test_i_cannot_eval_the_same_def_concept_twice(self):
|
||||
def test_i_cannot_evaluate_the_same_def_concept_twice(self):
|
||||
text = """
|
||||
def concept a + b
|
||||
where isinstance(a, int) and isinstance(b, int)
|
||||
@@ -162,7 +170,7 @@ as:
|
||||
" ",
|
||||
"\n",
|
||||
])
|
||||
def test_i_can_eval_a_empty_input(self, text):
|
||||
def test_i_can_recognize_a_empty_input(self, text):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
res = sheerka.evaluate_user_input(text)
|
||||
@@ -171,7 +179,7 @@ as:
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(res[0].value, BuiltinConcepts.NOP)
|
||||
|
||||
def test_i_can_eval_concept_with_variable(self):
|
||||
def test_i_can_recognize_concept_with_variable(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept_hello = Concept(name="hello a").def_prop("a")
|
||||
concept_foo = Concept(name="foo")
|
||||
@@ -183,9 +191,13 @@ as:
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(return_value, concept_hello)
|
||||
assert return_value.props["a"].value == concept_foo
|
||||
assert return_value.metadata.props[0] == ('a', "foo")
|
||||
|
||||
def test_i_can_eval_concept_with_variable_and_python_as_body(self):
|
||||
# sanity check
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(), return_value, True)
|
||||
assert evaluated.props["a"].value == concept_foo
|
||||
|
||||
def test_i_can_recognize_concept_with_variable_and_python_as_body(self):
|
||||
sheerka = self.get_sheerka()
|
||||
hello_a = sheerka.add_in_cache(Concept(name="hello a", body="'hello ' + a").def_prop("a"))
|
||||
sheerka.add_in_cache(Concept(name="foo", body="'foo'"))
|
||||
@@ -194,12 +206,15 @@ as:
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(res[0].value, hello_a)
|
||||
assert res[0].value.body == "hello foo"
|
||||
assert res[0].value.metadata.is_evaluated
|
||||
assert res[0].value.props["a"].value == simplec("foo", "foo")
|
||||
assert res[0].value.props["a"].value.metadata.is_evaluated
|
||||
|
||||
def test_i_can_eval_duplicate_concepts_with_same_value(self):
|
||||
# sanity check
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(), res[0].value, True)
|
||||
assert evaluated.body == "hello foo"
|
||||
assert evaluated.metadata.is_evaluated
|
||||
assert evaluated.props["a"].value == simplec("foo", "foo")
|
||||
assert evaluated.props["a"].value.metadata.is_evaluated
|
||||
|
||||
def test_i_can_recognize_duplicate_concepts_with_same_value(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
sheerka.add_in_cache(Concept(name="hello a", body="'hello ' + a").def_prop("a"))
|
||||
@@ -248,11 +263,11 @@ as:
|
||||
context = self.get_context(sheerka)
|
||||
|
||||
sheerka.create_new_concept(context, Concept(name="concepts", body="sheerka.concepts()"))
|
||||
res = sheerka.evaluate_user_input("concepts")
|
||||
res = sheerka.evaluate_user_input("eval concepts")
|
||||
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert isinstance(res[0].value.body, list)
|
||||
assert isinstance(res[0].value, list)
|
||||
|
||||
def test_i_can_create_concept_with_bnf_definition(self):
|
||||
sheerka = self.get_sheerka(use_dict=False, skip_builtins_in_db=False)
|
||||
@@ -284,7 +299,7 @@ as:
|
||||
assert "a" in new_concept.props
|
||||
assert "plus" in new_concept.props
|
||||
|
||||
def test_i_can_eval_bnf_definitions(self):
|
||||
def test_i_can_recognize_bnf_definitions(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept_a = sheerka.evaluate_user_input("def concept a from bnf 'one' | 'two'")[0].body.body
|
||||
|
||||
@@ -294,7 +309,7 @@ as:
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(res[0].value, concept_a)
|
||||
|
||||
def test_i_can_eval_bnf_definitions_with_variables(self):
|
||||
def test_i_can_recognize_bnf_definitions_with_variables(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept_a = sheerka.evaluate_user_input("def concept a from bnf 'one' | 'two'")[0].body.body
|
||||
concept_b = sheerka.evaluate_user_input("def concept b from bnf a 'three'")[0].body.body
|
||||
@@ -306,13 +321,15 @@ as:
|
||||
return_value = res[0].value
|
||||
|
||||
assert sheerka.isinstance(return_value, concept_b)
|
||||
assert return_value.body == "one three"
|
||||
assert return_value.metadata.is_evaluated
|
||||
|
||||
assert return_value.props["a"] == Property("a", sheerka.new(concept_a.key, body="one").init_key())
|
||||
assert return_value.props["a"].value.metadata.is_evaluated
|
||||
# sanity check
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(), return_value, True)
|
||||
assert evaluated.body == "one three"
|
||||
assert evaluated.metadata.is_evaluated
|
||||
assert evaluated.props["a"] == Property("a", sheerka.new(concept_a.key, body="one").init_key())
|
||||
assert evaluated.props["a"].value.metadata.is_evaluated
|
||||
|
||||
def test_i_can_eval_bnf_definitions_from_separate_instances(self):
|
||||
def test_i_can_recognize_bnf_definitions_from_separate_instances(self):
|
||||
"""
|
||||
Same test then before,
|
||||
but make sure that the BNF are correctly persisted and loaded
|
||||
@@ -337,8 +354,10 @@ as:
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(res[0].value, concept_b)
|
||||
assert res[0].value.body == "one two three"
|
||||
assert res[0].value.props["a"] == Property("a", sheerka.new(concept_a.key, body="one two").init_key())
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(), res[0].value, True)
|
||||
assert evaluated.body == "one two three"
|
||||
assert evaluated.props["a"] == Property("a", sheerka.new(concept_a.key, body="one two").init_key())
|
||||
|
||||
@pytest.mark.parametrize("desc, definitions", [
|
||||
("Simple form", [
|
||||
@@ -387,7 +406,7 @@ as:
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(res[0].body, "twenties")
|
||||
assert res[0].body.body == 21
|
||||
assert sheerka.evaluate_concept(self.get_context(), res[0].body, True).body == 21
|
||||
|
||||
res = sheerka.evaluate_user_input("twenty one + 1")
|
||||
assert len(res) == 1
|
||||
@@ -430,7 +449,8 @@ as:
|
||||
res = sheerka.evaluate_user_input("twenty one")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].body == simplec("twenties", 21)
|
||||
assert sheerka.isinstance(res[0].body, "twenties")
|
||||
assert sheerka.evaluate_concept(self.get_context(), res[0].value, True).body == 21
|
||||
|
||||
res = sheerka.evaluate_user_input("twenty one + 1")
|
||||
assert len(res) == 1
|
||||
@@ -472,10 +492,10 @@ as:
|
||||
for exp in init:
|
||||
sheerka.evaluate_user_input(exp)
|
||||
|
||||
res = sheerka.evaluate_user_input("twenty one")
|
||||
res = sheerka.evaluate_user_input("eval twenty one")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].body == simplec("twenties", 21)
|
||||
assert res[0].body == 21
|
||||
|
||||
def test_i_can_mix_concept_of_concept(self):
|
||||
sheerka = self.get_sheerka()
|
||||
@@ -490,55 +510,55 @@ as:
|
||||
for definition in definitions:
|
||||
sheerka.evaluate_user_input(definition)
|
||||
|
||||
res = sheerka.evaluate_user_input("1 plus 2")
|
||||
res = sheerka.evaluate_user_input("eval 1 plus 2")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].body.body == 3
|
||||
assert res[0].body == 3
|
||||
|
||||
res = sheerka.evaluate_user_input("1 plus one")
|
||||
res = sheerka.evaluate_user_input("eval 1 plus one")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].body.body == 2
|
||||
assert res[0].body == 2
|
||||
|
||||
res = sheerka.evaluate_user_input("1 + 1 plus 1")
|
||||
res = sheerka.evaluate_user_input("eval 1 + 1 plus 1")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].body.body == 3
|
||||
assert res[0].body == 3
|
||||
|
||||
res = sheerka.evaluate_user_input("1 plus twenty one")
|
||||
res = sheerka.evaluate_user_input("eval 1 plus twenty one")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].body.body == 22
|
||||
assert res[0].body == 22
|
||||
|
||||
res = sheerka.evaluate_user_input("one plus 1")
|
||||
res = sheerka.evaluate_user_input("eval one plus 1")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].body.body == 2
|
||||
assert res[0].body == 2
|
||||
|
||||
res = sheerka.evaluate_user_input("one plus two")
|
||||
res = sheerka.evaluate_user_input("eval one plus two")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].body.body == 3
|
||||
assert res[0].body == 3
|
||||
|
||||
res = sheerka.evaluate_user_input("one plus twenty one")
|
||||
res = sheerka.evaluate_user_input("eval one plus twenty one")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].body.body == 22
|
||||
assert res[0].body == 22
|
||||
|
||||
res = sheerka.evaluate_user_input("twenty one plus 1")
|
||||
res = sheerka.evaluate_user_input("eval twenty one plus 1")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].body.body == 22
|
||||
assert res[0].body == 22
|
||||
|
||||
res = sheerka.evaluate_user_input("twenty one plus one")
|
||||
res = sheerka.evaluate_user_input("eval twenty one plus one")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].body.body == 22
|
||||
assert res[0].body == 22
|
||||
|
||||
res = sheerka.evaluate_user_input("twenty one plus twenty two")
|
||||
res = sheerka.evaluate_user_input("eval twenty one plus twenty two")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].body.body == 43
|
||||
assert res[0].body == 43
|
||||
|
||||
@pytest.mark.xfail
|
||||
def test_i_can_evaluate_concept_of_concept_when_multiple_choices(self):
|
||||
@@ -663,23 +683,29 @@ as:
|
||||
for exp in init:
|
||||
sheerka.evaluate_user_input(exp)
|
||||
|
||||
res = sheerka.evaluate_user_input("twenty one")
|
||||
assert len(res) == 1 and res[0].status and sheerka.isinstance(res[0].body, "twenties")
|
||||
|
||||
res = sheerka.evaluate_user_input("eval twenty one")
|
||||
assert len(res) == 1 and res[0].status and res[0].body == 21
|
||||
|
||||
res = sheerka.evaluate_user_input("twenty two")
|
||||
assert len(res) == 1 and res[0].status and sheerka.isinstance(res[0].body, "twenties")
|
||||
|
||||
res = sheerka.evaluate_user_input("eval twenty two")
|
||||
assert len(res) == 1 and res[0].status and res[0].body == 22
|
||||
|
||||
res = sheerka.evaluate_user_input("eval twenty three")
|
||||
assert len(res) > 1
|
||||
|
||||
def test_i_can_detect_when_only_one_evaluator_is_in_error(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
sheerka.evaluate_user_input("def concept 1 as one")
|
||||
res = sheerka.evaluate_user_input("1")
|
||||
assert len(res) == 1
|
||||
assert not res[0].status
|
||||
assert sheerka.isinstance(res[0].body, BuiltinConcepts.CONCEPT_EVAL_ERROR)
|
||||
# def test_i_can_detect_when_only_one_evaluator_is_in_error(self):
|
||||
# sheerka = self.get_sheerka()
|
||||
#
|
||||
# sheerka.evaluate_user_input("def concept 1 as one")
|
||||
# res = sheerka.evaluate_user_input("eval 1")
|
||||
# assert len(res) == 1
|
||||
# assert not res[0].status
|
||||
# assert sheerka.isinstance(res[0].body, BuiltinConcepts.CONCEPT_EVAL_ERROR)
|
||||
|
||||
def test_i_can_manage_some_type_of_infinite_recursion(self):
|
||||
sheerka = self.get_sheerka()
|
||||
@@ -696,3 +722,56 @@ as:
|
||||
assert res[0].status
|
||||
assert res[0].body == 2
|
||||
|
||||
@pytest.mark.xfail
|
||||
def test_i_can_evaluate_bnf_concept_with_where_clause(self):
|
||||
|
||||
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
sheerka.evaluate_user_input("def concept a from bnf 'bar' | 'baz'")
|
||||
sheerka.evaluate_user_input("def concept b as 'hello world'")
|
||||
sheerka.evaluate_user_input("def concept foobar from bnf 'foo' a where a=='bar' as b")
|
||||
|
||||
res = sheerka.evaluate_user_input("foo bar")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(res[0].body, "foobar")
|
||||
assert res[0].body.body is None
|
||||
|
||||
res = sheerka.evaluate_user_input("eval foo bar")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].body.body == "hello world"
|
||||
|
||||
res = sheerka.evaluate_user_input("foo baz")
|
||||
assert len(res) == 1
|
||||
assert not res[0].status
|
||||
assert sheerka.isinstance(res[0].body, BuiltinConcepts.WHERE_CLAUSE_FAILED)
|
||||
|
||||
res = sheerka.evaluate_user_input("eval foo baz")
|
||||
assert len(res) > 1
|
||||
|
||||
# The following test fails
|
||||
# the Where clause is evaluated while it should not
|
||||
res = sheerka.evaluate_user_input("foobar")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
|
||||
res = sheerka.evaluate_user_input("eval foobar")
|
||||
assert len(res) > 1 # error
|
||||
assert res[0].status
|
||||
|
||||
def test_i_can_say_than_bnf_concept_isa_another_concept(self):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka.evaluate_user_input("def concept number")
|
||||
sheerka.evaluate_user_input("def concept one as 1")
|
||||
sheerka.evaluate_user_input("def concept two as 2")
|
||||
sheerka.evaluate_user_input("def concept twenties from bnf 'twenty' (one|two)=unit as 20 + unit")
|
||||
|
||||
res = sheerka.evaluate_user_input("twenties isa number")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
|
||||
twenties = sheerka.get("twenties")
|
||||
number = sheerka.get("number")
|
||||
assert sheerka.isa(twenties, number)
|
||||
|
||||
Reference in New Issue
Block a user