You must now use 'eval' to get the body of a concept
This commit is contained in:
@@ -9,6 +9,9 @@ indent_size=4
|
|||||||
indent_style=space
|
indent_style=space
|
||||||
indent_size=2
|
indent_size=2
|
||||||
|
|
||||||
|
[*.py]
|
||||||
|
insert_final_newline=true
|
||||||
|
|
||||||
# Tab indentation (no size specified)
|
# Tab indentation (no size specified)
|
||||||
[Makefile]
|
[Makefile]
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
|
|||||||
@@ -44,8 +44,10 @@ class BuiltinConcepts(Enum):
|
|||||||
CONCEPT_EVAL_ERROR = "concept evaluation error" # cannot evaluate a property or metadata of a concept
|
CONCEPT_EVAL_ERROR = "concept evaluation error" # cannot evaluate a property or metadata of a concept
|
||||||
ENUMERATION = "enum" # represents a list or a set
|
ENUMERATION = "enum" # represents a list or a set
|
||||||
LIST = "list" # represents a list
|
LIST = "list" # represents a list
|
||||||
CANNOT_RESOLVE_VALUE_ERROR = "value cannot be resolved" # don't know how to find concept value
|
|
||||||
CONCEPT_ALREADY_IN_SET = "concept already in set"
|
CONCEPT_ALREADY_IN_SET = "concept already in set"
|
||||||
|
EVALUATOR_PRE_PROCESS = "evaluator pre process" # used modify / tweak behaviour of evaluators
|
||||||
|
CONCEPT_EVAL_REQUESTED = "concept eval requested"
|
||||||
|
REDUCE_REQUESTED = "reduce requested" # remove meaningless error when possible
|
||||||
|
|
||||||
NODE = "node"
|
NODE = "node"
|
||||||
GENERIC_NODE = "generic node"
|
GENERIC_NODE = "generic node"
|
||||||
@@ -68,7 +70,6 @@ BuiltinErrors = [str(e) for e in {
|
|||||||
BuiltinConcepts.INVALID_RETURN_VALUE,
|
BuiltinConcepts.INVALID_RETURN_VALUE,
|
||||||
BuiltinConcepts.CONCEPT_ALREADY_DEFINED,
|
BuiltinConcepts.CONCEPT_ALREADY_DEFINED,
|
||||||
BuiltinConcepts.CONCEPT_EVAL_ERROR,
|
BuiltinConcepts.CONCEPT_EVAL_ERROR,
|
||||||
BuiltinConcepts.CANNOT_RESOLVE_VALUE_ERROR,
|
|
||||||
BuiltinConcepts.CONCEPT_ALREADY_IN_SET,
|
BuiltinConcepts.CONCEPT_ALREADY_IN_SET,
|
||||||
}]
|
}]
|
||||||
|
|
||||||
@@ -267,6 +268,15 @@ class AfterEvaluationConcept(Concept):
|
|||||||
super().__init__(BuiltinConcepts.AFTER_EVALUATION, True, True, BuiltinConcepts.AFTER_EVALUATION)
|
super().__init__(BuiltinConcepts.AFTER_EVALUATION, True, True, BuiltinConcepts.AFTER_EVALUATION)
|
||||||
|
|
||||||
|
|
||||||
|
class ConceptEvalRequested(Concept):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(BuiltinConcepts.CONCEPT_EVAL_REQUESTED, True, True, BuiltinConcepts.CONCEPT_EVAL_REQUESTED)
|
||||||
|
|
||||||
|
|
||||||
|
class ReduceRequested(Concept):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(BuiltinConcepts.REDUCE_REQUESTED, True, True, BuiltinConcepts.REDUCE_REQUESTED)
|
||||||
|
|
||||||
class ConceptEvalError(Concept):
|
class ConceptEvalError(Concept):
|
||||||
def __init__(self, error=None, concept=None, property_name=None):
|
def __init__(self, error=None, concept=None, property_name=None):
|
||||||
super().__init__(BuiltinConcepts.CONCEPT_EVAL_ERROR,
|
super().__init__(BuiltinConcepts.CONCEPT_EVAL_ERROR,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ PROPERTIES_FOR_DIGEST = ("name", "key",
|
|||||||
"where", "pre", "post", "body",
|
"where", "pre", "post", "body",
|
||||||
"desc")
|
"desc")
|
||||||
PROPERTIES_TO_SERIALIZE = PROPERTIES_FOR_DIGEST + tuple(["id"])
|
PROPERTIES_TO_SERIALIZE = PROPERTIES_FOR_DIGEST + tuple(["id"])
|
||||||
|
PROPERTIES_FOR_NEW = ("where", "pre", "post", "body", "desc")
|
||||||
VARIABLE_PREFIX = "__var__"
|
VARIABLE_PREFIX = "__var__"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+110
-40
@@ -1,13 +1,13 @@
|
|||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
|
|
||||||
from core.builtin_concepts import BuiltinConcepts, ErrorConcept, ReturnValueConcept, BuiltinErrors
|
from core.builtin_concepts import BuiltinConcepts, ErrorConcept, ReturnValueConcept, BuiltinErrors
|
||||||
from core.concept import Concept, ConceptParts, PROPERTIES_FOR_DIGEST
|
from core.concept import Concept, ConceptParts, PROPERTIES_FOR_NEW
|
||||||
from parsers.BaseParser import BaseParser
|
from parsers.BaseParser import BaseParser
|
||||||
from sdp.sheerkaDataProvider import SheerkaDataProvider, Event, SheerkaDataProviderDuplicateKeyError
|
from sdp.sheerkaDataProvider import SheerkaDataProvider, Event, SheerkaDataProviderDuplicateKeyError
|
||||||
import core.utils
|
import core.utils
|
||||||
import core.builtin_helpers
|
import core.builtin_helpers
|
||||||
|
|
||||||
from core.sheerka_logger import console_handler, get_logger
|
from core.sheerka_logger import console_handler
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@@ -85,8 +85,9 @@ class Sheerka(Concept):
|
|||||||
if self.sdp.first_time:
|
if self.sdp.first_time:
|
||||||
self.sdp.set_key(self.USER_CONCEPTS_KEYS, 1000)
|
self.sdp.set_key(self.USER_CONCEPTS_KEYS, 1000)
|
||||||
|
|
||||||
evt_digest = self.sdp.save_event(Event("Initializing Sheerka."))
|
event = Event("Initializing Sheerka.")
|
||||||
exec_context = ExecutionContext(self.key, evt_digest, self)
|
self.sdp.save_event(event)
|
||||||
|
exec_context = ExecutionContext(self.key, event, self)
|
||||||
|
|
||||||
self.initialize_builtin_concepts()
|
self.initialize_builtin_concepts()
|
||||||
self.initialize_builtin_parsers()
|
self.initialize_builtin_parsers()
|
||||||
@@ -181,19 +182,24 @@ class Sheerka(Concept):
|
|||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
self.log.debug(f"Processing user input '{text}', {user_name=}.")
|
self.log.debug(f"Processing user input '{text}', {user_name=}.")
|
||||||
evt_digest = self.sdp.save_event(Event(text, user_name))
|
event = Event(text, user_name)
|
||||||
|
evt_digest = self.sdp.save_event(event)
|
||||||
self.log.debug(f"{evt_digest=}")
|
self.log.debug(f"{evt_digest=}")
|
||||||
execution_context = ExecutionContext(self.key, evt_digest, self)
|
execution_context = ExecutionContext(self.key, event, self)
|
||||||
|
|
||||||
user_input = self.ret(self.name, True, self.new(BuiltinConcepts.USER_INPUT, body=text, user_name=user_name))
|
user_input = self.ret(self.name, True, self.new(BuiltinConcepts.USER_INPUT, body=text, user_name=user_name))
|
||||||
|
reduce_requested = self.ret(self.name, True, self.new(BuiltinConcepts.REDUCE_REQUESTED))
|
||||||
|
|
||||||
steps = [
|
steps = [
|
||||||
BuiltinConcepts.BEFORE_PARSING,
|
BuiltinConcepts.BEFORE_PARSING,
|
||||||
BuiltinConcepts.PARSING,
|
BuiltinConcepts.PARSING,
|
||||||
|
BuiltinConcepts.AFTER_PARSING,
|
||||||
|
BuiltinConcepts.BEFORE_EVALUATION,
|
||||||
BuiltinConcepts.EVALUATION,
|
BuiltinConcepts.EVALUATION,
|
||||||
BuiltinConcepts.AFTER_EVALUATION
|
BuiltinConcepts.AFTER_EVALUATION
|
||||||
]
|
]
|
||||||
|
|
||||||
return self.execute(execution_context, user_input, steps)
|
return self.execute(execution_context, [user_input, reduce_requested], steps)
|
||||||
|
|
||||||
def _call_parsers(self, execution_context, return_values, logger=None):
|
def _call_parsers(self, execution_context, return_values, logger=None):
|
||||||
|
|
||||||
@@ -205,6 +211,7 @@ class Sheerka(Concept):
|
|||||||
for return_value in return_values:
|
for return_value in return_values:
|
||||||
# make sure we only parse user input
|
# make sure we only parse user input
|
||||||
if not return_value.status or not self.isinstance(return_value.body, BuiltinConcepts.USER_INPUT):
|
if not return_value.status or not self.isinstance(return_value.body, BuiltinConcepts.USER_INPUT):
|
||||||
|
result.append(return_value)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
to_parse = self.value(return_value)
|
to_parse = self.value(return_value)
|
||||||
@@ -232,6 +239,26 @@ class Sheerka(Concept):
|
|||||||
|
|
||||||
def _call_evaluators(self, execution_context, return_values, process_step, evaluation_context=None, logger=None):
|
def _call_evaluators(self, execution_context, return_values, process_step, evaluation_context=None, logger=None):
|
||||||
|
|
||||||
|
def _preprocess_evaluators(context, evaluators):
|
||||||
|
if not context.preprocess:
|
||||||
|
return evaluators
|
||||||
|
|
||||||
|
if not hasattr(evaluators, "__iter__"):
|
||||||
|
single_one = True
|
||||||
|
evaluators = [evaluators]
|
||||||
|
else:
|
||||||
|
single_one = False
|
||||||
|
|
||||||
|
for preprocess in context.preprocess:
|
||||||
|
for e in evaluators:
|
||||||
|
if preprocess.props["name"].value == e.name:
|
||||||
|
for prop, value in preprocess.props.items():
|
||||||
|
if prop == "name":
|
||||||
|
continue
|
||||||
|
if hasattr(e, prop):
|
||||||
|
setattr(e, prop, value.value)
|
||||||
|
return evaluators[0] if single_one else evaluators
|
||||||
|
|
||||||
# return_values must be a list
|
# return_values must be a list
|
||||||
if not isinstance(return_values, list):
|
if not isinstance(return_values, list):
|
||||||
return_values = [return_values]
|
return_values = [return_values]
|
||||||
@@ -255,6 +282,10 @@ class Sheerka(Concept):
|
|||||||
# The first one to be applied will be the one with the highest priority
|
# The first one to be applied will be the one with the highest priority
|
||||||
grouped_evaluators = {}
|
grouped_evaluators = {}
|
||||||
instantiated_evaluators = [e_class() for e_class in self.evaluators]
|
instantiated_evaluators = [e_class() for e_class in self.evaluators]
|
||||||
|
|
||||||
|
# pre-process evaluators if needed
|
||||||
|
instantiated_evaluators = _preprocess_evaluators(execution_context, instantiated_evaluators)
|
||||||
|
|
||||||
for evaluator in [e for e in instantiated_evaluators if e.enabled and process_step in e.steps]:
|
for evaluator in [e for e in instantiated_evaluators if e.enabled and process_step in e.steps]:
|
||||||
if logger:
|
if logger:
|
||||||
evaluator.log = logger
|
evaluator.log = logger
|
||||||
@@ -273,6 +304,7 @@ class Sheerka(Concept):
|
|||||||
evaluated_items = []
|
evaluated_items = []
|
||||||
to_delete = []
|
to_delete = []
|
||||||
for evaluator in grouped_evaluators[priority]:
|
for evaluator in grouped_evaluators[priority]:
|
||||||
|
evaluator = _preprocess_evaluators(execution_context, evaluator.__class__()) # fresh copy
|
||||||
|
|
||||||
# process evaluators that work on return value
|
# process evaluators that work on return value
|
||||||
from evaluators.BaseEvaluator import OneReturnValueEvaluator
|
from evaluators.BaseEvaluator import OneReturnValueEvaluator
|
||||||
@@ -334,12 +366,16 @@ class Sheerka(Concept):
|
|||||||
for step in execution_steps:
|
for step in execution_steps:
|
||||||
sub_context = execution_context.push(step=step)
|
sub_context = execution_context.push(step=step)
|
||||||
sub_context.log(logger or self.log, f"{step=}, context='{sub_context}'")
|
sub_context.log(logger or self.log, f"{step=}, context='{sub_context}'")
|
||||||
|
|
||||||
|
copy = return_values[:] if hasattr(return_values, "__iter__") else return_values
|
||||||
|
|
||||||
if step == BuiltinConcepts.PARSING:
|
if step == BuiltinConcepts.PARSING:
|
||||||
return_values = self._call_parsers(sub_context, return_values, logger)
|
return_values = self._call_parsers(sub_context, return_values, logger)
|
||||||
else:
|
else:
|
||||||
return_values = self._call_evaluators(sub_context, return_values, step, None, logger)
|
return_values = self._call_evaluators(sub_context, return_values, step, None, logger)
|
||||||
|
|
||||||
sub_context.log_result(logger or self.log, return_values)
|
if copy != return_values:
|
||||||
|
sub_context.log_result(logger or self.log, return_values)
|
||||||
|
|
||||||
return return_values
|
return return_values
|
||||||
|
|
||||||
@@ -374,7 +410,11 @@ class Sheerka(Concept):
|
|||||||
# TODO checks if it exists in cache first
|
# TODO checks if it exists in cache first
|
||||||
if self.sdp.exists(self.CONCEPTS_ENTRY, concept.key, concept.get_digest()):
|
if self.sdp.exists(self.CONCEPTS_ENTRY, concept.key, concept.get_digest()):
|
||||||
error = SheerkaDataProviderDuplicateKeyError(self.CONCEPTS_ENTRY + "." + concept.key, concept)
|
error = SheerkaDataProviderDuplicateKeyError(self.CONCEPTS_ENTRY + "." + concept.key, concept)
|
||||||
return self.ret(self.create_new_concept.__name__, False, ErrorConcept(error), error.args[0])
|
return self.ret(
|
||||||
|
self.create_new_concept.__name__,
|
||||||
|
False,
|
||||||
|
self.new(BuiltinConcepts.CONCEPT_ALREADY_DEFINED, body=concept),
|
||||||
|
error.args[0])
|
||||||
|
|
||||||
# set id before saving in db
|
# set id before saving in db
|
||||||
self.set_id_if_needed(concept, False)
|
self.set_id_if_needed(concept, False)
|
||||||
@@ -394,12 +434,18 @@ class Sheerka(Concept):
|
|||||||
|
|
||||||
# save the new context in sdp
|
# save the new context in sdp
|
||||||
try:
|
try:
|
||||||
self.sdp.add(context.event_digest, self.CONCEPTS_ENTRY, concept, use_ref=True)
|
self.sdp.add(context.event.get_digest(), self.CONCEPTS_ENTRY, concept, use_ref=True)
|
||||||
if concepts_definitions is not None:
|
if concepts_definitions is not None:
|
||||||
self.sdp.set(context.event_digest, self.CONCEPTS_DEFINITIONS_ENTRY, concepts_definitions, use_ref=True)
|
self.sdp.set(context.event.get_digest(),
|
||||||
|
self.CONCEPTS_DEFINITIONS_ENTRY,
|
||||||
|
concepts_definitions, use_ref=True)
|
||||||
except SheerkaDataProviderDuplicateKeyError as error:
|
except SheerkaDataProviderDuplicateKeyError as error:
|
||||||
context.log_error(logger, "Failed to create a new concept.", who=self.create_new_concept.__name__)
|
context.log_error(logger, "Failed to create a new concept.", who=self.create_new_concept.__name__)
|
||||||
return self.ret(self.create_new_concept.__name__, False, ErrorConcept(error), error.args[0])
|
return self.ret(
|
||||||
|
self.create_new_concept.__name__,
|
||||||
|
False,
|
||||||
|
self.new(BuiltinConcepts.CONCEPT_ALREADY_DEFINED, body=concept),
|
||||||
|
error.args[0])
|
||||||
|
|
||||||
# Updates the caches
|
# Updates the caches
|
||||||
self.concepts_cache[concept.key] = self.sdp.get_safe(self.CONCEPTS_ENTRY, concept.key)
|
self.concepts_cache[concept.key] = self.sdp.get_safe(self.CONCEPTS_ENTRY, concept.key)
|
||||||
@@ -427,8 +473,8 @@ class Sheerka(Concept):
|
|||||||
assert concept_set.id
|
assert concept_set.id
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ret = self.sdp.add_unique(context.event_digest, "All_" + str(concept_set.id), concept.id)
|
ret = self.sdp.add_unique(context.event.get_digest(), "All_" + str(concept_set.id), concept.id)
|
||||||
if ret == (None, None): # concept already in set
|
if ret == (None, None): # concept already in set
|
||||||
return self.ret(
|
return self.ret(
|
||||||
self.add_concept_to_set.__name__,
|
self.add_concept_to_set.__name__,
|
||||||
False,
|
False,
|
||||||
@@ -506,12 +552,13 @@ class Sheerka(Concept):
|
|||||||
|
|
||||||
# to make sure of the order, it don't use ConceptParts.get_parts()
|
# to make sure of the order, it don't use ConceptParts.get_parts()
|
||||||
# props must be evaluated first
|
# props must be evaluated first
|
||||||
properties_to_eval = ["props", "where", "pre", "post", "body"]
|
all_metadata_to_eval = ["props", "where", "pre", "post", "body"]
|
||||||
|
|
||||||
for prop_to_eval in properties_to_eval:
|
for metadata_to_eval in all_metadata_to_eval:
|
||||||
if prop_to_eval == "props":
|
if metadata_to_eval == "props":
|
||||||
for prop_name in (p for p in concept.props if p in concept.cached_asts):
|
for prop_name in (p for p in concept.props if p in concept.cached_asts):
|
||||||
sub_context = context.push(desc=f"Evaluating property '{prop_name}'")
|
sub_context = context.push(desc=f"Evaluating property '{prop_name}'")
|
||||||
|
sub_context.add_preprocess(self.get_evaluator_name("Concept"), return_body=True)
|
||||||
res = _resolve(sub_context, concept.cached_asts[prop_name])
|
res = _resolve(sub_context, concept.cached_asts[prop_name])
|
||||||
if res.status:
|
if res.status:
|
||||||
concept.set_prop(prop_name, res.value)
|
concept.set_prop(prop_name, res.value)
|
||||||
@@ -521,12 +568,14 @@ class Sheerka(Concept):
|
|||||||
concept=concept,
|
concept=concept,
|
||||||
property_name=prop_name)
|
property_name=prop_name)
|
||||||
else:
|
else:
|
||||||
part_key = ConceptParts(prop_to_eval)
|
part_key = ConceptParts(metadata_to_eval)
|
||||||
|
|
||||||
if part_key in concept.cached_asts and concept.cached_asts[part_key] is not None:
|
if part_key in concept.cached_asts and concept.cached_asts[part_key] is not None:
|
||||||
sub_context = context.push(desc=f"Evaluating '{part_key}'", obj=concept)
|
sub_context = context.push(desc=f"Evaluating '{part_key}'", obj=concept)
|
||||||
|
sub_context.add_preprocess(self.get_evaluator_name("Concept"), return_body=True)
|
||||||
res = _resolve(sub_context, concept.cached_asts[part_key])
|
res = _resolve(sub_context, concept.cached_asts[part_key])
|
||||||
if res.status:
|
if res.status:
|
||||||
setattr(concept.metadata, prop_to_eval, res.value)
|
setattr(concept.metadata, metadata_to_eval, res.value)
|
||||||
else:
|
else:
|
||||||
return self.new(BuiltinConcepts.CONCEPT_EVAL_ERROR,
|
return self.new(BuiltinConcepts.CONCEPT_EVAL_ERROR,
|
||||||
body=res.value,
|
body=res.value,
|
||||||
@@ -611,7 +660,7 @@ class Sheerka(Concept):
|
|||||||
for k, v in kwargs_.items():
|
for k, v in kwargs_.items():
|
||||||
if k in concept.props:
|
if k in concept.props:
|
||||||
concept.set_prop(k, v)
|
concept.set_prop(k, v)
|
||||||
elif k in PROPERTIES_FOR_DIGEST:
|
elif k in PROPERTIES_FOR_NEW:
|
||||||
setattr(concept.metadata, k, v)
|
setattr(concept.metadata, k, v)
|
||||||
elif hasattr(concept, k):
|
elif hasattr(concept, k):
|
||||||
setattr(concept, k, v)
|
setattr(concept, k, v)
|
||||||
@@ -651,28 +700,25 @@ class Sheerka(Concept):
|
|||||||
message=message,
|
message=message,
|
||||||
parents=parents)
|
parents=parents)
|
||||||
|
|
||||||
def value(self, obj, allow_none_body=False):
|
def value(self, obj, reduce_simple_list=False):
|
||||||
if obj is None:
|
if obj is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if self.isinstance(obj, BuiltinConcepts.RETURN_VALUE) and \
|
|
||||||
obj.status and \
|
|
||||||
self.isinstance(obj.value, BuiltinConcepts.USER_INPUT):
|
|
||||||
return obj.value.body
|
|
||||||
|
|
||||||
if not isinstance(obj, Concept):
|
|
||||||
return obj
|
|
||||||
|
|
||||||
if hasattr(obj, "get_value"):
|
if hasattr(obj, "get_value"):
|
||||||
return obj.get_value()
|
return obj.get_value()
|
||||||
|
|
||||||
if obj.body is not None:
|
if not isinstance(obj, Concept):
|
||||||
if (isinstance(obj.body, list) or isinstance(obj.body, set)) and len(obj.body) == 1:
|
return obj
|
||||||
return obj.body[0]
|
|
||||||
else:
|
|
||||||
return obj.body
|
|
||||||
|
|
||||||
return obj if allow_none_body else self.new(BuiltinConcepts.CANNOT_RESOLVE_VALUE_ERROR, body=obj)
|
if obj.body is None:
|
||||||
|
return obj
|
||||||
|
|
||||||
|
if reduce_simple_list and (isinstance(obj.body, list) or isinstance(obj.body, set)) and len(obj.body) == 1:
|
||||||
|
body_to_use = obj.body[0]
|
||||||
|
else:
|
||||||
|
body_to_use = obj.body
|
||||||
|
|
||||||
|
return self.value(body_to_use)
|
||||||
|
|
||||||
def values(self, objs):
|
def values(self, objs):
|
||||||
if not (isinstance(objs, list) or
|
if not (isinstance(objs, list) or
|
||||||
@@ -786,6 +832,17 @@ class Sheerka(Concept):
|
|||||||
defs = self.sdp.get(self.CONCEPTS_DEFINITIONS_ENTRY)
|
defs = self.sdp.get(self.CONCEPTS_DEFINITIONS_ENTRY)
|
||||||
self.log.info(defs)
|
self.log.info(defs)
|
||||||
|
|
||||||
|
def dump_desc(self, concept_name):
|
||||||
|
c = self.get(concept_name)
|
||||||
|
if self.isinstance(c, BuiltinConcepts.UNKNOWN_CONCEPT):
|
||||||
|
self.log.error("Concept unknown")
|
||||||
|
return False
|
||||||
|
|
||||||
|
self.log.info(f"name : {c.name}")
|
||||||
|
self.log.info(f"bnf : {c.metadata.definition}")
|
||||||
|
self.log.info(f"key : {c.key}")
|
||||||
|
self.log.info(f"body : {c.body}")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_builtins_classes_as_dict():
|
def get_builtins_classes_as_dict():
|
||||||
res = {}
|
res = {}
|
||||||
@@ -817,7 +874,7 @@ class ExecutionContext:
|
|||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
who,
|
who,
|
||||||
event_digest: str,
|
event: Event,
|
||||||
sheerka: Sheerka,
|
sheerka: Sheerka,
|
||||||
/,
|
/,
|
||||||
desc: str = None,
|
desc: str = None,
|
||||||
@@ -827,20 +884,32 @@ class ExecutionContext:
|
|||||||
concepts: dict = None):
|
concepts: dict = None):
|
||||||
|
|
||||||
self.who = who # who is asking
|
self.who = who # who is asking
|
||||||
self.event_digest = event_digest # what was the (original) trigger
|
self.event = event # what was the (original) trigger
|
||||||
self.sheerka = sheerka # sheerka
|
self.sheerka = sheerka # sheerka
|
||||||
|
|
||||||
self.step = step
|
self.step = step
|
||||||
self.iteration = iteration
|
self.iteration = iteration
|
||||||
|
self.preprocess = None
|
||||||
|
|
||||||
self.desc = desc # human description of what is going on
|
self.desc = desc # human description of what is going on
|
||||||
self.obj = obj # what is the subject of the execution context (if known)
|
self.obj = obj # what is the subject of the execution context (if known)
|
||||||
|
|
||||||
self.concepts = concepts or {}
|
self.concepts = concepts or {} # cache for concepts that are specific to this execution
|
||||||
|
|
||||||
self._id = ExecutionContextIdManager.get_id(event_digest)
|
self._id = ExecutionContextIdManager.get_id(event.get_digest())
|
||||||
self._tab = ""
|
self._tab = ""
|
||||||
|
|
||||||
|
def add_preprocess(self, name, **kwargs):
|
||||||
|
preprocess = self.sheerka.new(BuiltinConcepts.EVALUATOR_PRE_PROCESS)
|
||||||
|
preprocess.set_prop("name", name)
|
||||||
|
for k, v in kwargs.items():
|
||||||
|
preprocess.set_prop(k, v)
|
||||||
|
|
||||||
|
if not self.preprocess:
|
||||||
|
self.preprocess = set()
|
||||||
|
self.preprocess.add(preprocess)
|
||||||
|
return self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def id(self):
|
def id(self):
|
||||||
return self._id
|
return self._id
|
||||||
@@ -854,7 +923,7 @@ class ExecutionContext:
|
|||||||
iteration = kwargs.get("iteration", self.iteration)
|
iteration = kwargs.get("iteration", self.iteration)
|
||||||
new = ExecutionContext(
|
new = ExecutionContext(
|
||||||
who,
|
who,
|
||||||
self.event_digest,
|
self.event,
|
||||||
self.sheerka,
|
self.sheerka,
|
||||||
desc=desc,
|
desc=desc,
|
||||||
obj=obj,
|
obj=obj,
|
||||||
@@ -863,6 +932,7 @@ class ExecutionContext:
|
|||||||
iteration=iteration,
|
iteration=iteration,
|
||||||
)
|
)
|
||||||
new._tab = self._tab + " " * DEBUG_TAB_SIZE
|
new._tab = self._tab + " " * DEBUG_TAB_SIZE
|
||||||
|
new.preprocess = self.preprocess
|
||||||
return new
|
return new
|
||||||
|
|
||||||
def log_new(self, logger):
|
def log_new(self, logger):
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ class BaseEvaluator:
|
|||||||
self.priority = priority
|
self.priority = priority
|
||||||
self.enabled = enabled
|
self.enabled = enabled
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"{self.name} ({self.priority})"
|
||||||
|
|
||||||
|
|
||||||
class OneReturnValueEvaluator(BaseEvaluator):
|
class OneReturnValueEvaluator(BaseEvaluator):
|
||||||
"""
|
"""
|
||||||
@@ -37,8 +40,13 @@ class AllReturnValuesEvaluator(BaseEvaluator):
|
|||||||
Evaluates the groups of ReturnValues
|
Evaluates the groups of ReturnValues
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def __init__(self, name, steps, priority: int, enabled=True):
|
||||||
|
super().__init__(name, steps, priority, enabled)
|
||||||
|
self.eaten = []
|
||||||
|
|
||||||
def matches(self, context: ExecutionContext, return_values):
|
def matches(self, context: ExecutionContext, return_values):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def eval(self, context: ExecutionContext, return_values):
|
def eval(self, context: ExecutionContext, return_values):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@@ -17,8 +17,9 @@ class ConceptEvaluator(OneReturnValueEvaluator):
|
|||||||
BuiltinConcepts.AFTER_EVALUATION
|
BuiltinConcepts.AFTER_EVALUATION
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, return_body=False):
|
||||||
super().__init__(self.NAME, [BuiltinConcepts.EVALUATION], 50)
|
super().__init__(self.NAME, [BuiltinConcepts.EVALUATION], 50)
|
||||||
|
self.return_body = return_body
|
||||||
|
|
||||||
def matches(self, context, return_value):
|
def matches(self, context, return_value):
|
||||||
return return_value.status and \
|
return return_value.status and \
|
||||||
@@ -35,7 +36,7 @@ class ConceptEvaluator(OneReturnValueEvaluator):
|
|||||||
# If we evaluate Concept("foo", body="a").set_prop("a", "'property_a'")
|
# If we evaluate Concept("foo", body="a").set_prop("a", "'property_a'")
|
||||||
# The body should be 'property_a', and not a concept called a in our universe
|
# The body should be 'property_a', and not a concept called a in our universe
|
||||||
if context.obj and concept.name in context.obj.props:
|
if context.obj and concept.name in context.obj.props:
|
||||||
return sheerka.ret(self.name, False, sheerka.new(BuiltinConcepts.NOT_FOR_ME), parents=[return_value])
|
return sheerka.ret(self.name, True, context.obj.props[concept.name].value, parents=[return_value])
|
||||||
|
|
||||||
evaluated = sheerka.evaluate_concept(context, concept, self.verbose_log)
|
evaluated = sheerka.evaluate_concept(context, concept, self.verbose_log)
|
||||||
|
|
||||||
@@ -48,7 +49,7 @@ class ConceptEvaluator(OneReturnValueEvaluator):
|
|||||||
evaluated,
|
evaluated,
|
||||||
parents=[return_value])
|
parents=[return_value])
|
||||||
|
|
||||||
if ConceptParts.BODY not in evaluated.cached_asts:
|
if not self.return_body or ConceptParts.BODY not in evaluated.cached_asts:
|
||||||
return sheerka.ret(self.name, True, evaluated, parents=[return_value])
|
return sheerka.ret(self.name, True, evaluated, parents=[return_value])
|
||||||
else:
|
else:
|
||||||
return sheerka.ret(self.name, True, evaluated.body, parents=[return_value])
|
return sheerka.ret(self.name, True, evaluated.body, parents=[return_value])
|
||||||
|
|||||||
@@ -1,45 +0,0 @@
|
|||||||
from core.builtin_concepts import BuiltinConcepts
|
|
||||||
from evaluators.AddConceptEvaluator import AddConceptEvaluator
|
|
||||||
from evaluators.BaseEvaluator import AllReturnValuesEvaluator
|
|
||||||
from parsers.BaseParser import BaseParser
|
|
||||||
from sdp.sheerkaDataProvider import SheerkaDataProviderDuplicateKeyError
|
|
||||||
|
|
||||||
|
|
||||||
class DuplicateConceptEvaluator(AllReturnValuesEvaluator):
|
|
||||||
"""
|
|
||||||
Use to recognize when we tried to add the same concept twice
|
|
||||||
"""
|
|
||||||
|
|
||||||
NAME = "DuplicateConcept"
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__(self.NAME, [BuiltinConcepts.AFTER_EVALUATION], 10)
|
|
||||||
self.already_defined = None
|
|
||||||
|
|
||||||
def matches(self, context, return_values):
|
|
||||||
sheerka = context.sheerka
|
|
||||||
parsing = False
|
|
||||||
add_concept_in_error = False
|
|
||||||
only_parsers = True
|
|
||||||
|
|
||||||
for ret in return_values:
|
|
||||||
if sheerka.isinstance(ret.value, BuiltinConcepts.AFTER_EVALUATION):
|
|
||||||
if ret.status:
|
|
||||||
parsing = True
|
|
||||||
elif ret.who == sheerka.get_evaluator_name(AddConceptEvaluator.NAME):
|
|
||||||
if not ret.status and isinstance(ret.value.body, SheerkaDataProviderDuplicateKeyError):
|
|
||||||
add_concept_in_error = True
|
|
||||||
self.already_defined = ret.value.body.obj
|
|
||||||
else:
|
|
||||||
if not ret.who.startswith(BaseParser.PREFIX):
|
|
||||||
only_parsers = False
|
|
||||||
|
|
||||||
return parsing and add_concept_in_error and only_parsers
|
|
||||||
|
|
||||||
def eval(self, context, return_values):
|
|
||||||
sheerka = context.sheerka
|
|
||||||
return sheerka.ret(
|
|
||||||
self.name,
|
|
||||||
False,
|
|
||||||
sheerka.new(BuiltinConcepts.CONCEPT_ALREADY_DEFINED, body=self.already_defined),
|
|
||||||
parents=return_values)
|
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
from core.builtin_concepts import BuiltinConcepts
|
||||||
|
from core.concept import Concept
|
||||||
|
from evaluators.BaseEvaluator import AllReturnValuesEvaluator
|
||||||
|
|
||||||
|
|
||||||
|
class EvalEvaluator(AllReturnValuesEvaluator):
|
||||||
|
"""
|
||||||
|
Returns the body of all successful concepts
|
||||||
|
"""
|
||||||
|
|
||||||
|
NAME = "Eval"
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(self.NAME, [BuiltinConcepts.AFTER_EVALUATION], 80)
|
||||||
|
self.successful_return_value = None
|
||||||
|
self.to_eval = []
|
||||||
|
self.eval_requested = None
|
||||||
|
|
||||||
|
def matches(self, context, return_values):
|
||||||
|
sheerka = context.sheerka
|
||||||
|
for ret in return_values:
|
||||||
|
if ret.status and sheerka.isinstance(ret.body, BuiltinConcepts.CONCEPT_EVAL_REQUESTED):
|
||||||
|
self.eval_requested = ret
|
||||||
|
elif ret.status and isinstance(ret.body, Concept) and ret.body.body:
|
||||||
|
self.to_eval.append(ret)
|
||||||
|
|
||||||
|
return self.eval_requested is not None and len(self.to_eval) > 0
|
||||||
|
|
||||||
|
def eval(self, context, return_value):
|
||||||
|
sheerka = context.sheerka
|
||||||
|
result = []
|
||||||
|
context.log(self.verbose_log, f"{len(self.to_eval)} return value(s) to eval", who=self)
|
||||||
|
|
||||||
|
for ret_val in self.to_eval:
|
||||||
|
context.log(self.verbose_log, f"{ret_val}", who=self)
|
||||||
|
result.append(sheerka.ret(self.name, True, ret_val.body.body, parents=[ret_val, self.eval_requested]))
|
||||||
|
|
||||||
|
return result
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
from core.builtin_concepts import BuiltinConcepts
|
from core.builtin_concepts import BuiltinConcepts
|
||||||
import core.builtin_helpers
|
import core.builtin_helpers
|
||||||
|
from core.concept import Concept
|
||||||
from evaluators.BaseEvaluator import AllReturnValuesEvaluator, BaseEvaluator
|
from evaluators.BaseEvaluator import AllReturnValuesEvaluator, BaseEvaluator
|
||||||
|
from evaluators.ConceptEvaluator import ConceptEvaluator
|
||||||
|
from evaluators.PythonEvaluator import PythonEvaluator
|
||||||
from parsers.BaseParser import BaseParser
|
from parsers.BaseParser import BaseParser
|
||||||
|
|
||||||
|
|
||||||
@@ -15,38 +18,66 @@ class MultipleSameSuccessEvaluator(AllReturnValuesEvaluator):
|
|||||||
NAME = "MultipleSameSuccess"
|
NAME = "MultipleSameSuccess"
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__(self.NAME, [BuiltinConcepts.AFTER_EVALUATION], 10)
|
super().__init__(self.NAME, [BuiltinConcepts.AFTER_EVALUATION], 50)
|
||||||
self.success = []
|
self.success = []
|
||||||
|
|
||||||
def matches(self, context, return_values):
|
def matches(self, context, return_values):
|
||||||
sheerka = context.sheerka
|
|
||||||
after_evaluation = False
|
|
||||||
nb_successful_evaluators = 0
|
nb_successful_evaluators = 0
|
||||||
only_parsers_in_error = True
|
only_parsers_in_error = True
|
||||||
unlisted = False
|
to_process = False
|
||||||
|
|
||||||
for ret in return_values:
|
for ret in return_values:
|
||||||
|
|
||||||
if sheerka.isinstance(ret.value, BuiltinConcepts.AFTER_EVALUATION):
|
if ret.status and context.sheerka.isinstance(ret.body, BuiltinConcepts.REDUCE_REQUESTED):
|
||||||
if ret.status:
|
to_process = True
|
||||||
after_evaluation = True
|
self.eaten.append(ret)
|
||||||
|
|
||||||
elif ret.who.startswith(BaseEvaluator.PREFIX):
|
elif ret.who.startswith(BaseEvaluator.PREFIX):
|
||||||
if ret.status:
|
if ret.status:
|
||||||
nb_successful_evaluators += 1
|
nb_successful_evaluators += 1
|
||||||
self.success.append(ret)
|
self.success.append(ret)
|
||||||
|
self.eaten.append(ret)
|
||||||
elif ret.who.startswith(BaseParser.PREFIX):
|
elif ret.who.startswith(BaseParser.PREFIX):
|
||||||
|
self.eaten.append(ret)
|
||||||
if ret.status:
|
if ret.status:
|
||||||
only_parsers_in_error = False
|
only_parsers_in_error = False
|
||||||
else:
|
|
||||||
unlisted = True
|
|
||||||
|
|
||||||
return after_evaluation and nb_successful_evaluators > 1 and only_parsers_in_error and not unlisted
|
return to_process and nb_successful_evaluators > 1 and only_parsers_in_error
|
||||||
|
|
||||||
def eval(self, context, return_values):
|
def eval(self, context, return_values):
|
||||||
sheerka = context.sheerka
|
sheerka = context.sheerka
|
||||||
if core.builtin_helpers.is_same_success(sheerka, self.success):
|
context.log(self.verbose_log, f"{len(self.success)} successful return value(s)", who=self)
|
||||||
reference = sheerka.value(self.success[0].value, allow_none_body=True)
|
for s in self.success:
|
||||||
return sheerka.ret(self.name, True, reference, parents=return_values)
|
context.log(self.verbose_log, f"{s}", who=self)
|
||||||
|
|
||||||
|
if not core.builtin_helpers.is_same_success(sheerka, self.success):
|
||||||
|
return None
|
||||||
|
|
||||||
|
# ######################################
|
||||||
|
# !!!!! W A R N I N G !!!!!!!!
|
||||||
|
# I have a massive issue with how I implement this feature
|
||||||
|
# I have forced an arbitrary order between Concept evaluator and Python evaluator
|
||||||
|
# I gave a random order to the other
|
||||||
|
#
|
||||||
|
# I guess that we need a proper algorithm to elect which return value to use if they have the same result
|
||||||
|
# I guts feeling is that, it will depend on the intent of the user
|
||||||
|
# So it depends on the context
|
||||||
|
|
||||||
|
# try to return a concept if possible
|
||||||
|
# give the priority to the ConceptEvaluator
|
||||||
|
for s in self.success:
|
||||||
|
if isinstance(s.value, Concept) and s.who == ConceptEvaluator().name:
|
||||||
|
return sheerka.ret(self.name, True, s.value, parents=self.eaten)
|
||||||
|
|
||||||
|
# Then the PythonEvaluator
|
||||||
|
for s in self.success:
|
||||||
|
if isinstance(s.value, Concept) and s.who == PythonEvaluator().name:
|
||||||
|
return sheerka.ret(self.name, True, s.value, parents=self.eaten)
|
||||||
|
|
||||||
|
# Then the first concept.
|
||||||
|
# It's not predictable, so I guess that it's not a good implementation choice
|
||||||
|
for s in self.success:
|
||||||
|
if isinstance(s.value, Concept):
|
||||||
|
return sheerka.ret(self.name, True, s.value, parents=self.eaten)
|
||||||
|
|
||||||
|
return sheerka.ret(self.name, True, self.success[0].value, parents=self.eaten)
|
||||||
|
|
||||||
return None
|
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
from core.builtin_concepts import BuiltinConcepts
|
||||||
|
from evaluators.BaseEvaluator import AllReturnValuesEvaluator
|
||||||
|
from parsers.BaseParser import BaseParser
|
||||||
|
|
||||||
|
|
||||||
|
class OneErrorEvaluator(AllReturnValuesEvaluator):
|
||||||
|
"""
|
||||||
|
Use to reduce when there is only one evaluator in error
|
||||||
|
The rest of the return values must be parsers in error
|
||||||
|
"""
|
||||||
|
|
||||||
|
NAME = "OneError"
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(self.NAME, [BuiltinConcepts.AFTER_EVALUATION], 40)
|
||||||
|
self.return_value_in_error = None
|
||||||
|
|
||||||
|
def matches(self, context, return_values):
|
||||||
|
nb_evaluators_in_error = 0
|
||||||
|
to_process = False
|
||||||
|
|
||||||
|
for ret in return_values:
|
||||||
|
if ret.status and (ret.who.startswith(self.PREFIX) or ret.who.startswith(BaseParser.PREFIX)):
|
||||||
|
return False
|
||||||
|
elif ret.status and context.sheerka.isinstance(ret.body, BuiltinConcepts.REDUCE_REQUESTED):
|
||||||
|
to_process = True
|
||||||
|
self.eaten.append(ret)
|
||||||
|
elif not ret.status and ret.who.startswith(self.PREFIX):
|
||||||
|
nb_evaluators_in_error += 1
|
||||||
|
self.return_value_in_error = ret
|
||||||
|
self.eaten.append(ret)
|
||||||
|
elif not ret.status and ret.who.startswith(BaseParser.PREFIX):
|
||||||
|
self.eaten.append(ret)
|
||||||
|
|
||||||
|
return to_process and nb_evaluators_in_error == 1
|
||||||
|
|
||||||
|
def eval(self, context, return_values):
|
||||||
|
context.log(self.verbose_log, f"1 return value in error, {len(self.eaten)} item(s) eaten", who=self)
|
||||||
|
context.log(self.verbose_log, f"{self.return_value_in_error}", who=self)
|
||||||
|
|
||||||
|
sheerka = context.sheerka
|
||||||
|
return sheerka.ret(self.name, False, self.return_value_in_error.value, parents=self.eaten)
|
||||||
@@ -14,28 +14,31 @@ class OneSuccessEvaluator(AllReturnValuesEvaluator):
|
|||||||
NAME = "OneSuccess"
|
NAME = "OneSuccess"
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__(self.NAME, [BuiltinConcepts.AFTER_EVALUATION], 10)
|
super().__init__(self.NAME, [BuiltinConcepts.AFTER_EVALUATION], 60) # before MultipleSameSuccess
|
||||||
self.successful_return_value = None
|
self.successful_return_value = None
|
||||||
|
|
||||||
def matches(self, context, return_values):
|
def matches(self, context, return_values):
|
||||||
sheerka = context.sheerka
|
|
||||||
after_evaluation = False
|
|
||||||
nb_successful_evaluators = 0
|
nb_successful_evaluators = 0
|
||||||
only_parsers = True
|
to_process = False
|
||||||
for ret in return_values:
|
|
||||||
if sheerka.isinstance(ret.value, BuiltinConcepts.AFTER_EVALUATION):
|
|
||||||
if ret.status:
|
|
||||||
after_evaluation = True
|
|
||||||
elif ret.who.startswith(self.PREFIX):
|
|
||||||
if ret.status:
|
|
||||||
nb_successful_evaluators += 1
|
|
||||||
self.successful_return_value = ret
|
|
||||||
else:
|
|
||||||
if not ret.who.startswith(BaseParser.PREFIX):
|
|
||||||
only_parsers = False
|
|
||||||
|
|
||||||
return after_evaluation and nb_successful_evaluators == 1 and only_parsers
|
for ret in return_values:
|
||||||
|
if ret.status and ret.who.startswith(BaseParser.PREFIX):
|
||||||
|
return False
|
||||||
|
elif ret.status and context.sheerka.isinstance(ret.body, BuiltinConcepts.REDUCE_REQUESTED):
|
||||||
|
to_process = True
|
||||||
|
self.eaten.append(ret)
|
||||||
|
elif ret.status and ret.who.startswith(self.PREFIX):
|
||||||
|
nb_successful_evaluators += 1
|
||||||
|
self.successful_return_value = ret
|
||||||
|
self.eaten.append(ret)
|
||||||
|
elif not ret.status:
|
||||||
|
self.eaten.append(ret)
|
||||||
|
|
||||||
|
return to_process and nb_successful_evaluators == 1
|
||||||
|
|
||||||
def eval(self, context, return_values):
|
def eval(self, context, return_values):
|
||||||
|
context.log(self.verbose_log, f"1 successful return value, {len(self.eaten)} item(s) eaten", who=self)
|
||||||
|
context.log(self.verbose_log, f"{self.successful_return_value}", who=self)
|
||||||
|
|
||||||
sheerka = context.sheerka
|
sheerka = context.sheerka
|
||||||
return sheerka.ret(self.name, True, self.successful_return_value.value, parents=return_values)
|
return sheerka.ret(self.name, True, self.successful_return_value.value, parents=self.eaten)
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
from core.builtin_concepts import BuiltinConcepts
|
||||||
|
from evaluators.BaseEvaluator import OneReturnValueEvaluator
|
||||||
|
|
||||||
|
|
||||||
|
class PrepareEvalEvaluator(OneReturnValueEvaluator):
|
||||||
|
"""
|
||||||
|
To parse evaluation requests
|
||||||
|
"""
|
||||||
|
|
||||||
|
NAME = "PrepareEval"
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
super().__init__(self.NAME, [BuiltinConcepts.BEFORE_PARSING], 90)
|
||||||
|
self.text = None
|
||||||
|
|
||||||
|
def matches(self, context, return_value):
|
||||||
|
if not (return_value.status and
|
||||||
|
context.sheerka.isinstance(return_value.body, BuiltinConcepts.USER_INPUT) and
|
||||||
|
isinstance(return_value.body.body, str)):
|
||||||
|
return False
|
||||||
|
|
||||||
|
text = return_value.body.body.strip()
|
||||||
|
if not text.startswith("eval "):
|
||||||
|
return False
|
||||||
|
|
||||||
|
self.text = text
|
||||||
|
return True
|
||||||
|
|
||||||
|
def eval(self, context, return_value):
|
||||||
|
sheerka = context.sheerka
|
||||||
|
|
||||||
|
new_text_to_parse = sheerka.ret(
|
||||||
|
self.name,
|
||||||
|
True, sheerka.new(BuiltinConcepts.USER_INPUT, body=self.text[5:], user_name=context.event.user))
|
||||||
|
|
||||||
|
evaluation_requested = sheerka.ret(
|
||||||
|
self.name,
|
||||||
|
True, sheerka.new(BuiltinConcepts.CONCEPT_EVAL_REQUESTED))
|
||||||
|
|
||||||
|
return [new_text_to_parse, evaluation_requested]
|
||||||
@@ -2,6 +2,7 @@ import copy
|
|||||||
|
|
||||||
from core.ast.visitors import UnreferencedNamesVisitor
|
from core.ast.visitors import UnreferencedNamesVisitor
|
||||||
from core.builtin_concepts import BuiltinConcepts, ParserResultConcept
|
from core.builtin_concepts import BuiltinConcepts, ParserResultConcept
|
||||||
|
from core.concept import ConceptParts
|
||||||
from evaluators.BaseEvaluator import OneReturnValueEvaluator
|
from evaluators.BaseEvaluator import OneReturnValueEvaluator
|
||||||
from parsers.PythonParser import PythonNode
|
from parsers.PythonParser import PythonNode
|
||||||
import ast
|
import ast
|
||||||
@@ -29,6 +30,14 @@ class PythonEvaluator(OneReturnValueEvaluator):
|
|||||||
try:
|
try:
|
||||||
context.log(self.verbose_log, f"Evaluating python node {node}.", self.name)
|
context.log(self.verbose_log, f"Evaluating python node {node}.", self.name)
|
||||||
|
|
||||||
|
# Do not evaluate if the ast refers to a concept (leave it to ConceptEvaluator)
|
||||||
|
if isinstance(node.ast_, ast.Expression) and isinstance(node.ast_.body, ast.Name):
|
||||||
|
c = context.sheerka.get(node.ast_.body.id)
|
||||||
|
if not context.sheerka.isinstance(c, BuiltinConcepts.UNKNOWN_CONCEPT):
|
||||||
|
context.log(self.verbose_log, "It's a simple concept. Not for me.", self.name)
|
||||||
|
not_for_me = context.sheerka.new(BuiltinConcepts.NOT_FOR_ME, body=node)
|
||||||
|
return sheerka.ret(self.name, False, not_for_me, parents=[return_value])
|
||||||
|
|
||||||
my_locals = self.get_locals(context, node.ast_)
|
my_locals = self.get_locals(context, node.ast_)
|
||||||
context.log(self.verbose_log, f"locals={my_locals}", self.name)
|
context.log(self.verbose_log, f"locals={my_locals}", self.name)
|
||||||
|
|
||||||
@@ -78,7 +87,7 @@ class PythonEvaluator(OneReturnValueEvaluator):
|
|||||||
evaluated = context.sheerka.evaluate_concept(sub_context, concept, self.verbose_log)
|
evaluated = context.sheerka.evaluate_concept(sub_context, concept, self.verbose_log)
|
||||||
|
|
||||||
if evaluated.key == concept.key:
|
if evaluated.key == concept.key:
|
||||||
my_locals[name] = evaluated.body or evaluated
|
my_locals[name] = evaluated.body or evaluated # if ConceptParts.BODY not in evaluated.cached_asts else evaluated
|
||||||
|
|
||||||
return my_locals
|
return my_locals
|
||||||
|
|
||||||
|
|||||||
@@ -17,33 +17,25 @@ class TooManySuccessEvaluator(AllReturnValuesEvaluator):
|
|||||||
NAME = "TooManySuccess"
|
NAME = "TooManySuccess"
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__(self.NAME, [BuiltinConcepts.AFTER_EVALUATION], 10)
|
super().__init__(self.NAME, [BuiltinConcepts.AFTER_EVALUATION], 60)
|
||||||
self.success = []
|
self.success = []
|
||||||
|
|
||||||
def matches(self, context, return_values):
|
def matches(self, context, return_values):
|
||||||
sheerka = context.sheerka
|
to_process = False
|
||||||
after_evaluation = False
|
|
||||||
nb_successful_evaluators = 0
|
|
||||||
only_parsers_in_error = True
|
|
||||||
unlisted = False
|
|
||||||
|
|
||||||
for ret in return_values:
|
for ret in return_values:
|
||||||
|
if ret.status and ret.who.startswith(BaseParser.PREFIX):
|
||||||
|
return False
|
||||||
|
elif ret.status and context.sheerka.isinstance(ret.body, BuiltinConcepts.REDUCE_REQUESTED):
|
||||||
|
to_process = True
|
||||||
|
self.eaten.append(ret)
|
||||||
|
elif ret.status and ret.who.startswith(self.PREFIX):
|
||||||
|
self.success.append(ret)
|
||||||
|
self.eaten.append(ret)
|
||||||
|
elif not ret.status:
|
||||||
|
self.eaten.append(ret)
|
||||||
|
|
||||||
if sheerka.isinstance(ret.value, BuiltinConcepts.AFTER_EVALUATION):
|
return to_process and len(self.success) > 1
|
||||||
if ret.status:
|
|
||||||
after_evaluation = True
|
|
||||||
|
|
||||||
elif ret.who.startswith(BaseEvaluator.PREFIX):
|
|
||||||
if ret.status:
|
|
||||||
nb_successful_evaluators += 1
|
|
||||||
self.success.append(ret)
|
|
||||||
elif ret.who.startswith(BaseParser.PREFIX):
|
|
||||||
if ret.status:
|
|
||||||
only_parsers_in_error = False
|
|
||||||
else:
|
|
||||||
unlisted = True
|
|
||||||
|
|
||||||
return after_evaluation and nb_successful_evaluators > 1 and only_parsers_in_error and not unlisted
|
|
||||||
|
|
||||||
def eval(self, context, return_values):
|
def eval(self, context, return_values):
|
||||||
sheerka = context.sheerka
|
sheerka = context.sheerka
|
||||||
@@ -56,8 +48,7 @@ class TooManySuccessEvaluator(AllReturnValuesEvaluator):
|
|||||||
context.log(self.verbose_log,
|
context.log(self.verbose_log,
|
||||||
f"Values are different. Raising {BuiltinConcepts.TOO_MANY_SUCCESS}.", self.name)
|
f"Values are different. Raising {BuiltinConcepts.TOO_MANY_SUCCESS}.", self.name)
|
||||||
too_many_success = sheerka.new(BuiltinConcepts.TOO_MANY_SUCCESS, body=self.success)
|
too_many_success = sheerka.new(BuiltinConcepts.TOO_MANY_SUCCESS, body=self.success)
|
||||||
return sheerka.ret(self.name, False, too_many_success, parents=return_values)
|
return sheerka.ret(self.name, False, too_many_success, parents=self.eaten)
|
||||||
|
|
||||||
context.log(self.verbose_log,
|
context.log(self.verbose_log, f"Values are the same. Nothing to do.", self.name)
|
||||||
f"Values are the same. Nothing to do.", self.name)
|
|
||||||
return None
|
return None
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
from core.builtin_concepts import BuiltinConcepts
|
from core.builtin_concepts import BuiltinConcepts
|
||||||
from parsers.BaseParser import BaseParser
|
from parsers.BaseParser import BaseParser
|
||||||
import logging
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class EmptyStringParser(BaseParser):
|
class EmptyStringParser(BaseParser):
|
||||||
|
|||||||
@@ -25,21 +25,31 @@ class Event(object):
|
|||||||
Class that represents something that modifies the state of the system
|
Class that represents something that modifies the state of the system
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, message="", user="kodjo", date=datetime.now()):
|
def __init__(self, message="", user="", date=datetime.now()):
|
||||||
self.version = 1
|
self.version = 1
|
||||||
self.user = user
|
self.user = user
|
||||||
self.date = date
|
self.date = date
|
||||||
self.message = message
|
self.message = message
|
||||||
|
self._digest = None
|
||||||
|
|
||||||
def get_digest(self):
|
def get_digest(self):
|
||||||
"""
|
"""
|
||||||
Returns the digest of the event
|
Returns the digest of the event
|
||||||
:return: hexa form of the sha256
|
:return: hexa form of the sha256
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if self._digest:
|
||||||
|
return self._digest
|
||||||
|
|
||||||
|
if self.message == "" and self.user == "":
|
||||||
|
self._digest = "xxx" # to speed unit tests
|
||||||
|
return self._digest
|
||||||
|
|
||||||
if not isinstance(self.message, str):
|
if not isinstance(self.message, str):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
return hashlib.sha256(f"Event:{self.user}{self.date}{self.message}".encode("utf-8")).hexdigest()
|
self._digest = hashlib.sha256(f"Event:{self.user}{self.date}{self.message}".encode("utf-8")).hexdigest()
|
||||||
|
return self._digest
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
return self.__dict__
|
return self.__dict__
|
||||||
|
|||||||
@@ -12,12 +12,13 @@ from parsers.ConceptLexerParser import Sequence, StrMatch, ZeroOrMore, ConceptMa
|
|||||||
from parsers.BnfParser import BnfParser
|
from parsers.BnfParser import BnfParser
|
||||||
from parsers.DefaultParser import DefConceptNode, NameNode
|
from parsers.DefaultParser import DefConceptNode, NameNode
|
||||||
from parsers.PythonParser import PythonNode, PythonParser
|
from parsers.PythonParser import PythonNode, PythonParser
|
||||||
|
from sdp.sheerkaDataProvider import Event
|
||||||
|
|
||||||
|
|
||||||
def get_context():
|
def get_context():
|
||||||
sheerka = Sheerka(skip_builtins_in_db=True)
|
sheerka = Sheerka(skip_builtins_in_db=True)
|
||||||
sheerka.initialize("mem://")
|
sheerka.initialize("mem://")
|
||||||
return ExecutionContext("test", "xxx", sheerka)
|
return ExecutionContext("test", Event(), sheerka)
|
||||||
|
|
||||||
|
|
||||||
def get_concept(name, where=None, pre=None, post=None, body=None, definition=None):
|
def get_concept(name, where=None, pre=None, post=None, body=None, definition=None):
|
||||||
|
|||||||
@@ -6,12 +6,13 @@ from core.sheerka import Sheerka, ExecutionContext
|
|||||||
from core.tokenizer import Tokenizer
|
from core.tokenizer import Tokenizer
|
||||||
from evaluators.AddConceptInSetEvaluator import AddConceptInSetEvaluator
|
from evaluators.AddConceptInSetEvaluator import AddConceptInSetEvaluator
|
||||||
from parsers.DefaultParser import IsaConceptNode, NameNode
|
from parsers.DefaultParser import IsaConceptNode, NameNode
|
||||||
|
from sdp.sheerkaDataProvider import Event
|
||||||
|
|
||||||
|
|
||||||
def get_context():
|
def get_context():
|
||||||
sheerka = Sheerka(skip_builtins_in_db=True)
|
sheerka = Sheerka(skip_builtins_in_db=True)
|
||||||
sheerka.initialize("mem://")
|
sheerka.initialize("mem://")
|
||||||
return ExecutionContext("test", "xxx", sheerka)
|
return ExecutionContext("test", Event(), sheerka)
|
||||||
|
|
||||||
|
|
||||||
def get_ret_val(concept_name, concept_set_name):
|
def get_ret_val(concept_name, concept_set_name):
|
||||||
@@ -74,6 +75,23 @@ def test_i_can_add_concept_to_a_set_of_concept():
|
|||||||
assert context.sheerka.isinstance(res.value, BuiltinConcepts.SUCCESS)
|
assert context.sheerka.isinstance(res.value, BuiltinConcepts.SUCCESS)
|
||||||
|
|
||||||
|
|
||||||
|
def test_i_can_add_concept_with_a_body_to_a_set_of_concept():
|
||||||
|
context = get_context()
|
||||||
|
foo = Concept("foo", body="1")
|
||||||
|
context.sheerka.set_id_if_needed(foo, False)
|
||||||
|
context.sheerka.add_in_cache(foo)
|
||||||
|
|
||||||
|
bar = Concept("bar")
|
||||||
|
context.sheerka.set_id_if_needed(bar, False)
|
||||||
|
context.sheerka.add_in_cache(bar)
|
||||||
|
|
||||||
|
ret_val = get_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():
|
def test_i_cannot_add_the_same_concept_twice():
|
||||||
context = get_context()
|
context = get_context()
|
||||||
foo = Concept("foo")
|
foo = Concept("foo")
|
||||||
|
|||||||
@@ -7,13 +7,14 @@ from parsers.BaseParser import UnexpectedTokenErrorNode
|
|||||||
from parsers.BnfParser import BnfParser, UnexpectedEndOfFileError
|
from parsers.BnfParser import BnfParser, UnexpectedEndOfFileError
|
||||||
from parsers.ConceptLexerParser import StrMatch, Optional, ZeroOrMore, OrderedChoice, Sequence, OneOrMore, \
|
from parsers.ConceptLexerParser import StrMatch, Optional, ZeroOrMore, OrderedChoice, Sequence, OneOrMore, \
|
||||||
ConceptLexerParser, ConceptNode, ConceptMatch
|
ConceptLexerParser, ConceptNode, ConceptMatch
|
||||||
|
from sdp.sheerkaDataProvider import Event
|
||||||
|
|
||||||
|
|
||||||
def get_context():
|
def get_context():
|
||||||
sheerka = Sheerka(skip_builtins_in_db=True)
|
sheerka = Sheerka(skip_builtins_in_db=True)
|
||||||
sheerka.initialize("mem://")
|
sheerka.initialize("mem://")
|
||||||
|
|
||||||
return ExecutionContext("sheerka", "xxxx", sheerka)
|
return ExecutionContext("sheerka", Event(), sheerka)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("expression, expected", [
|
@pytest.mark.parametrize("expression, expected", [
|
||||||
|
|||||||
@@ -6,12 +6,13 @@ from core.sheerka import Sheerka, ExecutionContext
|
|||||||
from evaluators.ConceptEvaluator import ConceptEvaluator
|
from evaluators.ConceptEvaluator import ConceptEvaluator
|
||||||
from parsers.BaseParser import BaseParser
|
from parsers.BaseParser import BaseParser
|
||||||
from parsers.ExactConceptParser import ExactConceptParser
|
from parsers.ExactConceptParser import ExactConceptParser
|
||||||
|
from sdp.sheerkaDataProvider import Event
|
||||||
|
|
||||||
|
|
||||||
def get_context():
|
def get_context():
|
||||||
sheerka = Sheerka(skip_builtins_in_db=True)
|
sheerka = Sheerka(skip_builtins_in_db=True)
|
||||||
sheerka.initialize("mem://")
|
sheerka.initialize("mem://")
|
||||||
return ExecutionContext("test", "xxx", sheerka)
|
return ExecutionContext("test", Event(), sheerka)
|
||||||
|
|
||||||
|
|
||||||
def get_return_value(concept, source=None):
|
def get_return_value(concept, source=None):
|
||||||
@@ -55,7 +56,7 @@ def test_i_can_evaluate_concept():
|
|||||||
assert result.parents == [item]
|
assert result.parents == [item]
|
||||||
|
|
||||||
|
|
||||||
def test_body_is_returned_when_defined():
|
def test_body_is_returned_when_defined_and_requested():
|
||||||
context = get_context()
|
context = get_context()
|
||||||
concept = Concept(name="foo",
|
concept = Concept(name="foo",
|
||||||
body="'I have a value'",
|
body="'I have a value'",
|
||||||
@@ -63,7 +64,7 @@ def test_body_is_returned_when_defined():
|
|||||||
pre="2",
|
pre="2",
|
||||||
post="3").set_prop("a", "4").set_prop("b", "5")
|
post="3").set_prop("a", "4").set_prop("b", "5")
|
||||||
|
|
||||||
evaluator = ConceptEvaluator()
|
evaluator = ConceptEvaluator(return_body=True)
|
||||||
item = get_return_value(concept)
|
item = get_return_value(concept)
|
||||||
result = evaluator.eval(context, item)
|
result = evaluator.eval(context, item)
|
||||||
|
|
||||||
@@ -73,7 +74,25 @@ def test_body_is_returned_when_defined():
|
|||||||
assert result.parents == [item]
|
assert result.parents == [item]
|
||||||
|
|
||||||
|
|
||||||
def test_i_cannot_eval_if_with_the_same_name_is_defined_in_the_context():
|
def test_body_is_not_returned_if_not_requested():
|
||||||
|
context = get_context()
|
||||||
|
concept = Concept(name="foo",
|
||||||
|
body="'I have a value'",
|
||||||
|
where="1",
|
||||||
|
pre="2",
|
||||||
|
post="3").set_prop("a", "4").set_prop("b", "5")
|
||||||
|
|
||||||
|
evaluator = ConceptEvaluator(return_body=False) # which is the default behaviour
|
||||||
|
item = get_return_value(concept)
|
||||||
|
result = evaluator.eval(context, item)
|
||||||
|
|
||||||
|
assert result.who == evaluator.name
|
||||||
|
assert result.status
|
||||||
|
assert result.value == concept
|
||||||
|
assert result.parents == [item]
|
||||||
|
|
||||||
|
|
||||||
|
def test_i_can_eval_if_with_the_same_name_is_defined_in_the_context():
|
||||||
# If we evaluate Concept("foo", body="a").set_prop("a", "'property_a'")
|
# If we evaluate Concept("foo", body="a").set_prop("a", "'property_a'")
|
||||||
# ConceptEvaluator will be called to resolve 'a' while we know that 'a' refers to the string 'property_a'
|
# ConceptEvaluator will be called to resolve 'a' while we know that 'a' refers to the string 'property_a'
|
||||||
|
|
||||||
@@ -84,8 +103,8 @@ def test_i_cannot_eval_if_with_the_same_name_is_defined_in_the_context():
|
|||||||
item = get_return_value(concept)
|
item = get_return_value(concept)
|
||||||
result = ConceptEvaluator().eval(context, item)
|
result = ConceptEvaluator().eval(context, item)
|
||||||
|
|
||||||
assert not result.status
|
assert result.status
|
||||||
assert context.sheerka.isinstance(result.value, BuiltinConcepts.NOT_FOR_ME)
|
assert result.value == "'some_other_value'"
|
||||||
|
|
||||||
|
|
||||||
def test_i_cannot_recognize_a_concept_if_one_of_the_prop_is_unknown():
|
def test_i_cannot_recognize_a_concept_if_one_of_the_prop_is_unknown():
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from core.concept import Concept
|
|||||||
from core.sheerka import Sheerka, ExecutionContext
|
from core.sheerka import Sheerka, ExecutionContext
|
||||||
from parsers.ConceptLexerParser import ConceptLexerParser, ConceptNode, Sequence, StrMatch, OrderedChoice, Optional, \
|
from parsers.ConceptLexerParser import ConceptLexerParser, ConceptNode, Sequence, StrMatch, OrderedChoice, Optional, \
|
||||||
ParsingExpressionVisitor, TerminalNode, NonTerminalNode, LexerNode, ConceptMatch, ZeroOrMore, OneOrMore
|
ParsingExpressionVisitor, TerminalNode, NonTerminalNode, LexerNode, ConceptMatch, ZeroOrMore, OneOrMore
|
||||||
|
from sdp.sheerkaDataProvider import Event
|
||||||
|
|
||||||
|
|
||||||
class ConceptVisitor(ParsingExpressionVisitor):
|
class ConceptVisitor(ParsingExpressionVisitor):
|
||||||
@@ -849,4 +850,4 @@ def get_context():
|
|||||||
sheerka = Sheerka(skip_builtins_in_db=True)
|
sheerka = Sheerka(skip_builtins_in_db=True)
|
||||||
sheerka.initialize("mem://")
|
sheerka.initialize("mem://")
|
||||||
|
|
||||||
return ExecutionContext("sheerka", "xxxx", sheerka)
|
return ExecutionContext("sheerka", Event(), sheerka)
|
||||||
|
|||||||
@@ -4,14 +4,15 @@ from core.builtin_concepts import ReturnValueConcept, ParserResultConcept
|
|||||||
from core.concept import Concept
|
from core.concept import Concept
|
||||||
from core.sheerka import Sheerka, ExecutionContext
|
from core.sheerka import Sheerka, ExecutionContext
|
||||||
from evaluators.ConceptNodeEvaluator import ConceptNodeEvaluator
|
from evaluators.ConceptNodeEvaluator import ConceptNodeEvaluator
|
||||||
from parsers.ConceptLexerParser import ConceptNode, ConceptLexerParser, NonTerminalNode, Sequence, TerminalNode, \
|
from parsers.ConceptLexerParser import ConceptNode, ConceptLexerParser, Sequence, TerminalNode, \
|
||||||
StrMatch, Optional, OrderedChoice, ZeroOrMore
|
StrMatch, Optional, OrderedChoice, ZeroOrMore
|
||||||
|
from sdp.sheerkaDataProvider import Event
|
||||||
|
|
||||||
|
|
||||||
def get_context():
|
def get_context():
|
||||||
sheerka = Sheerka(skip_builtins_in_db=True)
|
sheerka = Sheerka(skip_builtins_in_db=True)
|
||||||
sheerka.initialize("mem://")
|
sheerka.initialize("mem://")
|
||||||
return ExecutionContext("test", "xxx", sheerka)
|
return ExecutionContext("test", Event(), sheerka)
|
||||||
|
|
||||||
|
|
||||||
def get_return_value(nodes, source):
|
def get_return_value(nodes, source):
|
||||||
|
|||||||
@@ -11,49 +11,8 @@ from parsers.DefaultParser import UnexpectedTokenErrorNode, DefConceptNode
|
|||||||
from parsers.BnfParser import BnfParser
|
from parsers.BnfParser import BnfParser
|
||||||
|
|
||||||
|
|
||||||
# def nop():
|
from sdp.sheerkaDataProvider import Event
|
||||||
# return NopNode()
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# def n(number):
|
|
||||||
# return NumberNode([], number)
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# def s(string, quote="'"):
|
|
||||||
# return StringNode([], string, quote)
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# def v(name):
|
|
||||||
# return VariableNode([], name)
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# def t():
|
|
||||||
# return TrueNode([])
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# def f():
|
|
||||||
# return FalseNode([])
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# def null():
|
|
||||||
# return NullNode([])
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# def b(operator, left, right):
|
|
||||||
# return BinaryNode([], operator, left, right)
|
|
||||||
|
|
||||||
#
|
|
||||||
# def compare_ast(left, right):
|
|
||||||
# left_as_string = ast.dump(left)
|
|
||||||
# left_as_string = left_as_string.replace(", ctx=Load()", "")
|
|
||||||
# left_as_string = left_as_string.replace(", kind=None", "")
|
|
||||||
#
|
|
||||||
# right_as_string = right if isinstance(right, str) else ast.dump(right)
|
|
||||||
# right_as_string = right_as_string.replace(", ctx=Load()", "")
|
|
||||||
# right_as_string = right_as_string.replace(", kind=None", "")
|
|
||||||
#
|
|
||||||
# return left_as_string == right_as_string
|
|
||||||
#
|
|
||||||
|
|
||||||
def get_def_concept(name, where=None, pre=None, post=None, body=None, definition=None):
|
def get_def_concept(name, where=None, pre=None, post=None, body=None, definition=None):
|
||||||
def_concept = DefConceptNode([], name=NameNode(list(Tokenizer(name))))
|
def_concept = DefConceptNode([], name=NameNode(list(Tokenizer(name))))
|
||||||
@@ -78,7 +37,7 @@ def get_def_concept(name, where=None, pre=None, post=None, body=None, definition
|
|||||||
def get_context():
|
def get_context():
|
||||||
sheerka = Sheerka(skip_builtins_in_db=True)
|
sheerka = Sheerka(skip_builtins_in_db=True)
|
||||||
sheerka.initialize("mem://")
|
sheerka.initialize("mem://")
|
||||||
return ExecutionContext("test", "xxx", sheerka)
|
return ExecutionContext("test", Event(), sheerka)
|
||||||
|
|
||||||
|
|
||||||
def get_concept_part(part):
|
def get_concept_part(part):
|
||||||
@@ -104,45 +63,6 @@ def get_concept_part(part):
|
|||||||
if isinstance(part, ReturnValueConcept):
|
if isinstance(part, ReturnValueConcept):
|
||||||
return part
|
return part
|
||||||
|
|
||||||
# @pytest.mark.parametrize("text, expected", [
|
|
||||||
# ("1", n(1)),
|
|
||||||
# ("+1", n(1)),
|
|
||||||
# ("-1", n(-1)),
|
|
||||||
# ("'foo'", s("foo")),
|
|
||||||
# ("identifier", v("identifier")),
|
|
||||||
# ("true", t()),
|
|
||||||
# ("false", f()),
|
|
||||||
# ("null", null()),
|
|
||||||
# ("1 * 2", b(TokenKind.STAR, n(1), n(2))),
|
|
||||||
# ("1 * 2/3", b(TokenKind.STAR, n(1), b(TokenKind.SLASH, n(2), n(3)))),
|
|
||||||
# ("1 + 2", b(TokenKind.PLUS, n(1), n(2))),
|
|
||||||
# ("1 + 2 - 3", b(TokenKind.PLUS, n(1), b(TokenKind.MINUS, n(2), n(3)))),
|
|
||||||
# ("1 + 2-3", b(TokenKind.PLUS, n(1), b(TokenKind.PLUS, n(2), n(-3)))),
|
|
||||||
# ("1 + 2 +-3", b(TokenKind.PLUS, n(1), b(TokenKind.PLUS, n(2), n(-3)))),
|
|
||||||
# ("1 + 2 * 3", b(TokenKind.PLUS, n(1), b(TokenKind.STAR, n(2), n(3)))),
|
|
||||||
# ("1 * 2 + 3", b(TokenKind.PLUS, b(TokenKind.STAR, n(1), n(2)), n(3))),
|
|
||||||
# ("(1 + 2) * 3", b(TokenKind.STAR, b(TokenKind.PLUS, n(1), n(2)), n(3))),
|
|
||||||
# ("1 * (2 + 3)", b(TokenKind.STAR, n(1), b(TokenKind.PLUS, n(2), n(3)))),
|
|
||||||
# ])
|
|
||||||
# def test_i_can_parse_simple_expression(text, expected):
|
|
||||||
# parser = DefaultParser(text, None)
|
|
||||||
# ast = parser.parse()
|
|
||||||
# assert ast.is_same(expected)
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# @pytest.mark.parametrize("text, token_found, expected_tokens", [
|
|
||||||
# ("1+", TokenKind.EOF,
|
|
||||||
# [TokenKind.NUMBER, TokenKind.STRING, TokenKind.IDENTIFIER, 'true', 'false', 'null', TokenKind.LPAR]),
|
|
||||||
# ("(1+1", TokenKind.EOF, [TokenKind.RPAR])
|
|
||||||
# ])
|
|
||||||
# def test_i_can_detect_unexpected_end_of_code(text, token_found, expected_tokens):
|
|
||||||
# parser = DefaultParser(text, None)
|
|
||||||
# parser.parse()
|
|
||||||
#
|
|
||||||
# assert parser.has_error
|
|
||||||
# assert parser.error_sink[0].tokens[0].type == token_found
|
|
||||||
# assert parser.error_sink[0].expected_tokens == expected_tokens
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("text, expected", [
|
@pytest.mark.parametrize("text, expected", [
|
||||||
("def concept hello", get_def_concept(name="hello")),
|
("def concept hello", get_def_concept(name="hello")),
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from core.builtin_concepts import ReturnValueConcept, BuiltinConcepts
|
||||||
|
from core.concept import Concept
|
||||||
|
from core.sheerka import Sheerka, ExecutionContext
|
||||||
|
from evaluators.EvalEvaluator import EvalEvaluator
|
||||||
|
from sdp.sheerkaDataProvider import Event
|
||||||
|
|
||||||
|
|
||||||
|
def get_context():
|
||||||
|
sheerka = Sheerka(skip_builtins_in_db=True)
|
||||||
|
sheerka.initialize("mem://")
|
||||||
|
return ExecutionContext("test", Event(), sheerka)
|
||||||
|
|
||||||
|
|
||||||
|
def r(value, status=True):
|
||||||
|
return ReturnValueConcept("some_name", status, value)
|
||||||
|
|
||||||
|
|
||||||
|
eval_requested = ReturnValueConcept("some_name", True, Concept(key=BuiltinConcepts.CONCEPT_EVAL_REQUESTED))
|
||||||
|
|
||||||
|
|
||||||
|
def test_i_can_match_and_eval():
|
||||||
|
context = get_context()
|
||||||
|
|
||||||
|
to_eval1 = ReturnValueConcept("some_name", True, Concept(name="2", body="to eval"))
|
||||||
|
to_eval2 = ReturnValueConcept("some_name", True, Concept(name="3", body="also to eval"))
|
||||||
|
|
||||||
|
return_values = [
|
||||||
|
ReturnValueConcept("some_name", True, "not to eval"),
|
||||||
|
ReturnValueConcept("some_name", True, Concept(name="not to eval")),
|
||||||
|
ReturnValueConcept("some_name", False, Concept(name="1", body="not to eval")),
|
||||||
|
to_eval1,
|
||||||
|
to_eval2,
|
||||||
|
eval_requested
|
||||||
|
]
|
||||||
|
|
||||||
|
evaluator = EvalEvaluator()
|
||||||
|
assert evaluator.matches(context, return_values)
|
||||||
|
|
||||||
|
evaluated = evaluator.eval(context, return_values)
|
||||||
|
assert len(evaluated) == 2
|
||||||
|
assert evaluated[0].value == to_eval1.body.body
|
||||||
|
assert evaluated[0].parents == [to_eval1, eval_requested]
|
||||||
|
|
||||||
|
assert evaluated[1].value == to_eval2.body.body
|
||||||
|
assert evaluated[1].parents == [to_eval2, eval_requested]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("return_values, expected", [
|
||||||
|
([r(Concept("foo", body="bar")), eval_requested], True),
|
||||||
|
([r(Concept("status is false", body="bar"), False), eval_requested], False),
|
||||||
|
([r("string_value"), eval_requested], False),
|
||||||
|
([r(Concept("no body")), eval_requested], False),
|
||||||
|
([r(Concept("eval requested missing", body="bar"))], False),
|
||||||
|
])
|
||||||
|
def test_i_cannot_match_if_eval_request_is_not_present(return_values, expected):
|
||||||
|
context = get_context()
|
||||||
|
assert EvalEvaluator().matches(context, return_values) == expected
|
||||||
@@ -3,6 +3,7 @@ from core.concept import Concept, Property
|
|||||||
from core.sheerka import Sheerka, ExecutionContext
|
from core.sheerka import Sheerka, ExecutionContext
|
||||||
from core.tokenizer import Tokenizer
|
from core.tokenizer import Tokenizer
|
||||||
from parsers.ExactConceptParser import ExactConceptParser
|
from parsers.ExactConceptParser import ExactConceptParser
|
||||||
|
from sdp.sheerkaDataProvider import Event
|
||||||
|
|
||||||
|
|
||||||
def test_i_can_compute_combinations():
|
def test_i_can_compute_combinations():
|
||||||
@@ -130,7 +131,7 @@ def get_context():
|
|||||||
sheerka = Sheerka(skip_builtins_in_db=True)
|
sheerka = Sheerka(skip_builtins_in_db=True)
|
||||||
sheerka.initialize("mem://")
|
sheerka.initialize("mem://")
|
||||||
|
|
||||||
return ExecutionContext("sheerka", "xxxx", sheerka)
|
return ExecutionContext("sheerka", Event(), sheerka)
|
||||||
|
|
||||||
|
|
||||||
def get_concept(name, variables):
|
def get_concept(name, variables):
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
from core.builtin_concepts import BuiltinConcepts
|
from core.builtin_concepts import BuiltinConcepts
|
||||||
from core.concept import Concept
|
from core.concept import Concept
|
||||||
from core.sheerka import ExecutionContext
|
from core.sheerka import ExecutionContext
|
||||||
|
from sdp.sheerkaDataProvider import Event
|
||||||
|
|
||||||
|
|
||||||
def test_id_is_incremented_by_event_digest():
|
def test_id_is_incremented_by_event_digest():
|
||||||
a = ExecutionContext("foo", "event_1", None)
|
a = ExecutionContext("foo", Event("event_1"), None)
|
||||||
b = ExecutionContext("foo", "event_1", None)
|
b = ExecutionContext("foo", Event("event_1"), None)
|
||||||
c = ExecutionContext("foo", "event_2", None)
|
c = ExecutionContext("foo", Event("event_2"), None)
|
||||||
d = b.push()
|
d = b.push()
|
||||||
e = c.push()
|
e = c.push()
|
||||||
|
|
||||||
@@ -18,17 +19,19 @@ def test_id_is_incremented_by_event_digest():
|
|||||||
|
|
||||||
|
|
||||||
def test_some_properties_are_given_to_the_child():
|
def test_some_properties_are_given_to_the_child():
|
||||||
a = ExecutionContext("foo", "event_1", "fake_sheerka",
|
a = ExecutionContext("foo", Event("event_1"), "fake_sheerka",
|
||||||
desc="some description",
|
desc="some description",
|
||||||
obj=Concept("foo"),
|
obj=Concept("foo"),
|
||||||
step=BuiltinConcepts.EVALUATION,
|
step=BuiltinConcepts.EVALUATION,
|
||||||
iteration=15,
|
iteration=15,
|
||||||
concepts={"bar": Concept("bar")})
|
concepts={"bar": Concept("bar")})
|
||||||
|
a.preprocess = set()
|
||||||
|
a.preprocess.add("preprocess")
|
||||||
|
|
||||||
b = a.push()
|
b = a.push()
|
||||||
|
|
||||||
assert b.who == a.who
|
assert b.who == a.who
|
||||||
assert b.event_digest == a.event_digest
|
assert b.event == a.event
|
||||||
assert b.sheerka == a.sheerka
|
assert b.sheerka == a.sheerka
|
||||||
assert b.desc == ""
|
assert b.desc == ""
|
||||||
assert b.obj == a.obj
|
assert b.obj == a.obj
|
||||||
@@ -37,3 +40,4 @@ def test_some_properties_are_given_to_the_child():
|
|||||||
assert b.concepts == a.concepts
|
assert b.concepts == a.concepts
|
||||||
assert b.id == a.id + 1
|
assert b.id == a.id + 1
|
||||||
assert b._tab == a._tab + " "
|
assert b._tab == a._tab + " "
|
||||||
|
assert b.preprocess == a.preprocess
|
||||||
|
|||||||
@@ -4,12 +4,13 @@ from core.sheerka import Sheerka, ExecutionContext
|
|||||||
from evaluators.BaseEvaluator import BaseEvaluator
|
from evaluators.BaseEvaluator import BaseEvaluator
|
||||||
from evaluators.MutipleSameSuccessEvaluator import MultipleSameSuccessEvaluator
|
from evaluators.MutipleSameSuccessEvaluator import MultipleSameSuccessEvaluator
|
||||||
from parsers.BaseParser import BaseParser
|
from parsers.BaseParser import BaseParser
|
||||||
|
from sdp.sheerkaDataProvider import Event
|
||||||
|
|
||||||
|
|
||||||
def get_context():
|
def get_context():
|
||||||
sheerka = Sheerka(skip_builtins_in_db=True)
|
sheerka = Sheerka(skip_builtins_in_db=True)
|
||||||
sheerka.initialize("mem://")
|
sheerka.initialize("mem://")
|
||||||
return ExecutionContext("test", "xxx", sheerka)
|
return ExecutionContext("test", Event(), sheerka)
|
||||||
|
|
||||||
|
|
||||||
def test_i_can_match_and_eval():
|
def test_i_can_match_and_eval():
|
||||||
@@ -21,7 +22,7 @@ def test_i_can_match_and_eval():
|
|||||||
ReturnValueConcept(BaseParser.PREFIX + "some_name2", False, "Not relevant"),
|
ReturnValueConcept(BaseParser.PREFIX + "some_name2", False, "Not relevant"),
|
||||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1", body="value")),
|
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1", body="value")),
|
||||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="2", body="value")),
|
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="2", body="value")),
|
||||||
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.AFTER_EVALUATION))
|
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.REDUCE_REQUESTED))
|
||||||
]
|
]
|
||||||
|
|
||||||
evaluator = MultipleSameSuccessEvaluator()
|
evaluator = MultipleSameSuccessEvaluator()
|
||||||
@@ -29,7 +30,7 @@ def test_i_can_match_and_eval():
|
|||||||
|
|
||||||
evaluated = evaluator.eval(context, return_values)
|
evaluated = evaluator.eval(context, return_values)
|
||||||
assert evaluated.status
|
assert evaluated.status
|
||||||
assert evaluated.value == "value"
|
assert evaluated.value == Concept(name="1", body="value") # the first concept is returned
|
||||||
|
|
||||||
|
|
||||||
def test_i_can_match_and_eval_when_no_body():
|
def test_i_can_match_and_eval_when_no_body():
|
||||||
@@ -41,7 +42,7 @@ def test_i_can_match_and_eval_when_no_body():
|
|||||||
ReturnValueConcept(BaseParser.PREFIX + "some_name2", False, "Not relevant"),
|
ReturnValueConcept(BaseParser.PREFIX + "some_name2", False, "Not relevant"),
|
||||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1")),
|
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1")),
|
||||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1")),
|
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1")),
|
||||||
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.AFTER_EVALUATION))
|
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.REDUCE_REQUESTED))
|
||||||
]
|
]
|
||||||
|
|
||||||
evaluator = MultipleSameSuccessEvaluator()
|
evaluator = MultipleSameSuccessEvaluator()
|
||||||
@@ -61,7 +62,7 @@ def test_i_can_match_and_eval_when_value_is_not_a_concept():
|
|||||||
ReturnValueConcept(BaseParser.PREFIX + "some_name2", False, "Not relevant"),
|
ReturnValueConcept(BaseParser.PREFIX + "some_name2", False, "Not relevant"),
|
||||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, "value"),
|
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, "value"),
|
||||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, "value"),
|
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, "value"),
|
||||||
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.AFTER_EVALUATION))
|
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.REDUCE_REQUESTED))
|
||||||
]
|
]
|
||||||
|
|
||||||
evaluator = MultipleSameSuccessEvaluator()
|
evaluator = MultipleSameSuccessEvaluator()
|
||||||
@@ -72,6 +73,54 @@ def test_i_can_match_and_eval_when_value_is_not_a_concept():
|
|||||||
assert evaluated.value == "value"
|
assert evaluated.value == "value"
|
||||||
|
|
||||||
|
|
||||||
|
def test_i_can_match_and_eval_when_at_least_one_value_is_a_concept_concept_evaluator_first():
|
||||||
|
context = get_context()
|
||||||
|
sheerka = context.sheerka
|
||||||
|
|
||||||
|
return_values = [
|
||||||
|
ReturnValueConcept(BaseParser.PREFIX + "some_name", False, "Not relevant"),
|
||||||
|
ReturnValueConcept(BaseParser.PREFIX + "some_name2", False, "Not relevant"),
|
||||||
|
ReturnValueConcept(BaseEvaluator.PREFIX + "Python", True, "value"),
|
||||||
|
ReturnValueConcept(BaseEvaluator.PREFIX + "other", True, "value"),
|
||||||
|
ReturnValueConcept(BaseEvaluator.PREFIX + "Python", True, Concept(name="2", body="value")),
|
||||||
|
ReturnValueConcept(BaseEvaluator.PREFIX + "Concept", True, Concept(name="1", body="value")),
|
||||||
|
ReturnValueConcept(BaseEvaluator.PREFIX + "Python", True, Concept(name="3", body="value")),
|
||||||
|
ReturnValueConcept(BaseEvaluator.PREFIX + "other", True, "value"),
|
||||||
|
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.REDUCE_REQUESTED))
|
||||||
|
]
|
||||||
|
|
||||||
|
evaluator = MultipleSameSuccessEvaluator()
|
||||||
|
assert evaluator.matches(context, return_values)
|
||||||
|
|
||||||
|
evaluated = evaluator.eval(context, return_values)
|
||||||
|
assert evaluated.status
|
||||||
|
assert evaluated.value == Concept(name="1", body="value") # the concept is returned, not the value
|
||||||
|
|
||||||
|
|
||||||
|
def test_i_can_match_and_eval_when_at_least_one_value_is_a_concept_python_evaluator_first():
|
||||||
|
context = get_context()
|
||||||
|
sheerka = context.sheerka
|
||||||
|
|
||||||
|
return_values = [
|
||||||
|
ReturnValueConcept(BaseParser.PREFIX + "some_name", False, "Not relevant"),
|
||||||
|
ReturnValueConcept(BaseParser.PREFIX + "some_name2", False, "Not relevant"),
|
||||||
|
ReturnValueConcept(BaseEvaluator.PREFIX + "Python", True, "value"),
|
||||||
|
ReturnValueConcept(BaseEvaluator.PREFIX + "other", True, "value"),
|
||||||
|
ReturnValueConcept(BaseEvaluator.PREFIX + "other", True, Concept(name="2", body="value")),
|
||||||
|
ReturnValueConcept(BaseEvaluator.PREFIX + "Python", True, Concept(name="1", body="value")),
|
||||||
|
ReturnValueConcept(BaseEvaluator.PREFIX + "other", True, Concept(name="3", body="value")),
|
||||||
|
ReturnValueConcept(BaseEvaluator.PREFIX + "other", True, "value"),
|
||||||
|
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.REDUCE_REQUESTED))
|
||||||
|
]
|
||||||
|
|
||||||
|
evaluator = MultipleSameSuccessEvaluator()
|
||||||
|
assert evaluator.matches(context, return_values)
|
||||||
|
|
||||||
|
evaluated = evaluator.eval(context, return_values)
|
||||||
|
assert evaluated.status
|
||||||
|
assert evaluated.value == Concept(name="1", body="value") # the concept is returned, not the value
|
||||||
|
|
||||||
|
|
||||||
def test_i_can_match_even_if_the_value_are_not_the_same_but_eval_will_fail():
|
def test_i_can_match_even_if_the_value_are_not_the_same_but_eval_will_fail():
|
||||||
context = get_context()
|
context = get_context()
|
||||||
sheerka = context.sheerka
|
sheerka = context.sheerka
|
||||||
@@ -81,7 +130,7 @@ def test_i_can_match_even_if_the_value_are_not_the_same_but_eval_will_fail():
|
|||||||
ReturnValueConcept(BaseParser.PREFIX + "some_name2", False, "Not relevant"),
|
ReturnValueConcept(BaseParser.PREFIX + "some_name2", False, "Not relevant"),
|
||||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1", body="value")),
|
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1", body="value")),
|
||||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="2", body="value2")),
|
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="2", body="value2")),
|
||||||
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.AFTER_EVALUATION))
|
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.REDUCE_REQUESTED))
|
||||||
]
|
]
|
||||||
|
|
||||||
evaluator = MultipleSameSuccessEvaluator()
|
evaluator = MultipleSameSuccessEvaluator()
|
||||||
@@ -98,7 +147,7 @@ def test_i_can_match_even_if_the_value_are_not_the_same_but_eval_will_fail_when_
|
|||||||
ReturnValueConcept(BaseParser.PREFIX + "some_name2", False, "Not relevant"),
|
ReturnValueConcept(BaseParser.PREFIX + "some_name2", False, "Not relevant"),
|
||||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1")),
|
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1")),
|
||||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="2")),
|
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="2")),
|
||||||
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.AFTER_EVALUATION))
|
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.REDUCE_REQUESTED))
|
||||||
]
|
]
|
||||||
|
|
||||||
evaluator = MultipleSameSuccessEvaluator()
|
evaluator = MultipleSameSuccessEvaluator()
|
||||||
@@ -113,13 +162,13 @@ def test_i_can_match_if_no_parser():
|
|||||||
return_values = [
|
return_values = [
|
||||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1", body="value")),
|
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1", body="value")),
|
||||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="2", body="value")),
|
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="2", body="value")),
|
||||||
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.AFTER_EVALUATION))
|
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.REDUCE_REQUESTED))
|
||||||
]
|
]
|
||||||
|
|
||||||
assert MultipleSameSuccessEvaluator().matches(context, return_values)
|
assert MultipleSameSuccessEvaluator().matches(context, return_values)
|
||||||
|
|
||||||
|
|
||||||
def test_i_cannot_match_if_not_after_evaluation():
|
def test_i_cannot_match_if_not_reduced_requested():
|
||||||
context = get_context()
|
context = get_context()
|
||||||
sheerka = context.sheerka
|
sheerka = context.sheerka
|
||||||
|
|
||||||
@@ -129,7 +178,7 @@ def test_i_cannot_match_if_not_after_evaluation():
|
|||||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1", body="value")),
|
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1", body="value")),
|
||||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="2", body="value")),
|
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="2", body="value")),
|
||||||
ReturnValueConcept("some_name", True, Concept(name="2", body="value")),
|
ReturnValueConcept("some_name", True, Concept(name="2", body="value")),
|
||||||
# ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.AFTER_EVALUATION))
|
# ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.REDUCE_REQUESTED))
|
||||||
]
|
]
|
||||||
|
|
||||||
assert not MultipleSameSuccessEvaluator().matches(context, return_values)
|
assert not MultipleSameSuccessEvaluator().matches(context, return_values)
|
||||||
@@ -145,7 +194,7 @@ def test_i_cannot_match_if_only_one_successful_evaluator():
|
|||||||
# ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1", body="value")),
|
# ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1", body="value")),
|
||||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="2", body="value")),
|
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="2", body="value")),
|
||||||
ReturnValueConcept("some_name", True, Concept(name="2", body="value")),
|
ReturnValueConcept("some_name", True, Concept(name="2", body="value")),
|
||||||
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.AFTER_EVALUATION))
|
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.REDUCE_REQUESTED))
|
||||||
]
|
]
|
||||||
|
|
||||||
assert not MultipleSameSuccessEvaluator().matches(context, return_values)
|
assert not MultipleSameSuccessEvaluator().matches(context, return_values)
|
||||||
@@ -160,41 +209,8 @@ def test_i_cannot_match_if_at_least_one_parser_is_successful():
|
|||||||
ReturnValueConcept(BaseParser.PREFIX + "some_name2", True, "Not relevant"),
|
ReturnValueConcept(BaseParser.PREFIX + "some_name2", True, "Not relevant"),
|
||||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1", body="value")),
|
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1", body="value")),
|
||||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="2", body="value")),
|
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="2", body="value")),
|
||||||
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.AFTER_EVALUATION))
|
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.REDUCE_REQUESTED))
|
||||||
]
|
]
|
||||||
|
|
||||||
assert not MultipleSameSuccessEvaluator().matches(context, return_values)
|
assert not MultipleSameSuccessEvaluator().matches(context, return_values)
|
||||||
|
|
||||||
|
|
||||||
def test_i_cannot_match_if_i_have_unlisted_return_value_in_success():
|
|
||||||
context = get_context()
|
|
||||||
sheerka = context.sheerka
|
|
||||||
|
|
||||||
return_values = [
|
|
||||||
ReturnValueConcept(BaseParser.PREFIX + "some_name", False, "Not relevant"),
|
|
||||||
ReturnValueConcept(BaseParser.PREFIX + "some_name2", False, "Not relevant"),
|
|
||||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1", body="value")),
|
|
||||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="2", body="value")),
|
|
||||||
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.AFTER_EVALUATION)),
|
|
||||||
ReturnValueConcept("some_name", True, "not relevant"),
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
assert not MultipleSameSuccessEvaluator().matches(context, return_values)
|
|
||||||
|
|
||||||
|
|
||||||
def test_i_cannot_match_if_i_have_unlisted_return_value_in_error():
|
|
||||||
context = get_context()
|
|
||||||
sheerka = context.sheerka
|
|
||||||
|
|
||||||
return_values = [
|
|
||||||
ReturnValueConcept(BaseParser.PREFIX + "some_name", False, "Not relevant"),
|
|
||||||
ReturnValueConcept(BaseParser.PREFIX + "some_name2", False, "Not relevant"),
|
|
||||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1", body="value")),
|
|
||||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="2", body="value")),
|
|
||||||
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.AFTER_EVALUATION)),
|
|
||||||
ReturnValueConcept("some_name", False, "not relevant"),
|
|
||||||
|
|
||||||
]
|
|
||||||
|
|
||||||
assert not MultipleSameSuccessEvaluator().matches(context, return_values)
|
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from core.builtin_concepts import ReturnValueConcept, BuiltinConcepts
|
||||||
|
from core.concept import Concept
|
||||||
|
from core.sheerka import Sheerka, ExecutionContext
|
||||||
|
from evaluators.OneErrorEvaluator import OneErrorEvaluator
|
||||||
|
from sdp.sheerkaDataProvider import Event
|
||||||
|
|
||||||
|
|
||||||
|
def get_context():
|
||||||
|
sheerka = Sheerka(skip_builtins_in_db=True)
|
||||||
|
sheerka.initialize("mem://")
|
||||||
|
return ExecutionContext("test", Event(), sheerka)
|
||||||
|
|
||||||
|
|
||||||
|
def r(value, status=True):
|
||||||
|
return ReturnValueConcept(value, status, value)
|
||||||
|
|
||||||
|
|
||||||
|
reduce_requested = ReturnValueConcept("some_name", True, Concept(key=BuiltinConcepts.REDUCE_REQUESTED))
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("return_values, expected", [
|
||||||
|
([r("evaluators.one error", False), reduce_requested], True),
|
||||||
|
([r("evaluators.one error", False), r("failed", False), r("failed", False), reduce_requested], True),
|
||||||
|
([r("evaluators.error", False), r("not a parser in success"), reduce_requested], True),
|
||||||
|
([r("evaluators.no reduce required", False), r("failed", False), r("failed", False)], False),
|
||||||
|
([r("evaluators.no reduce required", False)], False),
|
||||||
|
([r("evaluators.error", False), r("evaluators.success"), reduce_requested], False),
|
||||||
|
([r("evaluators.error", False), r("parsers.success"), reduce_requested], False),
|
||||||
|
([r("evaluators.success"), r("not an evaluator in error", False), reduce_requested], False),
|
||||||
|
([r("evaluators.error", False), r("evaluators.another error", False), reduce_requested], False),
|
||||||
|
])
|
||||||
|
def test_i_can_match(return_values, expected):
|
||||||
|
context = get_context()
|
||||||
|
assert OneErrorEvaluator().matches(context, return_values) == expected
|
||||||
|
|
||||||
|
|
||||||
|
def test_i_can_eval():
|
||||||
|
context = get_context()
|
||||||
|
|
||||||
|
return_values = [
|
||||||
|
r("evaluators.one error", False),
|
||||||
|
r("parsers.failed", False),
|
||||||
|
r("parsers.failed", False),
|
||||||
|
reduce_requested
|
||||||
|
]
|
||||||
|
|
||||||
|
evaluator = OneErrorEvaluator()
|
||||||
|
evaluator.matches(context, return_values)
|
||||||
|
res = evaluator.eval(context, return_values)
|
||||||
|
|
||||||
|
assert not res.status
|
||||||
|
assert res.body == "evaluators.one error"
|
||||||
|
assert len(res.parents) == 4
|
||||||
|
|
||||||
|
|
||||||
|
def test_unwanted_return_values_are_not_eaten():
|
||||||
|
context = get_context()
|
||||||
|
|
||||||
|
a_successful_concept = r("successful concept")
|
||||||
|
a_concept_in_error = r("concept in error", False)
|
||||||
|
return_values = [
|
||||||
|
r("evaluators.one error", False),
|
||||||
|
r("parsers.failed", False),
|
||||||
|
r("parsers.failed", False),
|
||||||
|
a_successful_concept,
|
||||||
|
a_concept_in_error,
|
||||||
|
reduce_requested
|
||||||
|
]
|
||||||
|
|
||||||
|
evaluator = OneErrorEvaluator()
|
||||||
|
evaluator.matches(context, return_values)
|
||||||
|
res = evaluator.eval(context, return_values)
|
||||||
|
|
||||||
|
assert not res.status
|
||||||
|
assert res.body == "evaluators.one error"
|
||||||
|
assert len(res.parents) == 4
|
||||||
|
|
||||||
|
assert a_successful_concept not in res.parents
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from core.builtin_concepts import ReturnValueConcept, BuiltinConcepts
|
||||||
|
from core.concept import Concept
|
||||||
|
from core.sheerka import Sheerka, ExecutionContext
|
||||||
|
from evaluators.OneSuccessEvaluator import OneSuccessEvaluator
|
||||||
|
from sdp.sheerkaDataProvider import Event
|
||||||
|
|
||||||
|
|
||||||
|
def get_context():
|
||||||
|
sheerka = Sheerka(skip_builtins_in_db=True)
|
||||||
|
sheerka.initialize("mem://")
|
||||||
|
return ExecutionContext("test", Event(), sheerka)
|
||||||
|
|
||||||
|
|
||||||
|
def r(value, status=True):
|
||||||
|
return ReturnValueConcept(value, status, value)
|
||||||
|
|
||||||
|
|
||||||
|
reduce_requested = ReturnValueConcept("some_name", True, Concept(key=BuiltinConcepts.REDUCE_REQUESTED))
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("return_values, expected", [
|
||||||
|
([r("evaluators.one success"), reduce_requested], True),
|
||||||
|
([r("evaluators.one success"), r("failed", False), r("failed", False), reduce_requested], True),
|
||||||
|
([r("evaluators.no reduce required"), r("failed", False), r("failed", False)], False),
|
||||||
|
([r("evaluators.no reduce required")], False),
|
||||||
|
([r("evaluators.failed", False), r("failed", False), r("failed", False), reduce_requested], False),
|
||||||
|
([r("evaluators.failed", False), r("not evaluator success"), reduce_requested], False),
|
||||||
|
([r("evaluators.success"), r("evaluators.another success"), reduce_requested], False),
|
||||||
|
([r("evaluators.one success"), r("other success"), r("failed", False), reduce_requested], True),
|
||||||
|
([r("evaluators.one success"), r("parsers.success"), reduce_requested], False),
|
||||||
|
])
|
||||||
|
def test_i_can_match(return_values, expected):
|
||||||
|
context = get_context()
|
||||||
|
assert OneSuccessEvaluator().matches(context, return_values) == expected
|
||||||
|
|
||||||
|
|
||||||
|
def test_i_can_eval():
|
||||||
|
context = get_context()
|
||||||
|
|
||||||
|
return_values = [
|
||||||
|
r("evaluators.one success"),
|
||||||
|
r("failed", False),
|
||||||
|
r("failed", False),
|
||||||
|
reduce_requested
|
||||||
|
]
|
||||||
|
|
||||||
|
evaluator = OneSuccessEvaluator()
|
||||||
|
matches = evaluator.matches(context, return_values)
|
||||||
|
res = evaluator.eval(context, return_values)
|
||||||
|
|
||||||
|
assert matches
|
||||||
|
assert res.status
|
||||||
|
assert res.body == "evaluators.one success"
|
||||||
|
assert len(res.parents) == 4
|
||||||
|
|
||||||
|
|
||||||
|
def test_i_do_not_eat_the_other_success():
|
||||||
|
context = get_context()
|
||||||
|
|
||||||
|
not_a_parser_success = r("other success")
|
||||||
|
return_values = [
|
||||||
|
r("evaluators.one success"),
|
||||||
|
not_a_parser_success,
|
||||||
|
r("failed", False),
|
||||||
|
reduce_requested
|
||||||
|
]
|
||||||
|
|
||||||
|
evaluator = OneSuccessEvaluator()
|
||||||
|
matches = evaluator.matches(context, return_values)
|
||||||
|
res = evaluator.eval(context, return_values)
|
||||||
|
|
||||||
|
assert matches
|
||||||
|
assert res.status
|
||||||
|
assert res.body == "evaluators.one success"
|
||||||
|
assert len(res.parents) == 3
|
||||||
|
|
||||||
|
assert not_a_parser_success not in res.parents
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from core.builtin_concepts import BuiltinConcepts, ReturnValueConcept
|
||||||
|
from core.concept import Concept
|
||||||
|
from core.sheerka import Sheerka, ExecutionContext
|
||||||
|
from evaluators.PrepareEvalEvaluator import PrepareEvalEvaluator
|
||||||
|
from sdp.sheerkaDataProvider import Event
|
||||||
|
|
||||||
|
|
||||||
|
def get_context():
|
||||||
|
sheerka = Sheerka(skip_builtins_in_db=True)
|
||||||
|
sheerka.initialize("mem://")
|
||||||
|
return ExecutionContext("test", Event(), sheerka)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("ret_val, expected", [
|
||||||
|
(ReturnValueConcept("some_name", True, Concept(key=BuiltinConcepts.USER_INPUT, body="eval 1 + 1")), True),
|
||||||
|
(ReturnValueConcept("some_name", True, Concept(key=BuiltinConcepts.USER_INPUT, body=" eval 1 + 1")), True),
|
||||||
|
(ReturnValueConcept("some_name", True, Concept(key=BuiltinConcepts.USER_INPUT, body="eval")), False),
|
||||||
|
(ReturnValueConcept("some_name", True, Concept(key=BuiltinConcepts.USER_INPUT, body="1+1")), False),
|
||||||
|
(ReturnValueConcept("some_name", True, Concept(key=BuiltinConcepts.USER_INPUT, body="")), False),
|
||||||
|
(ReturnValueConcept("some_name", True, Concept(key=BuiltinConcepts.USER_INPUT, body="eval ")), False),
|
||||||
|
(ReturnValueConcept("some_name", True, Concept(key=BuiltinConcepts.USER_INPUT, body=[])), False),
|
||||||
|
(ReturnValueConcept("some_name", True, Concept("foo")), False),
|
||||||
|
(ReturnValueConcept("some_name", True, "not a concept"), False),
|
||||||
|
(ReturnValueConcept("some_name", False, Concept(key=BuiltinConcepts.USER_INPUT, body="eval 1 + 1")), False),
|
||||||
|
(ReturnValueConcept("some_name", False, Concept(key=BuiltinConcepts.USER_INPUT, body=" eval 1 + 1")), False),
|
||||||
|
])
|
||||||
|
def test_i_can_match(ret_val, expected):
|
||||||
|
context = get_context()
|
||||||
|
assert PrepareEvalEvaluator().matches(context, ret_val) == expected
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("ret_val, expected", [
|
||||||
|
(ReturnValueConcept("some_name", True, Concept(key=BuiltinConcepts.USER_INPUT, body="eval 1 + 1")), "1 + 1"),
|
||||||
|
(ReturnValueConcept("some_name", True, Concept(key=BuiltinConcepts.USER_INPUT, body=" eval 1 + 1")), "1 + 1"),
|
||||||
|
])
|
||||||
|
def test_i_can_eval(ret_val, expected):
|
||||||
|
context = get_context()
|
||||||
|
sheerka = context.sheerka
|
||||||
|
|
||||||
|
prepare_evaluator = PrepareEvalEvaluator()
|
||||||
|
prepare_evaluator.matches(context, ret_val)
|
||||||
|
res = prepare_evaluator.eval(context, ret_val)
|
||||||
|
|
||||||
|
assert len(res) == 2
|
||||||
|
assert res[0].status
|
||||||
|
assert sheerka.isinstance(res[0].body, BuiltinConcepts.USER_INPUT)
|
||||||
|
assert res[0].body.body == expected
|
||||||
|
|
||||||
|
assert res[1].status
|
||||||
|
assert sheerka.isinstance(res[1].body, BuiltinConcepts.CONCEPT_EVAL_REQUESTED)
|
||||||
@@ -5,12 +5,13 @@ from core.sheerka import Sheerka, ExecutionContext
|
|||||||
from core.concept import Concept
|
from core.concept import Concept
|
||||||
from evaluators.PythonEvaluator import PythonEvaluator
|
from evaluators.PythonEvaluator import PythonEvaluator
|
||||||
from parsers.PythonParser import PythonNode, PythonParser
|
from parsers.PythonParser import PythonNode, PythonParser
|
||||||
|
from sdp.sheerkaDataProvider import Event
|
||||||
|
|
||||||
|
|
||||||
def get_context():
|
def get_context():
|
||||||
sheerka = Sheerka(skip_builtins_in_db=True)
|
sheerka = Sheerka(skip_builtins_in_db=True)
|
||||||
sheerka.initialize("mem://")
|
sheerka.initialize("mem://")
|
||||||
return ExecutionContext("test", "xxx", sheerka)
|
return ExecutionContext("test", Event(), sheerka)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("ret_val, expected", [
|
@pytest.mark.parametrize("ret_val, expected", [
|
||||||
@@ -39,30 +40,62 @@ def test_i_can_eval(text, expected):
|
|||||||
assert evaluated.value == expected
|
assert evaluated.value == expected
|
||||||
|
|
||||||
|
|
||||||
def test_i_can_eval_expression_that_references_concepts():
|
@pytest.mark.parametrize("concept", [
|
||||||
|
Concept("foo"),
|
||||||
|
Concept("foo", body="2"),
|
||||||
|
Concept("foo").set_prop("prop", "'a'"),
|
||||||
|
Concept("foo", body="bar")
|
||||||
|
])
|
||||||
|
def test_i_cannot_eval_simple_concept(concept):
|
||||||
context = get_context()
|
context = get_context()
|
||||||
context.sheerka.add_in_cache(Concept("foo"))
|
context.sheerka.add_in_cache(Concept("foo"))
|
||||||
|
|
||||||
parsed = PythonParser().parse(context, "foo")
|
parsed = PythonParser().parse(context, "foo")
|
||||||
evaluated = PythonEvaluator().eval(context, parsed)
|
evaluated = PythonEvaluator().eval(context, parsed)
|
||||||
|
|
||||||
assert evaluated.status
|
assert not evaluated.status
|
||||||
assert evaluated.value == Concept("foo").init_key()
|
assert context.sheerka.isinstance(evaluated.value, BuiltinConcepts.NOT_FOR_ME)
|
||||||
|
|
||||||
|
|
||||||
def test_i_can_eval_expression_that_references_concepts_with_body():
|
#
|
||||||
|
# def test_i_can_eval_expression_that_references_concepts():
|
||||||
|
# context = get_context()
|
||||||
|
# context.sheerka.add_in_cache(Concept("foo"))
|
||||||
|
#
|
||||||
|
# parsed = PythonParser().parse(context, "foo")
|
||||||
|
# evaluated = PythonEvaluator().eval(context, parsed)
|
||||||
|
#
|
||||||
|
# assert evaluated.status
|
||||||
|
# assert evaluated.value == Concept("foo").init_key()
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# def test_i_can_eval_expression_that_references_concepts_with_body():
|
||||||
|
# """
|
||||||
|
# I can test expression with variables
|
||||||
|
# :return:
|
||||||
|
# """
|
||||||
|
# context = get_context()
|
||||||
|
# context.sheerka.add_in_cache(Concept("foo", body="2"))
|
||||||
|
#
|
||||||
|
# parsed = PythonParser().parse(context, "foo")
|
||||||
|
# evaluated = PythonEvaluator().eval(context, parsed)
|
||||||
|
#
|
||||||
|
# assert evaluated.status
|
||||||
|
# assert evaluated.value == 2
|
||||||
|
|
||||||
|
def test_i_can_eval_expression_with_that_references_concepts():
|
||||||
"""
|
"""
|
||||||
I can test expression with variables
|
I can test modules with variables
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
context = get_context()
|
context = get_context()
|
||||||
context.sheerka.add_in_cache(Concept("foo", body="2"))
|
context.sheerka.add_in_cache(Concept("foo", body=1))
|
||||||
|
|
||||||
parsed = PythonParser().parse(context, "foo")
|
parsed = PythonParser().parse(context, "foo + 2")
|
||||||
evaluated = PythonEvaluator().eval(context, parsed)
|
evaluated = PythonEvaluator().eval(context, parsed)
|
||||||
|
|
||||||
assert evaluated.status
|
assert evaluated.status
|
||||||
assert evaluated.value == 2
|
assert evaluated.value == 3
|
||||||
|
|
||||||
|
|
||||||
def test_i_can_eval_module_with_that_references_concepts():
|
def test_i_can_eval_module_with_that_references_concepts():
|
||||||
@@ -94,24 +127,24 @@ def test_i_can_eval_module_with_that_references_concepts_with_body():
|
|||||||
assert evaluated.status
|
assert evaluated.status
|
||||||
assert evaluated.value == 2
|
assert evaluated.value == 2
|
||||||
|
|
||||||
|
#
|
||||||
def test_i_can_eval_concept_with_props():
|
# def test_i_can_eval_concept_with_props():
|
||||||
context = get_context()
|
# context = get_context()
|
||||||
context.sheerka.add_in_cache(Concept("foo").set_prop("prop", "'a'"))
|
# context.sheerka.add_in_cache(Concept("foo").set_prop("prop", "'a'"))
|
||||||
|
#
|
||||||
parsed = PythonParser().parse(context, "foo")
|
# parsed = PythonParser().parse(context, "foo")
|
||||||
evaluated = PythonEvaluator().eval(context, parsed)
|
# evaluated = PythonEvaluator().eval(context, parsed)
|
||||||
|
#
|
||||||
assert evaluated.status
|
# assert evaluated.status
|
||||||
assert evaluated.value == Concept("foo").set_prop("prop", "a").init_key() # evaluated version of foo
|
# assert evaluated.value == Concept("foo").set_prop("prop", "a").init_key() # evaluated version of foo
|
||||||
|
#
|
||||||
|
#
|
||||||
def test_i_cannot_eval_when_body_references_unknown_concept():
|
# def test_i_cannot_eval_when_body_references_unknown_concept():
|
||||||
context = get_context()
|
# context = get_context()
|
||||||
context.sheerka.add_in_cache(Concept("foo", body="bar"))
|
# context.sheerka.add_in_cache(Concept("foo", body="bar"))
|
||||||
|
#
|
||||||
parsed = PythonParser().parse(context, "foo")
|
# parsed = PythonParser().parse(context, "foo")
|
||||||
evaluated = PythonEvaluator().eval(context, parsed)
|
# evaluated = PythonEvaluator().eval(context, parsed)
|
||||||
|
#
|
||||||
assert not evaluated.status
|
# assert not evaluated.status
|
||||||
assert context.sheerka.isinstance(evaluated.value, BuiltinConcepts.ERROR)
|
# assert context.sheerka.isinstance(evaluated.value, BuiltinConcepts.ERROR)
|
||||||
|
|||||||
@@ -6,12 +6,13 @@ from core.builtin_concepts import ParserResultConcept
|
|||||||
from core.sheerka import Sheerka, ExecutionContext
|
from core.sheerka import Sheerka, ExecutionContext
|
||||||
from core.tokenizer import Tokenizer
|
from core.tokenizer import Tokenizer
|
||||||
from parsers.PythonParser import PythonNode, PythonParser, PythonErrorNode
|
from parsers.PythonParser import PythonNode, PythonParser, PythonErrorNode
|
||||||
|
from sdp.sheerkaDataProvider import Event
|
||||||
|
|
||||||
|
|
||||||
def get_context():
|
def get_context():
|
||||||
sheerka = Sheerka(skip_builtins_in_db=True)
|
sheerka = Sheerka(skip_builtins_in_db=True)
|
||||||
sheerka.initialize("mem://")
|
sheerka.initialize("mem://")
|
||||||
return ExecutionContext("test", "xxx", sheerka)
|
return ExecutionContext("test", Event(), sheerka)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("text, expected", [
|
@pytest.mark.parametrize("text, expected", [
|
||||||
|
|||||||
@@ -0,0 +1,112 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from core.builtin_concepts import ReturnValueConcept, BuiltinConcepts
|
||||||
|
from core.concept import Concept
|
||||||
|
from core.sheerka import Sheerka, ExecutionContext
|
||||||
|
from evaluators.TooManySuccessEvaluator import TooManySuccessEvaluator
|
||||||
|
from sdp.sheerkaDataProvider import Event
|
||||||
|
|
||||||
|
|
||||||
|
def get_context():
|
||||||
|
sheerka = Sheerka(skip_builtins_in_db=True)
|
||||||
|
sheerka.initialize("mem://")
|
||||||
|
return ExecutionContext("test", Event(), sheerka)
|
||||||
|
|
||||||
|
|
||||||
|
def r(name, status=True, value=None):
|
||||||
|
value = value or name
|
||||||
|
return ReturnValueConcept(name, status, value)
|
||||||
|
|
||||||
|
|
||||||
|
reduce_requested = ReturnValueConcept("some_name", True, Concept(key=BuiltinConcepts.REDUCE_REQUESTED))
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("return_values, expected", [
|
||||||
|
([r("evaluators.success1"), r("evaluators.success2"), reduce_requested], True),
|
||||||
|
([r("evaluators.success1"), r("evaluators.success2"), r("other"), reduce_requested], True),
|
||||||
|
([r("evaluators.success1"), r("evaluators.success2"), r("other", False), reduce_requested], True),
|
||||||
|
([r("evaluators.a", value=Concept("c1", body="1")),
|
||||||
|
r("evaluators.a", value=Concept("c2", body="1")),
|
||||||
|
r("other"),
|
||||||
|
reduce_requested], True),
|
||||||
|
([r("evaluators.a", value=Concept("c1", body="1")),
|
||||||
|
r("evaluators.a", value=Concept("c2", body="1")),
|
||||||
|
r("parsers.other", False),
|
||||||
|
reduce_requested], True),
|
||||||
|
([r("evaluators.a", value=Concept("c1", body="1")),
|
||||||
|
r("evaluators.a", value=Concept("c2", body="1")),
|
||||||
|
r("parsers.other"),
|
||||||
|
reduce_requested], False),
|
||||||
|
([r("evaluators.success1"), reduce_requested], False),
|
||||||
|
([reduce_requested], False),
|
||||||
|
([r("evaluators.success1"), r("evaluators.success2")], False),
|
||||||
|
])
|
||||||
|
def test_i_can_match(return_values, expected):
|
||||||
|
context = get_context()
|
||||||
|
assert TooManySuccessEvaluator().matches(context, return_values) == expected
|
||||||
|
|
||||||
|
|
||||||
|
def test_i_can_eval():
|
||||||
|
context = get_context()
|
||||||
|
|
||||||
|
value1 = r("evaluators.a", value=Concept("c1", body="1"))
|
||||||
|
value2 = r("evaluators.a", value=Concept("c2", body="2"))
|
||||||
|
return_values = [
|
||||||
|
value1,
|
||||||
|
value2,
|
||||||
|
r("other", False),
|
||||||
|
reduce_requested
|
||||||
|
]
|
||||||
|
|
||||||
|
evaluator = TooManySuccessEvaluator()
|
||||||
|
matches = evaluator.matches(context, return_values)
|
||||||
|
res = evaluator.eval(context, return_values)
|
||||||
|
|
||||||
|
assert matches
|
||||||
|
assert not res.status
|
||||||
|
assert context.sheerka.isinstance(res.body, BuiltinConcepts.TOO_MANY_SUCCESS)
|
||||||
|
assert res.body.body == [value1, value2]
|
||||||
|
assert len(res.parents) == 4
|
||||||
|
|
||||||
|
|
||||||
|
def test_i_can_eval_when_same_success():
|
||||||
|
context = get_context()
|
||||||
|
|
||||||
|
return_values = [
|
||||||
|
r("evaluators.a", value=Concept("c1", body="1")),
|
||||||
|
r("evaluators.a", value=Concept("c2", body="1")),
|
||||||
|
r("other", False),
|
||||||
|
reduce_requested
|
||||||
|
]
|
||||||
|
|
||||||
|
evaluator = TooManySuccessEvaluator()
|
||||||
|
matches = evaluator.matches(context, return_values)
|
||||||
|
res = evaluator.eval(context, return_values)
|
||||||
|
|
||||||
|
assert matches
|
||||||
|
assert res is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_other_success_are_not_reduced():
|
||||||
|
context = get_context()
|
||||||
|
|
||||||
|
value1 = r("evaluators.a", value=Concept("c1", body="1"))
|
||||||
|
value2 = r("evaluators.a", value=Concept("c2", body="2"))
|
||||||
|
other_success = r("other")
|
||||||
|
return_values = [
|
||||||
|
value1,
|
||||||
|
value2,
|
||||||
|
other_success,
|
||||||
|
reduce_requested
|
||||||
|
]
|
||||||
|
|
||||||
|
evaluator = TooManySuccessEvaluator()
|
||||||
|
matches = evaluator.matches(context, return_values)
|
||||||
|
res = evaluator.eval(context, return_values)
|
||||||
|
|
||||||
|
assert matches
|
||||||
|
assert not res.status
|
||||||
|
assert context.sheerka.isinstance(res.body, BuiltinConcepts.TOO_MANY_SUCCESS)
|
||||||
|
assert res.body.body == [value1, value2]
|
||||||
|
assert len(res.parents) == 3
|
||||||
|
assert other_success not in res.parents
|
||||||
@@ -5,6 +5,7 @@ import pytest
|
|||||||
from core.builtin_concepts import ReturnValueConcept, BuiltinConcepts
|
from core.builtin_concepts import ReturnValueConcept, BuiltinConcepts
|
||||||
from core.sheerka import Sheerka, ExecutionContext
|
from core.sheerka import Sheerka, ExecutionContext
|
||||||
import core.builtin_helpers
|
import core.builtin_helpers
|
||||||
|
from sdp.sheerkaDataProvider import Event
|
||||||
|
|
||||||
|
|
||||||
def test_i_can_use_expect_one_when_empty():
|
def test_i_can_use_expect_one_when_empty():
|
||||||
@@ -160,7 +161,7 @@ def get_sheerka():
|
|||||||
|
|
||||||
|
|
||||||
def get_context(sheerka):
|
def get_context(sheerka):
|
||||||
return ExecutionContext("test", "xxx", sheerka)
|
return ExecutionContext("test", Event(), sheerka)
|
||||||
|
|
||||||
|
|
||||||
def dump_ast(node):
|
def dump_ast(node):
|
||||||
|
|||||||
+24
-21
@@ -9,7 +9,7 @@ from core.sheerka import Sheerka, ExecutionContext
|
|||||||
from evaluators.MutipleSameSuccessEvaluator import MultipleSameSuccessEvaluator
|
from evaluators.MutipleSameSuccessEvaluator import MultipleSameSuccessEvaluator
|
||||||
from parsers.ConceptLexerParser import Sequence, ZeroOrMore, StrMatch, OrderedChoice, Optional, ConceptMatch, \
|
from parsers.ConceptLexerParser import Sequence, ZeroOrMore, StrMatch, OrderedChoice, Optional, ConceptMatch, \
|
||||||
ConceptLexerParser
|
ConceptLexerParser
|
||||||
from sdp.sheerkaDataProvider import SheerkaDataProvider
|
from sdp.sheerkaDataProvider import SheerkaDataProvider, Event
|
||||||
|
|
||||||
tests_root = path.abspath("../build/tests")
|
tests_root = path.abspath("../build/tests")
|
||||||
root_folder = "init_folder"
|
root_folder = "init_folder"
|
||||||
@@ -39,7 +39,7 @@ def get_sheerka(use_dict=True, skip_builtins_in_db=True):
|
|||||||
|
|
||||||
|
|
||||||
def get_context(sheerka):
|
def get_context(sheerka):
|
||||||
return ExecutionContext("test", "xxx", sheerka)
|
return ExecutionContext("test", Event(), sheerka)
|
||||||
|
|
||||||
|
|
||||||
def get_default_concept():
|
def get_default_concept():
|
||||||
@@ -131,8 +131,8 @@ def test_i_cannot_add_the_same_concept_twice():
|
|||||||
res = sheerka.create_new_concept(get_context(sheerka), concept)
|
res = sheerka.create_new_concept(get_context(sheerka), concept)
|
||||||
|
|
||||||
assert not res.status
|
assert not res.status
|
||||||
assert sheerka.isinstance(res.value, BuiltinConcepts.ERROR)
|
assert sheerka.isinstance(res.value, BuiltinConcepts.CONCEPT_ALREADY_DEFINED)
|
||||||
assert res.value.body.args[0] == "Duplicate object."
|
assert res.value.body == concept
|
||||||
|
|
||||||
|
|
||||||
def test_i_can_get_a_builtin_concept_by_their_enum_or_the_string():
|
def test_i_can_get_a_builtin_concept_by_their_enum_or_the_string():
|
||||||
@@ -317,33 +317,27 @@ def test_i_cannot_instantiate_when_properties_are_not_recognized():
|
|||||||
assert sheerka.isinstance(new.concept, concept)
|
assert sheerka.isinstance(new.concept, concept)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("concept, allow_non_body, expected", [
|
@pytest.mark.parametrize("concept, reduce_simple_list, expected", [
|
||||||
(None, False, None),
|
(None, False, None),
|
||||||
(3.14, False, 3.14),
|
(3.14, False, 3.14),
|
||||||
("foo", False, "foo"),
|
("foo", False, "foo"),
|
||||||
(True, False, True),
|
(True, False, True),
|
||||||
(Concept("name", body="foo"), False, "foo"),
|
(Concept("name", body="foo"), False, "foo"),
|
||||||
(Concept("name"), True, Concept("name")),
|
(Concept("name"), False, Concept("name")),
|
||||||
(ConceptWithGetValue("name").set_prop("my_prop", "my_value"), True, "my_value"),
|
(ConceptWithGetValue("name").set_prop("my_prop", "my_value"), False, "my_value"),
|
||||||
(ReturnValueConcept(value="return_value"), False, "return_value"),
|
(ReturnValueConcept(value="return_value"), False, "return_value"),
|
||||||
(ReturnValueConcept(value=Concept(key=BuiltinConcepts.USER_INPUT, body="text"), status=True), False, "text"),
|
(ReturnValueConcept(value=Concept(key=BuiltinConcepts.USER_INPUT, body="text"), status=True), False, "text"),
|
||||||
(ReturnValueConcept(value=UserInputConcept("text"), status=True), False, "text"),
|
(ReturnValueConcept(value=UserInputConcept("text"), status=True), False, "text"),
|
||||||
(Concept("name", body=["foo", "bar"]), False, ["foo", "bar"]),
|
(Concept("name", body=["foo", "bar"]), False, ["foo", "bar"]),
|
||||||
(Concept("name", body=["foo"]), False, "foo"),
|
(Concept("name", body=["foo"]), True, "foo"),
|
||||||
|
(Concept("name", body=Concept("foo")), False, Concept("foo")),
|
||||||
|
(Concept("name", body=Concept("foo", body="value")), False, "value"),
|
||||||
|
(Concept("name", body=Concept("foo", body=ReturnValueConcept(value="return_value"))), False, "return_value"),
|
||||||
])
|
])
|
||||||
def test_i_can_get_value(concept, allow_non_body, expected):
|
def test_i_can_get_value(concept, reduce_simple_list, expected):
|
||||||
sheerka = get_sheerka()
|
sheerka = get_sheerka()
|
||||||
|
|
||||||
assert sheerka.value(concept, allow_non_body) == expected
|
assert sheerka.value(concept, reduce_simple_list) == expected
|
||||||
|
|
||||||
|
|
||||||
def test_i_cannot_get_value_when_no_body_and_allow_none_body_is_false():
|
|
||||||
sheerka = get_sheerka()
|
|
||||||
concept = Concept("name")
|
|
||||||
allow_none_body = False
|
|
||||||
|
|
||||||
assert sheerka.value(concept, allow_none_body) == sheerka.new(BuiltinConcepts.CANNOT_RESOLVE_VALUE_ERROR,
|
|
||||||
body=concept)
|
|
||||||
|
|
||||||
|
|
||||||
def test_list_of_concept_is_sorted_by_id():
|
def test_list_of_concept_is_sorted_by_id():
|
||||||
@@ -569,6 +563,17 @@ def test_properties_values_takes_precedence_over_the_outside_world():
|
|||||||
assert evaluated.body == 'concept_b'
|
assert evaluated.body == 'concept_b'
|
||||||
|
|
||||||
|
|
||||||
|
def test_properties_values_takes_precedence():
|
||||||
|
sheerka = get_sheerka()
|
||||||
|
sheerka.add_in_cache(Concept(name="a", body="'concept_a'").init_key())
|
||||||
|
sheerka.add_in_cache(Concept(name="b", body="'concept_b'").init_key())
|
||||||
|
|
||||||
|
concept = Concept("foo", body="a + b").set_prop("a", "'prop_a'").init_key()
|
||||||
|
evaluated = sheerka.evaluate_concept(get_context(sheerka), concept)
|
||||||
|
assert evaluated.key == concept.key
|
||||||
|
assert evaluated.body == 'prop_aconcept_b'
|
||||||
|
|
||||||
|
|
||||||
def test_i_can_reference_sub_property_of_a_property():
|
def test_i_can_reference_sub_property_of_a_property():
|
||||||
sheerka = get_sheerka()
|
sheerka = get_sheerka()
|
||||||
sheerka.add_in_cache(Concept(name="concept_a").set_prop("subProp", "'sub_a'").init_key())
|
sheerka.add_in_cache(Concept(name="concept_a").set_prop("subProp", "'sub_a'").init_key())
|
||||||
@@ -666,5 +671,3 @@ def test_i_cannot_add_the_same_concept_twice_in_a_set():
|
|||||||
all_entries = sheerka.sdp.get("All_" + all_foos.id, None, False)
|
all_entries = sheerka.sdp.get("All_" + all_foos.id, None, False)
|
||||||
assert len(all_entries) == 1
|
assert len(all_entries) == 1
|
||||||
assert foo.id in all_entries
|
assert foo.id in all_entries
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ from core.builtin_concepts import BuiltinConcepts, SuccessConcept
|
|||||||
from core.concept import Concept
|
from core.concept import Concept
|
||||||
from core.sheerka import Sheerka, ExecutionContext
|
from core.sheerka import Sheerka, ExecutionContext
|
||||||
from evaluators.BaseEvaluator import OneReturnValueEvaluator, BaseEvaluator, AllReturnValuesEvaluator
|
from evaluators.BaseEvaluator import OneReturnValueEvaluator, BaseEvaluator, AllReturnValuesEvaluator
|
||||||
|
from sdp.sheerkaDataProvider import Event
|
||||||
|
|
||||||
|
|
||||||
def get_sheerka():
|
def get_sheerka():
|
||||||
@@ -12,7 +13,7 @@ def get_sheerka():
|
|||||||
|
|
||||||
|
|
||||||
def get_context(sheerka):
|
def get_context(sheerka):
|
||||||
return ExecutionContext("test", "xxx", sheerka)
|
return ExecutionContext("test", Event(), sheerka)
|
||||||
|
|
||||||
|
|
||||||
def get_ret_val(sheerka, concept, who="who"):
|
def get_ret_val(sheerka, concept, who="who"):
|
||||||
@@ -142,7 +143,7 @@ class EvaluatorOnePreEvaluation(OneReturnValueEvaluatorForTestingPurpose):
|
|||||||
|
|
||||||
class EvaluatorOneMultiSteps(OneReturnValueEvaluatorForTestingPurpose):
|
class EvaluatorOneMultiSteps(OneReturnValueEvaluatorForTestingPurpose):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__("multiStep", [BuiltinConcepts.BEFORE_EVALUATION, BuiltinConcepts.EVALUATION], 10)
|
super().__init__("multiStep", [BuiltinConcepts.EVALUATION, BuiltinConcepts.BEFORE_EVALUATION], 10)
|
||||||
|
|
||||||
|
|
||||||
class EvaluatorAllReduceFooBar(EvaluatorAllWithPriority):
|
class EvaluatorAllReduceFooBar(EvaluatorAllWithPriority):
|
||||||
@@ -321,10 +322,10 @@ def test_evaluation_steps_are_respected():
|
|||||||
sheerka.evaluators = [EvaluatorOneWithPriority10, EvaluatorOnePreEvaluation]
|
sheerka.evaluators = [EvaluatorOneWithPriority10, EvaluatorOnePreEvaluation]
|
||||||
|
|
||||||
entries = [get_ret_val(sheerka, Concept("foo"))]
|
entries = [get_ret_val(sheerka, Concept("foo"))]
|
||||||
BaseEvaluator.debug_out = []
|
Out.debug_out = []
|
||||||
sheerka.execute(get_context(sheerka), entries, [BuiltinConcepts.BEFORE_EVALUATION])
|
sheerka.execute(get_context(sheerka), entries, [BuiltinConcepts.BEFORE_EVALUATION])
|
||||||
|
|
||||||
assert BaseEvaluator.debug_out == [
|
assert Out.debug_out == [
|
||||||
'__BEFORE_EVALUATION [0] preEval - matches - target=foo',
|
'__BEFORE_EVALUATION [0] preEval - matches - target=foo',
|
||||||
'__BEFORE_EVALUATION [0] preEval - eval - target=foo',
|
'__BEFORE_EVALUATION [0] preEval - eval - target=foo',
|
||||||
'__BEFORE_EVALUATION [0] preEval - matches - target=__BEFORE_EVALUATION',
|
'__BEFORE_EVALUATION [0] preEval - matches - target=__BEFORE_EVALUATION',
|
||||||
@@ -336,10 +337,10 @@ def test_evaluation_multi_steps_are_respected():
|
|||||||
sheerka.evaluators = [EvaluatorOneMultiSteps]
|
sheerka.evaluators = [EvaluatorOneMultiSteps]
|
||||||
|
|
||||||
entries = [get_ret_val(sheerka, Concept("foo"))]
|
entries = [get_ret_val(sheerka, Concept("foo"))]
|
||||||
BaseEvaluator.debug_out = []
|
Out.debug_out = []
|
||||||
sheerka.execute(get_context(sheerka), entries, [BuiltinConcepts.BEFORE_EVALUATION, BuiltinConcepts.EVALUATION])
|
sheerka.execute(get_context(sheerka), entries, [BuiltinConcepts.BEFORE_EVALUATION, BuiltinConcepts.EVALUATION])
|
||||||
|
|
||||||
assert BaseEvaluator.debug_out == [
|
assert Out.debug_out == [
|
||||||
'__BEFORE_EVALUATION [0] multiStep - matches - target=foo',
|
'__BEFORE_EVALUATION [0] multiStep - matches - target=foo',
|
||||||
'__BEFORE_EVALUATION [0] multiStep - eval - target=foo',
|
'__BEFORE_EVALUATION [0] multiStep - eval - target=foo',
|
||||||
'__BEFORE_EVALUATION [0] multiStep - matches - target=__BEFORE_EVALUATION',
|
'__BEFORE_EVALUATION [0] multiStep - matches - target=__BEFORE_EVALUATION',
|
||||||
@@ -349,3 +350,28 @@ def test_evaluation_multi_steps_are_respected():
|
|||||||
'__EVALUATION [0] multiStep - matches - target=__EVALUATION',
|
'__EVALUATION [0] multiStep - matches - target=__EVALUATION',
|
||||||
'__EVALUATION [0] multiStep - eval - target=__EVALUATION'
|
'__EVALUATION [0] multiStep - eval - target=__EVALUATION'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def test_evaluators_can_be_pre_processed():
|
||||||
|
sheerka = get_sheerka()
|
||||||
|
sheerka.evaluators = [EvaluatorOneModifyFoo]
|
||||||
|
|
||||||
|
entries = [get_ret_val(sheerka, Concept("foo"))]
|
||||||
|
|
||||||
|
# disable evaluator
|
||||||
|
context = get_context(sheerka)
|
||||||
|
context.add_preprocess(EvaluatorOneModifyFoo().name, enabled=False) # disabled for this exec context
|
||||||
|
Out.debug_out = []
|
||||||
|
sheerka.execute(context, entries, [BuiltinConcepts.EVALUATION])
|
||||||
|
assert Out.debug_out == []
|
||||||
|
|
||||||
|
# other contextes are not impacted
|
||||||
|
Out.debug_out = []
|
||||||
|
sheerka.execute(get_context(sheerka), entries, [BuiltinConcepts.EVALUATION])
|
||||||
|
assert Out.debug_out == [
|
||||||
|
'__EVALUATION [0] modifyFoo - matches - target=foo',
|
||||||
|
'__EVALUATION [0] modifyFoo - eval - target=foo',
|
||||||
|
'__EVALUATION [0] modifyFoo - matches - target=__EVALUATION',
|
||||||
|
'__EVALUATION [1] modifyFoo - matches - target=bar',
|
||||||
|
'__EVALUATION [1] modifyFoo - matches - target=__EVALUATION'
|
||||||
|
]
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ from core.sheerka import Sheerka, ExecutionContext
|
|||||||
from evaluators.MutipleSameSuccessEvaluator import MultipleSameSuccessEvaluator
|
from evaluators.MutipleSameSuccessEvaluator import MultipleSameSuccessEvaluator
|
||||||
from parsers.ConceptLexerParser import Sequence, ZeroOrMore, StrMatch, OrderedChoice, Optional, ConceptMatch, \
|
from parsers.ConceptLexerParser import Sequence, ZeroOrMore, StrMatch, OrderedChoice, Optional, ConceptMatch, \
|
||||||
ConceptLexerParser
|
ConceptLexerParser
|
||||||
from sdp.sheerkaDataProvider import SheerkaDataProvider
|
from sdp.sheerkaDataProvider import SheerkaDataProvider, Event
|
||||||
|
|
||||||
tests_root = path.abspath("../build/tests")
|
tests_root = path.abspath("../build/tests")
|
||||||
root_folder = "init_folder"
|
root_folder = "init_folder"
|
||||||
@@ -39,7 +39,7 @@ def get_sheerka(use_dict=True, skip_builtins_in_db=True):
|
|||||||
|
|
||||||
|
|
||||||
def get_context(sheerka):
|
def get_context(sheerka):
|
||||||
return ExecutionContext("test", "xxx", sheerka)
|
return ExecutionContext("test", Event(), sheerka)
|
||||||
|
|
||||||
|
|
||||||
def get_default_concept():
|
def get_default_concept():
|
||||||
@@ -79,7 +79,7 @@ def test_i_can_eval_concept_with_python_body():
|
|||||||
res = sheerka.evaluate_user_input(text)
|
res = sheerka.evaluate_user_input(text)
|
||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert res[0].value == 1
|
assert res[0].value == Concept(name="one", body=1).init_key() # by default, the concept is returned
|
||||||
|
|
||||||
|
|
||||||
def test_i_can_eval_concept_with_concept_body():
|
def test_i_can_eval_concept_with_concept_body():
|
||||||
@@ -93,7 +93,7 @@ def test_i_can_eval_concept_with_concept_body():
|
|||||||
return_value = res[0].value
|
return_value = res[0].value
|
||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert sheerka.isinstance(return_value, concept_one)
|
assert return_value == Concept(name="un", body=Concept(name="one").init_key()).init_key()
|
||||||
|
|
||||||
|
|
||||||
def test_i_can_eval_concept_with_no_body():
|
def test_i_can_eval_concept_with_no_body():
|
||||||
@@ -207,23 +207,6 @@ as:
|
|||||||
assert sheerka.isinstance(res[0].value, BuiltinConcepts.CONCEPT_ALREADY_DEFINED)
|
assert sheerka.isinstance(res[0].value, BuiltinConcepts.CONCEPT_ALREADY_DEFINED)
|
||||||
|
|
||||||
|
|
||||||
# def test_i_can_disable_an_evaluator():
|
|
||||||
# sheerka = get_sheerka()
|
|
||||||
# concept = Concept(name="one", body="1")
|
|
||||||
# sheerka.add_in_cache(concept)
|
|
||||||
#
|
|
||||||
# text = "one"
|
|
||||||
# p = next(e for e in sheerka.evaluators if e.__name__ == "PythonEvaluator")
|
|
||||||
# p.enabled = False # not that you disable the class, not the instance
|
|
||||||
#
|
|
||||||
# res = sheerka.evaluate_user_input(text)
|
|
||||||
# assert len(res) == 1
|
|
||||||
# assert res[0].status
|
|
||||||
# assert sheerka.isinstance(res[0].value, BuiltinConcepts.PARSER_RESULT)
|
|
||||||
#
|
|
||||||
# p.enabled = True # put back for the remaining unit tests
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("text", [
|
@pytest.mark.parametrize("text", [
|
||||||
"",
|
"",
|
||||||
" ",
|
" ",
|
||||||
@@ -293,9 +276,9 @@ def test_i_cannot_manage_duplicate_concepts_when_the_values_are_different():
|
|||||||
|
|
||||||
concepts = res[0].value.body
|
concepts = res[0].value.body
|
||||||
assert len(concepts) == 2
|
assert len(concepts) == 2
|
||||||
sorted_values = sorted(concepts, key=lambda x: x.value)
|
sorted_values = sorted(concepts, key=lambda x: x.value.body)
|
||||||
assert sorted_values[0].value == "hello another value"
|
assert sorted_values[0].value.body == "hello another value"
|
||||||
assert sorted_values[1].value == "hello foo"
|
assert sorted_values[1].value.body == "hello foo"
|
||||||
|
|
||||||
|
|
||||||
def test_i_can_manage_concepts_with_the_same_key_when_values_are_the_same():
|
def test_i_can_manage_concepts_with_the_same_key_when_values_are_the_same():
|
||||||
@@ -308,7 +291,7 @@ def test_i_can_manage_concepts_with_the_same_key_when_values_are_the_same():
|
|||||||
res = sheerka.evaluate_user_input("hello 'foo'")
|
res = sheerka.evaluate_user_input("hello 'foo'")
|
||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert res[0].value == "hello foo"
|
assert res[0].value.body == "hello foo" # I don't know yet the one to choose
|
||||||
assert res[0].who == sheerka.get_evaluator_name(MultipleSameSuccessEvaluator.NAME)
|
assert res[0].who == sheerka.get_evaluator_name(MultipleSameSuccessEvaluator.NAME)
|
||||||
|
|
||||||
|
|
||||||
@@ -321,7 +304,7 @@ def test_i_can_create_concepts_with_python_code_as_body():
|
|||||||
|
|
||||||
assert len(res) == 1
|
assert len(res) == 1
|
||||||
assert res[0].status
|
assert res[0].status
|
||||||
assert isinstance(res[0].value, list)
|
assert isinstance(res[0].value.body, list)
|
||||||
|
|
||||||
|
|
||||||
def test_i_can_create_concept_with_bnf_definition():
|
def test_i_can_create_concept_with_bnf_definition():
|
||||||
|
|||||||
Reference in New Issue
Block a user