import pytest from core.builtin_concepts import BuiltinConcepts from core.sheerka.services.SheerkaComparisonManager import SheerkaComparisonManager, ComparisonObj from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka class TestSheerkaGreaterThanManager(TestUsingMemoryBasedSheerka): @staticmethod def execution_definition(context, service, concepts_map, definition): if ">>" in definition: a = concepts_map[definition.split(">>")[0].strip()] return service.set_is_greatest(context, "prop_name", a) if "<<" in definition: a = concepts_map[definition.split("<<")[0].strip()] return service.set_is_lesser(context, "prop_name", a) if ">" in definition: a, b = [concepts_map[e.strip()] for e in definition.split(">")] return service.set_is_greater_than(context, "prop_name", a, b) if "<" in definition: a, b = [concepts_map[e.strip()] for e in definition.split("<")] return service.set_is_less_than(context, "prop_name", a, b) def test_i_can_add_a_is_greater_than(self): sheerka, context, one, two = self.init_concepts("one", "two", cache_only=False) service = sheerka.services[SheerkaComparisonManager.NAME] res = service.set_is_greater_than(context, "prop_name", two, one) assert res.status assert sheerka.isinstance(res.body, BuiltinConcepts.SUCCESS) in_cache = sheerka.cache_manager.get(SheerkaComparisonManager.COMPARISON_ENTRY, "prop_name|#") assert in_cache == [ComparisonObj(context.event.get_digest(), "prop_name", two.id, one.id, ">", "#")] weighted = sheerka.cache_manager.get(SheerkaComparisonManager.RESOLVED_COMPARISON_ENTRY, "prop_name|#") assert weighted == {"1001": 1, "1002": 2} # I can commit sheerka.cache_manager.commit(context) in_db = sheerka.sdp.get(SheerkaComparisonManager.COMPARISON_ENTRY, "prop_name|#") assert in_db == [ComparisonObj(context.event.get_digest(), "prop_name", two.id, one.id, ">", "#")] def test_i_can_add_a_is_less_than(self): sheerka, context, one, two = self.init_concepts("one", "two", cache_only=False) service = sheerka.services[SheerkaComparisonManager.NAME] res = service.set_is_less_than(context, "prop_name", one, two) assert res.status assert sheerka.isinstance(res.body, BuiltinConcepts.SUCCESS) in_cache = sheerka.cache_manager.get(SheerkaComparisonManager.COMPARISON_ENTRY, "prop_name|#") assert in_cache == [ComparisonObj(context.event.get_digest(), "prop_name", one.id, two.id, "<", "#")] weighted = sheerka.cache_manager.get(SheerkaComparisonManager.RESOLVED_COMPARISON_ENTRY, "prop_name|#") assert weighted == {"1001": 1, "1002": 2} # I can commit sheerka.cache_manager.commit(context) in_db = sheerka.sdp.get(SheerkaComparisonManager.COMPARISON_ENTRY, "prop_name|#") assert in_db == [ComparisonObj(context.event.get_digest(), "prop_name", one.id, two.id, "<", "#")] def test_i_can_add_multiples_constraints(self): sheerka, context, one, two, three, four = self.init_concepts("one", "two", "three", "four", cache_only=False) service = sheerka.services[SheerkaComparisonManager.NAME] service.set_is_greater_than(context, "prop_name", two, one) service.set_is_greater_than(context, "prop_name", three, two) in_cache = sheerka.cache_manager.get(SheerkaComparisonManager.COMPARISON_ENTRY, "prop_name|#") assert in_cache == [ ComparisonObj(context.event.get_digest(), "prop_name", two.id, one.id, ">", "#"), ComparisonObj(context.event.get_digest(), "prop_name", three.id, two.id, ">", "#") ] # I can commit sheerka.cache_manager.commit(context) in_db = sheerka.sdp.get(SheerkaComparisonManager.COMPARISON_ENTRY, "prop_name|#") assert in_db == [ ComparisonObj(context.event.get_digest(), "prop_name", two.id, one.id, ">", "#"), ComparisonObj(context.event.get_digest(), "prop_name", three.id, two.id, ">", "#") ] sheerka.cache_manager.clear(SheerkaComparisonManager.COMPARISON_ENTRY) # reset the cache service.set_is_greater_than(context, "prop_name", four, three) in_cache = sheerka.cache_manager.get(SheerkaComparisonManager.COMPARISON_ENTRY, "prop_name|#") assert in_cache == [ ComparisonObj(context.event.get_digest(), "prop_name", two.id, one.id, ">", "#"), ComparisonObj(context.event.get_digest(), "prop_name", three.id, two.id, ">", "#"), ComparisonObj(context.event.get_digest(), "prop_name", four.id, three.id, ">", "#"), ] weighted = sheerka.cache_manager.get(SheerkaComparisonManager.RESOLVED_COMPARISON_ENTRY, "prop_name|#") assert weighted == {"1001": 1, "1002": 2, "1003": 3, "1004": 4} @pytest.mark.parametrize("entries, expected", [ (["two > one"], {'1001': 1, '1002': 2}), (["one < two"], {'1001': 1, '1002': 2}), (["three > two", "one < two"], {'1001': 1, '1002': 2, '1003': 3}), (["three > one", "one < two"], {'1001': 1, '1002': 2, '1003': 2}), (["three >>"], {'1003': 2}), (["one <<"], {'1001': 0}), ]) def test_i_can_get_concept_weight(self, entries, expected): sheerka, context, *concepts = self.init_concepts("one", "two", "three") service = sheerka.services[SheerkaComparisonManager.NAME] concepts_map = dict(zip(["one", "two", "three"], concepts)) for entry in entries: self.execution_definition(context, service, concepts_map, entry) assert service.get_concepts_weights("prop_name") == expected def test_i_can_get_concept_weight_when_no_comparison_is_defined(self): sheerka, context = self.init_concepts() service = sheerka.services[SheerkaComparisonManager.NAME] assert service.get_concepts_weights("prop_name") == {} def test_i_can_recover_from_deleted_weight(self): sheerka, context, one = self.init_concepts("one") service = sheerka.services[SheerkaComparisonManager.NAME] service.set_is_lesser(context, "prop_name", one) sheerka.cache_manager.clear(service.RESOLVED_COMPARISON_ENTRY) assert service.get_concepts_weights("prop_name") == {"1001": 0} def test_i_can_get_partition(self): sheerka, context, one, two, three = self.init_concepts("one", "two", "three") service = sheerka.services[SheerkaComparisonManager.NAME] service.set_is_greater_than(context, "prop_name", two, one) service.set_is_less_than(context, "prop_name", two, three) res = service.get_partition("prop_name") assert res == { 1: ["1001"], 2: ["1002"], 3: ["1003"], } def test_i_can_detect_chicken_and_egg(self): sheerka, context, one, two = self.init_concepts("one", "two") service = sheerka.services[SheerkaComparisonManager.NAME] service.set_is_greater_than(context, "prop_name", two, one) res = service.set_is_greater_than(context, "prop_name", one, two) assert not res.status assert sheerka.isinstance(res.body, BuiltinConcepts.CHICKEN_AND_EGG) assert set(res.body.body) == {one, two} def test_i_can_detect_more_complex_chicken_and_egg(self): sheerka, context, one, two, three, four, five = self.init_concepts("one", "two", "three", "four", "five") service = sheerka.services[SheerkaComparisonManager.NAME] service.set_is_greater_than(context, "prop_name", two, one) service.set_is_greater_than(context, "prop_name", five, four) service.set_is_greater_than(context, "prop_name", four, three) service.set_is_greater_than(context, "prop_name", five, two) res = service.set_is_greater_than(context, "prop_name", one, five) assert not res.status assert sheerka.isinstance(res.body, BuiltinConcepts.CHICKEN_AND_EGG) assert set(res.body.body) == {one, two, five} def test_i_can_give_the_same_information_in_many_ways(self): sheerka, context, one, two = self.init_concepts("one", "two") service = sheerka.services[SheerkaComparisonManager.NAME] service.set_is_greater_than(context, "prop_name", two, one) service.set_is_less_than(context, "prop_name", one, two) weighted = sheerka.cache_manager.get(SheerkaComparisonManager.RESOLVED_COMPARISON_ENTRY, "prop_name|#") assert weighted == {"1001": 1, "1002": 2} def test_methods_are_correctly_bound(self): sheerka, context, one, two = self.init_concepts("one", "two") res = sheerka.set_is_greater_than(context, "prop_name", two, one) assert res.status def test_a_lesser_concept_has_the_lowest_weight(self): sheerka, context, one, two, three = self.init_concepts("one", "two", "three", cache_only=False) service = sheerka.services[SheerkaComparisonManager.NAME] service.set_is_lesser(context, "prop_name", one) assert service.get_concepts_weights("prop_name") == {"1001": 0} # DEFAULT_COMPARISON_VALUE - 1 sheerka.set_is_greater_than(context, "prop_name", three, two) assert service.get_concepts_weights("prop_name") == {"1001": 0, "1002": 1, "1003": 2} # I can commit sheerka.cache_manager.commit(context) in_db = sheerka.sdp.get(SheerkaComparisonManager.COMPARISON_ENTRY, "prop_name|#") assert in_db == [ ComparisonObj(context.event.get_digest(), "prop_name", one.id, None, "<<", "#"), ComparisonObj(context.event.get_digest(), "prop_name", three.id, two.id, ">", "#") ] def test_i_can_define_an_order_for_lesser_concepts(self): sheerka, context, lesser, less_l, even_more_l = self.init_concepts("lesser", "less_l", "even_less_l") service = sheerka.services[SheerkaComparisonManager.NAME] service.set_is_lesser(context, "prop_name", lesser) service.set_is_lesser(context, "prop_name", less_l) service.set_is_lesser(context, "prop_name", even_more_l) sheerka.set_is_less_than(context, "prop_name", less_l, lesser) sheerka.set_is_greater_than(context, "prop_name", less_l, even_more_l) assert service.get_concepts_weights("prop_name") == {"1001": 0, "1002": -1, "1003": -2} def test_i_cannot_define_less_than_a_lesser_if_not_a_lesser_itself(self): """ minus_one cannot be defined as less that one is one is defined as lesser unless minus_one is defined as lesser itself :return: """ sheerka, context, lesser, foo = self.init_concepts("lesser", "foo") service = sheerka.services[SheerkaComparisonManager.NAME] service.set_is_lesser(context, "prop_name", lesser) res = sheerka.set_is_less_than(context, "prop_name", foo, lesser) assert not res.status assert sheerka.isinstance(res.body, BuiltinConcepts.INVALID_LESSER_OPERATION) res = sheerka.set_is_greater_than(context, "prop_name", foo, lesser) assert not res.status assert sheerka.isinstance(res.body, BuiltinConcepts.INVALID_LESSER_OPERATION) def test_a_greatest_concept_has_the_highest_weight(self): sheerka, context, one, two, three = self.init_concepts("one", "two", "three") service = sheerka.services[SheerkaComparisonManager.NAME] service.set_is_greatest(context, "prop_name", three) assert service.get_concepts_weights("prop_name") == {"1003": 2} # DEFAULT_COMPARISON_VALUE + 1 sheerka.set_is_greater_than(context, "prop_name", two, one) assert service.get_concepts_weights("prop_name") == {"1001": 1, "1002": 2, "1003": 3} def test_i_cannot_define_greater_than_a_greatest_if_not_a_greater_itself(self): sheerka, context, greatest, foo = self.init_concepts("greatest", "foo") service = sheerka.services[SheerkaComparisonManager.NAME] service.set_is_greatest(context, "prop_name", greatest) res = sheerka.set_is_less_than(context, "prop_name", foo, greatest) assert not res.status assert sheerka.isinstance(res.body, BuiltinConcepts.INVALID_GREATEST_OPERATION) res = sheerka.set_is_greater_than(context, "prop_name", foo, greatest) assert not res.status assert sheerka.isinstance(res.body, BuiltinConcepts.INVALID_GREATEST_OPERATION) @pytest.mark.parametrize("definitions, expected", [ (["foo >>", "foo <<"], BuiltinConcepts.INVALID_GREATEST_OPERATION), (["foo <<", "foo >>"], BuiltinConcepts.INVALID_LESSER_OPERATION), ]) def test_i_cannot_define_a_concept_as_lesser_and_greatest_at_the_same_time(self, definitions, expected): sheerka, context, foo = self.init_concepts("foo") service = sheerka.services[SheerkaComparisonManager.NAME] concepts_map = {"foo": foo} self.execution_definition(context, service, concepts_map, definitions[0]) res = self.execution_definition(context, service, concepts_map, definitions[1]) assert not res.status assert sheerka.isinstance(res.body, expected) def test_i_can_define_an_order_for_greatest_concepts(self): sheerka, context, greatest, more_g, even_more_g = self.init_concepts("greatest", "more_g", "even_more_g") service = sheerka.services[SheerkaComparisonManager.NAME] service.set_is_greatest(context, "prop_name", greatest) service.set_is_greatest(context, "prop_name", more_g) service.set_is_greatest(context, "prop_name", even_more_g) sheerka.set_is_less_than(context, "prop_name", greatest, more_g) sheerka.set_is_greater_than(context, "prop_name", even_more_g, more_g) assert service.get_concepts_weights("prop_name") == {"1001": 2, "1002": 3, "1003": 4} def test_i_can_mix_all_comparisons(self): sheerka, context, one, two, three, four, five, six, three_and_half = self.init_concepts( "one", "two", "three", "four", "five", "six", "two_and_half") service = sheerka.services[SheerkaComparisonManager.NAME] service.set_is_lesser(context, "prop_name", one) service.set_is_lesser(context, "prop_name", two) sheerka.set_is_less_than(context, "prop_name", one, two) service.set_is_greatest(context, "prop_name", five) service.set_is_greatest(context, "prop_name", six) sheerka.set_is_greater_than(context, "prop_name", six, five) sheerka.set_is_less_than(context, "prop_name", three, four) assert service.get_concepts_weights("prop_name") == { "1001": -1, "1002": 0, "1003": 1, "1004": 2, "1005": 3, "1006": 4 } sheerka.set_is_less_than(context, "prop_name", three_and_half, four) sheerka.set_is_greater_than(context, "prop_name", three_and_half, three) assert service.get_concepts_weights("prop_name") == { "1001": -1, "1002": 0, "1003": 1, "1007": 2, "1004": 3, "1005": 4, "1006": 5 } @pytest.mark.parametrize("definition", [ "one >>", "one <<", "one > two", "one < two", ]) def test_i_cannot_add_the_same_definition_twice(self, definition): sheerka, context, *concepts = self.init_concepts("one", "two") service = sheerka.services[SheerkaComparisonManager.NAME] concepts_map = dict(zip(["one", "two"], concepts)) self.execution_definition(context, service, concepts_map, definition) res = self.execution_definition(context, service, concepts_map, definition) assert not res.status assert sheerka.isinstance(res.body, BuiltinConcepts.CONCEPT_ALREADY_DEFINED)