Refactored Caching, Refactored BnfNodeParser, Introduced Sphinx
This commit is contained in:
+39
-10
@@ -1,8 +1,9 @@
|
||||
import ast
|
||||
|
||||
from core.builtin_concepts import ReturnValueConcept, ParserResultConcept, BuiltinConcepts
|
||||
from core.concept import Concept, DEFINITION_TYPE_BNF
|
||||
from core.concept import Concept, DEFINITION_TYPE_BNF, DEFINITION_TYPE_DEF
|
||||
from core.sheerka.ExecutionContext import ExecutionContext
|
||||
from parsers.BnfNodeParser import StrMatch
|
||||
from parsers.BnfParser import BnfParser
|
||||
from sdp.sheerkaDataProvider import Event
|
||||
|
||||
@@ -28,8 +29,8 @@ class BaseTest:
|
||||
post="isinstance(res, int)",
|
||||
body="def func(x,y):\n return x+y\nfunc(a,b)",
|
||||
desc="specific description")
|
||||
concept.def_prop("a", "value1")
|
||||
concept.def_prop("b", "value2")
|
||||
concept.def_var("a", "value1")
|
||||
concept.def_var("b", "value2")
|
||||
|
||||
return concept
|
||||
|
||||
@@ -41,15 +42,17 @@ class BaseTest:
|
||||
|
||||
def init_concepts(self, *concepts, **kwargs):
|
||||
sheerka = self.get_sheerka(**kwargs)
|
||||
context = self.get_context(sheerka)
|
||||
create_new = kwargs.get("create_new", False)
|
||||
|
||||
context_args = dict([(k, v) for k, v in kwargs.items() if k in ["sheerka", "eval_body", "eval_where"]])
|
||||
context = self.get_context(sheerka, **context_args)
|
||||
create_new = kwargs.get("create_new", None)
|
||||
|
||||
result = []
|
||||
for c in concepts:
|
||||
if isinstance(c, str):
|
||||
c = Concept(c)
|
||||
|
||||
if c.metadata.definition:
|
||||
if c.metadata.definition and c.metadata.definition_type != DEFINITION_TYPE_DEF:
|
||||
bnf_parser = BnfParser()
|
||||
res = bnf_parser.parse(context, c.metadata.definition)
|
||||
if res.status:
|
||||
@@ -57,8 +60,8 @@ class BaseTest:
|
||||
c.metadata.definition_type = DEFINITION_TYPE_BNF
|
||||
else:
|
||||
raise Exception(f"Error in bnf definition '{c.metadata.definition}'", sheerka.get_error(res))
|
||||
sheerka.create_new_concept(context, c)
|
||||
elif create_new:
|
||||
|
||||
if create_new:
|
||||
sheerka.create_new_concept(context, c)
|
||||
else:
|
||||
c.init_key()
|
||||
@@ -79,8 +82,8 @@ class BaseTest:
|
||||
"""True ret_val + add concept in cache"""
|
||||
if isinstance(obj, Concept):
|
||||
obj.init_key()
|
||||
if obj.key not in sheerka.cache_by_key:
|
||||
sheerka.cache_by_key[obj.key] = obj
|
||||
if sheerka.has_key(obj.key):
|
||||
sheerka.add_in_cache(obj)
|
||||
return sheerka.ret(who, True, obj)
|
||||
|
||||
@staticmethod
|
||||
@@ -93,3 +96,29 @@ class BaseTest:
|
||||
source=source or concept.name,
|
||||
value=concept,
|
||||
try_parsed=concept))
|
||||
|
||||
@staticmethod
|
||||
def create_concept_lite(sheerka, name, variables=None, bnf=None):
|
||||
concept = Concept(name) if isinstance(name, str) else name
|
||||
if variables:
|
||||
for v in variables:
|
||||
concept.def_var(v)
|
||||
if bnf:
|
||||
concept.bnf = bnf
|
||||
concept.metadata.definition_type = DEFINITION_TYPE_BNF
|
||||
concept.init_key()
|
||||
sheerka.set_id_if_needed(concept, False)
|
||||
sheerka.add_in_cache(concept)
|
||||
return concept
|
||||
|
||||
@staticmethod
|
||||
def bnf_concept(concept, expression=None):
|
||||
if isinstance(concept, Concept):
|
||||
name = concept.name
|
||||
else:
|
||||
name = concept
|
||||
concept = Concept(concept)
|
||||
|
||||
concept.bnf = expression or StrMatch(name)
|
||||
concept.metadata.definition_type = DEFINITION_TYPE_BNF
|
||||
return concept
|
||||
|
||||
@@ -4,11 +4,11 @@ from os import path
|
||||
|
||||
import pytest
|
||||
from core.sheerka.Sheerka import Sheerka
|
||||
|
||||
from tests.BaseTest import BaseTest
|
||||
|
||||
|
||||
class TestUsingFileBasedSheerka(BaseTest):
|
||||
|
||||
tests_root = path.abspath("../../build/tests")
|
||||
root_folder = "init_folder"
|
||||
|
||||
@@ -26,11 +26,15 @@ class TestUsingFileBasedSheerka(BaseTest):
|
||||
|
||||
os.chdir(current_pwd)
|
||||
|
||||
def get_sheerka(self, **kwargs):
|
||||
use_dict = kwargs.get("use_dict", True)
|
||||
skip_builtins_in_db = kwargs.get("skip_builtins_in_db", True)
|
||||
def get_sheerka(self, **kwargs):
|
||||
|
||||
# use dictionary based io instead of file
|
||||
# If you do so, information between two different instances of sheerka
|
||||
# won't be shared
|
||||
use_dict = kwargs.get("use_dict", False)
|
||||
|
||||
root = "mem://" if use_dict else self.root_folder
|
||||
sheerka = Sheerka(skip_builtins_in_db=skip_builtins_in_db)
|
||||
sheerka.initialize(root)
|
||||
sheerka = Sheerka()
|
||||
sheerka.initialize(root, save_execution_context=False)
|
||||
|
||||
return sheerka
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
from core.sheerka.Sheerka import Sheerka
|
||||
|
||||
from tests.BaseTest import BaseTest
|
||||
|
||||
|
||||
class TestUsingMemoryBasedSheerka(BaseTest):
|
||||
singleton_instance = None
|
||||
builtin_concepts = {}
|
||||
dump = None
|
||||
|
||||
@staticmethod
|
||||
def _inner_get_sheerka(skip_builtins_in_db):
|
||||
sheerka = Sheerka(skip_builtins_in_db=skip_builtins_in_db)
|
||||
sheerka.initialize("mem://")
|
||||
def _inner_get_sheerka(cache_only):
|
||||
sheerka = Sheerka(cache_only=cache_only)
|
||||
sheerka.initialize("mem://", save_execution_context=False)
|
||||
return sheerka
|
||||
|
||||
def get_sheerka(self, **kwargs):
|
||||
skip_builtins_in_db = kwargs.get("skip_builtins_in_db", True)
|
||||
use_singleton = kwargs.get("singleton", False)
|
||||
cache_only = kwargs.get("cache_only", True)
|
||||
use_singleton = kwargs.get("singleton", True)
|
||||
|
||||
sheerka = kwargs.get("sheerka", None)
|
||||
if sheerka:
|
||||
@@ -23,14 +24,13 @@ class TestUsingMemoryBasedSheerka(BaseTest):
|
||||
if use_singleton:
|
||||
singleton_instance = TestUsingMemoryBasedSheerka.singleton_instance
|
||||
if singleton_instance:
|
||||
singleton_instance.reset()
|
||||
singleton_instance.cache_by_key.update(TestUsingMemoryBasedSheerka.builtin_concepts) # quicker ?
|
||||
# singleton_instance.cache_by_key = TestUsingMemoryBasedSheerka.builtin_concepts
|
||||
singleton_instance.reset(cache_only)
|
||||
singleton_instance.cache_manager.init_from(TestUsingMemoryBasedSheerka.dump)
|
||||
return singleton_instance
|
||||
else:
|
||||
new_instance = self._inner_get_sheerka(skip_builtins_in_db)
|
||||
TestUsingMemoryBasedSheerka.builtin_concepts.update(new_instance.cache_by_key)
|
||||
new_instance = self._inner_get_sheerka(cache_only)
|
||||
TestUsingMemoryBasedSheerka.dump = new_instance.cache_manager.dump()
|
||||
TestUsingMemoryBasedSheerka.singleton_instance = new_instance
|
||||
return TestUsingMemoryBasedSheerka.singleton_instance
|
||||
|
||||
return self._inner_get_sheerka(skip_builtins_in_db)
|
||||
return self._inner_get_sheerka(cache_only)
|
||||
|
||||
Vendored
Vendored
+534
@@ -0,0 +1,534 @@
|
||||
import pytest
|
||||
from cache.Cache import Cache
|
||||
from cache.CacheManager import CacheManager
|
||||
from cache.DictionaryCache import DictionaryCache
|
||||
from cache.IncCache import IncCache
|
||||
from cache.ListCache import ListCache
|
||||
from cache.ListIfNeededCache import ListIfNeededCache
|
||||
from cache.SetCache import SetCache
|
||||
from core.concept import Concept
|
||||
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
class TestCache(TestUsingMemoryBasedSheerka):
|
||||
def test_i_can_get_an_retrieve_value_from_cache(self):
|
||||
cache = Cache()
|
||||
cache.put("key", "value")
|
||||
assert cache.get("key") == "value"
|
||||
assert len(cache) == 1
|
||||
|
||||
cache.put("key", "another value") # another value in the cache replace the previous one
|
||||
assert cache.get("key") == "another value"
|
||||
assert len(cache) == 1
|
||||
|
||||
cache.put("key2", "value2") # another key
|
||||
assert cache.get("key2") == "value2"
|
||||
assert len(cache) == 2
|
||||
assert cache.copy() == {"key": "another value", "key2": "value2"}
|
||||
|
||||
def test_i_can_evict(self):
|
||||
maxsize = 5
|
||||
cache = Cache(max_size=5)
|
||||
|
||||
for key in range(maxsize):
|
||||
cache.put(key, key)
|
||||
|
||||
assert len(cache) == maxsize
|
||||
assert cache.has(0)
|
||||
|
||||
for key in range(maxsize, maxsize * 2):
|
||||
cache.put(key, key)
|
||||
|
||||
assert len(cache) == maxsize
|
||||
assert not cache.has(key - maxsize)
|
||||
|
||||
def test_i_can_get_default_value_from_simple_cache(self):
|
||||
cache = Cache()
|
||||
assert cache.get("key") is None
|
||||
|
||||
cache = Cache(default=10)
|
||||
assert cache.get("key") == 10
|
||||
assert "key" not in cache # default value are not put in cache
|
||||
|
||||
cache = Cache(default=lambda key: key + "_not_found")
|
||||
assert cache.get("key") == "key_not_found"
|
||||
assert "key" in cache # default callable are put in cache
|
||||
|
||||
def test_i_can_put_and_retrieve_value_from_list_cache(self):
|
||||
cache = ListCache()
|
||||
|
||||
cache.put("key", "value")
|
||||
assert cache.get("key") == ["value"]
|
||||
assert len(cache) == 1
|
||||
|
||||
cache.put("key", "value2") # we can append to this list
|
||||
assert cache.get("key") == ["value", "value2"]
|
||||
assert len(cache) == 2
|
||||
|
||||
cache.put("key2", "value")
|
||||
assert cache.get("key2") == ["value"]
|
||||
assert len(cache) == 3
|
||||
|
||||
# duplicates are allowed
|
||||
cache.put("key", "value")
|
||||
assert cache.get("key") == ["value", "value2", "value"]
|
||||
assert len(cache) == 4
|
||||
|
||||
assert cache.copy() == {'key': ['value', 'value2', 'value'], 'key2': ['value']}
|
||||
|
||||
def test_i_can_put_and_retrieve_value_from_list_if_needed_cache(self):
|
||||
cache = ListIfNeededCache()
|
||||
|
||||
cache.put("key", "value")
|
||||
assert cache.get("key") == "value"
|
||||
|
||||
# second time with the same key creates a list
|
||||
cache.put("key", "value2")
|
||||
assert cache.get("key") == ["value", "value2"]
|
||||
assert len(cache) == 2
|
||||
|
||||
# third time, we now have a list
|
||||
cache.put("key", "value3")
|
||||
assert cache.get("key") == ["value", "value2", "value3"]
|
||||
assert len(cache) == 3
|
||||
|
||||
# other keys are not affected
|
||||
cache.put("key2", "value")
|
||||
assert cache.get("key2") == "value"
|
||||
assert len(cache) == 4
|
||||
|
||||
# duplicates are allowed
|
||||
cache.put("key", "value")
|
||||
assert cache.get("key") == ["value", "value2", "value3", "value"]
|
||||
assert len(cache) == 5
|
||||
|
||||
def test_i_can_put_and_retrieve_values_from_set_cache(self):
|
||||
cache = SetCache()
|
||||
|
||||
cache.put("key", "value")
|
||||
assert cache.get("key") == {"value"}
|
||||
assert len(cache) == 1
|
||||
|
||||
# we can add to this set
|
||||
cache.put("key", "value2")
|
||||
assert cache.get("key") == {"value", "value2"}
|
||||
assert len(cache) == 2
|
||||
|
||||
# other keys are not affected
|
||||
cache.put("key2", "value")
|
||||
assert cache.get("key2") == {"value"}
|
||||
assert len(cache) == 3
|
||||
|
||||
# duplicates are removed
|
||||
cache.put("key", "value")
|
||||
assert cache.get("key") == {"value", "value2"}
|
||||
assert len(cache) == 3
|
||||
|
||||
assert cache.copy() == {'key': {'value', 'value2'}, 'key2': {'value'}}
|
||||
|
||||
def test_i_can_put_and_retrieve_value_from_dictionary_cache(self):
|
||||
cache = DictionaryCache()
|
||||
|
||||
# # key must be None
|
||||
# with pytest.raises(KeyError):
|
||||
# cache.put("key", None)
|
||||
#
|
||||
# # value must be a dictionary
|
||||
# with pytest.raises(ValueError):
|
||||
# cache.put(True, "value")
|
||||
|
||||
entry = {"key": "value", "key2": ["value21", "value22"]}
|
||||
cache.put(False, entry)
|
||||
assert len(cache) == 3
|
||||
assert id(cache._cache) == id(entry)
|
||||
assert cache.get("key") == "value"
|
||||
assert cache.get("key2") == ["value21", "value22"]
|
||||
|
||||
# I can append values
|
||||
cache.put(True, {"key": "another_value", "key3": "value3"})
|
||||
assert len(cache) == 4
|
||||
assert cache.get("key") == "another_value"
|
||||
assert cache.get("key2") == ["value21", "value22"]
|
||||
assert cache.get("key3") == "value3"
|
||||
|
||||
# I can reset
|
||||
entry = {"key": "value", "key2": ["value21", "value22"]}
|
||||
cache.put(False, entry)
|
||||
assert len(cache) == 3
|
||||
assert id(cache._cache) == id(entry)
|
||||
assert cache.get("key") == "value"
|
||||
assert cache.get("key2") == ["value21", "value22"]
|
||||
|
||||
assert cache.copy() == {'key': 'value', 'key2': ['value21', 'value22']}
|
||||
|
||||
def test_i_can_put_and_retrieve_values_from_inc_cache(self):
|
||||
cache = IncCache()
|
||||
|
||||
assert cache.get("key") == 1
|
||||
assert cache.get("key") == 2
|
||||
assert cache.get("key") == 3
|
||||
assert cache.get("key2") == 1
|
||||
assert cache.get("key2") == 2
|
||||
|
||||
cache.put("key", 100)
|
||||
assert cache.get("key") == 101
|
||||
|
||||
assert cache.copy() == {'key': 101, 'key2': 2}
|
||||
|
||||
@pytest.mark.parametrize("key", [
|
||||
None,
|
||||
"something"
|
||||
])
|
||||
def test_keys_have_constraints_when_dictionary_cache(self, key):
|
||||
cache = DictionaryCache()
|
||||
with pytest.raises(KeyError):
|
||||
cache.put(key, None)
|
||||
|
||||
@pytest.mark.parametrize("value", [
|
||||
None,
|
||||
"something"
|
||||
])
|
||||
def test_values_have_constraints_when_dictionary_cache(self, value):
|
||||
cache = DictionaryCache()
|
||||
with pytest.raises(ValueError):
|
||||
cache.put(True, value)
|
||||
|
||||
def test_i_can_append_to_a_dictionary_cache_even_if_it_s_new(self):
|
||||
cache = DictionaryCache()
|
||||
|
||||
entry = {"key": "value", "key2": ["value21", "value22"]}
|
||||
cache.put(True, entry)
|
||||
assert len(cache) == 3
|
||||
assert id(cache._cache) != id(entry)
|
||||
assert cache.get("key") == "value"
|
||||
assert cache.get("key2") == ["value21", "value22"]
|
||||
|
||||
def test_i_can_update_from_simple_cache(self):
|
||||
cache = Cache()
|
||||
cache.put("key", "value")
|
||||
cache.update("key", "value", "key", "new_value")
|
||||
|
||||
assert len(cache._cache) == 1
|
||||
assert len(cache) == 1
|
||||
assert cache.get("key") == "new_value"
|
||||
|
||||
cache.update("key", "new_value", "another_key", "another_value")
|
||||
assert len(cache._cache) == 1
|
||||
assert len(cache) == 1
|
||||
assert cache.get("key") is None
|
||||
assert cache.get("another_key") == "another_value"
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("wrong key", "value", "key", "value")
|
||||
|
||||
def test_i_can_update_from_list_cache(self):
|
||||
cache = ListCache()
|
||||
|
||||
cache.put("key", "value")
|
||||
cache.put("key", "value2")
|
||||
cache.put("key", "value")
|
||||
cache.update("key", "value", "key", "another value")
|
||||
|
||||
assert len(cache._cache) == 1
|
||||
assert len(cache) == 3
|
||||
assert cache.get("key") == ["another value", "value2", "value"] # only the first one is affected
|
||||
|
||||
cache.update("key", "value2", "key2", "value2")
|
||||
assert len(cache._cache) == 2
|
||||
assert len(cache) == 3
|
||||
assert cache.get("key") == ["another value", "value"]
|
||||
assert cache.get("key2") == ["value2"]
|
||||
|
||||
cache.update("key2", "value2", "key3", "value2")
|
||||
assert len(cache._cache) == 2
|
||||
assert len(cache) == 3
|
||||
assert cache.get("key") == ["another value", "value"]
|
||||
assert cache.get("key3") == ["value2"]
|
||||
assert cache.get("key2") is None
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("wrong key", "value", "key", "value")
|
||||
|
||||
def test_i_can_update_from_list_if_needed_cache(self):
|
||||
cache = ListIfNeededCache()
|
||||
|
||||
cache.put("key", "value")
|
||||
cache.put("key", "value2")
|
||||
cache.put("key", "value")
|
||||
cache.update("key", "value", "key", "another value")
|
||||
|
||||
assert len(cache._cache) == 1
|
||||
assert len(cache) == 3
|
||||
assert cache.get("key") == ["another value", "value2", "value"] # only the first one is affected
|
||||
|
||||
cache.update("key", "value2", "key2", "value2")
|
||||
assert len(cache._cache) == 2
|
||||
assert len(cache) == 3
|
||||
assert cache.get("key") == ["another value", "value"]
|
||||
assert cache.get("key2") == "value2"
|
||||
|
||||
cache.update("key2", "value2", "key3", "value2")
|
||||
assert len(cache._cache) == 2
|
||||
assert len(cache) == 3
|
||||
assert cache.get("key") == ["another value", "value"]
|
||||
assert cache.get("key3") == "value2"
|
||||
assert cache.get("key2") is None
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("wrong key", "value", "key", "value")
|
||||
|
||||
def test_i_can_update_from_set_cache(self):
|
||||
cache = SetCache()
|
||||
|
||||
cache.put("key", "value")
|
||||
cache.put("key", "value2")
|
||||
cache.update("key", "value", "key", "another value")
|
||||
|
||||
assert len(cache._cache) == 1
|
||||
assert len(cache) == 2
|
||||
assert cache.get("key") == {"another value", "value2"}
|
||||
|
||||
cache.update("key", "value2", "key2", "value2")
|
||||
assert len(cache._cache) == 2
|
||||
assert len(cache) == 2
|
||||
assert cache.get("key") == {"another value"}
|
||||
assert cache.get("key2") == {"value2"}
|
||||
|
||||
cache.update("key", "another value", "key3", "another value")
|
||||
assert len(cache._cache) == 2
|
||||
assert len(cache) == 2
|
||||
assert cache.get("key") is None
|
||||
assert cache.get("key2") == {"value2"}
|
||||
assert cache.get("key3") == {"another value"}
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("wrong key", "value", "key", "value")
|
||||
|
||||
@pytest.mark.parametrize("cache", [
|
||||
Cache(), ListCache(), ListIfNeededCache(), SetCache(), IncCache()
|
||||
])
|
||||
def test_i_can_manage_cache_events(self, cache):
|
||||
cache.put("key", "value")
|
||||
|
||||
assert cache.to_add == {"key"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
cache.update("key", "value", "key", "another value")
|
||||
assert cache.to_add == {"key"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
cache.update("key", "another value", "key2", "value2")
|
||||
assert cache.to_add == {"key2"}
|
||||
assert cache.to_remove == {"key"}
|
||||
|
||||
cache.update("key2", "value2", "key", "value")
|
||||
assert cache.to_add == {"key"}
|
||||
assert cache.to_remove == {"key2"}
|
||||
|
||||
@pytest.mark.parametrize("cache", [
|
||||
ListCache(), SetCache(), ListIfNeededCache()
|
||||
])
|
||||
def test_i_can_manage_list_and_set_cache_events(self, cache):
|
||||
cache.put("key", "value")
|
||||
cache.put("key", "value2")
|
||||
|
||||
assert cache.to_add == {"key"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
cache.update("key", "value", "key", "another value")
|
||||
assert cache.to_add == {"key"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
cache.update("key", "value2", "key2", "value2")
|
||||
assert cache.to_add == {"key", "key2"}
|
||||
assert cache.to_remove == set()
|
||||
|
||||
cache.update("key", "another value", "key3", "another value")
|
||||
assert cache.to_add == {"key2", "key3"}
|
||||
assert cache.to_remove == {"key"}
|
||||
|
||||
@pytest.mark.parametrize("cache", [
|
||||
Cache(), ListCache(), SetCache(), ListIfNeededCache(), IncCache()
|
||||
])
|
||||
def test_exists(self, cache):
|
||||
assert not cache.exists("key")
|
||||
cache.put("key", "value")
|
||||
assert cache.exists("key")
|
||||
|
||||
def test_exists_in_dictionary_cache(self):
|
||||
cache = DictionaryCache()
|
||||
assert not cache.exists("key")
|
||||
|
||||
cache.put(True, {"key": "value"})
|
||||
assert cache.exists("key")
|
||||
|
||||
def test_exists_extend(self):
|
||||
cache = Cache(extend_exists=lambda k: True if k == "special_key" else False)
|
||||
assert not cache.exists("key")
|
||||
assert cache.exists("special_key")
|
||||
|
||||
def test_add_concept_fills_all_dependent_caches(self):
|
||||
sheerka, context, one, two, two_2, three = self.init_concepts("one", "two", Concept("two"), "three")
|
||||
cache_manager = CacheManager(None)
|
||||
|
||||
cache_manager.register_concept_cache("by_id", Cache(), lambda obj: obj.id, True)
|
||||
cache_manager.register_concept_cache("by_name", ListCache(), lambda obj: obj.name, True)
|
||||
cache_manager.register_concept_cache("by_name2", ListIfNeededCache(), lambda obj: obj.name, True)
|
||||
|
||||
cache_manager.add_concept(one)
|
||||
cache_manager.add_concept(two)
|
||||
cache_manager.add_concept(two_2)
|
||||
cache_manager.add_concept(three)
|
||||
|
||||
assert len(cache_manager.caches) == 3
|
||||
assert cache_manager.caches["by_id"].cache._cache == {
|
||||
"1001": one,
|
||||
"1002": two,
|
||||
"1003": two_2,
|
||||
"1004": three,
|
||||
}
|
||||
assert cache_manager.caches["by_name"].cache._cache == {
|
||||
"one": [one],
|
||||
"two": [two, two_2],
|
||||
"three": [three]
|
||||
}
|
||||
assert cache_manager.caches["by_name2"].cache._cache == {
|
||||
"one": one,
|
||||
"two": [two, two_2],
|
||||
"three": three
|
||||
}
|
||||
|
||||
assert cache_manager.get("by_id", "1002") == two
|
||||
assert cache_manager.get("by_name", "two") == [two, two_2]
|
||||
assert cache_manager.get("by_name2", "two") == [two, two_2]
|
||||
|
||||
def test_default_for_dictionary_cache(self):
|
||||
cache = DictionaryCache(default={"key": "value", "key2": "value2"})
|
||||
|
||||
assert cache.get("key") == "value"
|
||||
assert "key2" in cache
|
||||
assert len(cache) == 2
|
||||
|
||||
cache.clear()
|
||||
assert cache.get("key3") is None
|
||||
assert len(cache) == 2
|
||||
assert "key" in cache
|
||||
assert "key2" in cache
|
||||
|
||||
# default is not modified
|
||||
cache._cache["key"] = "another value" # operation that is normally not possible
|
||||
cache.clear()
|
||||
assert cache.get("key") == "value"
|
||||
|
||||
def test_default_callable_for_dictionary_cache(self):
|
||||
cache = DictionaryCache(default=lambda k: {"key": "value", "key2": "value2"})
|
||||
|
||||
assert cache.get("key") == "value"
|
||||
assert "key2" in cache
|
||||
assert len(cache) == 2
|
||||
|
||||
cache.clear()
|
||||
assert cache.get("key3") is None
|
||||
assert len(cache) == 2
|
||||
assert "key" in cache
|
||||
assert "key2" in cache
|
||||
|
||||
def test_dictionary_cache_cannot_be_null(self):
|
||||
cache = DictionaryCache(default=lambda k: None)
|
||||
assert cache.get("key") is None
|
||||
assert cache._cache == {}
|
||||
|
||||
cache = DictionaryCache(default=None)
|
||||
assert cache.get("key") is None
|
||||
assert cache._cache == {}
|
||||
|
||||
@pytest.mark.parametrize("cache, default, new_value, expected", [
|
||||
(ListCache(), lambda k: None, "value", ["value"]),
|
||||
(ListCache(), lambda k: ["value"], "value", ["value", "value"]),
|
||||
(ListIfNeededCache(), lambda k: None, "value", "value"),
|
||||
(ListIfNeededCache(), lambda k: "value", "value1", ["value", "value1"]),
|
||||
(ListIfNeededCache(), lambda k: ["value1", "value2"], "value1", ["value1", "value2", "value1"]),
|
||||
(SetCache(), lambda k: None, "value", {"value"}),
|
||||
(SetCache(), lambda k: {"value"}, "value", {"value"}),
|
||||
(SetCache(), lambda k: {"value1"}, "value2", {"value1", "value2"}),
|
||||
])
|
||||
def test_default_is_called_before_put_to_keep_in_sync(self, cache, default, new_value, expected):
|
||||
cache.configure(default=default)
|
||||
cache.put("key", new_value)
|
||||
|
||||
assert cache.get("key") == expected
|
||||
|
||||
def test_default_is_called_before_updating_simple_cache(self):
|
||||
cache = Cache(default=lambda k: None)
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
|
||||
cache = Cache(default=lambda k: "old_value")
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
assert cache.get("new_key") == "new_value"
|
||||
|
||||
def test_default_is_called_before_updating_list_cache(self):
|
||||
cache = ListCache(default=lambda k: None)
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
|
||||
cache = ListCache(default=lambda k: ["old_value", "other old value"])
|
||||
cache.update("old_key", "old_value", "old_key", "new_value")
|
||||
assert cache.get("old_key") == ["new_value", "other old value"]
|
||||
|
||||
cache = ListCache(default=lambda k: ["old_value", "other old value"] if k == "old_key" else None)
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
assert cache.get("old_key") == ["other old value"]
|
||||
assert cache.get("new_key") == ["new_value"]
|
||||
|
||||
cache = ListCache(default=lambda k: ["old_value", "other old value"] if k == "old_key" else ["other new"])
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
assert cache.get("old_key") == ["other old value"]
|
||||
assert cache.get("new_key") == ["other new", "new_value"]
|
||||
|
||||
def test_default_is_called_before_updating_list_if_needed_cache(self):
|
||||
cache = ListIfNeededCache(default=lambda k: None)
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
|
||||
cache = ListIfNeededCache(default=lambda k: "old_value")
|
||||
cache.update("old_key", "old_value", "old_key", "new_value")
|
||||
assert cache.get("old_key") == "new_value"
|
||||
|
||||
cache = ListIfNeededCache(default=lambda k: ["old_value", "other old value"])
|
||||
cache.update("old_key", "old_value", "old_key", "new_value")
|
||||
assert cache.get("old_key") == ["new_value", "other old value"]
|
||||
|
||||
cache = ListIfNeededCache(default=lambda k: ["old_value", "other old value"] if k == "old_key" else None)
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
assert cache.get("old_key") == ["other old value"]
|
||||
assert cache.get("new_key") == "new_value"
|
||||
|
||||
def test_default_is_called_before_updating_set_cache(self):
|
||||
cache = SetCache(default=lambda k: None)
|
||||
with pytest.raises(KeyError):
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
|
||||
cache = SetCache(default=lambda k: {"old_value", "other old value"})
|
||||
cache.update("old_key", "old_value", "old_key", "new_value")
|
||||
assert cache.get("old_key") == {"new_value", "other old value"}
|
||||
|
||||
cache = SetCache(default=lambda k: {"old_value", "other old value"} if k == "old_key" else None)
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
assert cache.get("old_key") == {"other old value"}
|
||||
assert cache.get("new_key") == {"new_value"}
|
||||
|
||||
cache = SetCache(default=lambda k: {"old_value", "other old value"} if k == "old_key" else {"other new"})
|
||||
cache.update("old_key", "old_value", "new_key", "new_value")
|
||||
assert cache.get("old_key") == {"other old value"}
|
||||
assert cache.get("new_key") == {"other new", "new_value"}
|
||||
|
||||
def test_i_can_delete_an_entry_from_cache(self):
|
||||
cache = Cache()
|
||||
cache.put("key", "value")
|
||||
|
||||
assert cache.get("key") == "value"
|
||||
cache.delete("key")
|
||||
assert cache.get("value") is None
|
||||
assert cache.to_remove == {"key"}
|
||||
Vendored
+111
@@ -0,0 +1,111 @@
|
||||
from cache.Cache import Cache
|
||||
from cache.CacheManager import CacheManager
|
||||
from cache.DictionaryCache import DictionaryCache
|
||||
from cache.ListCache import ListCache
|
||||
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
class TestCacheManager(TestUsingMemoryBasedSheerka):
|
||||
def test_i_do_not_push_into_sdp_when_cache_only(self):
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
|
||||
cache_manager = CacheManager(True)
|
||||
cache_manager.register_cache("test", Cache(), persist=True)
|
||||
cache_manager.put("test", "key", "value")
|
||||
|
||||
cache_manager.commit(context)
|
||||
assert not sheerka.sdp.exists("test", "key")
|
||||
|
||||
def test_i_do_not_get_value_from_sdp_when_cache_only_is_true(self):
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
with sheerka.sdp.get_transaction(context.event) as transaction:
|
||||
transaction.add("test", "key", "value")
|
||||
|
||||
cache = Cache(default=lambda k: sheerka.sdp.get("test", k))
|
||||
|
||||
cache_manager = CacheManager(True)
|
||||
cache_manager.register_cache("test", cache, persist=True)
|
||||
|
||||
assert cache_manager.get("test", "key") is None
|
||||
|
||||
def test_i_can_get_value_from_sdp_when_cache_only_is_false(self):
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
with sheerka.sdp.get_transaction(context.event) as transaction:
|
||||
transaction.add("test", "key", "value")
|
||||
|
||||
cache = Cache(default=lambda k: sheerka.sdp.get("test", k))
|
||||
|
||||
cache_manager = CacheManager(False)
|
||||
cache_manager.register_cache("test", cache, persist=True)
|
||||
|
||||
assert cache_manager.get("test", "key") == "value"
|
||||
|
||||
def test_i_can_commit_simple_cache(self):
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
|
||||
cache_manager = CacheManager(False)
|
||||
cache_manager.register_cache("test", Cache(), persist=True)
|
||||
cache = cache_manager.caches["test"].cache
|
||||
|
||||
cache_manager.put("test", "key", "value")
|
||||
|
||||
cache_manager.commit(context)
|
||||
assert sheerka.sdp.get("test", "key") == "value"
|
||||
|
||||
cache.update("key", "value", "key", "another_value")
|
||||
cache_manager.commit(context)
|
||||
assert sheerka.sdp.get("test", "key") == "another_value"
|
||||
|
||||
cache.update("key", "another_value", "key2", "another_value")
|
||||
cache_manager.commit(context)
|
||||
assert sheerka.sdp.get("test", "key") is None
|
||||
assert sheerka.sdp.get("test", "key2") == "another_value"
|
||||
|
||||
def test_i_can_commit_list_cache(self):
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
|
||||
cache_manager = CacheManager(False)
|
||||
cache_manager.register_cache("test", ListCache(), persist=True)
|
||||
cache = cache_manager.caches["test"].cache
|
||||
|
||||
cache.put("key", "value")
|
||||
cache_manager.commit(context)
|
||||
assert sheerka.sdp.get("test", "key") == ["value"]
|
||||
|
||||
cache.put("key", "value2")
|
||||
cache_manager.commit(context)
|
||||
assert sheerka.sdp.get("test", "key") == ["value", "value2"]
|
||||
|
||||
cache.update("key", "value2", "key2", "value2")
|
||||
cache_manager.commit(context)
|
||||
assert sheerka.sdp.get("test", "key") == ["value"]
|
||||
assert sheerka.sdp.get("test", "key2") == ["value2"]
|
||||
|
||||
cache.update("key2", "value2", "key3", "value2")
|
||||
cache_manager.commit(context)
|
||||
assert sheerka.sdp.get("test", "key") == ["value"]
|
||||
assert sheerka.sdp.get("test", "key2") is None
|
||||
assert sheerka.sdp.get("test", "key3") == ["value2"]
|
||||
|
||||
def test_i_can_commit_dictionary_cache(self):
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
|
||||
cache_manager = CacheManager(False)
|
||||
cache_manager.register_cache("test", DictionaryCache(), persist=True)
|
||||
cache = cache_manager.caches["test"].cache
|
||||
|
||||
cache.put(False, {"key": "value", "key2": "value2"})
|
||||
cache_manager.commit(context)
|
||||
assert sheerka.sdp.get("test") == {"key": "value", "key2": "value2"}
|
||||
assert sheerka.sdp.get("test", "key") == "value"
|
||||
|
||||
cache.put(False, {"key": "value", "key2": "value2", "key3": "value3"})
|
||||
cache_manager.commit(context)
|
||||
assert sheerka.sdp.get("test") == {"key": "value", "key2": "value2", "key3": "value3"}
|
||||
@@ -1,18 +1,20 @@
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import PROPERTIES_TO_SERIALIZE, Concept, DEFINITION_TYPE_DEF
|
||||
from core.sheerka.Sheerka import Sheerka
|
||||
from sdp.sheerkaDataProvider import SheerkaDataProvider
|
||||
|
||||
from tests.TestUsingFileBasedSheerka import TestUsingFileBasedSheerka
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
class TestSheerkaCreateNewConcept(TestUsingMemoryBasedSheerka):
|
||||
def test_i_can_add_a_concept(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
def test_i_can_create_a_concept(self):
|
||||
sheerka = self.get_sheerka(cache_only=False)
|
||||
context = self.get_context(sheerka)
|
||||
concept = self.get_default_concept()
|
||||
|
||||
res = sheerka.create_new_concept(self.get_context(sheerka), concept)
|
||||
res = sheerka.create_new_concept(context, concept)
|
||||
sheerka.cache_manager.commit(context)
|
||||
|
||||
assert res.status
|
||||
assert sheerka.isinstance(res.value, BuiltinConcepts.NEW_CONCEPT)
|
||||
@@ -24,22 +26,36 @@ class TestSheerkaCreateNewConcept(TestUsingMemoryBasedSheerka):
|
||||
assert concept_found.key == "__var__0 + __var__1"
|
||||
assert concept_found.id == "1001"
|
||||
|
||||
assert concept.key in sheerka.cache_by_key
|
||||
assert concept.id in sheerka.cache_by_id
|
||||
assert concept.name in sheerka.cache_by_name
|
||||
assert sheerka.sdp.io.exists(
|
||||
sheerka.sdp.io.get_obj_path(SheerkaDataProvider.ObjectsFolder, concept_found.get_origin()))
|
||||
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_HASH_ENTRY, concept.get_definition_hash())
|
||||
# saved in cache
|
||||
assert sheerka.has_id(concept.id)
|
||||
assert sheerka.has_key(concept.key)
|
||||
assert sheerka.has_name(concept.name)
|
||||
assert sheerka.has_hash(concept.get_definition_hash())
|
||||
|
||||
# I can get the concept using various index
|
||||
assert sheerka.get_by_id(concept.id) == concept
|
||||
assert sheerka.get_by_key(concept.key) == concept
|
||||
assert sheerka.get_by_name(concept.name) == concept
|
||||
assert sheerka.get_by_hash(concept.get_definition_hash()) == concept
|
||||
|
||||
# I can get by the first entry
|
||||
assert sheerka.cache_manager.get(sheerka.CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "+") == [concept.id]
|
||||
assert sheerka.cache_manager.get(sheerka.RESOLVED_CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "+") == [concept.id]
|
||||
|
||||
# saved in sdp
|
||||
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_ID_ENTRY, concept.id)
|
||||
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_KEY_ENTRY, concept.key)
|
||||
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_NAME_ENTRY, concept.name)
|
||||
assert sheerka.sdp.exists(Sheerka.CONCEPTS_ENTRY, concept.key)
|
||||
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_HASH_ENTRY, concept.get_definition_hash())
|
||||
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "+")
|
||||
|
||||
def test_i_can_add_a_concept_when_name_differs_from_the_key(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept = Concept("greetings", definition="hello a", definition_type=DEFINITION_TYPE_DEF).def_prop("a")
|
||||
sheerka = self.get_sheerka(cache_only=False)
|
||||
context = self.get_context(sheerka)
|
||||
concept = Concept("greetings", definition="hello a", definition_type=DEFINITION_TYPE_DEF).def_var("a")
|
||||
|
||||
res = sheerka.create_new_concept(self.get_context(sheerka), concept)
|
||||
sheerka.cache_manager.commit(context)
|
||||
|
||||
assert res.status
|
||||
assert sheerka.isinstance(res.value, BuiltinConcepts.NEW_CONCEPT)
|
||||
@@ -51,15 +67,24 @@ class TestSheerkaCreateNewConcept(TestUsingMemoryBasedSheerka):
|
||||
assert concept_found.key == "hello __var__0"
|
||||
assert concept_found.id == "1001"
|
||||
|
||||
assert concept.key in sheerka.cache_by_key
|
||||
assert concept.id in sheerka.cache_by_id
|
||||
assert concept.name in sheerka.cache_by_name
|
||||
assert sheerka.sdp.io.exists(
|
||||
sheerka.sdp.io.get_obj_path(SheerkaDataProvider.ObjectsFolder, concept_found.get_origin()))
|
||||
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_HASH_ENTRY, concept.get_definition_hash())
|
||||
# saved in cache
|
||||
assert sheerka.has_id(concept.id)
|
||||
assert sheerka.has_key(concept.key)
|
||||
assert sheerka.has_name(concept.name)
|
||||
assert sheerka.has_hash(concept.get_definition_hash())
|
||||
|
||||
# I can get the concept using various index
|
||||
assert sheerka.get_by_id(concept.id) == concept
|
||||
assert sheerka.get_by_key(concept.key) == concept
|
||||
assert sheerka.get_by_name(concept.name) == concept
|
||||
assert sheerka.get_by_hash(concept.get_definition_hash()) == concept
|
||||
|
||||
# saved in sdp
|
||||
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_ID_ENTRY, concept.id)
|
||||
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_KEY_ENTRY, concept.key)
|
||||
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_NAME_ENTRY, concept.name)
|
||||
assert sheerka.sdp.exists(Sheerka.CONCEPTS_ENTRY, concept.key)
|
||||
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_HASH_ENTRY, concept.get_definition_hash())
|
||||
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "hello")
|
||||
|
||||
def test_i_cannot_add_the_same_concept_twice(self):
|
||||
"""
|
||||
@@ -82,7 +107,7 @@ class TestSheerkaCreateNewConcept(TestUsingMemoryBasedSheerka):
|
||||
|
||||
sheerka.create_new_concept(self.get_context(sheerka), concept)
|
||||
|
||||
from_cache = sheerka.get(concept.key)
|
||||
from_cache = sheerka.get_by_key(concept.key)
|
||||
assert from_cache is not None
|
||||
assert from_cache == concept
|
||||
|
||||
@@ -90,57 +115,7 @@ class TestSheerkaCreateNewConcept(TestUsingMemoryBasedSheerka):
|
||||
assert from_cache is not None
|
||||
assert from_cache == concept
|
||||
|
||||
def test_i_first_look_in_local_cache(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept = self.get_default_concept()
|
||||
|
||||
sheerka.create_new_concept(self.get_context(sheerka), concept)
|
||||
sheerka.cache_by_key[concept.key].pre = "I have modified the concept in cache"
|
||||
|
||||
from_cache = sheerka.get(concept.key)
|
||||
assert from_cache is not None
|
||||
assert from_cache.key == concept.key
|
||||
assert from_cache.pre == "I have modified the concept in cache"
|
||||
|
||||
def test_i_can_get_a_known_concept_when_not_in_cache(self):
|
||||
"""
|
||||
When not in cache, uses sdp
|
||||
:return:
|
||||
"""
|
||||
sheerka = self.get_sheerka()
|
||||
concept = self.get_default_concept()
|
||||
sheerka.create_new_concept(self.get_context(sheerka), concept)
|
||||
|
||||
sheerka.reset_cache()
|
||||
loaded = sheerka.get(concept.key)
|
||||
|
||||
assert loaded == concept
|
||||
|
||||
# I can also get it by its id
|
||||
loaded = sheerka.sdp.get(sheerka.CONCEPTS_BY_ID_ENTRY, concept.id)
|
||||
assert loaded == concept
|
||||
|
||||
def test_i_can_instantiate_a_concept_from_sdp(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept = Concept("foo")
|
||||
sheerka.create_new_concept(self.get_context(sheerka), concept)
|
||||
|
||||
sheerka.reset_cache()
|
||||
loaded = sheerka.new("foo")
|
||||
|
||||
assert loaded == concept
|
||||
|
||||
def test_i_can_get_a_concept_by_its_id(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept = self.get_default_concept()
|
||||
sheerka.create_new_concept(self.get_context(sheerka), concept)
|
||||
|
||||
sheerka.cache_by_key = {} # reset the cache
|
||||
loaded = sheerka.get_by_id(concept.id)
|
||||
|
||||
assert loaded == concept
|
||||
|
||||
def test_i_can_get_list_of_concept_when_same_key_when_no_cache(self):
|
||||
def test_i_can_get_list_of_concept_when_same_key_using_cache(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept1 = self.get_default_concept()
|
||||
concept2 = self.get_default_concept()
|
||||
@@ -149,79 +124,13 @@ class TestSheerkaCreateNewConcept(TestUsingMemoryBasedSheerka):
|
||||
res1 = sheerka.create_new_concept(self.get_context(sheerka), concept1)
|
||||
res2 = sheerka.create_new_concept(self.get_context(sheerka), concept2)
|
||||
|
||||
assert res1.status
|
||||
assert res2.status
|
||||
assert res1.value.body.key == res2.value.body.key # same key
|
||||
|
||||
sheerka.cache_by_key = {} # reset the cache
|
||||
|
||||
result = sheerka.get(concept1.key)
|
||||
result = sheerka.get_by_key(concept1.key)
|
||||
assert len(result) == 2
|
||||
assert result[0] == concept1
|
||||
assert result[1] == concept2
|
||||
|
||||
def test_i_can_get_list_of_concept_when_same_key_when_cache(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept1 = self.get_default_concept()
|
||||
concept2 = self.get_default_concept()
|
||||
concept2.metadata.body = "a+b"
|
||||
|
||||
res1 = sheerka.create_new_concept(self.get_context(sheerka), concept1)
|
||||
res2 = sheerka.create_new_concept(self.get_context(sheerka), concept2)
|
||||
|
||||
assert res1.value.body.key == res2.value.body.key # same key
|
||||
|
||||
# sheerka.cache_by_key = {} # Do not reset the cache
|
||||
|
||||
result = sheerka.get(concept1.key)
|
||||
assert len(result) == 2
|
||||
assert result[0] == concept1
|
||||
assert result[1] == concept2
|
||||
|
||||
def test_i_can_get_the_correct_concept_using_the_id_when_same_key_when_no_cache(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept1 = self.get_default_concept()
|
||||
concept2 = self.get_default_concept()
|
||||
concept2.metadata.body = "a+b"
|
||||
|
||||
res1 = sheerka.create_new_concept(self.get_context(sheerka), concept1)
|
||||
res2 = sheerka.create_new_concept(self.get_context(sheerka), concept2)
|
||||
|
||||
assert res1.value.body.key == res2.value.body.key # same key
|
||||
|
||||
result = sheerka.get(concept1.key, res2.body.body.id)
|
||||
assert result.name == "a + b"
|
||||
assert result.metadata.body == "a+b"
|
||||
|
||||
def test_i_can_get_the_correct_concept_using_the_id__when_same_key_when_cache(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept1 = self.get_default_concept()
|
||||
concept2 = self.get_default_concept()
|
||||
concept2.metadata.body = "a+b"
|
||||
|
||||
res1 = sheerka.create_new_concept(self.get_context(sheerka), concept1)
|
||||
res2 = sheerka.create_new_concept(self.get_context(sheerka), concept2)
|
||||
|
||||
assert res1.value.body.key == res2.value.body.key # same key
|
||||
|
||||
result = sheerka.get(concept1.key, res2.body.body.id)
|
||||
assert result.name == "a + b"
|
||||
assert result.metadata.body == "a+b"
|
||||
|
||||
def test_i_cannot_get_the_correct_concept_id_the_id_is_wrong(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept1 = self.get_default_concept()
|
||||
concept2 = self.get_default_concept()
|
||||
concept2.metadata.body = "a+b"
|
||||
|
||||
res1 = sheerka.create_new_concept(self.get_context(sheerka), concept1)
|
||||
res2 = sheerka.create_new_concept(self.get_context(sheerka), concept2)
|
||||
|
||||
assert res1.value.body.key == res2.value.body.key # same key
|
||||
|
||||
result = sheerka.get(concept1.key, "wrong id")
|
||||
assert sheerka.isinstance(result, BuiltinConcepts.UNKNOWN_CONCEPT)
|
||||
|
||||
def test_concept_that_references_itself_is_correctly_created(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept = Concept("foo", body="foo")
|
||||
@@ -233,27 +142,63 @@ class TestSheerkaCreateNewConcept(TestUsingMemoryBasedSheerka):
|
||||
|
||||
class TestSheerkaCreateNewConceptFileBased(TestUsingFileBasedSheerka):
|
||||
def test_i_can_add_several_concepts(self):
|
||||
sheerka, context, hello, greeting = self.init_concepts(
|
||||
Concept("Hello world a").def_prop("a"),
|
||||
Concept("Greeting a").def_prop("a"),
|
||||
use_dict=False
|
||||
)
|
||||
|
||||
res = sheerka.create_new_concept(self.get_context(sheerka), hello)
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
hello = Concept("Hello world a").def_var("a")
|
||||
res = sheerka.create_new_concept(context, hello)
|
||||
sheerka.cache_manager.commit(context)
|
||||
assert res.status
|
||||
|
||||
sheerka = self.get_sheerka(use_dict=False)
|
||||
res = sheerka.create_new_concept(self.get_context(sheerka), greeting)
|
||||
sheerka = self.get_sheerka() # another instance
|
||||
context = self.get_context(sheerka)
|
||||
greeting = Concept("Greeting a").def_var("a")
|
||||
res = sheerka.create_new_concept(context, greeting)
|
||||
sheerka.cache_manager.commit(context)
|
||||
assert res.status
|
||||
|
||||
assert sheerka.sdp.exists(Sheerka.CONCEPTS_ENTRY, hello.key)
|
||||
assert sheerka.sdp.exists(Sheerka.CONCEPTS_ENTRY, greeting.key)
|
||||
sheerka = self.get_sheerka() # another instance again
|
||||
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_KEY_ENTRY, hello.key)
|
||||
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_KEY_ENTRY, greeting.key)
|
||||
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_ID_ENTRY, hello.id)
|
||||
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_ID_ENTRY, greeting.id)
|
||||
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_NAME_ENTRY, "Hello world a")
|
||||
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_NAME_ENTRY, "Greeting a")
|
||||
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_HASH_ENTRY, hello.get_definition_hash())
|
||||
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_HASH_ENTRY, greeting.get_definition_hash())
|
||||
|
||||
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "Hello")
|
||||
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_FIRST_KEYWORD_ENTRY, "Greeting")
|
||||
|
||||
def test_i_cannot_add_the_same_concept_twice_using_sdp(self):
|
||||
"""
|
||||
Checks that duplicated concepts are managed by sheerka, not by sheerka.sdp
|
||||
:return:
|
||||
"""
|
||||
sheerka = self.get_sheerka(cache_only=False)
|
||||
context = self.get_context(sheerka)
|
||||
concept = self.get_default_concept()
|
||||
|
||||
sheerka.create_new_concept(context, concept)
|
||||
sheerka.cache_manager.commit(context)
|
||||
|
||||
sheerka.cache_manager.clear()
|
||||
res = sheerka.create_new_concept(context, concept)
|
||||
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(res.value, BuiltinConcepts.CONCEPT_ALREADY_DEFINED)
|
||||
assert res.value.body == concept
|
||||
|
||||
def test_new_entry_does_not_override_the_previous_ones(self):
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
sheerka.create_new_concept(context, Concept("foo", body="1"))
|
||||
sheerka.create_new_concept(context, Concept("foo", body="2"))
|
||||
sheerka.cache_manager.commit(context)
|
||||
|
||||
assert len(sheerka.sdp.get(Sheerka.CONCEPTS_BY_KEY_ENTRY, "foo")) == 2
|
||||
|
||||
sheerka = self.get_sheerka() # new instance
|
||||
sheerka.create_new_concept(context, Concept("foo", body="3"))
|
||||
sheerka.cache_manager.commit(context)
|
||||
|
||||
assert len(sheerka.sdp.get(Sheerka.CONCEPTS_BY_KEY_ENTRY, "foo")) == 3
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import pytest
|
||||
from core.builtin_concepts import BuiltinConcepts, ReturnValueConcept, ParserResultConcept
|
||||
from core.concept import Concept, simplec, DoNotResolve, ConceptParts, Property, InfiniteRecursionResolved
|
||||
from core.concept import Concept, DoNotResolve, ConceptParts, Property, InfiniteRecursionResolved, CB
|
||||
from parsers.PythonParser import PythonNode
|
||||
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
@@ -9,8 +9,8 @@ from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
|
||||
@pytest.mark.parametrize("body, expected", [
|
||||
# (None, None),
|
||||
# ("", ""),
|
||||
(None, None),
|
||||
("", ""),
|
||||
("1", 1),
|
||||
("1+1", 2),
|
||||
("'one'", "one"),
|
||||
@@ -19,10 +19,9 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
("1 > 2", False),
|
||||
])
|
||||
def test_i_can_evaluate_a_concept_with_simple_body(self, body, expected):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka, context, concept = self.init_concepts(Concept("foo", body=body), eval_body=True)
|
||||
|
||||
concept = Concept("foo", body=body).init_key()
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
evaluated = sheerka.evaluate_concept(context, concept)
|
||||
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == expected
|
||||
@@ -30,7 +29,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
assert evaluated.metadata.pre is None
|
||||
assert evaluated.metadata.post is None
|
||||
assert evaluated.metadata.where is None
|
||||
assert evaluated.props == {}
|
||||
assert evaluated.variables() == {}
|
||||
assert evaluated.metadata.is_evaluated
|
||||
assert len(evaluated.values) == 0 if body is None else 1
|
||||
|
||||
@@ -51,18 +50,17 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
:return:
|
||||
"""
|
||||
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka, context, concept = self.init_concepts(Concept("foo", pre=expr))
|
||||
|
||||
concept = Concept("foo", pre=expr).init_key()
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept)
|
||||
evaluated = sheerka.evaluate_concept(context, concept)
|
||||
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.metadata.body is None
|
||||
assert evaluated.metadata.pre == expr
|
||||
assert evaluated.metadata.post is None
|
||||
assert evaluated.metadata.where is None
|
||||
assert evaluated.get_metadata_value(ConceptParts.PRE) == expected
|
||||
assert evaluated.props == {}
|
||||
assert evaluated.get_value(ConceptParts.PRE) == expected
|
||||
assert evaluated.variables() == {}
|
||||
assert not evaluated.metadata.is_evaluated
|
||||
assert len(evaluated.values) == 0 if expr is None else 1
|
||||
|
||||
@@ -77,124 +75,121 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
("1 > 2", False),
|
||||
])
|
||||
def test_i_can_evaluate_a_concept_with_prop(self, expr, expected):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka, context, concept = self.init_concepts(Concept("foo").def_var("a", expr), eval_body=True)
|
||||
|
||||
concept = Concept("foo").def_prop("a", expr)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka,True), concept)
|
||||
evaluated = sheerka.evaluate_concept(context, concept)
|
||||
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.metadata.pre is None
|
||||
assert evaluated.metadata.pre is None
|
||||
assert evaluated.metadata.post is None
|
||||
assert evaluated.metadata.where is None
|
||||
assert evaluated.props == {"a": Property("a", expected)}
|
||||
assert evaluated.variables() == {"a": Property("a", expected)}
|
||||
assert evaluated.metadata.is_evaluated
|
||||
|
||||
def test_i_can_evaluate_metadata_using_do_not_resolve(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept = Concept("foo")
|
||||
sheerka, context, concept = self.init_concepts(Concept("foo"), eval_body=True)
|
||||
concept.compiled[ConceptParts.BODY] = DoNotResolve("do not resolve")
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
evaluated = sheerka.evaluate_concept(context, concept)
|
||||
|
||||
assert evaluated.body == "do not resolve"
|
||||
assert evaluated.metadata.is_evaluated
|
||||
|
||||
def test_i_can_evaluate_property_using_do_not_resolve(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept = Concept("foo").def_prop("a")
|
||||
sheerka, context, concept = self.init_concepts(Concept("foo").def_var("a"), eval_body=True)
|
||||
concept.compiled["a"] = DoNotResolve("do not resolve")
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
evaluated = sheerka.evaluate_concept(context, concept)
|
||||
|
||||
assert evaluated.get_prop("a") == "do not resolve"
|
||||
assert evaluated.get_value("a") == "do not resolve"
|
||||
assert evaluated.metadata.is_evaluated
|
||||
|
||||
def test_original_value_is_overridden_when_using_do_no_resolve(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept = Concept("foo", body="original value").set_prop("a", "original value")
|
||||
concept = Concept("foo", body="original value").def_var("a", "original value")
|
||||
sheerka, context, concept = self.init_concepts(concept, eval_body=True)
|
||||
concept.compiled["a"] = DoNotResolve("do not resolve")
|
||||
concept.compiled[ConceptParts.BODY] = DoNotResolve("do not resolve")
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
evaluated = sheerka.evaluate_concept(context, concept)
|
||||
|
||||
assert evaluated.body == "do not resolve"
|
||||
assert evaluated.get_prop("a") == "do not resolve"
|
||||
assert evaluated.get_value("a") == "do not resolve"
|
||||
assert evaluated.metadata.is_evaluated
|
||||
|
||||
def test_props_are_evaluated_before_body(self):
|
||||
sheerka = self.get_sheerka()
|
||||
def test_variables_are_evaluated_before_body(self):
|
||||
sheerka, context, concept = self.init_concepts(Concept("foo", body="a+1").def_var("a", "10"), eval_body=True)
|
||||
|
||||
concept = Concept("foo", body="a+1").def_prop("a", "10").init_key()
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
evaluated = sheerka.evaluate_concept(context, concept)
|
||||
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == 11
|
||||
assert evaluated == CB(concept, 11)
|
||||
|
||||
def test_i_can_evaluate_when_another_concept_is_referenced(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept_a = Concept("a")
|
||||
sheerka.add_in_cache(concept_a)
|
||||
sheerka, context, concept_a, concept = self.init_concepts(
|
||||
Concept("a"),
|
||||
Concept("foo", body="a"),
|
||||
eval_body=True)
|
||||
|
||||
concept = Concept("foo", body="a").init_key()
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
evaluated = sheerka.evaluate_concept(context, concept)
|
||||
|
||||
assert evaluated == simplec("foo", simplec("a", None))
|
||||
assert id(evaluated.body) != id(concept_a)
|
||||
assert evaluated == CB("foo", CB("a", None))
|
||||
assert evaluated.metadata.is_evaluated
|
||||
assert evaluated.body.metadata.is_evaluated
|
||||
|
||||
def test_i_can_evaluate_when_the_referenced_concept_has_a_body(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept_a = Concept("a", body="1")
|
||||
sheerka.add_in_cache(concept_a)
|
||||
sheerka, context, concept_a, concept = self.init_concepts(
|
||||
Concept("a", body="1"),
|
||||
Concept("foo", body="a"),
|
||||
eval_body=True)
|
||||
|
||||
concept = Concept("foo", body="a")
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
evaluated = sheerka.evaluate_concept(context, concept)
|
||||
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == simplec("a", 1)
|
||||
assert evaluated.body == CB("a", 1)
|
||||
assert not concept_a.metadata.is_evaluated
|
||||
assert evaluated.metadata.is_evaluated
|
||||
|
||||
def test_i_can_evaluate_concept_of_concept_when_the_leaf_has_a_body(self):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka.add_in_cache(Concept(name="a", body="'a'"))
|
||||
sheerka.add_in_cache(Concept(name="b", body="a"))
|
||||
sheerka.add_in_cache(Concept(name="c", body="b"))
|
||||
concept_d = sheerka.add_in_cache(Concept(name="d", body="c"))
|
||||
sheerka, context, concept_a, concept_b, concept_c, concept_d = self.init_concepts(
|
||||
Concept("a", body="'a'"),
|
||||
Concept("b", body="a"),
|
||||
Concept("c", body="b"),
|
||||
Concept("d", body="c"),
|
||||
eval_body=True)
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept_d)
|
||||
evaluated = sheerka.evaluate_concept(context, concept_d)
|
||||
|
||||
assert evaluated.key == concept_d.key
|
||||
expected = simplec("c", simplec("b", simplec("a", "a")))
|
||||
expected = CB("c", CB("b", CB("a", "a")))
|
||||
assert evaluated.body == expected
|
||||
assert sheerka.value(evaluated) == 'a'
|
||||
assert sheerka.objvalue(evaluated) == 'a'
|
||||
assert evaluated.metadata.is_evaluated
|
||||
|
||||
def test_i_can_evaluate_concept_of_concept_does_not_have_a_body(self):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka.add_in_cache(Concept(name="a"))
|
||||
sheerka.add_in_cache(Concept(name="b", body="a"))
|
||||
sheerka.add_in_cache(Concept(name="c", body="b"))
|
||||
concept_d = sheerka.add_in_cache(Concept(name="d", body="c"))
|
||||
sheerka, context, concept_a, concept_b, concept_c, concept_d = self.init_concepts(
|
||||
Concept("a"),
|
||||
Concept("b", body="a"),
|
||||
Concept("c", body="b"),
|
||||
Concept("d", body="c"),
|
||||
eval_body=True)
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept_d)
|
||||
evaluated = sheerka.evaluate_concept(context, concept_d)
|
||||
|
||||
assert evaluated.key == concept_d.key
|
||||
expected = simplec("c", simplec("b", simplec("a", None)))
|
||||
expected = CB("c", CB("b", CB("a", None)))
|
||||
assert evaluated.body == expected
|
||||
assert sheerka.value(evaluated) == Concept(name="a").init_key()
|
||||
assert sheerka.objvalue(evaluated) == CB("a", None)
|
||||
assert evaluated.metadata.is_evaluated
|
||||
|
||||
def test_i_can_evaluate_concept_when_properties_reference_others_concepts(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept_a = sheerka.add_in_cache(Concept(name="a").init_key())
|
||||
sheerka, context, concept_a, concept = self.init_concepts(
|
||||
Concept("a"),
|
||||
Concept("foo", body="a").def_var("a", "a"),
|
||||
eval_body=True)
|
||||
|
||||
concept = Concept("foo", body="a").def_prop("a", "a").init_key()
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
evaluated = sheerka.evaluate_concept(context, concept)
|
||||
|
||||
# first prop a is evaluated to concept_a
|
||||
# first, prop a is evaluated to concept_a
|
||||
# then body is evaluated to prop a -> concept_a
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == concept_a
|
||||
@@ -205,49 +200,49 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
but the name of the property and the name of the concept are different
|
||||
:return:
|
||||
"""
|
||||
sheerka = self.get_sheerka()
|
||||
concept_a = sheerka.add_in_cache(Concept(name="a"))
|
||||
sheerka, context, concept_a = self.init_concepts(Concept(name="a"), eval_body=True)
|
||||
|
||||
concept = Concept("foo", body="concept_a").def_prop("concept_a", "a")
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
concept = Concept("foo", body="concept_a").def_var("concept_a", "a")
|
||||
evaluated = sheerka.evaluate_concept(context, concept)
|
||||
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == concept_a
|
||||
|
||||
def test_i_can_evaluate_concept_when_properties_reference_others_concepts_with_body(self):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka.add_in_cache(Concept(name="a", body="1"))
|
||||
sheerka.add_in_cache(Concept(name="b", body="2"))
|
||||
sheerka, context, *concepts = self.init_concepts(
|
||||
Concept(name="a", body="1"),
|
||||
Concept(name="b", body="2"),
|
||||
eval_body=True
|
||||
)
|
||||
|
||||
concept = Concept("foo", body="propA + propB").def_prop("propA", "a").def_prop("propB", "b")
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
concept = Concept("foo", body="propA + propB").def_var("propA", "a").def_var("propB", "b")
|
||||
evaluated = sheerka.evaluate_concept(context, concept)
|
||||
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == 3
|
||||
|
||||
def test_i_can_evaluate_concept_when_properties_is_a_concept(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept_a = sheerka.add_in_cache(Concept(name="a", body="'a'").init_key())
|
||||
sheerka, context, concept_a = self.init_concepts(Concept(name="a", body="'a'"), eval_body=True)
|
||||
|
||||
concept = Concept("foo").def_prop("a")
|
||||
concept = Concept("foo").def_var("a")
|
||||
concept.compiled["a"] = concept_a
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
evaluated = sheerka.evaluate_concept(context, concept)
|
||||
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.get_prop("a") == simplec("a", "a")
|
||||
assert evaluated.get_value("a") == CB("a", "a")
|
||||
|
||||
def test_i_can_evaluate_when_property_asts_is_a_list(self):
|
||||
sheerka = self.get_sheerka()
|
||||
foo = Concept("foo", body="1")
|
||||
|
||||
concept = Concept("to_eval").def_prop("prop")
|
||||
concept = Concept("to_eval").def_var("prop")
|
||||
concept.compiled["prop"] = [foo, DoNotResolve("1")]
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
|
||||
props = evaluated.get_prop("prop")
|
||||
assert len(props) == 2
|
||||
assert props[0] == simplec("foo", 1)
|
||||
assert props[1] == "1"
|
||||
variables = evaluated.get_value("prop")
|
||||
assert len(variables) == 2
|
||||
assert variables[0] == CB("foo", 1)
|
||||
assert variables[1] == "1"
|
||||
|
||||
def test_i_can_evaluate_when_compiled_is_set_up_with_return_value(self):
|
||||
sheerka = self.get_sheerka()
|
||||
@@ -255,16 +250,16 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
python_node = PythonNode("1 +1 ")
|
||||
parser_result = ParserResultConcept(parser="who", value=python_node)
|
||||
|
||||
concept = Concept("to_eval").def_prop("prop")
|
||||
concept = Concept("to_eval").def_var("prop")
|
||||
concept.compiled["prop"] = [ReturnValueConcept("who", True, parser_result)]
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
assert evaluated.get_prop("prop") == 2
|
||||
assert evaluated.get_value("prop") == 2
|
||||
|
||||
# also works when only one return value
|
||||
concept = Concept("to_eval").def_prop("prop")
|
||||
concept = Concept("to_eval").def_var("prop")
|
||||
concept.compiled["prop"] = ReturnValueConcept("who", True, parser_result)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
assert evaluated.get_prop("prop") == 2
|
||||
assert evaluated.get_value("prop") == 2
|
||||
|
||||
def test_i_can_reference_sheerka(self):
|
||||
sheerka = self.get_sheerka()
|
||||
@@ -276,49 +271,55 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
assert evaluated.body == sheerka.test()
|
||||
|
||||
def test_properties_values_takes_precedence_over_the_outside_world(self):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka.add_in_cache(Concept(name="a", body="'concept_a'"))
|
||||
sheerka.add_in_cache(Concept(name="b", body="'concept_b'"))
|
||||
sheerka, context, concept_a, concept_b = self.init_concepts(
|
||||
Concept(name="a", body="'concept_a'"),
|
||||
Concept(name="b", body="'concept_b'"),
|
||||
eval_body=True
|
||||
)
|
||||
|
||||
concept = Concept("foo", body="a")
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
evaluated = sheerka.evaluate_concept(context, concept)
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == simplec("a", "concept_a") # this test was already done
|
||||
assert evaluated.body == CB("a", "concept_a") # this test was already done
|
||||
|
||||
# so check this one.
|
||||
concept = Concept("foo", body="a").def_prop("a", "'property_a'")
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
concept = Concept("foo", body="a").def_var("a", "'property_a'")
|
||||
evaluated = sheerka.evaluate_concept(context, concept)
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == 'property_a'
|
||||
|
||||
# or this one.
|
||||
concept = Concept("foo", body="a").def_prop("a", "b")
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
concept = Concept("foo", body="a").def_var("a", "b")
|
||||
evaluated = sheerka.evaluate_concept(context, concept)
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == simplec(name="b", body="concept_b")
|
||||
assert evaluated.body == CB("b", "concept_b")
|
||||
|
||||
def test_properties_values_takes_precedence(self):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka.add_in_cache(Concept(name="a", body="'concept_a'"))
|
||||
sheerka.add_in_cache(Concept(name="b", body="'concept_b'"))
|
||||
sheerka, context, concept_a, concept_b = self.init_concepts(
|
||||
Concept(name="a", body="'concept_a'"),
|
||||
Concept(name="b", body="'concept_b'"),
|
||||
eval_body=True
|
||||
)
|
||||
|
||||
concept = Concept("foo", body="a + b").def_prop("a", "'prop_a'").init_key()
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
concept = Concept("foo", body="a + b").def_var("a", "'prop_a'").init_key()
|
||||
evaluated = sheerka.evaluate_concept(context, concept)
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == 'prop_aconcept_b'
|
||||
|
||||
def test_i_can_reference_sub_property_of_a_property(self):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka.add_in_cache(Concept(name="concept_a").def_prop("subProp", "'sub_a'"))
|
||||
sheerka, context, concept_a = self.init_concepts(
|
||||
Concept(name="concept_a").def_var("subProp", "'sub_a'"),
|
||||
eval_body=True
|
||||
)
|
||||
|
||||
concept = Concept("foo", body="a.props['subProp'].value").def_prop("a", "concept_a")
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
assert evaluated == simplec(concept.key, "sub_a")
|
||||
concept = Concept("foo", body="a.subProp").def_var("a", "concept_a")
|
||||
evaluated = sheerka.evaluate_concept(context, concept)
|
||||
assert evaluated == CB(concept.key, "sub_a")
|
||||
|
||||
def test_i_cannot_evaluate_concept_if_property_is_in_error(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
concept = Concept(name="concept_a").def_prop("subProp", "undef_concept")
|
||||
concept = Concept(name="concept_a").def_var("subProp", "undef_concept")
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CONCEPT_EVAL_ERROR)
|
||||
|
||||
@@ -340,11 +341,10 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
("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)
|
||||
|
||||
sheerka, context, concept = self.init_concepts(
|
||||
Concept("foo", body="10", where=where_clause).def_var("a", "20"),
|
||||
)
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, False, True), concept)
|
||||
|
||||
if expected:
|
||||
@@ -354,12 +354,10 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
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)
|
||||
sheerka, context, foo_true, foo_false = self.init_concepts(
|
||||
Concept("foo_true", body="True"),
|
||||
Concept("foo_false", body="False"),
|
||||
)
|
||||
|
||||
concept = Concept("foo", where="foo_true").init_key()
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, False, True), concept)
|
||||
@@ -375,12 +373,9 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
assert evaluated.key == concept.key
|
||||
|
||||
def test_i_can_evaluate_disable_where_clause_evaluation(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
concept = Concept("foo", body="10", where="a > 10").def_prop("a", None)
|
||||
sheerka.add_in_cache(concept)
|
||||
|
||||
context = self.get_context(sheerka)
|
||||
sheerka, context, concept = self.init_concepts(
|
||||
Concept("foo", body="10", where="a > 10").def_var("a", None),
|
||||
)
|
||||
evaluated = sheerka.evaluate_concept(context, concept)
|
||||
assert evaluated.key == concept.key
|
||||
|
||||
@@ -389,82 +384,84 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CONCEPT_EVAL_ERROR)
|
||||
|
||||
def test_i_can_detect_infinite_recursion_with_numeric_constant(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
one_str = Concept("one", body="1")
|
||||
one_digit = Concept("1", body="one")
|
||||
sheerka, context, one_str, one_digit = self.init_concepts(
|
||||
Concept("one", body="1"),
|
||||
Concept("1", body="one"),
|
||||
eval_body=True
|
||||
)
|
||||
|
||||
sheerka.add_in_cache(one_str)
|
||||
sheerka.add_in_cache(one_digit)
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), one_digit)
|
||||
evaluated = sheerka.evaluate_concept(context, one_digit)
|
||||
assert evaluated.key == one_digit.key
|
||||
assert evaluated.body == InfiniteRecursionResolved(1)
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), one_str)
|
||||
evaluated = sheerka.evaluate_concept(context, one_str)
|
||||
assert evaluated.key == one_str.key
|
||||
assert evaluated.body == InfiniteRecursionResolved(1)
|
||||
|
||||
def test_i_can_detect_infinite_recursion_with_boolean_constant(self):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka, context, true_str, true_bool = self.init_concepts(
|
||||
Concept("true", body="True"),
|
||||
Concept("True", body="true"),
|
||||
eval_body=True
|
||||
)
|
||||
|
||||
true_str = Concept("true", body="True")
|
||||
true_bool = Concept("True", body="true")
|
||||
|
||||
sheerka.add_in_cache(true_str)
|
||||
sheerka.add_in_cache(true_bool)
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), true_str)
|
||||
evaluated = sheerka.evaluate_concept(context, true_str)
|
||||
assert evaluated.key == true_str.key
|
||||
assert evaluated.body == InfiniteRecursionResolved(True)
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), true_bool)
|
||||
evaluated = sheerka.evaluate_concept(context, true_bool)
|
||||
assert evaluated.key == true_bool.key
|
||||
assert evaluated.body == InfiniteRecursionResolved(True)
|
||||
|
||||
def test_i_can_detect_infinite_recursion_with_constant_with_more_concepts(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
c1 = sheerka.add_in_cache(Concept("one", body="1"))
|
||||
c2 = sheerka.add_in_cache(Concept("1", body="2"))
|
||||
c3 = sheerka.add_in_cache(Concept("2", body="3"))
|
||||
c4 = sheerka.add_in_cache(Concept("3", body="one"))
|
||||
sheerka, context, c1, c2, c3, c4 = self.init_concepts(
|
||||
Concept("one", body="1"),
|
||||
Concept("1", body="2"),
|
||||
Concept("2", body="3"),
|
||||
Concept("3", body="one"),
|
||||
eval_body=True
|
||||
)
|
||||
|
||||
for concept in (c1, c2, c3, c4):
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
|
||||
evaluated = sheerka.evaluate_concept(context, concept)
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == InfiniteRecursionResolved(3)
|
||||
|
||||
def test_i_can_detect_infinite_recursion_when_no_constant(self):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka, context, foo, bar, baz, qux = self.init_concepts(
|
||||
Concept("foo", body="bar"),
|
||||
Concept("bar", body="baz"),
|
||||
Concept("baz", body="qux"),
|
||||
Concept("qux", body="foo"),
|
||||
eval_body=True
|
||||
)
|
||||
|
||||
foo = sheerka.add_in_cache(Concept("foo", body="bar"))
|
||||
bar = sheerka.add_in_cache(Concept("bar", body="baz"))
|
||||
baz = sheerka.add_in_cache(Concept("baz", body="qux"))
|
||||
qux = sheerka.add_in_cache(Concept("qux", body="foo"))
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), foo)
|
||||
evaluated = sheerka.evaluate_concept(context, foo)
|
||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
|
||||
assert evaluated.body == {foo, bar, baz, qux}
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), bar)
|
||||
evaluated = sheerka.evaluate_concept(context, bar)
|
||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
|
||||
assert evaluated.body == {foo, bar, baz, qux}
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), baz)
|
||||
evaluated = sheerka.evaluate_concept(context, baz)
|
||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
|
||||
assert evaluated.body == {foo, bar, baz, qux}
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), qux)
|
||||
evaluated = sheerka.evaluate_concept(context, qux)
|
||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
|
||||
assert evaluated.body == {foo, bar, baz, qux}
|
||||
|
||||
def test_i_can_detect_auto_recursion(self):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka, context, foo = self.init_concepts(
|
||||
Concept("foo", body="foo"),
|
||||
eval_body=True
|
||||
)
|
||||
|
||||
foo = sheerka.add_in_cache(Concept("foo", body="foo"))
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), foo)
|
||||
evaluated = sheerka.evaluate_concept(context, foo)
|
||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
|
||||
assert evaluated.body == {foo}
|
||||
|
||||
@@ -475,6 +472,3 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), one)
|
||||
assert evaluated.key == one.key
|
||||
assert evaluated.body == 1
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,8 @@ from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
class TestSheerkaHistoryManager(TestUsingMemoryBasedSheerka):
|
||||
def test_i_can_retrieve_history(self):
|
||||
sheerka = self.get_sheerka(skip_builtins_in_db=False, singleton=False)
|
||||
sheerka = self.get_sheerka(singleton=False)
|
||||
sheerka.save_execution_context = True
|
||||
|
||||
sheerka.evaluate_user_input("def concept one as 1")
|
||||
sheerka.evaluate_user_input("one")
|
||||
|
||||
@@ -1,96 +1,79 @@
|
||||
import pytest
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import Concept, ConceptParts
|
||||
from core.sheerka.Sheerka import Sheerka
|
||||
|
||||
from tests.TestUsingFileBasedSheerka import TestUsingFileBasedSheerka
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
class TestSheerkaModifyConcept(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def test_i_can_modify_a_concept(self):
|
||||
sheerka, context, foo, bar = self.init_concepts("foo", "bar", create_new=True)
|
||||
sheerka, context, foo, bar = self.init_concepts("foo", "bar", create_new=True, cache_only=False)
|
||||
|
||||
foo_instance = sheerka.new("foo")
|
||||
foo_instance.metadata.body = "value" # modify metadata
|
||||
foo_instance.set_prop(BuiltinConcepts.ISA, bar) # modify property
|
||||
foo_instance.set_metadata_value(ConceptParts.BODY, "body value") # modify value
|
||||
foo_instance.metadata.body = "metadata value" # modify metadata
|
||||
foo_instance.def_var("var_name", "default value") # modify definition of variables
|
||||
foo_instance.add_prop(BuiltinConcepts.ISA, bar) # modify property
|
||||
foo_instance.set_value(ConceptParts.BODY, "body value") # modify value
|
||||
foo_instance.set_value("var_name", "var value") # modify value
|
||||
res = sheerka.modify_concept(context, foo_instance)
|
||||
|
||||
assert res.status
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.NEW_CONCEPT)
|
||||
assert res.body.body.metadata.body == "value"
|
||||
assert res.body.body.get_prop(BuiltinConcepts.ISA) == bar
|
||||
assert res.body.body.metadata.body == "metadata value"
|
||||
assert res.body.body.metadata.variables == [("var_name", "default value")]
|
||||
assert res.body.body.get_prop(BuiltinConcepts.ISA) == {bar}
|
||||
assert res.body.body.body == "body value"
|
||||
assert res.body.body.get_value("var_name") == "var value"
|
||||
|
||||
# test that object
|
||||
sheerka.reset_cache()
|
||||
foo_from_sheerka = sheerka.new("foo")
|
||||
assert foo_from_sheerka.metadata.body == "value"
|
||||
assert foo_from_sheerka.get_prop(BuiltinConcepts.ISA) == bar
|
||||
foo_from_sheerka = sheerka.get_by_key("foo")
|
||||
assert foo_from_sheerka.metadata.body == "metadata value"
|
||||
assert foo_from_sheerka.metadata.variables == [("var_name", "default value")]
|
||||
assert foo_from_sheerka.get_prop(BuiltinConcepts.ISA) == {bar}
|
||||
assert foo_from_sheerka.body == "body value"
|
||||
assert foo_from_sheerka.get_value("var_name") == "var value"
|
||||
|
||||
# test that ref by id is updated
|
||||
sheerka.reset_cache()
|
||||
foo_from_sheerka = sheerka.get_by_id(foo.id)
|
||||
assert foo_from_sheerka.metadata.body == "value"
|
||||
assert foo_from_sheerka.get_prop(BuiltinConcepts.ISA) == bar
|
||||
assert foo_from_sheerka.body == "body value"
|
||||
# other caches are also updated
|
||||
assert sheerka.get_by_id(foo.id).metadata.body == "metadata value"
|
||||
assert sheerka.get_by_name(foo.name).metadata.body == "metadata value"
|
||||
assert sheerka.get_by_hash(foo_instance.get_definition_hash()).metadata.body == "metadata value"
|
||||
|
||||
# test that ref by name is updated
|
||||
sheerka.reset_cache()
|
||||
foo_from_sheerka = sheerka.get_by_name(foo.name)
|
||||
assert foo_from_sheerka.metadata.body == "value"
|
||||
assert foo_from_sheerka.get_prop(BuiltinConcepts.ISA) == bar
|
||||
assert foo_from_sheerka.body == "body value"
|
||||
|
||||
# test that ref by hash is updated
|
||||
foo_from_sdp = sheerka.sdp.get(Sheerka.CONCEPTS_BY_HASH_ENTRY, foo_instance.get_definition_hash())
|
||||
assert foo_from_sdp.metadata.body == "value"
|
||||
assert foo_from_sdp.get_prop(BuiltinConcepts.ISA) == bar
|
||||
assert foo_from_sdp.body == "body value"
|
||||
|
||||
# previous ref by hash is removed (since that definition hash has changed)
|
||||
with pytest.raises(IndexError):
|
||||
sheerka.sdp.get(Sheerka.CONCEPTS_BY_HASH_ENTRY, foo_instance.get_original_definition_hash())
|
||||
|
||||
def test_i_can_modify_concept_modifying_only_properties_and_body(self):
|
||||
sheerka, context, foo, bar = self.init_concepts("foo", "bar", create_new=True)
|
||||
|
||||
foo_instance = sheerka.new("foo")
|
||||
foo_instance.set_prop(BuiltinConcepts.ISA, bar)
|
||||
foo_instance.set_metadata_value(ConceptParts.BODY, "body value")
|
||||
res = sheerka.modify_concept(context, foo_instance)
|
||||
|
||||
assert res.status
|
||||
|
||||
foo_from_sheerka = sheerka.new("foo")
|
||||
assert foo_from_sheerka.get_prop(BuiltinConcepts.ISA) == bar
|
||||
assert foo_from_sheerka.body == "body value"
|
||||
|
||||
def test_cache_is_updated_when_a_concept_is_modified(self):
|
||||
sheerka, context, foo = self.init_concepts("foo", create_new=True)
|
||||
|
||||
foo_instance = sheerka.new("foo")
|
||||
foo_instance.metadata.body = "value"
|
||||
res = sheerka.modify_concept(context, foo_instance)
|
||||
assert res.status
|
||||
|
||||
foo_from_sheerka = sheerka.get("foo")
|
||||
assert foo_from_sheerka.metadata.body == "value"
|
||||
|
||||
foo_by_id_from_sheerka = sheerka.get_by_id(foo.id)
|
||||
assert foo_by_id_from_sheerka.metadata.body == "value"
|
||||
# sdp can be updated
|
||||
sheerka.cache_manager.commit(context)
|
||||
from_sdp = sheerka.sdp.get(sheerka.CONCEPTS_BY_ID_ENTRY, foo.id)
|
||||
assert from_sdp.metadata.body == "metadata value"
|
||||
assert from_sdp.metadata.variables == [("var_name", "default value")]
|
||||
assert from_sdp.get_prop(BuiltinConcepts.ISA) == {bar}
|
||||
assert from_sdp.body == "body value"
|
||||
assert from_sdp.get_value("var_name") == "var value"
|
||||
|
||||
def test_i_cannot_modify_a_concept_that_does_not_exists(self):
|
||||
sheerka, context, foo = self.init_concepts("foo", create_new=False)
|
||||
sheerka, context = self.init_concepts()
|
||||
|
||||
foo_instance = sheerka.new("foo")
|
||||
foo_instance.metadata.body = "value"
|
||||
res = sheerka.modify_concept(context, foo_instance)
|
||||
foo = Concept("foo").init_key()
|
||||
sheerka.set_id_if_needed(foo, False)
|
||||
|
||||
res = sheerka.modify_concept(context, foo)
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.UNKNOWN_CONCEPT)
|
||||
assert res.body.body.key == foo.key
|
||||
assert res.body.body == ("id", foo.id)
|
||||
|
||||
def test_i_cannot_modify_a_concept_that_returns_an_error(self):
|
||||
sheerka, context = self.init_concepts()
|
||||
|
||||
foo = Concept("foo").init_key()
|
||||
res = sheerka.modify_concept(context, foo)
|
||||
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.ERROR)
|
||||
|
||||
def test_i_cannot_modify_if_the_concept_has_not_changed(self):
|
||||
sheerka, context, foo = self.init_concepts("foo", create_new=True)
|
||||
res = sheerka.modify_concept(context, foo)
|
||||
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.CONCEPT_ALREADY_DEFINED)
|
||||
|
||||
def test_i_can_modify_a_concept_that_is_in_a_list(self):
|
||||
sheerka, context, foo1, foo2 = self.init_concepts(
|
||||
@@ -105,7 +88,19 @@ class TestSheerkaModifyConcept(TestUsingMemoryBasedSheerka):
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.NEW_CONCEPT)
|
||||
assert res.body.body.metadata.body == "value"
|
||||
|
||||
sheerka.reset_cache()
|
||||
foo_from_sheerka = sheerka.new("foo")
|
||||
assert foo_from_sheerka[0].metadata.body == "1"
|
||||
assert foo_from_sheerka[1].metadata.body == "value"
|
||||
|
||||
|
||||
class TestSheerkaModifyConceptUsingFile(TestUsingFileBasedSheerka):
|
||||
|
||||
def test_i_can_modify_a_concept_from_a_new_sheerka(self):
|
||||
sheerka, context, foo = self.init_concepts("foo", create_new=True)
|
||||
sheerka.cache_manager.commit(context)
|
||||
|
||||
sheerka = self.get_sheerka()
|
||||
foo.add_prop("a", "b")
|
||||
res = sheerka.modify_concept(context, foo)
|
||||
|
||||
assert res.status
|
||||
|
||||
@@ -1,79 +1,65 @@
|
||||
from core.builtin_concepts import ConceptAlreadyInSet, BuiltinConcepts
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
|
||||
from tests.TestUsingFileBasedSheerka import TestUsingFileBasedSheerka
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
class TestSheerkaSetsManager(TestUsingFileBasedSheerka):
|
||||
class TestSheerkaSetsManager(TestUsingMemoryBasedSheerka):
|
||||
|
||||
# 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_a_concept_to_a_set(self):
|
||||
sheerka, context, foo, group = self.init_concepts(
|
||||
Concept("foo"),
|
||||
Concept("group"),
|
||||
cache_only=False
|
||||
)
|
||||
assert sheerka.add_concept_to_set(context, foo, group).status
|
||||
|
||||
def test_i_can_add_concept_to_set(self):
|
||||
sheerka, context, foo, all_foos = self.init_concepts(Concept("foo"), Concept("all_foo"), use_dict=False)
|
||||
group_elements = sheerka.cache_manager.get(sheerka.CONCEPTS_GROUPS_ENTRY, group.id)
|
||||
assert group_elements == {foo.id}
|
||||
|
||||
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(use_dict=False).sdp.get("All_" + all_foos.id, None, False)
|
||||
assert len(all_entries) == 1
|
||||
assert foo.id in all_entries
|
||||
|
||||
def test_i_can_add_several_concepts_to_set(self):
|
||||
sheerka, context, foo1, foo2, all_foos = self.init_concepts(
|
||||
Concept("foo1"),
|
||||
Concept("foo2"),
|
||||
Concept("all_foo"), use_dict=False)
|
||||
|
||||
res = sheerka.sets_handler.add_concepts_to_set(context, (foo1, foo2), all_foos)
|
||||
|
||||
assert res.status
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.SUCCESS)
|
||||
|
||||
all_entries = self.get_sheerka(use_dict=False).sdp.get("All_" + all_foos.id, None, False)
|
||||
assert len(all_entries) == 2
|
||||
assert foo1.id in all_entries
|
||||
assert foo2.id in all_entries
|
||||
|
||||
# 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(use_dict=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
|
||||
# it can be persisted
|
||||
sheerka.cache_manager.commit(context)
|
||||
assert sheerka.sdp.get(sheerka.CONCEPTS_GROUPS_ENTRY, group.id) == {foo.id}
|
||||
|
||||
def test_i_cannot_add_the_same_concept_twice_in_a_set(self):
|
||||
sheerka, context, foo, all_foos = self.init_concepts(Concept("foo"), Concept("all_foos"))
|
||||
sheerka, context, foo, group = self.init_concepts(Concept("foo"), Concept("group"))
|
||||
sheerka.add_concept_to_set(context, foo, group)
|
||||
|
||||
sheerka.add_concept_to_set(context, foo, all_foos)
|
||||
res = sheerka.add_concept_to_set(context, foo, all_foos)
|
||||
# add again
|
||||
res = sheerka.add_concept_to_set(context, foo, group)
|
||||
|
||||
assert not res.status
|
||||
assert res.body == ConceptAlreadyInSet(foo, all_foos)
|
||||
assert sheerka.isinstance(res.body, BuiltinConcepts.CONCEPT_ALREADY_IN_SET)
|
||||
assert res.body.body == foo
|
||||
assert res.body.concept_set == group
|
||||
|
||||
all_entries = sheerka.sdp.get("All_" + all_foos.id, None, False)
|
||||
assert len(all_entries) == 1
|
||||
assert foo.id in all_entries
|
||||
all_entries = sheerka.cache_manager.get(sheerka.CONCEPTS_GROUPS_ENTRY, group.id)
|
||||
assert all_entries == {foo.id}
|
||||
|
||||
def test_i_can_have_multiple_groups(self):
|
||||
sheerka, context, foo, bar, baz, group1, group2 = self.init_concepts(
|
||||
Concept("foo"),
|
||||
Concept("bar"),
|
||||
Concept("baz"),
|
||||
Concept("group1"),
|
||||
Concept("group2"),
|
||||
cache_only=False
|
||||
)
|
||||
|
||||
assert sheerka.add_concept_to_set(context, foo, group1).status
|
||||
assert sheerka.add_concept_to_set(context, bar, group1).status
|
||||
assert sheerka.add_concept_to_set(context, bar, group2).status
|
||||
assert sheerka.add_concept_to_set(context, baz, group2).status
|
||||
|
||||
assert sheerka.cache_manager.get(sheerka.CONCEPTS_GROUPS_ENTRY, group1.id) == {foo.id, bar.id}
|
||||
assert sheerka.cache_manager.get(sheerka.CONCEPTS_GROUPS_ENTRY, group2.id) == {baz.id, bar.id}
|
||||
|
||||
# I can save in db
|
||||
sheerka.cache_manager.commit(context)
|
||||
assert sheerka.sdp.get(sheerka.CONCEPTS_GROUPS_ENTRY) == {
|
||||
'1004': {'1001', '1002'}, '1005': {'1002', '1003'}
|
||||
}
|
||||
|
||||
def test_i_get_elements_from_a_set(self):
|
||||
sheerka, context, one, two, three, number = self.init_concepts(
|
||||
@@ -83,7 +69,6 @@ class TestSheerkaSetsManager(TestUsingFileBasedSheerka):
|
||||
sheerka.add_concept_to_set(context, c, number)
|
||||
|
||||
elements = sheerka.get_set_elements(context, number)
|
||||
|
||||
assert set(elements) == {one, two, three}
|
||||
|
||||
def test_i_cannot_get_elements_if_not_a_set(self):
|
||||
@@ -100,8 +85,9 @@ class TestSheerkaSetsManager(TestUsingFileBasedSheerka):
|
||||
assert not sheerka.isaset(context, group)
|
||||
assert not sheerka.isinset(foo, group)
|
||||
|
||||
context = self.get_context(sheerka)
|
||||
context = self.get_context(sheerka) # another context ?
|
||||
sheerka.add_concept_to_set(context, foo, group)
|
||||
|
||||
assert sheerka.isaset(context, group)
|
||||
assert sheerka.isinset(foo, group)
|
||||
|
||||
@@ -112,7 +98,7 @@ class TestSheerkaSetsManager(TestUsingFileBasedSheerka):
|
||||
sheerka.sets_handler.add_concepts_to_set(context, [foo, bar], group1)
|
||||
|
||||
assert sheerka.isaset(context, group2)
|
||||
assert sheerka.get_set_elements(context, group2) == [foo, bar]
|
||||
assert set(sheerka.get_set_elements(context, group2)) == {foo, bar}
|
||||
|
||||
def test_i_can_define_subset_of_another_group(self):
|
||||
sheerka, context, one, two, three, four, five, number, sub_number = self.init_concepts(
|
||||
@@ -122,15 +108,30 @@ class TestSheerkaSetsManager(TestUsingFileBasedSheerka):
|
||||
Concept("four", body="4"),
|
||||
Concept("five", body="5"),
|
||||
Concept("number"),
|
||||
Concept("sub_number", body="number", where="number < 4"),
|
||||
create_new=True
|
||||
Concept("sub_number", body="number", where="number < 4")
|
||||
)
|
||||
sheerka.sets_handler.add_concepts_to_set(context, [one, two, three, four, five], number)
|
||||
|
||||
assert sheerka.isaset(context, sub_number)
|
||||
assert sheerka.get_set_elements(context, sub_number) == [one, two, three]
|
||||
assert set(sheerka.get_set_elements(context, sub_number)) == {one, two, three}
|
||||
|
||||
def test_i_can_define_subset_of_another_set_when_some_concept_dont_have_a_defined_body(self):
|
||||
def test_i_can_define_subset_of_subset(self):
|
||||
sheerka, context, one, two, three, four, five, number, sub_number, sub_sub_number = self.init_concepts(
|
||||
Concept("one", body="1"),
|
||||
Concept("two", body="2"),
|
||||
Concept("three", body="3"),
|
||||
Concept("four", body="4"),
|
||||
Concept("five", body="5"),
|
||||
Concept("number"),
|
||||
Concept("sub_number", body="number", where="number < 4"),
|
||||
Concept("sub_sub_number", body="sub_number", where="sub_number > 2")
|
||||
)
|
||||
sheerka.sets_handler.add_concepts_to_set(context, [one, two, three, four, five], number)
|
||||
|
||||
assert sheerka.isaset(context, sub_sub_number)
|
||||
assert set(sheerka.get_set_elements(context, sub_sub_number)) == {three}
|
||||
|
||||
def test_i_can_define_subset_of_another_set_when_some_concept_do_not_have_a_defined_body(self):
|
||||
"""
|
||||
Example
|
||||
def concept unit from number where number <10
|
||||
@@ -151,7 +152,7 @@ class TestSheerkaSetsManager(TestUsingFileBasedSheerka):
|
||||
sheerka.sets_handler.add_concepts_to_set(context, [one, two, three, four, five], number)
|
||||
|
||||
assert sheerka.isaset(context, sub_number)
|
||||
assert sheerka.get_set_elements(context, sub_number) == [one, three]
|
||||
assert set(sheerka.get_set_elements(context, sub_number)) == {one, three}
|
||||
|
||||
def test_i_can_define_subset_of_another_set_when_some_concept_are_bnf(self):
|
||||
"""
|
||||
@@ -190,8 +191,9 @@ class TestSheerkaSetsManager(TestUsingFileBasedSheerka):
|
||||
Concept("one", body="1"),
|
||||
Concept("two", body="2"),
|
||||
Concept("twenty", body="20"),
|
||||
Concept("twenties", definition="twenty (one|two)=unit", body="twenty + unit").def_prop("unit"),
|
||||
Concept("twenties", definition="twenty (one|two)=unit", body="twenty + unit").def_var("unit"),
|
||||
Concept("number"),
|
||||
create_new=True
|
||||
)
|
||||
|
||||
sheerka.sets_handler.add_concepts_to_set(context, [one, two, twenty, twenties], number)
|
||||
@@ -200,39 +202,27 @@ class TestSheerkaSetsManager(TestUsingFileBasedSheerka):
|
||||
twenty_one = sheerka.evaluate_user_input("twenty one", "")[0].body
|
||||
assert sheerka.isinset(twenty_one, number)
|
||||
|
||||
def test_i_can_set_isa(self):
|
||||
sheerka, context, foo, all_foos = self.init_concepts(
|
||||
"foo", "all_foo",
|
||||
create_new=True,
|
||||
use_dict=False)
|
||||
|
||||
assert BuiltinConcepts.ISA not in foo.props
|
||||
|
||||
sheerka.set_isa(context, foo, all_foos)
|
||||
|
||||
assert foo.get_prop(BuiltinConcepts.ISA) == [all_foos]
|
||||
assert sheerka.isa(foo, all_foos)
|
||||
assert sheerka.isinset(foo, all_foos)
|
||||
assert sheerka.isaset(context, all_foos)
|
||||
|
||||
def test_a_concept_can_be_in_multiple_sets(self):
|
||||
sheerka, context, foo, all_foos, all_bars = self.init_concepts(
|
||||
sheerka, context, foo, all_foo, all_bar = self.init_concepts(
|
||||
Concept("foo"),
|
||||
Concept("all_foo"),
|
||||
Concept("all_bar"),
|
||||
use_dict=False)
|
||||
sheerka.create_new_concept(context, foo)
|
||||
create_new=True
|
||||
)
|
||||
|
||||
sheerka.set_isa(context, foo, all_foos)
|
||||
sheerka.set_isa(context, foo, all_bars)
|
||||
foo = sheerka.new(foo.key) # new instance
|
||||
sheerka.set_isa(context, foo, all_foo)
|
||||
|
||||
assert foo.get_prop(BuiltinConcepts.ISA) == [all_foos, all_bars]
|
||||
assert sheerka.isa(foo, all_foos)
|
||||
assert sheerka.isa(foo, all_bars)
|
||||
assert sheerka.isinset(foo, all_foos)
|
||||
assert sheerka.isinset(foo, all_bars)
|
||||
assert sheerka.isaset(context, all_foos)
|
||||
assert sheerka.isaset(context, all_bars)
|
||||
foo = sheerka.new(foo.key) # new instance
|
||||
sheerka.set_isa(context, foo, all_bar)
|
||||
|
||||
assert foo.get_prop(BuiltinConcepts.ISA) == {all_foo, all_bar}
|
||||
assert sheerka.isa(foo, all_foo)
|
||||
assert sheerka.isa(foo, all_bar)
|
||||
assert sheerka.isinset(foo, all_foo)
|
||||
assert sheerka.isinset(foo, all_bar)
|
||||
assert sheerka.isaset(context, all_foo)
|
||||
assert sheerka.isaset(context, all_bar)
|
||||
|
||||
def test_i_can_manage_isa_transitivity(self):
|
||||
"""
|
||||
@@ -244,10 +234,9 @@ class TestSheerkaSetsManager(TestUsingFileBasedSheerka):
|
||||
Concept("foo"),
|
||||
Concept("bar"),
|
||||
Concept("baz"),
|
||||
create_new=True
|
||||
|
||||
)
|
||||
sheerka.create_new_concept(context, foo)
|
||||
sheerka.create_new_concept(context, bar)
|
||||
sheerka.create_new_concept(context, baz)
|
||||
|
||||
sheerka.set_isa(context, foo, bar)
|
||||
sheerka.set_isa(context, bar, baz)
|
||||
@@ -255,3 +244,88 @@ class TestSheerkaSetsManager(TestUsingFileBasedSheerka):
|
||||
assert sheerka.isa(foo, bar)
|
||||
assert sheerka.isa(bar, baz)
|
||||
assert sheerka.isa(foo, baz)
|
||||
|
||||
|
||||
class TestSheerkaSetsManagerUsingFileBasedSheerka(TestUsingFileBasedSheerka):
|
||||
def test_i_can_add_concept_to_set_and_retrieve_it_in_another_session(self):
|
||||
sheerka, context, foo, bar, group = self.init_concepts(
|
||||
Concept("foo"),
|
||||
Concept("bar"),
|
||||
Concept("group"),
|
||||
create_new=True)
|
||||
|
||||
assert sheerka.add_concept_to_set(context, foo, group).status
|
||||
sheerka.cache_manager.commit(context)
|
||||
|
||||
sheerka = self.get_sheerka() # another session
|
||||
assert sheerka.add_concept_to_set(context, bar, group).status
|
||||
|
||||
# I can get the elements
|
||||
assert set(sheerka.get_set_elements(context, group)) == {foo, bar}
|
||||
|
||||
sheerka.cache_manager.commit(context) # save in db
|
||||
all_entries = sheerka.sdp.get(sheerka.CONCEPTS_GROUPS_ENTRY) # check the db
|
||||
assert all_entries == {
|
||||
group.id: {foo.id, bar.id}
|
||||
}
|
||||
|
||||
# I can also add a group another elements
|
||||
sheerka = self.get_sheerka()
|
||||
foo3 = Concept("foo3")
|
||||
foo4 = Concept("foo4")
|
||||
for c in [foo3, foo4]:
|
||||
sheerka.create_new_concept(context, c)
|
||||
|
||||
res = sheerka.sets_handler.add_concepts_to_set(context, (foo3, foo4), group)
|
||||
assert res.status
|
||||
|
||||
# I can get the elements
|
||||
assert set(sheerka.get_set_elements(context, group)) == {foo, bar, foo3, foo4}
|
||||
|
||||
sheerka.cache_manager.commit(context) # save in db
|
||||
all_entries = sheerka.sdp.get(sheerka.CONCEPTS_GROUPS_ENTRY) # check the db
|
||||
assert all_entries == {
|
||||
group.id: {foo.id, bar.id, foo3.id, foo4.id}
|
||||
}
|
||||
|
||||
def test_i_can_set_isa(self):
|
||||
sheerka, context, foo, bar, group = self.init_concepts(
|
||||
"foo",
|
||||
"bar",
|
||||
"group",
|
||||
create_new=True, # needed by modify
|
||||
)
|
||||
|
||||
# nothing was previously in ISA
|
||||
foo = sheerka.new(foo.key)
|
||||
assert BuiltinConcepts.ISA not in foo.metadata.props
|
||||
res = sheerka.set_isa(context, foo, group)
|
||||
assert res.status
|
||||
sheerka.cache_manager.commit(context)
|
||||
|
||||
sheerka = self.get_sheerka()
|
||||
assert foo.get_prop(BuiltinConcepts.ISA) == {group}
|
||||
assert sheerka.isa(foo, group)
|
||||
assert sheerka.isinset(foo, group)
|
||||
assert sheerka.isaset(context, group)
|
||||
|
||||
# I can do the same for bar
|
||||
sheerka = self.get_sheerka()
|
||||
res = sheerka.set_isa(context, bar, group)
|
||||
assert res.status
|
||||
assert bar.get_prop(BuiltinConcepts.ISA) == {group}
|
||||
assert sheerka.isa(bar, group)
|
||||
assert sheerka.isinset(bar, group)
|
||||
assert sheerka.isaset(context, group)
|
||||
|
||||
sheerka.cache_manager.commit(context)
|
||||
|
||||
# they are both in the same group
|
||||
sheerka = self.get_sheerka()
|
||||
all_entries = sheerka.sdp.get(sheerka.CONCEPTS_GROUPS_ENTRY)
|
||||
assert all_entries == {
|
||||
group.id: {foo.id, bar.id}
|
||||
}
|
||||
|
||||
elements = sheerka.get_set_elements(context, group)
|
||||
assert set(elements) == {foo, bar}
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
from core.concept import Concept, ConceptParts
|
||||
from core.sheerka.Services.SheerkaVariableManager import SheerkaVariableManager
|
||||
from core.sheerka.Sheerka import Sheerka
|
||||
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
class TestSheerkaVariable(TestUsingMemoryBasedSheerka):
|
||||
def test_i_can_record_and_load_a_constant(self):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka = self.get_sheerka(cache_only=False)
|
||||
context = self.get_context(sheerka)
|
||||
|
||||
sheerka.record(context, "TestSheerkaVariable", "my_variable", 1)
|
||||
res = sheerka.load("TestSheerkaVariable", "my_variable")
|
||||
assert res == 1
|
||||
|
||||
assert sheerka.sdp.exists(SheerkaVariableManager.VARIABLES_ENTRY, "TestSheerkaVariable.my_variable")
|
||||
loaded = sheerka.sdp.get(SheerkaVariableManager.VARIABLES_ENTRY, "TestSheerkaVariable.my_variable")
|
||||
# I can persist in db
|
||||
sheerka.cache_manager.commit(context)
|
||||
|
||||
assert sheerka.sdp.exists(Sheerka.VARIABLES_ENTRY, "TestSheerkaVariable.my_variable")
|
||||
loaded = sheerka.sdp.get(Sheerka.VARIABLES_ENTRY, "TestSheerkaVariable.my_variable")
|
||||
assert loaded.event_id == context.event.get_digest()
|
||||
assert loaded.key == "my_variable"
|
||||
assert loaded.value == 1
|
||||
@@ -25,47 +28,60 @@ class TestSheerkaVariable(TestUsingMemoryBasedSheerka):
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
|
||||
concept = Concept("foo").set_prop("a", "alpha").set_metadata_value(ConceptParts.BODY, 3.14)
|
||||
concept = Concept("foo").set_value("a", "alpha").set_value(ConceptParts.BODY, 3.14)
|
||||
|
||||
sheerka.record(context, "TestSheerkaVariable", "my_variable", concept)
|
||||
res = sheerka.load("TestSheerkaVariable", "my_variable")
|
||||
|
||||
assert res == concept
|
||||
assert res.body == concept.body
|
||||
assert res.a == concept.a
|
||||
|
||||
def test_i_can_get_the_parent_when_modified(self):
|
||||
def test_i_can_delete_an_entry(self):
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
|
||||
sheerka.record(context, "TestSheerkaVariable", "my_variable", 1)
|
||||
sheerka.record(context, "TestSheerkaVariable", "my_variable", 2)
|
||||
res = sheerka.load("TestSheerkaVariable", "my_variable")
|
||||
assert res == 2
|
||||
concept = Concept("foo")
|
||||
|
||||
loaded = sheerka.sdp.get(SheerkaVariableManager.VARIABLES_ENTRY, "TestSheerkaVariable.my_variable")
|
||||
assert loaded.event_id == context.event.get_digest()
|
||||
assert loaded.key == "my_variable"
|
||||
assert loaded.value == 2
|
||||
assert loaded.who == "TestSheerkaVariable"
|
||||
assert loaded.parents == ['8c9ada7bf488d84229f6539f76042431638f16d600fe3b7ec7e7161043a40d59']
|
||||
sheerka.record(context, "TestSheerkaVariable", "my_variable", concept)
|
||||
assert sheerka.load("TestSheerkaVariable", "my_variable") is not None
|
||||
|
||||
parent = sheerka.sdp.load_obj(loaded.parents[0])
|
||||
assert parent.event_id == context.event.get_digest()
|
||||
assert parent.key == "my_variable"
|
||||
assert parent.value == 1
|
||||
assert parent.who == "TestSheerkaVariable"
|
||||
assert parent.parents is None
|
||||
sheerka.delete(context, "TestSheerkaVariable", "my_variable")
|
||||
assert sheerka.load("TestSheerkaVariable", "my_variable") is None
|
||||
|
||||
def test_variable_is_not_persisted_if_the_value_is_the_same(self):
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
# def test_i_can_get_the_parent_when_modified(self):
|
||||
# sheerka = self.get_sheerka()
|
||||
# context = self.get_context(sheerka)
|
||||
#
|
||||
# sheerka.record(context, "TestSheerkaVariable", "my_variable", 1)
|
||||
# sheerka.record(context, "TestSheerkaVariable", "my_variable", 2)
|
||||
# res = sheerka.load("TestSheerkaVariable", "my_variable")
|
||||
# assert res == 2
|
||||
#
|
||||
# loaded = sheerka.sdp.get(Sheerka.VARIABLES_ENTRY, "TestSheerkaVariable.my_variable")
|
||||
# assert loaded.event_id == context.event.get_digest()
|
||||
# assert loaded.key == "my_variable"
|
||||
# assert loaded.value == 2
|
||||
# assert loaded.who == "TestSheerkaVariable"
|
||||
# assert loaded.parents == ['8c9ada7bf488d84229f6539f76042431638f16d600fe3b7ec7e7161043a40d59']
|
||||
#
|
||||
# parent = sheerka.sdp.load_obj(loaded.parents[0])
|
||||
# assert parent.event_id == context.event.get_digest()
|
||||
# assert parent.key == "my_variable"
|
||||
# assert parent.value == 1
|
||||
# assert parent.who == "TestSheerkaVariable"
|
||||
# assert parent.parents is None
|
||||
|
||||
sheerka.record(context, "TestSheerkaVariable", "my_variable", 1)
|
||||
sheerka.record(context, "TestSheerkaVariable", "my_variable", 1)
|
||||
|
||||
loaded = sheerka.sdp.get(SheerkaVariableManager.VARIABLES_ENTRY, "TestSheerkaVariable.my_variable")
|
||||
assert loaded.event_id == context.event.get_digest()
|
||||
assert loaded.key == "my_variable"
|
||||
assert loaded.value == 1
|
||||
assert loaded.who == "TestSheerkaVariable"
|
||||
assert loaded.parents is None
|
||||
# def test_variable_is_not_persisted_if_the_value_is_the_same(self):
|
||||
# sheerka = self.get_sheerka(singleton=True)
|
||||
# context = self.get_context(sheerka)
|
||||
#
|
||||
# sheerka.record(context, "TestSheerkaVariable", "my_variable", 1)
|
||||
# sheerka.record(context, "TestSheerkaVariable", "my_variable", 1)
|
||||
#
|
||||
# loaded = sheerka.sdp.get(Sheerka.VARIABLES_ENTRY, "TestSheerkaVariable.my_variable")
|
||||
# assert loaded.event_id == context.event.get_digest()
|
||||
# assert loaded.key == "my_variable"
|
||||
# assert loaded.value == 1
|
||||
# assert loaded.who == "TestSheerkaVariable"
|
||||
# assert loaded.parents is None
|
||||
|
||||
+18
-19
@@ -1,16 +1,15 @@
|
||||
import ast
|
||||
|
||||
import pytest
|
||||
|
||||
from core.ast.nodes import NodeParent, GenericNodeConcept
|
||||
import core.ast.nodes
|
||||
import pytest
|
||||
from core.ast.nodes import NodeParent, GenericNodeConcept
|
||||
from core.ast.visitors import ConceptNodeVisitor, UnreferencedNamesVisitor
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.sheerka.Sheerka import Sheerka
|
||||
|
||||
|
||||
def get_sheerka():
|
||||
sheerka = Sheerka(skip_builtins_in_db=True)
|
||||
sheerka = Sheerka(cache_only=True)
|
||||
sheerka.initialize("mem://")
|
||||
|
||||
return sheerka
|
||||
@@ -40,32 +39,32 @@ def my_function(a,b):
|
||||
sheerka = get_sheerka()
|
||||
|
||||
assert tree_as_concept.node_type == "Module"
|
||||
assert sheerka.isinstance(tree_as_concept.get_prop("body"), BuiltinConcepts.LIST)
|
||||
assert sheerka.isinstance(tree_as_concept.get_value("body"), BuiltinConcepts.LIST)
|
||||
|
||||
def_func = tree_as_concept.get_prop("body").body[0]
|
||||
def_func = tree_as_concept.get_value("body").body[0]
|
||||
assert sheerka.isinstance(def_func, BuiltinConcepts.GENERIC_NODE)
|
||||
assert def_func.node_type == "FunctionDef"
|
||||
assert def_func.parent == NodeParent(tree_as_concept, "body")
|
||||
assert def_func.get_prop("name") == "my_function"
|
||||
assert def_func.get_value("name") == "my_function"
|
||||
|
||||
def_func_args = def_func.get_prop("args")
|
||||
def_func_args = def_func.get_value("args")
|
||||
assert sheerka.isinstance(def_func_args, BuiltinConcepts.GENERIC_NODE)
|
||||
assert def_func_args.node_type == "arguments"
|
||||
|
||||
def_func_args_real_args = def_func_args.get_prop("args")
|
||||
def_func_args_real_args = def_func_args.get_value("args")
|
||||
assert sheerka.isinstance(def_func_args_real_args, BuiltinConcepts.LIST)
|
||||
assert len(def_func_args_real_args.body) == 2
|
||||
|
||||
assert sheerka.isinstance(def_func_args_real_args.body[0], BuiltinConcepts.GENERIC_NODE)
|
||||
assert def_func_args_real_args.body[0].node_type == "arg"
|
||||
assert def_func_args_real_args.body[0].parent == NodeParent(def_func_args, "args")
|
||||
assert def_func_args_real_args.body[0].get_prop("arg") == "a"
|
||||
assert def_func_args_real_args.body[0].get_value("arg") == "a"
|
||||
assert sheerka.isinstance(def_func_args_real_args.body[1], BuiltinConcepts.GENERIC_NODE)
|
||||
assert def_func_args_real_args.body[1].node_type == "arg"
|
||||
assert def_func_args_real_args.body[1].parent == NodeParent(def_func_args, "args")
|
||||
assert def_func_args_real_args.body[1].get_prop("arg") == "b"
|
||||
assert def_func_args_real_args.body[1].get_value("arg") == "b"
|
||||
|
||||
def_fun_body = def_func.get_prop("body")
|
||||
def_fun_body = def_func.get_value("body")
|
||||
assert sheerka.isinstance(def_fun_body, BuiltinConcepts.LIST)
|
||||
assert len(def_fun_body.body) == 2
|
||||
|
||||
@@ -95,13 +94,13 @@ def my_function(a,b):
|
||||
visitor.visit(concept_node)
|
||||
|
||||
sheerka = get_sheerka()
|
||||
assert sheerka.value(visitor.names[0]) == "i"
|
||||
assert sheerka.value(visitor.names[1]) == "range"
|
||||
assert sheerka.value(visitor.names[2]) == "b"
|
||||
assert sheerka.value(visitor.names[3]) == "a"
|
||||
assert sheerka.value(visitor.names[4]) == "a"
|
||||
assert sheerka.value(visitor.names[5]) == "b"
|
||||
assert sheerka.value(visitor.names[6]) == "a"
|
||||
assert sheerka.objvalue(visitor.names[0]) == "i"
|
||||
assert sheerka.objvalue(visitor.names[1]) == "range"
|
||||
assert sheerka.objvalue(visitor.names[2]) == "b"
|
||||
assert sheerka.objvalue(visitor.names[3]) == "a"
|
||||
assert sheerka.objvalue(visitor.names[4]) == "a"
|
||||
assert sheerka.objvalue(visitor.names[5]) == "b"
|
||||
assert sheerka.objvalue(visitor.names[6]) == "a"
|
||||
|
||||
|
||||
def test_i_can_get_unreferenced_variables():
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import ast
|
||||
import pytest
|
||||
import core.builtin_helpers
|
||||
|
||||
import core.builtin_helpers
|
||||
import pytest
|
||||
from core.builtin_concepts import ReturnValueConcept, BuiltinConcepts
|
||||
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
+47
-24
@@ -3,7 +3,7 @@ import pytest
|
||||
from core.concept import Concept, ConceptParts, DEFINITION_TYPE_DEF
|
||||
|
||||
|
||||
@pytest.mark.parametrize("name, properties, expected", [
|
||||
@pytest.mark.parametrize("name, variables, expected", [
|
||||
("foo", [], "foo"),
|
||||
("foo(bar)", [], "foo ( bar )"),
|
||||
("foo a", ["a"], "foo __var__0"),
|
||||
@@ -20,21 +20,20 @@ from core.concept import Concept, ConceptParts, DEFINITION_TYPE_DEF
|
||||
("a b a c", ["a", "b"], "__var__0 __var__1 __var__0 c"),
|
||||
("a b a c", ["b", "a"], "__var__1 __var__0 __var__1 c"),
|
||||
])
|
||||
def test_i_can_compute_the_key(name, properties, expected):
|
||||
def test_i_can_compute_the_key(name, variables, expected):
|
||||
concept = Concept(name)
|
||||
for prop in properties:
|
||||
concept.metadata.props.append((prop, None))
|
||||
for var_name in variables:
|
||||
concept.metadata.variables.append((var_name, None))
|
||||
concept.init_key()
|
||||
|
||||
assert concept.key == expected
|
||||
|
||||
|
||||
def test_i_can_compute_the_key_when_from_definition():
|
||||
|
||||
# if definition is not defined, use the name
|
||||
concept = Concept()
|
||||
concept.metadata.name = "hello a"
|
||||
concept.metadata.props = [("a", None)]
|
||||
concept.metadata.variables = [("a", None)]
|
||||
concept.init_key()
|
||||
assert concept.key == "hello __var__0"
|
||||
|
||||
@@ -43,13 +42,13 @@ def test_i_can_compute_the_key_when_from_definition():
|
||||
concept.metadata.name = "greetings"
|
||||
concept.metadata.definition = "hello a"
|
||||
concept.metadata.definition_type = DEFINITION_TYPE_DEF
|
||||
concept.metadata.props = [("a", None)]
|
||||
concept.metadata.variables = [("a", None)]
|
||||
concept.init_key()
|
||||
assert concept.key == "hello __var__0"
|
||||
|
||||
|
||||
def test_key_does_not_use_variable_when_definition_is_set():
|
||||
concept = Concept("plus").def_prop('plus')
|
||||
concept = Concept("plus").def_var('plus')
|
||||
|
||||
concept.init_key()
|
||||
assert concept.metadata.key == "plus"
|
||||
@@ -73,7 +72,7 @@ def test_i_can_serialize():
|
||||
definition_type="def type",
|
||||
desc="this this the desc",
|
||||
id="123456"
|
||||
).def_prop("a", "10").def_prop("b", None)
|
||||
).def_var("a", "10").def_var("b", None)
|
||||
|
||||
to_dict = concept.to_dict()
|
||||
assert to_dict == {
|
||||
@@ -88,7 +87,8 @@ def test_i_can_serialize():
|
||||
'name': 'concept_name',
|
||||
'post': 'definition of the post',
|
||||
'pre': 'definition of the pre',
|
||||
'props': [('a', "10"), ('b', None)],
|
||||
'props': {},
|
||||
'variables': [('a', "10"), ('b', None)],
|
||||
'where': 'definition of the where'
|
||||
}
|
||||
|
||||
@@ -111,7 +111,8 @@ def test_i_can_deserialize():
|
||||
'name': 'concept_name',
|
||||
'post': 'definition of the post',
|
||||
'pre': 'definition of the pre',
|
||||
'props': [('a', "10"), ('b', None)],
|
||||
'props': {},
|
||||
'variables': [('a', "10"), ('b', None)],
|
||||
'where': 'definition of the where'
|
||||
}
|
||||
|
||||
@@ -130,16 +131,16 @@ def test_i_can_deserialize():
|
||||
definition_type="def type",
|
||||
desc="this this the desc",
|
||||
id="123456"
|
||||
).def_prop("a", "10").def_prop("b", None)
|
||||
).def_var("a", "10").def_var("b", None)
|
||||
|
||||
|
||||
def test_i_can_deserialize_props_coming_from_sdp():
|
||||
def test_i_can_deserialize_variables_coming_from_sdp():
|
||||
from_dict = {
|
||||
'props': [['a', "10"], ['b', None]], # JSON transform set into list
|
||||
'variables': [['a', "10"], ['b', None]], # JSON transform set into list
|
||||
}
|
||||
|
||||
concept = Concept().from_dict(from_dict)
|
||||
assert concept == Concept().def_prop("a", "10").def_prop("b", None)
|
||||
assert concept == Concept().def_var("a", "10").def_var("b", None)
|
||||
|
||||
|
||||
def test_i_can_compare_concepts():
|
||||
@@ -156,7 +157,7 @@ def test_i_can_compare_concepts():
|
||||
definition_type="def type",
|
||||
desc="this this the desc",
|
||||
id="123456"
|
||||
).def_prop("a", "10").def_prop("b", None)
|
||||
).def_var("a", "10").def_var("b", None).add_prop("prop", "prop_val")
|
||||
|
||||
concept_b = Concept(
|
||||
name="concept_name",
|
||||
@@ -171,11 +172,33 @@ def test_i_can_compare_concepts():
|
||||
definition_type="def type",
|
||||
desc="this this the desc",
|
||||
id="123456"
|
||||
).def_prop("a", "10").def_prop("b", None)
|
||||
).def_var("a", "10").def_var("b", None).add_prop("prop", "prop_val")
|
||||
|
||||
assert concept_a == concept_b
|
||||
|
||||
|
||||
def test_i_can_detect_concept_differences():
|
||||
assert Concept(name="concept_name") != Concept()
|
||||
assert Concept(is_builtin=True) != Concept()
|
||||
assert Concept(is_unique=True) != Concept()
|
||||
assert Concept(key="concept_key") != Concept()
|
||||
assert Concept(body="concept_body") != Concept()
|
||||
assert Concept(where="concept_where") != Concept()
|
||||
assert Concept(pre="concept_pre") != Concept()
|
||||
assert Concept(post="concept_post") != Concept()
|
||||
assert Concept(definition="def") != Concept()
|
||||
assert Concept(definition_type="def type") != Concept()
|
||||
assert Concept(desc="desc") != Concept()
|
||||
assert Concept(id="concept_id") != Concept()
|
||||
assert Concept().def_var("a") != Concept()
|
||||
assert Concept().add_prop("a", "b") != Concept()
|
||||
assert Concept().set_value("a", "b") != Concept()
|
||||
|
||||
concept = Concept()
|
||||
concept.compiled["foo"] = "value"
|
||||
assert concept == Concept() # compiled is not used in the comparison
|
||||
|
||||
|
||||
def test_i_can_compare_concept_with_circular_reference():
|
||||
foo = Concept("foo")
|
||||
foo.metadata.body = foo
|
||||
@@ -215,17 +238,17 @@ def test_i_can_update_from():
|
||||
definition_type="def type",
|
||||
desc="this this the desc",
|
||||
id="123456"
|
||||
).def_prop("a", "10").def_prop("b", None)
|
||||
).def_var("a", "10").def_var("b", None)
|
||||
|
||||
# make sure origin is preserved
|
||||
setattr(template, "##origin##", "digest")
|
||||
|
||||
template.values[ConceptParts.BODY] = "value in body"
|
||||
template.values[ConceptParts.WHERE] = "value in where"
|
||||
template.values[ConceptParts.PRE] = "value in pre"
|
||||
template.values[ConceptParts.POST] = "value in post"
|
||||
template.set_prop("a", 10)
|
||||
template.set_prop("b", 20)
|
||||
template.set_value(ConceptParts.BODY, "value in body")
|
||||
template.set_value(ConceptParts.WHERE, "value in where")
|
||||
template.set_value(ConceptParts.PRE, "value in pre")
|
||||
template.set_value(ConceptParts.POST, "value in post")
|
||||
template.set_value("a", 10)
|
||||
template.set_value("b", 20)
|
||||
|
||||
concept = Concept().update_from(template)
|
||||
|
||||
|
||||
+218
-103
@@ -1,24 +1,33 @@
|
||||
import pytest
|
||||
import os
|
||||
|
||||
import pytest
|
||||
from core.builtin_concepts import BuiltinConcepts, ReturnValueConcept, UserInputConcept
|
||||
from core.concept import Concept, PROPERTIES_TO_SERIALIZE
|
||||
from core.sheerka.Sheerka import Sheerka
|
||||
from core.concept import Concept, PROPERTIES_TO_SERIALIZE, ConceptParts
|
||||
from core.sheerka.Sheerka import Sheerka, BASE_NODE_PARSER_CLASS
|
||||
|
||||
from tests.TestUsingFileBasedSheerka import TestUsingFileBasedSheerka
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
class ConceptWithGetValue(Concept):
|
||||
def get_value(self):
|
||||
return self.get_prop("my_prop")
|
||||
class ConceptWithGetObjValue(Concept):
|
||||
def get_obj_value(self):
|
||||
return self.get_value("my_prop")
|
||||
|
||||
|
||||
class TestSheerka(TestUsingFileBasedSheerka):
|
||||
class TestSheerkaUsingMemoryBasedSheerka(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def test_root_folder_is_created_after_initialization(self):
|
||||
return_value = Sheerka().initialize(self.root_folder)
|
||||
assert return_value.status, "initialisation should be successful"
|
||||
assert os.path.exists(self.root_folder), "init folder should be created"
|
||||
def test_i_can_initialize_builtin_parsers(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
# test existence of some parser (not all)
|
||||
assert "parsers.DefaultParser.DefaultParser" in sheerka.parsers
|
||||
assert "parsers.BnfNodeParser.BnfNodeParser" in sheerka.parsers
|
||||
assert "parsers.SyaNodeParser.SyaNodeParser" in sheerka.parsers
|
||||
assert "parsers.AtomNodeParser.AtomNodeParser" in sheerka.parsers
|
||||
|
||||
# make sure BaseNodeParser is properly initialized
|
||||
assert BASE_NODE_PARSER_CLASS not in sheerka.parsers
|
||||
assert sheerka.bnp is not None
|
||||
|
||||
def test_i_can_list_builtin_concepts(self):
|
||||
sheerka = self.get_sheerka()
|
||||
@@ -27,27 +36,6 @@ class TestSheerka(TestUsingFileBasedSheerka):
|
||||
assert str(BuiltinConcepts.ERROR) in builtins
|
||||
assert str(BuiltinConcepts.RETURN_VALUE) in builtins
|
||||
|
||||
def test_builtin_concepts_are_initialized(self):
|
||||
sheerka = self.get_sheerka(skip_builtins_in_db=False)
|
||||
assert len(sheerka.cache_by_key) == len(BuiltinConcepts)
|
||||
for concept_name in BuiltinConcepts:
|
||||
assert str(concept_name) in sheerka.cache_by_key
|
||||
assert sheerka.sdp.get_safe(sheerka.CONCEPTS_ENTRY, str(concept_name)) is not None
|
||||
|
||||
for key, concept_class in sheerka.get_builtins_classes_as_dict().items():
|
||||
assert isinstance(sheerka.cache_by_key[key], concept_class)
|
||||
|
||||
def test_builtin_concepts_can_be_updated(self):
|
||||
sheerka = self.get_sheerka(use_dict=False, skip_builtins_in_db=False)
|
||||
loaded_sheerka = sheerka.get(BuiltinConcepts.SHEERKA)
|
||||
loaded_sheerka.metadata.desc = "I have a description"
|
||||
sheerka.sdp.modify("Test", sheerka.CONCEPTS_ENTRY, loaded_sheerka.key, loaded_sheerka)
|
||||
|
||||
sheerka = self.get_sheerka(use_dict=False, skip_builtins_in_db=False)
|
||||
loaded_sheerka = sheerka.get(BuiltinConcepts.SHEERKA)
|
||||
|
||||
assert loaded_sheerka.metadata.desc == "I have a description"
|
||||
|
||||
def test_i_can_get_a_builtin_concept_by_their_enum_or_the_string(self):
|
||||
"""
|
||||
Checks that a concept can be found its name
|
||||
@@ -56,27 +44,27 @@ class TestSheerka(TestUsingFileBasedSheerka):
|
||||
"""
|
||||
sheerka = self.get_sheerka()
|
||||
for key in sheerka.get_builtins_classes_as_dict():
|
||||
assert sheerka.get(key) is not None
|
||||
assert sheerka.get(str(key)) is not None
|
||||
assert sheerka.get_by_key(key) is not None
|
||||
assert sheerka.get_by_key(str(key)) is not None
|
||||
|
||||
def test_i_cannot_get_when_key_is_none(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
res = sheerka.get(None)
|
||||
res = sheerka.get_by_key(None)
|
||||
assert sheerka.isinstance(res, BuiltinConcepts.ERROR)
|
||||
assert res.body == "Concept key is undefined."
|
||||
assert res.body == "Concept 'None' is undefined."
|
||||
|
||||
def test_unknown_concept_is_return_when_the_concept_key_is_not_found(self):
|
||||
def test_i_cannot_get_when_key_is_not_found(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
loaded = sheerka.get("key_that_does_not_exist")
|
||||
loaded = sheerka.get_by_key("key_that_does_not_exist")
|
||||
|
||||
assert loaded is not None
|
||||
assert sheerka.isinstance(loaded, BuiltinConcepts.UNKNOWN_CONCEPT)
|
||||
assert loaded.body == ("key", "key_that_does_not_exist")
|
||||
assert loaded.metadata.is_evaluated
|
||||
|
||||
def test_unknown_concept_is_return_when_the_concept_id_is_not_found(self):
|
||||
def test_i_cannot_get_when_id_is_not_found(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
loaded = sheerka.get_by_id("id_that_does_not_exist")
|
||||
@@ -97,6 +85,10 @@ class TestSheerka(TestUsingFileBasedSheerka):
|
||||
assert ret.value == "value"
|
||||
assert ret.message == "message"
|
||||
|
||||
# check the others
|
||||
for key, concept_class in sheerka.get_builtins_classes_as_dict().items():
|
||||
assert isinstance(sheerka.get_by_key(key), concept_class)
|
||||
|
||||
def test_i_can_instantiate_a_builtin_concept_when_no_specific_class(self):
|
||||
sheerka = self.get_sheerka()
|
||||
ret = sheerka.new(BuiltinConcepts.UNKNOWN_CONCEPT, body="fake_concept")
|
||||
@@ -106,9 +98,7 @@ class TestSheerka(TestUsingFileBasedSheerka):
|
||||
assert ret.body == "fake_concept"
|
||||
|
||||
def test_i_can_instantiate_a_concept(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept = self.get_default_concept()
|
||||
sheerka.create_new_concept(self.get_context(sheerka), concept)
|
||||
sheerka, context, concept = self.init_concepts(self.get_default_concept(), create_new=True)
|
||||
|
||||
new = sheerka.new(concept.key, a=10, b="value")
|
||||
|
||||
@@ -116,27 +106,33 @@ class TestSheerka(TestUsingFileBasedSheerka):
|
||||
for prop in PROPERTIES_TO_SERIALIZE:
|
||||
assert getattr(new.metadata, prop) == getattr(concept.metadata, prop)
|
||||
|
||||
assert new.props["a"].value == 10
|
||||
assert new.props["b"].value == "value"
|
||||
assert new.get_value("a") == 10
|
||||
assert new.get_value("b") == "value"
|
||||
|
||||
def test_i_can_instantiate_with_the_name_and_the_id(self):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka.create_new_concept(self.get_context(sheerka), Concept("foo", body="foo1"))
|
||||
sheerka.create_new_concept(self.get_context(sheerka), Concept("foo", body="foo2"))
|
||||
def test_i_can_instantiate_multiple_when_same_key(self):
|
||||
sheerka, context, *concepts = self.init_concepts(
|
||||
Concept("foo", body="foo1"),
|
||||
Concept("foo", body="foo2"),
|
||||
create_new=True)
|
||||
|
||||
# when no id, i get two instances
|
||||
concepts = sheerka.new("foo")
|
||||
assert len(concepts) == 2
|
||||
assert concepts[0].id == "1001"
|
||||
assert concepts[0].metadata.body == "foo1"
|
||||
assert concepts[1].id == "1002"
|
||||
assert concepts[1].metadata.body == "foo2"
|
||||
|
||||
# only one instance if the id is given
|
||||
foo1 = sheerka.new(("foo", "1001"))
|
||||
assert foo1.metadata.body == "foo1"
|
||||
|
||||
# only one instance if the id is given
|
||||
foo2 = sheerka.new(("foo", "1002"))
|
||||
assert foo2.metadata.body == "foo2"
|
||||
|
||||
def test_instances_are_different_when_asking_for_new(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept = self.get_default_concept()
|
||||
sheerka.create_new_concept(self.get_context(sheerka), concept)
|
||||
sheerka, context, concept = self.init_concepts(self.get_default_concept(), create_new=True)
|
||||
|
||||
new1 = sheerka.new(concept.key, a=10, b="value")
|
||||
new2 = sheerka.new(concept.key, a=10, b="value")
|
||||
@@ -144,17 +140,50 @@ class TestSheerka(TestUsingFileBasedSheerka):
|
||||
assert new1 == new2
|
||||
assert id(new1) != id(new2)
|
||||
|
||||
def test_i_get_the_same_instance_when_is_unique_is_true(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept = Concept(name="unique", is_unique=True)
|
||||
sheerka.create_new_concept(self.get_context(sheerka), concept)
|
||||
def test_new_instance_does_not_impact_each_others(self):
|
||||
sheerka, context, foo, bar = self.init_concepts("foo", "bar", create_new=True)
|
||||
|
||||
new1 = sheerka.new(concept.key, a=10, b="value")
|
||||
new2 = sheerka.new(concept.key, a=10, b="value")
|
||||
new_foo = sheerka.new("foo")
|
||||
new_foo.metadata.body = "metadata value" # modify metadata
|
||||
new_foo.def_var("var_name", "default value") # modify definition of variables
|
||||
new_foo.add_prop(BuiltinConcepts.ISA, bar) # modify property
|
||||
new_foo.compiled["var_name"] = "'var value'"
|
||||
new_foo.set_value(ConceptParts.BODY, "body value") # modify value
|
||||
new_foo.set_value("var_name", "var value") # modify value
|
||||
|
||||
assert new_foo.metadata.body != foo.metadata.body
|
||||
assert new_foo.metadata.variables != foo.metadata.variables
|
||||
assert new_foo.metadata.props != foo.metadata.props
|
||||
assert new_foo.values != foo.values
|
||||
assert new_foo.compiled != foo.compiled
|
||||
|
||||
def test_i_get_the_same_instance_when_is_unique_is_true(self):
|
||||
sheerka, context, concept = self.init_concepts(Concept(name="unique", is_unique=True), create_new=True)
|
||||
|
||||
new1 = sheerka.new(concept.key)
|
||||
new2 = sheerka.new(concept.key, a=10, b="value") # not that variables are simply discareded
|
||||
|
||||
assert new1 == new2
|
||||
assert id(new1) == id(new2)
|
||||
|
||||
def test_values_are_reset_when_asking_for_a_new_instance(self):
|
||||
sheerka, context, template = self.init_concepts(
|
||||
Concept("foo", body="'foo body'"),
|
||||
create_new=True,
|
||||
eval_body=True)
|
||||
|
||||
sheerka.evaluate_concept(context, sheerka.get_by_id(template.id))
|
||||
assert template.metadata.is_evaluated
|
||||
assert template.body == "foo body"
|
||||
|
||||
new = sheerka.new(template.key)
|
||||
assert not new.metadata.is_evaluated
|
||||
assert not new.body
|
||||
|
||||
new = sheerka.new((None, template.id))
|
||||
assert not new.metadata.is_evaluated
|
||||
assert not new.body
|
||||
|
||||
def test_i_cannot_instantiate_an_unknown_concept(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
@@ -164,9 +193,10 @@ class TestSheerka(TestUsingFileBasedSheerka):
|
||||
assert new.body == ('key', 'fake_concept')
|
||||
|
||||
def test_i_cannot_instantiate_with_invalid_id(self):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka.create_new_concept(self.get_context(sheerka), Concept("foo", body="foo1"))
|
||||
sheerka.create_new_concept(self.get_context(sheerka), Concept("foo", body="foo2"))
|
||||
sheerka, context, *concepts = self.init_concepts(
|
||||
Concept("foo", body="foo1"),
|
||||
Concept("foo", body="foo2"),
|
||||
create_new=True)
|
||||
|
||||
new = sheerka.new(("foo", "invalid_id"))
|
||||
|
||||
@@ -174,9 +204,10 @@ class TestSheerka(TestUsingFileBasedSheerka):
|
||||
assert new.body == [('key', 'foo'), ('id', 'invalid_id')]
|
||||
|
||||
def test_i_cannot_instantiate_with_invalid_key(self):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka.create_new_concept(self.get_context(sheerka), Concept("foo", body="foo1"))
|
||||
sheerka.create_new_concept(self.get_context(sheerka), Concept("foo", body="foo2"))
|
||||
sheerka, context, *concepts = self.init_concepts(
|
||||
Concept("foo", body="foo1"),
|
||||
Concept("foo", body="foo2"),
|
||||
create_new=True)
|
||||
|
||||
new = sheerka.new(("invalid_key", "1001"))
|
||||
|
||||
@@ -184,8 +215,9 @@ class TestSheerka(TestUsingFileBasedSheerka):
|
||||
assert new.body == [('key', 'invalid_key'), ('id', '1001')]
|
||||
|
||||
def test_concept_id_is_irrelevant_when_only_one_concept(self):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka.create_new_concept(self.get_context(sheerka), Concept("foo", body="foo1"))
|
||||
sheerka, context, *concepts = self.init_concepts(
|
||||
Concept("foo", body="foo1"),
|
||||
create_new=True)
|
||||
|
||||
new = sheerka.new(("foo", "invalid_id"))
|
||||
|
||||
@@ -193,9 +225,7 @@ class TestSheerka(TestUsingFileBasedSheerka):
|
||||
assert new.metadata.body == "foo1"
|
||||
|
||||
def test_i_cannot_instantiate_when_properties_are_not_recognized(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept = self.get_default_concept()
|
||||
sheerka.create_new_concept(self.get_context(sheerka), concept)
|
||||
sheerka, context, concept = self.init_concepts(self.get_default_concept(), create_new=True)
|
||||
|
||||
new = sheerka.new(concept.key, a=10, c="value")
|
||||
|
||||
@@ -210,7 +240,7 @@ class TestSheerka(TestUsingFileBasedSheerka):
|
||||
(True, False, True),
|
||||
(Concept("name", body="foo"), False, "foo"),
|
||||
(Concept("name"), False, Concept("name")),
|
||||
(ConceptWithGetValue("name").set_prop("my_prop", "my_value"), False, "my_value"),
|
||||
(ConceptWithGetObjValue("name").set_value("my_prop", "my_value"), False, "my_value"),
|
||||
(ReturnValueConcept(value="return_value"), False, "return_value"),
|
||||
(ReturnValueConcept(value=Concept(key=BuiltinConcepts.USER_INPUT, body="text"), status=True), False, "text"),
|
||||
(ReturnValueConcept(value=UserInputConcept("text"), status=True), False, "text"),
|
||||
@@ -230,53 +260,138 @@ class TestSheerka(TestUsingFileBasedSheerka):
|
||||
c.auto_init()
|
||||
c = c.body
|
||||
|
||||
assert sheerka.value(concept, reduce_simple_list) == expected
|
||||
|
||||
def test_list_of_concept_is_sorted_by_id(self):
|
||||
sheerka = self.get_sheerka(use_dict=False, skip_builtins_in_db=False)
|
||||
concepts = sheerka.concepts()
|
||||
|
||||
assert concepts[0].id < concepts[-1].id
|
||||
assert sheerka.objvalue(concept, reduce_simple_list) == expected
|
||||
|
||||
def test_builtin_error_concept_are_errors(self):
|
||||
# only test a random one, it will be the same for the others
|
||||
sheerka = self.get_sheerka()
|
||||
assert not sheerka.is_success(sheerka.new(BuiltinConcepts.TOO_MANY_SUCCESS))
|
||||
|
||||
def test_cache_is_updated_after_get(self):
|
||||
sheerka = self.get_sheerka(skip_builtins_in_db=False)
|
||||
|
||||
# updated when by_key returns one element
|
||||
sheerka.create_new_concept(self.get_context(sheerka), Concept("foo", body="1"))
|
||||
sheerka.reset_cache()
|
||||
sheerka.get("foo")
|
||||
assert "foo" in sheerka.cache_by_key
|
||||
assert "1001" in sheerka.cache_by_id
|
||||
class TestSheerkaUsingFileBasedSheerka(TestUsingFileBasedSheerka):
|
||||
|
||||
# updated when by_key returns two elements
|
||||
sheerka.create_new_concept(self.get_context(sheerka), Concept("foo", body="2"))
|
||||
sheerka.reset_cache()
|
||||
sheerka.get("foo")
|
||||
assert "foo" in sheerka.cache_by_key
|
||||
assert "1001" in sheerka.cache_by_id
|
||||
assert "1002" in sheerka.cache_by_id
|
||||
def test_root_folder_is_created_after_initialization(self):
|
||||
return_value = Sheerka().initialize(self.root_folder)
|
||||
assert return_value.status, "initialisation should be successful"
|
||||
assert os.path.exists(self.root_folder), "init folder should be created"
|
||||
|
||||
def test_builtin_concepts_are_initialized(self):
|
||||
sheerka = self.get_sheerka()
|
||||
for concept_name in BuiltinConcepts:
|
||||
assert sheerka.has_key(str(concept_name))
|
||||
assert sheerka.sdp.get(sheerka.CONCEPTS_BY_KEY_ENTRY, str(concept_name)) is not None
|
||||
|
||||
# I can get back data from the sdp when the cache is empty
|
||||
sheerka.cache_manager.clear()
|
||||
|
||||
# caches are empty
|
||||
assert not sheerka.has_id("1")
|
||||
assert not sheerka.has_key(str(BuiltinConcepts.SHEERKA))
|
||||
|
||||
assert sheerka.get_by_id("1") == sheerka # use sdp
|
||||
|
||||
# assert sheerka.has_key(str(BuiltinConcepts.SHEERKA)) # auto update the other caches
|
||||
|
||||
def test_builtin_concepts_can_be_updated(self):
|
||||
sheerka = self.get_sheerka()
|
||||
before_parsing = sheerka.get_by_key(BuiltinConcepts.BEFORE_PARSING)
|
||||
before_parsing.metadata.desc = "I have a description"
|
||||
before_parsing.metadata.full_serialization = True
|
||||
with sheerka.sdp.get_transaction("Test") as transac:
|
||||
transac.add(sheerka.CONCEPTS_BY_KEY_ENTRY, before_parsing.key, before_parsing, use_ref=True)
|
||||
|
||||
sheerka = self.get_sheerka() # another fresh new instance
|
||||
before_parsing = sheerka.get_by_key(BuiltinConcepts.BEFORE_PARSING)
|
||||
|
||||
assert before_parsing.metadata.desc == "I have a description"
|
||||
|
||||
def test_i_first_look_in_local_cache(self):
|
||||
sheerka, context, concept = self.init_concepts("foo", create_new=True)
|
||||
sheerka.cache_manager.commit(context)
|
||||
|
||||
sheerka.get_by_key(concept.key).new_property = "I have modified the concept in cache"
|
||||
|
||||
from_cache = sheerka.get_by_key(concept.key)
|
||||
assert from_cache is not None
|
||||
assert from_cache.key == concept.key
|
||||
assert from_cache.new_property == "I have modified the concept in cache"
|
||||
|
||||
# sdp instance is not modified
|
||||
sheerka.cache_manager.clear()
|
||||
from_sdp = sheerka.get_by_key(concept.key)
|
||||
assert from_sdp is not None
|
||||
assert from_sdp.key == concept.key
|
||||
assert not hasattr(from_sdp, "new_property")
|
||||
|
||||
def test_i_can_retrieve_from_sdp_when_cache_is_reset(self):
|
||||
sheerka, context, concept = self.init_concepts(Concept("foo", body="1"))
|
||||
sheerka.cache_manager.commit(context)
|
||||
|
||||
sheerka.cache_manager.clear()
|
||||
sheerka.get_by_key("foo")
|
||||
assert sheerka.has_key("foo")
|
||||
|
||||
# It's also updated when sdp returns more than one element
|
||||
concept2 = Concept("foo", body="2")
|
||||
sheerka.create_new_concept(context, concept2)
|
||||
sheerka.cache_manager.commit(context)
|
||||
|
||||
sheerka.cache_manager.clear()
|
||||
assert len(sheerka.get_by_key("foo")) == 2
|
||||
assert sheerka.has_key("foo")
|
||||
|
||||
# updated when by_id
|
||||
sheerka.reset_cache()
|
||||
sheerka.get_by_id("1001")
|
||||
assert "1001" in sheerka.cache_by_id
|
||||
assert "foo" not in sheerka.cache_by_key # cache_by_key not updated as "1001" is not the only one
|
||||
sheerka.cache_manager.clear()
|
||||
assert sheerka.get_by_id("1001") == concept
|
||||
assert sheerka.has_id("1001")
|
||||
|
||||
def test_i_can_get_by_key_several_times(self):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka.create_new_concept(self.get_context(sheerka), Concept("foo", body="1"))
|
||||
sheerka.create_new_concept(self.get_context(sheerka), Concept("foo", body="2"))
|
||||
sheerka.cache_manager.clear()
|
||||
assert sheerka.get_by_name("foo") == [concept, concept2]
|
||||
assert sheerka.has_name("foo")
|
||||
|
||||
sheerka.reset_cache()
|
||||
sheerka.get("foo", "1001") # only one element requested. But the cache must be updated with two elements
|
||||
sheerka.cache_manager.clear()
|
||||
assert sheerka.get_by_hash(concept.get_definition_hash()) == concept
|
||||
assert sheerka.has_hash(concept.get_definition_hash())
|
||||
|
||||
# let's check it
|
||||
concepts = sheerka.get("foo")
|
||||
def test_get_by_key_retrieve_all_elements(self):
|
||||
sheerka, context, *concepts = self.init_concepts(
|
||||
Concept("foo", body="1"),
|
||||
Concept("foo", body="2"),
|
||||
create_new=True)
|
||||
sheerka.cache_manager.commit(context)
|
||||
|
||||
sheerka.cache_manager.clear()
|
||||
sheerka.get_by_key("foo", "1001") # I ask only for the one with id = "1001"
|
||||
|
||||
# but the two keys are returned
|
||||
concepts = sheerka.get_by_key("foo")
|
||||
assert len(concepts) == 2
|
||||
assert concepts[0].id == "1001"
|
||||
assert concepts[1].id == "1002"
|
||||
|
||||
def test_concept_node_parsing_is_initialized_at_startup(self):
|
||||
sheerka, context, foo, bar, baz = self.init_concepts(
|
||||
"foo",
|
||||
"bar",
|
||||
Concept("baz", definition="foo"),
|
||||
create_new=True)
|
||||
sheerka.cache_manager.commit(context)
|
||||
|
||||
assert sheerka.cache_manager.copy(sheerka.CONCEPTS_BY_FIRST_KEYWORD_ENTRY) == {
|
||||
'bar': ['1002'],
|
||||
'c:|1001:': ['1003'],
|
||||
'foo': ['1001']}
|
||||
assert sheerka.cache_manager.copy(sheerka.RESOLVED_CONCEPTS_BY_FIRST_KEYWORD_ENTRY) == {
|
||||
'bar': ['1002'],
|
||||
'foo': ['1001', '1003']
|
||||
}
|
||||
|
||||
sheerka = self.get_sheerka() # another instance
|
||||
assert sheerka.cache_manager.copy(sheerka.CONCEPTS_BY_FIRST_KEYWORD_ENTRY) == {
|
||||
'bar': ['1002'],
|
||||
'c:|1001:': ['1003'],
|
||||
'foo': ['1001']}
|
||||
assert sheerka.cache_manager.copy(sheerka.RESOLVED_CONCEPTS_BY_FIRST_KEYWORD_ENTRY) == {
|
||||
'bar': ['1002'],
|
||||
'foo': ['1001', '1003']
|
||||
}
|
||||
|
||||
@@ -189,6 +189,12 @@ class EvaluatorAllSuppressFooEntry(EvaluatorAllWithPriority):
|
||||
|
||||
class TestSheerkaExecuteEvaluators(TestUsingMemoryBasedSheerka):
|
||||
|
||||
@classmethod
|
||||
def teardown_class(cls):
|
||||
# At the end of the tests, sheerka singleton instance will be corrupted
|
||||
# Ask for a new one
|
||||
TestUsingMemoryBasedSheerka.singleton_instance = None
|
||||
|
||||
def test_that_return_values_is_unchanged_when_no_evaluator(self):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka.evaluators = []
|
||||
|
||||
@@ -135,6 +135,11 @@ class ListOfNoneParser(BaseTestParser):
|
||||
|
||||
|
||||
class TestSheerkaExecuteParsers(TestUsingMemoryBasedSheerka):
|
||||
@classmethod
|
||||
def teardown_class(cls):
|
||||
# At the end of the tests, sheerka singleton instance will be corrupted
|
||||
# Ask for a new one
|
||||
TestUsingMemoryBasedSheerka.singleton_instance = None
|
||||
|
||||
def test_disabled_parsers_are_not_executed(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
@@ -22,6 +22,7 @@ class ObjLongProp:
|
||||
|
||||
|
||||
class TestSheerkaPrinter(TestUsingMemoryBasedSheerka):
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("Hello world!", "Hello world!\n"),
|
||||
("%black%%red%%green%%yellow%%reset%", "\x1b[30m\x1b[31m\x1b[32m\x1b[33m\x1b[0m\n"),
|
||||
@@ -45,7 +46,7 @@ class TestSheerkaPrinter(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def test_i_can_print_concept(self, capsys):
|
||||
sheerka = self.get_sheerka()
|
||||
foo = Concept("foo a b").def_prop("a").def_prop("b")
|
||||
foo = Concept("foo a b").def_var("a").def_var("b")
|
||||
sheerka.print(foo)
|
||||
|
||||
captured = capsys.readouterr()
|
||||
@@ -53,11 +54,11 @@ class TestSheerkaPrinter(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def test_i_can_use_custom_format(self, capsys):
|
||||
sheerka = self.get_sheerka()
|
||||
foo = Concept("foo a b").def_prop("a").def_prop("b").init_key()
|
||||
foo = Concept("foo a b").def_var("a").def_var("b").init_key()
|
||||
sheerka.printer_handler.register_custom_printer(
|
||||
foo,
|
||||
lambda printer, instr, item: printer.fp(instr, f"foo a={item.a}, b={item.b}"))
|
||||
foo.set_prop("a", "value a").set_prop("b", "value b")
|
||||
foo.set_value("a", "value a").set_value("b", "value b")
|
||||
sheerka.print(foo)
|
||||
|
||||
captured = capsys.readouterr()
|
||||
@@ -66,8 +67,8 @@ class TestSheerkaPrinter(TestUsingMemoryBasedSheerka):
|
||||
def test_i_can_print_and_recurse(self, capsys):
|
||||
sheerka = self.get_sheerka()
|
||||
level3 = Concept("level3")
|
||||
level2 = Concept("level2").set_metadata_value(ConceptParts.BODY, level3)
|
||||
level1 = Concept("level1").set_metadata_value(ConceptParts.BODY, level2)
|
||||
level2 = Concept("level2").set_value(ConceptParts.BODY, level3)
|
||||
level1 = Concept("level1").set_value(ConceptParts.BODY, level2)
|
||||
|
||||
sheerka.print(level1)
|
||||
captured = capsys.readouterr()
|
||||
@@ -90,9 +91,9 @@ class TestSheerkaPrinter(TestUsingMemoryBasedSheerka):
|
||||
level31 = Concept("level31")
|
||||
level32 = Concept("level32")
|
||||
level33 = Concept("level33")
|
||||
level21 = Concept("level21").set_metadata_value(ConceptParts.BODY, [level31, level32])
|
||||
level22 = Concept("level22").set_metadata_value(ConceptParts.BODY, [level33])
|
||||
level1 = Concept("level1").set_metadata_value(ConceptParts.BODY, [level21, level22])
|
||||
level21 = Concept("level21").set_value(ConceptParts.BODY, [level31, level32])
|
||||
level22 = Concept("level22").set_value(ConceptParts.BODY, [level33])
|
||||
level1 = Concept("level1").set_value(ConceptParts.BODY, [level21, level22])
|
||||
|
||||
sheerka.print(level1)
|
||||
captured = capsys.readouterr()
|
||||
@@ -111,9 +112,9 @@ class TestSheerkaPrinter(TestUsingMemoryBasedSheerka):
|
||||
level31 = Concept("level31")
|
||||
level32 = Concept("level32")
|
||||
level33 = Concept("level33")
|
||||
level21 = Concept("level21").set_metadata_value(ConceptParts.BODY, [level31, level32])
|
||||
level22 = Concept("level22").set_metadata_value(ConceptParts.BODY, [level33])
|
||||
level1 = Concept("level1").set_metadata_value(ConceptParts.BODY, [level21, level22])
|
||||
level21 = Concept("level21").set_value(ConceptParts.BODY, [level31, level32])
|
||||
level22 = Concept("level22").set_value(ConceptParts.BODY, [level33])
|
||||
level1 = Concept("level1").set_value(ConceptParts.BODY, [level21, level22])
|
||||
|
||||
instructions = FormatInstructions(no_color=True)
|
||||
explanation = sheerka.new(
|
||||
@@ -150,9 +151,9 @@ class TestSheerkaPrinter(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def test_i_can_format_concept(self, capsys):
|
||||
sheerka = self.get_sheerka()
|
||||
foo = Concept("foo a b").def_prop("a").def_prop("b").init_key()
|
||||
foo.set_prop("a", "value a").set_prop("b", "value b")
|
||||
foo.set_metadata_value(ConceptParts.BODY, "body")
|
||||
foo = Concept("foo a b").def_var("a").def_var("b").init_key()
|
||||
foo.set_value("a", "value a").set_value("b", "value b")
|
||||
foo.set_value(ConceptParts.BODY, "body")
|
||||
sheerka.set_id_if_needed(foo, False)
|
||||
|
||||
sheerka.printer_handler.register_format_l(foo, "{id}-{name}-{key}-{body}-{a}-{b}")
|
||||
|
||||
@@ -69,13 +69,13 @@ def test_i_can_get_sub_classes():
|
||||
default_parser = core.utils.get_class("parsers.DefaultParser.DefaultParser")
|
||||
exact_concept_parser = core.utils.get_class("parsers.ExactConceptParser.ExactConceptParser")
|
||||
python_parser = core.utils.get_class("parsers.PythonParser.PythonParser")
|
||||
concept_lexer_parser = core.utils.get_class("parsers.BnfNodeParser.BnfNodeParser")
|
||||
bnf_node_parser = core.utils.get_class("parsers.BnfNodeParser.BnfNodeParser")
|
||||
|
||||
assert base_parser not in sub_classes
|
||||
assert default_parser in sub_classes
|
||||
assert exact_concept_parser in sub_classes
|
||||
assert python_parser in sub_classes
|
||||
assert concept_lexer_parser in sub_classes
|
||||
assert bnf_node_parser in sub_classes
|
||||
|
||||
|
||||
@pytest.mark.parametrize("a,b, expected", [
|
||||
@@ -170,12 +170,14 @@ def test_i_can_str_concept():
|
||||
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)) == ""
|
||||
assert core.utils.str_concept(("key", "id"), skip_key=True) == "c:|id:"
|
||||
|
||||
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:"
|
||||
assert core.utils.str_concept(concept, skip_key=True) == "c:|1001:"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
|
||||
@@ -142,12 +142,12 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
|
||||
body="print('hello' + a)")
|
||||
|
||||
# sanity. Make sure that the concept does not already exist
|
||||
from_db = context.sheerka.get("hello " + VARIABLE_PREFIX + "0")
|
||||
from_db = context.sheerka.get_by_key("hello " + VARIABLE_PREFIX + "0")
|
||||
assert context.sheerka.isinstance(from_db, BuiltinConcepts.UNKNOWN_CONCEPT)
|
||||
|
||||
AddConceptEvaluator().eval(context, def_concept_return_value)
|
||||
context.sheerka.concepts_cache = {} # reset cache
|
||||
from_db = context.sheerka.get("hello " + VARIABLE_PREFIX + "0")
|
||||
from_db = context.sheerka.get_by_key("hello " + VARIABLE_PREFIX + "0")
|
||||
|
||||
assert from_db.metadata.key == f"hello {VARIABLE_PREFIX}0"
|
||||
assert from_db.metadata.name == "hello a"
|
||||
@@ -157,38 +157,38 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
|
||||
assert from_db.metadata.body == "print('hello' + a)"
|
||||
assert from_db.metadata.definition == "hello a"
|
||||
assert from_db.metadata.definition_type == "bnf"
|
||||
assert len(from_db.metadata.props) == 1
|
||||
assert from_db.metadata.props[0] == ("a", None)
|
||||
assert "a" in from_db.props
|
||||
assert len(from_db.metadata.variables) == 1
|
||||
assert from_db.metadata.variables[0] == ("a", None)
|
||||
assert "a" in from_db.values
|
||||
|
||||
assert from_db.compiled == {} # ast is not saved in db
|
||||
|
||||
def test_i_can_get_props_from_python_node_when_long_name(self):
|
||||
def test_i_can_get_variables_from_python_node_when_long_name(self):
|
||||
ret_val = self.get_concept_part("isinstance(a, str)")
|
||||
context = self.get_context()
|
||||
|
||||
assert AddConceptEvaluator.get_props(context.sheerka, ret_val, ["a", "b"]) == ["a"]
|
||||
assert AddConceptEvaluator.get_variables(context.sheerka, ret_val, ["a", "b"]) == ["a"]
|
||||
|
||||
def test_i_cannot_get_props_from_python_node_when_name_has_only_one_token(self):
|
||||
def test_i_cannot_get_variables_from_python_node_when_name_has_only_one_token(self):
|
||||
ret_val = self.get_concept_part("isinstance(a, str)")
|
||||
context = self.get_context()
|
||||
|
||||
assert AddConceptEvaluator.get_props(context.sheerka, ret_val, ["a"]) == []
|
||||
assert AddConceptEvaluator.get_variables(context.sheerka, ret_val, ["a"]) == []
|
||||
|
||||
def test_i_can_get_props_from_another_concept(self):
|
||||
concept = Concept("hello").def_prop("a").def_prop("b")
|
||||
def test_i_can_get_variables_from_another_concept(self):
|
||||
concept = Concept("hello").def_var("a").def_var("b")
|
||||
ret_val = ReturnValueConcept(who="some_parser",
|
||||
status=True,
|
||||
value=ParserResultConcept(value=concept))
|
||||
|
||||
assert AddConceptEvaluator.get_props(self.get_sheerka(), ret_val, []) == ["a", "b"]
|
||||
assert AddConceptEvaluator.get_variables(self.get_sheerka(), ret_val, []) == ["a", "b"]
|
||||
|
||||
def test_i_can_get_props_from_definition(self):
|
||||
def test_i_can_get_variables_from_definition(self):
|
||||
parsing_expression = Sequence(ConceptExpression('mult'),
|
||||
ZeroOrMore(Sequence(StrMatch("+"), ConceptExpression("add"))))
|
||||
ret_val = self.get_return_value("mult (('+'|'-') add)?", parsing_expression)
|
||||
|
||||
assert AddConceptEvaluator.get_props(self.get_sheerka(), ret_val, []) == ["add", "mult"]
|
||||
assert AddConceptEvaluator.get_variables(self.get_sheerka(), ret_val, []) == ["add", "mult"]
|
||||
|
||||
def test_concept_that_references_itself_is_correctly_created(self):
|
||||
context = self.get_context()
|
||||
@@ -200,5 +200,5 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
|
||||
new_concept = ret_val.body.body
|
||||
assert new_concept.name == 'foo'
|
||||
assert new_concept.metadata.body == 'foo'
|
||||
assert new_concept.props == {}
|
||||
assert new_concept.metadata.props == []
|
||||
assert new_concept.values == {}
|
||||
assert new_concept.metadata.variables == []
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import ReturnValueConcept, ParserResultConcept, BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from core.tokenizer import Tokenizer
|
||||
from evaluators.AddConceptInSetEvaluator import AddConceptInSetEvaluator
|
||||
from parsers.DefaultParser import IsaConceptNode, NameNode
|
||||
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
def get_ret_val(concept_name, concept_set_name):
|
||||
def get_isa_ret_val(concept_name, concept_set_name):
|
||||
n1 = NameNode(list(Tokenizer(concept_name)))
|
||||
n2 = NameNode(list(Tokenizer(concept_set_name)))
|
||||
|
||||
@@ -30,7 +30,7 @@ class TestAddConceptInSetEvaluator(TestUsingMemoryBasedSheerka):
|
||||
def test_i_cannot_add_if_the_concept_does_not_exists(self):
|
||||
context = self.get_context()
|
||||
|
||||
ret_val = get_ret_val("foo", "bar")
|
||||
ret_val = get_isa_ret_val("foo", "bar")
|
||||
res = AddConceptInSetEvaluator().eval(context, ret_val)
|
||||
|
||||
assert not res.status
|
||||
@@ -43,7 +43,7 @@ class TestAddConceptInSetEvaluator(TestUsingMemoryBasedSheerka):
|
||||
context.sheerka.set_id_if_needed(foo, False)
|
||||
context.sheerka.add_in_cache(foo)
|
||||
|
||||
ret_val = get_ret_val("foo", "bar")
|
||||
ret_val = get_isa_ret_val("foo", "bar")
|
||||
res = AddConceptInSetEvaluator().eval(context, ret_val)
|
||||
|
||||
assert not res.status
|
||||
@@ -52,10 +52,10 @@ class TestAddConceptInSetEvaluator(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def test_i_can_add_concept_to_a_set_of_concept(self):
|
||||
sheerka, context, foo, bar = self.init_concepts("foo", "bar", create_new=True)
|
||||
ret_val = get_ret_val("foo", "bar")
|
||||
ret_val = get_isa_ret_val("foo", "bar")
|
||||
|
||||
res = AddConceptInSetEvaluator().eval(context, ret_val)
|
||||
foo = sheerka.new("foo") # reload it
|
||||
foo = sheerka.new("foo") # get a new instance
|
||||
|
||||
assert res.status
|
||||
assert context.sheerka.isinstance(res.value, BuiltinConcepts.SUCCESS)
|
||||
@@ -63,8 +63,7 @@ class TestAddConceptInSetEvaluator(TestUsingMemoryBasedSheerka):
|
||||
assert context.sheerka.isinset(foo, bar)
|
||||
assert context.sheerka.isa(foo, bar)
|
||||
|
||||
foo_from_sheerka = context.sheerka.get("foo")
|
||||
assert foo_from_sheerka.get_prop(BuiltinConcepts.ISA) == [bar]
|
||||
assert foo.get_prop(BuiltinConcepts.ISA) == {bar}
|
||||
|
||||
def test_i_can_add_bnf_concept_to_a_set_of_concept(self):
|
||||
"""
|
||||
@@ -76,11 +75,11 @@ class TestAddConceptInSetEvaluator(TestUsingMemoryBasedSheerka):
|
||||
sheerka, context, one, two, foo, bar = self.init_concepts(
|
||||
"one",
|
||||
"two",
|
||||
Concept("foo", definition="(one|two)=a 'plus' (one|two)=b", body="a + b").def_prop("a").def_prop("b"),
|
||||
Concept("foo", definition="(one|two)=a 'plus' (one|two)=b", body="a + b").def_var("a").def_var("b"),
|
||||
"bar",
|
||||
create_new=True)
|
||||
|
||||
ret_val = get_ret_val("foo", "bar")
|
||||
ret_val = get_isa_ret_val("foo", "bar")
|
||||
res = AddConceptInSetEvaluator().eval(context, ret_val)
|
||||
foo = sheerka.new("foo") # reload it
|
||||
|
||||
@@ -90,8 +89,8 @@ class TestAddConceptInSetEvaluator(TestUsingMemoryBasedSheerka):
|
||||
assert context.sheerka.isinset(foo, bar)
|
||||
assert context.sheerka.isa(foo, bar)
|
||||
|
||||
foo_from_sheerka = context.sheerka.get("foo")
|
||||
assert foo_from_sheerka.get_prop(BuiltinConcepts.ISA) == [bar]
|
||||
foo_from_sheerka = context.sheerka.get_by_key("foo")
|
||||
assert foo_from_sheerka.get_prop(BuiltinConcepts.ISA) == {bar}
|
||||
|
||||
def test_i_can_add_concept_with_a_body_to_a_set_of_concept(self):
|
||||
context = self.get_context()
|
||||
@@ -101,23 +100,18 @@ class TestAddConceptInSetEvaluator(TestUsingMemoryBasedSheerka):
|
||||
bar = Concept("bar")
|
||||
context.sheerka.create_new_concept(context, bar)
|
||||
|
||||
ret_val = get_ret_val("foo", "bar")
|
||||
ret_val = get_isa_ret_val("foo", "bar")
|
||||
res = AddConceptInSetEvaluator().eval(context, ret_val)
|
||||
|
||||
assert res.status
|
||||
assert context.sheerka.isinstance(res.value, BuiltinConcepts.SUCCESS)
|
||||
|
||||
def test_i_cannot_add_the_same_concept_twice(self):
|
||||
context = self.get_context()
|
||||
foo = Concept("foo")
|
||||
context.sheerka.create_new_concept(context, foo)
|
||||
sheerka, context, foo, bar = self.init_concepts("foo", "bar", create_new=True)
|
||||
|
||||
bar = Concept("bar")
|
||||
context.sheerka.create_new_concept(context, bar)
|
||||
|
||||
ret_val = get_ret_val("foo", "bar")
|
||||
ret_val = get_isa_ret_val("foo", "bar")
|
||||
AddConceptInSetEvaluator().eval(context, ret_val)
|
||||
res = AddConceptInSetEvaluator().eval(context, ret_val)
|
||||
res = AddConceptInSetEvaluator().eval(context, ret_val) # again
|
||||
|
||||
assert not res.status
|
||||
assert context.sheerka.isinstance(res.value, BuiltinConcepts.CONCEPT_ALREADY_IN_SET)
|
||||
|
||||
@@ -24,7 +24,7 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
|
||||
concept = Concept(name="foo",
|
||||
where="True",
|
||||
pre="2",
|
||||
post="3").def_prop("a", "4").def_prop("b", "5")
|
||||
post="3").def_var("a", "4").def_var("b", "5")
|
||||
|
||||
evaluator = ConceptEvaluator()
|
||||
item = self.pretval(concept)
|
||||
@@ -33,11 +33,11 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
|
||||
assert result.who == evaluator.name
|
||||
assert result.status
|
||||
assert result.value.name == "foo"
|
||||
assert result.value.get_metadata_value(ConceptParts.WHERE) == True
|
||||
assert result.value.get_metadata_value(ConceptParts.PRE) == 2
|
||||
assert result.value.get_metadata_value(ConceptParts.POST) == 3
|
||||
assert result.value.get_prop("a") == 4
|
||||
assert result.value.get_prop("b") == 5
|
||||
assert result.value.get_value(ConceptParts.WHERE) == True
|
||||
assert result.value.get_value(ConceptParts.PRE) == 2
|
||||
assert result.value.get_value(ConceptParts.POST) == 3
|
||||
assert result.value.get_value("a") == 4
|
||||
assert result.value.get_value("b") == 5
|
||||
assert result.value.key == "foo"
|
||||
assert result.parents == [item]
|
||||
|
||||
@@ -48,7 +48,7 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
|
||||
body="'I have a value'",
|
||||
where="True",
|
||||
pre="2",
|
||||
post="3").set_prop("a", "4").set_prop("b", "5")
|
||||
post="3").set_value("a", "4").set_value("b", "5")
|
||||
|
||||
evaluator = ConceptEvaluator(return_body=True)
|
||||
item = self.pretval(concept)
|
||||
@@ -65,7 +65,7 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
|
||||
body="'I have a value'",
|
||||
where="True",
|
||||
pre="2",
|
||||
post="3").set_prop("a", "4").set_prop("b", "5")
|
||||
post="3").set_value("a", "4").set_value("b", "5")
|
||||
|
||||
evaluator = ConceptEvaluator(return_body=False) # which is the default behaviour
|
||||
item = self.pretval(concept)
|
||||
@@ -77,11 +77,11 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
|
||||
assert result.parents == [item]
|
||||
|
||||
def test_i_can_eval_if_with_the_same_name_is_defined_in_the_context(self):
|
||||
# If we evaluate Concept("foo", body="a").set_prop("a", "'property_a'")
|
||||
# If we evaluate Concept("foo", body="a").set_value("a", "'property_a'")
|
||||
# ConceptEvaluator will be called to resolve 'a' while we know that 'a' refers to the string 'property_a'
|
||||
|
||||
context = self.get_context()
|
||||
context.obj = Concept("other").set_prop("foo", "'some_other_value'")
|
||||
context.obj = Concept("other").set_value("foo", "'some_other_value'")
|
||||
concept = Concept(name="foo")
|
||||
|
||||
item = self.pretval(concept)
|
||||
@@ -95,8 +95,8 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
|
||||
context.local_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
|
||||
context.sheerka.add_in_cache(Concept(name="one").init_key())
|
||||
concept_plus = context.sheerka.add_in_cache(Concept(name="a plus b")
|
||||
.def_prop("a", "one")
|
||||
.def_prop("b", "two").init_key())
|
||||
.def_var("a", "one")
|
||||
.def_var("b", "two").init_key())
|
||||
|
||||
evaluator = ConceptEvaluator()
|
||||
item = self.pretval(concept_plus)
|
||||
|
||||
@@ -75,4 +75,4 @@ class TestEvalEvaluator(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert len(evaluated) == 1
|
||||
assert evaluated[0].status
|
||||
assert evaluated[0].body == [foo, bar, baz]
|
||||
assert set(evaluated[0].body) == {foo, bar, baz}
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
import ast
|
||||
import pytest
|
||||
|
||||
import pytest
|
||||
from core.builtin_concepts import ReturnValueConcept, ParserResultConcept, BuiltinConcepts
|
||||
from core.concept import Concept, ConceptParts, DoNotResolve
|
||||
from evaluators.LexerNodeEvaluator import LexerNodeEvaluator
|
||||
from parsers.BaseNodeParser import SourceCodeNode
|
||||
from parsers.BnfNodeParser import ConceptNode, BnfNodeParser, StrMatch, UnrecognizedTokensNode
|
||||
from parsers.BnfNodeParser import ConceptNode, BnfNodeParser, UnrecognizedTokensNode
|
||||
from parsers.PythonParser import PythonNode
|
||||
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
class TestLexerNodeEvaluator(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def from_parsing(self, context, grammar, expression):
|
||||
def init_from_concepts(self, context, concepts, expression):
|
||||
parser = BnfNodeParser()
|
||||
parser.initialize(context, grammar)
|
||||
parser.init_from_concepts(context, concepts)
|
||||
|
||||
ret_val = parser.parse(context, expression)
|
||||
assert ret_val.status
|
||||
@@ -31,18 +32,6 @@ class TestLexerNodeEvaluator(TestUsingMemoryBasedSheerka):
|
||||
|
||||
return ReturnValueConcept("somme_name", True, ParserResultConcept(value=nodes))
|
||||
|
||||
def init(self, concept, grammar, text):
|
||||
context = self.get_context()
|
||||
if isinstance(concept, list):
|
||||
for c in concept:
|
||||
context.sheerka.add_in_cache(c)
|
||||
else:
|
||||
context.sheerka.add_in_cache(concept)
|
||||
ret_val = self.from_parsing(context, grammar, text)
|
||||
node = ret_val.value.value[0]
|
||||
|
||||
return context, node
|
||||
|
||||
@pytest.mark.parametrize("ret_val, expected", [
|
||||
(ReturnValueConcept("some_name", True, ParserResultConcept(value=[ConceptNode(Concept(), 0, 0)])), True),
|
||||
(ReturnValueConcept("some_name", True, ParserResultConcept(value=ConceptNode(Concept(), 0, 0))), True),
|
||||
@@ -60,15 +49,13 @@ class TestLexerNodeEvaluator(TestUsingMemoryBasedSheerka):
|
||||
(ReturnValueConcept("some_name", True, ConceptNode(Concept(), 0, 0)), False),
|
||||
])
|
||||
def test_i_can_match(self, ret_val, expected):
|
||||
context = self.get_context()
|
||||
sheerka = self.get_sheerka(singleton=True)
|
||||
context = self.get_context(sheerka)
|
||||
assert LexerNodeEvaluator().matches(context, ret_val) == expected
|
||||
|
||||
def test_concept_is_returned_when_only_one_in_the_list(self):
|
||||
foo = Concept("foo")
|
||||
context = self.get_context()
|
||||
context.sheerka.add_in_cache(foo)
|
||||
|
||||
ret_val = self.from_parsing(context, {foo: StrMatch("foo")}, "foo")
|
||||
sheerka, context, foo = self.init_concepts(self.bnf_concept("foo"), singleton=True)
|
||||
ret_val = self.init_from_concepts(context, [foo], "foo")
|
||||
|
||||
evaluator = LexerNodeEvaluator()
|
||||
result = evaluator.eval(context, ret_val)
|
||||
@@ -80,7 +67,7 @@ class TestLexerNodeEvaluator(TestUsingMemoryBasedSheerka):
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert wrapper.parser == evaluator
|
||||
assert wrapper.source == "foo"
|
||||
assert return_value == Concept("foo").init_key()
|
||||
assert return_value == foo
|
||||
assert return_value.compiled[ConceptParts.BODY] == DoNotResolve("foo")
|
||||
assert result.parents == [ret_val]
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ class TestPythonEvaluator(TestUsingMemoryBasedSheerka):
|
||||
@pytest.mark.parametrize("concept", [
|
||||
Concept("foo"),
|
||||
Concept("foo", body="2"),
|
||||
Concept("foo").set_prop("prop", "'a'"),
|
||||
Concept("foo").def_var("prop", "'a'"),
|
||||
Concept("foo", body="bar")
|
||||
])
|
||||
def test_i_cannot_eval_simple_concept(self, concept):
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import pytest
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import Concept, PROPERTIES_TO_SERIALIZE, Property, simplec
|
||||
from core.concept import Concept, PROPERTIES_TO_SERIALIZE, simplec
|
||||
from evaluators.MutipleSameSuccessEvaluator import MultipleSameSuccessEvaluator
|
||||
from parsers.BaseNodeParser import SyaAssociativity
|
||||
from parsers.BnfNodeParser import Sequence, StrMatch, OrderedChoice, Optional, ConceptExpression
|
||||
from sdp.sheerkaDataProvider import SheerkaDataProvider
|
||||
|
||||
from tests.TestUsingFileBasedSheerka import TestUsingFileBasedSheerka
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
class TestSheerkaNonReg(TestUsingFileBasedSheerka):
|
||||
class TestSheerkaNonRegMemory(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def init_scenario(self, init_expressions):
|
||||
sheerka = self.get_sheerka()
|
||||
@@ -105,10 +105,10 @@ as:
|
||||
expected = self.get_default_concept()
|
||||
expected.metadata.id = "1001"
|
||||
expected.metadata.desc = None
|
||||
expected.metadata.props = [("a", None), ("b", None)]
|
||||
expected.metadata.variables = [("a", None), ("b", None)]
|
||||
expected.init_key()
|
||||
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka = self.get_sheerka(cache_only=False)
|
||||
res = sheerka.evaluate_user_input(text)
|
||||
|
||||
assert len(res) == 1
|
||||
@@ -120,21 +120,15 @@ as:
|
||||
for prop in PROPERTIES_TO_SERIALIZE:
|
||||
assert getattr(concept_saved.metadata, prop) == getattr(expected.metadata, prop)
|
||||
|
||||
assert concept_saved.key in sheerka.cache_by_key
|
||||
assert concept_saved.id in sheerka.cache_by_id
|
||||
assert sheerka.sdp.io.exists(
|
||||
sheerka.sdp.io.get_obj_path(SheerkaDataProvider.ObjectsFolder, concept_saved.get_origin()))
|
||||
# cache is up to date
|
||||
assert sheerka.has_key(concept_saved.key)
|
||||
assert sheerka.has_id(concept_saved.id)
|
||||
assert sheerka.has_name(concept_saved.name)
|
||||
assert sheerka.has_hash(concept_saved.get_definition_hash())
|
||||
assert sheerka.cache_manager.copy(sheerka.CONCEPTS_BY_FIRST_KEYWORD_ENTRY) == {'+': ['1001']}
|
||||
|
||||
def test_i_can_def_several_concepts(self):
|
||||
sheerka = self.get_sheerka(use_dict=False)
|
||||
sheerka.evaluate_user_input("def concept foo")
|
||||
|
||||
sheerka = self.get_sheerka(use_dict=False)
|
||||
res = sheerka.evaluate_user_input("def concept bar")
|
||||
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].body.body.id == "1002"
|
||||
# sdp is up to date
|
||||
assert sheerka.sdp.exists(sheerka.CONCEPTS_BY_KEY_ENTRY, expected.key)
|
||||
|
||||
def test_i_can_evaluate_def_concept_part_when_one_part_is_a_ref_of_another_concept(self):
|
||||
"""
|
||||
@@ -145,11 +139,11 @@ as:
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
# concept 'a plus b' is known
|
||||
concept_a_plus_b = Concept(name="a plus b").def_prop("a").def_prop("b")
|
||||
concept_a_plus_b = Concept(name="a plus b").def_var("a").def_var("b").init_key()
|
||||
sheerka.add_in_cache(concept_a_plus_b)
|
||||
|
||||
res = sheerka.evaluate_user_input("def concept a xx b as a plus b")
|
||||
expected = Concept(name="a xx b", body="a plus b").def_prop("a").def_prop("b").init_key()
|
||||
expected = Concept(name="a xx b", body="a plus b").def_var("a").def_var("b").init_key()
|
||||
expected.metadata.id = "1001"
|
||||
|
||||
assert len(res) == 1
|
||||
@@ -161,10 +155,7 @@ as:
|
||||
for prop in PROPERTIES_TO_SERIALIZE:
|
||||
assert getattr(concept_saved.metadata, prop) == getattr(expected.metadata, prop)
|
||||
|
||||
assert concept_saved.key in sheerka.cache_by_key
|
||||
assert concept_saved.id in sheerka.cache_by_id
|
||||
assert sheerka.sdp.io.exists(
|
||||
sheerka.sdp.io.get_obj_path(SheerkaDataProvider.ObjectsFolder, concept_saved.get_origin()))
|
||||
assert sheerka.has_key(concept_saved.key)
|
||||
|
||||
def test_i_cannot_evaluate_the_same_def_concept_twice(self):
|
||||
text = """
|
||||
@@ -202,7 +193,7 @@ as:
|
||||
|
||||
def test_i_can_recognize_concept_with_variable(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept_hello = Concept(name="hello a").def_prop("a")
|
||||
concept_hello = Concept(name="hello a").def_var("a")
|
||||
concept_foo = Concept(name="foo")
|
||||
sheerka.add_in_cache(concept_hello)
|
||||
sheerka.add_in_cache(concept_foo)
|
||||
@@ -212,15 +203,15 @@ as:
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(return_value, concept_hello)
|
||||
assert return_value.metadata.props[0] == ('a', "foo")
|
||||
assert return_value.metadata.variables[0] == ('a', "foo")
|
||||
|
||||
# sanity check
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(eval_body=True), return_value)
|
||||
assert evaluated.props["a"].value == concept_foo
|
||||
assert evaluated.get_value("a") == concept_foo
|
||||
|
||||
def test_i_can_recognize_concept_with_variable_and_python_as_body(self):
|
||||
sheerka = self.get_sheerka()
|
||||
hello_a = sheerka.add_in_cache(Concept(name="hello a", body="'hello ' + a").def_prop("a"))
|
||||
hello_a = sheerka.add_in_cache(Concept(name="hello a", body="'hello ' + a").def_var("a"))
|
||||
sheerka.add_in_cache(Concept(name="foo", body="'foo'"))
|
||||
|
||||
res = sheerka.evaluate_user_input("hello foo")
|
||||
@@ -232,15 +223,14 @@ as:
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(eval_body=True), res[0].value)
|
||||
assert evaluated.body == "hello foo"
|
||||
assert evaluated.metadata.is_evaluated
|
||||
assert evaluated.props["a"].value == simplec("foo", "foo")
|
||||
assert evaluated.props["a"].value.metadata.is_evaluated
|
||||
assert evaluated.get_value("a") == simplec("foo", "foo")
|
||||
assert evaluated.get_value("a").metadata.is_evaluated
|
||||
|
||||
def test_i_can_recognize_duplicate_concepts_with_same_value(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
sheerka.add_in_cache(Concept(name="hello a", body="'hello ' + a").def_prop("a"))
|
||||
sheerka.add_in_cache(Concept(name="hello foo", body="'hello foo'"))
|
||||
sheerka.add_in_cache(Concept(name="foo", body="'foo'"))
|
||||
self.create_concept_lite(sheerka, Concept(name="hello a", body="'hello ' + a"), variables=["a"])
|
||||
self.create_concept_lite(sheerka, Concept(name="hello foo", body="'hello foo'"))
|
||||
self.create_concept_lite(sheerka, Concept(name="foo", body="'foo'"))
|
||||
|
||||
res = sheerka.evaluate_user_input("hello foo")
|
||||
assert len(res) == 1
|
||||
@@ -250,10 +240,9 @@ as:
|
||||
|
||||
def test_i_cannot_manage_duplicate_concepts_when_the_values_are_different(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
sheerka.add_in_cache(Concept(name="hello a", body="'hello ' + a").def_prop("a"))
|
||||
sheerka.add_in_cache(Concept(name="hello foo", body="'hello foo'"))
|
||||
sheerka.add_in_cache(Concept(name="foo", body="'another value'"))
|
||||
self.create_concept_lite(sheerka, Concept(name="hello a", body="'hello ' + a"), variables=["a"])
|
||||
self.create_concept_lite(sheerka, Concept(name="hello foo", body="'hello foo'"))
|
||||
self.create_concept_lite(sheerka, Concept(name="foo", body="'another value'"))
|
||||
|
||||
res = sheerka.evaluate_user_input("hello foo")
|
||||
assert len(res) == 1
|
||||
@@ -270,8 +259,8 @@ as:
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
|
||||
sheerka.create_new_concept(context, Concept(name="hello a", body="'hello ' + a").def_prop("a"))
|
||||
sheerka.create_new_concept(context, Concept(name="hello b", body="'hello ' + b").def_prop("b"))
|
||||
sheerka.create_new_concept(context, Concept(name="hello a", body="'hello ' + a").def_var("a"))
|
||||
sheerka.create_new_concept(context, Concept(name="hello b", body="'hello ' + b").def_var("b"))
|
||||
|
||||
res = sheerka.evaluate_user_input("hello 'foo'")
|
||||
assert len(res) == 1
|
||||
@@ -283,42 +272,12 @@ as:
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
|
||||
sheerka.create_new_concept(context, Concept(name="concepts", body="sheerka.concepts()"))
|
||||
sheerka.create_new_concept(context, Concept(name="concepts", body="sheerka.test()"))
|
||||
res = sheerka.evaluate_user_input("eval concepts")
|
||||
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert isinstance(res[0].value, list)
|
||||
|
||||
def test_i_can_create_concept_with_bnf_definition(self):
|
||||
sheerka = self.get_sheerka(use_dict=False, skip_builtins_in_db=False)
|
||||
a = Concept("a")
|
||||
sheerka.add_in_cache(a)
|
||||
sheerka.concepts_definition_cache = {a: OrderedChoice("one", "two")}
|
||||
|
||||
res = sheerka.evaluate_user_input("def concept plus from bnf a ('plus' plus)?")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(res[0].value, BuiltinConcepts.NEW_CONCEPT)
|
||||
|
||||
saved_concept = sheerka.sdp.get_safe(sheerka.CONCEPTS_ENTRY, "plus")
|
||||
assert saved_concept.key == "plus"
|
||||
assert saved_concept.metadata.definition == "a ('plus' plus)?"
|
||||
assert "a" in saved_concept.props
|
||||
assert "plus" in saved_concept.props
|
||||
|
||||
saved_definitions = sheerka.sdp.get_safe(sheerka.CONCEPTS_DEFINITIONS_ENTRY)
|
||||
expected_bnf = Sequence(
|
||||
ConceptExpression(a, rule_name="a"),
|
||||
Optional(Sequence(StrMatch("plus"), ConceptExpression(saved_concept, rule_name="plus"))))
|
||||
assert saved_definitions["c:plus|1001:"] == "(c:a:=a ('plus' c:plus|1001:=plus)?)"
|
||||
|
||||
new_concept = res[0].value.body
|
||||
assert new_concept.metadata.name == "plus"
|
||||
assert new_concept.metadata.definition == "a ('plus' plus)?"
|
||||
assert new_concept.bnf == expected_bnf
|
||||
assert "a" in new_concept.props
|
||||
assert "plus" in new_concept.props
|
||||
assert res[0].value == sheerka.test()
|
||||
|
||||
def test_i_can_recognize_bnf_definitions(self):
|
||||
sheerka = self.get_sheerka()
|
||||
@@ -344,41 +303,11 @@ as:
|
||||
assert sheerka.isinstance(return_value, concept_b)
|
||||
|
||||
# sanity check
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(eval_body=True), return_value)
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(sheerka=sheerka, eval_body=True), return_value)
|
||||
assert evaluated.body == "one three"
|
||||
assert evaluated.metadata.is_evaluated
|
||||
assert evaluated.props["a"] == Property("a", sheerka.new(concept_a.key, body="one").init_key())
|
||||
assert evaluated.props["a"].value.metadata.is_evaluated
|
||||
|
||||
def test_i_can_recognize_bnf_definitions_from_separate_instances(self):
|
||||
"""
|
||||
Same test then before,
|
||||
but make sure that the BNF are correctly persisted and loaded
|
||||
"""
|
||||
sheerka = self.get_sheerka(use_dict=False)
|
||||
concept_a = sheerka.evaluate_user_input("def concept a from bnf 'one' 'two'")[0].body.body
|
||||
|
||||
res = self.get_sheerka(use_dict=False).evaluate_user_input("one two")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(res[0].value, concept_a)
|
||||
|
||||
# add another bnf definition
|
||||
concept_b = sheerka.evaluate_user_input("def concept b from bnf a 'three'")[0].body.body
|
||||
|
||||
res = self.get_sheerka(use_dict=False).evaluate_user_input("one two") # previous one still works
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(res[0].value, concept_a)
|
||||
|
||||
res = self.get_sheerka(use_dict=False).evaluate_user_input("one two three") # new one works
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(res[0].value, concept_b)
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(eval_body=True), res[0].value)
|
||||
assert evaluated.body == "one two three"
|
||||
assert evaluated.props["a"] == Property("a", sheerka.new(concept_a.key, body="one two").init_key())
|
||||
assert evaluated.get_value("a") == sheerka.new(concept_a.key, body="one").init_key()
|
||||
assert evaluated.get_value("a").metadata.is_evaluated
|
||||
|
||||
@pytest.mark.parametrize("user_input", [
|
||||
"def concept greetings from def hello a where a",
|
||||
@@ -393,7 +322,7 @@ as:
|
||||
assert res[0].status
|
||||
concept_found = res[0].value
|
||||
assert sheerka.isinstance(concept_found, greetings)
|
||||
assert concept_found.get_prop("a") == "foo"
|
||||
assert concept_found.get_value("a") == "foo"
|
||||
assert concept_found.metadata.need_validation
|
||||
|
||||
res = sheerka.evaluate_user_input("greetings")
|
||||
@@ -401,10 +330,9 @@ as:
|
||||
assert res[0].status
|
||||
concept_found = res[0].value
|
||||
assert sheerka.isinstance(concept_found, greetings)
|
||||
assert concept_found.get_prop("a") is None
|
||||
assert concept_found.get_value("a") is None
|
||||
assert not concept_found.metadata.need_validation
|
||||
|
||||
# @pytest.mark.xfail
|
||||
@pytest.mark.parametrize("desc, definitions", [
|
||||
("Simple form", [
|
||||
"def concept one as 1",
|
||||
@@ -452,7 +380,7 @@ as:
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(res[0].body, "twenties")
|
||||
assert sheerka.evaluate_concept(self.get_context(eval_body=True), res[0].body).body == 21
|
||||
assert sheerka.evaluate_concept(self.get_context(sheerka=sheerka, eval_body=True), res[0].body).body == 21
|
||||
|
||||
res = sheerka.evaluate_user_input("twenty one + 1")
|
||||
assert len(res) == 1
|
||||
@@ -479,7 +407,6 @@ as:
|
||||
assert res[0].status
|
||||
assert res[0].body == 23
|
||||
|
||||
# @pytest.mark.xfail
|
||||
def test_i_can_mix_bnf_and_isa(self):
|
||||
"""
|
||||
if 'one' isa 'number, twenty number should be recognized
|
||||
@@ -497,7 +424,7 @@ as:
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(res[0].body, "twenties")
|
||||
assert sheerka.evaluate_concept(self.get_context(eval_body=True), res[0].value).body == 21
|
||||
assert sheerka.evaluate_concept(self.get_context(sheerka=sheerka, eval_body=True), res[0].value).body == 21
|
||||
|
||||
res = sheerka.evaluate_user_input("twenty one + 1")
|
||||
assert len(res) == 1
|
||||
@@ -524,7 +451,7 @@ as:
|
||||
assert res[0].status
|
||||
assert res[0].body == 23
|
||||
|
||||
def test_i_can_mix_bnf_and_isa_when_concept_other_case(self):
|
||||
def test_i_can_mix_bnf_and_isa_2(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
init = [
|
||||
@@ -544,7 +471,6 @@ as:
|
||||
assert res[0].status
|
||||
assert res[0].body == 21
|
||||
|
||||
# @pytest.mark.xfail
|
||||
def test_i_can_use_concepts_defined_with_from(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
@@ -656,31 +582,6 @@ as:
|
||||
assert res[0].status
|
||||
assert res[0].body == 3
|
||||
|
||||
@pytest.mark.xfail
|
||||
def test_i_can_recognize_composition_of_concept(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
definitions = [
|
||||
"def concept little a where a",
|
||||
"def concept blue a where a",
|
||||
"def concept house"
|
||||
]
|
||||
|
||||
for definition in definitions:
|
||||
sheerka.evaluate_user_input(definition)
|
||||
|
||||
### CAUTION ####
|
||||
# this test cannot work !!
|
||||
# it is just to hint the result that I would like to achieve
|
||||
|
||||
res = sheerka.evaluate_user_input("little blue house")
|
||||
assert len(res) == 2
|
||||
assert res[0].status
|
||||
assert res[0].body == "little(blue(house))"
|
||||
|
||||
assert res[1].status
|
||||
assert res[1].body == "little blue(house)"
|
||||
|
||||
def test_i_can_say_that_a_concept_isa_another_concept(self):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka.evaluate_user_input("def concept foo")
|
||||
@@ -779,36 +680,35 @@ as:
|
||||
sheerka.evaluate_user_input(exp)
|
||||
|
||||
res = sheerka.evaluate_user_input("twenty one")
|
||||
assert len(res) == 1 and res[0].status and sheerka.isinstance(res[0].body, "twenties")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(res[0].body, "twenties")
|
||||
|
||||
res = sheerka.evaluate_user_input("eval twenty one")
|
||||
assert len(res) == 1 and res[0].status and res[0].body == 21
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].body == 21
|
||||
|
||||
res = sheerka.evaluate_user_input("twenty two")
|
||||
assert len(res) == 1 and res[0].status and sheerka.isinstance(res[0].body, "twenties")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(res[0].body, "twenties")
|
||||
|
||||
res = sheerka.evaluate_user_input("eval twenty two")
|
||||
assert len(res) == 1 and res[0].status and res[0].body == 22
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].body == 22
|
||||
|
||||
res = sheerka.evaluate_user_input("twenty three")
|
||||
assert len(res) == 1
|
||||
assert not res[0].status
|
||||
assert sheerka.isinstance(res[0].body, BuiltinConcepts.WHERE_CLAUSE_FAILED)
|
||||
assert sheerka.isinstance(res[0].body, BuiltinConcepts.MULTIPLE_ERRORS)
|
||||
assert str(BuiltinConcepts.WHERE_CLAUSE_FAILED) in [error.key for error in sheerka.get_error(res[0].body.body)]
|
||||
|
||||
res = sheerka.evaluate_user_input("eval twenty three")
|
||||
assert len(res) == 1
|
||||
assert not res[0].status
|
||||
assert sheerka.isinstance(res[0].body, BuiltinConcepts.WHERE_CLAUSE_FAILED)
|
||||
|
||||
|
||||
# def test_i_can_detect_when_only_one_evaluator_is_in_error(self):
|
||||
# sheerka = self.get_sheerka()
|
||||
#
|
||||
# sheerka.evaluate_user_input("def concept 1 as one")
|
||||
# res = sheerka.evaluate_user_input("eval 1")
|
||||
# assert len(res) == 1
|
||||
# assert not res[0].status
|
||||
# assert sheerka.isinstance(res[0].body, BuiltinConcepts.CONCEPT_EVAL_ERROR)
|
||||
assert str(BuiltinConcepts.WHERE_CLAUSE_FAILED) in [error.key for error in sheerka.get_error(res[0].body.body)]
|
||||
|
||||
def test_i_can_manage_some_type_of_infinite_recursion(self):
|
||||
sheerka = self.get_sheerka()
|
||||
@@ -862,7 +762,7 @@ as:
|
||||
assert not res[0].status
|
||||
assert sheerka.isinstance(res[0].body, BuiltinConcepts.WHERE_CLAUSE_FAILED)
|
||||
|
||||
@pytest.mark.xfail
|
||||
@pytest.mark.skip("Not ready for that")
|
||||
def test_i_can_manage_missing_variables_from_bnf_parsing(self):
|
||||
definitions = [
|
||||
"def concept one as 1",
|
||||
@@ -894,8 +794,8 @@ as:
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
|
||||
twenties = sheerka.get("twenties")
|
||||
number = sheerka.get("number")
|
||||
twenties = sheerka.get_by_key("twenties")
|
||||
number = sheerka.get_by_key("number")
|
||||
assert sheerka.isa(twenties, number)
|
||||
|
||||
def test_i_can_mix_sya_concepts_and_bnf_concept(self):
|
||||
@@ -910,9 +810,9 @@ as:
|
||||
|
||||
sheerka = self.init_scenario(definitions)
|
||||
context = self.get_context(sheerka)
|
||||
sheerka.set_sya_def(context, [
|
||||
(sheerka.get("mult").id, 20, SyaAssociativity.Right),
|
||||
(sheerka.get("plus").id, 10, SyaAssociativity.Right),
|
||||
sheerka.force_sya_def(context, [
|
||||
(sheerka.get_by_name("mult").id, 20, SyaAssociativity.Right),
|
||||
(sheerka.get_by_name("plus").id, 10, SyaAssociativity.Right),
|
||||
])
|
||||
|
||||
res = sheerka.evaluate_user_input("eval one plus two mult three")
|
||||
@@ -954,3 +854,71 @@ as:
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].body == 64
|
||||
|
||||
|
||||
class TestSheerkaNonRegFile(TestUsingFileBasedSheerka):
|
||||
def test_i_can_def_several_concepts(self):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka.evaluate_user_input("def concept foo")
|
||||
|
||||
sheerka = self.get_sheerka()
|
||||
res = sheerka.evaluate_user_input("def concept bar")
|
||||
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].body.body.id == "1002"
|
||||
|
||||
def test_i_can_create_concept_with_bnf_definition(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept_a = self.bnf_concept("a", expression=OrderedChoice(StrMatch("one"), StrMatch("two")))
|
||||
sheerka.create_new_concept(self.get_context(sheerka), concept_a)
|
||||
|
||||
res = sheerka.evaluate_user_input("def concept plus from bnf a ('plus' plus)?")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(res[0].value, BuiltinConcepts.NEW_CONCEPT)
|
||||
|
||||
saved_concept = sheerka.sdp.get(sheerka.CONCEPTS_BY_KEY_ENTRY, "plus")
|
||||
assert saved_concept.key == "plus"
|
||||
assert saved_concept.metadata.definition == "a ('plus' plus)?"
|
||||
assert "a" in saved_concept.values
|
||||
assert "plus" in saved_concept.values
|
||||
|
||||
expected_bnf = Sequence(
|
||||
ConceptExpression(concept_a, rule_name="a"),
|
||||
Optional(Sequence(StrMatch("plus"), ConceptExpression("plus"))))
|
||||
|
||||
new_concept = res[0].value.body
|
||||
assert new_concept.metadata.name == "plus"
|
||||
assert new_concept.metadata.definition == "a ('plus' plus)?"
|
||||
assert new_concept.bnf == expected_bnf
|
||||
assert "a" in new_concept.values
|
||||
assert "plus" in new_concept.values
|
||||
|
||||
def test_i_can_recognize_bnf_definitions_from_separate_instances(self):
|
||||
sheerka = self.get_sheerka()
|
||||
concept_a = sheerka.evaluate_user_input("def concept a from bnf 'one' 'two'")[0].body.body
|
||||
|
||||
sheerka = self.get_sheerka()
|
||||
res = sheerka.evaluate_user_input("one two")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(res[0].value, concept_a)
|
||||
|
||||
# add another bnf definition
|
||||
concept_b = sheerka.evaluate_user_input("def concept b from bnf a 'three'")[0].body.body
|
||||
|
||||
sheerka = self.get_sheerka()
|
||||
res = sheerka.evaluate_user_input("one two") # previous one still works
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(res[0].value, concept_a)
|
||||
|
||||
res = self.get_sheerka().evaluate_user_input("one two three") # new one works
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(res[0].value, concept_b)
|
||||
|
||||
evaluated = sheerka.evaluate_concept(self.get_context(eval_body=True), res[0].value)
|
||||
assert evaluated.body == "one two three"
|
||||
assert evaluated.get_value("a") == sheerka.new(concept_a.key, body="one two").init_key()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from core.concept import CC, Concept
|
||||
from core.concept import CC, Concept, ConceptParts, DoNotResolve
|
||||
from core.tokenizer import Tokenizer, TokenKind, Token
|
||||
from parsers.BaseNodeParser import scnode, utnode, cnode, SCWC, CNC, short_cnode, SourceCodeWithConceptNode, CN, UTN
|
||||
from parsers.BaseNodeParser import scnode, utnode, cnode, SCWC, CNC, short_cnode, SourceCodeWithConceptNode, CN, UTN, \
|
||||
SCN
|
||||
from parsers.SyaNodeParser import SyaConceptParserHelper
|
||||
|
||||
|
||||
@@ -43,7 +44,16 @@ def compute_debug_array(res):
|
||||
return to_compare
|
||||
|
||||
|
||||
def get_node(concepts_map, expression_as_tokens, sub_expr, concept_key=None, skip=0, is_bnf=False, sya=False):
|
||||
def get_node(
|
||||
concepts_map,
|
||||
expression_as_tokens,
|
||||
sub_expr,
|
||||
concept_key=None,
|
||||
skip=0,
|
||||
is_bnf=False,
|
||||
sya=False,
|
||||
init_empty_body=False,
|
||||
exclude_body=False):
|
||||
"""
|
||||
Tries to find sub in expression
|
||||
When found, transform it to its correct type
|
||||
@@ -54,6 +64,8 @@ def get_node(concepts_map, expression_as_tokens, sub_expr, concept_key=None, ski
|
||||
:param skip: number of occurrences of sub_expr to skip
|
||||
:param is_bnf: True if the concept to search is a bnf definition
|
||||
:param sya: Return SyaConceptParserHelper instead of a ConceptNode when needed
|
||||
:param init_empty_body: if True adds the source in the body (actually in compiled.BODY)
|
||||
:param exclude_body: Ask to not compare body
|
||||
:return:
|
||||
"""
|
||||
if sub_expr == "')'":
|
||||
@@ -80,23 +92,38 @@ def get_node(concepts_map, expression_as_tokens, sub_expr, concept_key=None, ski
|
||||
content = [get_node(concepts_map, expression_as_tokens, c, sya=sya) for c in sub_expr.content]
|
||||
return SourceCodeWithConceptNode(first, last, content).pseudo_fix_source()
|
||||
|
||||
if isinstance(sub_expr, SCN):
|
||||
node = get_node(concepts_map, expression_as_tokens, sub_expr.source, sya=sya)
|
||||
sub_expr.fix_pos(node)
|
||||
return sub_expr
|
||||
|
||||
if isinstance(sub_expr, (CNC, CC, CN)):
|
||||
concept_node = get_node(
|
||||
concepts_map,
|
||||
expression_as_tokens,
|
||||
sub_expr.source or sub_expr.concept_key,
|
||||
sub_expr.concept_key, sya=sya)
|
||||
if not hasattr(concept_node, "concept"):
|
||||
raise Exception(f"'{sub_expr.concept_key}' is not a concept. Check your map.")
|
||||
concept_found = concept_node.concept
|
||||
sub_expr.concept_key = concept_found.key
|
||||
sub_expr.concept = concept_found
|
||||
sub_expr.fix_pos((concept_node.start, concept_node.end if hasattr(concept_node, "end") else concept_node.start))
|
||||
if hasattr(sub_expr, "compiled"):
|
||||
for k, v in sub_expr.compiled.items():
|
||||
node = get_node(concepts_map, expression_as_tokens, v, sya=sya) # need to get start and end positions
|
||||
new_value = CC(Concept().update_from(concepts_map[v])) if (isinstance(v, str) and v in concepts_map) \
|
||||
else node
|
||||
node = get_node(concepts_map, expression_as_tokens, v, sya=sya, exclude_body=exclude_body) # need to get start and end positions
|
||||
if isinstance(v, str) and v in concepts_map:
|
||||
new_value_concept = concepts_map[v]
|
||||
new_value = CC(Concept().update_from(new_value_concept), exclude_body=exclude_body)
|
||||
if init_empty_body:
|
||||
init_body(new_value, concept_found, v)
|
||||
else:
|
||||
new_value = node
|
||||
|
||||
sub_expr.compiled[k] = new_value
|
||||
sub_expr.fix_pos(node)
|
||||
if init_empty_body:
|
||||
init_body(sub_expr, concept_found, sub_expr.source)
|
||||
|
||||
if hasattr(sub_expr, "fix_source"):
|
||||
sub_expr.fix_source(expression_as_tokens[sub_expr.start: sub_expr.end + 1])
|
||||
@@ -119,32 +146,54 @@ def get_node(concepts_map, expression_as_tokens, sub_expr, concept_key=None, ski
|
||||
|
||||
# special case of python source code
|
||||
if "+" in sub_expr and sub_expr.strip() != "+":
|
||||
return scnode(start, start + length - 1, sub_expr)
|
||||
return SCN(sub_expr, start, start + length - 1)
|
||||
|
||||
# try to match one of the concept from the map
|
||||
concept_key = concept_key or sub_expr
|
||||
concept_found = concepts_map.get(concept_key, None)
|
||||
if concept_found:
|
||||
concept_found = Concept().update_from(concept_found) # make a copy when massively used in tests
|
||||
if not sya or len(concept_found.metadata.props) == 0 or is_bnf:
|
||||
# if it's an atom, then return a ConceptNode
|
||||
return CN(concept_found, start, start + length - 1, source=sub_expr)
|
||||
else:
|
||||
# else return a ParserHelper
|
||||
if sya and len(concept_found.metadata.variables) > 0 and not is_bnf:
|
||||
return SyaConceptParserHelper(concept_found, start)
|
||||
elif init_empty_body:
|
||||
node = CNC(concept_found, start, start + length - 1, source=sub_expr, exclude_body=exclude_body)
|
||||
init_body(node, concept_found, sub_expr)
|
||||
return node
|
||||
else:
|
||||
return CN(concept_found, start, start + length - 1, source=sub_expr)
|
||||
else:
|
||||
# else an UnrecognizedTokensNode
|
||||
return utnode(start, start + length - 1, sub_expr)
|
||||
|
||||
|
||||
def compute_expected_array(concepts_map, expression, expected, sya=False):
|
||||
def init_body(item, concept, value):
|
||||
if "body" in item.compiled:
|
||||
item.compiled[ConceptParts.BODY] = item.compiled["body"]
|
||||
del (item.compiled["body"])
|
||||
return
|
||||
|
||||
if not concept or concept.metadata.body or ConceptParts.BODY in item.compiled:
|
||||
return
|
||||
|
||||
item.compiled[ConceptParts.BODY] = DoNotResolve(value)
|
||||
|
||||
|
||||
def compute_expected_array(concepts_map, expression, expected, sya=False, init_empty_body=False, exclude_body=False):
|
||||
"""
|
||||
Computes a simple but sufficient version of the result of infix_to_postfix()
|
||||
:param concepts_map:
|
||||
:param expression:
|
||||
:param expected:
|
||||
:param sya: if true, generate an SyaConceptParserHelper instead of a cnode
|
||||
:param init_empty_body: if True adds the source in the body (actually in compiled.BODY)
|
||||
:param exclude_body: do not include ConceptParts.BODY in comparison
|
||||
:return:
|
||||
"""
|
||||
expression_as_tokens = [token.value for token in Tokenizer(expression) if token.type != TokenKind.EOF]
|
||||
return [get_node(concepts_map, expression_as_tokens, sub_expr, sya=sya) for sub_expr in expected]
|
||||
return [get_node(
|
||||
concepts_map,
|
||||
expression_as_tokens,
|
||||
sub_expr,
|
||||
sya=sya,
|
||||
init_empty_body=init_empty_body,
|
||||
exclude_body=exclude_body) for sub_expr in expected]
|
||||
|
||||
@@ -2,18 +2,21 @@ import pytest
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from parsers.AtomNodeParser import AtomNodeParser
|
||||
from parsers.BaseNodeParser import cnode, utnode, CNC
|
||||
from parsers.BaseNodeParser import cnode, utnode, CNC, scnode, SCN
|
||||
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
from tests.parsers.parsers_utils import compute_expected_array
|
||||
|
||||
|
||||
class TestAtomsParser(TestUsingMemoryBasedSheerka):
|
||||
def init_parser(self, concepts_map, **kwargs):
|
||||
sheerka, context, *updated_concepts = self.init_concepts(singleton=True, *concepts_map.values(), **kwargs)
|
||||
def init_parser(self, my_map, create_new=False, singleton=True):
|
||||
sheerka, context, *updated_concepts = self.init_concepts(
|
||||
*my_map.values(),
|
||||
create_new=create_new,
|
||||
singleton=singleton)
|
||||
|
||||
parser = AtomNodeParser()
|
||||
parser.initialize(context, updated_concepts)
|
||||
parser.init_from_concepts(context, updated_concepts)
|
||||
|
||||
return sheerka, context, parser
|
||||
|
||||
@@ -34,7 +37,7 @@ class TestAtomsParser(TestUsingMemoryBasedSheerka):
|
||||
concepts_map = {
|
||||
"foo": Concept("foo"),
|
||||
"bar": Concept("bar"),
|
||||
"twenties": Concept("twenties", definition="'twenty' ('one'|'two')=unit").def_prop("unit"),
|
||||
"twenties": Concept("twenties", definition="'twenty' ('one'|'two')=unit").def_var("unit"),
|
||||
}
|
||||
|
||||
sheerka, context, parser = self.init_parser(concepts_map)
|
||||
@@ -57,7 +60,7 @@ class TestAtomsParser(TestUsingMemoryBasedSheerka):
|
||||
concepts_map = {
|
||||
"foo bar": Concept("foo bar"),
|
||||
"one two three": Concept("one two three"),
|
||||
"twenties": Concept("twenties", definition="'twenty' ('one'|'two')=unit").def_prop("unit"),
|
||||
"twenties": Concept("twenties", definition="'twenty' ('one'|'two')=unit").def_var("unit"),
|
||||
}
|
||||
|
||||
sheerka, context, parser = self.init_parser(concepts_map)
|
||||
@@ -75,27 +78,27 @@ class TestAtomsParser(TestUsingMemoryBasedSheerka):
|
||||
("foo bar suffixed one", False, ["foo bar", " suffixed ", "one"]),
|
||||
("foo bar one prefixed", False, ["foo bar", "one", " prefixed"]),
|
||||
("foo bar one infix two", False, ["foo bar", "one", " infix ", "two"]),
|
||||
("foo bar 1 + 1", True, ["foo bar", " 1 + 1"]),
|
||||
("foo bar 1 + 1", False, ["foo bar", " 1 + 1"]),
|
||||
("foo bar twenty one", False, ["foo bar", " twenty ", "one"]),
|
||||
("foo bar x$!#", False, ["foo bar", " x$!#"]),
|
||||
|
||||
("suffixed one foo bar", False, ["suffixed ", "one", "foo bar"]),
|
||||
("one prefixed foo bar", False, ["one", " prefixed ", "foo bar"]),
|
||||
("one infix two foo bar", False, ["one", " infix ", "two", "foo bar"]),
|
||||
("1 + 1 foo bar", True, ["1 + 1 ", "foo bar"]),
|
||||
("1 + 1 foo bar", False, ["1 + 1 ", "foo bar"]),
|
||||
("twenty one foo bar", False, ["twenty ", "one", "foo bar"]),
|
||||
("x$!# foo bar", False, ["x$!# ", "foo bar"]),
|
||||
("func(one)", False, ["func(", "one", ")"]),
|
||||
])
|
||||
def test_i_can_parse_when_unrecognized(self, text, expected_status, expected):
|
||||
concepts_map = {
|
||||
"prefixed": Concept("a prefixed").def_prop("a"),
|
||||
"suffixed": Concept("prefixed a").def_prop("a"),
|
||||
"infix": Concept("a infix b").def_prop("a").def_prop("b"),
|
||||
"prefixed": Concept("a prefixed").def_var("a"),
|
||||
"suffixed": Concept("prefixed a").def_var("a"),
|
||||
"infix": Concept("a infix b").def_var("a").def_var("b"),
|
||||
"foo bar": Concept("foo bar"),
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"twenties": Concept("twenties", definition="'twenty' ('one'|'two')=unit").def_prop("unit"),
|
||||
"twenties": Concept("twenties", definition="'twenty' ('one'|'two')=unit").def_var("unit"),
|
||||
}
|
||||
|
||||
sheerka, context, parser = self.init_parser(concepts_map)
|
||||
@@ -116,13 +119,13 @@ class TestAtomsParser(TestUsingMemoryBasedSheerka):
|
||||
])
|
||||
def test_i_can_parse_when_surrounded_by_spaces(self, text, expected_status, expected):
|
||||
concepts_map = {
|
||||
"prefixed": Concept("a prefixed").def_prop("a"),
|
||||
"suffixed": Concept("prefixed a").def_prop("a"),
|
||||
"infix": Concept("a infix b").def_prop("a").def_prop("b"),
|
||||
"prefixed": Concept("a prefixed").def_var("a"),
|
||||
"suffixed": Concept("prefixed a").def_var("a"),
|
||||
"infix": Concept("a infix b").def_var("a").def_var("b"),
|
||||
"foo bar": Concept("foo bar"),
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"twenties": Concept("twenties", definition="'twenty' ('one'|'two')=unit").def_prop("unit"),
|
||||
"twenties": Concept("twenties", definition="'twenty' ('one'|'two')=unit").def_var("unit"),
|
||||
}
|
||||
|
||||
sheerka, context, parser = self.init_parser(concepts_map)
|
||||
@@ -201,8 +204,8 @@ class TestAtomsParser(TestUsingMemoryBasedSheerka):
|
||||
])
|
||||
def test_i_cannot_parse_concepts_with_property_or_bnf_or_unrecognized(self, text):
|
||||
concepts_map = {
|
||||
"foo": Concept("foo a").def_prop("a"),
|
||||
"twenties": Concept("twenties", definition="'twenty' ('one'|'two')=unit").def_prop("unit"),
|
||||
"foo": Concept("foo a").def_var("a"),
|
||||
"twenties": Concept("twenties", definition="'twenty' ('one'|'two')=unit").def_var("unit"),
|
||||
}
|
||||
|
||||
sheerka, context, parser = self.init_parser(concepts_map)
|
||||
@@ -221,12 +224,12 @@ class TestAtomsParser(TestUsingMemoryBasedSheerka):
|
||||
])
|
||||
def test_i_can_parse_when_unrecognized_yield_multiple_values(self, text, expected):
|
||||
concepts_map = {
|
||||
"hello1": Concept("hello a").def_prop("a"),
|
||||
"hello2": Concept("hello b").def_prop("b"),
|
||||
"hello1": Concept("hello a").def_var("a"),
|
||||
"hello2": Concept("hello b").def_var("b"),
|
||||
"bar": Concept("bar")
|
||||
}
|
||||
|
||||
sheerka, context, parser = self.init_parser(concepts_map, create_new=True)
|
||||
sheerka, context, parser = self.init_parser(concepts_map, create_new=True, singleton=False)
|
||||
list_of_res = parser.parse(context, text)
|
||||
|
||||
assert len(list_of_res) == len(expected)
|
||||
@@ -239,3 +242,23 @@ class TestAtomsParser(TestUsingMemoryBasedSheerka):
|
||||
expected_array = compute_expected_array(concepts_map, text, expected[1])
|
||||
assert sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == expected_array
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("1 + twenty one", [SCN("1 + twenty "), "one"]),
|
||||
("one + twenty one", ["one", SCN(" + twenty "), ("one", 1)]),
|
||||
])
|
||||
def test_source_code_found_must_be_considered_as_potential_false_positive(self, text, expected):
|
||||
concepts_map = {
|
||||
"one": Concept("one")
|
||||
}
|
||||
|
||||
sheerka, context, parser = self.init_parser(concepts_map)
|
||||
res = parser.parse(context, text)
|
||||
wrapper = res.body
|
||||
lexer_nodes = res.body.body
|
||||
|
||||
assert not res.status
|
||||
|
||||
expected_array = compute_expected_array(concepts_map, text, expected)
|
||||
assert sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == expected_array
|
||||
|
||||
@@ -0,0 +1,257 @@
|
||||
import pytest
|
||||
from core.concept import Concept
|
||||
from parsers.BaseNodeParser import BaseNodeParser
|
||||
from parsers.BnfNodeParser import StrMatch, Sequence, OrderedChoice, Optional, ZeroOrMore, OneOrMore, ConceptExpression
|
||||
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
class TestBaseNodeParser(TestUsingMemoryBasedSheerka):
|
||||
@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 = BaseNodeParser.get_concepts_by_first_keyword(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"]}),
|
||||
])
|
||||
def test_i_can_get_concepts_by_first_keyword_with_bnf(self, bnf, expected):
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
|
||||
bar = Concept("bar").init_key()
|
||||
sheerka.set_id_if_needed(bar, False)
|
||||
sheerka.add_in_cache(bar)
|
||||
|
||||
concept = Concept("foo").init_key()
|
||||
concept.bnf = bnf
|
||||
sheerka.set_id_if_needed(concept, False)
|
||||
|
||||
res = BaseNodeParser.get_concepts_by_first_keyword(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.add_in_cache(bar)
|
||||
|
||||
baz = Concept("baz").init_key()
|
||||
sheerka.set_id_if_needed(baz, False)
|
||||
sheerka.add_in_cache(baz)
|
||||
|
||||
foo = Concept("foo").init_key()
|
||||
foo.bnf = OrderedChoice(ConceptExpression("bar"), ConceptExpression("baz"), StrMatch("qux"))
|
||||
sheerka.set_id_if_needed(foo, False)
|
||||
|
||||
res = BaseNodeParser.get_concepts_by_first_keyword(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_concepts(
|
||||
"one",
|
||||
"two",
|
||||
Concept("twenty", definition="'twenty' (one|two)"),
|
||||
create_new=True
|
||||
)
|
||||
|
||||
bar = Concept("bar").init_key()
|
||||
sheerka.set_id_if_needed(bar, False)
|
||||
sheerka.add_in_cache(bar)
|
||||
|
||||
foo = Concept("foo").init_key()
|
||||
foo.bnf = OrderedChoice(ConceptExpression("one"), ConceptExpression("bar"), StrMatch("qux"))
|
||||
sheerka.set_id_if_needed(foo, False)
|
||||
|
||||
res = BaseNodeParser.get_concepts_by_first_keyword(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_can_resolve_concepts_by_first_keyword(self):
|
||||
sheerka, context, *updated = self.init_concepts(
|
||||
"one",
|
||||
Concept("two", definition="one"),
|
||||
Concept("three", definition="two"),
|
||||
create_new=False
|
||||
)
|
||||
|
||||
concepts_by_first_keywords = {
|
||||
"one": ["1001"],
|
||||
"c:|1001:": ["1002"],
|
||||
"c:|1002:": ["1003"],
|
||||
}
|
||||
|
||||
resolved_ret_val = BaseNodeParser.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, one, two, three, number, foo = self.init_concepts(
|
||||
"one",
|
||||
"two",
|
||||
"three",
|
||||
"number",
|
||||
Concept("foo", definition="number three"),
|
||||
create_new=True # mandatory because set_isa() needs it
|
||||
)
|
||||
|
||||
sheerka.set_isa(context, sheerka.new("one"), number)
|
||||
sheerka.set_isa(context, sheerka.new("two"), number)
|
||||
|
||||
cbfk = BaseNodeParser.get_concepts_by_first_keyword(context, [one, two, three, number, foo]).body
|
||||
|
||||
resolved_ret_val = BaseNodeParser.resolve_concepts_by_first_keyword(context, cbfk)
|
||||
|
||||
assert resolved_ret_val.status
|
||||
assert resolved_ret_val.body == {
|
||||
"one": ["1001", "1005"],
|
||||
"two": ["1002", "1005"],
|
||||
"three": ["1003"],
|
||||
"number": ["1004"],
|
||||
}
|
||||
|
||||
def test_concepts_are_defined_once(self):
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
good = self.create_concept_lite(sheerka, "good")
|
||||
foo = self.create_concept_lite(sheerka, "foo", bnf=ConceptExpression("good"))
|
||||
bar = self.create_concept_lite(sheerka, "bar", bnf=ConceptExpression("good"))
|
||||
baz = self.create_concept_lite(sheerka, "baz", bnf=OrderedChoice(
|
||||
ConceptExpression("foo"),
|
||||
ConceptExpression("bar")))
|
||||
|
||||
concepts_by_first_keywords = BaseNodeParser.get_concepts_by_first_keyword(
|
||||
context, [good, foo, bar, baz]).body
|
||||
|
||||
resolved_ret_val = BaseNodeParser.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_concept_lite(sheerka, "a", bnf=Sequence("one", "two"))
|
||||
b = self.create_concept_lite(sheerka, "b", bnf=Sequence(ConceptExpression("a"), "two"))
|
||||
|
||||
concepts_by_first_keywords = BaseNodeParser.get_concepts_by_first_keyword(
|
||||
context, [a, b]).body
|
||||
|
||||
resolved_ret_val = BaseNodeParser.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 = self.get_sheerka()
|
||||
# good = self.get_concept(sheerka, "good")
|
||||
# foo = self.get_concept(sheerka, "foo", ConceptExpression("bar"))
|
||||
# bar = self.get_concept(sheerka, "bar", ConceptExpression("foo"))
|
||||
#
|
||||
# concepts_by_first_keywords = BaseNodeParser.get_concepts_by_first_keyword(sheerka, [good, foo, bar]).body
|
||||
#
|
||||
# resolved_ret_val = BaseNodeParser.resolve_concepts_by_first_keyword(sheerka, concepts_by_first_keywords)
|
||||
# assert resolved_ret_val.status
|
||||
# assert resolved_ret_val.body == {
|
||||
# "good": ["1001"],
|
||||
# BuiltinConcepts.CHICKEN_AND_EGG: ["1002", "1003"]
|
||||
# }
|
||||
#
|
||||
# def test_i_can_detect_indirect_infinite_recursion(self):
|
||||
# sheerka = self.get_sheerka()
|
||||
# good = self.get_concept(sheerka, "good")
|
||||
# one = self.get_concept(sheerka, "one", ConceptExpression("two"))
|
||||
# two = self.get_concept(sheerka, "two", ConceptExpression("three"))
|
||||
# three = self.get_concept(sheerka, "three", ConceptExpression("two"))
|
||||
#
|
||||
# concepts_by_first_keywords = BaseNodeParser.get_concepts_by_first_keyword(sheerka, [good, one, two, three]).body
|
||||
#
|
||||
# resolved_ret_val = BaseNodeParser.resolve_concepts_by_first_keyword(sheerka, concepts_by_first_keywords)
|
||||
# assert resolved_ret_val.status
|
||||
# assert resolved_ret_val.body == {
|
||||
# "good": ["1001"],
|
||||
# BuiltinConcepts.CHICKEN_AND_EGG: ["1002", "1004", "1003"]
|
||||
# }
|
||||
#
|
||||
# def test_i_can_detect_infinite_recursion_from_ordered_choice(self):
|
||||
# sheerka = self.get_sheerka()
|
||||
# good = self.get_concept(sheerka, "good")
|
||||
# one = self.get_concept(sheerka, "one", ConceptExpression("two"))
|
||||
# two = self.get_concept(sheerka, "two", OrderedChoice(ConceptExpression("one"), ConceptExpression("two")))
|
||||
#
|
||||
# concepts_by_first_keywords = BaseNodeParser.get_concepts_by_first_keyword(sheerka, [good, one, two]).body
|
||||
#
|
||||
# resolved_ret_val = BaseNodeParser.resolve_concepts_by_first_keyword(sheerka, concepts_by_first_keywords)
|
||||
# assert resolved_ret_val.status
|
||||
# assert resolved_ret_val.body == {
|
||||
# "good": ["1001"],
|
||||
# BuiltinConcepts.CHICKEN_AND_EGG: ["1002", "1003"]
|
||||
# }
|
||||
#
|
||||
# def test_i_can_detect_infinite_recursion_with_sequence(self):
|
||||
# sheerka = self.get_sheerka()
|
||||
# good = self.get_concept(sheerka, "good")
|
||||
# one = self.get_concept(sheerka, "one", ConceptExpression("two"))
|
||||
# two = self.get_concept(sheerka, "two", Sequence(StrMatch("yes"), ConceptExpression("one")))
|
||||
#
|
||||
# concepts_by_first_keywords = BaseNodeParser.get_concepts_by_first_keyword(sheerka, [good, one, two]).body
|
||||
#
|
||||
# resolved_ret_val = BaseNodeParser.resolve_concepts_by_first_keyword(sheerka, concepts_by_first_keywords)
|
||||
# assert resolved_ret_val.status
|
||||
# assert resolved_ret_val.body == {
|
||||
# "good": ["1001"],
|
||||
# BuiltinConcepts.CHICKEN_AND_EGG: ["1002", "1003"]
|
||||
# }
|
||||
+662
-1175
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,13 +1,12 @@
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from core.concept import Concept, DEFINITION_TYPE_BNF
|
||||
from core.tokenizer import Tokenizer, TokenKind, LexerError, Token
|
||||
from parsers.BaseNodeParser import cnode
|
||||
from parsers.BaseParser import UnexpectedTokenErrorNode
|
||||
from parsers.BnfParser import BnfParser, UnexpectedEndOfFileError
|
||||
from parsers.BnfNodeParser import StrMatch, Optional, ZeroOrMore, OrderedChoice, Sequence, OneOrMore, \
|
||||
BnfNodeParser, ConceptExpression
|
||||
from parsers.BnfParser import BnfParser, UnexpectedEndOfFileError
|
||||
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
@@ -27,6 +26,12 @@ eof_token = Token(TokenKind.EOF, "", 0, 0, 0)
|
||||
|
||||
class TestBnfParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def init_parser(self, *concepts):
|
||||
sheerka, context, *updated = self.init_concepts(*concepts, singleton=True)
|
||||
parser = BnfParser()
|
||||
|
||||
return sheerka, context, parser, *updated
|
||||
|
||||
@pytest.mark.parametrize("expression, expected", [
|
||||
("'str'", StrMatch("str")),
|
||||
("1", StrMatch("1")),
|
||||
@@ -80,8 +85,9 @@ class TestBnfParser(TestUsingMemoryBasedSheerka):
|
||||
OneOrMore(StrMatch("b"), rule_name="y"), rule_name="z")),
|
||||
])
|
||||
def test_i_can_parse_regex(self, expression, expected):
|
||||
parser = BnfParser()
|
||||
res = parser.parse(self.get_context(), Tokenizer(expression))
|
||||
sheerka, context, parser = self.init_parser()
|
||||
|
||||
res = parser.parse(context, Tokenizer(expression))
|
||||
|
||||
assert not parser.has_error
|
||||
assert res.status
|
||||
@@ -96,16 +102,11 @@ class TestBnfParser(TestUsingMemoryBasedSheerka):
|
||||
("'str' = var", Sequence(StrMatch("str"), StrMatch("="), c("var"))),
|
||||
("'str''='var", Sequence(StrMatch("str"), StrMatch("="), c("var"))),
|
||||
("foo=f", c("foo", "f")),
|
||||
("foo=f 'constant'", Sequence(c("foo", "f"), StrMatch("constant"))),
|
||||
])
|
||||
def test_i_can_parse_regex_with_concept(self, expression, expected):
|
||||
foo = Concept("foo")
|
||||
bar = Concept("bar")
|
||||
var = Concept("var")
|
||||
context = self.get_context()
|
||||
sheerka, context, parser, foo, bar, var = self.init_parser("foo", "bar", "var")
|
||||
|
||||
for c in (foo, bar, var):
|
||||
context.sheerka.add_in_cache(c)
|
||||
parser = BnfParser()
|
||||
res = parser.parse(context, Tokenizer(expression))
|
||||
|
||||
assert not parser.has_error
|
||||
@@ -118,10 +119,9 @@ class TestBnfParser(TestUsingMemoryBasedSheerka):
|
||||
("foo=f", ConceptExpression("foo", rule_name="f")),
|
||||
])
|
||||
def test_i_can_parse_regex_with_concept_when_the_concept_is_still_under_definition(self, expression, expected):
|
||||
context = self.get_context()
|
||||
sheerka, context, parser = self.init_parser()
|
||||
context.obj = ClassWithName("foo")
|
||||
|
||||
parser = BnfParser()
|
||||
res = parser.parse(context, Tokenizer(expression))
|
||||
|
||||
assert not parser.has_error
|
||||
@@ -137,47 +137,43 @@ class TestBnfParser(TestUsingMemoryBasedSheerka):
|
||||
("'name", LexerError("Missing Trailing quote", "'name", 5, 1, 6))
|
||||
])
|
||||
def test_i_can_detect_errors(self, expression, error):
|
||||
parser = BnfParser()
|
||||
res = parser.parse(self.get_context(), Tokenizer(expression))
|
||||
sheerka, context, parser = self.init_parser()
|
||||
|
||||
res = parser.parse(context, Tokenizer(expression))
|
||||
ret_value = res.value.value
|
||||
assert parser.has_error
|
||||
assert not res.status
|
||||
assert ret_value[0] == error
|
||||
|
||||
def test_i_can_use_the_result_of_regex_parsing_to_parse_a_text(self):
|
||||
foo = Concept(name="foo")
|
||||
bar = Concept(name="bar")
|
||||
context = self.get_context()
|
||||
context.sheerka.add_in_cache(foo)
|
||||
context.sheerka.add_in_cache(bar)
|
||||
sheerka, context, regex_parser, foo, bar = self.init_parser("foo", "bar")
|
||||
|
||||
regex_parser = BnfParser()
|
||||
foo_definition = regex_parser.parse(context, "'twenty' | 'thirty'").value.value
|
||||
bar_definition = regex_parser.parse(context, "foo ('one' | 'two')").value.value
|
||||
for concept in [foo, bar]:
|
||||
concept.metadata.definition_type = DEFINITION_TYPE_BNF
|
||||
|
||||
concepts = {bar: bar_definition, foo: foo_definition}
|
||||
concept_parser = BnfNodeParser()
|
||||
concept_parser.initialize(context, concepts)
|
||||
foo.bnf = regex_parser.parse(context, "'twenty' | 'thirty'").value.value
|
||||
bar.bnf = regex_parser.parse(context, "foo ('one' | 'two')").value.value
|
||||
|
||||
res = concept_parser.parse(context, "twenty two")
|
||||
bnf_parser = BnfNodeParser()
|
||||
bnf_parser.init_from_concepts(context, [foo, bar])
|
||||
|
||||
res = bnf_parser.parse(context, "twenty two")
|
||||
assert res.status
|
||||
assert res.value.body == [cnode("bar", 0, 2, "twenty two")]
|
||||
|
||||
res = concept_parser.parse(context, "thirty one")
|
||||
res = bnf_parser.parse(context, "thirty one")
|
||||
assert res.status
|
||||
assert res.value.body == [cnode("bar", 0, 2, "thirty one")]
|
||||
|
||||
res = concept_parser.parse(context, "twenty")
|
||||
res = bnf_parser.parse(context, "twenty")
|
||||
assert res.status
|
||||
assert res.value.body == [cnode("foo", 0, 0, "twenty")]
|
||||
|
||||
def test_i_cannot_parse_when_too_many_concepts(self):
|
||||
foo1 = Concept(name="foo", body="1")
|
||||
foo2 = Concept(name="foo", body="2")
|
||||
context = self.get_context()
|
||||
context.sheerka.cache_by_key["foo"] = [foo1, foo2]
|
||||
sheerka, context, regex_parser, foo1, foo2 = self.init_parser(
|
||||
Concept(name="foo", body="1"),
|
||||
Concept(name="foo", body="2"))
|
||||
|
||||
regex_parser = BnfParser()
|
||||
res = regex_parser.parse(context, "foo")
|
||||
|
||||
assert not res.status
|
||||
@@ -185,9 +181,7 @@ class TestBnfParser(TestUsingMemoryBasedSheerka):
|
||||
assert res.value.body == ('key', 'foo')
|
||||
|
||||
def test_i_cannot_parse_when_unknown_concept(self):
|
||||
context = self.get_context()
|
||||
|
||||
regex_parser = BnfParser()
|
||||
sheerka, context, regex_parser = self.init_parser()
|
||||
res = regex_parser.parse(self.get_context(), "foo")
|
||||
|
||||
assert not res.status
|
||||
|
||||
@@ -1,194 +1,193 @@
|
||||
import ast
|
||||
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import ParserResultConcept, ReturnValueConcept, BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from core.tokenizer import Token, TokenKind, Tokenizer
|
||||
from parsers.BaseNodeParser import SourceCodeNode
|
||||
from parsers.BnfNodeParser import ConceptNode, UnrecognizedTokensNode
|
||||
from parsers.ConceptsWithConceptsParser import ConceptsWithConceptsParser
|
||||
from parsers.MultipleConceptsParser import MultipleConceptsParser
|
||||
from parsers.PythonParser import PythonNode
|
||||
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
multiple_concepts_parser = MultipleConceptsParser()
|
||||
|
||||
|
||||
def ret_val(*args):
|
||||
result = []
|
||||
index = 0
|
||||
source = ""
|
||||
for item in args:
|
||||
if isinstance(item, Concept):
|
||||
tokens = [Token(TokenKind.IDENTIFIER, item.name, 0, 0, 0)]
|
||||
result.append(ConceptNode(item, index, index, tokens, item.name))
|
||||
index += 1
|
||||
source += item.name
|
||||
elif isinstance(item, PythonNode):
|
||||
tokens = list(Tokenizer(item.source))[:-1] # strip trailing EOF
|
||||
result.append(SourceCodeNode(item, index, index + len(tokens) - 1, tokens, item.source))
|
||||
index += len(tokens)
|
||||
source += item.source
|
||||
else:
|
||||
tokens = list(Tokenizer(item))[:-1] # strip trailing EOF
|
||||
result.append(UnrecognizedTokensNode(index, index + len(tokens) - 1, tokens))
|
||||
index += len(tokens)
|
||||
source += item
|
||||
|
||||
return ReturnValueConcept(
|
||||
"who",
|
||||
False,
|
||||
ParserResultConcept(parser=multiple_concepts_parser, value=result, source=source))
|
||||
|
||||
|
||||
class TestConceptsWithConceptsParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def init(self, concepts, inputs):
|
||||
context = self.get_context()
|
||||
for concept in concepts:
|
||||
context.sheerka.create_new_concept(context, concept)
|
||||
|
||||
return context, ret_val(*inputs)
|
||||
|
||||
def execute(self, concepts, inputs):
|
||||
context, input_return_values = self.init(concepts, inputs)
|
||||
|
||||
parser = ConceptsWithConceptsParser()
|
||||
result = parser.parse(context, input_return_values.body)
|
||||
|
||||
wrapper = result.body
|
||||
return_value = result.body.body
|
||||
|
||||
return context, parser, result, wrapper, return_value
|
||||
|
||||
@pytest.mark.parametrize("text, interested", [
|
||||
("not parser result", False),
|
||||
(ParserResultConcept(parser="not multiple_concepts_parser"), False),
|
||||
(ParserResultConcept(parser=multiple_concepts_parser, value=[UnrecognizedTokensNode(0, 0, [])]), True),
|
||||
])
|
||||
def test_not_interested(self, text, interested):
|
||||
context = self.get_context()
|
||||
|
||||
res = ConceptsWithConceptsParser().parse(context, text)
|
||||
if interested:
|
||||
assert res is not None
|
||||
else:
|
||||
assert res is None
|
||||
|
||||
def test_i_can_parse_composition_of_concepts(self):
|
||||
foo = Concept("foo")
|
||||
bar = Concept("bar")
|
||||
plus = Concept("a plus b").def_prop("a").def_prop("b")
|
||||
|
||||
context, parser, result, wrapper, return_value = self.execute([foo, bar, plus], [foo, " plus ", bar])
|
||||
|
||||
assert result.status
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert result.who == wrapper.parser.name
|
||||
assert wrapper.source == "foo plus bar"
|
||||
assert context.sheerka.isinstance(return_value, plus)
|
||||
|
||||
assert return_value.compiled["a"] == foo
|
||||
assert return_value.compiled["b"] == bar
|
||||
|
||||
# sanity check, I can evaluate the result
|
||||
evaluated = context.sheerka.evaluate_concept(self.get_context(context.sheerka, True), return_value)
|
||||
assert evaluated.key == return_value.key
|
||||
assert evaluated.get_prop("a") == foo.init_key()
|
||||
assert evaluated.get_prop("b") == bar.init_key()
|
||||
|
||||
def test_i_can_parse_when_composition_of_source_code(self):
|
||||
plus = Concept("a plus b", body="a + b").def_prop("a").def_prop("b")
|
||||
left = PythonNode("1+1", ast.parse("1+1", mode="eval"))
|
||||
right = PythonNode("2+2", ast.parse("2+2", mode="eval"))
|
||||
context, parser, result, wrapper, return_value = self.execute([plus], [left, " plus ", right])
|
||||
|
||||
assert result.status
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert result.who == wrapper.parser.name
|
||||
assert wrapper.source == "1+1 plus 2+2"
|
||||
assert context.sheerka.isinstance(return_value, plus)
|
||||
|
||||
left_parser_result = ParserResultConcept(parser=parser, source="1+1", value=left)
|
||||
right_parser_result = ParserResultConcept(parser=parser, source="2+2", value=right)
|
||||
assert return_value.compiled["a"] == [ReturnValueConcept(parser.name, True, left_parser_result)]
|
||||
assert return_value.compiled["b"] == [ReturnValueConcept(parser.name, True, right_parser_result)]
|
||||
|
||||
# sanity check, I can evaluate the result
|
||||
evaluated = context.sheerka.evaluate_concept(self.get_context(context.sheerka, True), return_value)
|
||||
assert evaluated.key == return_value.key
|
||||
assert evaluated.get_prop("a") == 2
|
||||
assert evaluated.get_prop("b") == 4
|
||||
assert evaluated.body == 6
|
||||
|
||||
def test_i_can_parse_when_mix_of_concept_and_code(self):
|
||||
plus = Concept("a plus b").def_prop("a").def_prop("b")
|
||||
code = PythonNode("1+1", ast.parse("1+1", mode="eval"))
|
||||
foo = Concept("foo")
|
||||
context, parser, result, wrapper, return_value = self.execute([plus, foo], [foo, " plus ", code])
|
||||
|
||||
assert result.status
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert result.who == wrapper.parser.name
|
||||
assert wrapper.source == "foo plus 1+1"
|
||||
assert context.sheerka.isinstance(return_value, plus)
|
||||
|
||||
code_parser_result = ParserResultConcept(parser=parser, source="1+1", value=code)
|
||||
assert return_value.compiled["a"] == foo
|
||||
assert return_value.compiled["b"] == [ReturnValueConcept(parser.name, True, code_parser_result)]
|
||||
|
||||
# sanity check, I can evaluate the result
|
||||
evaluated = context.sheerka.evaluate_concept(self.get_context(context.sheerka, True), return_value)
|
||||
assert evaluated.key == return_value.key
|
||||
assert evaluated.get_prop("a") == foo.init_key()
|
||||
assert evaluated.get_prop("b") == 2
|
||||
|
||||
def test_i_can_parse_when_multiple_concepts_are_recognized(self):
|
||||
foo = Concept("foo")
|
||||
bar = Concept("bar")
|
||||
plus_1 = Concept("a plus b", body="body1").def_prop("a").def_prop("b")
|
||||
plus_2 = Concept("a plus b", body="body2").def_prop("a").def_prop("b")
|
||||
|
||||
context, input_return_values = self.init([foo, bar, plus_1, plus_2], [foo, " plus ", bar])
|
||||
parser = ConceptsWithConceptsParser()
|
||||
result = parser.parse(context, input_return_values.body)
|
||||
|
||||
assert len(result) == 2
|
||||
|
||||
res = result[0]
|
||||
wrapper = res.value
|
||||
return_value = res.value.value
|
||||
assert res.status
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert res.who == wrapper.parser.name
|
||||
assert wrapper.source == "foo plus bar"
|
||||
assert context.sheerka.isinstance(return_value, plus_1)
|
||||
assert return_value.compiled["a"] == foo
|
||||
assert return_value.compiled["b"] == bar
|
||||
|
||||
res = result[1]
|
||||
wrapper = res.value
|
||||
return_value = res.value.value
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert res.who == wrapper.parser.name
|
||||
assert wrapper.source == "foo plus bar"
|
||||
assert context.sheerka.isinstance(return_value, plus_2)
|
||||
assert return_value.compiled["a"] == foo
|
||||
assert return_value.compiled["b"] == bar
|
||||
|
||||
def test_i_cannot_parse_when_unknown_concept(self):
|
||||
foo = Concept("foo")
|
||||
bar = Concept("bar")
|
||||
|
||||
context, input_return_values = self.init([foo, bar], [foo, " plus ", bar])
|
||||
parser = ConceptsWithConceptsParser()
|
||||
result = parser.parse(context, input_return_values.body)
|
||||
wrapper = result.body
|
||||
return_value = result.body.body
|
||||
|
||||
assert not result.status
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.NOT_FOR_ME)
|
||||
assert result.who == parser.name
|
||||
assert return_value == input_return_values.body.body
|
||||
# import ast
|
||||
#
|
||||
# import pytest
|
||||
#
|
||||
# from core.builtin_concepts import ParserResultConcept, ReturnValueConcept, BuiltinConcepts
|
||||
# from core.concept import Concept
|
||||
# from core.tokenizer import Token, TokenKind, Tokenizer
|
||||
# from parsers.BaseNodeParser import SourceCodeNode, ConceptNode, UnrecognizedTokensNode
|
||||
# from parsers.ConceptsWithConceptsParser import ConceptsWithConceptsParser
|
||||
# from parsers.MultipleConceptsParser import MultipleConceptsParser
|
||||
# from parsers.PythonParser import PythonNode
|
||||
#
|
||||
# from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
#
|
||||
# multiple_concepts_parser = MultipleConceptsParser()
|
||||
#
|
||||
#
|
||||
# def ret_val(*args):
|
||||
# result = []
|
||||
# index = 0
|
||||
# source = ""
|
||||
# for item in args:
|
||||
# if isinstance(item, Concept):
|
||||
# tokens = [Token(TokenKind.IDENTIFIER, item.name, 0, 0, 0)]
|
||||
# result.append(ConceptNode(item, index, index, tokens, item.name))
|
||||
# index += 1
|
||||
# source += item.name
|
||||
# elif isinstance(item, PythonNode):
|
||||
# tokens = list(Tokenizer(item.source))[:-1] # strip trailing EOF
|
||||
# result.append(SourceCodeNode(item, index, index + len(tokens) - 1, tokens, item.source))
|
||||
# index += len(tokens)
|
||||
# source += item.source
|
||||
# else:
|
||||
# tokens = list(Tokenizer(item))[:-1] # strip trailing EOF
|
||||
# result.append(UnrecognizedTokensNode(index, index + len(tokens) - 1, tokens))
|
||||
# index += len(tokens)
|
||||
# source += item
|
||||
#
|
||||
# return ReturnValueConcept(
|
||||
# "who",
|
||||
# False,
|
||||
# ParserResultConcept(parser=multiple_concepts_parser, value=result, source=source))
|
||||
#
|
||||
#
|
||||
# class TestConceptsWithConceptsParser(TestUsingMemoryBasedSheerka):
|
||||
#
|
||||
# def init(self, concepts, inputs):
|
||||
# context = self.get_context()
|
||||
# for concept in concepts:
|
||||
# context.sheerka.create_new_concept(context, concept)
|
||||
#
|
||||
# return context, ret_val(*inputs)
|
||||
#
|
||||
# def execute(self, concepts, inputs):
|
||||
# context, input_return_values = self.init(concepts, inputs)
|
||||
#
|
||||
# parser = ConceptsWithConceptsParser()
|
||||
# result = parser.parse(context, input_return_values.body)
|
||||
#
|
||||
# wrapper = result.body
|
||||
# return_value = result.body.body
|
||||
#
|
||||
# return context, parser, result, wrapper, return_value
|
||||
#
|
||||
# @pytest.mark.parametrize("text, interested", [
|
||||
# ("not parser result", False),
|
||||
# (ParserResultConcept(parser="not multiple_concepts_parser"), False),
|
||||
# (ParserResultConcept(parser=multiple_concepts_parser, value=[UnrecognizedTokensNode(0, 0, [])]), True),
|
||||
# ])
|
||||
# def test_not_interested(self, text, interested):
|
||||
# context = self.get_context()
|
||||
#
|
||||
# res = ConceptsWithConceptsParser().parse(context, text)
|
||||
# if interested:
|
||||
# assert res is not None
|
||||
# else:
|
||||
# assert res is None
|
||||
#
|
||||
# def test_i_can_parse_composition_of_concepts(self):
|
||||
# foo = Concept("foo")
|
||||
# bar = Concept("bar")
|
||||
# plus = Concept("a plus b").def_var("a").def_var("b")
|
||||
#
|
||||
# context, parser, result, wrapper, return_value = self.execute([foo, bar, plus], [foo, " plus ", bar])
|
||||
#
|
||||
# assert result.status
|
||||
# assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
# assert result.who == wrapper.parser.name
|
||||
# assert wrapper.source == "foo plus bar"
|
||||
# assert context.sheerka.isinstance(return_value, plus)
|
||||
#
|
||||
# assert return_value.compiled["a"] == foo
|
||||
# assert return_value.compiled["b"] == bar
|
||||
#
|
||||
# # sanity check, I can evaluate the result
|
||||
# evaluated = context.sheerka.evaluate_concept(self.get_context(context.sheerka, True), return_value)
|
||||
# assert evaluated.key == return_value.key
|
||||
# assert evaluated.get_prop("a") == foo.init_key()
|
||||
# assert evaluated.get_prop("b") == bar.init_key()
|
||||
#
|
||||
# def test_i_can_parse_when_composition_of_source_code(self):
|
||||
# plus = Concept("a plus b", body="a + b").def_var("a").def_var("b")
|
||||
# left = PythonNode("1+1", ast.parse("1+1", mode="eval"))
|
||||
# right = PythonNode("2+2", ast.parse("2+2", mode="eval"))
|
||||
# context, parser, result, wrapper, return_value = self.execute([plus], [left, " plus ", right])
|
||||
#
|
||||
# assert result.status
|
||||
# assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
# assert result.who == wrapper.parser.name
|
||||
# assert wrapper.source == "1+1 plus 2+2"
|
||||
# assert context.sheerka.isinstance(return_value, plus)
|
||||
#
|
||||
# left_parser_result = ParserResultConcept(parser=parser, source="1+1", value=left)
|
||||
# right_parser_result = ParserResultConcept(parser=parser, source="2+2", value=right)
|
||||
# assert return_value.compiled["a"] == [ReturnValueConcept(parser.name, True, left_parser_result)]
|
||||
# assert return_value.compiled["b"] == [ReturnValueConcept(parser.name, True, right_parser_result)]
|
||||
#
|
||||
# # sanity check, I can evaluate the result
|
||||
# evaluated = context.sheerka.evaluate_concept(self.get_context(context.sheerka, True), return_value)
|
||||
# assert evaluated.key == return_value.key
|
||||
# assert evaluated.get_prop("a") == 2
|
||||
# assert evaluated.get_prop("b") == 4
|
||||
# assert evaluated.body == 6
|
||||
#
|
||||
# def test_i_can_parse_when_mix_of_concept_and_code(self):
|
||||
# plus = Concept("a plus b").def_var("a").def_var("b")
|
||||
# code = PythonNode("1+1", ast.parse("1+1", mode="eval"))
|
||||
# foo = Concept("foo")
|
||||
# context, parser, result, wrapper, return_value = self.execute([plus, foo], [foo, " plus ", code])
|
||||
#
|
||||
# assert result.status
|
||||
# assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
# assert result.who == wrapper.parser.name
|
||||
# assert wrapper.source == "foo plus 1+1"
|
||||
# assert context.sheerka.isinstance(return_value, plus)
|
||||
#
|
||||
# code_parser_result = ParserResultConcept(parser=parser, source="1+1", value=code)
|
||||
# assert return_value.compiled["a"] == foo
|
||||
# assert return_value.compiled["b"] == [ReturnValueConcept(parser.name, True, code_parser_result)]
|
||||
#
|
||||
# # sanity check, I can evaluate the result
|
||||
# evaluated = context.sheerka.evaluate_concept(self.get_context(context.sheerka, True), return_value)
|
||||
# assert evaluated.key == return_value.key
|
||||
# assert evaluated.get_prop("a") == foo.init_key()
|
||||
# assert evaluated.get_prop("b") == 2
|
||||
#
|
||||
# def test_i_can_parse_when_multiple_concepts_are_recognized(self):
|
||||
# foo = Concept("foo")
|
||||
# bar = Concept("bar")
|
||||
# plus_1 = Concept("a plus b", body="body1").def_var("a").def_var("b")
|
||||
# plus_2 = Concept("a plus b", body="body2").def_var("a").def_var("b")
|
||||
#
|
||||
# context, input_return_values = self.init([foo, bar, plus_1, plus_2], [foo, " plus ", bar])
|
||||
# parser = ConceptsWithConceptsParser()
|
||||
# result = parser.parse(context, input_return_values.body)
|
||||
#
|
||||
# assert len(result) == 2
|
||||
#
|
||||
# res = result[0]
|
||||
# wrapper = res.value
|
||||
# return_value = res.value.value
|
||||
# assert res.status
|
||||
# assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
# assert res.who == wrapper.parser.name
|
||||
# assert wrapper.source == "foo plus bar"
|
||||
# assert context.sheerka.isinstance(return_value, plus_1)
|
||||
# assert return_value.compiled["a"] == foo
|
||||
# assert return_value.compiled["b"] == bar
|
||||
#
|
||||
# res = result[1]
|
||||
# wrapper = res.value
|
||||
# return_value = res.value.value
|
||||
# assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
# assert res.who == wrapper.parser.name
|
||||
# assert wrapper.source == "foo plus bar"
|
||||
# assert context.sheerka.isinstance(return_value, plus_2)
|
||||
# assert return_value.compiled["a"] == foo
|
||||
# assert return_value.compiled["b"] == bar
|
||||
#
|
||||
# def test_i_cannot_parse_when_unknown_concept(self):
|
||||
# foo = Concept("foo")
|
||||
# bar = Concept("bar")
|
||||
#
|
||||
# context, input_return_values = self.init([foo, bar], [foo, " plus ", bar])
|
||||
# parser = ConceptsWithConceptsParser()
|
||||
# result = parser.parse(context, input_return_values.body)
|
||||
# wrapper = result.body
|
||||
# return_value = result.body.body
|
||||
#
|
||||
# assert not result.status
|
||||
# assert context.sheerka.isinstance(wrapper, BuiltinConcepts.NOT_FOR_ME)
|
||||
# assert result.who == parser.name
|
||||
# assert return_value == input_return_values.body.body
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import pytest
|
||||
import ast
|
||||
|
||||
import pytest
|
||||
from core.builtin_concepts import ParserResultConcept, BuiltinConcepts, ReturnValueConcept
|
||||
from core.concept import Concept, DEFINITION_TYPE_BNF, DEFINITION_TYPE_DEF
|
||||
from parsers.BnfNodeParser import OrderedChoice, StrMatch, ConceptExpression
|
||||
from parsers.PythonParser import PythonParser, PythonNode
|
||||
from core.concept import DEFINITION_TYPE_BNF, DEFINITION_TYPE_DEF
|
||||
from core.tokenizer import Keywords, Tokenizer, LexerError
|
||||
from parsers.BnfNodeParser import OrderedChoice, ConceptExpression, StrMatch
|
||||
from parsers.BnfParser import BnfParser
|
||||
from parsers.DefaultParser import DefaultParser, NameNode, SyntaxErrorNode, CannotHandleErrorNode, IsaConceptNode
|
||||
from parsers.DefaultParser import UnexpectedTokenErrorNode, DefConceptNode
|
||||
from parsers.BnfParser import BnfParser
|
||||
from parsers.PythonParser import PythonParser, PythonNode
|
||||
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
@@ -63,6 +63,11 @@ def get_concept_part(part):
|
||||
|
||||
class TestDefaultParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def init_parser(self, *concepts):
|
||||
sheerka, concept, *updated = self.init_concepts(*concepts, singleton=True)
|
||||
parser = DefaultParser()
|
||||
return sheerka, concept, parser, *updated
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("def concept hello", get_def_concept(name="hello")),
|
||||
("def concept hello ", get_def_concept(name="hello")),
|
||||
@@ -76,8 +81,8 @@ class TestDefaultParser(TestUsingMemoryBasedSheerka):
|
||||
("def concept hello as 1 + 1", get_def_concept(name="hello", body="1 + 1")),
|
||||
])
|
||||
def test_i_can_parse_def_concept(self, text, expected):
|
||||
parser = DefaultParser()
|
||||
res = parser.parse(self.get_context(), text)
|
||||
sheerka, context, parser = self.init_parser()
|
||||
res = parser.parse(context, text)
|
||||
node = res.value.value
|
||||
|
||||
assert res.status
|
||||
@@ -93,8 +98,8 @@ pre isinstance(a, int) and isinstance(b, float)
|
||||
post isinstance(res, int)
|
||||
as res = a + b
|
||||
"""
|
||||
parser = DefaultParser()
|
||||
res = parser.parse(self.get_context(), text)
|
||||
sheerka, context, parser = self.init_parser()
|
||||
res = parser.parse(context, text)
|
||||
return_value = res.value
|
||||
expected_concept = get_def_concept(
|
||||
name="a plus b",
|
||||
@@ -123,8 +128,8 @@ func(a)
|
||||
ast.parse("def func(x):\n return x+1\nfunc(a)", mode="exec"))
|
||||
)
|
||||
|
||||
parser = DefaultParser()
|
||||
res = parser.parse(self.get_context(), text)
|
||||
sheerka, context, parser = self.init_parser()
|
||||
res = parser.parse(context, text)
|
||||
return_value = res.value
|
||||
|
||||
assert res.status
|
||||
@@ -146,8 +151,8 @@ def concept add one to a as:
|
||||
ast.parse("def func(x):\n return x+1\nfunc(a)", mode="exec"))
|
||||
)
|
||||
|
||||
parser = DefaultParser()
|
||||
res = parser.parse(self.get_context(), text)
|
||||
sheerka, context, parser = self.init_parser()
|
||||
res = parser.parse(context, text)
|
||||
return_value = res.value
|
||||
|
||||
assert res.status
|
||||
@@ -162,8 +167,8 @@ def func(x):
|
||||
func(a)
|
||||
"""
|
||||
|
||||
parser = DefaultParser()
|
||||
res = parser.parse(self.get_context(), text)
|
||||
sheerka, context, parser = self.init_parser()
|
||||
res = parser.parse(context, text)
|
||||
return_value = res.value
|
||||
|
||||
assert not res.status
|
||||
@@ -178,9 +183,7 @@ def concept add one to a as
|
||||
return x+1
|
||||
func(a)
|
||||
"""
|
||||
context = self.get_context()
|
||||
|
||||
parser = DefaultParser()
|
||||
sheerka, context, parser = self.init_parser()
|
||||
res = parser.parse(context, text)
|
||||
return_value = res.value
|
||||
|
||||
@@ -190,8 +193,8 @@ def concept add one to a as
|
||||
def test_name_is_mandatory(self):
|
||||
text = "def concept as 'hello'"
|
||||
|
||||
parser = DefaultParser()
|
||||
res = parser.parse(self.get_context(), text)
|
||||
sheerka, context, parser = self.init_parser()
|
||||
res = parser.parse(context, text)
|
||||
return_value = res.value
|
||||
|
||||
assert not res.status
|
||||
@@ -203,8 +206,8 @@ def concept add one to a as
|
||||
text = "def hello as a where b pre c post d"
|
||||
|
||||
expected_concept = get_def_concept(name="hello", body="a", where="b", pre="c", post="d")
|
||||
parser = DefaultParser()
|
||||
res = parser.parse(self.get_context(), text)
|
||||
sheerka, context, parser = self.init_parser()
|
||||
res = parser.parse(context, text)
|
||||
return_value = res.value
|
||||
|
||||
assert not res.status
|
||||
@@ -221,10 +224,7 @@ def concept add one to a as
|
||||
"def concept hello as 1+"
|
||||
])
|
||||
def test_i_can_detect_error_in_declaration(self, text):
|
||||
context = self.get_context()
|
||||
sheerka = context.sheerka
|
||||
|
||||
parser = DefaultParser()
|
||||
sheerka, context, parser = self.init_parser()
|
||||
res = parser.parse(context, text)
|
||||
return_value = res.value
|
||||
|
||||
@@ -234,21 +234,18 @@ def concept add one to a as
|
||||
def test_new_line_is_not_allowed_in_the_name(self):
|
||||
text = "def concept hello \n my friend as 'hello'"
|
||||
|
||||
parser = DefaultParser()
|
||||
res = parser.parse(self.get_context(), text)
|
||||
sheerka, context, parser = self.init_parser()
|
||||
res = parser.parse(context, text)
|
||||
return_value = res.value
|
||||
|
||||
assert not res.status
|
||||
assert return_value.value == [SyntaxErrorNode([], "Newline are not allowed in name.")]
|
||||
|
||||
def test_i_can_parse_def_concept_from_bnf(self):
|
||||
context = self.get_context()
|
||||
a_concept = Concept("a_concept")
|
||||
context.sheerka.add_in_cache(a_concept)
|
||||
|
||||
text = "def concept name from bnf a_concept | 'a_string' as __definition[0]"
|
||||
parser = DefaultParser()
|
||||
sheerka, context, parser, a_concept = self.init_parser("a_concept")
|
||||
res = parser.parse(context, text)
|
||||
|
||||
node = res.value.value
|
||||
definition = OrderedChoice(ConceptExpression(a_concept, rule_name="a_concept"), StrMatch("a_string"))
|
||||
parser_result = ParserResultConcept(BnfParser(), "a_concept | 'a_string'", None, definition, definition)
|
||||
@@ -261,12 +258,8 @@ def concept add one to a as
|
||||
assert node == expected
|
||||
|
||||
def test_i_can_parse_def_concept_where_bnf_references_itself(self):
|
||||
context = self.get_context()
|
||||
a_concept = Concept("a_concept")
|
||||
context.sheerka.add_in_cache(a_concept)
|
||||
|
||||
text = "def concept name from bnf 'a' + name?"
|
||||
parser = DefaultParser()
|
||||
sheerka, context, parser, a_concept = self.init_parser("a_concept")
|
||||
parser.parse(context, text)
|
||||
|
||||
assert not parser.has_error
|
||||
@@ -277,9 +270,8 @@ def concept add one to a as
|
||||
"def concept name from as here is my body"
|
||||
])
|
||||
def test_i_can_detect_empty_bnf_declaration(self, text):
|
||||
|
||||
parser = DefaultParser()
|
||||
res = parser.parse(self.get_context(), text)
|
||||
sheerka, context, parser = self.init_parser()
|
||||
res = parser.parse(context, text)
|
||||
|
||||
assert not res.status
|
||||
assert res.value.value[0] == SyntaxErrorNode([], "Empty declaration")
|
||||
@@ -288,8 +280,8 @@ def concept add one to a as
|
||||
"def concept addition from a plus b as a + b",
|
||||
"def concept addition from def a plus b as a + b"])
|
||||
def test_i_can_def_concept_from_definition(self, text):
|
||||
parser = DefaultParser()
|
||||
res = parser.parse(self.get_context(), text)
|
||||
sheerka, context, parser = self.init_parser()
|
||||
res = parser.parse(context, text)
|
||||
expected = get_def_concept("addition", definition="a plus b", body="a + b")
|
||||
node = res.value.value
|
||||
|
||||
@@ -301,8 +293,7 @@ def concept add one to a as
|
||||
|
||||
def test_i_can_detect_not_for_me(self):
|
||||
text = "hello world"
|
||||
context = self.get_context()
|
||||
parser = DefaultParser()
|
||||
sheerka, context, parser = self.init_parser()
|
||||
res = parser.parse(context, text)
|
||||
|
||||
assert not res.status
|
||||
@@ -310,9 +301,9 @@ def concept add one to a as
|
||||
assert isinstance(res.value.body[0], CannotHandleErrorNode)
|
||||
|
||||
def test_i_can_parse_is_a(self):
|
||||
parser = DefaultParser()
|
||||
text = "the name of my 'concept' isa the name of the set"
|
||||
res = parser.parse(self.get_context(), text)
|
||||
sheerka, context, parser = self.init_parser()
|
||||
res = parser.parse(context, text)
|
||||
expected = IsaConceptNode([],
|
||||
concept=NameNode(list(Tokenizer("the name of my 'concept'"))),
|
||||
set=NameNode(list(Tokenizer("the name of the set"))))
|
||||
@@ -331,8 +322,8 @@ def concept add one to a as
|
||||
"def concept_name"
|
||||
])
|
||||
def test_i_cannot_parse_invalid_entries(self, text):
|
||||
parser = DefaultParser()
|
||||
res = parser.parse(self.get_context(), text)
|
||||
sheerka, context, parser = self.init_parser()
|
||||
res = parser.parse(context, text)
|
||||
|
||||
assert not res.status
|
||||
assert isinstance(res.body, ParserResultConcept)
|
||||
@@ -347,8 +338,8 @@ def concept add one to a as
|
||||
("def concept c::", "Concept identifiers not found", ""),
|
||||
])
|
||||
def test_i_cannot_parse_when_tokenizer_fails(self, text, error_msg, error_text):
|
||||
parser = DefaultParser()
|
||||
res = parser.parse(self.get_context(), text)
|
||||
sheerka, context, parser = self.init_parser()
|
||||
res = parser.parse(context, text)
|
||||
|
||||
assert not res.status
|
||||
assert isinstance(res.body, ParserResultConcept)
|
||||
@@ -357,10 +348,8 @@ def concept add one to a as
|
||||
assert res.body.body[0].text == error_text
|
||||
|
||||
def test_i_cannot_parse_bnf_definition_referencing_unknown_concept(self):
|
||||
context = self.get_context()
|
||||
text = "def concept name from bnf unknown"
|
||||
|
||||
parser = DefaultParser()
|
||||
sheerka, context, parser = self.init_parser()
|
||||
res = parser.parse(context, text)
|
||||
|
||||
assert not res.status
|
||||
|
||||
@@ -6,19 +6,19 @@ from parsers.ExactConceptParser import ExactConceptParser
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
def metadata_prop(concept, prop_name):
|
||||
for name, value in concept.metadata.props:
|
||||
def variable_def(concept, prop_name):
|
||||
for name, value in concept.metadata.variables:
|
||||
if name == prop_name:
|
||||
return value
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def get_concept(name, variables):
|
||||
def get_concept(name, variables=None):
|
||||
c = Concept(name=name)
|
||||
if variables:
|
||||
for v in variables:
|
||||
c.def_prop(v)
|
||||
c.def_var(v)
|
||||
c.init_key()
|
||||
return c
|
||||
|
||||
@@ -50,9 +50,9 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
|
||||
# TODO: the last tuple is not possible, so the algo can be improved
|
||||
|
||||
def test_i_can_recognize_a_simple_concept(self):
|
||||
context = self.get_context()
|
||||
concept = get_concept("hello world", [])
|
||||
context.sheerka.add_in_cache(concept)
|
||||
sheerka = self.get_sheerka(singleton=True)
|
||||
context = self.get_context(sheerka)
|
||||
concept = self.create_concept_lite(sheerka, "hello world")
|
||||
|
||||
source = "hello world"
|
||||
results = ExactConceptParser().parse(context, source)
|
||||
@@ -64,9 +64,10 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
|
||||
assert not concept_found.metadata.need_validation
|
||||
|
||||
def test_i_can_recognize_concepts_defined_several_times(self):
|
||||
context = self.get_context()
|
||||
context.sheerka.add_in_cache(get_concept("hello world", []))
|
||||
context.sheerka.add_in_cache(get_concept("hello a", ["a"]))
|
||||
sheerka = self.get_sheerka(singleton=True)
|
||||
context = self.get_context(sheerka)
|
||||
self.create_concept_lite(sheerka, "hello world")
|
||||
self.create_concept_lite(sheerka, "hello a", variables=["a"])
|
||||
|
||||
source = "hello world"
|
||||
results = ExactConceptParser().parse(context, source)
|
||||
@@ -76,7 +77,7 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert results[0].status
|
||||
assert results[0].value.value.name == "hello a"
|
||||
assert metadata_prop(results[0].value.value, "a") == "world"
|
||||
assert variable_def(results[0].value.value, "a") == "world"
|
||||
assert results[0].value.value.metadata.need_validation
|
||||
|
||||
assert results[1].status
|
||||
@@ -84,9 +85,10 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
|
||||
assert not results[1].value.value.metadata.need_validation
|
||||
|
||||
def test_i_can_recognize_a_concept_with_variables(self):
|
||||
context = self.get_context()
|
||||
concept = get_concept("a + b", ["a", "b"])
|
||||
context.sheerka.add_in_cache(concept)
|
||||
sheerka = self.get_sheerka(singleton=True)
|
||||
context = self.get_context(sheerka)
|
||||
concept = self.create_concept_lite(sheerka, "a + b", ["a", "b"])
|
||||
|
||||
source = "10 + 5"
|
||||
results = ExactConceptParser().parse(context, source)
|
||||
|
||||
@@ -95,46 +97,47 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
concept_found = results[0].value.value
|
||||
assert concept_found.key == concept.key
|
||||
assert metadata_prop(concept_found, "a") == "10"
|
||||
assert metadata_prop(concept_found, "b") == "5"
|
||||
assert variable_def(concept_found, "a") == "10"
|
||||
assert variable_def(concept_found, "b") == "5"
|
||||
assert concept_found.metadata.need_validation
|
||||
|
||||
def test_i_can_recognize_a_concept_with_duplicate_variables(self):
|
||||
context = self.get_context()
|
||||
concept = get_concept("a + b + a", ["a", "b"])
|
||||
context.sheerka.cache_by_key[concept.key] = concept
|
||||
sheerka = self.get_sheerka(singleton=True)
|
||||
context = self.get_context(sheerka)
|
||||
concept = self.create_concept_lite(sheerka, "a + b + a", ["a", "b"])
|
||||
|
||||
source = "10 + 5 + 10"
|
||||
results = ExactConceptParser().parse(context, source)
|
||||
results = ExactConceptParser(max_word_size=5).parse(context, source)
|
||||
|
||||
assert len(results) == 1
|
||||
assert results[0].status
|
||||
|
||||
concept_found = results[0].value.value
|
||||
assert concept_found.key == concept.key
|
||||
assert metadata_prop(concept_found, "a") == "10"
|
||||
assert metadata_prop(concept_found, "b") == "5"
|
||||
assert variable_def(concept_found, "a") == "10"
|
||||
assert variable_def(concept_found, "b") == "5"
|
||||
assert concept_found.metadata.need_validation
|
||||
|
||||
def test_i_can_manage_unknown_concept(self):
|
||||
context = self.get_context()
|
||||
source = "def concept hello world" # this is not a concept by itself
|
||||
context = self.get_context(self.get_sheerka(singleton=True))
|
||||
source = "def concept hello" # this is not a concept by itself
|
||||
res = ExactConceptParser().parse(context, source)
|
||||
|
||||
assert not res.status
|
||||
assert context.sheerka.isinstance(res.value, BuiltinConcepts.UNKNOWN_CONCEPT)
|
||||
assert res.value.body == "def concept hello world"
|
||||
assert res.value.body == "def concept hello"
|
||||
|
||||
def test_i_can_detect_concepts_too_long(self):
|
||||
context = self.get_context()
|
||||
source = "a very very long concept that cannot be an unique one"
|
||||
context = self.get_context(self.get_sheerka(singleton=True))
|
||||
source = "a very very long concept"
|
||||
res = ExactConceptParser().parse(context, source)
|
||||
|
||||
assert not res.status
|
||||
assert context.sheerka.isinstance(res.value, BuiltinConcepts.CONCEPT_TOO_LONG)
|
||||
assert res.value.body == "a very very long concept that cannot be an unique one"
|
||||
assert res.value.body == "a very very long concept"
|
||||
|
||||
def test_i_can_detect_concept_from_tokens(self):
|
||||
context = self.get_context()
|
||||
context = self.get_context(self.get_sheerka(singleton=True))
|
||||
concept = get_concept("hello world", [])
|
||||
context.sheerka.add_in_cache(concept)
|
||||
|
||||
|
||||
@@ -1,216 +1,216 @@
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import ParserResultConcept, BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from core.tokenizer import Tokenizer, TokenKind, Token
|
||||
from parsers.BaseNodeParser import cnode, scnode, utnode, SourceCodeNode
|
||||
from parsers.BnfNodeParser import BnfNodeParser, ConceptNode, Sequence
|
||||
from parsers.MultipleConceptsParser import MultipleConceptsParser
|
||||
from parsers.PythonParser import PythonNode
|
||||
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
def get_return_value(context, grammar, expression):
|
||||
parser = BnfNodeParser()
|
||||
parser.initialize(context, grammar)
|
||||
|
||||
ret_val = parser.parse(context, expression)
|
||||
assert not ret_val.status
|
||||
return ret_val
|
||||
|
||||
|
||||
class TestMultipleConceptsParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def init(self, concepts, grammar, expression):
|
||||
context = self.get_context()
|
||||
for c in concepts:
|
||||
context.sheerka.create_new_concept(context, c)
|
||||
return_value = get_return_value(context, grammar, expression)
|
||||
|
||||
return context, return_value
|
||||
|
||||
def test_not_interested_if_not_parser_result(self):
|
||||
context = self.get_context()
|
||||
text = "not parser result"
|
||||
|
||||
res = MultipleConceptsParser().parse(context, text)
|
||||
assert res is None
|
||||
|
||||
def test_not_interested_if_not_from_concept_lexer_parser(self):
|
||||
context = self.get_context()
|
||||
text = ParserResultConcept(parser="not concept lexer", value="some value")
|
||||
|
||||
res = MultipleConceptsParser().parse(context, text)
|
||||
assert res is None
|
||||
|
||||
def test_i_can_parse_exact_concepts(self):
|
||||
foo = Concept("foo", body="'foo'")
|
||||
bar = Concept("bar", body="'bar'")
|
||||
baz = Concept("baz", body="'baz'")
|
||||
grammar = {}
|
||||
context, return_value = self.init([foo, bar, baz], grammar, "bar foo baz")
|
||||
|
||||
parser = MultipleConceptsParser()
|
||||
ret_val = parser.parse(context, return_value.body)
|
||||
|
||||
assert ret_val.status
|
||||
assert ret_val.who == parser.name
|
||||
assert context.sheerka.isinstance(ret_val.value, BuiltinConcepts.PARSER_RESULT)
|
||||
assert ret_val.value.value == [
|
||||
ConceptNode(bar, 0, 0, source="bar"),
|
||||
ConceptNode(foo, 2, 2, source="foo"),
|
||||
ConceptNode(baz, 4, 4, source="baz")]
|
||||
assert ret_val.value.source == "bar foo baz"
|
||||
|
||||
def test_i_can_parse_when_ending_with_bnf(self):
|
||||
foo = Concept("foo", body="'foo'")
|
||||
bar = Concept("bar", body="'bar'")
|
||||
grammar = {foo: Sequence("foo1", "foo2", "foo3")}
|
||||
context, return_value = self.init([foo, bar], grammar, "bar foo1 foo2 foo3")
|
||||
|
||||
parser = MultipleConceptsParser()
|
||||
ret_val = parser.parse(context, return_value.body)
|
||||
|
||||
assert ret_val.status
|
||||
assert ret_val.who == parser.name
|
||||
assert context.sheerka.isinstance(ret_val.value, BuiltinConcepts.PARSER_RESULT)
|
||||
assert ret_val.value.value == [cnode("bar", 0, 0, "bar"), cnode("foo", 2, 6, "foo1 foo2 foo3")]
|
||||
assert ret_val.value.source == "bar foo1 foo2 foo3"
|
||||
|
||||
def test_i_can_parse_when_starting_with_bnf(self):
|
||||
foo = Concept("foo", body="'foo'")
|
||||
bar = Concept("bar", body="'bar'")
|
||||
grammar = {foo: Sequence("foo1", "foo2", "foo3")}
|
||||
context, return_value = self.init([foo, bar], grammar, "foo1 foo2 foo3 bar")
|
||||
|
||||
parser = MultipleConceptsParser()
|
||||
ret_val = parser.parse(context, return_value.body)
|
||||
|
||||
assert ret_val.status
|
||||
assert ret_val.who == parser.name
|
||||
assert context.sheerka.isinstance(ret_val.value, BuiltinConcepts.PARSER_RESULT)
|
||||
assert ret_val.value.value == [cnode("foo", 0, 4, "foo1 foo2 foo3"), cnode("bar", 6, 6, "bar")]
|
||||
assert ret_val.value.source == "foo1 foo2 foo3 bar"
|
||||
|
||||
def test_i_can_parse_when_concept_are_mixed(self):
|
||||
foo = Concept("foo")
|
||||
bar = Concept("bar")
|
||||
baz = Concept("baz")
|
||||
grammar = {foo: Sequence("foo1", "foo2", "foo3")}
|
||||
context, return_value = self.init([foo, bar, baz], grammar, "baz foo1 foo2 foo3 bar")
|
||||
|
||||
parser = MultipleConceptsParser()
|
||||
ret_val = parser.parse(context, return_value.body)
|
||||
|
||||
assert ret_val.status
|
||||
assert ret_val.who == parser.name
|
||||
assert context.sheerka.isinstance(ret_val.value, BuiltinConcepts.PARSER_RESULT)
|
||||
assert ret_val.value.value == [
|
||||
cnode("baz", 0, 0, "baz"),
|
||||
cnode("foo", 2, 6, "foo1 foo2 foo3"),
|
||||
cnode("bar", 8, 8, "bar")]
|
||||
assert ret_val.value.source == "baz foo1 foo2 foo3 bar"
|
||||
|
||||
def test_i_can_parse_when_multiple_concepts_are_matching(self):
|
||||
foo = Concept("foo")
|
||||
bar = Concept("bar", body="bar1")
|
||||
baz = Concept("bar", body="bar2")
|
||||
grammar = {foo: "foo"}
|
||||
context, return_value = self.init([foo, bar, baz], grammar, "foo bar")
|
||||
|
||||
parser = MultipleConceptsParser()
|
||||
ret_val = parser.parse(context, return_value.body)
|
||||
|
||||
assert len(ret_val) == 2
|
||||
assert ret_val[0].status
|
||||
assert ret_val[0].value.value == [cnode("foo", 0, 0, "foo"), cnode("bar", 2, 2, "bar")]
|
||||
assert ret_val[0].value.source == "foo bar"
|
||||
assert ret_val[0].value.value[1].concept.metadata.body == "bar1"
|
||||
|
||||
assert ret_val[1].status
|
||||
assert ret_val[1].value.value == [cnode("foo", 0, 0, "foo"), cnode("bar", 2, 2, "bar")]
|
||||
assert ret_val[1].value.source == "foo bar"
|
||||
assert ret_val[1].value.value[1].concept.metadata.body == "bar2"
|
||||
|
||||
def test_i_can_parse_when_source_code(self):
|
||||
foo = Concept("foo")
|
||||
grammar = {foo: "foo"}
|
||||
context, return_value = self.init([foo], grammar, "1 foo")
|
||||
|
||||
parser = MultipleConceptsParser()
|
||||
ret_val = parser.parse(context, return_value.body)
|
||||
wrapper = ret_val.value
|
||||
value = ret_val.value.value
|
||||
|
||||
assert ret_val.status
|
||||
assert ret_val.who == parser.name
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert wrapper.source == "1 foo"
|
||||
assert value == [
|
||||
scnode(0, 1, "1 "),
|
||||
cnode("foo", 2, 2, "foo")]
|
||||
|
||||
def test_i_cannot_parse_when_unrecognized_token(self):
|
||||
twenty_two = Concept("twenty two")
|
||||
one = Concept("one")
|
||||
grammar = {twenty_two: Sequence("twenty", "two")}
|
||||
context, return_value = self.init([twenty_two, one], grammar, "twenty two + one")
|
||||
|
||||
parser = MultipleConceptsParser()
|
||||
ret_val = parser.parse(context, return_value.body)
|
||||
|
||||
assert not ret_val.status
|
||||
assert ret_val.who == parser.name
|
||||
assert context.sheerka.isinstance(ret_val.value, BuiltinConcepts.PARSER_RESULT)
|
||||
assert ret_val.value.value == [
|
||||
cnode("twenty two", 0, 2, "twenty two"),
|
||||
utnode(3, 5, " + "),
|
||||
cnode("one", 6, 6, "one")
|
||||
]
|
||||
assert ret_val.value.source == "twenty two + one"
|
||||
|
||||
def test_i_cannot_parse_when_unknown_concepts(self):
|
||||
twenty_two = Concept("twenty two")
|
||||
one = Concept("one")
|
||||
grammar = {twenty_two: Sequence("twenty", "two")}
|
||||
context, return_value = self.init([twenty_two, one], grammar, "twenty two plus one")
|
||||
|
||||
parser = MultipleConceptsParser()
|
||||
ret_val = parser.parse(context, return_value.body)
|
||||
|
||||
assert not ret_val.status
|
||||
assert ret_val.who == parser.name
|
||||
assert context.sheerka.isinstance(ret_val.value, BuiltinConcepts.PARSER_RESULT)
|
||||
assert ret_val.value.value == [
|
||||
cnode("twenty two", 0, 2, "twenty two"),
|
||||
utnode(3, 5, " plus "),
|
||||
cnode("one", 6, 6, "one")
|
||||
]
|
||||
assert ret_val.value.source == "twenty two plus one"
|
||||
|
||||
@pytest.mark.parametrize("text, expected_source, expected_end", [
|
||||
("True", "True", 0),
|
||||
("1 == 1", "1 == 1", 4),
|
||||
("1!xdf", "1", 0),
|
||||
("1", "1", 0),
|
||||
])
|
||||
def test_i_can_get_source_code_node(self, text, expected_source, expected_end):
|
||||
tokens = list(Tokenizer(text))[:-1] # strip trailing EOF
|
||||
|
||||
start_index = 5 # a random number different of zero
|
||||
res = MultipleConceptsParser().get_source_code_node(self.get_context(), start_index, tokens)
|
||||
|
||||
assert isinstance(res, SourceCodeNode)
|
||||
assert isinstance(res.node, PythonNode)
|
||||
assert res.source == expected_source
|
||||
assert res.start == start_index
|
||||
assert res.end == start_index + expected_end
|
||||
|
||||
def test_i_cannot_parse_null_text(self):
|
||||
res = MultipleConceptsParser().get_source_code_node(self.get_context(), 0, [])
|
||||
assert res is None
|
||||
|
||||
eof = Token(TokenKind.EOF, "", 0, 0, 0)
|
||||
res = MultipleConceptsParser().get_source_code_node(self.get_context(), 0, [eof])
|
||||
assert res is None
|
||||
# import pytest
|
||||
#
|
||||
# from core.builtin_concepts import ParserResultConcept, BuiltinConcepts
|
||||
# from core.concept import Concept
|
||||
# from core.tokenizer import Tokenizer, TokenKind, Token
|
||||
# from parsers.BaseNodeParser import cnode, scnode, utnode, SourceCodeNode, ConceptNode
|
||||
# from parsers.BnfNodeParser import BnfNodeParser, Sequence
|
||||
# from parsers.MultipleConceptsParser import MultipleConceptsParser
|
||||
# from parsers.PythonParser import PythonNode
|
||||
#
|
||||
# from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
#
|
||||
#
|
||||
# def get_return_value(context, grammar, expression):
|
||||
# parser = BnfNodeParser()
|
||||
# parser.initialize(context, grammar)
|
||||
#
|
||||
# ret_val = parser.parse(context, expression)
|
||||
# assert not ret_val.status
|
||||
# return ret_val
|
||||
#
|
||||
#
|
||||
# class TestMultipleConceptsParser(TestUsingMemoryBasedSheerka):
|
||||
#
|
||||
# def init(self, concepts, grammar, expression):
|
||||
# context = self.get_context()
|
||||
# for c in concepts:
|
||||
# context.sheerka.create_new_concept(context, c)
|
||||
# return_value = get_return_value(context, grammar, expression)
|
||||
#
|
||||
# return context, return_value
|
||||
#
|
||||
# def test_not_interested_if_not_parser_result(self):
|
||||
# context = self.get_context()
|
||||
# text = "not parser result"
|
||||
#
|
||||
# res = MultipleConceptsParser().parse(context, text)
|
||||
# assert res is None
|
||||
#
|
||||
# def test_not_interested_if_not_from_concept_lexer_parser(self):
|
||||
# context = self.get_context()
|
||||
# text = ParserResultConcept(parser="not concept lexer", value="some value")
|
||||
#
|
||||
# res = MultipleConceptsParser().parse(context, text)
|
||||
# assert res is None
|
||||
#
|
||||
# def test_i_can_parse_exact_concepts(self):
|
||||
# foo = Concept("foo", body="'foo'")
|
||||
# bar = Concept("bar", body="'bar'")
|
||||
# baz = Concept("baz", body="'baz'")
|
||||
# grammar = {}
|
||||
# context, return_value = self.init([foo, bar, baz], grammar, "bar foo baz")
|
||||
#
|
||||
# parser = MultipleConceptsParser()
|
||||
# ret_val = parser.parse(context, return_value.body)
|
||||
#
|
||||
# assert ret_val.status
|
||||
# assert ret_val.who == parser.name
|
||||
# assert context.sheerka.isinstance(ret_val.value, BuiltinConcepts.PARSER_RESULT)
|
||||
# assert ret_val.value.value == [
|
||||
# ConceptNode(bar, 0, 0, source="bar"),
|
||||
# ConceptNode(foo, 2, 2, source="foo"),
|
||||
# ConceptNode(baz, 4, 4, source="baz")]
|
||||
# assert ret_val.value.source == "bar foo baz"
|
||||
#
|
||||
# def test_i_can_parse_when_ending_with_bnf(self):
|
||||
# foo = Concept("foo", body="'foo'")
|
||||
# bar = Concept("bar", body="'bar'")
|
||||
# grammar = {foo: Sequence("foo1", "foo2", "foo3")}
|
||||
# context, return_value = self.init([foo, bar], grammar, "bar foo1 foo2 foo3")
|
||||
#
|
||||
# parser = MultipleConceptsParser()
|
||||
# ret_val = parser.parse(context, return_value.body)
|
||||
#
|
||||
# assert ret_val.status
|
||||
# assert ret_val.who == parser.name
|
||||
# assert context.sheerka.isinstance(ret_val.value, BuiltinConcepts.PARSER_RESULT)
|
||||
# assert ret_val.value.value == [cnode("bar", 0, 0, "bar"), cnode("foo", 2, 6, "foo1 foo2 foo3")]
|
||||
# assert ret_val.value.source == "bar foo1 foo2 foo3"
|
||||
#
|
||||
# def test_i_can_parse_when_starting_with_bnf(self):
|
||||
# foo = Concept("foo", body="'foo'")
|
||||
# bar = Concept("bar", body="'bar'")
|
||||
# grammar = {foo: Sequence("foo1", "foo2", "foo3")}
|
||||
# context, return_value = self.init([foo, bar], grammar, "foo1 foo2 foo3 bar")
|
||||
#
|
||||
# parser = MultipleConceptsParser()
|
||||
# ret_val = parser.parse(context, return_value.body)
|
||||
#
|
||||
# assert ret_val.status
|
||||
# assert ret_val.who == parser.name
|
||||
# assert context.sheerka.isinstance(ret_val.value, BuiltinConcepts.PARSER_RESULT)
|
||||
# assert ret_val.value.value == [cnode("foo", 0, 4, "foo1 foo2 foo3"), cnode("bar", 6, 6, "bar")]
|
||||
# assert ret_val.value.source == "foo1 foo2 foo3 bar"
|
||||
#
|
||||
# def test_i_can_parse_when_concept_are_mixed(self):
|
||||
# foo = Concept("foo")
|
||||
# bar = Concept("bar")
|
||||
# baz = Concept("baz")
|
||||
# grammar = {foo: Sequence("foo1", "foo2", "foo3")}
|
||||
# context, return_value = self.init([foo, bar, baz], grammar, "baz foo1 foo2 foo3 bar")
|
||||
#
|
||||
# parser = MultipleConceptsParser()
|
||||
# ret_val = parser.parse(context, return_value.body)
|
||||
#
|
||||
# assert ret_val.status
|
||||
# assert ret_val.who == parser.name
|
||||
# assert context.sheerka.isinstance(ret_val.value, BuiltinConcepts.PARSER_RESULT)
|
||||
# assert ret_val.value.value == [
|
||||
# cnode("baz", 0, 0, "baz"),
|
||||
# cnode("foo", 2, 6, "foo1 foo2 foo3"),
|
||||
# cnode("bar", 8, 8, "bar")]
|
||||
# assert ret_val.value.source == "baz foo1 foo2 foo3 bar"
|
||||
#
|
||||
# def test_i_can_parse_when_multiple_concepts_are_matching(self):
|
||||
# foo = Concept("foo")
|
||||
# bar = Concept("bar", body="bar1")
|
||||
# baz = Concept("bar", body="bar2")
|
||||
# grammar = {foo: "foo"}
|
||||
# context, return_value = self.init([foo, bar, baz], grammar, "foo bar")
|
||||
#
|
||||
# parser = MultipleConceptsParser()
|
||||
# ret_val = parser.parse(context, return_value.body)
|
||||
#
|
||||
# assert len(ret_val) == 2
|
||||
# assert ret_val[0].status
|
||||
# assert ret_val[0].value.value == [cnode("foo", 0, 0, "foo"), cnode("bar", 2, 2, "bar")]
|
||||
# assert ret_val[0].value.source == "foo bar"
|
||||
# assert ret_val[0].value.value[1].concept.metadata.body == "bar1"
|
||||
#
|
||||
# assert ret_val[1].status
|
||||
# assert ret_val[1].value.value == [cnode("foo", 0, 0, "foo"), cnode("bar", 2, 2, "bar")]
|
||||
# assert ret_val[1].value.source == "foo bar"
|
||||
# assert ret_val[1].value.value[1].concept.metadata.body == "bar2"
|
||||
#
|
||||
# def test_i_can_parse_when_source_code(self):
|
||||
# foo = Concept("foo")
|
||||
# grammar = {foo: "foo"}
|
||||
# context, return_value = self.init([foo], grammar, "1 foo")
|
||||
#
|
||||
# parser = MultipleConceptsParser()
|
||||
# ret_val = parser.parse(context, return_value.body)
|
||||
# wrapper = ret_val.value
|
||||
# value = ret_val.value.value
|
||||
#
|
||||
# assert ret_val.status
|
||||
# assert ret_val.who == parser.name
|
||||
# assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
# assert wrapper.source == "1 foo"
|
||||
# assert value == [
|
||||
# scnode(0, 1, "1 "),
|
||||
# cnode("foo", 2, 2, "foo")]
|
||||
#
|
||||
# def test_i_cannot_parse_when_unrecognized_token(self):
|
||||
# twenty_two = Concept("twenty two")
|
||||
# one = Concept("one")
|
||||
# grammar = {twenty_two: Sequence("twenty", "two")}
|
||||
# context, return_value = self.init([twenty_two, one], grammar, "twenty two + one")
|
||||
#
|
||||
# parser = MultipleConceptsParser()
|
||||
# ret_val = parser.parse(context, return_value.body)
|
||||
#
|
||||
# assert not ret_val.status
|
||||
# assert ret_val.who == parser.name
|
||||
# assert context.sheerka.isinstance(ret_val.value, BuiltinConcepts.PARSER_RESULT)
|
||||
# assert ret_val.value.value == [
|
||||
# cnode("twenty two", 0, 2, "twenty two"),
|
||||
# utnode(3, 5, " + "),
|
||||
# cnode("one", 6, 6, "one")
|
||||
# ]
|
||||
# assert ret_val.value.source == "twenty two + one"
|
||||
#
|
||||
# def test_i_cannot_parse_when_unknown_concepts(self):
|
||||
# twenty_two = Concept("twenty two")
|
||||
# one = Concept("one")
|
||||
# grammar = {twenty_two: Sequence("twenty", "two")}
|
||||
# context, return_value = self.init([twenty_two, one], grammar, "twenty two plus one")
|
||||
#
|
||||
# parser = MultipleConceptsParser()
|
||||
# ret_val = parser.parse(context, return_value.body)
|
||||
#
|
||||
# assert not ret_val.status
|
||||
# assert ret_val.who == parser.name
|
||||
# assert context.sheerka.isinstance(ret_val.value, BuiltinConcepts.PARSER_RESULT)
|
||||
# assert ret_val.value.value == [
|
||||
# cnode("twenty two", 0, 2, "twenty two"),
|
||||
# utnode(3, 5, " plus "),
|
||||
# cnode("one", 6, 6, "one")
|
||||
# ]
|
||||
# assert ret_val.value.source == "twenty two plus one"
|
||||
#
|
||||
# @pytest.mark.parametrize("text, expected_source, expected_end", [
|
||||
# ("True", "True", 0),
|
||||
# ("1 == 1", "1 == 1", 4),
|
||||
# ("1!xdf", "1", 0),
|
||||
# ("1", "1", 0),
|
||||
# ])
|
||||
# def test_i_can_get_source_code_node(self, text, expected_source, expected_end):
|
||||
# tokens = list(Tokenizer(text))[:-1] # strip trailing EOF
|
||||
#
|
||||
# start_index = 5 # a random number different of zero
|
||||
# res = MultipleConceptsParser().get_source_code_node(self.get_context(), start_index, tokens)
|
||||
#
|
||||
# assert isinstance(res, SourceCodeNode)
|
||||
# assert isinstance(res.node, PythonNode)
|
||||
# assert res.source == expected_source
|
||||
# assert res.start == start_index
|
||||
# assert res.end == start_index + expected_end
|
||||
#
|
||||
# def test_i_cannot_parse_null_text(self):
|
||||
# res = MultipleConceptsParser().get_source_code_node(self.get_context(), 0, [])
|
||||
# assert res is None
|
||||
#
|
||||
# eof = Token(TokenKind.EOF, "", 0, 0, 0)
|
||||
# res = MultipleConceptsParser().get_source_code_node(self.get_context(), 0, [eof])
|
||||
# assert res is None
|
||||
|
||||
@@ -50,9 +50,9 @@ class TestPythonParser(TestUsingMemoryBasedSheerka):
|
||||
assert res.who == parser.name
|
||||
assert isinstance(res.value, NotForMeConcept)
|
||||
assert res.value.body == text
|
||||
assert len(res.value.get_prop("reason")) == 1
|
||||
assert isinstance(res.value.get_prop("reason")[0], PythonErrorNode)
|
||||
assert isinstance(res.value.get_prop("reason")[0].exception, SyntaxError)
|
||||
assert len(res.value.get_value("reason")) == 1
|
||||
assert isinstance(res.value.get_value("reason")[0], PythonErrorNode)
|
||||
assert isinstance(res.value.get_value("reason")[0].exception, SyntaxError)
|
||||
|
||||
@pytest.mark.parametrize("text, error_msg, error_text", [
|
||||
("c::", "Concept identifiers not found", ""),
|
||||
@@ -66,10 +66,10 @@ class TestPythonParser(TestUsingMemoryBasedSheerka):
|
||||
assert isinstance(res.value, NotForMeConcept)
|
||||
assert res.value.body == text
|
||||
|
||||
assert len(res.value.get_prop("reason")) == 1
|
||||
assert isinstance(res.value.get_prop("reason")[0], LexerError)
|
||||
assert res.value.get_prop("reason")[0].message == error_msg
|
||||
assert res.value.get_prop("reason")[0].text == error_text
|
||||
assert len(res.value.get_value("reason")) == 1
|
||||
assert isinstance(res.value.get_value("reason")[0], LexerError)
|
||||
assert res.value.get_value("reason")[0].message == error_msg
|
||||
assert res.value.get_value("reason")[0].text == error_text
|
||||
|
||||
def test_i_can_parse_a_concept(self):
|
||||
text = "c:name|key: + 1"
|
||||
|
||||
@@ -4,7 +4,7 @@ import pytest
|
||||
from core.builtin_concepts import ParserResultConcept, BuiltinConcepts, ReturnValueConcept
|
||||
from core.concept import Concept
|
||||
from core.tokenizer import Token, TokenKind, Tokenizer
|
||||
from parsers.BnfNodeParser import ConceptNode, UnrecognizedTokensNode
|
||||
from parsers.BaseNodeParser import ConceptNode, UnrecognizedTokensNode
|
||||
from parsers.PythonParser import PythonNode
|
||||
from parsers.PythonWithConceptsParser import PythonWithConceptsParser
|
||||
from parsers.UnrecognizedNodeParser import UnrecognizedNodeParser
|
||||
|
||||
+317
-276
@@ -3,7 +3,7 @@ from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import Concept, CC
|
||||
from core.tokenizer import Tokenizer
|
||||
from parsers.BaseNodeParser import utnode, ConceptNode, cnode, short_cnode, UnrecognizedTokensNode, \
|
||||
SCWC, CNC, CN, UTN, scnode
|
||||
SCWC, CNC, UTN
|
||||
from parsers.PythonParser import PythonNode
|
||||
from parsers.SyaNodeParser import SyaNodeParser, SyaConceptParserHelper, SyaAssociativity, \
|
||||
NoneAssociativeSequenceErrorNode, TooManyParametersFound
|
||||
@@ -16,14 +16,69 @@ def compute_expected_array(concepts_map, expression, expected):
|
||||
return tests.parsers.parsers_utils.compute_expected_array(concepts_map, expression, expected, sya=True)
|
||||
|
||||
|
||||
class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
cmap = {
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"three": Concept("three"),
|
||||
"four": Concept("four"),
|
||||
"plus": Concept("a plus b").def_var("a").def_var("b"),
|
||||
"minus": Concept("a minus b").def_var("a").def_var("b"),
|
||||
"mult": Concept("a mult b").def_var("a").def_var("b"),
|
||||
"prefixed": Concept("a prefixed").def_var("a"),
|
||||
"suffixed": Concept("suffixed a").def_var("a"),
|
||||
"infix": Concept("a infix b").def_var("a").def_var("b"),
|
||||
"?": Concept("a ? b : c").def_var("a").def_var("b").def_var("c"),
|
||||
"if": Concept("if a then b else c end").def_var("a").def_var("b").def_var("c"),
|
||||
"square": Concept("square(a)").def_var("a"),
|
||||
"foo bar": Concept("foo bar(a)").def_var("a"),
|
||||
"twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_var("unit"),
|
||||
}
|
||||
|
||||
def init_parser(self, concepts_map, sya_def, **kwargs):
|
||||
sheerka, context, *updated_concepts = self.init_concepts(
|
||||
*concepts_map.values(),
|
||||
singleton=True,
|
||||
|
||||
class TestSyaNodeParser(TestUsingMemoryBasedSheerka):
|
||||
sheerka = None
|
||||
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
t = TestSyaNodeParser()
|
||||
TestSyaNodeParser.sheerka, context, _ = t.init_parser(
|
||||
cmap,
|
||||
singleton=False,
|
||||
create_new=True,
|
||||
**kwargs)
|
||||
init_from_sheerka=True)
|
||||
|
||||
TestSyaNodeParser.sheerka.force_sya_def(context, [
|
||||
(cmap["plus"].id, 5, SyaAssociativity.Right),
|
||||
(cmap["mult"].id, 10, SyaAssociativity.Right),
|
||||
(cmap["minus"].id, 10, SyaAssociativity.Right),
|
||||
(cmap["square"].id, None, SyaAssociativity.No)])
|
||||
|
||||
def init_parser(self,
|
||||
my_concepts_map=None,
|
||||
sya_def=None,
|
||||
post_init_concepts=None,
|
||||
**kwargs):
|
||||
|
||||
if my_concepts_map is not None:
|
||||
# a new concept map is given
|
||||
# use it but
|
||||
# do not instantiate a new sheerka
|
||||
# do not update / init from sheerka
|
||||
if 'singleton' not in kwargs:
|
||||
kwargs["singleton"] = True
|
||||
init_from_sheerka = kwargs.get("init_from_sheerka", False)
|
||||
sheerka, context, *concepts = self.init_concepts(*my_concepts_map.values(), **kwargs)
|
||||
else:
|
||||
# No custom concept map is given -> Use the global cmap
|
||||
# Sheerka is already initialized (the class instance)
|
||||
# Use it to initialize the parser
|
||||
init_from_sheerka = kwargs.get("init_from_sheerka", True)
|
||||
sheerka = TestSyaNodeParser.sheerka
|
||||
context = self.get_context(sheerka)
|
||||
concepts = cmap.values()
|
||||
|
||||
if post_init_concepts:
|
||||
post_init_concepts(sheerka, context)
|
||||
|
||||
if sya_def:
|
||||
sya_def_to_use = {}
|
||||
@@ -32,29 +87,15 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
else:
|
||||
sya_def_to_use = None
|
||||
|
||||
parser = SyaNodeParser()
|
||||
parser.initialize(context, updated_concepts, sya_def_to_use)
|
||||
if init_from_sheerka:
|
||||
parser = SyaNodeParser(sheerka=sheerka)
|
||||
else:
|
||||
parser = SyaNodeParser()
|
||||
if my_concepts_map:
|
||||
parser.init_from_concepts(context, concepts, sya=sya_def_to_use)
|
||||
|
||||
return sheerka, context, parser
|
||||
|
||||
def test_i_can_initialize(self):
|
||||
sheerka, context, c1, c2, c3, c4, c5 = self.init_concepts(
|
||||
"foo",
|
||||
Concept("bar a").def_prop("a"),
|
||||
Concept("a baz").def_prop("a"),
|
||||
Concept("baz a qux b").def_prop("a").def_prop("b"),
|
||||
Concept("foo a bar b").def_prop("a").def_prop("b"),
|
||||
)
|
||||
|
||||
parser = SyaNodeParser()
|
||||
parser.initialize(context, [c1, c2, c3, c4, c5])
|
||||
|
||||
assert parser.concepts_by_first_keyword == {
|
||||
"foo": [c1.id, c5.id],
|
||||
"bar": [c2.id],
|
||||
"baz": [c3.id, c4.id],
|
||||
}
|
||||
|
||||
@pytest.mark.parametrize("expression, expected_sequences", [
|
||||
("one plus two", [["one", "two", "plus"]]),
|
||||
("1 + 1 plus two", [["1 + 1 ", "two", "plus"]]),
|
||||
@@ -143,21 +184,21 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
("x$!# plus z$!#", [["x$!# ", " z$!#", "plus"]]),
|
||||
])
|
||||
def test_i_can_post_fix_simple_infix_concepts(self, expression, expected_sequences):
|
||||
concepts_map = {
|
||||
"plus": Concept("a plus b").def_prop("a").def_prop("b"),
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"three": Concept("three"),
|
||||
"twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_prop("unit"),
|
||||
}
|
||||
sheerka, context, parser = self.init_parser(concepts_map, None)
|
||||
# concepts_map = {
|
||||
# "plus": Concept("a plus b").def_var("a").def_var("b"),
|
||||
# "one": Concept("one"),
|
||||
# "two": Concept("two"),
|
||||
# "three": Concept("three"),
|
||||
# "twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_var("unit"),
|
||||
# }
|
||||
sheerka, context, parser = self.init_parser()
|
||||
|
||||
res = parser.infix_to_postfix(context, expression)
|
||||
|
||||
assert len(res) == len(expected_sequences)
|
||||
for res_i, expected in zip(res, expected_sequences):
|
||||
assert len(res_i.errors) == 0
|
||||
expected_array = compute_expected_array(concepts_map, expression, expected)
|
||||
expected_array = compute_expected_array(cmap, expression, expected)
|
||||
assert res_i.out == expected_array
|
||||
|
||||
@pytest.mark.parametrize("expression, expected_sequences", [
|
||||
@@ -169,14 +210,14 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
])
|
||||
def test_i_can_post_fix_infix_concepts_with_long_name(self, expression, expected_sequences):
|
||||
concepts_map = {
|
||||
"plus plus plus": Concept("a plus plus plus b").def_prop("a").def_prop("b"),
|
||||
"another long name infix": Concept("a another long name infix b").def_prop("a").def_prop("b"),
|
||||
"plus plus plus": Concept("a plus plus plus b").def_var("a").def_var("b"),
|
||||
"another long name infix": Concept("a another long name infix b").def_var("a").def_var("b"),
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"three": Concept("three"),
|
||||
"twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_prop("unit"),
|
||||
"twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_var("unit"),
|
||||
}
|
||||
sheerka, context, parser = self.init_parser(concepts_map, None)
|
||||
sheerka, context, parser = self.init_parser(concepts_map, create_new=True, init_from_sheerka=True)
|
||||
|
||||
res = parser.infix_to_postfix(context, expression)
|
||||
|
||||
@@ -200,20 +241,20 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
("x$!# prefixed", [["x$!# ", "prefixed"]]),
|
||||
])
|
||||
def test_i_can_post_fix_simple_prefixed_concepts(self, expression, expected_sequences):
|
||||
concepts_map = {
|
||||
"prefixed": Concept("a prefixed").def_prop("a"),
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_prop("unit"),
|
||||
}
|
||||
sheerka, context, parser = self.init_parser(concepts_map, None)
|
||||
# concepts_map = {
|
||||
# "prefixed": Concept("a prefixed").def_var("a"),
|
||||
# "one": Concept("one"),
|
||||
# "two": Concept("two"),
|
||||
# "twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_var("unit"),
|
||||
# }
|
||||
sheerka, context, parser = self.init_parser()
|
||||
|
||||
res = parser.infix_to_postfix(context, expression)
|
||||
|
||||
assert len(res) == len(expected_sequences)
|
||||
for res_i, expected in zip(res, expected_sequences):
|
||||
assert len(res_i.errors) == 0
|
||||
expected_array = compute_expected_array(concepts_map, expression, expected)
|
||||
expected_array = compute_expected_array(cmap, expression, expected)
|
||||
assert res_i.out == expected_array
|
||||
|
||||
@pytest.mark.parametrize("expression, expected_sequences", [
|
||||
@@ -243,13 +284,13 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
])
|
||||
def test_i_can_post_fix_prefixed_concepts_with_long_names(self, expression, expected_sequences):
|
||||
concepts_map = {
|
||||
"prefixed prefixed": Concept("a prefixed prefixed").def_prop("a"),
|
||||
"long name prefixed": Concept("a long name prefixed").def_prop("a"),
|
||||
"prefixed prefixed": Concept("a prefixed prefixed").def_var("a"),
|
||||
"long name prefixed": Concept("a long name prefixed").def_var("a"),
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_prop("unit"),
|
||||
"twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_var("unit"),
|
||||
}
|
||||
sheerka, context, parser = self.init_parser(concepts_map, None)
|
||||
sheerka, context, parser = self.init_parser(concepts_map, create_new=True, init_from_sheerka=True)
|
||||
|
||||
res = parser.infix_to_postfix(context, expression)
|
||||
|
||||
@@ -273,20 +314,20 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
("suffixed x$!#", [[" x$!#", "suffixed"]]),
|
||||
])
|
||||
def test_i_can_post_fix_simple_suffixed_concepts(self, expression, expected_sequences):
|
||||
concepts_map = {
|
||||
"suffixed": Concept("suffixed a").def_prop("a"),
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_prop("unit"),
|
||||
}
|
||||
sheerka, context, parser = self.init_parser(concepts_map, None)
|
||||
# concepts_map = {
|
||||
# "suffixed": Concept("suffixed a").def_var("a"),
|
||||
# "one": Concept("one"),
|
||||
# "two": Concept("two"),
|
||||
# "twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_var("unit"),
|
||||
# }
|
||||
sheerka, context, parser = self.init_parser()
|
||||
|
||||
res = parser.infix_to_postfix(context, expression)
|
||||
|
||||
assert len(res) == len(expected_sequences)
|
||||
for res_i, expected in zip(res, expected_sequences):
|
||||
assert len(res_i.errors) == 0
|
||||
expected_array = compute_expected_array(concepts_map, expression, expected)
|
||||
expected_array = compute_expected_array(cmap, expression, expected)
|
||||
assert res_i.out == expected_array
|
||||
|
||||
@pytest.mark.parametrize("expression, expected", [
|
||||
@@ -295,11 +336,11 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
])
|
||||
def test_i_can_post_fix_suffixed_concepts_with_long_names(self, expression, expected):
|
||||
concepts_map = {
|
||||
"suffixed suffixed": Concept("suffixed suffixed a").def_prop("a"),
|
||||
"long name suffixed": Concept("long name suffixed a").def_prop("a"),
|
||||
"suffixed suffixed": Concept("suffixed suffixed a").def_var("a"),
|
||||
"long name suffixed": Concept("long name suffixed a").def_var("a"),
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_prop("unit"),
|
||||
"twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_var("unit"),
|
||||
}
|
||||
sheerka, context, parser = self.init_parser(concepts_map, None)
|
||||
|
||||
@@ -340,22 +381,22 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
:return:
|
||||
"""
|
||||
|
||||
concepts_map = {
|
||||
"?": Concept("a ? b : c").def_prop("a").def_prop("b").def_prop("c"),
|
||||
"if": Concept("if a then b else c end").def_prop("a").def_prop("b").def_prop("c"),
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"three": Concept("three"),
|
||||
"twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_prop("unit"),
|
||||
}
|
||||
sheerka, context, parser = self.init_parser(concepts_map, None)
|
||||
# concepts_map = {
|
||||
# "?": Concept("a ? b : c").def_var("a").def_var("b").def_var("c"),
|
||||
# "if": Concept("if a then b else c end").def_var("a").def_var("b").def_var("c"),
|
||||
# "one": Concept("one"),
|
||||
# "two": Concept("two"),
|
||||
# "three": Concept("three"),
|
||||
# "twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_var("unit"),
|
||||
# }
|
||||
sheerka, context, parser = self.init_parser()
|
||||
|
||||
res = parser.infix_to_postfix(context, expression)
|
||||
|
||||
assert len(res) == len(expected_sequences)
|
||||
for res_i, expected in zip(res, expected_sequences):
|
||||
# assert len(res_i.errors) == 0 # Do not validate errors
|
||||
expected_array = compute_expected_array(concepts_map, expression, expected)
|
||||
expected_array = compute_expected_array(cmap, expression, expected)
|
||||
assert res_i.out == expected_array
|
||||
|
||||
@pytest.mark.parametrize("expression, expected_sequences", [
|
||||
@@ -373,14 +414,14 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
])
|
||||
def test_i_can_post_fix_ternary_concept_with_long_names(self, expression, expected_sequences):
|
||||
concepts_map = {
|
||||
"? ?": Concept("a ? ? b : : c").def_prop("a").def_prop("b").def_prop("c"),
|
||||
"if if": Concept("if if a then then b else else c end end").def_prop("a").def_prop("b").def_prop("c"),
|
||||
"? ?": Concept("a ? ? b : : c").def_var("a").def_var("b").def_var("c"),
|
||||
"if if": Concept("if if a then then b else else c end end").def_var("a").def_var("b").def_var("c"),
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"three": Concept("three"),
|
||||
"twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_prop("unit"),
|
||||
"twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_var("unit"),
|
||||
}
|
||||
sheerka, context, parser = self.init_parser(concepts_map, None)
|
||||
sheerka, context, parser = self.init_parser(concepts_map, create_new=True, init_from_sheerka=True)
|
||||
|
||||
res = parser.infix_to_postfix(context, expression)
|
||||
|
||||
@@ -397,8 +438,8 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
])
|
||||
def test_i_can_post_fix_suffixed_unary_composition(self, expression, expected):
|
||||
concepts_map = {
|
||||
"foo": Concept("foo a").def_prop("a"),
|
||||
"bar": Concept("bar a").def_prop("a"),
|
||||
"foo": Concept("foo a").def_var("a"),
|
||||
"bar": Concept("bar a").def_var("a"),
|
||||
"baz": Concept("baz"),
|
||||
}
|
||||
sheerka, context, parser = self.init_parser(concepts_map, None)
|
||||
@@ -416,8 +457,8 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
])
|
||||
def test_i_can_post_fix_prefixed_unary_composition(self, expression, expected):
|
||||
concepts_map = {
|
||||
"foo": Concept("a foo").def_prop("a"),
|
||||
"bar": Concept("a bar").def_prop("a"),
|
||||
"foo": Concept("a foo").def_var("a"),
|
||||
"bar": Concept("a bar").def_var("a"),
|
||||
"baz": Concept("baz"),
|
||||
}
|
||||
sya_def = {
|
||||
@@ -439,29 +480,29 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
("one mult (two plus three)", ["one", "two", "three", "plus", "mult"]),
|
||||
])
|
||||
def test_i_can_post_fix_binary_with_precedence(self, expression, expected):
|
||||
concepts_map = {
|
||||
"plus": Concept("a plus b").def_prop("a").def_prop("b"),
|
||||
"mult": Concept("a mult b").def_prop("a").def_prop("b"),
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"three": Concept("three"),
|
||||
}
|
||||
sya_def = {
|
||||
concepts_map["plus"]: (5, SyaAssociativity.Right),
|
||||
concepts_map["mult"]: (10, SyaAssociativity.Right), # precedence greater than plus
|
||||
}
|
||||
sheerka, context, parser = self.init_parser(concepts_map, sya_def)
|
||||
# concepts_map = {
|
||||
# "plus": Concept("a plus b").def_var("a").def_var("b"),
|
||||
# "mult": Concept("a mult b").def_var("a").def_var("b"),
|
||||
# "one": Concept("one"),
|
||||
# "two": Concept("two"),
|
||||
# "three": Concept("three"),
|
||||
# }
|
||||
# sya_def = {
|
||||
# concepts_map["plus"]: (5, SyaAssociativity.Right),
|
||||
# concepts_map["mult"]: (10, SyaAssociativity.Right), # precedence greater than plus
|
||||
# }
|
||||
sheerka, context, parser = self.init_parser()
|
||||
|
||||
res = parser.infix_to_postfix(context, expression)
|
||||
expected_array = compute_expected_array(concepts_map, expression, expected)
|
||||
expected_array = compute_expected_array(cmap, expression, expected)
|
||||
|
||||
assert len(res) == 1
|
||||
assert res[0].out == expected_array
|
||||
|
||||
def test_i_can_post_fix_unary_with_precedence(self):
|
||||
concepts_map = {
|
||||
"suffixed": Concept("suffixed a").def_prop("a"),
|
||||
"prefixed": Concept("a prefixed").def_prop("a"),
|
||||
"suffixed": Concept("suffixed a").def_var("a"),
|
||||
"prefixed": Concept("a prefixed").def_var("a"),
|
||||
"a": Concept("a"),
|
||||
}
|
||||
|
||||
@@ -496,7 +537,7 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def test_i_can_post_fix_right_associated_binary(self):
|
||||
concepts_map = {
|
||||
"equals": Concept("a equals b").def_prop("a").def_prop("b"),
|
||||
"equals": Concept("a equals b").def_var("a").def_var("b"),
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"three": Concept("three"),
|
||||
@@ -518,7 +559,7 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def test_i_can_post_fix_left_associated_binary(self):
|
||||
concepts_map = {
|
||||
"plus": Concept("a plus b").def_prop("a").def_prop("b"),
|
||||
"plus": Concept("a plus b").def_var("a").def_var("b"),
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"three": Concept("three"),
|
||||
@@ -550,7 +591,7 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
])
|
||||
def test_i_can_post_fix_right_associated_ternary(self, expression, expected):
|
||||
concepts_map = {
|
||||
"?": Concept("a ? b : c").def_prop("a").def_prop("b").def_prop("c"),
|
||||
"?": Concept("a ? b : c").def_var("a").def_var("b").def_var("c"),
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"three": Concept("three"),
|
||||
@@ -577,7 +618,7 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
])
|
||||
def test_i_can_post_fix_left_associated_ternary(self, expression, expected):
|
||||
concepts_map = {
|
||||
"?": Concept("a ? b : c").def_prop("a").def_prop("b").def_prop("c"),
|
||||
"?": Concept("a ? b : c").def_var("a").def_var("b").def_var("c"),
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"three": Concept("three"),
|
||||
@@ -594,8 +635,8 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def test_i_can_post_fix_when_multiple_concepts_are_found(self):
|
||||
concepts_map = {
|
||||
"foo": Concept("foo a").def_prop("a"),
|
||||
"foo bar": Concept("foo bar a").def_prop("a"),
|
||||
"foo": Concept("foo a").def_var("a"),
|
||||
"foo bar": Concept("foo bar a").def_var("a"),
|
||||
"baz": Concept("baz"),
|
||||
}
|
||||
sheerka, context, parser = self.init_parser(concepts_map, None)
|
||||
@@ -603,7 +644,7 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
expression = "foo bar baz"
|
||||
res = parser.infix_to_postfix(context, expression)
|
||||
expected_sequences = [
|
||||
[" bar ", "foo", "baz"],
|
||||
[UTN(" bar "), "foo", "baz"],
|
||||
["baz", "foo bar"]
|
||||
]
|
||||
|
||||
@@ -646,30 +687,30 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
("foo bar ( one )", ["one", "foo bar"]),
|
||||
])
|
||||
def test_i_can_pos_fix_when_parenthesis(self, expression, expected):
|
||||
concepts_map = {
|
||||
"prefixed": Concept("a prefixed").def_prop("a"),
|
||||
"suffixed": Concept("suffixed a").def_prop("a"),
|
||||
"square": Concept("square(a)").def_prop("a"),
|
||||
"foo bar": Concept("foo bar(a)").def_prop("a"),
|
||||
"plus": Concept("a plus b").def_prop("a").def_prop("b"),
|
||||
"minus": Concept("a minus b").def_prop("a").def_prop("b"),
|
||||
"if": Concept("if a then b else c end").def_prop("a").def_prop("b").def_prop("c"),
|
||||
"?": Concept("a ? b : c").def_prop("a").def_prop("b").def_prop("c"),
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"three": Concept("three"),
|
||||
}
|
||||
# concepts_map = {
|
||||
# "prefixed": Concept("a prefixed").def_var("a"),
|
||||
# "suffixed": Concept("suffixed a").def_var("a"),
|
||||
# "square": Concept("square(a)").def_var("a"),
|
||||
# "foo bar": Concept("foo bar(a)").def_var("a"),
|
||||
# "plus": Concept("a plus b").def_var("a").def_var("b"),
|
||||
# "minus": Concept("a minus b").def_var("a").def_var("b"),
|
||||
# "if": Concept("if a then b else c end").def_var("a").def_var("b").def_var("c"),
|
||||
# "?": Concept("a ? b : c").def_var("a").def_var("b").def_var("c"),
|
||||
# "one": Concept("one"),
|
||||
# "two": Concept("two"),
|
||||
# "three": Concept("three"),
|
||||
# }
|
||||
#
|
||||
# sya_def = {
|
||||
# concepts_map["square"]: (None, SyaAssociativity.No),
|
||||
# concepts_map["plus"]: (10, SyaAssociativity.Right),
|
||||
# concepts_map["minus"]: (10, SyaAssociativity.Right),
|
||||
# }
|
||||
|
||||
sya_def = {
|
||||
concepts_map["square"]: (None, SyaAssociativity.No),
|
||||
concepts_map["plus"]: (10, SyaAssociativity.Right),
|
||||
concepts_map["minus"]: (10, SyaAssociativity.Right),
|
||||
}
|
||||
|
||||
sheerka, context, parser = self.init_parser(concepts_map, sya_def)
|
||||
sheerka, context, parser = self.init_parser()
|
||||
|
||||
res = parser.infix_to_postfix(context, expression)
|
||||
expected_array = compute_expected_array(concepts_map, expression, expected)
|
||||
expected_array = compute_expected_array(cmap, expression, expected)
|
||||
|
||||
assert len(res) == 1
|
||||
assert res[0].out == expected_array
|
||||
@@ -721,28 +762,28 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
("suffixed one function(two)", [["one", "suffixed", SCWC(" function(", ")", "two")]]),
|
||||
])
|
||||
def test_i_can_post_fix_when_parenthesis_and_unknown(self, expression, expected_sequences):
|
||||
concepts_map = {
|
||||
"prefixed": Concept("a prefixed").def_prop("a"),
|
||||
"suffixed": Concept("suffixed a").def_prop("a"),
|
||||
"plus": Concept("a plus b").def_prop("a").def_prop("b"),
|
||||
"mult": Concept("a mult b").def_prop("a").def_prop("b"),
|
||||
"if": Concept("if a then b else c end").def_prop("a").def_prop("b").def_prop("c"),
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"three": Concept("three"),
|
||||
"twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_prop("unit"),
|
||||
}
|
||||
sya_def = {
|
||||
concepts_map["plus"]: (5, SyaAssociativity.Right),
|
||||
concepts_map["mult"]: (10, SyaAssociativity.Right), # precedence greater than plus
|
||||
}
|
||||
sheerka, context, parser = self.init_parser(concepts_map, sya_def)
|
||||
# concepts_map = {
|
||||
# "prefixed": Concept("a prefixed").def_var("a"),
|
||||
# "suffixed": Concept("suffixed a").def_var("a"),
|
||||
# "plus": Concept("a plus b").def_var("a").def_var("b"),
|
||||
# "mult": Concept("a mult b").def_var("a").def_var("b"),
|
||||
# "if": Concept("if a then b else c end").def_var("a").def_var("b").def_var("c"),
|
||||
# "one": Concept("one"),
|
||||
# "two": Concept("two"),
|
||||
# "three": Concept("three"),
|
||||
# "twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_var("unit"),
|
||||
# }
|
||||
# sya_def = {
|
||||
# concepts_map["plus"]: (5, SyaAssociativity.Right),
|
||||
# concepts_map["mult"]: (10, SyaAssociativity.Right), # precedence greater than plus
|
||||
# }
|
||||
sheerka, context, parser = self.init_parser()
|
||||
|
||||
res = parser.infix_to_postfix(context, expression)
|
||||
|
||||
assert len(res) == len(expected_sequences)
|
||||
for res_i, expected in zip(res, expected_sequences):
|
||||
expected_array = compute_expected_array(concepts_map, expression, expected)
|
||||
expected_array = compute_expected_array(cmap, expression, expected)
|
||||
assert res_i.out == expected_array
|
||||
|
||||
@pytest.mark.parametrize("expression, expected", [
|
||||
@@ -762,13 +803,13 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
("(one plus ( 1 + )", ("(", 0)),
|
||||
])
|
||||
def test_i_can_detect_parenthesis_mismatch_error_when_post_fixing(self, expression, expected):
|
||||
concepts_map = {
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"plus": Concept("a plus b").def_prop("a").def_prop("b"),
|
||||
"?": Concept("a ? b : c").def_prop("a").def_prop("b").def_prop("c"),
|
||||
}
|
||||
sheerka, context, parser = self.init_parser(concepts_map, None)
|
||||
# concepts_map = {
|
||||
# "one": Concept("one"),
|
||||
# "two": Concept("two"),
|
||||
# "plus": Concept("a plus b").def_var("a").def_var("b"),
|
||||
# "?": Concept("a ? b : c").def_var("a").def_var("b").def_var("c"),
|
||||
# }
|
||||
sheerka, context, parser = self.init_parser()
|
||||
|
||||
res = parser.infix_to_postfix(context, expression)
|
||||
|
||||
@@ -779,13 +820,13 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
("one ? one two : three", ("?", ":")),
|
||||
])
|
||||
def test_i_can_detected_when_too_many_parameters(self, expression, expected):
|
||||
concepts_map = {
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"plus": Concept("a plus b").def_prop("a").def_prop("b"),
|
||||
"?": Concept("a ? b : c").def_prop("a").def_prop("b").def_prop("c"),
|
||||
}
|
||||
sheerka, context, parser = self.init_parser(concepts_map, None)
|
||||
# concepts_map = {
|
||||
# "one": Concept("one"),
|
||||
# "two": Concept("two"),
|
||||
# "plus": Concept("a plus b").def_var("a").def_var("b"),
|
||||
# "?": Concept("a ? b : c").def_var("a").def_var("b").def_var("c"),
|
||||
# }
|
||||
sheerka, context, parser = self.init_parser(cmap, None)
|
||||
|
||||
res = parser.infix_to_postfix(context, expression)
|
||||
|
||||
@@ -793,7 +834,7 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
assert len(res[0].errors) == 1
|
||||
error = res[0].errors[0]
|
||||
assert isinstance(error, TooManyParametersFound)
|
||||
assert error.concept == concepts_map[expected[0]]
|
||||
assert error.concept == cmap[expected[0]]
|
||||
assert error.token.value == expected[1]
|
||||
|
||||
@pytest.mark.parametrize("expression, expected", [
|
||||
@@ -819,30 +860,30 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
("(one infix two) (three prefixed)", ["one", "two", "infix", "three", "prefixed"]),
|
||||
])
|
||||
def test_i_can_post_fix_sequences(self, expression, expected):
|
||||
concepts_map = {
|
||||
"prefixed": Concept("a prefixed").def_prop("a"),
|
||||
"suffixed": Concept("suffixed a").def_prop("a"),
|
||||
"infix": Concept("a infix b").def_prop("a").def_prop("b"),
|
||||
"?": Concept("a ? b : c").def_prop("a").def_prop("b").def_prop("c"),
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"three": Concept("three"),
|
||||
"four": Concept("four"),
|
||||
}
|
||||
# concepts_map = {
|
||||
# "prefixed": Concept("a prefixed").def_var("a"),
|
||||
# "suffixed": Concept("suffixed a").def_var("a"),
|
||||
# "infix": Concept("a infix b").def_var("a").def_var("b"),
|
||||
# "?": Concept("a ? b : c").def_var("a").def_var("b").def_var("c"),
|
||||
# "one": Concept("one"),
|
||||
# "two": Concept("two"),
|
||||
# "three": Concept("three"),
|
||||
# "four": Concept("four"),
|
||||
# }
|
||||
|
||||
sheerka, context, parser = self.init_parser(concepts_map, None)
|
||||
sheerka, context, parser = self.init_parser(cmap, None)
|
||||
|
||||
res = parser.infix_to_postfix(context, expression)
|
||||
expected_array = compute_expected_array(concepts_map, expression, expected)
|
||||
expected_array = compute_expected_array(cmap, expression, expected)
|
||||
|
||||
assert len(res) == 1
|
||||
assert res[0].out == expected_array
|
||||
|
||||
def test_the_more_concepts_the_more_results(self):
|
||||
concepts_map = {
|
||||
"plus": Concept("a plus b").def_prop("a").def_prop("b"),
|
||||
"plus plus": Concept("a plus plus").def_prop("a"),
|
||||
"plus equals": Concept("a plus equals b").def_prop("a").def_prop("b"),
|
||||
"plus": Concept("a plus b").def_var("a").def_var("b"),
|
||||
"plus plus": Concept("a plus plus").def_var("a"),
|
||||
"plus equals": Concept("a plus equals b").def_var("a").def_var("b"),
|
||||
}
|
||||
|
||||
sheerka, context, parser = self.init_parser(concepts_map, None)
|
||||
@@ -864,7 +905,7 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def test_i_can_use_string_instead_of_identifier(self):
|
||||
concepts_map = {
|
||||
"ternary": Concept("a ? ? b '::' c").def_prop("a").def_prop("b").def_prop("c"),
|
||||
"ternary": Concept("a ? ? b '::' c").def_var("a").def_var("b").def_var("c"),
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"three": Concept("three"),
|
||||
@@ -883,7 +924,7 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def test_i_cannot_chain_non_associative(self):
|
||||
concepts_map = {
|
||||
"less than": Concept("a less than b").def_prop("a").def_prop("b"),
|
||||
"less than": Concept("a less than b").def_var("a").def_var("b"),
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"three": Concept("three"),
|
||||
@@ -904,35 +945,35 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
Not quite sure why this test is here
|
||||
:return:
|
||||
"""
|
||||
concepts_map = {
|
||||
"foo": Concept("foo a").def_prop("a"),
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_prop("unit"),
|
||||
}
|
||||
sheerka, context, parser = self.init_parser(concepts_map, None)
|
||||
# concepts_map = {
|
||||
# "foo": Concept("foo a").def_var("a"),
|
||||
# "one": Concept("one"),
|
||||
# "two": Concept("two"),
|
||||
# "twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_var("unit"),
|
||||
# }
|
||||
sheerka, context, parser = self.init_parser(cmap, None)
|
||||
|
||||
expression = "foo twenties"
|
||||
expression = "suffixed twenties"
|
||||
res = parser.infix_to_postfix(context, expression)
|
||||
|
||||
expected = [cnode("twenties", 2, 2, "twenties"), "foo"]
|
||||
expected_array = compute_expected_array(concepts_map, expression, expected)
|
||||
expected = [cnode("twenties", 2, 2, "twenties"), "suffixed"]
|
||||
expected_array = compute_expected_array(cmap, expression, expected)
|
||||
assert len(res) == 1
|
||||
assert res[0].out == expected_array
|
||||
|
||||
def test_i_can_parse_when_concept_atom_only(self):
|
||||
concepts_map = {
|
||||
"plus": Concept("a plus b").def_prop("a").def_prop("b"),
|
||||
"mult": Concept("a mult b").def_prop("a").def_prop("b"),
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"three": Concept("three"),
|
||||
}
|
||||
sya_def = {
|
||||
concepts_map["plus"]: (5, SyaAssociativity.Right),
|
||||
concepts_map["mult"]: (10, SyaAssociativity.Right), # precedence greater than plus
|
||||
}
|
||||
sheerka, context, parser = self.init_parser(concepts_map, sya_def)
|
||||
# concepts_map = {
|
||||
# "plus": Concept("a plus b").def_var("a").def_var("b"),
|
||||
# "mult": Concept("a mult b").def_var("a").def_var("b"),
|
||||
# "one": Concept("one"),
|
||||
# "two": Concept("two"),
|
||||
# "three": Concept("three"),
|
||||
# }
|
||||
# sya_def = {
|
||||
# concepts_map["plus"]: (5, SyaAssociativity.Right),
|
||||
# concepts_map["mult"]: (10, SyaAssociativity.Right), # precedence greater than plus
|
||||
# }
|
||||
sheerka, context, parser = self.init_parser()
|
||||
|
||||
text = "one plus two mult three"
|
||||
res = parser.parse(context, text)
|
||||
@@ -941,29 +982,29 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert res.status
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == [ConceptNode(concepts_map["plus"], 0, 8, source=text)]
|
||||
assert lexer_nodes == [ConceptNode(cmap["plus"], 0, 8, source=text)]
|
||||
|
||||
# check the compiled
|
||||
expected_concept = lexer_nodes[0].concept
|
||||
assert expected_concept.compiled["a"] == concepts_map["one"]
|
||||
assert expected_concept.compiled["b"] == concepts_map["mult"]
|
||||
assert expected_concept.compiled["b"].compiled["a"] == concepts_map["two"]
|
||||
assert expected_concept.compiled["b"].compiled["b"] == concepts_map["three"]
|
||||
assert expected_concept.compiled["a"] == cmap["one"]
|
||||
assert expected_concept.compiled["b"] == cmap["mult"]
|
||||
assert expected_concept.compiled["b"].compiled["a"] == cmap["two"]
|
||||
assert expected_concept.compiled["b"].compiled["b"] == cmap["three"]
|
||||
|
||||
def test_i_can_parse_when_python_code(self):
|
||||
concepts_map = {
|
||||
"foo": Concept("foo a").def_prop("a")
|
||||
}
|
||||
sheerka, context, parser = self.init_parser(concepts_map, None)
|
||||
# concepts_map = {
|
||||
# "foo": Concept("foo a").def_var("a")
|
||||
# }
|
||||
sheerka, context, parser = self.init_parser(cmap, None)
|
||||
|
||||
text = "foo 1 + 1"
|
||||
text = "suffixed 1 + 1"
|
||||
res = parser.parse(context, text)
|
||||
wrapper = res.body
|
||||
lexer_nodes = res.body.body
|
||||
|
||||
assert res.status
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == [ConceptNode(concepts_map["foo"], 0, 6, source=text)]
|
||||
assert lexer_nodes == [ConceptNode(cmap["suffixed"], 0, 6, source=text)]
|
||||
|
||||
# check the compiled
|
||||
expected_concept = lexer_nodes[0].concept
|
||||
@@ -977,15 +1018,15 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
assert isinstance(return_value_a.body.body, PythonNode)
|
||||
|
||||
def test_i_can_parse_when_bnf_concept(self):
|
||||
concepts_map = {
|
||||
"foo": Concept("foo a").def_prop("a"),
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_prop("unit"),
|
||||
}
|
||||
sheerka, context, parser = self.init_parser(concepts_map, None)
|
||||
# concepts_map = {
|
||||
# "foo": Concept("foo a").def_var("a"),
|
||||
# "one": Concept("one"),
|
||||
# "two": Concept("two"),
|
||||
# "twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_var("unit"),
|
||||
# }
|
||||
sheerka, context, parser = self.init_parser()
|
||||
|
||||
text = "foo twenty one"
|
||||
text = "suffixed twenty one"
|
||||
res = parser.parse(context, text)
|
||||
assert len(res) == 2
|
||||
assert res[1].status
|
||||
@@ -994,23 +1035,23 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
lexer_nodes = res[1].body.body
|
||||
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == [ConceptNode(concepts_map["foo"], 0, 4, source=text)]
|
||||
assert lexer_nodes == [ConceptNode(cmap["suffixed"], 0, 4, source=text)]
|
||||
|
||||
# check the compiled
|
||||
expected_concept = lexer_nodes[0].concept
|
||||
assert sheerka.isinstance(expected_concept.compiled["a"], "twenties")
|
||||
assert expected_concept.compiled["a"].compiled["unit"] == concepts_map["one"]
|
||||
assert expected_concept.compiled["a"].compiled["unit"] == cmap["one"]
|
||||
|
||||
def test_i_can_parse_sequences(self):
|
||||
concepts_map = {
|
||||
"plus": Concept("a plus b").def_prop("a").def_prop("b"),
|
||||
"foo": Concept("foo a").def_prop("a"),
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
}
|
||||
sheerka, context, parser = self.init_parser(concepts_map, None)
|
||||
# concepts_map = {
|
||||
# "plus": Concept("a plus b").def_var("a").def_var("b"),
|
||||
# "foo": Concept("foo a").def_var("a"),
|
||||
# "one": Concept("one"),
|
||||
# "two": Concept("two"),
|
||||
# }
|
||||
sheerka, context, parser = self.init_parser(cmap, None)
|
||||
|
||||
text = "one plus 1 + 1 foo two"
|
||||
text = "one plus 1 + 1 suffixed two"
|
||||
res = parser.parse(context, text)
|
||||
wrapper = res.body
|
||||
lexer_nodes = res.body.body
|
||||
@@ -1018,19 +1059,19 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
assert res.status
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == [
|
||||
ConceptNode(concepts_map["plus"], 0, 9, source="one plus 1 + 1 "),
|
||||
ConceptNode(concepts_map["foo"], 10, 12, source="foo two")]
|
||||
ConceptNode(cmap["plus"], 0, 9, source="one plus 1 + 1 "),
|
||||
ConceptNode(cmap["suffixed"], 10, 12, source="suffixed two")]
|
||||
|
||||
# check the compiled
|
||||
concept_plus_a = lexer_nodes[0].concept.compiled["a"]
|
||||
concept_plus_b = lexer_nodes[0].concept.compiled["b"]
|
||||
concept_foo_a = lexer_nodes[1].concept.compiled["a"]
|
||||
concept_suffixed_a = lexer_nodes[1].concept.compiled["a"]
|
||||
|
||||
assert concept_plus_a == concepts_map["one"]
|
||||
assert concept_plus_a == cmap["one"]
|
||||
assert len(concept_plus_b) == 1
|
||||
assert sheerka.isinstance(concept_plus_b[0], BuiltinConcepts.RETURN_VALUE)
|
||||
assert isinstance(concept_plus_b[0].body.body, PythonNode)
|
||||
assert concept_foo_a == concepts_map["two"]
|
||||
assert concept_suffixed_a == cmap["two"]
|
||||
|
||||
@pytest.mark.parametrize("text, expected_status, expected_result", [
|
||||
("function(suffixed one)", True, [
|
||||
@@ -1046,28 +1087,28 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
SCWC("function(", ")", CNC("suffixed", 2, 7, a=" x$!#"))]),
|
||||
])
|
||||
def test_i_can_parse_when_one_result(self, text, expected_status, expected_result):
|
||||
concepts_map = {
|
||||
"prefixed": Concept("a prefixed").def_prop("a"),
|
||||
"suffixed": Concept("suffixed a").def_prop("a"),
|
||||
"mult": Concept("a mult b").def_prop("a").def_prop("b"),
|
||||
"plus": Concept("a plus b").def_prop("a").def_prop("b"),
|
||||
"if": Concept("if a then b else c end").def_prop("a").def_prop("b").def_prop("c"),
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"three": Concept("three"),
|
||||
"twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_prop("unit"),
|
||||
}
|
||||
sya_def = {
|
||||
concepts_map["plus"]: (5, SyaAssociativity.Right),
|
||||
concepts_map["mult"]: (10, SyaAssociativity.Right), # precedence greater than plus
|
||||
}
|
||||
sheerka, context, parser = self.init_parser(concepts_map, sya_def)
|
||||
# concepts_map = {
|
||||
# "prefixed": Concept("a prefixed").def_var("a"),
|
||||
# "suffixed": Concept("suffixed a").def_var("a"),
|
||||
# "mult": Concept("a mult b").def_var("a").def_var("b"),
|
||||
# "plus": Concept("a plus b").def_var("a").def_var("b"),
|
||||
# "if": Concept("if a then b else c end").def_var("a").def_var("b").def_var("c"),
|
||||
# "one": Concept("one"),
|
||||
# "two": Concept("two"),
|
||||
# "three": Concept("three"),
|
||||
# "twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_var("unit"),
|
||||
# }
|
||||
# sya_def = {
|
||||
# concepts_map["plus"]: (5, SyaAssociativity.Right),
|
||||
# concepts_map["mult"]: (10, SyaAssociativity.Right), # precedence greater than plus
|
||||
# }
|
||||
sheerka, context, parser = self.init_parser()
|
||||
|
||||
res = parser.parse(context, text)
|
||||
wrapper = res.body
|
||||
lexer_nodes = res.body.body
|
||||
|
||||
expected_array = compute_expected_array(concepts_map, text, expected_result)
|
||||
expected_array = compute_expected_array(cmap, text, expected_result)
|
||||
assert res.status == expected_status
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == expected_array
|
||||
@@ -1080,15 +1121,15 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
# ])
|
||||
# def test_i_can_parse_when_multiple_results(self, text, list_of_expected):
|
||||
# concepts_map = {
|
||||
# "prefixed": Concept("a prefixed").def_prop("a"),
|
||||
# "suffixed": Concept("suffixed a").def_prop("a"),
|
||||
# "mult": Concept("a mult b").def_prop("a").def_prop("b"),
|
||||
# "plus": Concept("a plus b").def_prop("a").def_prop("b"),
|
||||
# "if": Concept("if a then b else c end").def_prop("a").def_prop("b").def_prop("c"),
|
||||
# "prefixed": Concept("a prefixed").def_var("a"),
|
||||
# "suffixed": Concept("suffixed a").def_var("a"),
|
||||
# "mult": Concept("a mult b").def_var("a").def_var("b"),
|
||||
# "plus": Concept("a plus b").def_var("a").def_var("b"),
|
||||
# "if": Concept("if a then b else c end").def_var("a").def_var("b").def_var("c"),
|
||||
# "one": Concept("one"),
|
||||
# "two": Concept("two"),
|
||||
# "three": Concept("three"),
|
||||
# "twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_prop("unit"),
|
||||
# "twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_var("unit"),
|
||||
# }
|
||||
# sya_def = {
|
||||
# concepts_map["plus"]: (5, SyaAssociativity.Right),
|
||||
@@ -1116,13 +1157,13 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
("x$!# infix z$!#", "infix", ["a", "b"]),
|
||||
])
|
||||
def test_i_cannot_parse_when_unrecognized(self, text, expected_concept, expected_unrecognized):
|
||||
concepts_map = {
|
||||
"suffixed": Concept("suffixed a").def_prop("a"),
|
||||
"prefixed": Concept("a prefixed").def_prop("a"),
|
||||
"infix": Concept("a infix b").def_prop("a").def_prop("b"),
|
||||
"one": Concept("one")
|
||||
}
|
||||
sheerka, context, parser = self.init_parser(concepts_map, None)
|
||||
# concepts_map = {
|
||||
# "suffixed": Concept("suffixed a").def_var("a"),
|
||||
# "prefixed": Concept("a prefixed").def_var("a"),
|
||||
# "infix": Concept("a infix b").def_var("a").def_var("b"),
|
||||
# "one": Concept("one")
|
||||
# }
|
||||
sheerka, context, parser = self.init_parser()
|
||||
|
||||
res = parser.parse(context, text)
|
||||
wrapper = res.body
|
||||
@@ -1131,7 +1172,7 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert not res.status
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert lexer_nodes == [ConceptNode(concepts_map[expected_concept], 0, expected_end, source=text)]
|
||||
assert lexer_nodes == [ConceptNode(cmap[expected_concept], 0, expected_end, source=text)]
|
||||
|
||||
concept_found = lexer_nodes[0].concept
|
||||
for unrecognized in expected_unrecognized:
|
||||
@@ -1142,14 +1183,14 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
("one prefixed x$!#", [cnode("__var__0 prefixed", 0, 2, "one prefixed"), utnode(3, 7, " x$!#")]),
|
||||
])
|
||||
def test_i_cannot_parse_when_part_of_the_sequence_is_not_recognized(self, text, expected):
|
||||
concepts_map = {
|
||||
"suffixed": Concept("suffixed a").def_prop("a"),
|
||||
"prefixed": Concept("a prefixed").def_prop("a"),
|
||||
"infix": Concept("a infix b").def_prop("a").def_prop("b"),
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
}
|
||||
sheerka, context, parser = self.init_parser(concepts_map, None)
|
||||
# concepts_map = {
|
||||
# "suffixed": Concept("suffixed a").def_var("a"),
|
||||
# "prefixed": Concept("a prefixed").def_var("a"),
|
||||
# "infix": Concept("a infix b").def_var("a").def_var("b"),
|
||||
# "one": Concept("one"),
|
||||
# "two": Concept("two"),
|
||||
# }
|
||||
sheerka, context, parser = self.init_parser()
|
||||
|
||||
res = parser.parse(context, text)
|
||||
wrapper = res.body
|
||||
@@ -1173,14 +1214,14 @@ class TestSyaConceptLexerParser(TestUsingMemoryBasedSheerka):
|
||||
Atoms concepts, source code or BNF concepts alone are discarded by the lexer
|
||||
:return:
|
||||
"""
|
||||
concepts_map = {
|
||||
"plus": Concept("a plus b").def_prop("a").def_prop("b"),
|
||||
"one": Concept("one"),
|
||||
"two": Concept("two"),
|
||||
"three": Concept("three"),
|
||||
"twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_prop("unit"),
|
||||
}
|
||||
sheerka, context, parser = self.init_parser(concepts_map, None)
|
||||
# concepts_map = {
|
||||
# "plus": Concept("a plus b").def_var("a").def_var("b"),
|
||||
# "one": Concept("one"),
|
||||
# "two": Concept("two"),
|
||||
# "three": Concept("three"),
|
||||
# "twenties": Concept("twenties", definition="'twenty' (one|two)=unit").def_var("unit"),
|
||||
# }
|
||||
sheerka, context, parser = self.init_parser()
|
||||
|
||||
res = parser.parse(context, text)
|
||||
|
||||
@@ -42,17 +42,17 @@ def get_input_nodes_from(my_concepts_map, full_expr, *args):
|
||||
|
||||
|
||||
concepts_map = {
|
||||
"5params": Concept("5params").def_prop("a").def_prop("b").def_prop("c").def_prop("d").def_prop("e"),
|
||||
"plus": Concept("a plus b", body="a + b").def_prop("a").def_prop("b"),
|
||||
"mult": Concept("a mult b", body="a * b").def_prop("a").def_prop("b"),
|
||||
"5params": Concept("5params").def_var("a").def_var("b").def_var("c").def_var("d").def_var("e"),
|
||||
"plus": Concept("a plus b", body="a + b").def_var("a").def_var("b"),
|
||||
"mult": Concept("a mult b", body="a * b").def_var("a").def_var("b"),
|
||||
"one": Concept("one", body="1"),
|
||||
"two": Concept("two", body="2"),
|
||||
"three": Concept("three", body="3"),
|
||||
"twenties": Concept("twenties", definition="'twenty' (one|two)=unit", body="20 + unit").def_prop("unit"),
|
||||
"twenties": Concept("twenties", definition="'twenty' (one|two)=unit", body="20 + unit").def_var("unit"),
|
||||
"hello_atom": Concept("hello one"),
|
||||
"hello_sya": Concept("hello a").def_prop("a"),
|
||||
"greetings_a": Concept("greetings a").def_prop("a"),
|
||||
"greetings_b": Concept("greetings b").def_prop("b"),
|
||||
"hello_sya": Concept("hello a").def_var("a"),
|
||||
"greetings_a": Concept("greetings a").def_var("a"),
|
||||
"greetings_b": Concept("greetings b").def_var("b"),
|
||||
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
|
||||
def setup_class(cls):
|
||||
t = TestUnrecognizedNodeParser()
|
||||
TestUnrecognizedNodeParser.sheerka, context, _ = t.init_parser(concepts_map, create_new=True)
|
||||
TestUnrecognizedNodeParser.sheerka.set_sya_def(context, [
|
||||
TestUnrecognizedNodeParser.sheerka.force_sya_def(context, [
|
||||
(concepts_map["mult"].id, 20, SyaAssociativity.Right),
|
||||
(concepts_map["plus"].id, 10, SyaAssociativity.Right),
|
||||
])
|
||||
@@ -144,13 +144,15 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
|
||||
expected_nodes = compute_expected_array(
|
||||
concepts_map,
|
||||
" one plus two mult three ",
|
||||
[CNC("plus", a="one", b=CC("mult", a="two", b="three"))])
|
||||
[CNC("plus", a="one", b=CC("mult", a="two", b="three"))],
|
||||
exclude_body=True)
|
||||
|
||||
assert concept.compiled["e"][0].body.body == expected_nodes
|
||||
|
||||
# # sanity check, I can evaluate the concept
|
||||
# evaluated = sheerka.evaluate_concept(self.get_context(sheerka, eval_body=True), concept)
|
||||
# assert evaluated.key == concept.key
|
||||
# assert evaluated.get_prop("a") ==
|
||||
# assert evaluated.get_value("a") ==
|
||||
|
||||
def test_i_can_validate_with_recursion(self):
|
||||
sheerka, context, parser = self.init_parser()
|
||||
@@ -246,6 +248,22 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
|
||||
assert len(actual_nodes) == 1
|
||||
assert actual_nodes[0] == scnode(0, 4, expression)
|
||||
|
||||
def test_i_cannot_parse_unrecognized_python_that_looks_like_concept(self):
|
||||
sheerka, context, parser = self.init_parser()
|
||||
|
||||
expression = "fake_concept_name" # as it's not a concept, it will be recognized as python node
|
||||
nodes = get_input_nodes_from(concepts_map, expression, UTN(expression))
|
||||
parser_input = ParserResultConcept("parsers.xxx", source=expression, value=nodes)
|
||||
|
||||
res = parser.parse(context, parser_input)
|
||||
parser_result = res.body
|
||||
actual_nodes = res.body.body
|
||||
|
||||
assert not res.status
|
||||
assert sheerka.isinstance(parser_result, BuiltinConcepts.PARSER_RESULT)
|
||||
assert len(actual_nodes) == 1
|
||||
assert actual_nodes[0] == nodes[0]
|
||||
|
||||
def test_i_can_parse_unrecognized_bnf_concept_node(self):
|
||||
|
||||
sheerka, context, parser = self.init_parser()
|
||||
@@ -285,7 +303,8 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
|
||||
concepts_map,
|
||||
expression, [CNC("plus",
|
||||
a="one",
|
||||
b=CC("mult", source="two mult three", a="two", b="three"))])
|
||||
b=CC("mult", source="two mult three", a="two", b="three"))],
|
||||
exclude_body=True)
|
||||
assert actual_nodes == expected_array
|
||||
|
||||
def test_i_can_parse_sequences(self):
|
||||
@@ -314,7 +333,7 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
|
||||
expression = "two hello one three"
|
||||
nodes = get_input_nodes_from(concepts_map, expression,
|
||||
"two", UTN("hello one"), "three")
|
||||
parser_input = ParserResultConcept("parsers.xxx", source="one plus two hello one", value=nodes)
|
||||
parser_input = ParserResultConcept("parsers.xxx", source=expression, value=nodes)
|
||||
|
||||
res = parser.parse(context, parser_input)
|
||||
assert len(res) == 2
|
||||
@@ -332,7 +351,8 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
|
||||
expected_1 = compute_expected_array(concepts_map, expression, [
|
||||
CN("two", 0, 0),
|
||||
CNC("hello_sya", source="hello one", start=2, end=4, a="one"),
|
||||
CN("three", 6, 6)])
|
||||
CN("three", 6, 6)],
|
||||
exclude_body=True)
|
||||
|
||||
assert actual_nodes1 == expected_1
|
||||
|
||||
@@ -341,7 +361,7 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
|
||||
expression = "greetings two"
|
||||
nodes = get_input_nodes_from(concepts_map, expression, UTN("greetings two"))
|
||||
|
||||
parser_input = ParserResultConcept("parsers.xxx", source="greetings two", value=nodes)
|
||||
parser_input = ParserResultConcept("parsers.xxx", source=expression, value=nodes)
|
||||
|
||||
res = parser.parse(context, parser_input)
|
||||
assert len(res) == 2
|
||||
@@ -350,14 +370,25 @@ class TestUnrecognizedNodeParser(TestUsingMemoryBasedSheerka):
|
||||
|
||||
actual_nodes0 = res[0].body.body
|
||||
expected_0 = compute_expected_array(concepts_map, expression, [
|
||||
CNC("greetings_a", source="greetings two", start=0, end=2, a="two")])
|
||||
CNC("greetings_a", source="greetings two", start=0, end=2, a="two")], exclude_body=True)
|
||||
assert actual_nodes0 == expected_0
|
||||
|
||||
actual_nodes1 = res[1].body.body
|
||||
expected_1 = compute_expected_array(concepts_map, expression, [
|
||||
CNC("greetings_b", source="greetings two", start=0, end=2, b="two")])
|
||||
CNC("greetings_b", source="greetings two", start=0, end=2, b="two")], exclude_body=True)
|
||||
assert actual_nodes1 == expected_1
|
||||
|
||||
def test_i_cannot_parse_when_some_unrecognized_remain(self):
|
||||
sheerka, context, parser = self.init_parser()
|
||||
expression = "twenty one + one"
|
||||
nodes = get_input_nodes_from(concepts_map, expression, UTN("twenty "), "one", " + ", ("one", 1))
|
||||
|
||||
parser_input = ParserResultConcept("parsers.xxx", source=expression, value=nodes)
|
||||
res = parser.parse(context, parser_input)
|
||||
|
||||
assert not res.status
|
||||
assert res.body.body == nodes
|
||||
|
||||
def test_i_cannot_parse_when_i_cannot_validate(self):
|
||||
sheerka, context, parser = self.init_parser(concepts_map, create_new=True)
|
||||
expression = "one plus unknown tokens"
|
||||
|
||||
+155
-1996
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -22,14 +22,14 @@ class Obj:
|
||||
|
||||
|
||||
def test_i_can_serialize_an_event():
|
||||
event = Event("test", user="user", date=datetime.fromisoformat("2019-10-21T10:20:30.999"))
|
||||
event = Event("test", user_id="user", date=datetime.fromisoformat("2019-10-21T10:20:30.999"))
|
||||
serializer = Serializer()
|
||||
|
||||
stream = serializer.serialize(event, None)
|
||||
loaded = serializer.deserialize(stream, None)
|
||||
|
||||
assert event.version == loaded.version
|
||||
assert event.user == loaded.user
|
||||
assert event.user_id == loaded.user_id
|
||||
assert event.date == loaded.date
|
||||
assert event.message == loaded.message
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import sheerkapickle
|
||||
from core.builtin_concepts import BuiltinConcepts, UserInputConcept, ReturnValueConcept
|
||||
from core.builtin_concepts import BuiltinConcepts, ReturnValueConcept
|
||||
from core.concept import Concept, ConceptParts
|
||||
from core.sheerka.ExecutionContext import ExecutionContext
|
||||
from core.tokenizer import Tokenizer
|
||||
@@ -56,10 +56,11 @@ class TestSheerkaPickleHandler(TestUsingMemoryBasedSheerka):
|
||||
assert decoded == concept
|
||||
assert to_string == '{"_sheerka/obj": "core.concept.Concept", "meta.name": "foo", "meta.where": "my_where"}'
|
||||
|
||||
concept = set_full_serialization(Concept("foo").def_prop("a", "value_a").def_prop("b", "value_b"))
|
||||
concept = set_full_serialization(Concept("foo").def_var("a", "value_a").def_var("b", "value_b"))
|
||||
to_string = sheerkapickle.encode(sheerka, concept)
|
||||
decoded = sheerkapickle.decode(sheerka, to_string)
|
||||
assert decoded == concept
|
||||
assert to_string == '{"_sheerka/obj": "core.concept.Concept", "meta.name": "foo", "meta.variables": [["a", "value_a"], ["b", "value_b"]], "values": [["a", null], ["b", null]]}'
|
||||
|
||||
concept = Concept("foo").init_key()
|
||||
sheerka.create_new_concept(self.get_context(sheerka), concept)
|
||||
@@ -73,76 +74,76 @@ class TestSheerkaPickleHandler(TestUsingMemoryBasedSheerka):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
concept = set_full_serialization(Concept("foo"))
|
||||
concept.values[ConceptParts.PRE] = 10 # an int
|
||||
concept.set_value(ConceptParts.PRE, 10) # an int
|
||||
to_string = sheerkapickle.encode(sheerka, concept)
|
||||
decoded = sheerkapickle.decode(sheerka, to_string)
|
||||
assert decoded == concept
|
||||
assert to_string == '{"_sheerka/obj": "core.concept.Concept", "meta.name": "foo", "pre": 10}'
|
||||
assert to_string == '{"_sheerka/obj": "core.concept.Concept", "meta.name": "foo", "values": [["cParts.pre", 10]]}'
|
||||
|
||||
concept = set_full_serialization(Concept("foo"))
|
||||
concept.values[ConceptParts.POST] = 'a string' # an string
|
||||
concept.set_value(ConceptParts.POST, 'a string') # an string
|
||||
to_string = sheerkapickle.encode(sheerka, concept)
|
||||
decoded = sheerkapickle.decode(sheerka, to_string)
|
||||
assert decoded == concept
|
||||
assert to_string == '{"_sheerka/obj": "core.concept.Concept", "meta.name": "foo", "post": "a string"}'
|
||||
assert to_string == '{"_sheerka/obj": "core.concept.Concept", "meta.name": "foo", "values": [["cParts.post", "a string"]]}'
|
||||
|
||||
concept = set_full_serialization(Concept("foo"))
|
||||
concept.values[ConceptParts.WHERE] = ['a string', 3.14] # a list
|
||||
concept.set_value(ConceptParts.WHERE, ['a string', 3.14]) # a list
|
||||
to_string = sheerkapickle.encode(sheerka, concept)
|
||||
decoded = sheerkapickle.decode(sheerka, to_string)
|
||||
assert decoded == concept
|
||||
assert to_string == '{"_sheerka/obj": "core.concept.Concept", "meta.name": "foo", "where": ["a string", 3.14]}'
|
||||
assert to_string == '{"_sheerka/obj": "core.concept.Concept", "meta.name": "foo", "values": [["cParts.where", ["a string", 3.14]]]}'
|
||||
|
||||
concept = set_full_serialization(Concept("foo"))
|
||||
concept.values[ConceptParts.WHERE] = ('a string', 3.14) # a tuple
|
||||
concept.set_value(ConceptParts.WHERE, ('a string', 3.14)) # a tuple
|
||||
to_string = sheerkapickle.encode(sheerka, concept)
|
||||
decoded = sheerkapickle.decode(sheerka, to_string)
|
||||
assert decoded == concept
|
||||
assert to_string == '{"_sheerka/obj": "core.concept.Concept", "meta.name": "foo", "where": {"_sheerka/tuple": ["a string", 3.14]}}'
|
||||
assert to_string == '{"_sheerka/obj": "core.concept.Concept", "meta.name": "foo", "values": [["cParts.where", {"_sheerka/tuple": ["a string", 3.14]}]]}'
|
||||
|
||||
concept = set_full_serialization(Concept("foo"))
|
||||
concept.values[ConceptParts.BODY] = set_full_serialization(Concept("foo", body="foo_body"))
|
||||
concept.set_value(ConceptParts.BODY, set_full_serialization(Concept("foo", body="foo_body")))
|
||||
to_string = sheerkapickle.encode(sheerka, concept)
|
||||
decoded = sheerkapickle.decode(sheerka, to_string)
|
||||
assert decoded == concept
|
||||
assert to_string == '{"_sheerka/obj": "core.concept.Concept", "meta.name": "foo", "body": {"_sheerka/obj": "core.concept.Concept", "meta.name": "foo", "meta.body": "foo_body"}}'
|
||||
assert to_string == '{"_sheerka/obj": "core.concept.Concept", "meta.name": "foo", "values": [["cParts.body", {"_sheerka/obj": "core.concept.Concept", "meta.name": "foo", "meta.body": "foo_body"}]]}'
|
||||
|
||||
def test_i_can_encode_decode_unknown_concept_properties(self):
|
||||
def test_i_can_encode_decode_unknown_concept_variables(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
concept = set_full_serialization(Concept("foo"))
|
||||
concept.set_prop("a", "value_a") # string
|
||||
concept.set_value("a", "value_a") # string
|
||||
to_string = sheerkapickle.encode(sheerka, concept)
|
||||
decoded = sheerkapickle.decode(sheerka, to_string)
|
||||
assert decoded == concept
|
||||
assert to_string == '{"_sheerka/obj": "core.concept.Concept", "meta.name": "foo", "props": [["a", "value_a"]]}'
|
||||
assert to_string == '{"_sheerka/obj": "core.concept.Concept", "meta.name": "foo", "values": [["a", "value_a"]]}'
|
||||
|
||||
concept = set_full_serialization(Concept("foo"))
|
||||
concept.set_prop("a", 10) # int
|
||||
concept.set_value("a", 10) # int
|
||||
to_string = sheerkapickle.encode(sheerka, concept)
|
||||
decoded = sheerkapickle.decode(sheerka, to_string)
|
||||
assert decoded == concept
|
||||
assert to_string == '{"_sheerka/obj": "core.concept.Concept", "meta.name": "foo", "props": [["a", 10]]}'
|
||||
assert to_string == '{"_sheerka/obj": "core.concept.Concept", "meta.name": "foo", "values": [["a", 10]]}'
|
||||
|
||||
concept = set_full_serialization(Concept("foo"))
|
||||
concept.set_prop("a", set_full_serialization(Concept("bar"))) # another concept
|
||||
concept.set_value("a", set_full_serialization(Concept("bar"))) # another concept
|
||||
to_string = sheerkapickle.encode(sheerka, concept)
|
||||
decoded = sheerkapickle.decode(sheerka, to_string)
|
||||
assert decoded == concept
|
||||
assert to_string == '{"_sheerka/obj": "core.concept.Concept", "meta.name": "foo", "props": [["a", {"_sheerka/obj": "core.concept.Concept", "meta.name": "bar"}]]}'
|
||||
assert to_string == '{"_sheerka/obj": "core.concept.Concept", "meta.name": "foo", "values": [["a", {"_sheerka/obj": "core.concept.Concept", "meta.name": "bar"}]]}'
|
||||
|
||||
concept = set_full_serialization(Concept("foo"))
|
||||
concept.set_prop("a", "a").set_prop("b", "b") # at least two props
|
||||
concept.set_value("a", "a").set_value("b", "b") # at least two variables
|
||||
to_string = sheerkapickle.encode(sheerka, concept)
|
||||
decoded = sheerkapickle.decode(sheerka, to_string)
|
||||
assert decoded == concept
|
||||
assert to_string == '{"_sheerka/obj": "core.concept.Concept", "meta.name": "foo", "props": [["a", "a"], ["b", "b"]]}'
|
||||
assert to_string == '{"_sheerka/obj": "core.concept.Concept", "meta.name": "foo", "values": [["a", "a"], ["b", "b"]]}'
|
||||
|
||||
def test_i_can_encode_decode_known_concepts(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
ref_concept = Concept("my_name", True, True, "my_key", "my_body", "my_where", "my_pre", "my_post", "my_def")
|
||||
ref_concept.def_prop("a", "value_a").def_prop("b", "value_b")
|
||||
ref_concept.def_var("a", "value_a").def_var("b", "value_b")
|
||||
|
||||
sheerka.create_new_concept(self.get_context(sheerka), ref_concept)
|
||||
|
||||
@@ -153,29 +154,30 @@ class TestSheerkaPickleHandler(TestUsingMemoryBasedSheerka):
|
||||
|
||||
# same test, modify a value and check if this modification is correctly saved
|
||||
concept = Concept().update_from(sheerka.get_by_id(ref_concept.id))
|
||||
concept.set_metadata_value(ConceptParts.BODY, set_full_serialization(Concept("bar")))
|
||||
concept.set_value(ConceptParts.BODY, set_full_serialization(Concept("bar")))
|
||||
to_string = sheerkapickle.encode(sheerka, concept)
|
||||
decoded = sheerkapickle.decode(sheerka, to_string)
|
||||
assert decoded == concept
|
||||
assert to_string == '{"_sheerka/obj": "core.concept.Concept", "concept/id": ["my_key", "1001"], "body": {"_sheerka/obj": "core.concept.Concept", "meta.name": "bar"}}'
|
||||
assert to_string == '{"_sheerka/obj": "core.concept.Concept", "concept/id": ["my_key", "1001"], "values": [["cParts.body", {"_sheerka/obj": "core.concept.Concept", "meta.name": "bar"}]]}'
|
||||
|
||||
def test_i_can_encode_decode_when_property_is_a_concept(self):
|
||||
def test_i_can_encode_decode_when_variable_is_a_concept(self):
|
||||
sheerka = self.get_sheerka()
|
||||
|
||||
foo = Concept("foo").init_key()
|
||||
foo = Concept("foo")
|
||||
sheerka.create_new_concept(self.get_context(sheerka), foo)
|
||||
|
||||
concept = Concept("my_name").init_key()
|
||||
concept = Concept("my_name")
|
||||
sheerka.create_new_concept(self.get_context(sheerka), concept)
|
||||
concept.def_prop(foo, "a value")
|
||||
concept.def_var(foo, "a value")
|
||||
concept.set_value(foo, "another value")
|
||||
concept.metadata.full_serialization = True
|
||||
|
||||
to_string = sheerkapickle.encode(sheerka, concept)
|
||||
decoded = sheerkapickle.decode(sheerka, to_string)
|
||||
assert decoded == concept
|
||||
assert to_string == '{"_sheerka/obj": "core.concept.Concept", "meta.name": "my_name", "meta.key": "my_name", ' + \
|
||||
'"meta.props": [{"_sheerka/tuple": [{"_sheerka/obj": "core.concept.Concept", "concept/id": ["foo", "1001"]}, "a value"]}], ' + \
|
||||
'"meta.id": "1002", "props": [[{"_sheerka/id": 1}, null]]}'
|
||||
'"meta.variables": [[{"_sheerka/obj": "core.concept.Concept", "concept/id": ["foo", "1001"]}, "a value"]], ' + \
|
||||
'"meta.id": "1002", "values": [[{"_sheerka/id": 1}, "another value"]]}'
|
||||
|
||||
def test_i_can_manage_reference_of_the_same_object(self):
|
||||
sheerka = self.get_sheerka()
|
||||
@@ -183,13 +185,13 @@ class TestSheerkaPickleHandler(TestUsingMemoryBasedSheerka):
|
||||
concept_ref = set_full_serialization(Concept("foo"))
|
||||
|
||||
concept = set_full_serialization(Concept("bar"))
|
||||
concept.set_metadata_value(ConceptParts.PRE, concept_ref)
|
||||
concept.set_metadata_value(ConceptParts.BODY, concept_ref)
|
||||
concept.set_value(ConceptParts.PRE, concept_ref)
|
||||
concept.set_value(ConceptParts.BODY, concept_ref)
|
||||
|
||||
to_string = sheerkapickle.encode(sheerka, concept)
|
||||
decoded = sheerkapickle.decode(sheerka, to_string)
|
||||
assert decoded == concept
|
||||
assert to_string == '{"_sheerka/obj": "core.concept.Concept", "meta.name": "bar", "pre": {"_sheerka/obj": "core.concept.Concept", "meta.name": "foo"}, "body": {"_sheerka/id": 1}}'
|
||||
assert to_string == '{"_sheerka/obj": "core.concept.Concept", "meta.name": "bar", "values": [["cParts.pre", {"_sheerka/obj": "core.concept.Concept", "meta.name": "foo"}], ["cParts.body", {"_sheerka/id": 1}]]}'
|
||||
|
||||
def test_i_can_encode_decode_user_input(self):
|
||||
sheerka = self.get_sheerka()
|
||||
@@ -199,7 +201,7 @@ class TestSheerkaPickleHandler(TestUsingMemoryBasedSheerka):
|
||||
to_string = sheerkapickle.encode(sheerka, user_input)
|
||||
decoded = sheerkapickle.decode(sheerka, to_string)
|
||||
assert decoded == user_input
|
||||
assert to_string == '{"_sheerka/obj": "core.builtin_concepts.UserInputConcept", "concept/id": ["__USER_INPUT", null], "user_name": "my_user_name", "text": "my_text"}'
|
||||
assert to_string == '{"_sheerka/obj": "core.builtin_concepts.UserInputConcept", "concept/id": ["__USER_INPUT", "11"], "user_name": "my_user_name", "text": "my_text"}'
|
||||
|
||||
def test_i_can_encode_decode_user_input_when_tokens(self):
|
||||
sheerka = self.get_sheerka()
|
||||
@@ -210,8 +212,8 @@ class TestSheerkaPickleHandler(TestUsingMemoryBasedSheerka):
|
||||
|
||||
to_string = sheerkapickle.encode(sheerka, user_input)
|
||||
decoded = sheerkapickle.decode(sheerka, to_string)
|
||||
assert decoded == UserInputConcept(text, "my_user_name")
|
||||
assert to_string == '{' + f'"_sheerka/obj": "core.builtin_concepts.UserInputConcept", "concept/id": ["__USER_INPUT", null], "user_name": "my_user_name", "text": "{text}"' + '}'
|
||||
assert decoded == sheerka.new(BuiltinConcepts.USER_INPUT, body=text, user_name="my_user_name")
|
||||
assert to_string == '{' + f'"_sheerka/obj": "core.builtin_concepts.UserInputConcept", "concept/id": ["__USER_INPUT", "11"], "user_name": "my_user_name", "text": "{text}"' + '}'
|
||||
|
||||
def test_i_can_encode_decode_return_value(self):
|
||||
sheerka = self.get_sheerka()
|
||||
@@ -221,7 +223,7 @@ class TestSheerkaPickleHandler(TestUsingMemoryBasedSheerka):
|
||||
to_string = sheerkapickle.encode(sheerka, ret_val)
|
||||
decoded = sheerkapickle.decode(sheerka, to_string)
|
||||
assert decoded == ret_val
|
||||
assert to_string == '{"_sheerka/obj": "core.builtin_concepts.ReturnValueConcept", "concept/id": ["__RETURN_VALUE", null], "who": "who", "status": true, "value": 10}'
|
||||
assert to_string == '{"_sheerka/obj": "core.builtin_concepts.ReturnValueConcept", "concept/id": ["__RETURN_VALUE", "16"], "who": "who", "status": true, "value": 10}'
|
||||
|
||||
def test_i_can_encode_decode_return_value_with_parent(self):
|
||||
sheerka = self.get_sheerka()
|
||||
@@ -234,7 +236,7 @@ class TestSheerkaPickleHandler(TestUsingMemoryBasedSheerka):
|
||||
decoded = sheerkapickle.decode(sheerka, to_string)
|
||||
assert decoded == ret_val
|
||||
assert decoded.parents == ret_val.parents
|
||||
id_str = ', "concept/id": ["__RETURN_VALUE", null]'
|
||||
id_str = ', "concept/id": ["__RETURN_VALUE", "16"]'
|
||||
parents_str = '[{"_sheerka/obj": "core.builtin_concepts.ReturnValueConcept"' + id_str + ', "who": "parent_who", "status": true, "value": "10"}, {"_sheerka/id": 1}]'
|
||||
assert to_string == '{"_sheerka/obj": "core.builtin_concepts.ReturnValueConcept"' + id_str + ', "who": "who", "status": true, "value": 10, "parents": ' + parents_str + '}'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user