Added basic implentation for where

This commit is contained in:
2020-02-05 18:47:20 +01:00
parent a5a721094b
commit afc1e22949
35 changed files with 864 additions and 320 deletions
+10
View File
@@ -8,3 +8,13 @@ def concept two as 2
def concept three as 3
def concept four as 4
def concept five as 5
def concept one as 1
def concept two as 2
def concept three as 3
def concept four as 4
def concept five as 5
def concept one as 1
def concept two as 2
def concept three as 3
def concept four as 4
def concept five as 5
+46 -7
View File
@@ -18,7 +18,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
("True", True),
("1 > 2", False),
])
def test_i_can_evaluate_a_concept_with_simple_body(self,body, expected):
def test_i_can_evaluate_a_concept_with_simple_body(self, body, expected):
sheerka = self.get_sheerka()
concept = Concept("foo", body=body)
@@ -43,9 +43,9 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
("True", True),
("1 > 2", False),
])
def test_i_can_evaluate_the_other_metadata(self,expr, expected):
def test_i_can_evaluate_the_other_metadata(self, expr, expected):
"""
I only test WHERE, it's the same for the others
I only test PRE, it's the same for the others
:param expr:
:param expected:
:return:
@@ -53,15 +53,15 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka = self.get_sheerka()
concept = Concept("foo", where=expr)
concept = Concept("foo", pre=expr)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
assert evaluated.key == concept.key
assert evaluated.metadata.body is None
assert evaluated.metadata.pre is None
assert evaluated.metadata.pre == expr
assert evaluated.metadata.post is None
assert evaluated.metadata.where == expr
assert evaluated.get_metadata_value(ConceptParts.WHERE) == expected
assert evaluated.metadata.where is None
assert evaluated.get_metadata_value(ConceptParts.PRE) == expected
assert evaluated.props == {}
assert evaluated.metadata.is_evaluated
assert len(evaluated.values) == 0 if expr is None else 1
@@ -330,3 +330,42 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
assert evaluated.key == concept.init_key().key
@pytest.mark.parametrize("where_clause, expected", [
("True", True),
("False", False),
("self < 10", False),
("self < 11", True),
("a < 20", False),
("a > 19", True),
("a + self > 20", True),
])
def test_i_can_evaluate_simple_where(self, where_clause, expected):
sheerka = self.get_sheerka()
concept = Concept("foo", body="10", where=where_clause).def_prop("a", "20")
sheerka.add_in_cache(concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
if expected:
assert evaluated.key == concept.key
else:
assert sheerka.isinstance(evaluated, BuiltinConcepts.WHERE_CLAUSE_FAILED)
assert evaluated.body == concept
def test_i_can_evaluate_where_when_using_other_concept(self):
sheerka = self.get_sheerka()
foo_true = Concept("foo_true", body="True").init_key()
foo_false = Concept("foo_false", body="False").init_key()
sheerka.add_in_cache(foo_false)
sheerka.add_in_cache(foo_true)
concept = Concept("foo", where="foo_true").init_key()
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
assert evaluated.key == concept.key
concept = Concept("foo", where="foo_false")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
assert sheerka.isinstance(evaluated, BuiltinConcepts.WHERE_CLAUSE_FAILED)
assert evaluated.body == concept
+44 -49
View File
@@ -1,8 +1,3 @@
import os
import shutil
from os import path
import pytest
from core.builtin_concepts import ConceptAlreadyInSet, BuiltinConcepts
from core.concept import Concept
@@ -11,42 +6,36 @@ from tests.TestUsingFileBasedSheerka import TestUsingFileBasedSheerka
class TestSheerkaSetsManager(TestUsingFileBasedSheerka):
def test_i_can_add_concept_to_set(self):
sheerka = self.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)
def init(self, use_dict, *concepts):
sheerka = self.get_sheerka(use_dict, True)
for c in concepts:
sheerka.set_id_if_needed(c, False)
sheerka.add_in_cache(c)
context = self.get_context(sheerka)
return sheerka, context
def test_i_can_add_concept_to_set(self):
foo = Concept("foo")
all_foos = Concept("all_foos")
sheerka, context = self.init(False, foo, all_foos)
res = sheerka.add_concept_to_set(context, foo, all_foos)
assert res.status
assert sheerka.isinstance(res.body, BuiltinConcepts.SUCCESS)
all_entries = self.get_sheerka(False, False).sdp.get("All_" + all_foos.id, None, False)
all_entries = self.get_sheerka(False, True).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(self):
sheerka = self.get_sheerka(False, False)
foo1 = Concept("foo1")
sheerka.set_id_if_needed(foo1, False)
foo2 = Concept("foo1")
sheerka.set_id_if_needed(foo2, False)
foo2 = Concept("foo2")
all_foos = Concept("all_foos")
sheerka.set_id_if_needed(all_foos, False)
sheerka, context = self.init(False, foo1, foo2, all_foos)
context = self.get_context(sheerka)
sheerka.add_concept_to_set(context, foo1, all_foos)
res = sheerka.add_concept_to_set(context, foo2, all_foos)
res = sheerka.sets_handler.add_concepts_to_set(context, (foo1, foo2), all_foos)
assert res.status
assert sheerka.isinstance(res.body, BuiltinConcepts.SUCCESS)
@@ -56,16 +45,30 @@ class TestSheerkaSetsManager(TestUsingFileBasedSheerka):
assert foo1.id in all_entries
assert foo2.id in all_entries
# I can add another elements
foo3 = Concept("foo3")
foo4 = Concept("foo4")
for c in [foo3, foo4]:
sheerka.set_id_if_needed(c, False)
sheerka.add_in_cache(c)
res = sheerka.sets_handler.add_concepts_to_set(context, (foo3, foo4), all_foos)
assert res.status
assert sheerka.isinstance(res.body, BuiltinConcepts.SUCCESS)
all_entries = self.get_sheerka(False, False).sdp.get("All_" + all_foos.id, None, False)
assert len(all_entries) == 4
assert foo1.id in all_entries
assert foo2.id in all_entries
assert foo3.id in all_entries
assert foo4.id in all_entries
def test_i_cannot_add_the_same_concept_twice_in_a_set(self):
sheerka = self.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)
sheerka, context = self.init(True, foo, all_foos)
context = self.get_context(sheerka)
sheerka.add_concept_to_set(context, foo, all_foos)
res = sheerka.add_concept_to_set(context, foo, all_foos)
@@ -77,18 +80,12 @@ class TestSheerkaSetsManager(TestUsingFileBasedSheerka):
assert foo.id in all_entries
def test_i_get_elements_from_a_set(self):
sheerka = self.get_sheerka()
one = Concept("one")
two = Concept("two")
three = Concept("three")
number = Concept("number")
sheerka, context = self.init(True, one, two, three, number)
for c in [one, two, three, number]:
sheerka.set_id_if_needed(c, False)
sheerka.add_in_cache(c)
context = self.get_context(sheerka)
for c in [one, two, three]:
sheerka.add_concept_to_set(context, c, number)
@@ -97,10 +94,8 @@ class TestSheerkaSetsManager(TestUsingFileBasedSheerka):
assert set(elements) == {one, two, three}
def test_i_cannot_get_elements_if_not_a_set(self):
sheerka = self.get_sheerka()
one = Concept("one")
sheerka.set_id_if_needed(one, False)
sheerka.add_in_cache(one)
sheerka, context = self.init(True, one)
error = sheerka.get_set_elements(one)
@@ -108,17 +103,17 @@ class TestSheerkaSetsManager(TestUsingFileBasedSheerka):
assert error.body == one
def test_isa_and_isa_group(self):
sheerka = self.get_sheerka()
group = Concept("group")
foo = Concept("foo")
sheerka, context = self.init(True, group, foo)
group = Concept("group").init_key()
group.metadata.id = "1001"
assert not sheerka.isaset(group)
foo = Concept("foo").init_key()
foo.metadata.id = "1002"
assert not sheerka.isa(foo, group)
context = self.get_context(sheerka)
sheerka.add_concept_to_set(context, foo, group)
assert sheerka.isaset(group)
assert sheerka.isa(foo, group)
def test_i_can_a_multiples_concepts(self):
pass
+17 -3
View File
@@ -40,7 +40,7 @@ def test_i_can_tokenize():
assert tokens[31] == Token(TokenKind.AMPER, '&', 78, 6, 20)
assert tokens[32] == Token(TokenKind.LESS, '<', 79, 6, 21)
assert tokens[33] == Token(TokenKind.GREATER, '>', 80, 6, 22)
assert tokens[34] == Token(TokenKind.CONCEPT, 'name', 81, 6, 23)
assert tokens[34] == Token(TokenKind.CONCEPT, ('name', None), 81, 6, 23)
assert tokens[35] == Token(TokenKind.DOLLAR, '$', 88, 6, 30)
assert tokens[36] == Token(TokenKind.STERLING, '£', 89, 6, 31)
assert tokens[37] == Token(TokenKind.EURO, '', 90, 6, 32)
@@ -79,8 +79,8 @@ def test_i_can_tokenize_identifiers(text, expected):
('"string', "Missing Trailing quote", '"string', 7, 1, 8),
('"a" + "string', "Missing Trailing quote", '"string', 13, 1, 14),
('"a"\n\n"string', "Missing Trailing quote", '"string', 12, 3, 8),
("c::", "Concept name not found", "", 2, 1, 3),
("c:foo\nbar:", "New line is forbidden in concept name", "foo", 5, 1, 6),
("c::", "Concept identifiers not found", "", 2, 1, 3),
("c:foo\nbar:", "New line in concept name", "foo", 5, 1, 6),
("c:foo", "Missing ending colon", "foo", 5, 1, 6)
])
def test_i_can_detect_tokenizer_errors(text, message, error_text, index, line, column):
@@ -139,3 +139,17 @@ def test_i_can_recognize_keywords(text, expected):
tokens = list(Tokenizer(text))
assert tokens[0].type == TokenKind.KEYWORD
assert tokens[0].value == expected
@pytest.mark.parametrize("text, expected", [
("c:key:", ("key", None)),
("c:key|id:", ("key", "id")),
("c:key|:", ("key", None)),
("c:|id:", (None, "id")),
("c:125:", ("125", None)),
])
def test_i_can_parse_concept_token(text, expected):
tokens = list(Tokenizer(text))
assert tokens[0].type == TokenKind.CONCEPT
assert tokens[0].value == expected
+56 -20
View File
@@ -1,10 +1,25 @@
import core.utils
import pytest
from core.concept import ConceptParts
from core.concept import ConceptParts, Concept
from core.tokenizer import Token, TokenKind
def get_tokens(lst):
res = []
for e in lst:
if e == " ":
res.append(Token(TokenKind.WHITESPACE, " ", 0, 0, 0))
elif e == "\n":
res.append(Token(TokenKind.NEWLINE, "\n", 0, 0, 0))
elif e == "<EOF>":
res.append(Token(TokenKind.EOF, "\n", 0, 0, 0))
else:
res.append(Token(TokenKind.IDENTIFIER, e, 0, 0, 0))
return res
@pytest.mark.parametrize("lst, as_string", [
(None, "",),
([], ""),
@@ -136,18 +151,33 @@ def test_i_can_escape():
(10, None, None),
("", None, None),
("xxx", None, None),
(":c:", None, None),
(":c:key", None, None),
(":c:key:", "key", None),
(":c:key:id", None, None),
(":c:key:id:", "key", "id"),
("c:", None, None),
("c:key", None, None),
("c:key:", "key", None),
("c:key|id", None, None),
("c:key|id:", "key", "id"),
("c:|id:", None, "id"),
("c:key|:", "key", None),
])
def test_i_can_decode_concept_repr(text, expected_key, expected_id):
k, i = core.utils.decode_concept(text)
def test_i_can_unstr_concept(text, expected_key, expected_id):
k, i = core.utils.unstr_concept(text)
assert k == expected_key
assert i == expected_id
def test_i_can_str_concept():
assert core.utils.str_concept(("key", "id")) == "c:key|id:"
assert core.utils.str_concept((None, "id")) == "c:|id:"
assert core.utils.str_concept(("key", None)) == "c:key:"
assert core.utils.str_concept((None, None)) == ""
concept = Concept("foo").init_key()
assert core.utils.str_concept(concept) == "c:foo:"
concept.metadata.id = "1001"
assert core.utils.str_concept(concept) == "c:foo|1001:"
@pytest.mark.parametrize("text, expected", [
(None, None),
(10, None),
@@ -162,16 +192,22 @@ def test_i_can_decode_enum(text, expected):
assert actual == expected
def get_tokens(lst):
res = []
for e in lst:
if e == " ":
res.append(Token(TokenKind.WHITESPACE, " ", 0, 0, 0))
elif e == "\n":
res.append(Token(TokenKind.NEWLINE, "\n", 0, 0, 0))
elif e == "<EOF>":
res.append(Token(TokenKind.EOF, "\n", 0, 0, 0))
else:
res.append(Token(TokenKind.IDENTIFIER, e, 0, 0, 0))
def test_encode_concept_key_id():
assert core.utils.encode_concept(("key", "id")) == "__C__KEY_key__ID_id__C__"
assert core.utils.encode_concept((None, "id")) == "__C__KEY_00None00__ID_id__C__"
assert core.utils.encode_concept(("key", None)) == "__C__KEY_key__ID_00None00__C__"
assert core.utils.encode_concept(("key", "id"), True) == "__C__USE_CONCEPT__KEY_key__ID_id__C__"
assert core.utils.encode_concept(("k + y", "id")) == "__C__KEY_k000y__ID_id__C__"
return res
concept = Concept("foo").init_key()
assert core.utils.encode_concept(concept) == "__C__KEY_foo__ID_00None00__C__"
concept.metadata.id = "1001"
assert core.utils.encode_concept(concept) == "__C__KEY_foo__ID_1001__C__"
def test_decode_concept_key_id():
assert core.utils.decode_concept("__C__KEY_key__ID_id__C__") == ("key", "id", False)
assert core.utils.decode_concept("__C__KEY_00None00__ID_id__C__") == (None, "id", False)
assert core.utils.decode_concept("__C__KEY_key__ID_00None00__C__") == ("key", None, False)
assert core.utils.decode_concept("__C__USE_CONCEPT__KEY_key__ID_id__C__") == ("key", "id", True)