Restarting the project.
Fixing unit tests. Continuing SyaParser
This commit is contained in:
+71
-71
@@ -12,103 +12,103 @@ DEFAULT_ONTOLOGY_NAME = "current_test_"
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def sheerka():
|
||||
from core.Sheerka import Sheerka
|
||||
|
||||
sheerka = Sheerka()
|
||||
sheerka.initialize("mem://")
|
||||
return sheerka
|
||||
from core.Sheerka import Sheerka
|
||||
|
||||
sheerka = Sheerka()
|
||||
sheerka.initialize("mem://")
|
||||
return sheerka
|
||||
|
||||
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def on_new_module(sheerka, request):
|
||||
"""
|
||||
For each new module, make sure to create a new ontology
|
||||
Remove it at the end of the module
|
||||
:param sheerka:
|
||||
:type sheerka:
|
||||
:param request:
|
||||
:type request:
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
from core.Event import Event
|
||||
from core.ExecutionContext import ExecutionContext, ContextActions
|
||||
module_name = request.module.__name__.split(".")[-1]
|
||||
context = ExecutionContext("test",
|
||||
Event(message=f"Executing module {module_name}"),
|
||||
sheerka,
|
||||
ContextActions.TESTING,
|
||||
None)
|
||||
|
||||
ontology = sheerka.om.push_ontology(module_name)
|
||||
yield
|
||||
sheerka.om.revert_ontology(context, ontology)
|
||||
"""
|
||||
For each new module, make sure to create a new ontology
|
||||
Remove it at the end of the module
|
||||
:param sheerka:
|
||||
:type sheerka:
|
||||
:param request:
|
||||
:type request:
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
from core.Event import Event
|
||||
from core.ExecutionContext import ExecutionContext, ContextActions
|
||||
module_name = request.module.__name__.split(".")[-1]
|
||||
context = ExecutionContext("test",
|
||||
Event(message=f"Executing module {module_name}"),
|
||||
sheerka,
|
||||
ContextActions.TESTING,
|
||||
None)
|
||||
|
||||
ontology = sheerka.om.push_ontology(module_name)
|
||||
yield
|
||||
sheerka.om.revert_ontology(context, ontology)
|
||||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def context(sheerka):
|
||||
from core.Event import Event
|
||||
from core.ExecutionContext import ExecutionContext, ContextActions
|
||||
|
||||
return ExecutionContext("test",
|
||||
Event(message=""),
|
||||
sheerka,
|
||||
ContextActions.TESTING,
|
||||
None)
|
||||
from core.Event import Event
|
||||
from core.ExecutionContext import ExecutionContext, ContextActions
|
||||
|
||||
return ExecutionContext("test",
|
||||
Event(message=""),
|
||||
sheerka,
|
||||
ContextActions.TESTING,
|
||||
None)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def next_id():
|
||||
return GetNextId()
|
||||
return GetNextId()
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def user():
|
||||
return User(username="johan doe", email="johan.doe@sheerka.com", firstname="johan", lastname="doe")
|
||||
return User(username="johan doe", email="johan.doe@sheerka.com", firstname="johan", lastname="doe")
|
||||
|
||||
|
||||
class TestUsingFileBasedSheerka:
|
||||
@pytest.fixture(scope="class")
|
||||
def sheerka(self):
|
||||
sheerka = Sheerka()
|
||||
sheerka.initialize()
|
||||
return sheerka
|
||||
@pytest.fixture(scope="class")
|
||||
def sheerka(self):
|
||||
sheerka = Sheerka()
|
||||
sheerka.initialize()
|
||||
return sheerka
|
||||
|
||||
|
||||
class NewOntology:
|
||||
"""
|
||||
For some test who may need to declare the same concepts across the tests
|
||||
"""
|
||||
from core.ExecutionContext import ExecutionContext
|
||||
|
||||
def __init__(self, context: ExecutionContext, name=None):
|
||||
self.sheerka = context.sheerka
|
||||
self.context = context
|
||||
self.name = name
|
||||
self.ontology = None
|
||||
|
||||
if self.name is None:
|
||||
self.name = inspect.stack()[1][3]
|
||||
|
||||
def __enter__(self):
|
||||
self.ontology = self.sheerka.om.push_ontology(self.name)
|
||||
return self.ontology
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
self.sheerka.om.revert_ontology(self.context, self.ontology)
|
||||
return False
|
||||
"""
|
||||
For some test who may need to declare the same concepts across the tests
|
||||
"""
|
||||
from core.ExecutionContext import ExecutionContext
|
||||
|
||||
def __init__(self, context: ExecutionContext, name=None):
|
||||
self.sheerka = context.sheerka
|
||||
self.context = context
|
||||
self.name = name
|
||||
self.ontology = None
|
||||
|
||||
if self.name is None:
|
||||
self.name = inspect.stack()[1][3]
|
||||
|
||||
def __enter__(self):
|
||||
self.ontology = self.sheerka.om.push_ontology(self.name)
|
||||
return self.ontology
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
self.sheerka.om.revert_ontology(self.context, self.ontology)
|
||||
return False
|
||||
|
||||
|
||||
def simple_token_compare(a, b):
|
||||
return a.type == b.type and a.value == b.value
|
||||
return a.type == b.type and a.value == b.value
|
||||
|
||||
|
||||
@contextmanager
|
||||
def comparable_tokens():
|
||||
eq = Token.__eq__
|
||||
ne = Token.__ne__
|
||||
setattr(Token, "__eq__", simple_token_compare)
|
||||
setattr(Token, "__ne__", lambda a, b: not simple_token_compare(a, b))
|
||||
yield
|
||||
setattr(Token, "__eq__", eq)
|
||||
setattr(Token, "__ne__", ne)
|
||||
eq = Token.__eq__
|
||||
ne = Token.__ne__
|
||||
setattr(Token, "__eq__", simple_token_compare)
|
||||
setattr(Token, "__ne__", lambda a, b: not simple_token_compare(a, b))
|
||||
yield
|
||||
setattr(Token, "__eq__", eq)
|
||||
setattr(Token, "__ne__", ne)
|
||||
|
||||
+356
-393
@@ -20,12 +20,12 @@ ATTR_MAP = {
|
||||
|
||||
|
||||
class GetNextId:
|
||||
def __init__(self):
|
||||
self.seq = 1000
|
||||
|
||||
def next(self):
|
||||
self.seq += 1
|
||||
return self.seq
|
||||
def __init__(self):
|
||||
self.seq = 1000
|
||||
|
||||
def next(self):
|
||||
self.seq += 1
|
||||
return self.seq
|
||||
|
||||
|
||||
def get_concept(name=None, body=None,
|
||||
@@ -47,126 +47,126 @@ def get_concept(name=None, body=None,
|
||||
autouse=False,
|
||||
sequence=None,
|
||||
init_parameters=True) -> Concept:
|
||||
"""
|
||||
Create a Concept objet
|
||||
Caution : 'id' and 'key' are not initialized
|
||||
"""
|
||||
Create a Concept objet
|
||||
Caution : 'id' and 'key' are not initialized
|
||||
|
||||
:param name:
|
||||
:type name:
|
||||
:param body:
|
||||
:type body:
|
||||
:param id:
|
||||
:type id:
|
||||
:param key:
|
||||
:type key:
|
||||
:param where:
|
||||
:type where:
|
||||
:param pre:
|
||||
:type pre:
|
||||
:param post:
|
||||
:type post:
|
||||
:param ret:
|
||||
:type ret:
|
||||
:param definition:
|
||||
:type definition:
|
||||
:param definition_type:
|
||||
:type definition_type:
|
||||
:param desc:
|
||||
:type desc:
|
||||
:param props:
|
||||
:type props:
|
||||
:param variables:
|
||||
:type variables:
|
||||
:param parameters:
|
||||
:type parameters:
|
||||
:param bound_body:
|
||||
:type bound_body:
|
||||
:param is_builtin:
|
||||
:type is_builtin:
|
||||
:param is_unique:
|
||||
:type is_unique:
|
||||
:param autouse:
|
||||
:type autouse:
|
||||
:param sequence:
|
||||
:type sequence:
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
metadata = get_metadata(
|
||||
name, body,
|
||||
id,
|
||||
key,
|
||||
where,
|
||||
pre,
|
||||
post,
|
||||
ret,
|
||||
definition,
|
||||
definition_type,
|
||||
desc,
|
||||
props,
|
||||
variables,
|
||||
parameters,
|
||||
bound_body,
|
||||
is_builtin,
|
||||
is_unique,
|
||||
autouse
|
||||
)
|
||||
if sequence:
|
||||
metadata.auto_init(sequence)
|
||||
else:
|
||||
metadata.digest = ConceptManager.compute_metadata_digest(metadata)
|
||||
metadata.all_attrs = ConceptManager.compute_all_attrs(metadata.variables)
|
||||
|
||||
if init_parameters and metadata.variables:
|
||||
metadata.parameters = [v[0] if isinstance(v, tuple) else v for v in metadata.variables]
|
||||
|
||||
return Concept(metadata)
|
||||
:param name:
|
||||
:type name:
|
||||
:param body:
|
||||
:type body:
|
||||
:param id:
|
||||
:type id:
|
||||
:param key:
|
||||
:type key:
|
||||
:param where:
|
||||
:type where:
|
||||
:param pre:
|
||||
:type pre:
|
||||
:param post:
|
||||
:type post:
|
||||
:param ret:
|
||||
:type ret:
|
||||
:param definition:
|
||||
:type definition:
|
||||
:param definition_type:
|
||||
:type definition_type:
|
||||
:param desc:
|
||||
:type desc:
|
||||
:param props:
|
||||
:type props:
|
||||
:param variables:
|
||||
:type variables:
|
||||
:param parameters:
|
||||
:type parameters:
|
||||
:param bound_body:
|
||||
:type bound_body:
|
||||
:param is_builtin:
|
||||
:type is_builtin:
|
||||
:param is_unique:
|
||||
:type is_unique:
|
||||
:param autouse:
|
||||
:type autouse:
|
||||
:param sequence:
|
||||
:type sequence:
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
metadata = get_metadata(
|
||||
name, body,
|
||||
id,
|
||||
key,
|
||||
where,
|
||||
pre,
|
||||
post,
|
||||
ret,
|
||||
definition,
|
||||
definition_type,
|
||||
desc,
|
||||
props,
|
||||
variables,
|
||||
parameters,
|
||||
bound_body,
|
||||
is_builtin,
|
||||
is_unique,
|
||||
autouse
|
||||
)
|
||||
if sequence:
|
||||
metadata.auto_init(sequence)
|
||||
else:
|
||||
metadata.digest = ConceptManager.compute_metadata_digest(metadata)
|
||||
metadata.all_attrs = ConceptManager.compute_all_attrs(metadata.variables)
|
||||
|
||||
if init_parameters and metadata.variables:
|
||||
metadata.parameters = [v[0] if isinstance(v, tuple) else v for v in metadata.variables]
|
||||
|
||||
return Concept(metadata)
|
||||
|
||||
|
||||
def get_evaluated_concept(blueprint: Concept | ConceptMetadata, **kwargs):
|
||||
"""
|
||||
Returns a concept where value are already initialized
|
||||
:param blueprint:
|
||||
:type blueprint:
|
||||
:param kwargs:
|
||||
:type kwargs:
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
|
||||
def _isfloat(num):
|
||||
try:
|
||||
float(num)
|
||||
return True
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
res = Concept(blueprint.get_metadata())
|
||||
|
||||
for attr in ATTR_MAP:
|
||||
source_code = getattr(res.get_metadata(), attr)
|
||||
if source_code == "" or source_code is None:
|
||||
value = NotInit
|
||||
elif source_code[0] in ("'", '"'):
|
||||
value = source_code[1:-1]
|
||||
elif source_code in ("True", "False"):
|
||||
value = source_code == "True"
|
||||
elif source_code.isdecimal():
|
||||
value = int(source_code)
|
||||
elif _isfloat(source_code):
|
||||
value = float(source_code)
|
||||
else:
|
||||
raise Exception(f"Cannot manage {attr=}, {source_code=}")
|
||||
|
||||
setattr(res, ATTR_MAP[attr], value)
|
||||
|
||||
# force values
|
||||
for k, v in kwargs.items():
|
||||
res.set_value(ATTR_MAP.get(k, k), v)
|
||||
|
||||
res.get_runtime_info().is_evaluated = True
|
||||
|
||||
return res
|
||||
"""
|
||||
Returns a concept where value are already initialized
|
||||
:param blueprint:
|
||||
:type blueprint:
|
||||
:param kwargs:
|
||||
:type kwargs:
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
|
||||
def _isfloat(num):
|
||||
try:
|
||||
float(num)
|
||||
return True
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
res = Concept(blueprint.get_metadata())
|
||||
|
||||
for attr in ATTR_MAP:
|
||||
source_code = getattr(res.get_metadata(), attr)
|
||||
if source_code == "" or source_code is None:
|
||||
value = NotInit
|
||||
elif source_code[0] in ("'", '"'):
|
||||
value = source_code[1:-1]
|
||||
elif source_code in ("True", "False"):
|
||||
value = source_code == "True"
|
||||
elif source_code.isdecimal():
|
||||
value = int(source_code)
|
||||
elif _isfloat(source_code):
|
||||
value = float(source_code)
|
||||
else:
|
||||
raise Exception(f"Cannot manage {attr=}, {source_code=}")
|
||||
|
||||
setattr(res, ATTR_MAP[attr], value)
|
||||
|
||||
# force values
|
||||
for k, v in kwargs.items():
|
||||
res.set_value(ATTR_MAP.get(k, k), v)
|
||||
|
||||
res.get_runtime_info().is_evaluated = True
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def get_metadata(name=None, body=None,
|
||||
@@ -188,68 +188,68 @@ def get_metadata(name=None, body=None,
|
||||
autouse=False,
|
||||
digest=None,
|
||||
all_attrs=None):
|
||||
new_variables = []
|
||||
if variables:
|
||||
for v in variables:
|
||||
if isinstance(v, tuple):
|
||||
new_variables.append(v)
|
||||
else:
|
||||
new_variables.append((v, NotInit))
|
||||
|
||||
return ConceptMetadata(
|
||||
id,
|
||||
name,
|
||||
key,
|
||||
is_builtin,
|
||||
is_unique,
|
||||
body,
|
||||
where,
|
||||
pre,
|
||||
post,
|
||||
ret,
|
||||
definition,
|
||||
definition_type,
|
||||
desc,
|
||||
autouse,
|
||||
bound_body,
|
||||
props or {},
|
||||
tuple(new_variables),
|
||||
parameters or [],
|
||||
digest,
|
||||
all_attrs,
|
||||
)
|
||||
new_variables = []
|
||||
if variables:
|
||||
for v in variables:
|
||||
if isinstance(v, tuple):
|
||||
new_variables.append(v)
|
||||
else:
|
||||
new_variables.append((v, NotInit))
|
||||
|
||||
return ConceptMetadata(
|
||||
id,
|
||||
name,
|
||||
key,
|
||||
is_builtin,
|
||||
is_unique,
|
||||
body,
|
||||
where,
|
||||
pre,
|
||||
post,
|
||||
ret,
|
||||
definition,
|
||||
definition_type,
|
||||
desc,
|
||||
autouse,
|
||||
bound_body,
|
||||
props or {},
|
||||
tuple(new_variables),
|
||||
parameters or [],
|
||||
digest,
|
||||
all_attrs,
|
||||
)
|
||||
|
||||
|
||||
def metadata_auto_init(self: ConceptMetadata, sequence) -> ConceptMetadata:
|
||||
"""
|
||||
Helper function for the unit tests.
|
||||
This method will be added to the `ConceptMetadata` to ease the writing of the unit tests
|
||||
It properly initializes the ConceptMetadata
|
||||
:param self:
|
||||
:type self:
|
||||
:param sequence:
|
||||
:type sequence:
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
if not self.id:
|
||||
self.id = str(sequence.next())
|
||||
if not self.key:
|
||||
self.key = ConceptManager.create_concept_key(self.name, self.definition, self.variables)
|
||||
if not self.is_unique:
|
||||
self.is_unique = False
|
||||
if not self.is_builtin:
|
||||
self.is_builtin = False
|
||||
if not self.definition_type:
|
||||
self.definition_type = DefinitionType.DEFAULT
|
||||
if not self.all_attrs:
|
||||
self.all_attrs = ConceptManager.compute_all_attrs(self.variables)
|
||||
if not self.digest:
|
||||
self.digest = ConceptManager.compute_metadata_digest(self)
|
||||
|
||||
# Note that I do not automatically update the digest as I don't want to make unnecessary computations
|
||||
|
||||
return self
|
||||
"""
|
||||
Helper function for the unit tests.
|
||||
This method will be added to the `ConceptMetadata` to ease the writing of the unit tests
|
||||
It properly initializes the ConceptMetadata
|
||||
:param self:
|
||||
:type self:
|
||||
:param sequence:
|
||||
:type sequence:
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
if not self.id:
|
||||
self.id = str(sequence.next())
|
||||
if not self.key:
|
||||
self.key = ConceptManager.create_concept_key(self.name, self.definition, self.variables)
|
||||
if not self.is_unique:
|
||||
self.is_unique = False
|
||||
if not self.is_builtin:
|
||||
self.is_builtin = False
|
||||
if not self.definition_type:
|
||||
self.definition_type = DefinitionType.DEFAULT
|
||||
if not self.all_attrs:
|
||||
self.all_attrs = ConceptManager.compute_all_attrs(self.variables)
|
||||
if not self.digest:
|
||||
self.digest = ConceptManager.compute_metadata_digest(self)
|
||||
|
||||
# Note that I do not automatically update the digest as I don't want to make unnecessary computations
|
||||
|
||||
return self
|
||||
|
||||
|
||||
def metadata_clone(self: ConceptMetadata, name=None, body=None,
|
||||
@@ -270,75 +270,75 @@ def metadata_clone(self: ConceptMetadata, name=None, body=None,
|
||||
autouse=None,
|
||||
digest=None,
|
||||
all_attrs=None) -> ConceptMetadata:
|
||||
"""
|
||||
Helper function for the unit tests.
|
||||
This method will be added to the `ConceptMetadata` to ease the writing of the unit tests
|
||||
It clones a ConceptMetadata, but can override some attributes if requested
|
||||
:param self:
|
||||
:type self:
|
||||
:param name:
|
||||
:type name:
|
||||
:param body:
|
||||
:type body:
|
||||
:param key:
|
||||
:type key:
|
||||
:param where:
|
||||
:type where:
|
||||
:param pre:
|
||||
:type pre:
|
||||
:param post:
|
||||
:type post:
|
||||
:param ret:
|
||||
:type ret:
|
||||
:param definition:
|
||||
:type definition:
|
||||
:param definition_type:
|
||||
:type definition_type:
|
||||
:param desc:
|
||||
:type desc:
|
||||
:param props:
|
||||
:type props:
|
||||
:param variables:
|
||||
:type variables:
|
||||
:param parameters:
|
||||
:type parameters:
|
||||
:param bound_body:
|
||||
:type bound_body:
|
||||
:param is_builtin:
|
||||
:type is_builtin:
|
||||
:param is_unique:
|
||||
:type is_unique:
|
||||
:param autouse:
|
||||
:type autouse:
|
||||
:param digest:
|
||||
:type digest:
|
||||
:param all_attrs:
|
||||
:type all_attrs:
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
return ConceptMetadata(
|
||||
id=self.id,
|
||||
name=self.name if name is None else name,
|
||||
body=self.body if body is None else body,
|
||||
key=self.key if key is None else key,
|
||||
where=self.where if where is None else where,
|
||||
pre=self.pre if pre is None else pre,
|
||||
post=self.post if post is None else post,
|
||||
ret=self.ret if ret is None else ret,
|
||||
definition=self.definition if definition is None else definition,
|
||||
definition_type=self.definition_type if definition_type is None else definition_type,
|
||||
desc=self.desc if desc is None else desc,
|
||||
props=self.props if props is None else props,
|
||||
variables=self.variables if variables is None else variables,
|
||||
parameters=self.parameters if parameters is None else parameters,
|
||||
bound_body=self.bound_body if bound_body is None else bound_body,
|
||||
is_builtin=self.is_builtin if is_builtin is None else is_builtin,
|
||||
is_unique=self.is_unique if is_unique is None else is_unique,
|
||||
autouse=self.autouse if autouse is None else autouse,
|
||||
digest=self.digest if digest is None else digest,
|
||||
all_attrs=self.all_attrs if all_attrs is None else all_attrs,
|
||||
)
|
||||
"""
|
||||
Helper function for the unit tests.
|
||||
This method will be added to the `ConceptMetadata` to ease the writing of the unit tests
|
||||
It clones a ConceptMetadata, but can override some attributes if requested
|
||||
:param self:
|
||||
:type self:
|
||||
:param name:
|
||||
:type name:
|
||||
:param body:
|
||||
:type body:
|
||||
:param key:
|
||||
:type key:
|
||||
:param where:
|
||||
:type where:
|
||||
:param pre:
|
||||
:type pre:
|
||||
:param post:
|
||||
:type post:
|
||||
:param ret:
|
||||
:type ret:
|
||||
:param definition:
|
||||
:type definition:
|
||||
:param definition_type:
|
||||
:type definition_type:
|
||||
:param desc:
|
||||
:type desc:
|
||||
:param props:
|
||||
:type props:
|
||||
:param variables:
|
||||
:type variables:
|
||||
:param parameters:
|
||||
:type parameters:
|
||||
:param bound_body:
|
||||
:type bound_body:
|
||||
:param is_builtin:
|
||||
:type is_builtin:
|
||||
:param is_unique:
|
||||
:type is_unique:
|
||||
:param autouse:
|
||||
:type autouse:
|
||||
:param digest:
|
||||
:type digest:
|
||||
:param all_attrs:
|
||||
:type all_attrs:
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
return ConceptMetadata(
|
||||
id=self.id,
|
||||
name=self.name if name is None else name,
|
||||
body=self.body if body is None else body,
|
||||
key=self.key if key is None else key,
|
||||
where=self.where if where is None else where,
|
||||
pre=self.pre if pre is None else pre,
|
||||
post=self.post if post is None else post,
|
||||
ret=self.ret if ret is None else ret,
|
||||
definition=self.definition if definition is None else definition,
|
||||
definition_type=self.definition_type if definition_type is None else definition_type,
|
||||
desc=self.desc if desc is None else desc,
|
||||
props=self.props if props is None else props,
|
||||
variables=self.variables if variables is None else variables,
|
||||
parameters=self.parameters if parameters is None else parameters,
|
||||
bound_body=self.bound_body if bound_body is None else bound_body,
|
||||
is_builtin=self.is_builtin if is_builtin is None else is_builtin,
|
||||
is_unique=self.is_unique if is_unique is None else is_unique,
|
||||
autouse=self.autouse if autouse is None else autouse,
|
||||
digest=self.digest if digest is None else digest,
|
||||
all_attrs=self.all_attrs if all_attrs is None else all_attrs,
|
||||
)
|
||||
|
||||
|
||||
# Helpers functions for unit tests
|
||||
@@ -347,175 +347,138 @@ setattr(ConceptMetadata, 'clone', metadata_clone)
|
||||
|
||||
|
||||
def get_metadatas(*args, **kwargs):
|
||||
as_metadatas = [arg if isinstance(arg, ConceptMetadata) else get_metadata(arg) for arg in args]
|
||||
next_id = kwargs.get("next_id", None)
|
||||
if next_id:
|
||||
for metadata in as_metadatas:
|
||||
metadata_auto_init(metadata, next_id)
|
||||
|
||||
return as_metadatas
|
||||
as_metadatas = [arg if isinstance(arg, ConceptMetadata) else get_metadata(arg) for arg in args]
|
||||
next_id = kwargs.get("next_id", None)
|
||||
if next_id:
|
||||
for metadata in as_metadatas:
|
||||
metadata_auto_init(metadata, next_id)
|
||||
|
||||
return as_metadatas
|
||||
|
||||
|
||||
def get_concepts(context: ExecutionContext, *concepts, **kwargs) -> list[Concept]:
|
||||
"""
|
||||
Simple and quick way to get initialize concepts for a test
|
||||
:param context:
|
||||
:param concepts: Concepts to create
|
||||
:param kwargs: named parameters to tweak the creation of the concepts
|
||||
use_sheerka : Adds the new concepts to Sheerka. If not simply creates concepts that do not affect Sheerka
|
||||
sequence : Sequence Manager, to give a correct id to the created concepts
|
||||
:return: the concepts
|
||||
"""
|
||||
res = []
|
||||
use_sheerka = kwargs.pop("use_sheerka", False)
|
||||
sequence = kwargs.pop("sequence", None)
|
||||
for c in concepts:
|
||||
if use_sheerka:
|
||||
c = define_new_concept(context, c)
|
||||
elif isinstance(c, str):
|
||||
c = get_concept(c)
|
||||
|
||||
if sequence:
|
||||
c.get_metadata().auto_init(sequence)
|
||||
|
||||
res.append(c)
|
||||
|
||||
return res
|
||||
"""
|
||||
Simple and quick way to get initialize concepts for a test
|
||||
:param context:
|
||||
:param concepts: Concepts to create
|
||||
:param kwargs: named parameters to tweak the creation of the concepts
|
||||
use_sheerka : Adds the new concepts to Sheerka. If not simply creates concepts that do not affect Sheerka
|
||||
sequence : Sequence Manager, to give a correct id to the created concepts
|
||||
:return: the concepts
|
||||
"""
|
||||
res = []
|
||||
use_sheerka = kwargs.pop("use_sheerka", False)
|
||||
sequence = kwargs.pop("sequence", None)
|
||||
for c in concepts:
|
||||
if use_sheerka:
|
||||
c = define_new_concept(context, c)
|
||||
elif isinstance(c, str):
|
||||
c = get_concept(c)
|
||||
|
||||
if sequence:
|
||||
c.get_metadata().auto_init(sequence)
|
||||
|
||||
res.append(c)
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def get_evaluated_concepts(context, *concepts, use_sheerka=False) -> list[Concept]:
|
||||
if use_sheerka:
|
||||
return [context.sheerka.evaluate_concept(context, Concept(c.get_metadata())) for c in concepts]
|
||||
else:
|
||||
return [get_evaluated_concept(concept) for concept in concepts]
|
||||
if use_sheerka:
|
||||
return [context.sheerka.evaluate_concept(context, Concept(c.get_metadata())) for c in concepts]
|
||||
else:
|
||||
return [get_evaluated_concept(concept) for concept in concepts]
|
||||
|
||||
|
||||
def define_new_concept(context: ExecutionContext, c: str | Concept | ConceptMetadata) -> Concept:
|
||||
sheerka = context.sheerka
|
||||
if isinstance(c, str):
|
||||
retval = sheerka.define_new_concept(context, c)
|
||||
else:
|
||||
metadata = c.get_metadata()
|
||||
retval = sheerka.define_new_concept(context,
|
||||
metadata.name,
|
||||
metadata.is_builtin,
|
||||
metadata.is_unique,
|
||||
metadata.body,
|
||||
metadata.where,
|
||||
metadata.pre,
|
||||
metadata.post,
|
||||
metadata.ret,
|
||||
metadata.definition,
|
||||
metadata.definition_type,
|
||||
metadata.autouse,
|
||||
metadata.bound_body,
|
||||
metadata.desc,
|
||||
metadata.props,
|
||||
metadata.variables,
|
||||
metadata.parameters)
|
||||
|
||||
assert retval.status
|
||||
concept = sheerka.newi(retval.value.metadata.id)
|
||||
return concept
|
||||
sheerka = context.sheerka
|
||||
if isinstance(c, str):
|
||||
retval = sheerka.define_new_concept(context, c)
|
||||
else:
|
||||
metadata = c.get_metadata()
|
||||
retval = sheerka.define_new_concept(context,
|
||||
metadata.name,
|
||||
metadata.is_builtin,
|
||||
metadata.is_unique,
|
||||
metadata.body,
|
||||
metadata.where,
|
||||
metadata.pre,
|
||||
metadata.post,
|
||||
metadata.ret,
|
||||
metadata.definition,
|
||||
metadata.definition_type,
|
||||
metadata.autouse,
|
||||
metadata.bound_body,
|
||||
metadata.desc,
|
||||
metadata.props,
|
||||
metadata.variables,
|
||||
metadata.parameters)
|
||||
|
||||
assert retval.status
|
||||
concept = sheerka.newi(retval.value.metadata.id)
|
||||
return concept
|
||||
|
||||
|
||||
def get_file_content(file_name):
|
||||
with open(file_name) as f:
|
||||
return f.read()
|
||||
with open(file_name) as f:
|
||||
return f.read()
|
||||
|
||||
|
||||
def get_parser_input(text):
|
||||
pi = ParserInput(text)
|
||||
assert pi.init()
|
||||
|
||||
return pi
|
||||
pi = ParserInput(text)
|
||||
assert pi.init()
|
||||
|
||||
return pi
|
||||
|
||||
|
||||
def get_from(*args, **kwargs):
|
||||
"""
|
||||
Convert the input to fix the positions
|
||||
:param args:
|
||||
:type args:
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
cache = {} # I keep the name in cache to avoid having to remind it everytime
|
||||
pos = 0
|
||||
res = []
|
||||
for item in args:
|
||||
start = pos
|
||||
if isinstance(item, MetadataToken):
|
||||
if item.metadata.name:
|
||||
cache[item.metadata.id] = item.metadata.name
|
||||
|
||||
tokens = list(Tokenizer(cache[item.metadata.id], yield_eof=False))
|
||||
pos += len(tokens)
|
||||
resolution_method = kwargs.get("resolution_method", item.resolution_method)
|
||||
parser = kwargs.get("parser", item.parser)
|
||||
res.append(MetadataToken(item.metadata, start, pos - 1, resolution_method, parser))
|
||||
elif isinstance(item, UnrecognizedToken):
|
||||
tokens = list(Tokenizer(item.buffer, yield_eof=False))
|
||||
pos += len(tokens)
|
||||
res.append(UnrecognizedToken(item.buffer, start, pos - 1))
|
||||
|
||||
return res
|
||||
"""
|
||||
Convert the input to fix the positions
|
||||
:param args:
|
||||
:type args:
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
cache = {} # I keep the name in cache to avoid having to remind it everytime
|
||||
pos = 0
|
||||
res = []
|
||||
for item in args:
|
||||
start = pos
|
||||
if isinstance(item, MetadataToken):
|
||||
if item.metadata.name:
|
||||
cache[item.metadata.id] = item.metadata.name
|
||||
|
||||
tokens = list(Tokenizer(cache[item.metadata.id], yield_eof=False))
|
||||
pos += len(tokens)
|
||||
resolution_method = kwargs.get("resolution_method", item.resolution_method)
|
||||
parser = kwargs.get("parser", item.parser)
|
||||
res.append(MetadataToken(item.metadata, start, pos - 1, resolution_method, parser))
|
||||
elif isinstance(item, UnrecognizedToken):
|
||||
tokens = list(Tokenizer(item.buffer, yield_eof=False))
|
||||
pos += len(tokens)
|
||||
res.append(UnrecognizedToken(item.buffer, start, pos - 1))
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def _rv(value, who="Test"):
|
||||
return ReturnValue(who=who, status=True, value=value)
|
||||
return ReturnValue(who=who, status=True, value=value)
|
||||
|
||||
|
||||
def _rvc(concept_name, who="Test"):
|
||||
next_id = GetNextId()
|
||||
concept = get_concept(concept_name, sequence=next_id)
|
||||
return ReturnValue(who=who, status=True, value=concept)
|
||||
next_id = GetNextId()
|
||||
concept = get_concept(concept_name, sequence=next_id)
|
||||
return ReturnValue(who=who, status=True, value=concept)
|
||||
|
||||
|
||||
def _rvf(value, who="Test"):
|
||||
"""
|
||||
Return Value False
|
||||
:param value:
|
||||
:type value:
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
return ReturnValue(who=who, status=False, value=value)
|
||||
"""
|
||||
Return Value False
|
||||
:param value:
|
||||
:type value:
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
return ReturnValue(who=who, status=False, value=value)
|
||||
|
||||
|
||||
def _ut(buffer, start=0, end=-1):
|
||||
"""
|
||||
helper to UnrecognizedToken
|
||||
:param buffer:
|
||||
:type buffer:
|
||||
:param start:
|
||||
:type start:
|
||||
:param end:
|
||||
:type end:
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
return UnrecognizedToken(buffer, start, end)
|
||||
|
||||
|
||||
def _mt(concept_id,
|
||||
start=0,
|
||||
end=-1,
|
||||
resolution_method: Literal["name", "key", "id"] = "id",
|
||||
parser="simple",
|
||||
**kwargs):
|
||||
"""
|
||||
helper to MetadataToken
|
||||
:param concept_id:
|
||||
:type concept_id:
|
||||
:param start:
|
||||
:type start:
|
||||
:param end:
|
||||
:type end:
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
name, _id = unstr_concept(concept_id)
|
||||
variables = [(k, v) for k, v in kwargs.items()] if kwargs else None
|
||||
metadata = get_metadata(id=concept_id, variables=variables) if _id is None \
|
||||
else get_metadata(id=_id, name=name, variables=variables)
|
||||
return MetadataToken(metadata, start, end, resolution_method, parser)
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
import logging
|
||||
from multiprocessing import Process
|
||||
from time import sleep
|
||||
|
||||
import uvicorn
|
||||
from fastapi import FastAPI
|
||||
|
||||
|
||||
class MockServer:
|
||||
""" Core application to test. """
|
||||
|
||||
def __init__(self, endpoints: list[dict]):
|
||||
"""
|
||||
|
||||
:param endpoints:
|
||||
:type endpoints: list of {path: '', response:''}
|
||||
"""
|
||||
self.api = FastAPI()
|
||||
|
||||
def raise_exception(ex):
|
||||
raise ex
|
||||
|
||||
# register endpoints
|
||||
for endpoint in endpoints:
|
||||
method = endpoint["method"] if "method" in endpoint else "get"
|
||||
if method == "post":
|
||||
if "exception" in endpoint:
|
||||
self.api.post(endpoint["path"])(lambda: raise_exception(endpoint["exception"]))
|
||||
else:
|
||||
self.api.post(endpoint["path"])(lambda: endpoint["response"])
|
||||
else:
|
||||
self.api.get(endpoint["path"])(lambda: endpoint["response"])
|
||||
|
||||
# register shutdown
|
||||
self.api.on_event("shutdown")(self.close)
|
||||
|
||||
# create the process
|
||||
self.proc = Process(target=uvicorn.run,
|
||||
args=(self.api,),
|
||||
kwargs={
|
||||
"host": "127.0.0.1",
|
||||
"port": 5000,
|
||||
"log_level": "info"},
|
||||
daemon=True)
|
||||
|
||||
async def close(self):
|
||||
""" Gracefull shutdown. """
|
||||
logging.warning("Shutting down the app.")
|
||||
|
||||
def start_server(self):
|
||||
self.proc.start()
|
||||
sleep(0.1)
|
||||
|
||||
def stop_server(self):
|
||||
self.proc.terminate()
|
||||
|
||||
def __enter__(self):
|
||||
self.start_server()
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
self.stop_server()
|
||||
@@ -0,0 +1,105 @@
|
||||
from typing import Literal
|
||||
|
||||
from common.utils import str_concept, unstr_concept
|
||||
from helpers import get_metadata
|
||||
from parsers.state_machine import MetadataToken, UnrecognizedToken
|
||||
|
||||
|
||||
class MetadataTokenForTest(MetadataToken):
|
||||
def __repr__(self):
|
||||
res = f"(MetadataTokenForTest metadata={str_concept(self.metadata, drop_name=True)}"
|
||||
if self.start is not None:
|
||||
res += f", start={self.start}"
|
||||
if self.end is not None:
|
||||
res += f", end={self.end}"
|
||||
if self.resolution_method is not None:
|
||||
res += f", method={self.resolution_method}"
|
||||
if self.parser is not None:
|
||||
res += f", origin={self.parser}"
|
||||
|
||||
res += ")"
|
||||
return res
|
||||
|
||||
def __eq__(self, other):
|
||||
if not isinstance(other, MetadataToken):
|
||||
return False
|
||||
|
||||
if self.metadata.id != other.metadata.id:
|
||||
return False
|
||||
|
||||
if self.start is not None and self.start != other.start:
|
||||
return False
|
||||
|
||||
if self.end is not None and self.end != other.end:
|
||||
return False
|
||||
|
||||
if self.parser is not None and self.parser != other.parser:
|
||||
return False
|
||||
|
||||
if self.resolution_method is not None and self.resolution_method != other.resolution_method:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def _ut(buffer, start=0, end=-1):
|
||||
"""
|
||||
helper to UnrecognizedToken
|
||||
:param buffer:
|
||||
:type buffer:
|
||||
:param start:
|
||||
:type start:
|
||||
:param end:
|
||||
:type end:
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
return UnrecognizedToken(buffer, start, end)
|
||||
|
||||
|
||||
def _mt(concept_id,
|
||||
start=0,
|
||||
end=-1,
|
||||
resolution_method: Literal["name", "key", "id"] = "key",
|
||||
parser="simple",
|
||||
**kwargs):
|
||||
"""
|
||||
helper to MetadataToken
|
||||
:param concept_id:
|
||||
:type concept_id:
|
||||
:param start:
|
||||
:type start:
|
||||
:param end:
|
||||
:type end:
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
name, _id = unstr_concept(concept_id)
|
||||
variables = [(k, v) for k, v in kwargs.items()] if kwargs else None
|
||||
metadata = get_metadata(id=concept_id, variables=variables) if _id is None \
|
||||
else get_metadata(id=_id, name=name, variables=variables)
|
||||
return MetadataTokenForTest(metadata, start, end, resolution_method, parser)
|
||||
|
||||
|
||||
def _mtsya(concept_id,
|
||||
start=0,
|
||||
end=None,
|
||||
resolution_method: Literal["name", "key", "id"] = "key",
|
||||
parser="sya",
|
||||
**kwargs):
|
||||
"""
|
||||
helper to MetadataToken
|
||||
:param concept_id:
|
||||
:type concept_id:
|
||||
:param start:
|
||||
:type start:
|
||||
:param end:
|
||||
:type end:
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
name, _id = unstr_concept(concept_id)
|
||||
variables = [(k, v) for k, v in kwargs.items()] if kwargs else None
|
||||
metadata = get_metadata(id=concept_id, variables=variables) if _id is None \
|
||||
else get_metadata(id=_id, name=name, variables=variables)
|
||||
return MetadataTokenForTest(metadata, start, end, resolution_method, parser)
|
||||
@@ -3,148 +3,149 @@ import pytest
|
||||
from base import BaseTest
|
||||
from conftest import NewOntology
|
||||
from evaluators.base_evaluator import MultipleChoices
|
||||
from helpers import _mt, _ut, get_concepts, get_from, get_metadata, get_parser_input
|
||||
from helpers import get_concepts, get_from, get_metadata, get_parser_input
|
||||
from parsers.SimpleConceptsParser import SimpleConceptsParser
|
||||
from tests.parsers.conftest import _mt, _ut
|
||||
|
||||
|
||||
class TestSimpleConceptsParser(BaseTest):
|
||||
|
||||
@pytest.fixture()
|
||||
def parser(self):
|
||||
return SimpleConceptsParser()
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("I am a new concept", [_mt("1003", 0, 8)]),
|
||||
("xxx yyy I am a new concept", [_ut("xxx yyy ", 0, 3), _mt("1003", 4, 12)]),
|
||||
("I am a new concept xxx yyy", [_mt("1003", 0, 8), _ut(" xxx yyy", 9, 12)]),
|
||||
("xxx I am a new concept yyy", [_ut("xxx ", 0, 1), _mt("1003", 2, 10), _ut(" yyy", 11, 12)]),
|
||||
("c:#1003:", [_mt("1003", 0, 0)]),
|
||||
("xxx c:#1003: yyy", [_ut("xxx ", 0, 1), _mt("1003", 2, 2), _ut(" yyy", 3, 4)]),
|
||||
("xxx c:I am: yyy", [_ut("xxx ", 0, 1), _mt("1002", 2, 2), _ut(" yyy", 3, 4)]),
|
||||
(" I am a new concept", [_ut(" ", 0, 0), _mt("1003", 1, 9)])
|
||||
])
|
||||
def test_i_can_recognize_a_concept(self, context, parser, text, expected):
|
||||
with NewOntology(context, "test_i_can_recognize_a_concept"):
|
||||
get_concepts(context, "I", "I am", "I am a new concept", use_sheerka=True)
|
||||
|
||||
pi = get_parser_input(text)
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
|
||||
assert res == MultipleChoices([expected])
|
||||
assert not error_sink
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("foo", [_mt("1001", 0, 0)]),
|
||||
("I am a new concept", [_mt("1001", 0, 8)])
|
||||
])
|
||||
def test_i_can_recognize_a_concept_by_its_name_and_its_definition(self, context, parser, text, expected):
|
||||
with NewOntology(context, "test_i_can_recognize_a_concept_by_its_name_and_its_definition"):
|
||||
get_concepts(context, get_metadata(name="foo", definition="I am a new concept"), use_sheerka=True)
|
||||
|
||||
pi = get_parser_input(text)
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
|
||||
assert res == MultipleChoices([expected])
|
||||
assert not error_sink
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("long concept name", [_mt("1001", 0, 4)]),
|
||||
("I am a new concept", [_mt("1001", 0, 8)])
|
||||
])
|
||||
def test_i_can_recognize_a_concept_by_its_name_when_long_name(self, context, parser, text, expected):
|
||||
with NewOntology(context, "test_i_can_recognize_a_concept_by_its_name_when_long_name"):
|
||||
get_concepts(context, get_metadata(name="long concept name", definition="I am a new concept"),
|
||||
use_sheerka=True)
|
||||
|
||||
pi = get_parser_input(text)
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
|
||||
assert res == MultipleChoices([expected])
|
||||
assert not error_sink
|
||||
|
||||
def test_i_can_parse_a_sequence_of_concept(self, context, parser):
|
||||
with NewOntology(context, "test_i_can_parse_a_sequence_of_concept"):
|
||||
get_concepts(context, "foo bar", "baz", "qux", use_sheerka=True)
|
||||
|
||||
pi = get_parser_input("foo bar baz foo, qux")
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
|
||||
expected = [_mt("1001", 0, 2),
|
||||
_ut(" ", 3, 3),
|
||||
_mt("1002", 4, 4),
|
||||
_ut(" foo, ", 5, 8),
|
||||
_mt("1003", 9, 9)]
|
||||
|
||||
assert res == MultipleChoices([expected])
|
||||
assert not error_sink
|
||||
|
||||
def test_i_can_detect_multiple_choices(self, context, parser):
|
||||
with NewOntology(context, "test_i_can_detect_multiple_choices"):
|
||||
get_concepts(context, "foo bar", "bar baz", use_sheerka=True)
|
||||
|
||||
pi = get_parser_input("foo bar baz")
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
|
||||
expected1 = [_mt("1001", 0, 2), _ut(" baz", 3, 4)]
|
||||
expected2 = [_ut("foo ", 0, 1), _mt("1002", 2, 4)]
|
||||
|
||||
assert res == MultipleChoices([expected1, expected2])
|
||||
assert not error_sink
|
||||
|
||||
def test_i_can_detect_multiple_choices_2(self, context, parser):
|
||||
with NewOntology(context, "test_i_can_detect_multiple_choices_2"):
|
||||
get_concepts(context, "one two", "one", "two", use_sheerka=True)
|
||||
|
||||
pi = get_parser_input("one two")
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
|
||||
expected1 = [_mt("1001", 0, 2)]
|
||||
expected2 = [_mt("1002", 0, 0), _ut(" ", 1, 1), _mt("1003", 2, 2)]
|
||||
|
||||
assert res == MultipleChoices([expected1, expected2])
|
||||
assert not error_sink
|
||||
|
||||
def test_i_can_detect_multiple_choices_3(self, context, parser):
|
||||
with NewOntology(context, "test_i_can_detect_multiple_choices_2"):
|
||||
get_concepts(context, "one two", "one", "two", use_sheerka=True)
|
||||
|
||||
pi = get_parser_input("one two xxx one two")
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
|
||||
e1 = get_from(_mt("c:one two#1001:"), _ut(" xxx "), _mt("c:#1001:"))
|
||||
e2 = get_from(_mt("c:one#1002:"), _ut(" "), _mt("c:two#1003:"), _ut(" xxx "), _mt("c:one two#1001:"))
|
||||
e3 = get_from(_mt("c:one two#1001:"), _ut(" xxx "), _mt("c:one#1002:"), _ut(" "), _mt("c:two#1003:"))
|
||||
e4 = get_from(_mt("c:one#1002:"), _ut(" "), _mt("c:two#1003:"), _ut(" xxx "), _mt("c:#1002:"), _ut(" "),
|
||||
_mt("c:#1003:"))
|
||||
|
||||
assert res == MultipleChoices([e1, e2, e3, e4])
|
||||
assert not error_sink
|
||||
|
||||
def test_nothing_is_return_is_no_concept_is_recognized(self, context, parser):
|
||||
pi = get_parser_input("one two three")
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
|
||||
assert res == MultipleChoices([])
|
||||
|
||||
def test_i_can_manage_attribute_reference(self, context, parser):
|
||||
with NewOntology(context, "test_i_can_detect_multiple_choices_2"):
|
||||
get_concepts(context, "foo", "i am a concept", use_sheerka=True)
|
||||
|
||||
pi = get_parser_input("foo.attribute")
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
expected = [_mt("1001", 0, 0), _ut(".attribute", 1, 2)]
|
||||
assert res == MultipleChoices([expected])
|
||||
|
||||
pi = get_parser_input("i am a concept.attribute")
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
expected = [_mt("1002", 0, 6), _ut(".attribute", 7, 8)]
|
||||
assert res == MultipleChoices([expected])
|
||||
|
||||
@pytest.fixture()
|
||||
def parser(self):
|
||||
return SimpleConceptsParser()
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("I am a new concept", [_mt("1003", 0, 8)]),
|
||||
("xxx yyy I am a new concept", [_ut("xxx yyy ", 0, 3), _mt("1003", 4, 12)]),
|
||||
("I am a new concept xxx yyy", [_mt("1003", 0, 8), _ut(" xxx yyy", 9, 12)]),
|
||||
("xxx I am a new concept yyy", [_ut("xxx ", 0, 1), _mt("1003", 2, 10), _ut(" yyy", 11, 12)]),
|
||||
("c:#1003:", [_mt("1003", 0, 0, resolution_method="id")]),
|
||||
("xxx c:#1003: yyy", [_ut("xxx ", 0, 1), _mt("1003", 2, 2, resolution_method="id"), _ut(" yyy", 3, 4)]),
|
||||
("xxx c:I am: yyy", [_ut("xxx ", 0, 1), _mt("1002", 2, 2, resolution_method="name"), _ut(" yyy", 3, 4)]),
|
||||
(" I am a new concept", [_ut(" ", 0, 0), _mt("1003", 1, 9)])
|
||||
])
|
||||
def test_i_can_recognize_a_concept(self, context, parser, text, expected):
|
||||
with NewOntology(context, "test_i_can_recognize_a_concept"):
|
||||
get_concepts(context, "I", "I am", "I am a new concept", use_sheerka=True)
|
||||
|
||||
pi = get_parser_input(text)
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
|
||||
assert res == MultipleChoices([expected])
|
||||
assert not error_sink
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("foo", [_mt("1001", 0, 0, resolution_method="name")]),
|
||||
("I am a new concept", [_mt("1001", 0, 8)])
|
||||
])
|
||||
def test_i_can_recognize_a_concept_by_its_name_and_its_definition(self, context, parser, text, expected):
|
||||
with NewOntology(context, "test_i_can_recognize_a_concept_by_its_name_and_its_definition"):
|
||||
get_concepts(context, get_metadata(name="foo", definition="I am a new concept"), use_sheerka=True)
|
||||
|
||||
pi = get_parser_input(text)
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
|
||||
assert res == MultipleChoices([expected])
|
||||
assert not error_sink
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("long concept name", [_mt("1001", 0, 4, resolution_method="name")]),
|
||||
("I am a new concept", [_mt("1001", 0, 8)])
|
||||
])
|
||||
def test_i_can_recognize_a_concept_by_its_name_when_long_name(self, context, parser, text, expected):
|
||||
with NewOntology(context, "test_i_can_recognize_a_concept_by_its_name_when_long_name"):
|
||||
get_concepts(context, get_metadata(name="long concept name", definition="I am a new concept"),
|
||||
use_sheerka=True)
|
||||
|
||||
pi = get_parser_input(text)
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
|
||||
assert res == MultipleChoices([expected])
|
||||
assert not error_sink
|
||||
|
||||
def test_i_can_parse_a_sequence_of_concept(self, context, parser):
|
||||
with NewOntology(context, "test_i_can_parse_a_sequence_of_concept"):
|
||||
get_concepts(context, "foo bar", "baz", "qux", use_sheerka=True)
|
||||
|
||||
pi = get_parser_input("foo bar baz foo, qux")
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
|
||||
expected = [_mt("1001", 0, 2),
|
||||
_ut(" ", 3, 3),
|
||||
_mt("1002", 4, 4),
|
||||
_ut(" foo, ", 5, 8),
|
||||
_mt("1003", 9, 9)]
|
||||
|
||||
assert res == MultipleChoices([expected])
|
||||
assert not error_sink
|
||||
|
||||
def test_i_can_detect_multiple_choices(self, context, parser):
|
||||
with NewOntology(context, "test_i_can_detect_multiple_choices"):
|
||||
get_concepts(context, "foo bar", "bar baz", use_sheerka=True)
|
||||
|
||||
pi = get_parser_input("foo bar baz")
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
|
||||
expected1 = [_mt("1001", 0, 2), _ut(" baz", 3, 4)]
|
||||
expected2 = [_ut("foo ", 0, 1), _mt("1002", 2, 4)]
|
||||
|
||||
assert res == MultipleChoices([expected1, expected2])
|
||||
assert not error_sink
|
||||
|
||||
def test_i_can_detect_multiple_choices_2(self, context, parser):
|
||||
with NewOntology(context, "test_i_can_detect_multiple_choices_2"):
|
||||
get_concepts(context, "one two", "one", "two", use_sheerka=True)
|
||||
|
||||
pi = get_parser_input("one two")
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
|
||||
expected1 = [_mt("1001", 0, 2)]
|
||||
expected2 = [_mt("1002", 0, 0), _ut(" ", 1, 1), _mt("1003", 2, 2)]
|
||||
|
||||
assert res == MultipleChoices([expected1, expected2])
|
||||
assert not error_sink
|
||||
|
||||
def test_i_can_detect_multiple_choices_3(self, context, parser):
|
||||
with NewOntology(context, "test_i_can_detect_multiple_choices_2"):
|
||||
get_concepts(context, "one two", "one", "two", use_sheerka=True)
|
||||
|
||||
pi = get_parser_input("one two xxx one two")
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
|
||||
e1 = get_from(_mt("c:one two#1001:"), _ut(" xxx "), _mt("c:#1001:"))
|
||||
e2 = get_from(_mt("c:one#1002:"), _ut(" "), _mt("c:two#1003:"), _ut(" xxx "), _mt("c:one two#1001:"))
|
||||
e3 = get_from(_mt("c:one two#1001:"), _ut(" xxx "), _mt("c:one#1002:"), _ut(" "), _mt("c:two#1003:"))
|
||||
e4 = get_from(_mt("c:one#1002:"), _ut(" "), _mt("c:two#1003:"), _ut(" xxx "), _mt("c:#1002:"), _ut(" "),
|
||||
_mt("c:#1003:"))
|
||||
|
||||
assert res == MultipleChoices([e1, e2, e3, e4])
|
||||
assert not error_sink
|
||||
|
||||
def test_nothing_is_return_is_no_concept_is_recognized(self, context, parser):
|
||||
pi = get_parser_input("one two three")
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
|
||||
assert res == MultipleChoices([])
|
||||
|
||||
def test_i_can_manage_attribute_reference(self, context, parser):
|
||||
with NewOntology(context, "test_i_can_detect_multiple_choices_2"):
|
||||
get_concepts(context, "foo", "i am a concept", use_sheerka=True)
|
||||
|
||||
pi = get_parser_input("foo.attribute")
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
expected = [_mt("1001", 0, 0), _ut(".attribute", 1, 2)]
|
||||
assert res == MultipleChoices([expected])
|
||||
|
||||
pi = get_parser_input("i am a concept.attribute")
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
expected = [_mt("1002", 0, 6), _ut(".attribute", 7, 8)]
|
||||
assert res == MultipleChoices([expected])
|
||||
|
||||
@@ -3,91 +3,92 @@ import pytest
|
||||
from base import BaseTest
|
||||
from conftest import NewOntology, comparable_tokens
|
||||
from evaluators.base_evaluator import MultipleChoices
|
||||
from helpers import _mt, get_concept, get_concepts, get_parser_input
|
||||
from helpers import get_concept, get_concepts, get_parser_input
|
||||
from parsers.SyaConceptsParser import SyaConceptsParser
|
||||
from parsers.tokenizer import Tokenizer
|
||||
from tests.parsers.conftest import _mtsya
|
||||
|
||||
|
||||
class TestSyaConceptsParser(BaseTest):
|
||||
|
||||
@pytest.fixture()
|
||||
def parser(self):
|
||||
return SyaConceptsParser()
|
||||
|
||||
@pytest.mark.parametrize("concept_key, expected_list", [
|
||||
["a long token name", [("a long token name", 0)]],
|
||||
["__var__0 __var__1 __var__2", [("", 3)]],
|
||||
["__var__0 __var__1 prefixed", [(" prefixed", 2)]],
|
||||
["suffixed __var__0 __var__1", [("suffixed ", 0), ["", 2]]],
|
||||
["__var__0 __var__1 infixed __var__0 __var__1", [(" infixed ", 2), ["", 2]]],
|
||||
["if __var__0 __var__1 then __var__2 end", [("if ", 0), (" then ", 2), (" end", 1)]]
|
||||
])
|
||||
def test_i_can_initialize_expected_parameters(self, parser, concept_key, expected_list):
|
||||
resolved_expected_list = [(list(Tokenizer(source, yield_eof=False)), nb) for source, nb in expected_list]
|
||||
actual = parser._get_expected_tokens(concept_key)
|
||||
|
||||
with comparable_tokens():
|
||||
assert actual == resolved_expected_list
|
||||
|
||||
@pytest.mark.parametrize("concept", [
|
||||
get_concept("a plus b", variables=["a", "b"]),
|
||||
get_concept("add a b", variables=["a", "b"]),
|
||||
get_concept("a b add", variables=["a", "b"]),
|
||||
])
|
||||
def test_i_can_parse_a_simple_case(self, context, parser, concept):
|
||||
with NewOntology(context, "test_i_can_parse_a_simple_case"):
|
||||
get_concepts(context, concept, use_sheerka=True)
|
||||
|
||||
pi = get_parser_input("1 plus 2")
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
|
||||
expected = [_mt("1001", a="1 ", b=" 2")]
|
||||
assert res == MultipleChoices([expected])
|
||||
assert not error_sink
|
||||
|
||||
def test_i_can_parse_long_names_concept(self, context, parser):
|
||||
with NewOntology(context, "test_i_can_parse_a_simple_case"):
|
||||
get_concepts(context, get_concept("a long named concept b", variables=["a", "b"]), use_sheerka=True)
|
||||
|
||||
pi = get_parser_input("1 long named concept 2")
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
|
||||
expected = [_mt("1001", a="1 ", b=" 2")]
|
||||
assert res == MultipleChoices([expected])
|
||||
assert not error_sink
|
||||
|
||||
def test_i_can_parse_sequence(self, context, parser):
|
||||
with NewOntology(context, "test_i_can_parse_sequence"):
|
||||
get_concepts(context, get_concept("a plus b", variables=["a", "b"]), use_sheerka=True)
|
||||
|
||||
pi = get_parser_input("1 plus 2 3 plus 7")
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
|
||||
expected = [[_mt("1001", a="1 ", b=" 2")], [_mt("1001", a=" 3 ", b=" 7")]]
|
||||
assert res == MultipleChoices(expected)
|
||||
assert not error_sink
|
||||
|
||||
def test_not_enough_parameters(self, context, parser):
|
||||
with NewOntology(context, "test_not_enough_parameters"):
|
||||
get_concepts(context, get_concept("a plus b", variables=["a", "b"]), use_sheerka=True)
|
||||
|
||||
pi = get_parser_input("1 plus 2 3 plus 7")
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
|
||||
expected = [[_mt("1001", a="1 ", b=" 2")], [_mt("1001", a=" 3 ", b=" 7")]]
|
||||
assert res == MultipleChoices(expected)
|
||||
assert not error_sink
|
||||
|
||||
def test_i_can_detect_when_name_does_not_match(self, context, parser):
|
||||
with NewOntology(context, "test_i_can_detect_when_name_does_not_match"):
|
||||
get_concepts(context, get_concept("a long named concept b", variables=["a", "b"]), use_sheerka=True)
|
||||
|
||||
pi = get_parser_input("1 long named mismatch 2")
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
|
||||
assert error_sink
|
||||
|
||||
@pytest.fixture()
|
||||
def parser(self):
|
||||
return SyaConceptsParser()
|
||||
|
||||
@pytest.mark.parametrize("concept_key, expected_list", [
|
||||
["a long token name", [("a long token name", 0)]],
|
||||
["__var__0 __var__1 __var__2", [("", 3)]],
|
||||
["__var__0 __var__1 prefixed", [(" prefixed", 2)]],
|
||||
["suffixed __var__0 __var__1", [("suffixed ", 0), ["", 2]]],
|
||||
["__var__0 __var__1 infixed __var__0 __var__1", [(" infixed ", 2), ["", 2]]],
|
||||
["if __var__0 __var__1 then __var__2 end", [("if ", 0), (" then ", 2), (" end", 1)]]
|
||||
])
|
||||
def test_i_can_initialize_expected_parameters(self, parser, concept_key, expected_list):
|
||||
resolved_expected_list = [(list(Tokenizer(source, yield_eof=False)), nb) for source, nb in expected_list]
|
||||
actual = parser._get_expected_tokens(concept_key)
|
||||
|
||||
with comparable_tokens():
|
||||
assert actual == resolved_expected_list
|
||||
|
||||
@pytest.mark.parametrize("concept, _input", [
|
||||
(get_concept("a plus b", variables=["a", "b"]), "1 plus 2"),
|
||||
(get_concept("add a b", variables=["a", "b"]), "add 1 2"),
|
||||
(get_concept("a b add", variables=["a", "b"]), "1 2 add")
|
||||
])
|
||||
def test_i_can_parse_a_simple_case(self, context, parser, concept, _input):
|
||||
with NewOntology(context, "test_i_can_parse_a_simple_case"):
|
||||
get_concepts(context, concept, use_sheerka=True)
|
||||
|
||||
pi = get_parser_input(_input)
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
|
||||
expected = [_mtsya("1001", a="1 ", b=" 2")]
|
||||
assert res == MultipleChoices([expected])
|
||||
assert not error_sink
|
||||
|
||||
def test_i_can_parse_long_names_concept(self, context, parser):
|
||||
with NewOntology(context, "test_i_can_parse_a_simple_case"):
|
||||
get_concepts(context, get_concept("a long named concept b", variables=["a", "b"]), use_sheerka=True)
|
||||
|
||||
pi = get_parser_input("1 long named concept 2")
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
|
||||
expected = [_mtsya("1001", a="1 ", b=" 2")]
|
||||
assert res == MultipleChoices([expected])
|
||||
assert not error_sink
|
||||
|
||||
def test_i_can_parse_sequence(self, context, parser):
|
||||
with NewOntology(context, "test_i_can_parse_sequence"):
|
||||
get_concepts(context, get_concept("a plus b", variables=["a", "b"]), use_sheerka=True)
|
||||
|
||||
pi = get_parser_input("1 plus 2 3 plus 7")
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
|
||||
expected = [[_mtsya("1001", a="1 ", b=" 2")], [_mtsya("1001", a=" 3 ", b=" 7")]]
|
||||
assert res == MultipleChoices(expected)
|
||||
assert not error_sink
|
||||
|
||||
def test_not_enough_parameters(self, context, parser):
|
||||
with NewOntology(context, "test_not_enough_parameters"):
|
||||
get_concepts(context, get_concept("a plus b", variables=["a", "b"]), use_sheerka=True)
|
||||
|
||||
pi = get_parser_input("1 plus ")
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
|
||||
expected = [[_mtsya("1001", a="1 ", b=" 2")], [_mtsya("1001", a=" 3 ", b=" 7")]]
|
||||
assert res == MultipleChoices(expected)
|
||||
assert not error_sink
|
||||
|
||||
def test_i_can_detect_when_name_does_not_match(self, context, parser):
|
||||
with NewOntology(context, "test_i_can_detect_when_name_does_not_match"):
|
||||
get_concepts(context, get_concept("a long named concept b", variables=["a", "b"]), use_sheerka=True)
|
||||
|
||||
pi = get_parser_input("1 long named mismatch 2")
|
||||
error_sink = []
|
||||
res = parser.parse(context, pi, error_sink)
|
||||
|
||||
assert error_sink
|
||||
|
||||
+20
-20
@@ -1,11 +1,11 @@
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from fastapi import HTTPException
|
||||
from starlette import status
|
||||
|
||||
from client import SheerkaClient, parse_arguments
|
||||
from mockserver import MockServer
|
||||
|
||||
|
||||
# @pytest.mark.skip("too long")
|
||||
class TestSheerkaClient:
|
||||
def test_i_can_start_with_a_default_hostname(self):
|
||||
parsed = parse_arguments([])
|
||||
@@ -41,7 +41,11 @@ class TestSheerkaClient:
|
||||
assert res.message == "Connection refused."
|
||||
|
||||
def test_i_can_manage_when_resource_is_not_found(self):
|
||||
with MockServer([]):
|
||||
mock_response = MagicMock()
|
||||
mock_response.__bool__ = MagicMock(return_value=False)
|
||||
mock_response.text = '{"detail":"Not Found"}'
|
||||
|
||||
with patch("requests.get", return_value=mock_response):
|
||||
client = SheerkaClient("http://localhost", 5000)
|
||||
res = client.check_url()
|
||||
|
||||
@@ -49,29 +53,25 @@ class TestSheerkaClient:
|
||||
assert res.message == '{"detail":"Not Found"}'
|
||||
|
||||
def test_i_can_connect_to_a_server(self):
|
||||
with MockServer([{
|
||||
"path": "/",
|
||||
"response": "Hello world"
|
||||
}]):
|
||||
mock_response = MagicMock()
|
||||
mock_response.__bool__ = MagicMock(return_value=True)
|
||||
mock_response.text = '"Hello world"'
|
||||
|
||||
with patch("requests.get", return_value=mock_response):
|
||||
client = SheerkaClient("http://localhost", 5000)
|
||||
res = client.check_url()
|
||||
|
||||
assert res.status
|
||||
assert res.message == '"Hello world"'
|
||||
|
||||
def test_i_can_manage_when_authentication_fails(self):
|
||||
with MockServer([{
|
||||
"path": "/",
|
||||
"response": "Hello world"
|
||||
}, {
|
||||
"method": "post",
|
||||
"path": "/token",
|
||||
"exception": HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="Incorrect username or password",
|
||||
headers={"WWW-Authenticate": "Bearer"},
|
||||
)
|
||||
}]):
|
||||
mock_response = MagicMock()
|
||||
mock_response.__bool__ = MagicMock(return_value=False)
|
||||
mock_response.json.return_value = {"detail": "Incorrect username or password"}
|
||||
|
||||
with patch("requests.post", return_value=mock_response):
|
||||
client = SheerkaClient("http://localhost", 5000)
|
||||
res = client.connect("username", "wrong_password")
|
||||
|
||||
assert not res.status
|
||||
assert res.message == 'Incorrect username or password'
|
||||
assert res.message == "Incorrect username or password"
|
||||
|
||||
+226
-225
@@ -2,279 +2,280 @@ import pytest
|
||||
|
||||
from common.global_symbols import NotInit
|
||||
from core.concept import Concept, ConceptDefaultProps, ConceptMetadata, DefinitionType
|
||||
from helpers import GetNextId, _mt, _ut, get_concept, get_concepts, get_evaluated_concept, get_from, get_metadata, \
|
||||
get_metadatas
|
||||
from helpers import GetNextId, get_concept, get_concepts, get_evaluated_concept, get_from, get_metadata, \
|
||||
get_metadatas
|
||||
from tests.parsers.conftest import _mt, _ut
|
||||
|
||||
|
||||
def test_i_can_get_default_value_when_get_metadata():
|
||||
metadata = get_metadata()
|
||||
assert metadata.id is None
|
||||
assert metadata.name is None
|
||||
assert metadata.name is None
|
||||
assert metadata.body is None
|
||||
assert metadata.id is None
|
||||
assert metadata.key is None
|
||||
assert metadata.where is None
|
||||
assert metadata.pre is None
|
||||
assert metadata.post is None
|
||||
assert metadata.ret is None
|
||||
assert metadata.definition is None
|
||||
assert metadata.definition_type == DefinitionType.DEFAULT
|
||||
assert metadata.desc is None
|
||||
assert metadata.props == {}
|
||||
assert metadata.variables == tuple()
|
||||
assert metadata.parameters == []
|
||||
assert metadata.bound_body is None
|
||||
assert metadata.is_builtin is False
|
||||
assert metadata.is_unique is False
|
||||
assert metadata.autouse is False
|
||||
metadata = get_metadata()
|
||||
assert metadata.id is None
|
||||
assert metadata.name is None
|
||||
assert metadata.name is None
|
||||
assert metadata.body is None
|
||||
assert metadata.id is None
|
||||
assert metadata.key is None
|
||||
assert metadata.where is None
|
||||
assert metadata.pre is None
|
||||
assert metadata.post is None
|
||||
assert metadata.ret is None
|
||||
assert metadata.definition is None
|
||||
assert metadata.definition_type == DefinitionType.DEFAULT
|
||||
assert metadata.desc is None
|
||||
assert metadata.props == {}
|
||||
assert metadata.variables == tuple()
|
||||
assert metadata.parameters == []
|
||||
assert metadata.bound_body is None
|
||||
assert metadata.is_builtin is False
|
||||
assert metadata.is_unique is False
|
||||
assert metadata.autouse is False
|
||||
|
||||
|
||||
def test_i_can_use_shortcut_to_declare_variables():
|
||||
metadata = get_metadata(variables=(("var1", NotInit), ("var2", "value")))
|
||||
assert metadata.variables == (("var1", NotInit), ("var2", "value")) # default behaviour
|
||||
|
||||
metadata = get_metadata(variables=[("var1", NotInit), ("var2", "value")])
|
||||
assert metadata.variables == (("var1", NotInit), ("var2", "value")) # lists are transformed into tuples
|
||||
|
||||
metadata = get_metadata(variables=["var1", "var2"])
|
||||
assert metadata.variables == (("var1", NotInit), ("var2", NotInit)) # expanded
|
||||
metadata = get_metadata(variables=(("var1", NotInit), ("var2", "value")))
|
||||
assert metadata.variables == (("var1", NotInit), ("var2", "value")) # default behaviour
|
||||
|
||||
metadata = get_metadata(variables=[("var1", NotInit), ("var2", "value")])
|
||||
assert metadata.variables == (("var1", NotInit), ("var2", "value")) # lists are transformed into tuples
|
||||
|
||||
metadata = get_metadata(variables=["var1", "var2"])
|
||||
assert metadata.variables == (("var1", NotInit), ("var2", NotInit)) # expanded
|
||||
|
||||
|
||||
def test_i_can_clone():
|
||||
metadata = ConceptMetadata(
|
||||
"id",
|
||||
"name",
|
||||
"key",
|
||||
True,
|
||||
True,
|
||||
"body",
|
||||
"where",
|
||||
"pre",
|
||||
"post",
|
||||
"ret",
|
||||
"definition",
|
||||
DefinitionType.BNF,
|
||||
"desc",
|
||||
True,
|
||||
"bound_body",
|
||||
{"prop": "value"},
|
||||
(("variable", "value"),),
|
||||
("p1",),
|
||||
"digest",
|
||||
("all_attr",),
|
||||
)
|
||||
|
||||
clone = metadata.clone()
|
||||
for attr, value in vars(metadata).items():
|
||||
clone_value = getattr(clone, attr)
|
||||
assert clone_value == value
|
||||
metadata = ConceptMetadata(
|
||||
"id",
|
||||
"name",
|
||||
"key",
|
||||
True,
|
||||
True,
|
||||
"body",
|
||||
"where",
|
||||
"pre",
|
||||
"post",
|
||||
"ret",
|
||||
"definition",
|
||||
DefinitionType.BNF,
|
||||
"desc",
|
||||
True,
|
||||
"bound_body",
|
||||
{"prop": "value"},
|
||||
(("variable", "value"),),
|
||||
("p1",),
|
||||
"digest",
|
||||
("all_attr",),
|
||||
)
|
||||
|
||||
clone = metadata.clone()
|
||||
for attr, value in vars(metadata).items():
|
||||
clone_value = getattr(clone, attr)
|
||||
assert clone_value == value
|
||||
|
||||
|
||||
def test_i_can_override_values_when_i_clone_metadata():
|
||||
metadata = get_metadata()
|
||||
assert metadata.clone(name="new_name").name == "new_name"
|
||||
assert metadata.clone(body="new_body").body == "new_body"
|
||||
assert metadata.clone(key="new_key").key == "new_key"
|
||||
assert metadata.clone(where="new_where").where == "new_where"
|
||||
assert metadata.clone(pre="new_pre").pre == "new_pre"
|
||||
assert metadata.clone(post="new_post").post == "new_post"
|
||||
assert metadata.clone(ret="new_ret").ret == "new_ret"
|
||||
assert metadata.clone(definition="new_definition").definition == "new_definition"
|
||||
assert metadata.clone(definition_type="new_definition_type").definition_type == "new_definition_type"
|
||||
assert metadata.clone(desc="new_desc").desc == "new_desc"
|
||||
assert metadata.clone(props="new_props").props == "new_props"
|
||||
assert metadata.clone(variables="new_variables").variables == "new_variables"
|
||||
assert metadata.clone(parameters="new_parameters").parameters == "new_parameters"
|
||||
assert metadata.clone(bound_body="new_bound_body").bound_body == "new_bound_body"
|
||||
assert metadata.clone(is_builtin="new_is_builtin").is_builtin == "new_is_builtin"
|
||||
assert metadata.clone(is_unique="new_is_unique").is_unique == "new_is_unique"
|
||||
assert metadata.clone(autouse="new_autouse").autouse == "new_autouse"
|
||||
assert metadata.clone(digest="new_digest").digest == "new_digest"
|
||||
assert metadata.clone(all_attrs="new_all_attrs").all_attrs == "new_all_attrs"
|
||||
metadata = get_metadata()
|
||||
assert metadata.clone(name="new_name").name == "new_name"
|
||||
assert metadata.clone(body="new_body").body == "new_body"
|
||||
assert metadata.clone(key="new_key").key == "new_key"
|
||||
assert metadata.clone(where="new_where").where == "new_where"
|
||||
assert metadata.clone(pre="new_pre").pre == "new_pre"
|
||||
assert metadata.clone(post="new_post").post == "new_post"
|
||||
assert metadata.clone(ret="new_ret").ret == "new_ret"
|
||||
assert metadata.clone(definition="new_definition").definition == "new_definition"
|
||||
assert metadata.clone(definition_type="new_definition_type").definition_type == "new_definition_type"
|
||||
assert metadata.clone(desc="new_desc").desc == "new_desc"
|
||||
assert metadata.clone(props="new_props").props == "new_props"
|
||||
assert metadata.clone(variables="new_variables").variables == "new_variables"
|
||||
assert metadata.clone(parameters="new_parameters").parameters == "new_parameters"
|
||||
assert metadata.clone(bound_body="new_bound_body").bound_body == "new_bound_body"
|
||||
assert metadata.clone(is_builtin="new_is_builtin").is_builtin == "new_is_builtin"
|
||||
assert metadata.clone(is_unique="new_is_unique").is_unique == "new_is_unique"
|
||||
assert metadata.clone(autouse="new_autouse").autouse == "new_autouse"
|
||||
assert metadata.clone(digest="new_digest").digest == "new_digest"
|
||||
assert metadata.clone(all_attrs="new_all_attrs").all_attrs == "new_all_attrs"
|
||||
|
||||
|
||||
def test_i_cannot_change_the_id_when_cloning():
|
||||
with pytest.raises(TypeError):
|
||||
metadata = get_metadata()
|
||||
metadata.clone(id="new_id")
|
||||
with pytest.raises(TypeError):
|
||||
metadata = get_metadata()
|
||||
metadata.clone(id="new_id")
|
||||
|
||||
|
||||
def test_i_can_auto_init():
|
||||
next_id = GetNextId()
|
||||
metadata = get_metadata("a plus b", body="a + b", variables=["a", "b"]).auto_init(next_id)
|
||||
|
||||
assert metadata.name == "a plus b"
|
||||
assert metadata.id == "1001"
|
||||
assert metadata.key == "__var__0 plus __var__1"
|
||||
assert metadata.all_attrs == ('#where#', '#pre#', '#post#', '#body#', '#ret#', 'a', 'b')
|
||||
assert metadata.is_unique is False
|
||||
assert metadata.is_builtin is False
|
||||
assert metadata.definition_type is DefinitionType.DEFAULT
|
||||
assert metadata.digest == '9e058bc1261d1e2c785889147066ce89960fd6844db5bb6f1d1d809a8eb790b7'
|
||||
next_id = GetNextId()
|
||||
metadata = get_metadata("a plus b", body="a + b", variables=["a", "b"]).auto_init(next_id)
|
||||
|
||||
assert metadata.name == "a plus b"
|
||||
assert metadata.id == "1001"
|
||||
assert metadata.key == "__var__0 plus __var__1"
|
||||
assert metadata.all_attrs == ('#where#', '#pre#', '#post#', '#body#', '#ret#', 'a', 'b')
|
||||
assert metadata.is_unique is False
|
||||
assert metadata.is_builtin is False
|
||||
assert metadata.definition_type is DefinitionType.DEFAULT
|
||||
assert metadata.digest == '9e058bc1261d1e2c785889147066ce89960fd6844db5bb6f1d1d809a8eb790b7'
|
||||
|
||||
|
||||
def test_sequences_are_incremented_when_multiples_call():
|
||||
next_id = GetNextId()
|
||||
assert get_metadata("foo").auto_init(next_id).id == "1001"
|
||||
assert get_metadata("bar").auto_init(next_id).id == "1002"
|
||||
next_id = GetNextId()
|
||||
assert get_metadata("foo").auto_init(next_id).id == "1001"
|
||||
assert get_metadata("bar").auto_init(next_id).id == "1002"
|
||||
|
||||
|
||||
def test_i_can_get_multiple_metadatas():
|
||||
res = get_metadatas("foo", get_metadata("bar", body="body"))
|
||||
|
||||
assert len(res) == 2
|
||||
|
||||
metadata = res[0]
|
||||
assert isinstance(metadata, ConceptMetadata)
|
||||
assert metadata.name == "foo"
|
||||
assert metadata.body is None
|
||||
assert metadata.key is None
|
||||
assert metadata.id is None
|
||||
|
||||
metadata = res[1]
|
||||
assert isinstance(metadata, ConceptMetadata)
|
||||
assert metadata.name == "bar"
|
||||
assert metadata.body == "body"
|
||||
assert metadata.key is None
|
||||
assert metadata.id is None
|
||||
res = get_metadatas("foo", get_metadata("bar", body="body"))
|
||||
|
||||
assert len(res) == 2
|
||||
|
||||
metadata = res[0]
|
||||
assert isinstance(metadata, ConceptMetadata)
|
||||
assert metadata.name == "foo"
|
||||
assert metadata.body is None
|
||||
assert metadata.key is None
|
||||
assert metadata.id is None
|
||||
|
||||
metadata = res[1]
|
||||
assert isinstance(metadata, ConceptMetadata)
|
||||
assert metadata.name == "bar"
|
||||
assert metadata.body == "body"
|
||||
assert metadata.key is None
|
||||
assert metadata.id is None
|
||||
|
||||
|
||||
def test_i_can_get_multiple_already_initialized_metadatas():
|
||||
res = get_metadatas("foo", get_metadata("bar", body="body"), next_id=GetNextId())
|
||||
|
||||
assert len(res) == 2
|
||||
|
||||
metadata = res[0]
|
||||
assert isinstance(metadata, ConceptMetadata)
|
||||
assert metadata.name == "foo"
|
||||
assert metadata.body is None
|
||||
assert metadata.key == "foo"
|
||||
assert metadata.id == "1001"
|
||||
|
||||
metadata = res[1]
|
||||
assert isinstance(metadata, ConceptMetadata)
|
||||
assert metadata.name == "bar"
|
||||
assert metadata.body == "body"
|
||||
assert metadata.key == "bar"
|
||||
assert metadata.id == "1002"
|
||||
res = get_metadatas("foo", get_metadata("bar", body="body"), next_id=GetNextId())
|
||||
|
||||
assert len(res) == 2
|
||||
|
||||
metadata = res[0]
|
||||
assert isinstance(metadata, ConceptMetadata)
|
||||
assert metadata.name == "foo"
|
||||
assert metadata.body is None
|
||||
assert metadata.key == "foo"
|
||||
assert metadata.id == "1001"
|
||||
|
||||
metadata = res[1]
|
||||
assert isinstance(metadata, ConceptMetadata)
|
||||
assert metadata.name == "bar"
|
||||
assert metadata.body == "body"
|
||||
assert metadata.key == "bar"
|
||||
assert metadata.id == "1002"
|
||||
|
||||
|
||||
def test_i_can_get_a_concept():
|
||||
foo = get_concept("foo", variables=("var1",))
|
||||
|
||||
assert isinstance(foo, Concept)
|
||||
assert foo.name == "foo"
|
||||
assert foo.key is None
|
||||
assert foo.id is None
|
||||
assert foo.all_attrs() == ('#where#', '#pre#', '#post#', '#body#', '#ret#', 'var1')
|
||||
foo = get_concept("foo", variables=("var1",))
|
||||
|
||||
assert isinstance(foo, Concept)
|
||||
assert foo.name == "foo"
|
||||
assert foo.key is None
|
||||
assert foo.id is None
|
||||
assert foo.all_attrs() == ('#where#', '#pre#', '#post#', '#body#', '#ret#', 'var1')
|
||||
|
||||
|
||||
def test_i_can_request_basic_initialization_when_getting_a_concept():
|
||||
next_id = GetNextId()
|
||||
foo = get_concept("foo", variables=("var1",), sequence=next_id)
|
||||
|
||||
assert foo.name == "foo"
|
||||
assert foo.key == "foo"
|
||||
assert foo.id == "1001"
|
||||
assert foo.all_attrs() == ('#where#', '#pre#', '#post#', '#body#', '#ret#', 'var1')
|
||||
next_id = GetNextId()
|
||||
foo = get_concept("foo", variables=("var1",), sequence=next_id)
|
||||
|
||||
assert foo.name == "foo"
|
||||
assert foo.key == "foo"
|
||||
assert foo.id == "1001"
|
||||
assert foo.all_attrs() == ('#where#', '#pre#', '#post#', '#body#', '#ret#', 'var1')
|
||||
|
||||
|
||||
def test_i_can_get_multiple_concepts(context):
|
||||
next_id = GetNextId()
|
||||
|
||||
foo, bar, baz = get_concepts(context,
|
||||
"foo",
|
||||
"bar",
|
||||
get_concept("baz", definition="baz var1", variables=("var1",)),
|
||||
sequence=next_id)
|
||||
assert foo.name == "foo"
|
||||
assert foo.id == "1001"
|
||||
assert foo.key == "foo"
|
||||
assert bar.name == "bar"
|
||||
assert bar.id == "1002"
|
||||
assert bar.key == "bar"
|
||||
assert baz.name == "baz"
|
||||
assert baz.id == "1003"
|
||||
assert baz.key == "baz __var__0"
|
||||
next_id = GetNextId()
|
||||
|
||||
foo, bar, baz = get_concepts(context,
|
||||
"foo",
|
||||
"bar",
|
||||
get_concept("baz", definition="baz var1", variables=("var1",)),
|
||||
sequence=next_id)
|
||||
assert foo.name == "foo"
|
||||
assert foo.id == "1001"
|
||||
assert foo.key == "foo"
|
||||
assert bar.name == "bar"
|
||||
assert bar.id == "1002"
|
||||
assert bar.key == "bar"
|
||||
assert baz.name == "baz"
|
||||
assert baz.id == "1003"
|
||||
assert baz.key == "baz __var__0"
|
||||
|
||||
|
||||
def test_i_can_get_multiple_concepts_using_sheerka(sheerka, context):
|
||||
foo, bar, baz = get_concepts(context,
|
||||
"foo",
|
||||
"bar",
|
||||
get_concept("baz", definition="baz var1", variables=("var1",)),
|
||||
use_sheerka=True)
|
||||
assert foo.name == "foo"
|
||||
assert foo.id == "1001"
|
||||
assert foo.key == "foo"
|
||||
assert bar.name == "bar"
|
||||
assert bar.id == "1002"
|
||||
assert bar.key == "bar"
|
||||
assert baz.name == "baz"
|
||||
assert baz.id == "1003"
|
||||
assert baz.key == "baz __var__0"
|
||||
assert baz.get_value("var1") is NotInit
|
||||
|
||||
# the concepts are defined in Sheerka, so we can instantiate them
|
||||
baz2 = sheerka.newn("baz", var1="value for var1")
|
||||
assert baz2.name == "baz"
|
||||
assert baz2.id == "1003"
|
||||
assert baz2.key == "baz __var__0"
|
||||
assert baz2.get_value("var1") == "value for var1"
|
||||
foo, bar, baz = get_concepts(context,
|
||||
"foo",
|
||||
"bar",
|
||||
get_concept("baz", definition="baz var1", variables=("var1",)),
|
||||
use_sheerka=True)
|
||||
assert foo.name == "foo"
|
||||
assert foo.id == "1001"
|
||||
assert foo.key == "foo"
|
||||
assert bar.name == "bar"
|
||||
assert bar.id == "1002"
|
||||
assert bar.key == "bar"
|
||||
assert baz.name == "baz"
|
||||
assert baz.id == "1003"
|
||||
assert baz.key == "baz __var__0"
|
||||
assert baz.get_value("var1") is NotInit
|
||||
|
||||
# the concepts are defined in Sheerka, so we can instantiate them
|
||||
baz2 = sheerka.newn("baz", var1="value for var1")
|
||||
assert baz2.name == "baz"
|
||||
assert baz2.id == "1003"
|
||||
assert baz2.key == "baz __var__0"
|
||||
assert baz2.get_value("var1") == "value for var1"
|
||||
|
||||
|
||||
def test_i_can_get_multiple_concepts_when_same_name(sheerka, context):
|
||||
one_str, one_int = get_concepts(context,
|
||||
get_metadata("one", body="'one'"),
|
||||
get_metadata("one", body="1"),
|
||||
use_sheerka=True)
|
||||
|
||||
assert sheerka.isinstance(one_str, "one")
|
||||
assert sheerka.isinstance(one_int, "one")
|
||||
one_str, one_int = get_concepts(context,
|
||||
get_metadata("one", body="'one'"),
|
||||
get_metadata("one", body="1"),
|
||||
use_sheerka=True)
|
||||
|
||||
assert sheerka.isinstance(one_str, "one")
|
||||
assert sheerka.isinstance(one_int, "one")
|
||||
|
||||
|
||||
def test_i_can_create_test_concept():
|
||||
concept = get_concept("one", body="'one'")
|
||||
|
||||
test_concept = get_evaluated_concept(concept, body='hello', a="value for a")
|
||||
|
||||
assert test_concept.get_metadata() == concept.get_metadata()
|
||||
assert test_concept.get_value(ConceptDefaultProps.BODY) == "hello"
|
||||
assert test_concept.get_value("a") == "value for a"
|
||||
concept = get_concept("one", body="'one'")
|
||||
|
||||
test_concept = get_evaluated_concept(concept, body='hello', a="value for a")
|
||||
|
||||
assert test_concept.get_metadata() == concept.get_metadata()
|
||||
assert test_concept.get_value(ConceptDefaultProps.BODY) == "hello"
|
||||
assert test_concept.get_value("a") == "value for a"
|
||||
|
||||
|
||||
def test_i_can_dummy_evaluate_concept():
|
||||
concept = get_concept("one", body="'one'", where="True", pre="False", ret="1", post="1.0")
|
||||
|
||||
evaluated = get_evaluated_concept(concept)
|
||||
assert evaluated.get_value(ConceptDefaultProps.WHERE) is True
|
||||
assert evaluated.get_value(ConceptDefaultProps.PRE) is False
|
||||
assert evaluated.get_value(ConceptDefaultProps.BODY) == "one"
|
||||
assert evaluated.get_value(ConceptDefaultProps.RET) == 1
|
||||
assert evaluated.get_value(ConceptDefaultProps.POST) == 1.0
|
||||
|
||||
concept = get_concept("one", body='"one"', ret="'a value'")
|
||||
evaluated = get_evaluated_concept(concept, ret='forced value')
|
||||
assert evaluated.get_value(ConceptDefaultProps.WHERE) == NotInit
|
||||
assert evaluated.get_value(ConceptDefaultProps.PRE) == NotInit
|
||||
assert evaluated.get_value(ConceptDefaultProps.BODY) == "one"
|
||||
assert evaluated.get_value(ConceptDefaultProps.RET) == "forced value"
|
||||
assert evaluated.get_value(ConceptDefaultProps.POST) == NotInit
|
||||
concept = get_concept("one", body="'one'", where="True", pre="False", ret="1", post="1.0")
|
||||
|
||||
evaluated = get_evaluated_concept(concept)
|
||||
assert evaluated.get_value(ConceptDefaultProps.WHERE) is True
|
||||
assert evaluated.get_value(ConceptDefaultProps.PRE) is False
|
||||
assert evaluated.get_value(ConceptDefaultProps.BODY) == "one"
|
||||
assert evaluated.get_value(ConceptDefaultProps.RET) == 1
|
||||
assert evaluated.get_value(ConceptDefaultProps.POST) == 1.0
|
||||
|
||||
concept = get_concept("one", body='"one"', ret="'a value'")
|
||||
evaluated = get_evaluated_concept(concept, ret='forced value')
|
||||
assert evaluated.get_value(ConceptDefaultProps.WHERE) == NotInit
|
||||
assert evaluated.get_value(ConceptDefaultProps.PRE) == NotInit
|
||||
assert evaluated.get_value(ConceptDefaultProps.BODY) == "one"
|
||||
assert evaluated.get_value(ConceptDefaultProps.RET) == "forced value"
|
||||
assert evaluated.get_value(ConceptDefaultProps.POST) == NotInit
|
||||
|
||||
|
||||
def test_i_can_get_from():
|
||||
res = get_from(_mt("c:i am a concept#1001:"))
|
||||
assert res == [_mt("1001", 0, 6)]
|
||||
|
||||
res = get_from(_ut("some unrecognized stuff"))
|
||||
assert res == [_ut("some unrecognized stuff", 0, 4)]
|
||||
|
||||
res = get_from(_mt("c:i am a concept#1001:"), _ut("some unrecognized stuff"))
|
||||
assert res == [_mt("1001", 0, 6), _ut("some unrecognized stuff", 7, 11)]
|
||||
|
||||
res = get_from(_mt("c:i am a concept#1001:"), _ut("some unrecognized stuff"), parser="other")
|
||||
assert res == [_mt("1001", 0, 6, parser="other"), _ut("some unrecognized stuff", 7, 11)]
|
||||
|
||||
res = get_from(_mt("c:i am a concept#1001:"), _mt("c:#1001:"))
|
||||
assert res == [_mt("1001", 0, 6), _mt("1001", 7, 13)]
|
||||
res = get_from(_mt("c:i am a concept#1001:"))
|
||||
assert res == [_mt("1001", 0, 6)]
|
||||
|
||||
res = get_from(_ut("some unrecognized stuff"))
|
||||
assert res == [_ut("some unrecognized stuff", 0, 4)]
|
||||
|
||||
res = get_from(_mt("c:i am a concept#1001:"), _ut("some unrecognized stuff"))
|
||||
assert res == [_mt("1001", 0, 6), _ut("some unrecognized stuff", 7, 11)]
|
||||
|
||||
res = get_from(_mt("c:i am a concept#1001:"), _ut("some unrecognized stuff"), parser="other")
|
||||
assert res == [_mt("1001", 0, 6, parser="other"), _ut("some unrecognized stuff", 7, 11)]
|
||||
|
||||
res = get_from(_mt("c:i am a concept#1001:"), _mt("c:#1001:"))
|
||||
assert res == [_mt("1001", 0, 6), _mt("1001", 7, 13)]
|
||||
|
||||
Reference in New Issue
Block a user