from dataclasses import dataclass import pytest from core.builtin_concepts_ids import BuiltinConcepts from core.concept import Concept from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka @dataclass class A: prop1: object prop2: object def __eq__(self, other): if not isinstance(other, A): return False return self.prop1 == other.prop1 and self.prop2 == other.prop2 def __hash__(self): hash_res = [] for p in [self.prop1, self.prop2]: hash_res.append(0 if isinstance(p, (list, dict, set)) else p) return hash(tuple(hash_res)) @dataclass class B(A): def as_bag(self): return { "fake_prop1": self.prop1, "fake_prop2": self.prop2 } def __hash__(self): return hash((self.prop1, self.prop2)) class TestSheerkaQueryManager(TestUsingMemoryBasedSheerka): def test_i_can_filter_objects_using_kwargs(self): sheerka, context = self.init_test().unpack() lst = [A("a11", 10), A("a21", 3.14), A({1, "v"}, 0xab), A([0, 1], {"key": "value"})] assert sheerka.filter_objects(context, lst, prop1="a21") == [lst[1]] assert sheerka.filter_objects(context, lst, prop2=10) == [lst[0]] assert sheerka.filter_objects(context, lst, prop2=3.14) == [lst[1]] assert sheerka.filter_objects(context, lst, prop2=0xab) == [lst[2]] assert sheerka.filter_objects(context, lst, prop1=[0, 1]) == [lst[3]] assert sheerka.filter_objects(context, lst, prop2={"key": "value"}) == [lst[3]] # assert sheerka.filter_objects(context, lst, prop1={1, "v"}) == [lst[2]] set are not supported # complex properties assert sheerka.filter_objects(context, lst, prop1_contains="a") == [lst[0], lst[1]] assert sheerka.filter_objects(context, lst, prop1_contains=1) == [lst[2], lst[3]] def test_i_can_filter_by_object_type(self): sheerka, context = self.init_test().unpack() lst = [A("a11", "a12"), Concept("foo", body="a").auto_init(), Concept("foo", body="b").auto_init()] assert sheerka.filter_objects(context, lst, __type="foo") == [lst[1], lst[2]] def test_i_can_filter_on_as_bag_property(self): sheerka, context = self.init_test().unpack() lst = [B("a11", "a12"), B("a21", "a22"), B("a31", "a32")] assert sheerka.filter_objects(context, lst, fake_prop1="a21") == [lst[1]] def test_i_can_filter_container(self): sheerka, context = self.init_test().unpack() lst = [A("a11", 10), A("a21", 3.14), A({1, "v"}, 0xab), A([0, 1], {"key": "value"})] container = sheerka.new(BuiltinConcepts.EXPLANATION, body=lst, digest="xxx", command="text") res = sheerka.filter_objects(context, container, prop1="a21") assert sheerka.isinstance(res, BuiltinConcepts.EXPLANATION) assert res.digest == "xxx" assert res.command == "text" assert res.body == [lst[1]] def test_i_can_filter_when_property_does_not_exist(self): sheerka, context = self.init_test().unpack() lst = [A("a11", "a12"), B("a21", "a22"), B("a31", "a32")] assert sheerka.filter_objects(context, lst, prop1="a11") == [lst[0]] def test_i_can_filter_objets_using_predicate(self): sheerka, context = self.init_test().unpack() lst = [A("a11", 10), A("a21", 3.14), A({1, "v"}, 0xab), A([0, 1], {"key": "value"}), Concept("foo", body="a").auto_init(), B("a21", "a22"), Concept("foo", body="b").auto_init(), B("a31", "a32")] assert sheerka.filter_objects(context, lst, "self.prop1 == 'a21'") == [lst[1]] assert sheerka.filter_objects(context, lst, "self.prop2 >= 1") == [lst[0], lst[1], lst[2]] assert sheerka.filter_objects(context, lst, "get_type(self) == 'foo' ") == [lst[4], lst[6]] assert sheerka.filter_objects(context, lst, "self.fake_prop1 == 'a21' ") == [lst[5]] assert sheerka.filter_objects(context, lst, "hasattr(self, 'fake_prop1')") == [lst[5], lst[7]] def test_i_can_filter_object_using_predicate_and_sheerka_objects(self): sheerka, context, foo, bar = self.init_concepts("foo", "bar") lst = [foo, bar, A("a21", 3.14)] assert sheerka.filter_objects(context, lst, "self == bar") == [lst[1]] def test_i_can_filter_objects_using_concept(self): sheerka, context, foo, bar, isa = self.init_concepts( "foo", "bar", Concept("x is a concept", body="isinstance(x, Concept)", pre="is_question()").def_var("x"), create_new=True) lst = [foo, A("a21", 3.14), bar, B("a21", 3.14)] assert sheerka.filter_objects(context, lst, "self is a concept") == [foo, bar] def test_i_can_filter_objects_when_no_kwargs_and_no_predicate(self): sheerka, context, foo, bar = self.init_concepts("foo", "bar") lst = [foo, bar, A("a21", 3.14)] assert sheerka.filter_objects(context, lst) == lst def test_i_must_select_object_property_using_string(self): sheerka, context = self.init_test().unpack() with pytest.raises(SyntaxError): sheerka.select_objects(context, [], 00) def test_i_can_select_objects_with_args(self): sheerka, context = self.init_test().unpack() lst = [A("a11", 10), A("a21", 3.14), A({1, "v"}, 0xab), A([0, 1], {"key": "value"})] assert sheerka.select_objects(context, lst, "prop1", "prop2") == ( ('a11', 10), ('a21', 3.14), ({1, 'v'}, 171), ([0, 1], {'key': 'value'})) def test_i_can_select_objects_when_container(self): sheerka, context = self.init_test().unpack() lst = [A("a11", 10), A("a21", 3.14), A({1, "v"}, 0xab), A([0, 1], {"key": "value"})] container = sheerka.new(BuiltinConcepts.EXPLANATION, body=lst, digest="xxx", command="text") res = sheerka.select_objects(context, container, "prop1", "prop2") assert sheerka.isinstance(res, BuiltinConcepts.EXPLANATION) assert res.digest == "xxx" assert res.command == "text" assert res.body == (('a11', 10), ('a21', 3.14), ({1, 'v'}, 171), ([0, 1], {'key': 'value'})) def test_i_can_select_objects_with_complicated_request(self): sheerka, context = self.init_test().unpack() lst = [A("a11", 10), A("a21", 3.14), A({1, "v"}, 0xab)] assert sheerka.select_objects(context, lst, "self.prop2 + 5") == (15, 8.14, 0xab + 5) assert sheerka.select_objects(context, lst, "isinstance(self.prop1, str)") == (True, True, False) def test_error_when_collecting_returns_are_managed(self): sheerka, context = self.init_test().unpack() lst = [A("a11", 10), A("a21", {"key": "value"})] res = sheerka.select_objects(context, lst, "self.prop2 + 5") assert len(res) == 2 assert res[0] == 15 assert isinstance(res[1], TypeError) def test_i_can_select_objects_using_kwargs(self): sheerka, context = self.init_test().unpack() lst = [A("a11", 10), A("a21", 3.14), A({1, "v"}, 0xab), A([0, 1], {"key": "value"})] assert sheerka.select_objects(context, lst, p1="prop1", p2="prop2") == ( {"p1": "a11", "p2": 10}, {"p1": "a21", "p2": 3.14}, {"p1": {1, "v"}, "p2": 0xab}, {"p1": [0, 1], "p2": {"key": "value"}}, ) def test_i_can_collect_attributes(self): sheerka = self.get_sheerka() lst = [A("", ""), B("", ""), Concept("foo").def_var("a").auto_init(), Concept("bar").def_var("y").def_var("x").auto_init()] res = sheerka.collect_attributes(lst) assert sheerka.isinstance(res, BuiltinConcepts.TO_DICT) assert res.body == { "A": ["prop1", "prop2"], "B": ["fake_prop1", "fake_prop2"], "foo": ["a", 'body', 'id', 'key', 'name'], "bar": ['body', 'id', 'key', 'name', "x", "y"] # attributes are sorted }