Added chicken and egg recursion detection
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import PROPERTIES_TO_SERIALIZE
|
||||
from core.concept import PROPERTIES_TO_SERIALIZE, Concept
|
||||
from sdp.sheerkaDataProvider import SheerkaDataProvider
|
||||
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
@@ -80,12 +80,10 @@ class TestSheerkaCreateNewConcept(TestUsingMemoryBasedSheerka):
|
||||
sheerka.cache_by_key = {} # reset the cache
|
||||
loaded = sheerka.get(concept.key)
|
||||
|
||||
assert loaded is not None
|
||||
assert loaded == concept
|
||||
|
||||
# I can also get it by its id
|
||||
loaded = sheerka.sdp.get(sheerka.CONCEPTS_BY_ID_ENTRY, concept.id)
|
||||
assert loaded is not None
|
||||
assert loaded == concept
|
||||
|
||||
def test_i_can_get_a_concept_by_its_id(self):
|
||||
@@ -96,7 +94,6 @@ class TestSheerkaCreateNewConcept(TestUsingMemoryBasedSheerka):
|
||||
sheerka.cache_by_key = {} # reset the cache
|
||||
loaded = sheerka.get_by_id(concept.id)
|
||||
|
||||
assert loaded is not None
|
||||
assert loaded == concept
|
||||
|
||||
def test_i_can_get_list_of_concept_when_same_key_when_no_cache(self):
|
||||
@@ -178,3 +175,12 @@ class TestSheerkaCreateNewConcept(TestUsingMemoryBasedSheerka):
|
||||
|
||||
result = sheerka.get(concept1.key, "wrong id")
|
||||
assert sheerka.isinstance(result, BuiltinConcepts.UNKNOWN_CONCEPT)
|
||||
|
||||
def test_concept_that_references_itself_is_correctly_created(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept = Concept("foo", body="foo")
|
||||
|
||||
res = sheerka.create_new_concept(self.get_context(sheerka), concept)
|
||||
|
||||
assert res.status
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import pytest
|
||||
from core.builtin_concepts import BuiltinConcepts, ReturnValueConcept, ParserResultConcept
|
||||
from core.concept import Concept, simplec, DoNotResolve, ConceptParts, Property
|
||||
from core.concept import Concept, simplec, DoNotResolve, ConceptParts, Property, InfiniteRecursionResolved
|
||||
from parsers.PythonParser import PythonNode
|
||||
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
@@ -369,3 +369,91 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.WHERE_CLAUSE_FAILED)
|
||||
assert evaluated.body == concept
|
||||
|
||||
def test_i_can_detect_infinite_recursion_with_numeric_constant(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
one_str = Concept("one", body="1")
|
||||
one_digit = Concept("1", body="one")
|
||||
|
||||
sheerka.add_in_cache(one_str)
|
||||
sheerka.add_in_cache(one_digit)
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), one_digit)
|
||||
assert evaluated.key == one_digit.key
|
||||
assert evaluated.body == InfiniteRecursionResolved(1)
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), one_str)
|
||||
assert evaluated.key == one_str.key
|
||||
assert evaluated.body == InfiniteRecursionResolved(1)
|
||||
|
||||
def test_i_can_detect_infinite_recursion_with_boolean_constant(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
true_str = Concept("true", body="True")
|
||||
true_bool = Concept("True", body="true")
|
||||
|
||||
sheerka.add_in_cache(true_str)
|
||||
sheerka.add_in_cache(true_bool)
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), true_str)
|
||||
assert evaluated.key == true_str.key
|
||||
assert evaluated.body == InfiniteRecursionResolved(True)
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), true_bool)
|
||||
assert evaluated.key == true_bool.key
|
||||
assert evaluated.body == InfiniteRecursionResolved(True)
|
||||
|
||||
def test_i_can_detect_infinite_recursion_with_constant_with_more_concepts(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
c1 = sheerka.add_in_cache(Concept("one", body="1"))
|
||||
c2 = sheerka.add_in_cache(Concept("1", body="2"))
|
||||
c3 = sheerka.add_in_cache(Concept("2", body="3"))
|
||||
c4 = sheerka.add_in_cache(Concept("3", body="one"))
|
||||
|
||||
for concept in (c1, c2, c3, c4):
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == InfiniteRecursionResolved(3)
|
||||
|
||||
def test_i_can_detect_infinite_recursion_when_no_constant(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
foo = sheerka.add_in_cache(Concept("foo", body="bar"))
|
||||
bar = sheerka.add_in_cache(Concept("bar", body="baz"))
|
||||
baz = sheerka.add_in_cache(Concept("baz", body="qux"))
|
||||
qux = sheerka.add_in_cache(Concept("qux", body="foo"))
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), foo)
|
||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
|
||||
assert evaluated.body == {foo, bar, baz, qux}
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), bar)
|
||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
|
||||
assert evaluated.body == {foo, bar, baz, qux}
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), baz)
|
||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
|
||||
assert evaluated.body == {foo, bar, baz, qux}
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), qux)
|
||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
|
||||
assert evaluated.body == {foo, bar, baz, qux}
|
||||
|
||||
def test_i_can_detect_auto_recursion(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
foo = sheerka.add_in_cache(Concept("foo", body="foo"))
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), foo)
|
||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
|
||||
assert evaluated.body == {foo}
|
||||
|
||||
def test_i_can_manage_auto_recursion_when_constant(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
one = Concept("1", body="1")
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), one)
|
||||
assert evaluated.key == one.key
|
||||
assert evaluated.body == 1
|
||||
|
||||
@@ -242,3 +242,41 @@ class TestSheerka(TestUsingFileBasedSheerka):
|
||||
# only test a random one, it will be the same for the others
|
||||
sheerka = self.get_sheerka()
|
||||
assert not sheerka.is_success(sheerka.new(BuiltinConcepts.TOO_MANY_SUCCESS))
|
||||
|
||||
def test_cache_is_updated_after_get(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
# updated when by_key returns one element
|
||||
sheerka.create_new_concept(self.get_context(sheerka), Concept("foo", body="1"))
|
||||
sheerka.reset_cache()
|
||||
sheerka.get("foo")
|
||||
assert "foo" in sheerka.cache_by_key
|
||||
assert "1001" in sheerka.cache_by_id
|
||||
|
||||
# updated when by_key returns two elements
|
||||
sheerka.create_new_concept(self.get_context(sheerka), Concept("foo", body="2"))
|
||||
sheerka.reset_cache()
|
||||
sheerka.get("foo")
|
||||
assert "foo" in sheerka.cache_by_key
|
||||
assert "1001" in sheerka.cache_by_id
|
||||
assert "1002" in sheerka.cache_by_id
|
||||
|
||||
# updated when by_id
|
||||
sheerka.reset_cache()
|
||||
sheerka.get_by_id("1001")
|
||||
assert "1001" in sheerka.cache_by_id
|
||||
assert "foo" not in sheerka.cache_by_key # cache_by_key not updated as "1001" is not the only one
|
||||
|
||||
def test_i_can_get_by_key_several_times(self):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka.create_new_concept(self.get_context(sheerka), Concept("foo", body="1"))
|
||||
sheerka.create_new_concept(self.get_context(sheerka), Concept("foo", body="2"))
|
||||
|
||||
sheerka.reset_cache()
|
||||
sheerka.get("foo", "1001") # only one element requested. But the cache must be updated with two elements
|
||||
|
||||
# let's check it
|
||||
concepts = sheerka.get("foo")
|
||||
assert len(concepts) == 2
|
||||
assert concepts[0].id == "1001"
|
||||
assert concepts[1].id == "1002"
|
||||
|
||||
Reference in New Issue
Block a user