import pytest import os from os import path import shutil from core.builtin_concepts import BuiltinConcepts, ReturnValueConcept, UserInputConcept, ConceptAlreadyInSet, \ ParserResultConcept from core.concept import Concept, PROPERTIES_TO_SERIALIZE, Property, ConceptParts, DoNotResolve from core.sheerka import Sheerka, ExecutionContext from parsers.PythonParser import PythonNode from sdp.sheerkaDataProvider import SheerkaDataProvider, Event tests_root = path.abspath("../build/tests") root_folder = "init_folder" @pytest.fixture(autouse=True) def init_test(): if path.exists(tests_root): shutil.rmtree(tests_root) if not path.exists(tests_root): os.makedirs(tests_root) current_pwd = os.getcwd() os.chdir(tests_root) yield None os.chdir(current_pwd) def get_sheerka(use_dict=True, skip_builtins_in_db=True): root = "mem://" if use_dict else root_folder sheerka = Sheerka(skip_builtins_in_db=skip_builtins_in_db) sheerka.initialize(root) return sheerka def get_context(sheerka): return ExecutionContext("test", Event(), sheerka) def get_default_concept(): concept = Concept( name="a + b", where="isinstance(a, int) and isinstance(b, int)", pre="isinstance(a, int) and isinstance(b, int)", post="isinstance(res, int)", body="def func(x,y):\n return x+y\nfunc(a,b)", desc="specific description") concept.set_prop("a", "value1") concept.set_prop("b", "value2") return concept class ConceptWithGetValue(Concept): def get_value(self): return self.get_prop("my_prop") def test_root_folder_is_created_after_initialization(): return_value = Sheerka().initialize(root_folder) assert return_value.status, "initialisation should be successful" assert os.path.exists(root_folder), "init folder should be created" def test_i_can_list_builtin_concepts(): sheerka = get_sheerka() builtins = list(sheerka.get_builtins_classes_as_dict()) assert str(BuiltinConcepts.ERROR) in builtins assert str(BuiltinConcepts.RETURN_VALUE) in builtins def test_builtin_concepts_are_initialized(): sheerka = get_sheerka(skip_builtins_in_db=False) assert len(sheerka.concepts_cache) == len(BuiltinConcepts) for concept_name in BuiltinConcepts: assert str(concept_name) in sheerka.concepts_cache assert sheerka.sdp.get_safe(sheerka.CONCEPTS_ENTRY, str(concept_name)) is not None for key, concept_class in sheerka.get_builtins_classes_as_dict().items(): assert isinstance(sheerka.concepts_cache[key], concept_class) def test_builtin_concepts_can_be_updated(): sheerka = get_sheerka(False, False) loaded_sheerka = sheerka.get(BuiltinConcepts.SHEERKA) loaded_sheerka.metadata.desc = "I have a description" sheerka.sdp.modify("Test", sheerka.CONCEPTS_ENTRY, loaded_sheerka.key, loaded_sheerka) sheerka = get_sheerka(False, False) loaded_sheerka = sheerka.get(BuiltinConcepts.SHEERKA) assert loaded_sheerka.metadata.desc == "I have a description" def test_i_can_add_a_concept(): sheerka = get_sheerka() concept = get_default_concept() res = sheerka.create_new_concept(get_context(sheerka), concept) 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" assert concept.key in sheerka.concepts_cache assert sheerka.sdp.io.exists( sheerka.sdp.io.get_obj_path(SheerkaDataProvider.ObjectsFolder, concept_found.get_digest())) def test_i_cannot_add_the_same_concept_twice(): """ Checks that duplicated concepts are managed by sheerka, not by sheerka.sdp :return: """ sheerka = get_sheerka() concept = get_default_concept() sheerka.create_new_concept(get_context(sheerka), concept) res = sheerka.create_new_concept(get_context(sheerka), concept) assert not res.status assert sheerka.isinstance(res.value, BuiltinConcepts.CONCEPT_ALREADY_DEFINED) assert res.value.body == concept def test_i_can_get_a_builtin_concept_by_their_enum_or_the_string(): """ Checks that a concept can be found its name even when there are variables in the name (ex 'hello + a' or 'a + b' ) :return: """ sheerka = get_sheerka() for key in sheerka.get_builtins_classes_as_dict(): assert sheerka.get(key) is not None assert sheerka.get(str(key)) is not None def test_i_can_get_a_newly_created_concept(): sheerka = get_sheerka() concept = get_default_concept() sheerka.create_new_concept(get_context(sheerka), concept) from_cache = sheerka.get(concept.key) assert from_cache is not None assert from_cache.key == concept.key assert from_cache == concept def test_i_first_look_in_local_cache(): sheerka = get_sheerka() concept = get_default_concept() sheerka.create_new_concept(get_context(sheerka), concept) sheerka.concepts_cache[concept.key].pre = "I have modified the concept in cache" from_cache = sheerka.get(concept.key) assert from_cache is not None assert from_cache.key == concept.key assert from_cache.pre == "I have modified the concept in cache" def test_i_can_get_a_known_concept_when_not_in_cache(): """ When not in cache, uses sdp :return: """ sheerka = get_sheerka() concept = get_default_concept() sheerka.create_new_concept(get_context(sheerka), concept) sheerka.concepts_cache = {} # reset the cache loaded = sheerka.get(concept.key) assert loaded is not None assert loaded == concept def test_i_can_get_list_of_concept_when_same_key_when_no_cache(): sheerka = get_sheerka() concept1 = get_default_concept() concept2 = get_default_concept() concept2.metadata.body = "a+b" res1 = sheerka.create_new_concept(get_context(sheerka), concept1) res2 = sheerka.create_new_concept(get_context(sheerka), concept2) assert res1.value.body.key == res2.value.body.key # same key sheerka.concepts_cache = {} # reset the cache result = sheerka.get(concept1.key) assert len(result) == 2 assert result[0] == concept1 assert result[1] == concept2 def test_i_can_get_list_of_concept_when_same_key_when_cache(): sheerka = get_sheerka() concept1 = get_default_concept() concept2 = get_default_concept() concept2.metadata.body = "a+b" res1 = sheerka.create_new_concept(get_context(sheerka), concept1) res2 = sheerka.create_new_concept(get_context(sheerka), concept2) assert res1.value.body.key == res2.value.body.key # same key # sheerka.concepts_cache = {} # Do not reset the cache result = sheerka.get(concept1.key) assert len(result) == 2 assert result[0] == concept1 assert result[1] == concept2 def test_i_can_get_the_correct_concept_using_the_id_when_same_key_when_no_cache(): sheerka = get_sheerka() concept1 = get_default_concept() concept2 = get_default_concept() concept2.metadata.body = "a+b" res1 = sheerka.create_new_concept(get_context(sheerka), concept1) res2 = sheerka.create_new_concept(get_context(sheerka), concept2) assert res1.value.body.key == res2.value.body.key # same key result = sheerka.get(concept1.key, res2.body.body.id) assert result.name == "a + b" assert result.body == "a+b" def test_i_can_get_the_correct_concept_using_the_id__when_same_key_when_cache(): sheerka = get_sheerka() concept1 = get_default_concept() concept2 = get_default_concept() concept2.metadata.body = "a+b" res1 = sheerka.create_new_concept(get_context(sheerka), concept1) res2 = sheerka.create_new_concept(get_context(sheerka), concept2) assert res1.value.body.key == res2.value.body.key # same key result = sheerka.get(concept1.key, res2.body.body.id) assert result.name == "a + b" assert result.body == "a+b" def test_i_cannot_get_the_correct_concept_id_the_id_is_wrong(): sheerka = get_sheerka() concept1 = get_default_concept() concept2 = get_default_concept() concept2.metadata.body = "a+b" res1 = sheerka.create_new_concept(get_context(sheerka), concept1) res2 = sheerka.create_new_concept(get_context(sheerka), concept2) assert res1.value.body.key == res2.value.body.key # same key result = sheerka.get(concept1.key, "wrong id") assert sheerka.isinstance(result, BuiltinConcepts.UNKNOWN_CONCEPT) def test_i_cannot_get_when_key_is_none(): sheerka = get_sheerka() res = sheerka.get(None) assert sheerka.isinstance(res, BuiltinConcepts.ERROR) assert res.body == "Concept key is undefined." def test_unknown_concept_is_return_when_the_concept_is_not_found(): sheerka = get_sheerka() loaded = sheerka.get("fake_key") assert loaded is not None assert sheerka.isinstance(loaded, BuiltinConcepts.UNKNOWN_CONCEPT) assert loaded.body == "fake_key" def test_i_can_instantiate_a_builtin_concept_when_it_has_its_own_class(): sheerka = get_sheerka() ret = sheerka.new(BuiltinConcepts.RETURN_VALUE, who="who", status="status", value="value", message="message") assert isinstance(ret, ReturnValueConcept) assert ret.key == str(BuiltinConcepts.RETURN_VALUE) assert ret.who == "who" assert ret.status == "status" assert ret.value == "value" assert ret.message == "message" def test_i_can_instantiate_a_builtin_concept_when_no_specific_class(): sheerka = get_sheerka() ret = sheerka.new(BuiltinConcepts.UNKNOWN_CONCEPT, body="fake_concept") assert isinstance(ret, Concept) assert ret.key == str(BuiltinConcepts.UNKNOWN_CONCEPT) assert ret.body == "fake_concept" def test_i_can_instantiate_a_concept(): sheerka = get_sheerka() concept = get_default_concept() sheerka.create_new_concept(get_context(sheerka), concept) new = sheerka.new(concept.key, a=10, b="value") assert sheerka.isinstance(new, concept) for prop in PROPERTIES_TO_SERIALIZE: assert getattr(new.metadata, prop) == getattr(concept.metadata, prop) assert new.props["a"].value == 10 assert new.props["b"].value == "value" def test_i_can_instantiate_with_the_name_and_the_id(): sheerka = get_sheerka() sheerka.create_new_concept(get_context(sheerka), Concept("foo", body="foo1")) sheerka.create_new_concept(get_context(sheerka), Concept("foo", body="foo2")) concepts = sheerka.new("foo") assert len(concepts) == 2 foo1 = sheerka.new(("foo", "1001")) assert foo1.body == "foo1" foo2 = sheerka.new(("foo", "1002")) assert foo2.body == "foo2" def test_instances_are_different_when_asking_for_new(): sheerka = get_sheerka() concept = get_default_concept() sheerka.create_new_concept(get_context(sheerka), concept) new1 = sheerka.new(concept.key, a=10, b="value") new2 = sheerka.new(concept.key, a=10, b="value") assert new1 == new2 assert id(new1) != id(new2) def test_i_get_the_same_instance_when_is_unique_is_true(): sheerka = get_sheerka() concept = Concept(name="unique", is_unique=True) sheerka.create_new_concept(get_context(sheerka), concept) new1 = sheerka.new(concept.key, a=10, b="value") new2 = sheerka.new(concept.key, a=10, b="value") assert new1 == new2 assert id(new1) == id(new2) def test_i_cannot_instantiate_an_unknown_concept(): sheerka = get_sheerka() new = sheerka.new("fake_concept") assert sheerka.isinstance(new, BuiltinConcepts.UNKNOWN_CONCEPT) assert new.body == "fake_concept" def test_i_cannot_instantiate_with_invalid_id(): sheerka = get_sheerka() sheerka.create_new_concept(get_context(sheerka), Concept("foo", body="foo1")) sheerka.create_new_concept(get_context(sheerka), Concept("foo", body="foo2")) new = sheerka.new(("foo", "invalid_id")) assert sheerka.isinstance(new, BuiltinConcepts.UNKNOWN_CONCEPT) assert new.body == "foo" def test_i_cannot_instantiate_with_invalid_key(): sheerka = get_sheerka() sheerka.create_new_concept(get_context(sheerka), Concept("foo", body="foo1")) sheerka.create_new_concept(get_context(sheerka), Concept("foo", body="foo2")) new = sheerka.new(("invalid_key", "1001")) assert sheerka.isinstance(new, BuiltinConcepts.UNKNOWN_CONCEPT) assert new.body == "invalid_key" def test_concept_id_is_irrelevant_when_only_one_concept(): sheerka = get_sheerka() sheerka.create_new_concept(get_context(sheerka), Concept("foo", body="foo1")) new = sheerka.new(("foo", "invalid_id")) assert sheerka.isinstance(new, "foo") assert new.body == "foo1" def test_i_cannot_instantiate_when_properties_are_not_recognized(): sheerka = get_sheerka() concept = get_default_concept() sheerka.create_new_concept(get_context(sheerka), concept) new = sheerka.new(concept.key, a=10, c="value") assert sheerka.isinstance(new, BuiltinConcepts.UNKNOWN_PROPERTY) assert new.property_name == "c" assert sheerka.isinstance(new.concept, concept) @pytest.mark.parametrize("concept, reduce_simple_list, expected", [ (None, False, None), (3.14, False, 3.14), ("foo", False, "foo"), (True, False, True), (Concept("name", body="foo"), False, "foo"), (Concept("name"), False, Concept("name")), (ConceptWithGetValue("name").set_prop("my_prop", "my_value"), False, "my_value"), (ReturnValueConcept(value="return_value"), False, "return_value"), (ReturnValueConcept(value=Concept(key=BuiltinConcepts.USER_INPUT, body="text"), status=True), False, "text"), (ReturnValueConcept(value=UserInputConcept("text"), status=True), False, "text"), (Concept("name", body=["foo", "bar"]), False, ["foo", "bar"]), (Concept("name", body=["foo"]), True, "foo"), (Concept("name", body=Concept("foo")), False, Concept("foo")), (Concept("name", body=Concept("foo", body="value")), False, "value"), (Concept("name", body=Concept("foo", body=Concept("bar", body="value"))), False, "value"), (Concept("name", body=Concept("foo", body=ReturnValueConcept(value="return_value"))), False, "return_value"), ]) def test_i_can_get_value(concept, reduce_simple_list, expected): sheerka = get_sheerka() assert sheerka.value(concept, reduce_simple_list) == expected def test_list_of_concept_is_sorted_by_id(): sheerka = get_sheerka(False, False) concepts = sheerka.concepts() assert concepts[0].id < concepts[-1].id @pytest.mark.parametrize("body, expected", [ (None, None), ("", ""), ("1", 1), ("1+1", 2), ("'one'", "one"), ("'one' + 'two'", "onetwo"), ("True", True), ("1 > 2", False), ]) def test_i_can_evaluate_a_concept_with_simple_body(body, expected): sheerka = get_sheerka() concept = Concept("foo", body=body).init_key() evaluated = sheerka.evaluate_concept(get_context(sheerka), concept) assert evaluated.key == concept.key assert evaluated.body == expected assert evaluated.metadata.pre is None assert evaluated.metadata.post is None assert evaluated.metadata.where is None assert evaluated.props == {} assert evaluated.metadata.is_evaluated @pytest.mark.parametrize("expr, expected", [ ("", ""), ("1", 1), ("1+1", 2), ("'one'", "one"), ("'one' + 'two'", "onetwo"), ("True", True), ("1 > 2", False), ]) def test_i_can_evaluate_the_other_metadata(expr, expected): """ I only test WHERE, it's the same for the others :param expr: :param expected: :return: """ sheerka = get_sheerka() concept = Concept("foo", where=expr).init_key() evaluated = sheerka.evaluate_concept(get_context(sheerka), concept) assert evaluated.key == concept.key assert evaluated.body is None assert evaluated.metadata.pre is None assert evaluated.metadata.post is None assert evaluated.metadata.where == expected assert evaluated.props == {} assert evaluated.metadata.is_evaluated @pytest.mark.parametrize("expr, expected", [ # (None, None), ("", ""), ("1", 1), ("1+1", 2), ("'one'", "one"), ("'one' + 'two'", "onetwo"), ("True", True), ("1 > 2", False), ]) def test_i_can_evaluate_a_concept_with_prop(expr, expected): sheerka = get_sheerka() concept = Concept("foo").set_prop("a", expr).init_key() evaluated = sheerka.evaluate_concept(get_context(sheerka), concept) assert evaluated.key == concept.key assert evaluated.body is None assert evaluated.metadata.pre is None assert evaluated.metadata.post is None assert evaluated.metadata.where is None assert evaluated.props == {"a": Property("a", expected)} assert evaluated.metadata.is_evaluated def test_i_can_evaluate_metadata_using_do_not_resolve(): sheerka = get_sheerka() concept = Concept("foo") concept.cached_asts[ConceptParts.BODY] = DoNotResolve("do not resolve") evaluated = sheerka.evaluate_concept(get_context(sheerka), concept) assert evaluated.body == "do not resolve" assert evaluated.metadata.is_evaluated def test_i_can_evaluate_property_using_do_not_resolve(): sheerka = get_sheerka() concept = Concept("foo").set_prop("a") concept.cached_asts["a"] = DoNotResolve("do not resolve") evaluated = sheerka.evaluate_concept(get_context(sheerka), concept) assert evaluated.get_prop("a") == "do not resolve" assert evaluated.metadata.is_evaluated def test_original_value_is_overridden_when_using_do_no_resolve(): sheerka = get_sheerka() concept = Concept("foo", body="original value").set_prop("a", "original value") concept.cached_asts["a"] = DoNotResolve("do not resolve") concept.cached_asts[ConceptParts.BODY] = DoNotResolve("do not resolve") evaluated = sheerka.evaluate_concept(get_context(sheerka), concept) assert evaluated.body == "do not resolve" assert evaluated.get_prop("a") == "do not resolve" assert evaluated.metadata.is_evaluated def test_props_are_evaluated_before_body(): sheerka = get_sheerka() concept = Concept("foo", body="a+1").set_prop("a", "10").init_key() evaluated = sheerka.evaluate_concept(get_context(sheerka), concept) assert evaluated.key == concept.key assert evaluated.body == 11 def test_i_can_evaluate_when_another_concept_is_referenced(): sheerka = get_sheerka() concept_a = Concept("a") sheerka.add_in_cache(concept_a) concept = Concept("foo", body="a").init_key() evaluated = sheerka.evaluate_concept(get_context(sheerka), concept) assert evaluated.key == concept.key assert sheerka.isinstance(evaluated.body, concept_a) assert id(evaluated.body) != id(concept_a) assert evaluated.metadata.is_evaluated assert evaluated.body.metadata.is_evaluated def test_i_can_evaluate_when_the_referenced_concept_has_a_body(): sheerka = get_sheerka() concept_a = Concept("a", body="1") sheerka.add_in_cache(concept_a) concept = Concept("foo", body="a").init_key() evaluated = sheerka.evaluate_concept(get_context(sheerka), concept) assert evaluated.key == concept.key assert evaluated.body == Concept("a", body=1).init_key() assert not concept_a.metadata.is_evaluated assert evaluated.metadata.is_evaluated def test_i_can_evaluate_concept_of_concept_when_the_leaf_has_a_body(): sheerka = get_sheerka() sheerka.add_in_cache(Concept(name="a", body="'a'")) sheerka.add_in_cache(Concept(name="b", body="a")) sheerka.add_in_cache(Concept(name="c", body="b")) concept_d = sheerka.add_in_cache(Concept(name="d", body="c")) evaluated = sheerka.evaluate_concept(get_context(sheerka), concept_d) assert evaluated.key == concept_d.key assert evaluated.body == Concept( name="c", body=Concept( name="b", body=Concept( name="a", body="a").init_key()).init_key()).init_key() assert sheerka.value(evaluated) == 'a' assert evaluated.metadata.is_evaluated def test_i_can_evaluate_concept_of_concept_does_not_have_a_body(): sheerka = get_sheerka() sheerka.add_in_cache(Concept(name="a")) sheerka.add_in_cache(Concept(name="b", body="a")) sheerka.add_in_cache(Concept(name="c", body="b")) concept_d = sheerka.add_in_cache(Concept(name="d", body="c")) evaluated = sheerka.evaluate_concept(get_context(sheerka), concept_d) assert evaluated.key == concept_d.key assert evaluated.body == Concept( name="c", body=Concept( name="b", body=Concept( name="a").init_key()).init_key()).init_key() assert sheerka.value(evaluated) == Concept(name="a").init_key() assert evaluated.metadata.is_evaluated def test_i_can_evaluate_concept_when_properties_reference_others_concepts(): sheerka = get_sheerka() concept_a = sheerka.add_in_cache(Concept(name="a").init_key()) concept = Concept("foo", body="a").set_prop("a", "a").init_key() evaluated = sheerka.evaluate_concept(get_context(sheerka), concept) # first prop a is evaluated to concept_a # then body is evaluated to prop a -> concept_a assert evaluated.key == concept.key assert evaluated.body == concept_a def test_i_can_evaluate_concept_when_properties_reference_others_concepts_2(): """ Same test, but the name of the property and the name of the concept are different :return: """ sheerka = get_sheerka() concept_a = sheerka.add_in_cache(Concept(name="a")) concept = Concept("foo", body="concept_a").set_prop("concept_a", "a") evaluated = sheerka.evaluate_concept(get_context(sheerka), concept) assert evaluated.key == concept.key assert evaluated.body == concept_a def test_i_can_evaluate_concept_when_properties_reference_others_concepts_with_body(): sheerka = get_sheerka() sheerka.add_in_cache(Concept(name="a", body="1")) sheerka.add_in_cache(Concept(name="b", body="2")) concept = Concept("foo", body="propA + propB").set_prop("propA", "a").set_prop("propB", "b") evaluated = sheerka.evaluate_concept(get_context(sheerka), concept) assert evaluated.key == concept.key assert evaluated.body == 3 def test_i_can_evaluate_concept_when_properties_is_a_concept(): sheerka = get_sheerka() concept_a = sheerka.add_in_cache(Concept(name="a", body="'a'").init_key()) concept = Concept("foo").set_prop("a", concept_a) evaluated = sheerka.evaluate_concept(get_context(sheerka), concept) assert evaluated.key == concept.key assert evaluated.get_prop("a") == Concept(name="a", body="a").init_key() def test_i_can_evaluate_when_property_asts_is_a_list(): sheerka = get_sheerka() foo = Concept("foo", body="1") concept = Concept("to_eval").set_prop("prop") concept.cached_asts["prop"] = [foo, DoNotResolve("1")] evaluated = sheerka.evaluate_concept(get_context(sheerka), concept) props = evaluated.get_prop("prop") assert len(props) == 2 assert props[0] == Concept("foo", body=1).init_key() assert props[1] == "1" def test_i_can_evaluate_when_compiled_is_set_up_with_return_value(): sheerka = get_sheerka() python_node = PythonNode("1 +1 ") parser_result = ParserResultConcept(parser="who", value=python_node) concept = Concept("to_eval").set_prop("prop") concept.cached_asts["prop"] = [ReturnValueConcept("who", True, parser_result)] evaluated = sheerka.evaluate_concept(get_context(sheerka), concept) assert evaluated.get_prop("prop") == 2 # also works when only one return value concept = Concept("to_eval").set_prop("prop") concept.cached_asts["prop"] = ReturnValueConcept("who", True, parser_result) evaluated = sheerka.evaluate_concept(get_context(sheerka), concept) assert evaluated.get_prop("prop") == 2 def test_i_can_reference_sheerka(): sheerka = get_sheerka() concept = Concept("foo", body="sheerka.test()").init_key() evaluated = sheerka.evaluate_concept(get_context(sheerka), concept) assert evaluated.key == concept.key assert evaluated.body == sheerka.test() def test_properties_values_takes_precedence_over_the_outside_world(): sheerka = get_sheerka() sheerka.add_in_cache(Concept(name="a", body="'concept_a'")) sheerka.add_in_cache(Concept(name="b", body="'concept_b'")) concept = Concept("foo", body="a") evaluated = sheerka.evaluate_concept(get_context(sheerka), concept) assert evaluated.key == concept.key assert evaluated.body == Concept(name="a", body="concept_a").init_key() # this test was already done # so check this one. concept = Concept("foo", body="a").set_prop("a", "'property_a'") evaluated = sheerka.evaluate_concept(get_context(sheerka), concept) assert evaluated.key == concept.key assert evaluated.body == 'property_a' # or this one. concept = Concept("foo", body="a").set_prop("a", "b") evaluated = sheerka.evaluate_concept(get_context(sheerka), concept) assert evaluated.key == concept.key assert evaluated.body == Concept(name="b", body="concept_b").init_key() def test_properties_values_takes_precedence(): sheerka = get_sheerka() sheerka.add_in_cache(Concept(name="a", body="'concept_a'")) sheerka.add_in_cache(Concept(name="b", body="'concept_b'")) concept = Concept("foo", body="a + b").set_prop("a", "'prop_a'") evaluated = sheerka.evaluate_concept(get_context(sheerka), concept) assert evaluated.key == concept.key assert evaluated.body == 'prop_aconcept_b' def test_i_can_reference_sub_property_of_a_property(): sheerka = get_sheerka() sheerka.add_in_cache(Concept(name="concept_a").set_prop("subProp", "'sub_a'")) concept = Concept("foo", body="a.props['subProp'].value").set_prop("a", "concept_a") evaluated = sheerka.evaluate_concept(get_context(sheerka), concept) assert evaluated.key == concept.key assert evaluated.body == 'sub_a' def test_i_cannot_evaluate_concept_if_property_is_in_error(): sheerka = get_sheerka() concept = Concept(name="concept_a").set_prop("subProp", "undef_concept") evaluated = sheerka.evaluate_concept(get_context(sheerka), concept) assert sheerka.isinstance(evaluated, BuiltinConcepts.CONCEPT_EVAL_ERROR) def test_key_is_initialized_by_evaluation(): sheerka = get_sheerka() concept = Concept("foo") evaluated = sheerka.evaluate_concept(get_context(sheerka), concept) assert evaluated.key == concept.init_key().key def test_builtin_error_concept_are_errors(): # only test a random one, it will be the same for the others sheerka = get_sheerka() assert not sheerka.is_success(sheerka.new(BuiltinConcepts.TOO_MANY_SUCCESS)) def test_i_can_add_concept_to_set(): sheerka = get_sheerka(False, False) foo = Concept("foo") sheerka.set_id_if_needed(foo, False) all_foos = Concept("all_foos") sheerka.set_id_if_needed(all_foos, False) context = get_context(sheerka) res = sheerka.add_concept_to_set(context, foo, all_foos) assert res.status assert sheerka.isinstance(res.body, BuiltinConcepts.SUCCESS) all_entries = get_sheerka(False, False).sdp.get("All_" + all_foos.id, None, False) assert len(all_entries) == 1 assert foo.id in all_entries def test_i_can_add_several_concepts_to_set(): sheerka = get_sheerka(False, False) foo1 = Concept("foo1") sheerka.set_id_if_needed(foo1, False) foo2 = Concept("foo1") sheerka.set_id_if_needed(foo2, False) all_foos = Concept("all_foos") sheerka.set_id_if_needed(all_foos, False) context = get_context(sheerka) sheerka.add_concept_to_set(context, foo1, all_foos) res = sheerka.add_concept_to_set(context, foo2, all_foos) assert res.status assert sheerka.isinstance(res.body, BuiltinConcepts.SUCCESS) all_entries = get_sheerka(False, False).sdp.get("All_" + all_foos.id, None, False) assert len(all_entries) == 2 assert foo1.id in all_entries assert foo2.id in all_entries def test_i_cannot_add_the_same_concept_twice_in_a_set(): sheerka = get_sheerka() foo = Concept("foo") sheerka.set_id_if_needed(foo, False) all_foos = Concept("all_foos") sheerka.set_id_if_needed(all_foos, False) context = get_context(sheerka) sheerka.add_concept_to_set(context, foo, all_foos) res = sheerka.add_concept_to_set(context, foo, all_foos) assert not res.status assert res.body == ConceptAlreadyInSet(foo, all_foos) all_entries = sheerka.sdp.get("All_" + all_foos.id, None, False) assert len(all_entries) == 1 assert foo.id in all_entries