Concept validation must be requested

This commit is contained in:
2020-03-09 12:23:53 +01:00
parent ef31a4807d
commit 1bde97b5e3
27 changed files with 346 additions and 280 deletions
+19
View File
@@ -42,11 +42,30 @@ twenty isa number
def concept twenties from bnf twenty number where number < 10 as twenty + number def concept twenties from bnf twenty number where number < 10 as twenty + number
twenties isa number twenties isa number
def concept thirty as 30 def concept thirty as 30
thirty isa number
def concept thirties from bnf thirty number where number < 10 as thirty + number def concept thirties from bnf thirty number where number < 10 as thirty + number
thirties isa number thirties isa number
def concept forty as 40 def concept forty as 40
forty isa number
def concept forties from bnf forty number where number < 10 as forty + number def concept forties from bnf forty number where number < 10 as forty + number
forties isa number forties isa number
def concept fifty as 50 def concept fifty as 50
fifty isa number
def concept fifties from bnf fifty number where number < 10 as fifty + number def concept fifties from bnf fifty number where number < 10 as fifty + number
fifties isa number fifties isa number
def concept sixty as 60
sixty isa number
def concept sixties from bnf sixty number where number < 10 as sixty + number
sixties isa number
def concept seventy as 70
seventy isa number
def concept seventies from bnf seventy number where number < 10 as seventy + number
seventies isa number
def concept eighty as 80
eighty isa number
def concept eighties from bnf eighty number where number < 10 as eighty + number
eighties isa number
def concept ninety as 90
ninety isa number
def concept nineties from bnf ninety number where number < 10 as ninety + number
nineties isa number
+5 -4
View File
@@ -47,13 +47,14 @@ class BuiltinConcepts(Enum):
LIST = "list" # represents a list LIST = "list" # represents a list
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 EVALUATOR_PRE_PROCESS = "evaluator pre process" # used modify / tweak behaviour of evaluators
CONCEPT_EVAL_REQUESTED = "concept eval requested" EVAL_BODY_REQUESTED = "eval body requested" # to evaluate the body
EVAL_WHERE_REQUESTED = "eval where requested" # to evaluate the where clause
CONCEPT_VALUE_REQUESTED = "concept value requested" # returns the body of the concept instead of the concept itself
REDUCE_REQUESTED = "reduce requested" # remove meaningless error when possible REDUCE_REQUESTED = "reduce requested" # remove meaningless error when possible
NOT_A_SET = "not a set" # the concept has no entry in sets NOT_A_SET = "not a set" # the concept has no entry in sets
WHERE_CLAUSE_FAILED = "where clause failed" # failed to validate where clause during evaluation WHERE_CLAUSE_FAILED = "where clause failed" # failed to validate where clause during evaluation
CHICKEN_AND_EGG = "chicken and egg" # infinite recursion when declaring concept CHICKEN_AND_EGG = "chicken and egg" # infinite recursion when declaring concept
ISA = "is a" # builtin concept to express that a concept is an instance of another one ISA = "is a" # builtin concept to express that a concept is an instance of another one
CONCEPT_VALUE_REQUESTED = "concept value requested" # returns the body of the concept instead of the concept itself
NODE = "node" NODE = "node"
GENERIC_NODE = "generic node" GENERIC_NODE = "generic node"
@@ -78,7 +79,7 @@ BuiltinUnique = [
BuiltinConcepts.AFTER_RENDERING, BuiltinConcepts.AFTER_RENDERING,
BuiltinConcepts.SUCCESS, BuiltinConcepts.SUCCESS,
BuiltinConcepts.NOP, BuiltinConcepts.NOP,
BuiltinConcepts.CONCEPT_EVAL_REQUESTED, BuiltinConcepts.EVAL_BODY_REQUESTED,
BuiltinConcepts.REDUCE_REQUESTED, BuiltinConcepts.REDUCE_REQUESTED,
] ]
@@ -248,7 +249,7 @@ class ParserResultConcept(Concept):
Result of a parsing Result of a parsing
""" """
def __init__(self, parser=None, source=None, value=None, try_parsed=None): def __init__(self, parser=None, source=None, value=None, try_parsed=None, validate_concept=None):
super().__init__(BuiltinConcepts.PARSER_RESULT, True, False, BuiltinConcepts.PARSER_RESULT) super().__init__(BuiltinConcepts.PARSER_RESULT, True, False, BuiltinConcepts.PARSER_RESULT)
self.set_metadata_value(ConceptParts.BODY, value) self.set_metadata_value(ConceptParts.BODY, value)
self.set_prop("parser", parser) self.set_prop("parser", parser)
+23 -21
View File
@@ -17,32 +17,34 @@ def is_same_success(context, return_values):
""" """
assert isinstance(return_values, list) assert isinstance(return_values, list)
if not return_values[0].status: def _get_value(ret_val):
return False if not ret_val.status:
raise Exception("Status is false")
if isinstance(return_values[0].body, Concept): if isinstance(ret_val.body, Concept):
evaluated = context.sheerka.evaluate_concept(context, return_values[0].body, True) if not ret_val.body.metadata.is_evaluated:
if evaluated.key != return_values[0].body.key: with context.push(desc=f"Evaluating concept '{ret_val.body}'") as sub_context:
return False sub_context.local_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
reference = context.sheerka.value(evaluated) evaluated = context.sheerka.evaluate_concept(sub_context, ret_val.body)
else: if evaluated.key != ret_val.body.key:
reference = context.sheerka.value(return_values[0]) raise Exception("Failed to evaluate evaluate")
return context.sheerka.value(evaluated)
else:
return context.sheerka.value(ret_val.body)
else:
return context.sheerka.value(ret_val)
for return_value in return_values[1:]: try:
if not return_value.status: reference = _get_value(return_values[0])
return False
if isinstance(return_value.body, Concept): for return_value in return_values[1:]:
evaluated = context.sheerka.evaluate_concept(context, return_value.body, True) actual = _get_value(return_value)
if evaluated.key != return_value.body.key: if actual != reference:
return False return False
actual = context.sheerka.value(evaluated) except Exception as ex:
else: context.log_error(ex)
actual = context.sheerka.value(return_value) return False
if actual != reference:
return False
return True return True
+1
View File
@@ -48,6 +48,7 @@ class ConceptMetadata:
id: str # unique identifier for a concept. The id will never be modified (but the key can) id: str # unique identifier for a concept. The id will never be modified (but the key can)
props: list # list properties, with their default values props: list # list properties, with their default values
is_evaluated: bool = False # True is the concept is evaluated by sheerka.eval_concept() is_evaluated: bool = False # True is the concept is evaluated by sheerka.eval_concept()
need_validation = False # True if the properties of the concept need to be validated
full_serialization: bool = False # If True, the full object will be serialized, rather than just the diff full_serialization: bool = False # If True, the full object will be serialized, rather than just the diff
+14 -4
View File
@@ -21,8 +21,6 @@ PROPERTIES_TO_SERIALIZE = ("_id",
"concepts") "concepts")
class ExecutionContext: class ExecutionContext:
""" """
To keep track of the execution of a request To keep track of the execution of a request
@@ -44,6 +42,7 @@ class ExecutionContext:
sheerka, sheerka,
desc: str = None, desc: str = None,
logger=None, logger=None,
global_hints=None,
**kwargs): **kwargs):
self._parent = None self._parent = None
@@ -60,7 +59,8 @@ class ExecutionContext:
self.children = [] self.children = []
self.preprocess = None self.preprocess = None
self.logger = logger self.logger = logger
self.extra_info = [] self.local_hints = set()
self.global_hints = set() if global_hints is None else global_hints
self.inputs = {} # what was the parameters of the execution context self.inputs = {} # what was the parameters of the execution context
self.values = {} # what was produced by the execution context self.values = {} # what was produced by the execution context
@@ -211,11 +211,12 @@ class ExecutionContext:
self.sheerka, self.sheerka,
desc, desc,
logger, logger,
self.global_hints,
**_kwargs) **_kwargs)
new._parent = self new._parent = self
new._tab = self._tab + " " * DEBUG_TAB_SIZE new._tab = self._tab + " " * DEBUG_TAB_SIZE
new.preprocess = self.preprocess new.preprocess = self.preprocess
new.extra_info.extend(self.extra_info) new.local_hints.update(self.local_hints)
self.children.append(new) self.children.append(new)
return new return new
@@ -247,6 +248,15 @@ class ExecutionContext:
def get_parent(self): def get_parent(self):
return self._parent return self._parent
def in_context(self, concept_key):
if concept_key in self.local_hints:
return True
if concept_key in self.global_hints:
return True
return False
@staticmethod @staticmethod
def return_value_to_str(r): def return_value_to_str(r):
value = str(r.value) value = str(r.value)
+2 -1
View File
@@ -53,9 +53,10 @@ class SheerkaDump:
if not first: if not first:
self.sheerka.log.info("") self.sheerka.log.info("")
self.sheerka.log.info(f"name : {c.name}") self.sheerka.log.info(f"name : {c.name}")
self.sheerka.log.info(f"bnf : {c.metadata.definition}")
self.sheerka.log.info(f"key : {c.key}") self.sheerka.log.info(f"key : {c.key}")
self.sheerka.log.info(f"bnf : {c.metadata.definition}")
self.sheerka.log.info(f"body : {c.metadata.body}") self.sheerka.log.info(f"body : {c.metadata.body}")
self.sheerka.log.info(f"where : {c.metadata.where}")
if eval: if eval:
self.sheerka.log.info(f"value : {value}") self.sheerka.log.info(f"value : {value}")
for p in c.props: for p in c.props:
@@ -118,7 +118,7 @@ class SheerkaEvaluateConcept:
else: else:
self.sheerka.cache_by_key[concept.key].compiled = concept.compiled self.sheerka.cache_by_key[concept.key].compiled = concept.compiled
def resolve(self, context, to_resolve, current_prop, current_concept, evaluate_body): def resolve(self, context, to_resolve, current_prop, current_concept, force_evaluation):
if isinstance(to_resolve, DoNotResolve): if isinstance(to_resolve, DoNotResolve):
return to_resolve.value return to_resolve.value
@@ -134,10 +134,13 @@ class SheerkaEvaluateConcept:
context.log(desc, self.logger_name) context.log(desc, self.logger_name)
with context.push(desc=desc, obj=current_concept) as sub_context: with context.push(desc=desc, obj=current_concept) as sub_context:
if force_evaluation:
sub_context.local_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
# when it's a concept, evaluate it # when it's a concept, evaluate it
if isinstance(to_resolve, Concept) and \ if isinstance(to_resolve, Concept) and \
not context.sheerka.isinstance(to_resolve, BuiltinConcepts.RETURN_VALUE): not context.sheerka.isinstance(to_resolve, BuiltinConcepts.RETURN_VALUE):
evaluated = self.evaluate_concept(sub_context, to_resolve, evaluate_body) evaluated = self.evaluate_concept(sub_context, to_resolve)
sub_context.add_values(return_values=evaluated) sub_context.add_values(return_values=evaluated)
if evaluated.key == to_resolve.key: if evaluated.key == to_resolve.key:
return evaluated return evaluated
@@ -147,8 +150,6 @@ class SheerkaEvaluateConcept:
# otherwise, execute all return values to find out what is the value # otherwise, execute all return values to find out what is the value
else: else:
use_copy = [r for r in to_resolve] if hasattr(to_resolve, "__iter__") else to_resolve use_copy = [r for r in to_resolve] if hasattr(to_resolve, "__iter__") else to_resolve
if evaluate_body:
sub_context.extra_info.append(BuiltinConcepts.CONCEPT_EVAL_REQUESTED)
r = self.sheerka.execute(sub_context, use_copy, CONCEPT_EVALUATION_STEPS) r = self.sheerka.execute(sub_context, use_copy, CONCEPT_EVALUATION_STEPS)
one_r = expect_one(context, r) one_r = expect_one(context, r)
@@ -164,7 +165,7 @@ class SheerkaEvaluateConcept:
concept=current_concept, concept=current_concept,
property_name=current_prop) property_name=current_prop)
def resolve_list(self, context, list_to_resolve, current_prop, current_concept, evaluate_body): def resolve_list(self, context, list_to_resolve, current_prop, current_concept, force_evaluation):
"""When dealing with a list, there are two possibilities""" """When dealing with a list, there are two possibilities"""
# It may be a list of ReturnValueConcept to execute (always the case for metadata) # It may be a list of ReturnValueConcept to execute (always the case for metadata)
# or a list of single values (may be the case for properties) # or a list of single values (may be the case for properties)
@@ -173,7 +174,7 @@ class SheerkaEvaluateConcept:
return [] return []
if self.sheerka.isinstance(list_to_resolve[0], BuiltinConcepts.RETURN_VALUE): if self.sheerka.isinstance(list_to_resolve[0], BuiltinConcepts.RETURN_VALUE):
return self.resolve(context, list_to_resolve, current_prop, current_concept, evaluate_body) return self.resolve(context, list_to_resolve, current_prop, current_concept, force_evaluation)
res = [] res = []
for to_resolve in list_to_resolve: for to_resolve in list_to_resolve:
@@ -184,14 +185,14 @@ class SheerkaEvaluateConcept:
concept=current_concept, concept=current_concept,
property_name=current_prop) property_name=current_prop)
r = self.resolve(context, to_resolve, current_prop, current_concept, evaluate_body) r = self.resolve(context, to_resolve, current_prop, current_concept, force_evaluation)
if self.sheerka.isinstance(r, BuiltinConcepts.CONCEPT_EVAL_ERROR): if self.sheerka.isinstance(r, BuiltinConcepts.CONCEPT_EVAL_ERROR):
return r return r
res.append(r) res.append(r)
return res return res
def evaluate_concept(self, context, concept: Concept, evaluate_body=False): def evaluate_concept(self, context, concept: Concept):
""" """
Evaluation a concept Evaluation a concept
It means that if the where clause is True, will evaluate the body It means that if the where clause is True, will evaluate the body
@@ -208,7 +209,7 @@ class SheerkaEvaluateConcept:
# 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, body must be evaluated before where # props must be evaluated first, body must be evaluated before where
all_metadata_to_eval = self.choose_metadata_to_eval(concept, evaluate_body) all_metadata_to_eval = self.choose_metadata_to_eval(context, concept)
for metadata_to_eval in all_metadata_to_eval: for metadata_to_eval in all_metadata_to_eval:
if metadata_to_eval == "props": if metadata_to_eval == "props":
@@ -221,6 +222,7 @@ class SheerkaEvaluateConcept:
else: else:
# Do not send the current concept for the properties # Do not send the current concept for the properties
resolved = self.resolve(context, prop_ast, prop_name, None, True) resolved = self.resolve(context, prop_ast, prop_name, None, True)
if isinstance(resolved, Concept) and not context.sheerka.is_success(resolved): if isinstance(resolved, Concept) and not context.sheerka.is_success(resolved):
resolved.set_prop("concept", concept) # since current concept was not sent resolved.set_prop("concept", concept) # since current concept was not sent
return resolved return resolved
@@ -236,7 +238,10 @@ class SheerkaEvaluateConcept:
if part_key in concept.compiled and concept.compiled[part_key] is not None: if part_key in concept.compiled and concept.compiled[part_key] is not None:
metadata_ast = concept.compiled[part_key] metadata_ast = concept.compiled[part_key]
resolved = self.resolve(context, metadata_ast, part_key, concept, evaluate_body) # if part_key is PRE, POST or WHERE, the concepts need to be evaluated
# otherwise the predicates cannot be resolved
force_concept_eval = False if part_key == ConceptParts.BODY else True
resolved = self.resolve(context, metadata_ast, part_key, concept, force_concept_eval)
if isinstance(resolved, Concept) and not context.sheerka.is_success(resolved): if isinstance(resolved, Concept) and not context.sheerka.is_success(resolved):
return resolved return resolved
else: else:
@@ -260,49 +265,57 @@ class SheerkaEvaluateConcept:
concept.metadata.is_evaluated = "body" in all_metadata_to_eval concept.metadata.is_evaluated = "body" in all_metadata_to_eval
return concept return concept
def choose_metadata_to_eval(self, concept, evaluate_body): def choose_metadata_to_eval(self, context, concept):
if evaluate_body: if context.in_context(BuiltinConcepts.EVAL_BODY_REQUESTED):
return ["pre", "post", "props", "body", "where"] return ["pre", "post", "props", "body", "where"]
metadata = ["pre", "post"] + self.needed_metadata(concept) + ["where"] metadata = ["pre", "post"]
if context.in_context(BuiltinConcepts.EVAL_WHERE_REQUESTED) or concept.metadata.need_validation:
needed = self.needed_metadata(concept, ConceptParts.WHERE)
for e in needed:
if e not in metadata:
metadata.append(e)
if "where" not in metadata:
metadata.append("where")
return metadata return metadata
def needed_metadata(self, concept): def needed_metadata(self, concept, metadata):
""" """
Tries to find out if the evaluation of the body is necessary Tries to find out if the evaluation of the body is necessary
It's a very basic approach that will need to be improved It's a very basic approach that will need to be improved
:param concept: :param concept:
:param metadata:
:return: :return:
""" """
if metadata not in concept.compiled:
return []
return_values = concept.compiled[metadata]
if not isinstance(return_values, list):
return []
needed = [] needed = []
for return_value in return_values:
for metadata in (ConceptParts.PRE, ConceptParts.POST, ConceptParts.WHERE): if not self.sheerka.isinstance(return_value, BuiltinConcepts.RETURN_VALUE):
if metadata not in concept.compiled:
continue continue
return_values = concept.compiled[metadata] if not return_value.status:
if not isinstance(return_values, list):
continue continue
for return_value in return_values: if not self.sheerka.isinstance(return_value.body, BuiltinConcepts.PARSER_RESULT):
if not self.sheerka.isinstance(return_value, BuiltinConcepts.RETURN_VALUE): continue
continue
if not return_value.status: if not isinstance(return_value.body.source, str):
continue continue
if not self.sheerka.isinstance(return_value.body, BuiltinConcepts.PARSER_RESULT): for prop_name in (p[0] for p in concept.metadata.props):
continue if prop_name in return_value.body.source:
needed.append("props")
break
if not isinstance(return_value.body.source, str): if "self" in return_value.body.source:
continue needed.append("body")
for prop_name in (p[0] for p in concept.metadata.props):
if prop_name in return_value.body.source:
needed.append("props")
break
if "self" in return_value.body.source:
needed.append("body")
return needed return needed
+2 -19
View File
@@ -90,27 +90,12 @@ class SheerkaExecute:
result = core.utils.remove_list_from_list(result, user_inputs) result = core.utils.remove_list_from_list(result, user_inputs)
return result return result
def call_evaluators(self, execution_context, return_values, process_step, evaluation_context=None): def call_evaluators(self, execution_context, return_values, process_step):
# 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]
# Evaluation context are contexts that may modify the behaviour of the execution
# For example, a concept to indicate that the value is not wanted
# Or a concept to indicate that we want the letter form of the response
# But first, they need to be transformed into return values
if evaluation_context is None:
evaluation_return_values = []
else:
evaluation_return_values = [self.sheerka.ret(execution_context.who, True, c) for c in evaluation_context]
# add the current step as part as the evaluation context
evaluation_return_values.append(self.sheerka.ret(execution_context.who, True, self.sheerka.new(process_step)))
# the pool of return values are the mix
return_values.extend(evaluation_return_values)
# group the evaluators by priority and sort them # group the evaluators by priority and sort them
# 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 = {}
@@ -203,8 +188,6 @@ class SheerkaExecute:
# inc the iteration and continue # inc the iteration and continue
iteration += 1 iteration += 1
# remove all evaluation context that are not reduced
return_values = core.utils.remove_list_from_list(return_values, evaluation_return_values)
return return_values return return_values
def execute(self, execution_context, return_values, execution_steps): def execute(self, execution_context, return_values, execution_steps):
@@ -223,7 +206,7 @@ class SheerkaExecute:
if step == BuiltinConcepts.PARSING: if step == BuiltinConcepts.PARSING:
return_values = self.call_parsers(sub_context, return_values) return_values = self.call_parsers(sub_context, return_values)
else: else:
return_values = self.call_evaluators(sub_context, return_values, step, None) return_values = self.call_evaluators(sub_context, return_values, step)
if copy != return_values: if copy != return_values:
sub_context.log_result(return_values) sub_context.log_result(return_values)
@@ -108,7 +108,8 @@ class SheerkaSetsManager:
# it may be a concept that references a set # it may be a concept that references a set
if not sub_concept.metadata.is_evaluated: if not sub_concept.metadata.is_evaluated:
with context.push(desc=f"Evaluating concept {sub_concept}") as sub_context: with context.push(desc=f"Evaluating concept {sub_concept}") as sub_context:
evaluated = self.sheerka.evaluate_concept(sub_context, sub_concept, True) sub_context.local_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
evaluated = self.sheerka.evaluate_concept(sub_context, sub_concept)
if evaluated.key != concept.key: if evaluated.key != concept.key:
return False return False
return _get_set_elements(context, concept, sub_concept.body) return _get_set_elements(context, concept, sub_concept.body)
@@ -167,7 +168,8 @@ class SheerkaSetsManager:
# it may be a concept that references a set # it may be a concept that references a set
if not concept.metadata.is_evaluated: if not concept.metadata.is_evaluated:
with context.push(desc=f"Evaluating concept {concept}") as sub_context: with context.push(desc=f"Evaluating concept {concept}") as sub_context:
evaluated = self.sheerka.evaluate_concept(sub_context, concept, True) sub_context.local_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
evaluated = self.sheerka.evaluate_concept(sub_context, concept)
if evaluated.key != concept.key: if evaluated.key != concept.key:
return False return False
@@ -216,9 +218,10 @@ for x in xx__concepts__xx:
result = [] result = []
with context.push(desc=f"Evaluating concepts of a set") as sub_context: with context.push(desc=f"Evaluating concepts of a set") as sub_context:
sub_context.local_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
for element_id in ids: for element_id in ids:
concept = self.sheerka.get_by_id(element_id) concept = self.sheerka.get_by_id(element_id)
evaluated = self.sheerka.evaluate_concept(sub_context, concept, True) evaluated = self.sheerka.evaluate_concept(sub_context, concept)
result.append(evaluated) result.append(evaluated)
return result return result
+3 -4
View File
@@ -239,6 +239,7 @@ class Sheerka(Concept):
with ExecutionContext(self.key, event, self, f"Evaluating '{text}'", self.log) as execution_context: with ExecutionContext(self.key, event, self, f"Evaluating '{text}'", self.log) as execution_context:
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)) reduce_requested = self.ret(self.name, True, self.new(BuiltinConcepts.REDUCE_REQUESTED))
#execution_context.local_hints.add(BuiltinConcepts.EVAL_WHERE_REQUESTED)
steps = [ steps = [
BuiltinConcepts.BEFORE_PARSING, BuiltinConcepts.BEFORE_PARSING,
@@ -332,17 +333,15 @@ class Sheerka(Concept):
return self.sets_handler.get_set_elements(context, concept) return self.sets_handler.get_set_elements(context, concept)
def evaluate_concept(self, context, concept: Concept, evaluate_body=False): def evaluate_concept(self, context, concept: Concept):
""" """
Evaluation a concept Evaluation a concept
It means that if the where clause is True, will evaluate the body It means that if the where clause is True, will evaluate the body
:param evaluate_body:
:param context: :param context:
:param concept: :param concept:
:param evaluate_body:
:return: value of the evaluation or error :return: value of the evaluation or error
""" """
return self.evaluate_concept_handler.evaluate_concept(context, concept, evaluate_body) return self.evaluate_concept_handler.evaluate_concept(context, concept)
def add_in_cache(self, concept: Concept): def add_in_cache(self, concept: Concept):
""" """
+11 -13
View File
@@ -15,19 +15,17 @@ class ConceptEvaluator(OneReturnValueEvaluator):
def __init__(self, return_body=False): 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 self.return_body = return_body
self.evaluate_body = False
self.is_initialized = False
def init_evaluator(self, context, return_values): # def init_evaluator(self, context, return_values):
if BuiltinConcepts.CONCEPT_EVAL_REQUESTED in context.extra_info: # if BuiltinConcepts.EVAL_BODY_REQUESTED in context.local_hints:
self.evaluate_body = True # self.evaluate_body = True
#
for r in return_values: # for r in return_values:
if r.status and context.sheerka.isinstance(r.body, BuiltinConcepts.CONCEPT_VALUE_REQUESTED): # if r.status and context.sheerka.isinstance(r.body, BuiltinConcepts.CONCEPT_VALUE_REQUESTED):
self.evaluate_body = True # self.evaluate_body = True
break # break
#
self.is_initialized = True # self.is_initialized = True
def matches(self, context, return_value): def matches(self, context, return_value):
return return_value.status and \ return return_value.status and \
@@ -49,7 +47,7 @@ class ConceptEvaluator(OneReturnValueEvaluator):
return sheerka.ret(self.name, True, value, parents=[return_value]) return sheerka.ret(self.name, True, value, parents=[return_value])
evaluated = sheerka.evaluate_concept(context, concept, self.evaluate_body) evaluated = sheerka.evaluate_concept(context, concept)
if evaluated.key != concept.key: if evaluated.key != concept.key:
# evaluated.key != concept.key means that we have transformed the concept # evaluated.key != concept.key means that we have transformed the concept
+5 -18
View File
@@ -12,16 +12,9 @@ class EvalEvaluator(AllReturnValuesEvaluator):
def __init__(self): def __init__(self):
super().__init__(self.NAME, [BuiltinConcepts.AFTER_EVALUATION], 80) super().__init__(self.NAME, [BuiltinConcepts.AFTER_EVALUATION], 80)
self.eval_requested = None
def matches(self, context, return_values): def matches(self, context, return_values):
sheerka = context.sheerka return context.in_context(BuiltinConcepts.CONCEPT_VALUE_REQUESTED)
for ret in return_values:
if ret.status and sheerka.isinstance(ret.body, BuiltinConcepts.CONCEPT_VALUE_REQUESTED):
self.eval_requested = ret
return True
return False
def eval(self, context, return_values): def eval(self, context, return_values):
sheerka = context.sheerka sheerka = context.sheerka
@@ -30,22 +23,16 @@ class EvalEvaluator(AllReturnValuesEvaluator):
for ret_val in return_values: for ret_val in return_values:
if ret_val.status and isinstance(ret_val.body, Concept) and ret_val.body.body: if ret_val.status and isinstance(ret_val.body, Concept) and ret_val.body.body:
context.log(f"Evaluating {ret_val.body}", who=self) context.log(f"Evaluating {ret_val.body}", who=self)
result.append(sheerka.ret(self.name, True, ret_val.body.body, parents=[ret_val, self.eval_requested])) result.append(sheerka.ret(self.name, True, ret_val.body.body, parents=[ret_val]))
elif ret_val.status and sheerka.isaset(context, ret_val.body): elif ret_val.status and sheerka.isaset(context, ret_val.body):
context.log(f"Evaluating set {ret_val.body}", who=self) context.log(f"Evaluating set {ret_val.body}", who=self)
result.append(sheerka.ret( result.append(sheerka.ret(
self.name, self.name,
True, True,
sheerka.get_set_elements(context, ret_val.body), sheerka.get_set_elements(context, ret_val.body),
parents=[ret_val, self.eval_requested])) parents=[ret_val]))
if len(result) > 0: if len(result) > 0:
return result return result
else:
# suppress the successful BuiltinConcepts.CONCEPT_EVAL_REQUESTED return None
# status of CONCEPT_EVAL_REQUESTED is now set to False
return sheerka.ret(
self.name,
False,
sheerka.new(BuiltinConcepts.CONCEPT_VALUE_REQUESTED),
parents=[self.eval_requested])
+3 -4
View File
@@ -33,8 +33,7 @@ class PrepareEvalEvaluator(OneReturnValueEvaluator):
self.name, self.name,
True, sheerka.new(BuiltinConcepts.USER_INPUT, body=self.text[5:], user_name=context.event.user)) True, sheerka.new(BuiltinConcepts.USER_INPUT, body=self.text[5:], user_name=context.event.user))
evaluation_requested = sheerka.ret( context.global_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
self.name, context.global_hints.add(BuiltinConcepts.CONCEPT_VALUE_REQUESTED)
True, sheerka.new(BuiltinConcepts.CONCEPT_VALUE_REQUESTED))
return [new_text_to_parse, evaluation_requested] return new_text_to_parse
+2 -1
View File
@@ -112,7 +112,8 @@ class PythonEvaluator(OneReturnValueEvaluator):
context.log(f"Evaluating '{concept}'", self.name) context.log(f"Evaluating '{concept}'", self.name)
with context.push(self.name, desc=f"Evaluating '{concept}'", obj=concept) as sub_context: with context.push(self.name, desc=f"Evaluating '{concept}'", obj=concept) as sub_context:
evaluated = context.sheerka.evaluate_concept(sub_context, concept, True) sub_context.local_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
evaluated = context.sheerka.evaluate_concept(sub_context, concept)
sub_context.add_values(return_values=evaluated) sub_context.add_values(return_values=evaluated)
if evaluated.key == concept.key: if evaluated.key == concept.key:
+1
View File
@@ -944,6 +944,7 @@ class ConceptLexerParser(BaseParser):
if _underlying.parsing_expression.rule_name: if _underlying.parsing_expression.rule_name:
value = _get_underlying_value(_underlying) value = _get_underlying_value(_underlying)
_add_prop(_concept, _underlying.parsing_expression.rule_name, value) _add_prop(_concept, _underlying.parsing_expression.rule_name, value)
_concept.metadata.need_validation = True
if isinstance(_underlying, NonTerminalNode): if isinstance(_underlying, NonTerminalNode):
for child in _underlying.children: for child in _underlying.children:
+3 -2
View File
@@ -41,21 +41,22 @@ class ExactConceptParser(BaseParser):
for combination in self.combinations(words): for combination in self.combinations(words):
concept_key = " ".join(combination) concept_key = " ".join(combination)
result = sheerka.new(concept_key) result = sheerka.new(concept_key) # use new(), not get() because we need a new instance
if sheerka.isinstance(result, BuiltinConcepts.UNKNOWN_CONCEPT): if sheerka.isinstance(result, BuiltinConcepts.UNKNOWN_CONCEPT):
continue continue
# concepts = result.body if sheerka.isinstance(result, BuiltinConcepts.ENUMERATION) else [result]
concepts = result if isinstance(result, list) else [result] concepts = result if isinstance(result, list) else [result]
for concept in concepts: for concept in concepts:
context.log(f"Recognized concept {concept}.", self.name) context.log(f"Recognized concept {concept}.", self.name)
# update the properties if needed # update the properties if needed
need_validation = False
for i, token in enumerate(combination): for i, token in enumerate(combination):
if token.startswith(VARIABLE_PREFIX): if token.startswith(VARIABLE_PREFIX):
index = int(token[len(VARIABLE_PREFIX):]) index = int(token[len(VARIABLE_PREFIX):])
concept.def_prop_by_index(index, words[i]) concept.def_prop_by_index(index, words[i])
concept.metadata.need_validation = True
if self.verbose_log.isEnabledFor(logging.DEBUG): if self.verbose_log.isEnabledFor(logging.DEBUG):
prop_name = list(concept.props.keys())[index] prop_name = list(concept.props.keys())[index]
context.log( context.log(
+9 -3
View File
@@ -1,6 +1,6 @@
import ast import ast
from core.builtin_concepts import ReturnValueConcept, ParserResultConcept from core.builtin_concepts import ReturnValueConcept, ParserResultConcept, BuiltinConcepts
from core.concept import Concept from core.concept import Concept
from core.sheerka.ExecutionContext import ExecutionContext from core.sheerka.ExecutionContext import ExecutionContext
from parsers.BnfParser import BnfParser from parsers.BnfParser import BnfParser
@@ -11,8 +11,14 @@ class BaseTest:
def get_sheerka(self, **kwargs): def get_sheerka(self, **kwargs):
pass pass
def get_context(self, sheerka=None): def get_context(self, sheerka=None, eval_body=False, eval_where=False):
return ExecutionContext("test", Event(), sheerka or self.get_sheerka()) context = ExecutionContext("test", Event(), sheerka or self.get_sheerka())
if eval_body:
context.local_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
if eval_where:
context.local_hints.add(BuiltinConcepts.EVAL_WHERE_REQUESTED)
return context
def get_default_concept(self): def get_default_concept(self):
concept = Concept( concept = Concept(
+30 -2
View File
@@ -34,7 +34,8 @@ def test_i_can_push():
concepts={"bar": Concept("bar")}) concepts={"bar": Concept("bar")})
a.preprocess = set() a.preprocess = set()
a.preprocess.add("preprocess") a.preprocess.add("preprocess")
a.extra_info.append(BuiltinConcepts.CONCEPT_EVAL_REQUESTED) a.local_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
a.global_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
b = a.push() b = a.push()
@@ -50,7 +51,8 @@ def test_i_can_push():
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 assert b.preprocess == a.preprocess
assert b.extra_info == [BuiltinConcepts.CONCEPT_EVAL_REQUESTED] assert b.local_hints == {BuiltinConcepts.EVAL_BODY_REQUESTED}
assert b.global_hints == a.global_hints
def test_children_i_created_when_i_push(): def test_children_i_created_when_i_push():
@@ -72,3 +74,29 @@ def test_i_can_add_variable_when_i_push():
assert sub_e.my_new_var == "new var value" assert sub_e.my_new_var == "new var value"
with pytest.raises(AttributeError): with pytest.raises(AttributeError):
assert e.my_new_var == "" # my_new_var does not exist in parent assert e.my_new_var == "" # my_new_var does not exist in parent
def test_local_hints_are_local_and_global_hints_are_global():
a = ExecutionContext("foo", Event("event_1"), "fake_sheerka")
a.local_hints.add("local hint 1")
a.global_hints.add("global hint 1")
b = a.push()
b.local_hints.add("local hint 2")
b.global_hints.add("global hint 2")
assert a.local_hints == {"local hint 1"}
assert a.global_hints == {"global hint 1", "global hint 2"}
assert b.local_hints == {"local hint 1", "local hint 2"}
assert b.global_hints == {"global hint 1", "global hint 2"}
def test_global_hits_are_global_even_when_empty():
a = ExecutionContext("foo", Event("event_1"), "fake_sheerka")
b = a.push()
b.global_hints.add("global hint 2")
assert a.global_hints == {"global hint 2"}
assert b.global_hints == {"global hint 2"}
+59 -39
View File
@@ -22,7 +22,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka = self.get_sheerka() sheerka = self.get_sheerka()
concept = Concept("foo", body=body).init_key() concept = Concept("foo", body=body).init_key()
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
assert evaluated.key == concept.key assert evaluated.key == concept.key
assert evaluated.body == expected assert evaluated.body == expected
@@ -80,7 +80,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka = self.get_sheerka() sheerka = self.get_sheerka()
concept = Concept("foo").def_prop("a", expr) concept = Concept("foo").def_prop("a", expr)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka,True), concept)
assert evaluated.key == concept.key assert evaluated.key == concept.key
assert evaluated.metadata.pre is None assert evaluated.metadata.pre is None
@@ -95,7 +95,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
concept = Concept("foo") concept = Concept("foo")
concept.compiled[ConceptParts.BODY] = DoNotResolve("do not resolve") concept.compiled[ConceptParts.BODY] = DoNotResolve("do not resolve")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
assert evaluated.body == "do not resolve" assert evaluated.body == "do not resolve"
assert evaluated.metadata.is_evaluated assert evaluated.metadata.is_evaluated
@@ -105,7 +105,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
concept = Concept("foo").def_prop("a") concept = Concept("foo").def_prop("a")
concept.compiled["a"] = DoNotResolve("do not resolve") concept.compiled["a"] = DoNotResolve("do not resolve")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
assert evaluated.get_prop("a") == "do not resolve" assert evaluated.get_prop("a") == "do not resolve"
assert evaluated.metadata.is_evaluated assert evaluated.metadata.is_evaluated
@@ -116,7 +116,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
concept.compiled["a"] = DoNotResolve("do not resolve") concept.compiled["a"] = DoNotResolve("do not resolve")
concept.compiled[ConceptParts.BODY] = DoNotResolve("do not resolve") concept.compiled[ConceptParts.BODY] = DoNotResolve("do not resolve")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
assert evaluated.body == "do not resolve" assert evaluated.body == "do not resolve"
assert evaluated.get_prop("a") == "do not resolve" assert evaluated.get_prop("a") == "do not resolve"
@@ -126,7 +126,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka = self.get_sheerka() sheerka = self.get_sheerka()
concept = Concept("foo", body="a+1").def_prop("a", "10").init_key() concept = Concept("foo", body="a+1").def_prop("a", "10").init_key()
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
assert evaluated.key == concept.key assert evaluated.key == concept.key
assert evaluated.body == 11 assert evaluated.body == 11
@@ -137,7 +137,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka.add_in_cache(concept_a) sheerka.add_in_cache(concept_a)
concept = Concept("foo", body="a").init_key() concept = Concept("foo", body="a").init_key()
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
assert evaluated == simplec("foo", simplec("a", None)) assert evaluated == simplec("foo", simplec("a", None))
assert id(evaluated.body) != id(concept_a) assert id(evaluated.body) != id(concept_a)
@@ -150,7 +150,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka.add_in_cache(concept_a) sheerka.add_in_cache(concept_a)
concept = Concept("foo", body="a") concept = Concept("foo", body="a")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
assert evaluated.key == concept.key assert evaluated.key == concept.key
assert evaluated.body == simplec("a", 1) assert evaluated.body == simplec("a", 1)
@@ -164,7 +164,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka.add_in_cache(Concept(name="c", body="b")) sheerka.add_in_cache(Concept(name="c", body="b"))
concept_d = sheerka.add_in_cache(Concept(name="d", body="c")) concept_d = sheerka.add_in_cache(Concept(name="d", body="c"))
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept_d, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept_d)
assert evaluated.key == concept_d.key assert evaluated.key == concept_d.key
expected = simplec("c", simplec("b", simplec("a", "a"))) expected = simplec("c", simplec("b", simplec("a", "a")))
@@ -179,7 +179,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka.add_in_cache(Concept(name="c", body="b")) sheerka.add_in_cache(Concept(name="c", body="b"))
concept_d = sheerka.add_in_cache(Concept(name="d", body="c")) concept_d = sheerka.add_in_cache(Concept(name="d", body="c"))
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept_d, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept_d)
assert evaluated.key == concept_d.key assert evaluated.key == concept_d.key
expected = simplec("c", simplec("b", simplec("a", None))) expected = simplec("c", simplec("b", simplec("a", None)))
@@ -192,7 +192,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
concept_a = sheerka.add_in_cache(Concept(name="a").init_key()) concept_a = sheerka.add_in_cache(Concept(name="a").init_key())
concept = Concept("foo", body="a").def_prop("a", "a").init_key() concept = Concept("foo", body="a").def_prop("a", "a").init_key()
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
# first prop a is evaluated to concept_a # first prop a is evaluated to concept_a
# then body is evaluated to prop a -> concept_a # then body is evaluated to prop a -> concept_a
@@ -209,7 +209,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
concept_a = sheerka.add_in_cache(Concept(name="a")) concept_a = sheerka.add_in_cache(Concept(name="a"))
concept = Concept("foo", body="concept_a").def_prop("concept_a", "a") concept = Concept("foo", body="concept_a").def_prop("concept_a", "a")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
assert evaluated.key == concept.key assert evaluated.key == concept.key
assert evaluated.body == concept_a assert evaluated.body == concept_a
@@ -220,7 +220,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka.add_in_cache(Concept(name="b", body="2")) sheerka.add_in_cache(Concept(name="b", body="2"))
concept = Concept("foo", body="propA + propB").def_prop("propA", "a").def_prop("propB", "b") concept = Concept("foo", body="propA + propB").def_prop("propA", "a").def_prop("propB", "b")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
assert evaluated.key == concept.key assert evaluated.key == concept.key
assert evaluated.body == 3 assert evaluated.body == 3
@@ -231,7 +231,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
concept = Concept("foo").def_prop("a") concept = Concept("foo").def_prop("a")
concept.compiled["a"] = concept_a concept.compiled["a"] = concept_a
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
assert evaluated.key == concept.key assert evaluated.key == concept.key
assert evaluated.get_prop("a") == simplec("a", "a") assert evaluated.get_prop("a") == simplec("a", "a")
@@ -242,7 +242,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
concept = Concept("to_eval").def_prop("prop") concept = Concept("to_eval").def_prop("prop")
concept.compiled["prop"] = [foo, DoNotResolve("1")] concept.compiled["prop"] = [foo, DoNotResolve("1")]
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
props = evaluated.get_prop("prop") props = evaluated.get_prop("prop")
assert len(props) == 2 assert len(props) == 2
@@ -257,20 +257,20 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
concept = Concept("to_eval").def_prop("prop") concept = Concept("to_eval").def_prop("prop")
concept.compiled["prop"] = [ReturnValueConcept("who", True, parser_result)] concept.compiled["prop"] = [ReturnValueConcept("who", True, parser_result)]
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
assert evaluated.get_prop("prop") == 2 assert evaluated.get_prop("prop") == 2
# also works when only one return value # also works when only one return value
concept = Concept("to_eval").def_prop("prop") concept = Concept("to_eval").def_prop("prop")
concept.compiled["prop"] = ReturnValueConcept("who", True, parser_result) concept.compiled["prop"] = ReturnValueConcept("who", True, parser_result)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
assert evaluated.get_prop("prop") == 2 assert evaluated.get_prop("prop") == 2
def test_i_can_reference_sheerka(self): def test_i_can_reference_sheerka(self):
sheerka = self.get_sheerka() sheerka = self.get_sheerka()
concept = Concept("foo", body="sheerka.test()").init_key() concept = Concept("foo", body="sheerka.test()").init_key()
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
assert evaluated.key == concept.key assert evaluated.key == concept.key
assert evaluated.body == sheerka.test() assert evaluated.body == sheerka.test()
@@ -281,19 +281,19 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka.add_in_cache(Concept(name="b", body="'concept_b'")) sheerka.add_in_cache(Concept(name="b", body="'concept_b'"))
concept = Concept("foo", body="a") concept = Concept("foo", body="a")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
assert evaluated.key == concept.key assert evaluated.key == concept.key
assert evaluated.body == simplec("a", "concept_a") # this test was already done assert evaluated.body == simplec("a", "concept_a") # this test was already done
# so check this one. # so check this one.
concept = Concept("foo", body="a").def_prop("a", "'property_a'") concept = Concept("foo", body="a").def_prop("a", "'property_a'")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
assert evaluated.key == concept.key assert evaluated.key == concept.key
assert evaluated.body == 'property_a' assert evaluated.body == 'property_a'
# or this one. # or this one.
concept = Concept("foo", body="a").def_prop("a", "b") concept = Concept("foo", body="a").def_prop("a", "b")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
assert evaluated.key == concept.key assert evaluated.key == concept.key
assert evaluated.body == simplec(name="b", body="concept_b") assert evaluated.body == simplec(name="b", body="concept_b")
@@ -303,7 +303,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka.add_in_cache(Concept(name="b", body="'concept_b'")) sheerka.add_in_cache(Concept(name="b", body="'concept_b'"))
concept = Concept("foo", body="a + b").def_prop("a", "'prop_a'").init_key() concept = Concept("foo", body="a + b").def_prop("a", "'prop_a'").init_key()
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
assert evaluated.key == concept.key assert evaluated.key == concept.key
assert evaluated.body == 'prop_aconcept_b' assert evaluated.body == 'prop_aconcept_b'
@@ -312,21 +312,21 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka.add_in_cache(Concept(name="concept_a").def_prop("subProp", "'sub_a'")) sheerka.add_in_cache(Concept(name="concept_a").def_prop("subProp", "'sub_a'"))
concept = Concept("foo", body="a.props['subProp'].value").def_prop("a", "concept_a") concept = Concept("foo", body="a.props['subProp'].value").def_prop("a", "concept_a")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
assert evaluated == simplec(concept.key, "sub_a") assert evaluated == simplec(concept.key, "sub_a")
def test_i_cannot_evaluate_concept_if_property_is_in_error(self): def test_i_cannot_evaluate_concept_if_property_is_in_error(self):
sheerka = self.get_sheerka() sheerka = self.get_sheerka()
concept = Concept(name="concept_a").def_prop("subProp", "undef_concept") concept = Concept(name="concept_a").def_prop("subProp", "undef_concept")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
assert sheerka.isinstance(evaluated, BuiltinConcepts.CONCEPT_EVAL_ERROR) assert sheerka.isinstance(evaluated, BuiltinConcepts.CONCEPT_EVAL_ERROR)
def test_key_is_initialized_by_evaluation(self): def test_key_is_initialized_by_evaluation(self):
sheerka = self.get_sheerka() sheerka = self.get_sheerka()
concept = Concept("foo") concept = Concept("foo")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
assert evaluated.key == concept.init_key().key assert evaluated.key == concept.init_key().key
@@ -345,7 +345,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
concept = Concept("foo", body="10", where=where_clause).def_prop("a", "20") concept = Concept("foo", body="10", where=where_clause).def_prop("a", "20")
sheerka.add_in_cache(concept) sheerka.add_in_cache(concept)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, False, True), concept)
if expected: if expected:
assert evaluated.key == concept.key assert evaluated.key == concept.key
@@ -362,14 +362,32 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka.add_in_cache(foo_true) sheerka.add_in_cache(foo_true)
concept = Concept("foo", where="foo_true").init_key() concept = Concept("foo", where="foo_true").init_key()
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, False, True), concept)
assert evaluated.key == concept.key assert evaluated.key == concept.key
concept = Concept("foo", where="foo_false") concept = Concept("foo", where="foo_false")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, False, True), concept)
assert sheerka.isinstance(evaluated, BuiltinConcepts.WHERE_CLAUSE_FAILED) assert sheerka.isinstance(evaluated, BuiltinConcepts.WHERE_CLAUSE_FAILED)
assert evaluated.body == concept assert evaluated.body == concept
concept = Concept("foo", where="foo_false").init_key()
evaluated = sheerka.evaluate_concept(self.get_context(sheerka, False, False), concept)
assert evaluated.key == concept.key
def test_i_can_evaluate_disable_where_clause_evaluation(self):
sheerka = self.get_sheerka()
concept = Concept("foo", body="10", where="a > 10").def_prop("a", None)
sheerka.add_in_cache(concept)
context = self.get_context(sheerka)
evaluated = sheerka.evaluate_concept(context, concept)
assert evaluated.key == concept.key
context.local_hints.add(BuiltinConcepts.EVAL_WHERE_REQUESTED)
evaluated = sheerka.evaluate_concept(context, concept)
assert sheerka.isinstance(evaluated, BuiltinConcepts.CONCEPT_EVAL_ERROR)
def test_i_can_detect_infinite_recursion_with_numeric_constant(self): def test_i_can_detect_infinite_recursion_with_numeric_constant(self):
sheerka = self.get_sheerka() sheerka = self.get_sheerka()
@@ -379,11 +397,11 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka.add_in_cache(one_str) sheerka.add_in_cache(one_str)
sheerka.add_in_cache(one_digit) sheerka.add_in_cache(one_digit)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), one_digit, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), one_digit)
assert evaluated.key == one_digit.key assert evaluated.key == one_digit.key
assert evaluated.body == InfiniteRecursionResolved(1) assert evaluated.body == InfiniteRecursionResolved(1)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), one_str, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), one_str)
assert evaluated.key == one_str.key assert evaluated.key == one_str.key
assert evaluated.body == InfiniteRecursionResolved(1) assert evaluated.body == InfiniteRecursionResolved(1)
@@ -396,11 +414,11 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka.add_in_cache(true_str) sheerka.add_in_cache(true_str)
sheerka.add_in_cache(true_bool) sheerka.add_in_cache(true_bool)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), true_str, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), true_str)
assert evaluated.key == true_str.key assert evaluated.key == true_str.key
assert evaluated.body == InfiniteRecursionResolved(True) assert evaluated.body == InfiniteRecursionResolved(True)
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), true_bool, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), true_bool)
assert evaluated.key == true_bool.key assert evaluated.key == true_bool.key
assert evaluated.body == InfiniteRecursionResolved(True) assert evaluated.body == InfiniteRecursionResolved(True)
@@ -413,7 +431,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
c4 = sheerka.add_in_cache(Concept("3", body="one")) c4 = sheerka.add_in_cache(Concept("3", body="one"))
for concept in (c1, c2, c3, c4): for concept in (c1, c2, c3, c4):
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), concept, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), concept)
assert evaluated.key == concept.key assert evaluated.key == concept.key
assert evaluated.body == InfiniteRecursionResolved(3) assert evaluated.body == InfiniteRecursionResolved(3)
@@ -425,19 +443,19 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
baz = sheerka.add_in_cache(Concept("baz", body="qux")) baz = sheerka.add_in_cache(Concept("baz", body="qux"))
qux = sheerka.add_in_cache(Concept("qux", body="foo")) qux = sheerka.add_in_cache(Concept("qux", body="foo"))
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), foo, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), foo)
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG) assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
assert evaluated.body == {foo, bar, baz, qux} assert evaluated.body == {foo, bar, baz, qux}
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), bar, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), bar)
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG) assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
assert evaluated.body == {foo, bar, baz, qux} assert evaluated.body == {foo, bar, baz, qux}
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), baz, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), baz)
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG) assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
assert evaluated.body == {foo, bar, baz, qux} assert evaluated.body == {foo, bar, baz, qux}
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), qux, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), qux)
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG) assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
assert evaluated.body == {foo, bar, baz, qux} assert evaluated.body == {foo, bar, baz, qux}
@@ -446,7 +464,7 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
foo = sheerka.add_in_cache(Concept("foo", body="foo")) foo = sheerka.add_in_cache(Concept("foo", body="foo"))
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), foo, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), foo)
assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG) assert sheerka.isinstance(evaluated, BuiltinConcepts.CHICKEN_AND_EGG)
assert evaluated.body == {foo} assert evaluated.body == {foo}
@@ -454,7 +472,9 @@ class TestSheerkaEvaluateConcept(TestUsingMemoryBasedSheerka):
sheerka = self.get_sheerka() sheerka = self.get_sheerka()
one = Concept("1", body="1") one = Concept("1", body="1")
evaluated = sheerka.evaluate_concept(self.get_context(sheerka), one, True) evaluated = sheerka.evaluate_concept(self.get_context(sheerka, True), one)
assert evaluated.key == one.key assert evaluated.key == one.key
assert evaluated.body == 1 assert evaluated.body == 1
+14 -40
View File
@@ -249,22 +249,16 @@ class TestSheerkaExecuteEvaluators(TestUsingMemoryBasedSheerka):
assert Out.debug_out == [ assert Out.debug_out == [
'__EVALUATION [0] priority20 - matches - target=foo', '__EVALUATION [0] priority20 - matches - target=foo',
'__EVALUATION [0] priority20 - eval - target=foo', '__EVALUATION [0] priority20 - eval - target=foo',
'__EVALUATION [0] priority20 - matches - target=__EVALUATION', "__EVALUATION [0] all_priority20 - matches - target=['foo']",
'__EVALUATION [0] priority20 - eval - target=__EVALUATION', "__EVALUATION [0] all_priority20 - eval - target=['foo']",
"__EVALUATION [0] all_priority20 - matches - target=['foo', '__EVALUATION']", "__EVALUATION [0] all_priority15 - matches - target=['foo']",
"__EVALUATION [0] all_priority20 - eval - target=['foo', '__EVALUATION']", "__EVALUATION [0] all_priority15 - eval - target=['foo']",
"__EVALUATION [0] all_priority15 - matches - target=['foo', '__EVALUATION']",
"__EVALUATION [0] all_priority15 - eval - target=['foo', '__EVALUATION']",
'__EVALUATION [0] priority15 - matches - target=foo', '__EVALUATION [0] priority15 - matches - target=foo',
'__EVALUATION [0] priority15 - eval - target=foo', '__EVALUATION [0] priority15 - eval - target=foo',
'__EVALUATION [0] priority15 - matches - target=__EVALUATION', "__EVALUATION [0] all_priority10 - matches - target=['foo']",
'__EVALUATION [0] priority15 - eval - target=__EVALUATION', "__EVALUATION [0] all_priority10 - eval - target=['foo']",
"__EVALUATION [0] all_priority10 - matches - target=['foo', '__EVALUATION']",
"__EVALUATION [0] all_priority10 - eval - target=['foo', '__EVALUATION']",
'__EVALUATION [0] priority10 - matches - target=foo', '__EVALUATION [0] priority10 - matches - target=foo',
'__EVALUATION [0] priority10 - eval - target=foo', '__EVALUATION [0] priority10 - eval - target=foo',
'__EVALUATION [0] priority10 - matches - target=__EVALUATION',
'__EVALUATION [0] priority10 - eval - target=__EVALUATION'
] ]
def test_that_predicate_is_checked_before_evaluation_for_one_return(self): def test_that_predicate_is_checked_before_evaluation_for_one_return(self):
@@ -279,10 +273,8 @@ class TestSheerkaExecuteEvaluators(TestUsingMemoryBasedSheerka):
'__EVALUATION [0] modifyFoo - matches - target=foo', '__EVALUATION [0] modifyFoo - matches - target=foo',
'__EVALUATION [0] modifyFoo - eval - target=foo', '__EVALUATION [0] modifyFoo - eval - target=foo',
'__EVALUATION [0] modifyFoo - matches - target=baz', '__EVALUATION [0] modifyFoo - matches - target=baz',
'__EVALUATION [0] modifyFoo - matches - target=__EVALUATION',
'__EVALUATION [1] modifyFoo - matches - target=bar', '__EVALUATION [1] modifyFoo - matches - target=bar',
'__EVALUATION [1] modifyFoo - matches - target=baz', '__EVALUATION [1] modifyFoo - matches - target=baz',
'__EVALUATION [1] modifyFoo - matches - target=__EVALUATION'
] ]
def test_that_predicate_is_checked_before_evaluation_for_all_return(self): def test_that_predicate_is_checked_before_evaluation_for_all_return(self):
@@ -293,8 +285,8 @@ class TestSheerkaExecuteEvaluators(TestUsingMemoryBasedSheerka):
Out.debug_out = [] Out.debug_out = []
sheerka.execute(self.get_context(sheerka), entries, [BuiltinConcepts.EVALUATION]) sheerka.execute(self.get_context(sheerka), entries, [BuiltinConcepts.EVALUATION])
assert Out.debug_out == [ assert Out.debug_out == [
"__EVALUATION [0] all_reduce_foobar - matches - target=['foo', 'bar', '__EVALUATION']", "__EVALUATION [0] all_reduce_foobar - matches - target=['foo', 'bar']",
"__EVALUATION [0] all_reduce_foobar - eval - target=['foo', 'bar', '__EVALUATION']", "__EVALUATION [0] all_reduce_foobar - eval - target=['foo', 'bar']",
"__EVALUATION [1] all_reduce_foobar - matches - target=['__SUCCESS']" "__EVALUATION [1] all_reduce_foobar - matches - target=['__SUCCESS']"
] ]
@@ -302,7 +294,7 @@ class TestSheerkaExecuteEvaluators(TestUsingMemoryBasedSheerka):
Out.debug_out = [] Out.debug_out = []
sheerka.execute(self.get_context(sheerka), entries, [BuiltinConcepts.EVALUATION]) sheerka.execute(self.get_context(sheerka), entries, [BuiltinConcepts.EVALUATION])
assert Out.debug_out == [ assert Out.debug_out == [
"__EVALUATION [0] all_reduce_foobar - matches - target=['foo', '__EVALUATION']" "__EVALUATION [0] all_reduce_foobar - matches - target=['foo']"
] ]
def test_evaluation_continue_until_no_more_modification(self): def test_evaluation_continue_until_no_more_modification(self):
@@ -317,23 +309,17 @@ class TestSheerkaExecuteEvaluators(TestUsingMemoryBasedSheerka):
'__EVALUATION [0] modifyFoo - matches - target=foo', '__EVALUATION [0] modifyFoo - matches - target=foo',
'__EVALUATION [0] modifyFoo - eval - target=foo', '__EVALUATION [0] modifyFoo - eval - target=foo',
'__EVALUATION [0] modifyFoo - matches - target=baz', '__EVALUATION [0] modifyFoo - matches - target=baz',
'__EVALUATION [0] modifyFoo - matches - target=__EVALUATION',
'__EVALUATION [0] modifyBar - matches - target=foo', '__EVALUATION [0] modifyBar - matches - target=foo',
'__EVALUATION [0] modifyBar - matches - target=baz', '__EVALUATION [0] modifyBar - matches - target=baz',
'__EVALUATION [0] modifyBar - matches - target=__EVALUATION',
'__EVALUATION [1] modifyFoo - matches - target=bar', '__EVALUATION [1] modifyFoo - matches - target=bar',
'__EVALUATION [1] modifyFoo - matches - target=baz', '__EVALUATION [1] modifyFoo - matches - target=baz',
'__EVALUATION [1] modifyFoo - matches - target=__EVALUATION',
'__EVALUATION [1] modifyBar - matches - target=bar', '__EVALUATION [1] modifyBar - matches - target=bar',
'__EVALUATION [1] modifyBar - eval - target=bar', '__EVALUATION [1] modifyBar - eval - target=bar',
'__EVALUATION [1] modifyBar - matches - target=baz', '__EVALUATION [1] modifyBar - matches - target=baz',
'__EVALUATION [1] modifyBar - matches - target=__EVALUATION',
'__EVALUATION [2] modifyFoo - matches - target=baz', '__EVALUATION [2] modifyFoo - matches - target=baz',
'__EVALUATION [2] modifyFoo - matches - target=baz', '__EVALUATION [2] modifyFoo - matches - target=baz',
'__EVALUATION [2] modifyFoo - matches - target=__EVALUATION',
'__EVALUATION [2] modifyBar - matches - target=baz', '__EVALUATION [2] modifyBar - matches - target=baz',
'__EVALUATION [2] modifyBar - matches - target=baz', '__EVALUATION [2] modifyBar - matches - target=baz',
'__EVALUATION [2] modifyBar - matches - target=__EVALUATION'
] ]
def test_evaluation_steps_are_respected(self): def test_evaluation_steps_are_respected(self):
@@ -347,8 +333,7 @@ class TestSheerkaExecuteEvaluators(TestUsingMemoryBasedSheerka):
assert Out.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 - eval - target=__BEFORE_EVALUATION']
def test_evaluation_multi_steps_are_respected(self): def test_evaluation_multi_steps_are_respected(self):
sheerka = self.get_sheerka() sheerka = self.get_sheerka()
@@ -362,12 +347,8 @@ class TestSheerkaExecuteEvaluators(TestUsingMemoryBasedSheerka):
assert Out.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 - eval - target=__BEFORE_EVALUATION',
'__EVALUATION [0] multiStep - matches - target=foo', '__EVALUATION [0] multiStep - matches - target=foo',
'__EVALUATION [0] multiStep - eval - target=foo', '__EVALUATION [0] multiStep - eval - target=foo',
'__EVALUATION [0] multiStep - matches - target=__EVALUATION',
'__EVALUATION [0] multiStep - eval - target=__EVALUATION'
] ]
def test_evaluators_can_be_pre_processed(self): def test_evaluators_can_be_pre_processed(self):
@@ -389,9 +370,7 @@ class TestSheerkaExecuteEvaluators(TestUsingMemoryBasedSheerka):
assert Out.debug_out == [ assert Out.debug_out == [
'__EVALUATION [0] modifyFoo - matches - target=foo', '__EVALUATION [0] modifyFoo - matches - target=foo',
'__EVALUATION [0] modifyFoo - eval - 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=bar',
'__EVALUATION [1] modifyFoo - matches - target=__EVALUATION'
] ]
def test_i_can_initialize_evaluator_if_initialize_evaluator_is_defined(self): def test_i_can_initialize_evaluator_if_initialize_evaluator_is_defined(self):
@@ -407,14 +386,12 @@ class TestSheerkaExecuteEvaluators(TestUsingMemoryBasedSheerka):
sheerka.execute(context, entries, [BuiltinConcepts.EVALUATION]) sheerka.execute(context, entries, [BuiltinConcepts.EVALUATION])
assert Out.debug_out == [ assert Out.debug_out == [
'__EVALUATION [0] init_once - matches - target=foo', '__EVALUATION [0] init_once - matches - target=foo',
"__EVALUATION [0] init_once - init_evaluator - target=['foo', 'bar', 'baz', '__EVALUATION']", "__EVALUATION [0] init_once - init_evaluator - target=['foo', 'bar', 'baz']",
'__EVALUATION [0] init_once - eval - target=foo', '__EVALUATION [0] init_once - eval - target=foo',
'__EVALUATION [0] init_once - matches - target=bar', '__EVALUATION [0] init_once - matches - target=bar',
'__EVALUATION [0] init_once - eval - target=bar', '__EVALUATION [0] init_once - eval - target=bar',
'__EVALUATION [0] init_once - matches - target=baz', '__EVALUATION [0] init_once - matches - target=baz',
'__EVALUATION [0] init_once - eval - target=baz', '__EVALUATION [0] init_once - eval - target=baz',
'__EVALUATION [0] init_once - matches - target=__EVALUATION',
'__EVALUATION [0] init_once - eval - target=__EVALUATION'
] ]
def test_i_can_initialize_evaluators_multiple_times(self): def test_i_can_initialize_evaluators_multiple_times(self):
@@ -430,15 +407,12 @@ class TestSheerkaExecuteEvaluators(TestUsingMemoryBasedSheerka):
sheerka.execute(context, entries, [BuiltinConcepts.EVALUATION]) sheerka.execute(context, entries, [BuiltinConcepts.EVALUATION])
assert Out.debug_out == [ assert Out.debug_out == [
'__EVALUATION [0] init_multiple - matches - target=foo', '__EVALUATION [0] init_multiple - matches - target=foo',
"__EVALUATION [0] init_multiple - init_evaluator - target=['foo', 'bar', 'baz', '__EVALUATION']", "__EVALUATION [0] init_multiple - init_evaluator - target=['foo', 'bar', 'baz']",
'__EVALUATION [0] init_multiple - eval - target=foo', '__EVALUATION [0] init_multiple - eval - target=foo',
'__EVALUATION [0] init_multiple - matches - target=bar', '__EVALUATION [0] init_multiple - matches - target=bar',
"__EVALUATION [0] init_multiple - init_evaluator - target=['foo', 'bar', 'baz', '__EVALUATION']", "__EVALUATION [0] init_multiple - init_evaluator - target=['foo', 'bar', 'baz']",
'__EVALUATION [0] init_multiple - eval - target=bar', '__EVALUATION [0] init_multiple - eval - target=bar',
'__EVALUATION [0] init_multiple - matches - target=baz', '__EVALUATION [0] init_multiple - matches - target=baz',
"__EVALUATION [0] init_multiple - init_evaluator - target=['foo', 'bar', 'baz', '__EVALUATION']", "__EVALUATION [0] init_multiple - init_evaluator - target=['foo', 'bar', 'baz']",
'__EVALUATION [0] init_multiple - eval - target=baz', '__EVALUATION [0] init_multiple - eval - target=baz',
'__EVALUATION [0] init_multiple - matches - target=__EVALUATION',
"__EVALUATION [0] init_multiple - init_evaluator - target=['foo', 'bar', 'baz', '__EVALUATION']",
'__EVALUATION [0] init_multiple - eval - target=__EVALUATION'
] ]
+3 -7
View File
@@ -20,7 +20,7 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
def test_i_can_evaluate_concept(self): def test_i_can_evaluate_concept(self):
context = self.get_context() context = self.get_context()
context.extra_info.append(BuiltinConcepts.CONCEPT_EVAL_REQUESTED) context.local_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
concept = Concept(name="foo", concept = Concept(name="foo",
where="True", where="True",
pre="2", pre="2",
@@ -28,7 +28,6 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
evaluator = ConceptEvaluator() evaluator = ConceptEvaluator()
item = self.pretval(concept) item = self.pretval(concept)
evaluator.init_evaluator(context, [item])
result = evaluator.eval(context, item) result = evaluator.eval(context, item)
assert result.who == evaluator.name assert result.who == evaluator.name
@@ -44,7 +43,7 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
def test_body_is_returned_when_defined_and_requested(self): def test_body_is_returned_when_defined_and_requested(self):
context = self.get_context() context = self.get_context()
context.extra_info.append(BuiltinConcepts.CONCEPT_EVAL_REQUESTED) context.local_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
concept = Concept(name="foo", concept = Concept(name="foo",
body="'I have a value'", body="'I have a value'",
where="True", where="True",
@@ -53,7 +52,6 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
evaluator = ConceptEvaluator(return_body=True) evaluator = ConceptEvaluator(return_body=True)
item = self.pretval(concept) item = self.pretval(concept)
evaluator.init_evaluator(context, [item])
result = evaluator.eval(context, item) result = evaluator.eval(context, item)
assert result.who == evaluator.name assert result.who == evaluator.name
@@ -71,7 +69,6 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
evaluator = ConceptEvaluator(return_body=False) # which is the default behaviour evaluator = ConceptEvaluator(return_body=False) # which is the default behaviour
item = self.pretval(concept) item = self.pretval(concept)
evaluator.init_evaluator(context, [item])
result = evaluator.eval(context, item) result = evaluator.eval(context, item)
assert result.who == evaluator.name assert result.who == evaluator.name
@@ -95,7 +92,7 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
def test_i_cannot_recognize_a_concept_if_one_of_the_prop_is_unknown(self): def test_i_cannot_recognize_a_concept_if_one_of_the_prop_is_unknown(self):
context = self.get_context() context = self.get_context()
context.extra_info.append(BuiltinConcepts.CONCEPT_EVAL_REQUESTED) context.local_hints.add(BuiltinConcepts.EVAL_BODY_REQUESTED)
context.sheerka.add_in_cache(Concept(name="one").init_key()) context.sheerka.add_in_cache(Concept(name="one").init_key())
concept_plus = context.sheerka.add_in_cache(Concept(name="a plus b") concept_plus = context.sheerka.add_in_cache(Concept(name="a plus b")
.def_prop("a", "one") .def_prop("a", "one")
@@ -103,7 +100,6 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
evaluator = ConceptEvaluator() evaluator = ConceptEvaluator()
item = self.pretval(concept_plus) item = self.pretval(concept_plus)
evaluator.init_evaluator(context, [item])
result = evaluator.eval(context, item) result = evaluator.eval(context, item)
assert not result.status assert not result.status
+19 -31
View File
@@ -5,8 +5,6 @@ from core.concept import Concept
from evaluators.EvalEvaluator import EvalEvaluator from evaluators.EvalEvaluator import EvalEvaluator
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
value_requested = ReturnValueConcept("some_name", True, Concept(key=BuiltinConcepts.CONCEPT_VALUE_REQUESTED))
def retval(obj, who="who", status=True): def retval(obj, who="who", status=True):
"""ret_val""" """ret_val"""
@@ -16,6 +14,7 @@ def retval(obj, who="who", status=True):
class TestEvalEvaluator(TestUsingMemoryBasedSheerka): class TestEvalEvaluator(TestUsingMemoryBasedSheerka):
def test_i_can_match_and_eval(self): def test_i_can_match_and_eval(self):
context = self.get_context() context = self.get_context()
context.global_hints.add(BuiltinConcepts.CONCEPT_VALUE_REQUESTED)
to_eval1 = ReturnValueConcept("some_name", True, Concept(name="2", body="to eval").auto_init()) to_eval1 = ReturnValueConcept("some_name", True, Concept(name="2", body="to eval").auto_init())
to_eval2 = ReturnValueConcept("some_name", True, Concept(name="3", body="also to eval").auto_init()) to_eval2 = ReturnValueConcept("some_name", True, Concept(name="3", body="also to eval").auto_init())
@@ -26,7 +25,6 @@ class TestEvalEvaluator(TestUsingMemoryBasedSheerka):
ReturnValueConcept("some_name", False, Concept(name="1", body="'not to eval'")), ReturnValueConcept("some_name", False, Concept(name="1", body="'not to eval'")),
to_eval1, to_eval1,
to_eval2, to_eval2,
value_requested
] ]
evaluator = EvalEvaluator() evaluator = EvalEvaluator()
@@ -35,41 +33,35 @@ class TestEvalEvaluator(TestUsingMemoryBasedSheerka):
evaluated = evaluator.eval(context, return_values) evaluated = evaluator.eval(context, return_values)
assert len(evaluated) == 2 assert len(evaluated) == 2
assert evaluated[0].value == to_eval1.body.body assert evaluated[0].value == to_eval1.body.body
assert evaluated[0].parents == [to_eval1, value_requested] assert evaluated[0].parents == [to_eval1]
assert evaluated[1].value == to_eval2.body.body assert evaluated[1].value == to_eval2.body.body
assert evaluated[1].parents == [to_eval2, value_requested] assert evaluated[1].parents == [to_eval2]
@pytest.mark.parametrize("return_values, expected", [ @pytest.mark.parametrize("return_value", [
([retval(Concept("foo", body="bar")), value_requested], True), retval(Concept("foo", body="bar")),
([retval(Concept("status is false", body="bar"), status=False), value_requested], True), retval(Concept("status is false", body="bar"), status=False),
([retval("string_value"), value_requested], True), retval("string_value"),
([retval(Concept("no body")), value_requested], True), retval(Concept("no body")),
([retval(Concept("eval requested missing", body="bar"))], False),
]) ])
def test_i_cannot_match_if_eval_request_is_not_present(self, return_values, expected): def test_i_cannot_match_if_eval_request_is_not_present(self, return_value):
context = self.get_context() context = self.get_context()
assert EvalEvaluator().matches(context, return_values) == expected assert not EvalEvaluator().matches(context, [return_value])
context.global_hints.add(BuiltinConcepts.CONCEPT_VALUE_REQUESTED)
assert EvalEvaluator().matches(context, [return_value])
def test_concept_eval_requested_is_reduced_when_nothing_to_reduce(self): def test_concept_eval_requested_is_reduced_when_nothing_to_reduce(self):
context = self.get_context() context = self.get_context()
return_values = [ return_values = [
ReturnValueConcept("some_name", True, "not to eval"), ReturnValueConcept("some_name", True, "not to eval"), # not a concept
ReturnValueConcept("some_name", True, Concept(name="not to eval")), ReturnValueConcept("some_name", True, Concept(name="not to eval")), # no body
ReturnValueConcept("some_name", False, Concept(name="1", body="not to eval")), ReturnValueConcept("some_name", False, Concept(name="1", body="not to eval")), # no evaluated body
value_requested
] ]
evaluator = EvalEvaluator() evaluated = EvalEvaluator().eval(context, return_values)
assert evaluator.matches(context, return_values) assert evaluated is None
evaluated = evaluator.eval(context, return_values)
assert evaluated == ReturnValueConcept(
"evaluators.Eval",
False,
context.sheerka.new(BuiltinConcepts.CONCEPT_VALUE_REQUESTED))
assert evaluated.parents == [value_requested]
def test_i_can_evaluate_sets(self): def test_i_can_evaluate_sets(self):
sheerka, context, foo, bar, baz, number = self.init_concepts( sheerka, context, foo, bar, baz, number = self.init_concepts(
@@ -79,11 +71,7 @@ class TestEvalEvaluator(TestUsingMemoryBasedSheerka):
Concept("number")) Concept("number"))
sheerka.sets_handler.add_concepts_to_set(context, [foo, bar, baz], number) sheerka.sets_handler.add_concepts_to_set(context, [foo, bar, baz], number)
return_values = [retval(number), value_requested] evaluated = EvalEvaluator().eval(context, [retval(number)])
evaluator = EvalEvaluator()
evaluator.matches(context, return_values)
evaluated = evaluator.eval(context, return_values)
assert len(evaluated) == 1 assert len(evaluated) == 1
assert evaluated[0].status assert evaluated[0].status
@@ -40,10 +40,9 @@ class TestPrepareEvalEvaluator(TestUsingMemoryBasedSheerka):
prepare_evaluator.matches(context, ret_val) prepare_evaluator.matches(context, ret_val)
res = prepare_evaluator.eval(context, ret_val) res = prepare_evaluator.eval(context, ret_val)
assert len(res) == 2 assert res.status
assert res[0].status assert sheerka.isinstance(res.body, BuiltinConcepts.USER_INPUT)
assert sheerka.isinstance(res[0].body, BuiltinConcepts.USER_INPUT) assert res.body.body == expected
assert res[0].body.body == expected
assert res[1].status assert BuiltinConcepts.EVAL_BODY_REQUESTED in context.global_hints
assert sheerka.isinstance(res[1].body, BuiltinConcepts.CONCEPT_VALUE_REQUESTED) assert BuiltinConcepts.CONCEPT_VALUE_REQUESTED in context.global_hints
+23 -18
View File
@@ -36,7 +36,7 @@ class TestSheerkaNonReg(TestUsingFileBasedSheerka):
assert res[0].value == concept assert res[0].value == concept
# sanity check # sanity check
evaluated = sheerka.evaluate_concept(self.get_context(), res[0].value, True) evaluated = sheerka.evaluate_concept(self.get_context(eval_body=True), res[0].value)
assert evaluated == simplec("one", 1) assert evaluated == simplec("one", 1)
def test_i_can_recognize_concept_with_concept_body(self): def test_i_can_recognize_concept_with_concept_body(self):
@@ -53,7 +53,7 @@ class TestSheerkaNonReg(TestUsingFileBasedSheerka):
assert return_value == concept_un assert return_value == concept_un
# sanity check # sanity check
evaluated = sheerka.evaluate_concept(self.get_context(), return_value, True) evaluated = sheerka.evaluate_concept(self.get_context(eval_body=True), return_value)
assert evaluated == simplec("un", simplec("one", None)) assert evaluated == simplec("un", simplec("one", None))
def test_i_can_recognize_concept_with_no_body(self): def test_i_can_recognize_concept_with_no_body(self):
@@ -194,7 +194,7 @@ as:
assert return_value.metadata.props[0] == ('a', "foo") assert return_value.metadata.props[0] == ('a', "foo")
# sanity check # sanity check
evaluated = sheerka.evaluate_concept(self.get_context(), return_value, True) evaluated = sheerka.evaluate_concept(self.get_context(eval_body=True), return_value)
assert evaluated.props["a"].value == concept_foo assert evaluated.props["a"].value == concept_foo
def test_i_can_recognize_concept_with_variable_and_python_as_body(self): def test_i_can_recognize_concept_with_variable_and_python_as_body(self):
@@ -208,7 +208,7 @@ as:
assert sheerka.isinstance(res[0].value, hello_a) assert sheerka.isinstance(res[0].value, hello_a)
# sanity check # sanity check
evaluated = sheerka.evaluate_concept(self.get_context(), res[0].value, True) evaluated = sheerka.evaluate_concept(self.get_context(eval_body=True), res[0].value)
assert evaluated.body == "hello foo" assert evaluated.body == "hello foo"
assert evaluated.metadata.is_evaluated assert evaluated.metadata.is_evaluated
assert evaluated.props["a"].value == simplec("foo", "foo") assert evaluated.props["a"].value == simplec("foo", "foo")
@@ -323,7 +323,7 @@ as:
assert sheerka.isinstance(return_value, concept_b) assert sheerka.isinstance(return_value, concept_b)
# sanity check # sanity check
evaluated = sheerka.evaluate_concept(self.get_context(), return_value, True) evaluated = sheerka.evaluate_concept(self.get_context(eval_body=True), return_value)
assert evaluated.body == "one three" assert evaluated.body == "one three"
assert evaluated.metadata.is_evaluated assert evaluated.metadata.is_evaluated
assert evaluated.props["a"] == Property("a", sheerka.new(concept_a.key, body="one").init_key()) assert evaluated.props["a"] == Property("a", sheerka.new(concept_a.key, body="one").init_key())
@@ -355,7 +355,7 @@ as:
assert res[0].status assert res[0].status
assert sheerka.isinstance(res[0].value, concept_b) assert sheerka.isinstance(res[0].value, concept_b)
evaluated = sheerka.evaluate_concept(self.get_context(), res[0].value, True) evaluated = sheerka.evaluate_concept(self.get_context(eval_body=True), res[0].value)
assert evaluated.body == "one two three" assert evaluated.body == "one two three"
assert evaluated.props["a"] == Property("a", sheerka.new(concept_a.key, body="one two").init_key()) assert evaluated.props["a"] == Property("a", sheerka.new(concept_a.key, body="one two").init_key())
@@ -406,7 +406,7 @@ as:
assert len(res) == 1 assert len(res) == 1
assert res[0].status assert res[0].status
assert sheerka.isinstance(res[0].body, "twenties") assert sheerka.isinstance(res[0].body, "twenties")
assert sheerka.evaluate_concept(self.get_context(), res[0].body, True).body == 21 assert sheerka.evaluate_concept(self.get_context(eval_body=True), res[0].body).body == 21
res = sheerka.evaluate_user_input("twenty one + 1") res = sheerka.evaluate_user_input("twenty one + 1")
assert len(res) == 1 assert len(res) == 1
@@ -450,7 +450,7 @@ as:
assert len(res) == 1 assert len(res) == 1
assert res[0].status assert res[0].status
assert sheerka.isinstance(res[0].body, "twenties") assert sheerka.isinstance(res[0].body, "twenties")
assert sheerka.evaluate_concept(self.get_context(), res[0].value, True).body == 21 assert sheerka.evaluate_concept(self.get_context(eval_body=True), res[0].value).body == 21
res = sheerka.evaluate_user_input("twenty one + 1") res = sheerka.evaluate_user_input("twenty one + 1")
assert len(res) == 1 assert len(res) == 1
@@ -695,8 +695,15 @@ as:
res = sheerka.evaluate_user_input("eval twenty two") res = sheerka.evaluate_user_input("eval twenty two")
assert len(res) == 1 and res[0].status and res[0].body == 22 assert len(res) == 1 and res[0].status and res[0].body == 22
res = sheerka.evaluate_user_input("twenty three")
assert len(res) == 1
assert not res[0].status
assert sheerka.isinstance(res[0].body, BuiltinConcepts.WHERE_CLAUSE_FAILED)
res = sheerka.evaluate_user_input("eval twenty three") res = sheerka.evaluate_user_input("eval twenty three")
assert len(res) > 1 assert len(res) == 1
assert not res[0].status
assert sheerka.isinstance(res[0].body, BuiltinConcepts.WHERE_CLAUSE_FAILED)
# def test_i_can_detect_when_only_one_evaluator_is_in_error(self): # def test_i_can_detect_when_only_one_evaluator_is_in_error(self):
# sheerka = self.get_sheerka() # sheerka = self.get_sheerka()
@@ -722,10 +729,7 @@ as:
assert res[0].status assert res[0].status
assert res[0].body == 2 assert res[0].body == 2
@pytest.mark.xfail
def test_i_can_evaluate_bnf_concept_with_where_clause(self): def test_i_can_evaluate_bnf_concept_with_where_clause(self):
sheerka = self.get_sheerka() sheerka = self.get_sheerka()
sheerka.evaluate_user_input("def concept a from bnf 'bar' | 'baz'") sheerka.evaluate_user_input("def concept a from bnf 'bar' | 'baz'")
@@ -741,7 +745,7 @@ as:
res = sheerka.evaluate_user_input("eval foo bar") res = sheerka.evaluate_user_input("eval foo bar")
assert len(res) == 1 assert len(res) == 1
assert res[0].status assert res[0].status
assert res[0].body.body == "hello world" assert res[0].body == "hello world"
res = sheerka.evaluate_user_input("foo baz") res = sheerka.evaluate_user_input("foo baz")
assert len(res) == 1 assert len(res) == 1
@@ -749,17 +753,18 @@ as:
assert sheerka.isinstance(res[0].body, BuiltinConcepts.WHERE_CLAUSE_FAILED) assert sheerka.isinstance(res[0].body, BuiltinConcepts.WHERE_CLAUSE_FAILED)
res = sheerka.evaluate_user_input("eval foo baz") res = sheerka.evaluate_user_input("eval foo baz")
assert len(res) > 1 assert len(res) == 1
assert not res[0].status
assert sheerka.isinstance(res[0].body, BuiltinConcepts.WHERE_CLAUSE_FAILED)
# The following test fails
# the Where clause is evaluated while it should not
res = sheerka.evaluate_user_input("foobar") res = sheerka.evaluate_user_input("foobar")
assert len(res) == 1 assert len(res) == 1
assert res[0].status assert res[0].status
res = sheerka.evaluate_user_input("eval foobar") res = sheerka.evaluate_user_input("eval foobar")
assert len(res) > 1 # error assert len(res) == 1 # error
assert res[0].status assert not res[0].status
assert sheerka.isinstance(res[0].body, BuiltinConcepts.WHERE_CLAUSE_FAILED)
def test_i_can_say_than_bnf_concept_isa_another_concept(self): def test_i_can_say_than_bnf_concept_isa_another_concept(self):
sheerka = self.get_sheerka() sheerka = self.get_sheerka()
+22
View File
@@ -1225,6 +1225,28 @@ class TestConceptLexerParser(TestUsingMemoryBasedSheerka):
OneOrMore(ConceptExpression(baz, rule_name="baz")), rule_name="oc"), rule_name="s") OneOrMore(ConceptExpression(baz, rule_name="baz")), rule_name="oc"), rule_name="s")
assert parse_res.value.value == expected assert parse_res.value.value == expected
def test_i_concept_validation_is_not_set_when_no_variables(self):
foo = Concept(name="foo")
grammar = {foo: "foo"}
context, res, wrapper, return_value = self.execute([foo], grammar, "foo")
assert not return_value[0].concept.metadata.need_validation
def test_i_concept_validation_is_set_when_unnamed_variables_are_found(self):
foo = Concept(name="foo")
grammar = {foo: Sequence("foo", OrderedChoice("a", "b"))}
context, res, wrapper, return_value = self.execute([foo], grammar, "foo a")
assert not return_value[0].concept.metadata.need_validation
def test_i_concept_validation_is_set_when_named_variables_are_found(self):
foo = Concept(name="foo")
grammar = {foo: Sequence("foo", OrderedChoice("a", "b", rule_name="var"))}
context, res, wrapper, return_value = self.execute([foo], grammar, "foo a")
assert return_value[0].concept.metadata.need_validation
# #
# def test_i_can_parse_basic_arithmetic_operations_and_resolve_properties(self): # def test_i_can_parse_basic_arithmetic_operations_and_resolve_properties(self):
# context = self.get_context() # context = self.get_context()
@@ -93,7 +93,7 @@ class TestConceptsWithConceptsParser(TestUsingMemoryBasedSheerka):
assert return_value.compiled["b"] == bar assert return_value.compiled["b"] == bar
# sanity check, I can evaluate the result # sanity check, I can evaluate the result
evaluated = context.sheerka.evaluate_concept(context, return_value, True) evaluated = context.sheerka.evaluate_concept(self.get_context(context.sheerka, True), return_value)
assert evaluated.key == return_value.key assert evaluated.key == return_value.key
assert evaluated.get_prop("a") == foo.init_key() assert evaluated.get_prop("a") == foo.init_key()
assert evaluated.get_prop("b") == bar.init_key() assert evaluated.get_prop("b") == bar.init_key()
@@ -116,7 +116,7 @@ class TestConceptsWithConceptsParser(TestUsingMemoryBasedSheerka):
assert return_value.compiled["b"] == [ReturnValueConcept(parser.name, True, right_parser_result)] assert return_value.compiled["b"] == [ReturnValueConcept(parser.name, True, right_parser_result)]
# sanity check, I can evaluate the result # sanity check, I can evaluate the result
evaluated = context.sheerka.evaluate_concept(context, return_value, True) evaluated = context.sheerka.evaluate_concept(self.get_context(context.sheerka, True), return_value)
assert evaluated.key == return_value.key assert evaluated.key == return_value.key
assert evaluated.get_prop("a") == 2 assert evaluated.get_prop("a") == 2
assert evaluated.get_prop("b") == 4 assert evaluated.get_prop("b") == 4
@@ -139,7 +139,7 @@ class TestConceptsWithConceptsParser(TestUsingMemoryBasedSheerka):
assert return_value.compiled["b"] == [ReturnValueConcept(parser.name, True, code_parser_result)] assert return_value.compiled["b"] == [ReturnValueConcept(parser.name, True, code_parser_result)]
# sanity check, I can evaluate the result # sanity check, I can evaluate the result
evaluated = context.sheerka.evaluate_concept(context, return_value, True) evaluated = context.sheerka.evaluate_concept(self.get_context(context.sheerka, True), return_value)
assert evaluated.key == return_value.key assert evaluated.key == return_value.key
assert evaluated.get_prop("a") == foo.init_key() assert evaluated.get_prop("a") == foo.init_key()
assert evaluated.get_prop("b") == 2 assert evaluated.get_prop("b") == 2
+10 -1
View File
@@ -56,10 +56,12 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
source = "hello world" source = "hello world"
results = ExactConceptParser().parse(context, source) results = ExactConceptParser().parse(context, source)
concept_found = results[0].value.value
assert len(results) == 1 assert len(results) == 1
assert results[0].status assert results[0].status
assert results[0].value.value == concept assert concept_found == concept
assert not concept_found.metadata.need_validation
def test_i_can_recognize_concepts_defined_several_times(self): def test_i_can_recognize_concepts_defined_several_times(self):
context = self.get_context() context = self.get_context()
@@ -75,9 +77,11 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
assert results[0].status assert results[0].status
assert results[0].value.value.name == "hello a" assert results[0].value.value.name == "hello a"
assert metadata_prop(results[0].value.value, "a") == "world" assert metadata_prop(results[0].value.value, "a") == "world"
assert results[0].value.value.metadata.need_validation
assert results[1].status assert results[1].status
assert results[1].value.value.name == "hello world" assert results[1].value.value.name == "hello world"
assert not results[1].value.value.metadata.need_validation
def test_i_can_recognize_a_concept_with_variables(self): def test_i_can_recognize_a_concept_with_variables(self):
context = self.get_context() context = self.get_context()
@@ -88,10 +92,12 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
assert len(results) == 1 assert len(results) == 1
assert results[0].status assert results[0].status
concept_found = results[0].value.value concept_found = results[0].value.value
assert concept_found.key == concept.key assert concept_found.key == concept.key
assert metadata_prop(concept_found, "a") == "10" assert metadata_prop(concept_found, "a") == "10"
assert metadata_prop(concept_found, "b") == "5" assert metadata_prop(concept_found, "b") == "5"
assert concept_found.metadata.need_validation
def test_i_can_recognize_a_concept_with_duplicate_variables(self): def test_i_can_recognize_a_concept_with_duplicate_variables(self):
context = self.get_context() context = self.get_context()
@@ -102,10 +108,12 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
assert len(results) == 1 assert len(results) == 1
assert results[0].status assert results[0].status
concept_found = results[0].value.value concept_found = results[0].value.value
assert concept_found.key == concept.key assert concept_found.key == concept.key
assert metadata_prop(concept_found, "a") == "10" assert metadata_prop(concept_found, "a") == "10"
assert metadata_prop(concept_found, "b") == "5" assert metadata_prop(concept_found, "b") == "5"
assert concept_found.metadata.need_validation
def test_i_can_manage_unknown_concept(self): def test_i_can_manage_unknown_concept(self):
context = self.get_context() context = self.get_context()
@@ -136,3 +144,4 @@ class TestExactConceptParser(TestUsingMemoryBasedSheerka):
assert len(results) == 1 assert len(results) == 1
assert results[0].status assert results[0].status
assert results[0].value.value == concept assert results[0].value.value == concept
assert not results[0].value.value.metadata.need_validation