import pytest from core.builtin_concepts import BuiltinConcepts from core.concept import PROPERTIES_TO_SERIALIZE, Concept, DEFINITION_TYPE_DEF from core.sheerka.Sheerka import Sheerka from tests.TestUsingFileBasedSheerka import TestUsingFileBasedSheerka from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka class TestSheerkaCreateNewConcept(TestUsingMemoryBasedSheerka): def test_i_can_create_a_concept(self): sheerka = self.get_sheerka(cache_only=False) context = self.get_context(sheerka) concept = self.get_default_concept() res = sheerka.create_new_concept(context, concept) sheerka.cache_manager.commit(context) assert res.status assert sheerka.isinstance(res.value, BuiltinConcepts.NEW_CONCEPT) concept_found = res.value.body for prop in PROPERTIES_TO_SERIALIZE: assert getattr(concept_found.metadata, prop) == getattr(concept.metadata, prop) assert concept_found.key == "__var__0 + __var__1" assert concept_found.id == "1001" # saved in cache assert sheerka.has_id(concept.id) assert sheerka.has_key(concept.key) assert sheerka.has_name(concept.name) assert sheerka.has_hash(concept.get_definition_hash()) # I can get the concept using various index assert sheerka.get_by_id(concept.id) == concept assert sheerka.get_by_key(concept.key) == concept assert sheerka.get_by_name(concept.name) == concept assert sheerka.get_by_hash(concept.get_definition_hash()) == concept # I can get by the first entry assert sheerka.cache_manager.get(sheerka.CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "+") == [concept.id] assert sheerka.cache_manager.get(sheerka.RESOLVED_CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "+") == [concept.id] # saved in sdp assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_ID_ENTRY, concept.id) assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_KEY_ENTRY, concept.key) assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_NAME_ENTRY, concept.name) assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_HASH_ENTRY, concept.get_definition_hash()) assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "+") def test_i_can_add_a_concept_when_name_differs_from_the_key(self): sheerka = self.get_sheerka(cache_only=False) context = self.get_context(sheerka) concept = Concept("greetings", definition="hello a", definition_type=DEFINITION_TYPE_DEF).def_var("a") res = sheerka.create_new_concept(self.get_context(sheerka), concept) sheerka.cache_manager.commit(context) assert res.status assert sheerka.isinstance(res.value, BuiltinConcepts.NEW_CONCEPT) concept_found = res.value.body for prop in PROPERTIES_TO_SERIALIZE: assert getattr(concept_found.metadata, prop) == getattr(concept.metadata, prop) assert concept_found.key == "hello __var__0" assert concept_found.id == "1001" # saved in cache assert sheerka.has_id(concept.id) assert sheerka.has_key(concept.key) assert sheerka.has_name(concept.name) assert sheerka.has_hash(concept.get_definition_hash()) # I can get the concept using various index assert sheerka.get_by_id(concept.id) == concept assert sheerka.get_by_key(concept.key) == concept assert sheerka.get_by_name(concept.name) == concept assert sheerka.get_by_hash(concept.get_definition_hash()) == concept # saved in sdp assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_ID_ENTRY, concept.id) assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_KEY_ENTRY, concept.key) assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_NAME_ENTRY, concept.name) assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_HASH_ENTRY, concept.get_definition_hash()) assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "hello") def test_i_cannot_add_the_same_concept_twice(self): """ Checks that duplicated concepts are managed by sheerka, not by sheerka.sdp :return: """ sheerka = self.get_sheerka() concept = self.get_default_concept() sheerka.create_new_concept(self.get_context(sheerka), concept) res = sheerka.create_new_concept(self.get_context(sheerka), concept) assert not res.status assert sheerka.isinstance(res.value, BuiltinConcepts.ALREADY_DEFINED) assert res.value.body == concept def test_i_can_get_a_newly_created_concept(self): sheerka = self.get_sheerka() concept = self.get_default_concept() sheerka.create_new_concept(self.get_context(sheerka), concept) from_cache = sheerka.get_by_key(concept.key) assert from_cache is not None assert from_cache == concept from_cache = sheerka.get_by_id(concept.id) assert from_cache is not None assert from_cache == concept def test_i_can_get_list_of_concept_when_same_key_using_cache(self): sheerka = self.get_sheerka() concept1 = self.get_default_concept() concept2 = self.get_default_concept() concept2.metadata.body = "a+b" res1 = sheerka.create_new_concept(self.get_context(sheerka), concept1) res2 = sheerka.create_new_concept(self.get_context(sheerka), concept2) assert res1.value.body.key == res2.value.body.key # same key result = sheerka.get_by_key(concept1.key) assert len(result) == 2 assert result[0] == concept1 assert result[1] == concept2 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 def test_i_can_get_by_name_when_created_with_def_definition(self): sheerka = self.get_sheerka(cache_only=False) context = self.get_context(sheerka) concept = self.from_def_concept("plus", "a plus b", ["a", "b"]) res = sheerka.create_new_concept(context, concept) assert res.status assert sheerka.get_by_name(concept.name) == concept assert sheerka.get_by_name(concept.metadata.definition) == concept concept = Concept(name="foo", definition="foo", definition_type=DEFINITION_TYPE_DEF) res = sheerka.create_new_concept(context, concept) assert res.status assert sheerka.get_by_name(concept.name) == concept # it's not a list, ie the entry is not duplicated def test_i_can_get_first_token_when_not_a_letter(self): sheerka = self.get_sheerka(cache_only=False) context = self.get_context(sheerka) concept = Concept("--filter a").def_var("a") res = sheerka.create_new_concept(context, concept) assert res.status # I can get by the first entry assert sheerka.cache_manager.get(sheerka.CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "-") == [concept.id] assert sheerka.cache_manager.get(sheerka.RESOLVED_CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "-") == [concept.id] @pytest.mark.parametrize("expression", [ "--'filter' ('one' | 'two') ", "'--filter' ('one' | 'two') ", ]) def test_i_can_get_first_token_when_bnf_concept_and_not_a_letter(self, expression): sheerka, context, bnf_concept = self.init_concepts( Concept("foo", definition=expression), create_new=True) # I can get by the first entry assert sheerka.cache_manager.get(sheerka.CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "-") == [bnf_concept.id] assert sheerka.cache_manager.get(sheerka.RESOLVED_CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "-") == [bnf_concept.id] def test_concept_references_are_updated_1(self): sheerka, context, one, two, number, twenty, twenties = self.init_concepts( "one", "two", "number", "twenty", Concept("twenties", definition="twenty one | two 'hundred'"), create_new=True ) assert sheerka.cache_manager.get(sheerka.CONCEPTS_REFERENCES_ENTRY, one.id) == {twenties.id} assert sheerka.cache_manager.get(sheerka.CONCEPTS_REFERENCES_ENTRY, two.id) == {twenties.id} assert sheerka.cache_manager.get(sheerka.CONCEPTS_REFERENCES_ENTRY, number.id) is None assert sheerka.cache_manager.get(sheerka.CONCEPTS_REFERENCES_ENTRY, twenty.id) == {twenties.id} assert sheerka.cache_manager.get(sheerka.CONCEPTS_REFERENCES_ENTRY, twenties.id) is None def test_concept_references_are_updated_2(self): sheerka, context, one, two, number, twenty, twenties = self.init_concepts( "one", "two", "number", "twenty", Concept("twenties", definition="twenty number"), create_new=True ) assert sheerka.cache_manager.get(sheerka.CONCEPTS_REFERENCES_ENTRY, one.id) is None assert sheerka.cache_manager.get(sheerka.CONCEPTS_REFERENCES_ENTRY, two.id) is None assert sheerka.cache_manager.get(sheerka.CONCEPTS_REFERENCES_ENTRY, number.id) == {twenties.id} assert sheerka.cache_manager.get(sheerka.CONCEPTS_REFERENCES_ENTRY, twenty.id) == {twenties.id} assert sheerka.cache_manager.get(sheerka.CONCEPTS_REFERENCES_ENTRY, twenties.id) is None class TestSheerkaCreateNewConceptFileBased(TestUsingFileBasedSheerka): def test_i_can_add_several_concepts(self): sheerka = self.get_sheerka() context = self.get_context(sheerka) hello = Concept("Hello world a").def_var("a") res = sheerka.create_new_concept(context, hello) sheerka.cache_manager.commit(context) assert res.status sheerka = self.get_sheerka() # another instance context = self.get_context(sheerka) greeting = Concept("Greeting a").def_var("a") res = sheerka.create_new_concept(context, greeting) sheerka.cache_manager.commit(context) assert res.status sheerka = self.get_sheerka() # another instance again assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_KEY_ENTRY, hello.key) assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_KEY_ENTRY, greeting.key) assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_ID_ENTRY, hello.id) assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_ID_ENTRY, greeting.id) assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_NAME_ENTRY, "Hello world a") assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_NAME_ENTRY, "Greeting a") assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_HASH_ENTRY, hello.get_definition_hash()) assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_HASH_ENTRY, greeting.get_definition_hash()) assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "Hello") assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "Greeting") def test_i_cannot_add_the_same_concept_twice_using_sdp(self): """ Checks that duplicated concepts are managed by sheerka, not by sheerka.sdp :return: """ sheerka = self.get_sheerka(cache_only=False) context = self.get_context(sheerka) concept = self.get_default_concept() sheerka.create_new_concept(context, concept) sheerka.cache_manager.commit(context) sheerka.cache_manager.clear() res = sheerka.create_new_concept(context, concept) assert not res.status assert sheerka.isinstance(res.value, BuiltinConcepts.ALREADY_DEFINED) assert res.value.body == concept def test_new_entry_does_not_override_the_previous_ones(self): sheerka = self.get_sheerka() context = self.get_context(sheerka) sheerka.create_new_concept(context, Concept("foo", body="1")) sheerka.create_new_concept(context, Concept("foo", body="2")) sheerka.cache_manager.commit(context) assert len(sheerka.sdp.get(Sheerka.CONCEPTS_BY_KEY_ENTRY, "foo")) == 2 sheerka = self.get_sheerka() # new instance sheerka.create_new_concept(context, Concept("foo", body="3")) sheerka.cache_manager.commit(context) assert len(sheerka.sdp.get(Sheerka.CONCEPTS_BY_KEY_ENTRY, "foo")) == 3