Fixed #3: Added sheerka.resolve_rule()
Fixed #5: Refactored SheerkaComparisonManager Fixed #6: Sya parser no longer works after restart
This commit is contained in:
@@ -1,16 +1,35 @@
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from core.global_symbols import EVENT_CONCEPT_PRECEDENCE_MODIFIED, CONCEPT_COMPARISON_CONTEXT, \
|
||||
EVENT_RULE_PRECEDENCE_MODIFIED, \
|
||||
RULE_COMPARISON_CONTEXT
|
||||
EVENT_RULE_PRECEDENCE_MODIFIED, RULE_COMPARISON_CONTEXT
|
||||
from core.sheerka.services.SheerkaComparisonManager import SheerkaComparisonManager, ComparisonObj
|
||||
|
||||
from core.sheerka.services.SheerkaConceptManager import ChickenAndEggError
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
class TestSheerkaGreaterThanManager(TestUsingMemoryBasedSheerka):
|
||||
|
||||
@staticmethod
|
||||
def get_comparison_objs(lst, prop_name="prop_name", context="#"):
|
||||
for item in lst:
|
||||
if ">>" in item:
|
||||
a = item.split(">>")[0]
|
||||
yield ComparisonObj("id", prop_name, a.strip(), None, ">>", context)
|
||||
elif "<<" in item:
|
||||
a = item.split("<<")[0]
|
||||
yield ComparisonObj("id", prop_name, a.strip(), None, "<<", context)
|
||||
elif ">" in item:
|
||||
a, b = item.split(">")
|
||||
yield ComparisonObj("id", prop_name, a.strip(), b.strip(), ">", context)
|
||||
elif "<" in item:
|
||||
a, b = item.split("<")
|
||||
yield ComparisonObj("id", prop_name, a.strip(), b.strip(), "<", context)
|
||||
else:
|
||||
a, b = item.split("=")
|
||||
yield ComparisonObj("id", prop_name, a.strip(), b.strip(), "=", context)
|
||||
|
||||
@staticmethod
|
||||
def execution_definition(context, service, concepts_map, definition):
|
||||
if ">>" in definition:
|
||||
@@ -214,13 +233,13 @@ class TestSheerkaGreaterThanManager(TestUsingMemoryBasedSheerka):
|
||||
for entry in entries:
|
||||
self.execution_definition(context, service, concepts_map, entry)
|
||||
|
||||
assert service.get_concepts_weights("prop_name") == expected
|
||||
assert service.get_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") == {}
|
||||
assert service.get_weights("prop_name") == {}
|
||||
|
||||
def test_i_can_recover_from_deleted_weight(self):
|
||||
sheerka, context, one = self.init_concepts("one")
|
||||
@@ -229,7 +248,7 @@ class TestSheerkaGreaterThanManager(TestUsingMemoryBasedSheerka):
|
||||
service.set_is_lesser(context, "prop_name", one)
|
||||
sheerka.om.clear(service.RESOLVED_COMPARISON_ENTRY)
|
||||
|
||||
assert service.get_concepts_weights("prop_name") == {"c:one|1001:": 0}
|
||||
assert service.get_weights("prop_name") == {"c:one|1001:": 0}
|
||||
|
||||
def test_i_can_get_partition(self):
|
||||
sheerka, context, one, two, three = self.init_concepts("one", "two", "three")
|
||||
@@ -246,6 +265,38 @@ class TestSheerkaGreaterThanManager(TestUsingMemoryBasedSheerka):
|
||||
3: ["c:three|1003:"],
|
||||
}
|
||||
|
||||
def test_i_can_toposort(self):
|
||||
# using sample test from https://code.activestate.com/recipes/578272-topological-sort/
|
||||
comparison_objs = self.get_comparison_objs([
|
||||
"2 < 11",
|
||||
"11 > 9",
|
||||
"9 < 8",
|
||||
"10 < 11",
|
||||
"3 > 10",
|
||||
"11 < 7",
|
||||
"11 < 5",
|
||||
"7 > 8",
|
||||
"3 > 8"])
|
||||
assert list(SheerkaComparisonManager.toposort(comparison_objs)) == [{'2', '9', '10'},
|
||||
{'8', '11'},
|
||||
{'3', '5', '7'}]
|
||||
|
||||
def test_i_can_toposort_when_no_data(self):
|
||||
assert list(SheerkaComparisonManager.toposort([])) == []
|
||||
|
||||
def test_i_cannot_toposort_when_cycle(self):
|
||||
comparison_objs = self.get_comparison_objs([
|
||||
"1 < 2",
|
||||
"2 < 3",
|
||||
"3 < 1",
|
||||
"1 < 4", # no issue with this
|
||||
"2 < 5", # no issue with this
|
||||
])
|
||||
with pytest.raises(ChickenAndEggError) as ex:
|
||||
list(SheerkaComparisonManager.toposort(comparison_objs))
|
||||
|
||||
assert ex.value.concepts == {"1", "2", "3"}
|
||||
|
||||
def test_i_can_detect_chicken_and_egg(self):
|
||||
sheerka, context, one, two = self.init_concepts("one", "two")
|
||||
service = sheerka.services[SheerkaComparisonManager.NAME]
|
||||
@@ -255,7 +306,7 @@ class TestSheerkaGreaterThanManager(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.CHICKEN_AND_EGG)
|
||||
assert set(res.body.body) == {one, two}
|
||||
assert set(res.body.body) == {one.str_id, two.str_id}
|
||||
|
||||
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")
|
||||
@@ -270,7 +321,7 @@ class TestSheerkaGreaterThanManager(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.CHICKEN_AND_EGG)
|
||||
assert set(res.body.body) == {one, two, five}
|
||||
assert set(res.body.body) == {one.str_id, two.str_id, five.str_id}
|
||||
|
||||
def test_i_can_give_the_same_information_in_many_ways(self):
|
||||
sheerka, context, one, two = self.init_concepts("one", "two")
|
||||
@@ -292,10 +343,10 @@ class TestSheerkaGreaterThanManager(TestUsingMemoryBasedSheerka):
|
||||
service = sheerka.services[SheerkaComparisonManager.NAME]
|
||||
|
||||
service.set_is_lesser(context, "prop_name", one)
|
||||
assert service.get_concepts_weights("prop_name") == {"c:one|1001:": 0} # DEFAULT_COMPARISON_VALUE - 1
|
||||
assert service.get_weights("prop_name") == {"c:one|1001:": 0} # DEFAULT_COMPARISON_VALUE - 1
|
||||
|
||||
sheerka.set_is_greater_than(context, "prop_name", three, two)
|
||||
assert service.get_concepts_weights("prop_name") == {"c:one|1001:": 0, "c:two|1002:": 1, "c:three|1003:": 2}
|
||||
assert service.get_weights("prop_name") == {"c:one|1001:": 0, "c:two|1002:": 1, "c:three|1003:": 2}
|
||||
|
||||
# I can commit
|
||||
sheerka.om.commit(context)
|
||||
@@ -315,7 +366,7 @@ class TestSheerkaGreaterThanManager(TestUsingMemoryBasedSheerka):
|
||||
|
||||
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") == {"c:lesser|1001:": 0,
|
||||
assert service.get_weights("prop_name") == {"c:lesser|1001:": 0,
|
||||
"c:less_l|1002:": -1,
|
||||
"c:even_less_l|1003:": -2}
|
||||
|
||||
@@ -325,46 +376,46 @@ class TestSheerkaGreaterThanManager(TestUsingMemoryBasedSheerka):
|
||||
unless minus_one is defined as lesser itself
|
||||
:return:
|
||||
"""
|
||||
sheerka, context, lesser, foo = self.init_concepts("lesser", "foo")
|
||||
sheerka, context, lesser, foo, bar = self.init_concepts("lesser", "foo", "bar")
|
||||
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)
|
||||
|
||||
# sanity check
|
||||
res = sheerka.set_is_greater_than(context, "prop_name", foo, lesser)
|
||||
assert res.status
|
||||
|
||||
res = sheerka.set_is_less_than(context, "prop_name", bar, lesser)
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.INVALID_LESSER_OPERATION)
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.IS_LESSER_CONSTRAINT_ERROR)
|
||||
|
||||
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") == {"c:three|1003:": 2} # DEFAULT_COMPARISON_VALUE + 1
|
||||
assert service.get_weights("prop_name") == {"c:three|1003:": 2} # DEFAULT_COMPARISON_VALUE + 1
|
||||
|
||||
sheerka.set_is_greater_than(context, "prop_name", two, one)
|
||||
assert service.get_concepts_weights("prop_name") == {"c:one|1001:": 1, "c:two|1002:": 2, "c:three|1003:": 3}
|
||||
assert service.get_weights("prop_name") == {"c:one|1001:": 1, "c:two|1002:": 2, "c:three|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")
|
||||
sheerka, context, greatest, foo, bar = self.init_concepts("greatest", "foo", "bar")
|
||||
service = sheerka.services[SheerkaComparisonManager.NAME]
|
||||
|
||||
service.set_is_greatest(context, "prop_name", greatest)
|
||||
|
||||
# sanity check
|
||||
res = sheerka.set_is_less_than(context, "prop_name", foo, greatest)
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.INVALID_GREATEST_OPERATION)
|
||||
assert res.status
|
||||
|
||||
res = sheerka.set_is_greater_than(context, "prop_name", foo, greatest)
|
||||
res = sheerka.set_is_greater_than(context, "prop_name", bar, greatest)
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.INVALID_GREATEST_OPERATION)
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.IS_GREATEST_CONSTRAINT_ERROR)
|
||||
|
||||
@pytest.mark.parametrize("definitions, expected", [
|
||||
(["foo >>", "foo <<"], BuiltinConcepts.INVALID_GREATEST_OPERATION),
|
||||
(["foo <<", "foo >>"], BuiltinConcepts.INVALID_LESSER_OPERATION),
|
||||
(["foo >>", "foo <<"], BuiltinConcepts.IS_GREATEST_CONSTRAINT_ERROR),
|
||||
(["foo <<", "foo >>"], BuiltinConcepts.IS_LESSER_CONSTRAINT_ERROR),
|
||||
])
|
||||
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")
|
||||
@@ -386,7 +437,7 @@ class TestSheerkaGreaterThanManager(TestUsingMemoryBasedSheerka):
|
||||
|
||||
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") == {"c:greatest|1001:": 2,
|
||||
assert service.get_weights("prop_name") == {"c:greatest|1001:": 2,
|
||||
"c:more_g|1002:": 3,
|
||||
"c:even_more_g|1003:": 4}
|
||||
|
||||
@@ -405,7 +456,7 @@ class TestSheerkaGreaterThanManager(TestUsingMemoryBasedSheerka):
|
||||
|
||||
sheerka.set_is_less_than(context, "prop_name", three, four)
|
||||
|
||||
assert service.get_concepts_weights("prop_name") == {
|
||||
assert service.get_weights("prop_name") == {
|
||||
"c:one|1001:": -1,
|
||||
"c:two|1002:": 0,
|
||||
"c:three|1003:": 1,
|
||||
@@ -417,7 +468,7 @@ class TestSheerkaGreaterThanManager(TestUsingMemoryBasedSheerka):
|
||||
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") == {
|
||||
assert service.get_weights("prop_name") == {
|
||||
"c:one|1001:": -1,
|
||||
"c:two|1002:": 0,
|
||||
"c:three|1003:": 1,
|
||||
@@ -446,7 +497,7 @@ class TestSheerkaGreaterThanManager(TestUsingMemoryBasedSheerka):
|
||||
service.set_is_greater_than(context, "prop_name", five, one)
|
||||
service.set_is_greater_than(context, "prop_name", five, three)
|
||||
|
||||
assert service.get_concepts_weights("prop_name") == {
|
||||
assert service.get_weights("prop_name") == {
|
||||
"c:zero|1001:": 0,
|
||||
"c:one|1002:": 1,
|
||||
"c:two|1003:": 2,
|
||||
@@ -471,7 +522,7 @@ class TestSheerkaGreaterThanManager(TestUsingMemoryBasedSheerka):
|
||||
res = self.execution_definition(context, service, concepts_map, definition)
|
||||
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.CONCEPT_ALREADY_DEFINED)
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.COMPARISON_ALREADY_DEFINED)
|
||||
|
||||
def test_an_event_is_fired_when_modifying_concepts_precedence(self):
|
||||
sheerka, context, one, two, foo = self.init_concepts("one", "two", "foo")
|
||||
@@ -514,3 +565,170 @@ class TestSheerkaGreaterThanManager(TestUsingMemoryBasedSheerka):
|
||||
|
||||
sheerka.set_is_greater_than(context, BuiltinConcepts.PRECEDENCE, r1, r2, RULE_COMPARISON_CONTEXT)
|
||||
assert event_received
|
||||
|
||||
@pytest.mark.parametrize("entries, expected", [
|
||||
([], (set(), set(), set())),
|
||||
(["a<<", "a<<", "b<<", "a<c"], (set(), {"a", "b"}, {"a", "b", "c"})),
|
||||
(["a>>", "a>>", "b>>", "a<c"], ({"a", "b"}, set(), {"a", "b", "c"})),
|
||||
(["a<<", "b>>", "c=d", "e<f", "g>h"], ({"b"}, {"a"}, {"a", "b", "c", "d", "e", "f", "g", "h"})),
|
||||
])
|
||||
def test_i_can_get_objs_groups(self, entries, expected):
|
||||
comparison_objs = self.get_comparison_objs(entries)
|
||||
assert SheerkaComparisonManager.get_objs_groups(comparison_objs) == expected
|
||||
|
||||
@pytest.mark.parametrize("entries, greatest, lowest, expected_tuple", [
|
||||
# greatest
|
||||
(["a < b"], {"a", "b"}, set(), (["a < b"], [], [], [])),
|
||||
(["a > b"], {"a", "b"}, set(), (["a > b"], [], [], [])),
|
||||
|
||||
# lowest
|
||||
(["a < b"], set(), {"a", "b"}, ([], ["a < b"], [], [])),
|
||||
(["a > b"], set(), {"a", "b"}, ([], ["a > b"], [], [])),
|
||||
|
||||
# equiv
|
||||
(["a = b"], set(), set(), ([], [], ["a = b"], [])),
|
||||
|
||||
# neither
|
||||
(["a < b"], set(), set(), ([], [], [], ["a < b"])),
|
||||
(["a > b"], set(), set(), ([], [], [], ["a > b"])),
|
||||
|
||||
# irrelevant information
|
||||
(["a > b"], {"a"}, set(), ([], [], [], [])),
|
||||
(["a > b"], set(), {"b"}, ([], [], [], [])),
|
||||
(["a < b"], {"b"}, set(), ([], [], [], [])),
|
||||
(["a < b"], set(), {"a"}, ([], [], [], [])),
|
||||
|
||||
# mixed
|
||||
(["a<b", "c<d", "e<f", "z=b"], {"a", "b", "c", "d"}, set(), (["a<b", "c<d"], [], ["z=b"], ["e<f"])),
|
||||
])
|
||||
def test_i_can_group_comparison_objs(self, entries, greatest, lowest, expected_tuple):
|
||||
comparison_objs = self.get_comparison_objs(entries)
|
||||
g, l, e, o = SheerkaComparisonManager.group_comparison_objs(comparison_objs, greatest, lowest)
|
||||
|
||||
def compare_results(actual_result, expected_result):
|
||||
assert len(actual_result) == len(expected_result)
|
||||
for actual, expected in zip(actual_result, expected_result):
|
||||
expected_comparison_obj = list(self.get_comparison_objs([expected]))[0]
|
||||
assert actual.a == expected_comparison_obj.a
|
||||
assert actual.b == expected_comparison_obj.b
|
||||
assert actual.op == expected_comparison_obj.op
|
||||
|
||||
compare_results(g, expected_tuple[0])
|
||||
compare_results(l, expected_tuple[1])
|
||||
compare_results(e, expected_tuple[2])
|
||||
compare_results(o, expected_tuple[3])
|
||||
|
||||
@pytest.mark.parametrize("entries, expected", [
|
||||
([], {}),
|
||||
(["a < b"], {"a": 1, "b": 2}),
|
||||
(["a > b"], {"a": 2, "b": 1}),
|
||||
(["a < b", "b > a"], {"a": 1, "b": 2}),
|
||||
(["a < b", "b < c"], {"a": 1, "b": 2, "c": 3}),
|
||||
(["a < b", "a < c"], {"a": 1, "b": 2, "c": 2}),
|
||||
|
||||
# greatest between themselves
|
||||
(["a < b", "a>>", "b>>"], {"a": 2, "b": 3}),
|
||||
(["a > b", "a>>", "b>>"], {"a": 3, "b": 2}),
|
||||
(["a < b", "b > a", "a>>", "b>>"], {"a": 2, "b": 3}),
|
||||
(["a < b", "b < c", "a>>", "b>>", "c>>"], {"a": 2, "b": 3, "c": 4}),
|
||||
(["a < b", "a < c", "a>>", "b>>", "c>>"], {"a": 2, "b": 3, "c": 3}),
|
||||
|
||||
# lowest between themselves
|
||||
(["a < b", "a<<", "b<<"], {"a": -1, "b": 0}),
|
||||
(["a > b", "a<<", "b<<"], {"a": 0, "b": -1}),
|
||||
(["a < b", "b > a", "a<<", "b<<"], {"a": -1, "b": 0}),
|
||||
(["a < b", "b < c", "a<<", "b<<", "c<<"], {"a": -2, "b": -1, "c": 0}),
|
||||
(["a < b", "a < c", "a<<", "b<<", "c<<"], {"a": -1, "b": 0, "c": 0}),
|
||||
|
||||
# greatest that does not appear in other relations
|
||||
(["a >>", "b < c"], {"a": 3, "b": 1, "c": 2}),
|
||||
(["a >>", "a > b"], {"a": 2, "b": 1}),
|
||||
(["a >>", "a > b", "c > d", "d > e"], {"a": 4, "b": 1, "c": 3, "d": 2, "e": 1}),
|
||||
|
||||
# lowest that does not appear in other relations
|
||||
(["a <<", "b < c"], {"a": 0, "b": 1, "c": 2}),
|
||||
(["a <<", "a < b"], {"a": 0, "b": 1}),
|
||||
(["a <<", "a < b", "c < d", "d < e"], {"a": 0, "b": 1, "c": 1, "d": 2, "e": 3}),
|
||||
(["z <<", "a<<", "b<<", "c<<", "a < b", "b < c"], {"a": -2, "b": -1, "c": 0, "z": -3}),
|
||||
|
||||
# eq
|
||||
(["a = b"], {"a": 1, "b": 1}),
|
||||
(["a = b", "b > c"], {"a": 2, "b": 2, "c": 1}),
|
||||
(["a = z", "z>>", "b<c", "c<d"], {"a": 4, "b": 1, "c": 2, "d": 3, "z": 4}),
|
||||
(["b = a", "c = b", "a > d"], {"a": 2, "b": 2, "c": 2, "d": 1}),
|
||||
(["a = b", "b = c", "a > d"], {"a": 2, "b": 2, "c": 2, "d": 1}),
|
||||
#(["a = b", "b = c", "c > d"], {"a": 2, "b": 2, "c": 2, "d": 1}), # not working
|
||||
|
||||
# mix greatest and lesser
|
||||
(["a >>", "b<<", "a > b"], {"a": 2, "b": 0}),
|
||||
])
|
||||
def test_i_can_compute_weight_new(self, entries, expected):
|
||||
comparison_objs = list(self.get_comparison_objs(entries))
|
||||
assert SheerkaComparisonManager.compute_weights(comparison_objs) == expected
|
||||
|
||||
@pytest.mark.parametrize("previous_entries, new_entry, items_in_cycle", [
|
||||
(["a > b"], "b > a", {"a", "b"}),
|
||||
(["a > b", "c > d"], "b > a", {"a", "b"}),
|
||||
(["a < b", "b < c"], "c < a", {"a", "b", "c"}),
|
||||
])
|
||||
def test_validate_new_entry_i_can_detect_cycle(self, previous_entries, new_entry, items_in_cycle):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
new_co = list(self.get_comparison_objs([new_entry]))[0]
|
||||
previous_comparison_objs = list(self.get_comparison_objs(previous_entries))
|
||||
|
||||
res = SheerkaComparisonManager.validate_new_entry(context, new_co, previous_comparison_objs)
|
||||
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.CHICKEN_AND_EGG)
|
||||
assert set(res.body.body) == items_in_cycle
|
||||
|
||||
@pytest.mark.parametrize("previous_entries, new_entry", [
|
||||
(["a > b"], "a > b"),
|
||||
(["a < b"], "a < b"),
|
||||
(["a = b"], "a = b"),
|
||||
(["a <<"], "a <<"),
|
||||
(["a >>"], "a >>"),
|
||||
])
|
||||
def test_validate_new_entry_i_can_detect_duplicate_entries(self, previous_entries, new_entry):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
new_co = list(self.get_comparison_objs([new_entry]))[0]
|
||||
previous_comparison_objs = list(self.get_comparison_objs(previous_entries))
|
||||
|
||||
res = SheerkaComparisonManager.validate_new_entry(context, new_co, previous_comparison_objs)
|
||||
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.COMPARISON_ALREADY_DEFINED)
|
||||
|
||||
@pytest.mark.parametrize("previous_entries, new_entry", [
|
||||
(["a>>"], "a<<"),
|
||||
(["a>>"], "a < b"),
|
||||
(["a>>"], "b > a"),
|
||||
])
|
||||
def test_validate_new_entry_i_can_detect_is_greatest_constraint_error(self, previous_entries, new_entry):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
new_co = list(self.get_comparison_objs([new_entry]))[0]
|
||||
previous_comparison_objs = list(self.get_comparison_objs(previous_entries))
|
||||
|
||||
res = SheerkaComparisonManager.validate_new_entry(context, new_co, previous_comparison_objs)
|
||||
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.IS_GREATEST_CONSTRAINT_ERROR)
|
||||
|
||||
@pytest.mark.parametrize("previous_entries, new_entry", [
|
||||
(["a<<"], "a>>"),
|
||||
(["a<<"], "a > b"),
|
||||
(["a<<"], "b < a"),
|
||||
])
|
||||
def test_validate_new_entry_i_can_detect_is_lesser_constraint_error(self, previous_entries, new_entry):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
new_co = list(self.get_comparison_objs([new_entry]))[0]
|
||||
previous_comparison_objs = list(self.get_comparison_objs(previous_entries))
|
||||
|
||||
res = SheerkaComparisonManager.validate_new_entry(context, new_co, previous_comparison_objs)
|
||||
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.IS_LESSER_CONSTRAINT_ERROR)
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
import pytest
|
||||
|
||||
from cache.CacheManager import ConceptNotFound
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.builtin_helpers import ensure_bnf
|
||||
from core.concept import PROPERTIES_TO_SERIALIZE, Concept, DEFINITION_TYPE_DEF, get_concept_attrs, \
|
||||
DEFINITION_TYPE_BNF
|
||||
from core.global_symbols import NotInit, NotFound
|
||||
from core.sheerka.Sheerka import Sheerka
|
||||
from core.sheerka.services.SheerkaConceptManager import SheerkaConceptManager, NoModificationFound, ForbiddenAttribute, \
|
||||
UnknownAttribute, CannotRemoveMeta, ValueNotFound, ConceptIsReferenced
|
||||
from parsers.BaseNodeParser import BaseNodeParser
|
||||
from parsers.BnfNodeParser import Sequence, StrMatch, ConceptExpression
|
||||
|
||||
UnknownAttribute, CannotRemoveMeta, ValueNotFound, ConceptIsReferenced, NoFirstTokenError
|
||||
from parsers.BnfNodeParser import Sequence, StrMatch, ConceptExpression, OrderedChoice, Optional, ZeroOrMore, OneOrMore
|
||||
from tests.TestUsingFileBasedSheerka import TestUsingFileBasedSheerka
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
compute_concepts_by_first_token = SheerkaConceptManager.compute_concepts_by_first_token
|
||||
resolve_concepts_by_first_keyword = SheerkaConceptManager.resolve_concepts_by_first_keyword
|
||||
|
||||
|
||||
class TestSheerkaConceptManager(TestUsingMemoryBasedSheerka):
|
||||
def test_i_can_create_a_concept(self):
|
||||
@@ -48,15 +50,15 @@ class TestSheerkaConceptManager(TestUsingMemoryBasedSheerka):
|
||||
assert sheerka.get_by_hash(concept.get_definition_hash()) == concept
|
||||
|
||||
# I can get by the first entry
|
||||
assert sheerka.om.get(sheerka.CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "+") == [concept.id]
|
||||
assert sheerka.om.get(sheerka.RESOLVED_CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "+") == [concept.id]
|
||||
assert sheerka.om.get(service.CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "+") == [concept.id]
|
||||
assert sheerka.om.get(service.RESOLVED_CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "+") == [concept.id]
|
||||
|
||||
# saved in sdp
|
||||
assert sheerka.om.current_sdp().exists(service.CONCEPTS_BY_ID_ENTRY, concept.id)
|
||||
assert sheerka.om.current_sdp().exists(service.CONCEPTS_BY_KEY_ENTRY, concept.key)
|
||||
assert sheerka.om.current_sdp().exists(service.CONCEPTS_BY_NAME_ENTRY, concept.name)
|
||||
assert sheerka.om.current_sdp().exists(service.CONCEPTS_BY_HASH_ENTRY, concept.get_definition_hash())
|
||||
assert sheerka.om.current_sdp().exists(sheerka.CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "+")
|
||||
assert sheerka.om.current_sdp().exists(service.CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "+")
|
||||
|
||||
def test_i_cannot_create_a_bnf_concept_that_references_a_concept_that_cannot_be_resolved(self):
|
||||
sheerka, context, one_1, one_1_0 = self.init_concepts(Concept("one", body="1"), Concept("one", body="1.0"))
|
||||
@@ -104,7 +106,7 @@ class TestSheerkaConceptManager(TestUsingMemoryBasedSheerka):
|
||||
assert sheerka.om.current_sdp().exists(service.CONCEPTS_BY_KEY_ENTRY, concept.key)
|
||||
assert sheerka.om.current_sdp().exists(service.CONCEPTS_BY_NAME_ENTRY, concept.name)
|
||||
assert sheerka.om.current_sdp().exists(service.CONCEPTS_BY_HASH_ENTRY, concept.get_definition_hash())
|
||||
assert sheerka.om.current_sdp().exists(sheerka.CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "hello")
|
||||
assert sheerka.om.current_sdp().exists(service.CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "hello")
|
||||
|
||||
def test_i_cannot_add_the_same_concept_twice(self):
|
||||
"""
|
||||
@@ -185,8 +187,8 @@ class TestSheerkaConceptManager(TestUsingMemoryBasedSheerka):
|
||||
assert res.status
|
||||
|
||||
# I can get by the first entry
|
||||
assert sheerka.om.get(sheerka.CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "-") == [concept.id]
|
||||
assert sheerka.om.get(sheerka.RESOLVED_CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "-") == [concept.id]
|
||||
assert sheerka.om.get(SheerkaConceptManager.CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "-") == [concept.id]
|
||||
assert sheerka.om.get(SheerkaConceptManager.RESOLVED_CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "-") == [concept.id]
|
||||
|
||||
@pytest.mark.parametrize("expression", [
|
||||
"--'filter' ('one' | 'two') ",
|
||||
@@ -198,8 +200,8 @@ class TestSheerkaConceptManager(TestUsingMemoryBasedSheerka):
|
||||
create_new=True).unpack()
|
||||
|
||||
# I can get by the first entry
|
||||
assert sheerka.om.get(sheerka.CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "-") == [bnf_concept.id]
|
||||
assert sheerka.om.get(sheerka.RESOLVED_CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "-") == [bnf_concept.id]
|
||||
assert sheerka.om.get(SheerkaConceptManager.CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "-") == [bnf_concept.id]
|
||||
assert sheerka.om.get(SheerkaConceptManager.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_test().with_concepts(
|
||||
@@ -494,11 +496,11 @@ class TestSheerkaConceptManager(TestUsingMemoryBasedSheerka):
|
||||
Concept("baz", definition="foo"),
|
||||
create_new=True).unpack()
|
||||
|
||||
assert sheerka.om.copy(sheerka.CONCEPTS_BY_FIRST_KEYWORD_ENTRY) == {
|
||||
assert sheerka.om.copy(SheerkaConceptManager.CONCEPTS_BY_FIRST_KEYWORD_ENTRY) == {
|
||||
"foo": ["1001"],
|
||||
"bar": ["1002"],
|
||||
'c:|1001:': ['1003']}
|
||||
assert sheerka.om.copy(sheerka.RESOLVED_CONCEPTS_BY_FIRST_KEYWORD_ENTRY) == {
|
||||
assert sheerka.om.copy(SheerkaConceptManager.RESOLVED_CONCEPTS_BY_FIRST_KEYWORD_ENTRY) == {
|
||||
'foo': ['1001', '1003'],
|
||||
'bar': ['1002']}
|
||||
|
||||
@@ -506,10 +508,10 @@ class TestSheerkaConceptManager(TestUsingMemoryBasedSheerka):
|
||||
res = sheerka.modify_concept(context, foo, to_add)
|
||||
|
||||
assert res.status
|
||||
assert sheerka.om.copy(sheerka.CONCEPTS_BY_FIRST_KEYWORD_ENTRY) == {
|
||||
assert sheerka.om.copy(SheerkaConceptManager.CONCEPTS_BY_FIRST_KEYWORD_ENTRY) == {
|
||||
"bar": ["1002", "1001"],
|
||||
'c:|1001:': ['1003']}
|
||||
assert sheerka.om.copy(sheerka.RESOLVED_CONCEPTS_BY_FIRST_KEYWORD_ENTRY) == {
|
||||
assert sheerka.om.copy(SheerkaConceptManager.RESOLVED_CONCEPTS_BY_FIRST_KEYWORD_ENTRY) == {
|
||||
'bar': ['1002', '1001', '1003']}
|
||||
|
||||
def test_references_are_updated_after_concept_modification(self):
|
||||
@@ -531,7 +533,7 @@ class TestSheerkaConceptManager(TestUsingMemoryBasedSheerka):
|
||||
assert twenty_one.get_metadata().definition == "'twenty' one"
|
||||
assert twenty_one.get_bnf() is None
|
||||
|
||||
BaseNodeParser.ensure_bnf(context, twenty_one)
|
||||
ensure_bnf(context, twenty_one)
|
||||
assert twenty_one.get_bnf() == Sequence(StrMatch('twenty'), ConceptExpression(modified, rule_name='one'))
|
||||
|
||||
def test_i_can_modify_on_top_of_a_new_ontology_layer(self):
|
||||
@@ -730,6 +732,258 @@ class TestSheerkaConceptManager(TestUsingMemoryBasedSheerka):
|
||||
assert res.status
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.NEW_CONCEPT)
|
||||
|
||||
@pytest.mark.parametrize("concept, expected", [
|
||||
(Concept("foo"), {"foo": ["1001"]}),
|
||||
(Concept("foo a").def_var("a"), {"foo": ["1001"]}),
|
||||
(Concept("a b foo").def_var("a").def_var("b"), {"foo": ["1001"]}),
|
||||
])
|
||||
def test_i_can_get_concepts_by_first_keyword(self, concept, expected):
|
||||
"""
|
||||
Given a concept, i can find the first know token
|
||||
example:
|
||||
Concept("a foo b").def_var("a").def_var("b")
|
||||
'a' and 'b' are properties
|
||||
the first 'real' token is foo
|
||||
:return:
|
||||
"""
|
||||
|
||||
sheerka, context, *updated = self.init_concepts(concept)
|
||||
|
||||
res = SheerkaConceptManager.compute_concepts_by_first_token(context, updated)
|
||||
|
||||
assert res.status
|
||||
assert res.body == expected
|
||||
|
||||
@pytest.mark.parametrize("bnf, expected", [
|
||||
(StrMatch("foo"), {"foo": ["1002"]}),
|
||||
(StrMatch("bar"), {"bar": ["1002"]}),
|
||||
(ConceptExpression("bar"), {"c:|1001:": ["1002"]}),
|
||||
(Sequence(StrMatch("foo"), StrMatch("bar")), {"foo": ["1002"]}),
|
||||
(Sequence(StrMatch("foo"), ConceptExpression("bar")), {"foo": ["1002"]}),
|
||||
(Sequence(ConceptExpression("bar"), StrMatch("foo")), {"c:|1001:": ["1002"]}),
|
||||
(OrderedChoice(StrMatch("foo"), StrMatch("bar")), {"foo": ["1002"], "bar": ["1002"]}),
|
||||
(Optional(StrMatch("foo")), {"foo": ["1002"]}),
|
||||
(ZeroOrMore(StrMatch("foo")), {"foo": ["1002"]}),
|
||||
(OneOrMore(StrMatch("foo")), {"foo": ["1002"]}),
|
||||
(StrMatch("--filter"), {"--filter": ["1002"]}), # add both entries
|
||||
])
|
||||
def test_i_can_get_concepts_by_first_keyword_with_bnf(self, bnf, expected):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
bar = Concept("bar").init_key()
|
||||
sheerka.set_id_if_needed(bar, False)
|
||||
sheerka.test_only_add_in_cache(bar)
|
||||
|
||||
concept = Concept("foo").init_key()
|
||||
concept.set_bnf(bnf)
|
||||
sheerka.set_id_if_needed(concept, False)
|
||||
|
||||
res = compute_concepts_by_first_token(context, [concept])
|
||||
|
||||
assert res.status
|
||||
assert res.body == expected
|
||||
|
||||
def test_i_can_get_concepts_by_first_keyword_when_multiple_concepts(self):
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
|
||||
bar = Concept("bar").init_key()
|
||||
sheerka.set_id_if_needed(bar, False)
|
||||
sheerka.test_only_add_in_cache(bar)
|
||||
|
||||
baz = Concept("baz").init_key()
|
||||
sheerka.set_id_if_needed(baz, False)
|
||||
sheerka.test_only_add_in_cache(baz)
|
||||
|
||||
foo = Concept("foo").init_key()
|
||||
foo.set_bnf(OrderedChoice(ConceptExpression("bar"), ConceptExpression("baz"), StrMatch("qux")))
|
||||
sheerka.set_id_if_needed(foo, False)
|
||||
|
||||
res = compute_concepts_by_first_token(context, [bar, baz, foo])
|
||||
|
||||
assert res.status
|
||||
assert res.body == {
|
||||
"bar": ["1001"],
|
||||
"baz": ["1002"],
|
||||
"c:|1001:": ["1003"],
|
||||
"c:|1002:": ["1003"],
|
||||
"qux": ["1003"],
|
||||
}
|
||||
|
||||
def test_i_can_get_concepts_by_first_keyword_using_sheerka(self):
|
||||
sheerka, context, *updated = self.init_test().with_concepts(
|
||||
"one",
|
||||
"two",
|
||||
Concept("twenty", definition="'twenty' (one|two)"),
|
||||
create_new=True
|
||||
).unpack()
|
||||
|
||||
bar = Concept("bar").init_key()
|
||||
sheerka.set_id_if_needed(bar, False)
|
||||
sheerka.test_only_add_in_cache(bar)
|
||||
|
||||
foo = Concept("foo").init_key()
|
||||
foo.set_bnf(OrderedChoice(ConceptExpression("one"), ConceptExpression("bar"), StrMatch("qux")))
|
||||
sheerka.set_id_if_needed(foo, False)
|
||||
|
||||
res = compute_concepts_by_first_token(context, [bar, foo], use_sheerka=True)
|
||||
|
||||
assert res.status
|
||||
assert res.body == {
|
||||
"one": ["1001"],
|
||||
"two": ["1002"],
|
||||
"twenty": ["1003"],
|
||||
"bar": ["1004"],
|
||||
"c:|1001:": ["1005"],
|
||||
"c:|1004:": ["1005"],
|
||||
"qux": ["1005"],
|
||||
}
|
||||
|
||||
def test_i_cannot_get_concept_by_first_keyword_when_no_first_keyword(self):
|
||||
sheerka, context, foo = self.init_concepts(Concept("x y", body="x y").def_var("x").def_var("y"))
|
||||
res = compute_concepts_by_first_token(context, [foo])
|
||||
|
||||
assert not res.status
|
||||
assert res.body == NoFirstTokenError(foo, foo.key)
|
||||
|
||||
def test_i_can_resolve_concepts_by_first_keyword(self):
|
||||
sheerka, context, *updated = self.init_concepts(
|
||||
"one",
|
||||
Concept("two", definition="one"),
|
||||
Concept("three", definition="two"))
|
||||
|
||||
concepts_by_first_keywords = {
|
||||
"one": ["1001"],
|
||||
"c:|1001:": ["1002"],
|
||||
"c:|1002:": ["1003"],
|
||||
}
|
||||
|
||||
resolved_ret_val = resolve_concepts_by_first_keyword(context, concepts_by_first_keywords)
|
||||
|
||||
assert resolved_ret_val.status
|
||||
assert resolved_ret_val.body == {
|
||||
"one": ["1001", "1002", "1003"],
|
||||
}
|
||||
|
||||
def test_i_can_resolve_when_concepts_are_sets(self):
|
||||
sheerka, context, number, *concepts = self.init_concepts(
|
||||
"number",
|
||||
"one",
|
||||
"two",
|
||||
"twenty",
|
||||
"hundred",
|
||||
Concept("twenties", definition="twenty number"),
|
||||
Concept("hundreds", definition="number hundred"),
|
||||
)
|
||||
|
||||
sheerka.set_isa(context, sheerka.new("one"), number)
|
||||
sheerka.set_isa(context, sheerka.new("two"), number)
|
||||
sheerka.set_isa(context, sheerka.new("twenty"), number)
|
||||
sheerka.set_isa(context, sheerka.new("thirty"), number)
|
||||
sheerka.set_isa(context, sheerka.new("hundred"), number)
|
||||
sheerka.set_isa(context, sheerka.new("twenties"), number)
|
||||
sheerka.set_isa(context, sheerka.new("hundreds"), number)
|
||||
|
||||
sheerka.concepts_grammars.clear() # reset all the grammar to simulate Sheerka restart
|
||||
|
||||
# cbft : concept_by_first_token (I usually don't use abbreviation)
|
||||
cbft = compute_concepts_by_first_token(context, [number] + concepts).body
|
||||
resolved_ret_val = resolve_concepts_by_first_keyword(context, cbft)
|
||||
|
||||
assert resolved_ret_val.status
|
||||
assert resolved_ret_val.body == {
|
||||
'number': ['1001'],
|
||||
'one': ['1002', '1007'],
|
||||
'two': ['1003', '1007'],
|
||||
'twenty': ['1004', '1006', '1007'],
|
||||
'hundred': ['1005', '1007'],
|
||||
}
|
||||
|
||||
def test_concepts_are_defined_once(self):
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
good = self.create_and_add_in_cache_concept(sheerka, "good")
|
||||
foo = self.create_and_add_in_cache_concept(sheerka, "foo", bnf=ConceptExpression("good"))
|
||||
bar = self.create_and_add_in_cache_concept(sheerka, "bar", bnf=ConceptExpression("good"))
|
||||
baz = self.create_and_add_in_cache_concept(sheerka, "baz", bnf=OrderedChoice(
|
||||
ConceptExpression("foo"),
|
||||
ConceptExpression("bar")))
|
||||
|
||||
concepts_by_first_keywords = compute_concepts_by_first_token(context, [good, foo, bar, baz]).body
|
||||
|
||||
resolved_ret_val = resolve_concepts_by_first_keyword(context, concepts_by_first_keywords)
|
||||
assert resolved_ret_val.status
|
||||
assert resolved_ret_val.body == {
|
||||
"good": ["1001", "1002", "1003", "1004"],
|
||||
}
|
||||
|
||||
def test_i_can_resolve_more_complex(self):
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
|
||||
a = self.create_and_add_in_cache_concept(sheerka, "a", bnf=Sequence("one", "two"))
|
||||
b = self.create_and_add_in_cache_concept(sheerka, "b", bnf=Sequence(ConceptExpression("a"), "two"))
|
||||
|
||||
concepts_by_first_keywords = compute_concepts_by_first_token(context, [a, b]).body
|
||||
|
||||
resolved_ret_val = resolve_concepts_by_first_keyword(context, concepts_by_first_keywords)
|
||||
assert resolved_ret_val.status
|
||||
assert resolved_ret_val.body == {
|
||||
"one": ["1001", "1002"],
|
||||
}
|
||||
|
||||
def tests_i_can_detect_direct_recursion(self):
|
||||
sheerka, context, good, foo, bar = self.init_concepts(
|
||||
"good",
|
||||
self.bnf_concept("foo", ConceptExpression("bar")),
|
||||
self.bnf_concept("bar", ConceptExpression("foo")),
|
||||
)
|
||||
|
||||
concepts_by_first_keywords = compute_concepts_by_first_token(context, [good, foo, bar]).body
|
||||
resolved_ret_val = resolve_concepts_by_first_keyword(context, concepts_by_first_keywords)
|
||||
assert resolved_ret_val.status
|
||||
assert resolved_ret_val.body == {
|
||||
"good": ["1001"],
|
||||
}
|
||||
assert sheerka.chicken_and_eggs.get(foo.id) == {foo.id, bar.id}
|
||||
assert sheerka.chicken_and_eggs.get(bar.id) == {foo.id, bar.id}
|
||||
|
||||
def test_i_can_detect_indirect_infinite_recursion(self):
|
||||
sheerka, context, good, one, two, three = self.init_concepts(
|
||||
"good",
|
||||
self.bnf_concept("one", ConceptExpression("two")),
|
||||
self.bnf_concept("two", ConceptExpression("three")),
|
||||
self.bnf_concept("three", ConceptExpression("two")),
|
||||
)
|
||||
|
||||
concepts_by_first_keywords = compute_concepts_by_first_token(context, [good, one, two, three]).body
|
||||
resolved_ret_val = resolve_concepts_by_first_keyword(context, concepts_by_first_keywords)
|
||||
assert resolved_ret_val.status
|
||||
assert resolved_ret_val.body == {
|
||||
"good": ["1001"],
|
||||
}
|
||||
assert sheerka.chicken_and_eggs.get(one.id) == {one.id, two.id, three.id}
|
||||
assert sheerka.chicken_and_eggs.get(two.id) == {one.id, two.id, three.id}
|
||||
assert sheerka.chicken_and_eggs.get(three.id) == {one.id, two.id, three.id}
|
||||
|
||||
def test_i_can_detect_the_longest_infinite_recursion_chain(self):
|
||||
sheerka, context, good, one, two, three = self.init_concepts(
|
||||
"good",
|
||||
self.bnf_concept("two", ConceptExpression("three")),
|
||||
self.bnf_concept("three", ConceptExpression("two")),
|
||||
self.bnf_concept("one", ConceptExpression("three")),
|
||||
)
|
||||
|
||||
concepts_by_first_keywords = compute_concepts_by_first_token(context, [good, one, two, three]).body
|
||||
resolved_ret_val = resolve_concepts_by_first_keyword(context, concepts_by_first_keywords)
|
||||
assert resolved_ret_val.status
|
||||
assert resolved_ret_val.body == {
|
||||
"good": ["1001"],
|
||||
}
|
||||
assert sheerka.chicken_and_eggs.get(one.id) == {one.id, two.id, three.id}
|
||||
assert sheerka.chicken_and_eggs.get(two.id) == {one.id, two.id, three.id}
|
||||
assert sheerka.chicken_and_eggs.get(three.id) == {one.id, two.id, three.id}
|
||||
|
||||
|
||||
class TestSheerkaConceptManagerUsingFileBasedSheerka(TestUsingFileBasedSheerka):
|
||||
def test_i_can_add_several_concepts(self):
|
||||
@@ -759,8 +1013,8 @@ class TestSheerkaConceptManagerUsingFileBasedSheerka(TestUsingFileBasedSheerka):
|
||||
assert sheerka.om.current_sdp().exists(service.CONCEPTS_BY_HASH_ENTRY, hello.get_definition_hash())
|
||||
assert sheerka.om.current_sdp().exists(service.CONCEPTS_BY_HASH_ENTRY, greeting.get_definition_hash())
|
||||
|
||||
assert sheerka.om.current_sdp().exists(Sheerka.CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "Hello")
|
||||
assert sheerka.om.current_sdp().exists(Sheerka.CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "Greeting")
|
||||
assert sheerka.om.current_sdp().exists(service.CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "Hello")
|
||||
assert sheerka.om.current_sdp().exists(service.CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "Greeting")
|
||||
|
||||
def test_i_cannot_add_the_same_concept_twice_using_sdp(self):
|
||||
"""
|
||||
|
||||
@@ -973,3 +973,4 @@ class TestSheerkaDebugManager(TestUsingMemoryBasedSheerka):
|
||||
assert service.debug_vars_settings == [DebugItem("v_name", "v_service", "v_method", 1, True, 1, False, True)]
|
||||
assert service.debug_rules_settings == [DebugItem("r_name", "r_service", "r_method", 2, True, 2, False, True)]
|
||||
assert service.debug_concepts_settings == [DebugItem("c_name", "c_serv", "c_method", 3, True, 3, False, True)]
|
||||
|
||||
|
||||
@@ -88,17 +88,6 @@ class TestSheerkaMemory(TestUsingMemoryBasedSheerka):
|
||||
assert sheerka.om.copy(SheerkaMemory.OBJECTS_ENTRY) == {"a": MemoryObject(context.event.get_digest(), foo)}
|
||||
assert id(sheerka.get_from_memory(context, "a").obj) == id(foo)
|
||||
|
||||
def test_i_can_use_memory_to_get_the_list_of_all_objects(self):
|
||||
sheerka, context = self.init_test(cache_only=False).unpack()
|
||||
foo = Concept("foo")
|
||||
bar = Concept("bar")
|
||||
|
||||
sheerka.add_to_memory(context, "foo", 'value that will not appear')
|
||||
sheerka.add_to_memory(context, "foo", foo)
|
||||
sheerka.add_to_memory(context, "bar", bar)
|
||||
sheerka.om.commit(context)
|
||||
|
||||
assert sheerka.memory(context) == {"foo": foo, "bar": bar}
|
||||
|
||||
def test_i_can_use_memory_with_a_string(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
@@ -138,7 +127,7 @@ class TestSheerkaMemory(TestUsingMemoryBasedSheerka):
|
||||
def test_object_are_not_added_in_memory_during_the_initialisation(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
|
||||
assert len(sheerka.memory(context)) == 0
|
||||
assert len(sheerka.om.get_all(SheerkaMemory.OBJECTS_ENTRY)) == 0
|
||||
|
||||
|
||||
class TestSheerkaMemoryUsingFileBase(TestUsingFileBasedSheerka):
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import ast
|
||||
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import Concept, CMV
|
||||
from core.global_symbols import RULE_COMPARISON_CONTEXT, NotFound
|
||||
from core.global_symbols import RULE_COMPARISON_CONTEXT
|
||||
from core.rule import Rule, ACTION_TYPE_PRINT, ACTION_TYPE_EXEC
|
||||
from core.sheerka.services.SheerkaRuleManager import SheerkaRuleManager, FormatRuleParser, \
|
||||
FormatAstRawText, FormatAstVariable, FormatAstSequence, FormatAstFunction, \
|
||||
@@ -11,7 +12,6 @@ from core.sheerka.services.SheerkaRuleManager import SheerkaRuleManager, FormatR
|
||||
from core.tokenizer import Token, TokenKind
|
||||
from parsers.BaseNodeParser import SourceCodeWithConceptNode, SourceCodeNode
|
||||
from parsers.PythonParser import PythonNode
|
||||
|
||||
from tests.TestUsingFileBasedSheerka import TestUsingFileBasedSheerka
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
@@ -335,6 +335,41 @@ class TestSheerkaRuleManager(TestUsingMemoryBasedSheerka):
|
||||
assert sheerka.get_rule_by_id(rule_true.id) == rule_true
|
||||
assert not sheerka.is_known(sheerka.get_rule_by_id(rule_false.id))
|
||||
|
||||
def test_i_can_resolve_rule(self):
|
||||
sheerka, context, rule = self.init_test().with_rules(("my rule", "True", "True")).unpack()
|
||||
context.add_to_short_term_memory("x", rule.id)
|
||||
|
||||
# direct access by id
|
||||
assert sheerka.resolve_rule(context, rule.id) == rule
|
||||
|
||||
# direct access by token
|
||||
assert sheerka.resolve_rule(context, Token(TokenKind.RULE, ("i_do_not_care", rule.id), -1, -1, -1)) == rule
|
||||
|
||||
# indirect access by token
|
||||
assert sheerka.resolve_rule(context, Token(TokenKind.RULE, ("i_do_not_care", "x"), -1, -1, -1)) == rule
|
||||
|
||||
# Simple returns the rule if id is resolved
|
||||
assert sheerka.resolve_rule(context, rule) == rule
|
||||
|
||||
# look for the correct rule when id is unresolved
|
||||
unresolved = Rule(rule_id="x")
|
||||
unresolved.metadata.id_is_unresolved = True
|
||||
assert sheerka.resolve_rule(context, unresolved) == rule
|
||||
|
||||
# look for the correct rule when id is unresolved
|
||||
unresolved = Rule(rule_id="y")
|
||||
unresolved.metadata.id_is_unresolved = True
|
||||
assert sheerka.resolve_rule(context, unresolved) is None # no error raised
|
||||
|
||||
# I still can get the value when the indirection has the wrong type
|
||||
context.add_to_short_term_memory("z", int(rule.id))
|
||||
|
||||
assert sheerka.resolve_rule(context, Token(TokenKind.RULE, ("i_do_not_care", "z"), -1, -1, -1)) == rule
|
||||
|
||||
unresolved = Rule(rule_id="z")
|
||||
unresolved.metadata.id_is_unresolved = True
|
||||
assert sheerka.resolve_rule(context, unresolved) == rule
|
||||
|
||||
# @pytest.mark.skip
|
||||
# @pytest.mark.parametrize("text, expected", [
|
||||
# ("cat is an animal", set()),
|
||||
|
||||
@@ -539,21 +539,21 @@ class TestSheerkaUsingFileBasedSheerka(TestUsingFileBasedSheerka):
|
||||
create_new=True).unpack()
|
||||
sheerka.om.commit(context)
|
||||
|
||||
assert sheerka.om.copy(sheerka.CONCEPTS_BY_FIRST_KEYWORD_ENTRY) == {
|
||||
assert sheerka.om.copy(SheerkaConceptManager.CONCEPTS_BY_FIRST_KEYWORD_ENTRY) == {
|
||||
'bar': ['1002'],
|
||||
'c:|1001:': ['1003'],
|
||||
'foo': ['1001']}
|
||||
assert sheerka.om.copy(sheerka.RESOLVED_CONCEPTS_BY_FIRST_KEYWORD_ENTRY) == {
|
||||
assert sheerka.om.copy(SheerkaConceptManager.RESOLVED_CONCEPTS_BY_FIRST_KEYWORD_ENTRY) == {
|
||||
'bar': ['1002'],
|
||||
'foo': ['1001', '1003']
|
||||
}
|
||||
|
||||
sheerka = self.get_sheerka() # another instance
|
||||
assert sheerka.om.copy(sheerka.CONCEPTS_BY_FIRST_KEYWORD_ENTRY) == {
|
||||
assert sheerka.om.copy(SheerkaConceptManager.CONCEPTS_BY_FIRST_KEYWORD_ENTRY) == {
|
||||
'bar': ['1002'],
|
||||
'c:|1001:': ['1003'],
|
||||
'foo': ['1001']}
|
||||
assert sheerka.om.copy(sheerka.RESOLVED_CONCEPTS_BY_FIRST_KEYWORD_ENTRY) == {
|
||||
assert sheerka.om.copy(SheerkaConceptManager.RESOLVED_CONCEPTS_BY_FIRST_KEYWORD_ENTRY) == {
|
||||
'bar': ['1002'],
|
||||
'foo': ['1001', '1003']
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import types
|
||||
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.sheerka.ExecutionContext import ExecutionContext
|
||||
from core.sheerka.SheerkaOntologyManager import SheerkaOntologyManager
|
||||
from core.sheerka.services.SheerkaResultManager import SheerkaResultConcept
|
||||
from core.sheerka.services.SheerkaResultManager import SheerkaResultManager
|
||||
from sdp.sheerkaDataProvider import Event
|
||||
|
||||
from tests.TestUsingFileBasedSheerka import TestUsingFileBasedSheerka
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
@@ -25,7 +26,7 @@ class TestSheerkaResultManager(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def init_service(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
service = sheerka.services[SheerkaResultConcept.NAME]
|
||||
service = sheerka.services[SheerkaResultManager.NAME]
|
||||
|
||||
return sheerka, context, service
|
||||
|
||||
@@ -64,7 +65,7 @@ class TestSheerkaResultManager(TestUsingMemoryBasedSheerka):
|
||||
assert isinstance(res.body, types.GeneratorType)
|
||||
|
||||
# the digest is correctly recorded
|
||||
assert sheerka.load_var(SheerkaResultConcept.NAME, "digest") == digest
|
||||
assert sheerka.load_var(SheerkaResultManager.NAME, "digest") == digest
|
||||
|
||||
previous_results = list(res.body)
|
||||
|
||||
@@ -93,7 +94,7 @@ class TestSheerkaResultManager(TestUsingMemoryBasedSheerka):
|
||||
assert isinstance(res.body, types.GeneratorType)
|
||||
|
||||
# the digest is correctly recorded
|
||||
assert sheerka.load_var(SheerkaResultConcept.NAME, "digest") == digest
|
||||
assert sheerka.load_var(SheerkaResultManager.NAME, "digest") == digest
|
||||
|
||||
previous_results = list(res.body)
|
||||
|
||||
@@ -148,7 +149,7 @@ class TestSheerkaResultManager(TestUsingMemoryBasedSheerka):
|
||||
sheerka.evaluate_user_input("one")
|
||||
sheerka.evaluate_user_input("one")
|
||||
|
||||
service = SheerkaResultConcept(sheerka, 2)
|
||||
service = SheerkaResultManager(sheerka, 2)
|
||||
res = service.get_results_by_command(context, "def concept")
|
||||
assert sheerka.isinstance(res, BuiltinConcepts.EXPLANATION)
|
||||
assert res.command == "def concept one as 1"
|
||||
@@ -171,7 +172,7 @@ class TestSheerkaResultManager(TestUsingMemoryBasedSheerka):
|
||||
sheerka.evaluate_user_input("one")
|
||||
sheerka.evaluate_user_input("one")
|
||||
|
||||
service = SheerkaResultConcept(sheerka, 2)
|
||||
service = SheerkaResultManager(sheerka, 2)
|
||||
res = service.get_results_by_command(context, "fake command")
|
||||
assert sheerka.isinstance(res, BuiltinConcepts.NOT_FOUND)
|
||||
assert res.body == {'command': 'fake command'}
|
||||
@@ -336,7 +337,7 @@ class TestSheerkaResultManager(TestUsingMemoryBasedSheerka):
|
||||
def test_i_can_manage_invalid_predicates(self):
|
||||
predicate = {"filter": "a b c"}
|
||||
with pytest.raises(SyntaxError):
|
||||
SheerkaResultConcept.get_predicate(**predicate)
|
||||
SheerkaResultManager.get_predicate(**predicate)
|
||||
|
||||
def test_i_can_get_last_return_value(self):
|
||||
sheerka, context, service = self.init_service()
|
||||
@@ -368,3 +369,62 @@ class TestSheerkaResultManager(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert service.last_created_concept_id == new_concept.id
|
||||
assert sheerka.get_last_created_concept(context) == new_concept
|
||||
|
||||
def test_last_error_is_recorded(self):
|
||||
sheerka, context, foo = self.init_test().with_concepts("foo", create_new=True).unpack()
|
||||
service = sheerka.services[SheerkaResultManager.NAME]
|
||||
res = sheerka.evaluate_user_input("bar") # does not exist, will cause an error
|
||||
sheerka.evaluate_user_input("foo") # exists, to validate that the error is not reset
|
||||
|
||||
assert service.last_error_event_id is not None
|
||||
assert len(res) == 1
|
||||
assert sheerka.get_last_error() == res[0]
|
||||
|
||||
def test_multiple_errors_are_recorded(self):
|
||||
sheerka, context, foo = self.init_test().with_concepts("foo", create_new=True).unpack()
|
||||
service = sheerka.services[SheerkaResultManager.NAME]
|
||||
service.test_only_reset()
|
||||
|
||||
res = sheerka.evaluate_user_input("x x") # cannot be parsed
|
||||
sheerka.evaluate_user_input("foo") # exists, to validate that the error is not reset
|
||||
|
||||
assert service.last_error_event_id is not None
|
||||
assert len(res) > 1
|
||||
assert sheerka.get_last_error() == [r for r in res if not r.status]
|
||||
|
||||
def test_i_cannot_get_last_error_when_no_error(self):
|
||||
sheerka, context = self.init_test().unpack()
|
||||
service = sheerka.services[SheerkaResultManager.NAME]
|
||||
service.test_only_reset()
|
||||
|
||||
assert service.last_error_event_id is None
|
||||
assert sheerka.get_last_error() == self.sheerka.new(BuiltinConcepts.NOT_FOUND, body={"query": "get_last_error"})
|
||||
|
||||
|
||||
class TestSheerkaResultManagerFileBased(TestUsingFileBasedSheerka):
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
sheerka = cls().get_sheerka(cache_only=False, ontology="#TestSheerkaResultManager#")
|
||||
sheerka.save_execution_context = True
|
||||
cls.root_ontology_name = "#TestSheerkaResultManager#"
|
||||
|
||||
@classmethod
|
||||
def teardown_class(cls):
|
||||
cls.sheerka.pop_ontology()
|
||||
cls.root_ontology_name = SheerkaOntologyManager.ROOT_ONTOLOGY_NAME
|
||||
|
||||
def test_i_can_retrieve_the_last_error_after_startup(self):
|
||||
sheerka, context, foo = self.init_test().with_concepts("foo", create_new=True).unpack()
|
||||
service = sheerka.services[SheerkaResultManager.NAME]
|
||||
res_in_error = sheerka.evaluate_user_input("bar") # does not exist, will cause an error
|
||||
sheerka.evaluate_user_input("foo") # exists, to validate that the error is not reset
|
||||
|
||||
assert service.last_error_event_id is not None
|
||||
assert service.get_last_error() == res_in_error[0]
|
||||
|
||||
# simulate restart
|
||||
sheerka = self.new_sheerka_instance(False)
|
||||
service = sheerka.services[SheerkaResultManager.NAME]
|
||||
|
||||
assert service.last_error_event_id is not None
|
||||
assert service.get_last_error() == res_in_error[0]
|
||||
|
||||
@@ -1167,106 +1167,107 @@ class TestSheerkaOntology(TestUsingMemoryBasedSheerka):
|
||||
"key5": "value5"
|
||||
}
|
||||
|
||||
def test_i_can_list_by_key_when_dictionaries(self):
|
||||
sheerka = self.get_sheerka(cache_only=False)
|
||||
context = self.get_context(sheerka)
|
||||
# def test_i_can_list_by_key_when_dictionaries(self):
|
||||
# sheerka = self.get_sheerka(cache_only=False)
|
||||
# context = self.get_context(sheerka)
|
||||
#
|
||||
# manager = SheerkaOntologyManager(sheerka, sheerka.root_folder, sheerka.cache_only)
|
||||
# manager.register_cache("cache_name", Cache().auto_configure("cache_name"))
|
||||
# manager.freeze()
|
||||
#
|
||||
# manager.put("cache_name", "key1", {"a": "value1", "b": "value2", "c": "value3"})
|
||||
# manager.commit(context)
|
||||
#
|
||||
# manager.push_ontology("new ontology")
|
||||
# manager.put("cache_name", "key1", {"a": "new value1", "d": "value4"}) # only in cache
|
||||
#
|
||||
# manager.push_ontology("another ontology")
|
||||
# with manager.current_sdp().get_transaction(context.event) as transaction:
|
||||
# transaction.add("cache_name", "key1", {"b": "new value2", "e": "value5"})
|
||||
#
|
||||
# assert manager.list_by_key("cache_name", "key1") == {
|
||||
# "a": "new value1",
|
||||
# "b": "new value2",
|
||||
# "c": "value3",
|
||||
# "d": "value4",
|
||||
# "e": "value5",
|
||||
# }
|
||||
#
|
||||
# def test_i_can_list_by_key_when_lists(self):
|
||||
# sheerka = self.get_sheerka(cache_only=False)
|
||||
# context = self.get_context(sheerka)
|
||||
#
|
||||
# manager = SheerkaOntologyManager(sheerka, sheerka.root_folder, sheerka.cache_only)
|
||||
# manager.register_cache("cache_name", Cache().auto_configure("cache_name"))
|
||||
# manager.freeze()
|
||||
#
|
||||
# manager.put("cache_name", "key1", ["a", "b", "c"])
|
||||
# manager.commit(context)
|
||||
#
|
||||
# manager.push_ontology("new ontology")
|
||||
# manager.put("cache_name", "key1", ["a", "d"]) # only in cache
|
||||
#
|
||||
# manager.push_ontology("another ontology")
|
||||
# with manager.current_sdp().get_transaction(context.event) as transaction:
|
||||
# transaction.add("cache_name", "key1", ["b", "e"])
|
||||
#
|
||||
# assert manager.list_by_key("cache_name", "key1") == ["a", "b", "c", "a", "d", "b", "e"]
|
||||
#
|
||||
# def test_i_can_list_by_key_when_dictionaries_and_entries_are_removed(self):
|
||||
# sheerka = self.get_sheerka(cache_only=False)
|
||||
# context = self.get_context(sheerka)
|
||||
#
|
||||
# manager = SheerkaOntologyManager(sheerka, sheerka.root_folder, sheerka.cache_only)
|
||||
# manager.register_cache("cache_name", Cache().auto_configure("cache_name"))
|
||||
# manager.freeze()
|
||||
#
|
||||
# manager.put("cache_name", "key1", {"a": "value1", "b": "value2", "c": "value3"})
|
||||
# manager.put("cache_name", "key2", {"a": "value1", "b": "value2", "c": "value3"})
|
||||
# manager.put("cache_name", "key3", {"a": "value1", "b": "value2", "c": "value3"})
|
||||
# manager.commit(context)
|
||||
#
|
||||
# manager.push_ontology("new ontology")
|
||||
# manager.put("cache_name", "key1", Removed) # removed in cache
|
||||
# with manager.current_sdp().get_transaction(context.event) as transaction:
|
||||
# transaction.add("cache_name", "key2", Removed) # removed in sdp
|
||||
#
|
||||
# manager.push_ontology("another ontology")
|
||||
# manager.put("cache_name", "key1", {"e": "value1", "f": "value2", "g": "value3"})
|
||||
# manager.put("cache_name", "key2", {"e": "value1", "f": "value2", "g": "value3"})
|
||||
# manager.put("cache_name", "key3", {"e": "value1", "f": "value2", "g": "value3"})
|
||||
#
|
||||
# assert manager.list_by_key("cache_name", "key1") == {"e": "value1", "f": "value2", "g": "value3"}
|
||||
# assert manager.list_by_key("cache_name", "key2") == {"e": "value1", "f": "value2", "g": "value3"}
|
||||
# assert manager.list_by_key("cache_name", "key3") == {"a": "value1", "b": "value2", "c": "value3",
|
||||
# "e": "value1", "f": "value2", "g": "value3"}
|
||||
#
|
||||
# def test_i_can_list_by_key_when_lists_and_entries_are_removed(self):
|
||||
# sheerka = self.get_sheerka(cache_only=False)
|
||||
# context = self.get_context(sheerka)
|
||||
#
|
||||
# manager = SheerkaOntologyManager(sheerka, sheerka.root_folder, sheerka.cache_only)
|
||||
# manager.register_cache("cache_name", Cache().auto_configure("cache_name"))
|
||||
# manager.freeze()
|
||||
#
|
||||
# manager.put("cache_name", "key1", ["a", "b", "c"])
|
||||
# manager.put("cache_name", "key2", ["a", "b", "c"])
|
||||
# manager.put("cache_name", "key3", ["a", "b", "c"])
|
||||
# manager.commit(context)
|
||||
#
|
||||
# manager.push_ontology("new ontology")
|
||||
# manager.put("cache_name", "key1", Removed) # removed in cache
|
||||
# with manager.current_sdp().get_transaction(context.event) as transaction:
|
||||
# transaction.add("cache_name", "key2", Removed) # removed in sdp
|
||||
#
|
||||
# manager.push_ontology("another ontology")
|
||||
# manager.put("cache_name", "key1", ["e", "f", "g"])
|
||||
# manager.put("cache_name", "key2", ["e", "f", "g"])
|
||||
# manager.put("cache_name", "key3", ["e", "f", "g"])
|
||||
#
|
||||
# assert manager.list_by_key("cache_name", "key1") == ["e", "f", "g"]
|
||||
# assert manager.list_by_key("cache_name", "key2") == ["e", "f", "g"]
|
||||
# assert manager.list_by_key("cache_name", "key3") == ["a", "b", "c", "e", "f", "g"]
|
||||
|
||||
manager = SheerkaOntologyManager(sheerka, sheerka.root_folder, sheerka.cache_only)
|
||||
manager.register_cache("cache_name", Cache().auto_configure("cache_name"))
|
||||
manager.freeze()
|
||||
|
||||
manager.put("cache_name", "key1", {"a": "value1", "b": "value2", "c": "value3"})
|
||||
manager.commit(context)
|
||||
|
||||
manager.push_ontology("new ontology")
|
||||
manager.put("cache_name", "key1", {"a": "new value1", "d": "value4"}) # only in cache
|
||||
|
||||
manager.push_ontology("another ontology")
|
||||
with manager.current_sdp().get_transaction(context.event) as transaction:
|
||||
transaction.add("cache_name", "key1", {"b": "new value2", "e": "value5"})
|
||||
|
||||
assert manager.list_by_key("cache_name", "key1") == {
|
||||
"a": "new value1",
|
||||
"b": "new value2",
|
||||
"c": "value3",
|
||||
"d": "value4",
|
||||
"e": "value5",
|
||||
}
|
||||
|
||||
def test_i_can_list_by_key_when_lists(self):
|
||||
sheerka = self.get_sheerka(cache_only=False)
|
||||
context = self.get_context(sheerka)
|
||||
|
||||
manager = SheerkaOntologyManager(sheerka, sheerka.root_folder, sheerka.cache_only)
|
||||
manager.register_cache("cache_name", Cache().auto_configure("cache_name"))
|
||||
manager.freeze()
|
||||
|
||||
manager.put("cache_name", "key1", ["a", "b", "c"])
|
||||
manager.commit(context)
|
||||
|
||||
manager.push_ontology("new ontology")
|
||||
manager.put("cache_name", "key1", ["a", "d"]) # only in cache
|
||||
|
||||
manager.push_ontology("another ontology")
|
||||
with manager.current_sdp().get_transaction(context.event) as transaction:
|
||||
transaction.add("cache_name", "key1", ["b", "e"])
|
||||
|
||||
assert manager.list_by_key("cache_name", "key1") == ["a", "b", "c", "a", "d", "b", "e"]
|
||||
|
||||
def test_i_can_list_by_key_when_dictionaries_and_entries_are_removed(self):
|
||||
sheerka = self.get_sheerka(cache_only=False)
|
||||
context = self.get_context(sheerka)
|
||||
|
||||
manager = SheerkaOntologyManager(sheerka, sheerka.root_folder, sheerka.cache_only)
|
||||
manager.register_cache("cache_name", Cache().auto_configure("cache_name"))
|
||||
manager.freeze()
|
||||
|
||||
manager.put("cache_name", "key1", {"a": "value1", "b": "value2", "c": "value3"})
|
||||
manager.put("cache_name", "key2", {"a": "value1", "b": "value2", "c": "value3"})
|
||||
manager.put("cache_name", "key3", {"a": "value1", "b": "value2", "c": "value3"})
|
||||
manager.commit(context)
|
||||
|
||||
manager.push_ontology("new ontology")
|
||||
manager.put("cache_name", "key1", Removed) # removed in cache
|
||||
with manager.current_sdp().get_transaction(context.event) as transaction:
|
||||
transaction.add("cache_name", "key2", Removed) # removed in sdp
|
||||
|
||||
manager.push_ontology("another ontology")
|
||||
manager.put("cache_name", "key1", {"e": "value1", "f": "value2", "g": "value3"})
|
||||
manager.put("cache_name", "key2", {"e": "value1", "f": "value2", "g": "value3"})
|
||||
manager.put("cache_name", "key3", {"e": "value1", "f": "value2", "g": "value3"})
|
||||
|
||||
assert manager.list_by_key("cache_name", "key1") == {"e": "value1", "f": "value2", "g": "value3"}
|
||||
assert manager.list_by_key("cache_name", "key2") == {"e": "value1", "f": "value2", "g": "value3"}
|
||||
assert manager.list_by_key("cache_name", "key3") == {"a": "value1", "b": "value2", "c": "value3",
|
||||
"e": "value1", "f": "value2", "g": "value3"}
|
||||
|
||||
def test_i_can_list_by_key_when_lists_and_entries_are_removed(self):
|
||||
sheerka = self.get_sheerka(cache_only=False)
|
||||
context = self.get_context(sheerka)
|
||||
|
||||
manager = SheerkaOntologyManager(sheerka, sheerka.root_folder, sheerka.cache_only)
|
||||
manager.register_cache("cache_name", Cache().auto_configure("cache_name"))
|
||||
manager.freeze()
|
||||
|
||||
manager.put("cache_name", "key1", ["a", "b", "c"])
|
||||
manager.put("cache_name", "key2", ["a", "b", "c"])
|
||||
manager.put("cache_name", "key3", ["a", "b", "c"])
|
||||
manager.commit(context)
|
||||
|
||||
manager.push_ontology("new ontology")
|
||||
manager.put("cache_name", "key1", Removed) # removed in cache
|
||||
with manager.current_sdp().get_transaction(context.event) as transaction:
|
||||
transaction.add("cache_name", "key2", Removed) # removed in sdp
|
||||
|
||||
manager.push_ontology("another ontology")
|
||||
manager.put("cache_name", "key1", ["e", "f", "g"])
|
||||
manager.put("cache_name", "key2", ["e", "f", "g"])
|
||||
manager.put("cache_name", "key3", ["e", "f", "g"])
|
||||
|
||||
assert manager.list_by_key("cache_name", "key1") == ["e", "f", "g"]
|
||||
assert manager.list_by_key("cache_name", "key2") == ["e", "f", "g"]
|
||||
assert manager.list_by_key("cache_name", "key3") == ["a", "b", "c", "e", "f", "g"]
|
||||
|
||||
def test_i_can_get_call_when_a_cache_is_cleared(self):
|
||||
sheerka = self.get_sheerka(cache_only=False)
|
||||
|
||||
Reference in New Issue
Block a user