Refactored sheerka class: splitted to use sub handlers. Refactored unit tests to use classes.
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
import ast
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import ReturnValueConcept, ParserResultConcept, BuiltinConcepts
|
||||
from core.concept import VARIABLE_PREFIX, Concept
|
||||
from core.tokenizer import Tokenizer
|
||||
from evaluators.AddConceptEvaluator import AddConceptEvaluator
|
||||
from parsers.BaseParser import BaseParser
|
||||
from parsers.ConceptLexerParser import Sequence, StrMatch, ZeroOrMore, ConceptExpression
|
||||
from parsers.BnfParser import BnfParser
|
||||
from parsers.DefaultParser import DefConceptNode, NameNode
|
||||
from parsers.PythonParser import PythonNode, PythonParser
|
||||
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
|
||||
|
||||
@staticmethod
|
||||
def get_concept_part(part):
|
||||
if isinstance(part, str):
|
||||
node = PythonNode(part, ast.parse(part, mode="eval"))
|
||||
return ReturnValueConcept(
|
||||
who="parsers.Default",
|
||||
status=True,
|
||||
value=ParserResultConcept(
|
||||
source=part,
|
||||
parser=PythonParser(),
|
||||
value=node))
|
||||
|
||||
if isinstance(part, PythonNode):
|
||||
return ReturnValueConcept(
|
||||
who="parsers.Default",
|
||||
status=True,
|
||||
value=ParserResultConcept(
|
||||
source=part.source,
|
||||
parser=PythonParser(),
|
||||
value=part))
|
||||
|
||||
if isinstance(part, ReturnValueConcept):
|
||||
return part
|
||||
|
||||
@staticmethod
|
||||
def get_return_value(source, parsing_expression):
|
||||
return ReturnValueConcept(
|
||||
who="Parsers:RegexParser",
|
||||
status=True,
|
||||
value=ParserResultConcept(
|
||||
source=source,
|
||||
parser=BnfParser(),
|
||||
value=parsing_expression
|
||||
)
|
||||
)
|
||||
|
||||
def get_def_concept(self, name, where=None, pre=None, post=None, body=None, definition=None):
|
||||
concept = DefConceptNode([], name=NameNode(list(Tokenizer(name))))
|
||||
|
||||
if body:
|
||||
concept.body = self.get_concept_part(body)
|
||||
if where:
|
||||
concept.where = self.get_concept_part(where)
|
||||
if pre:
|
||||
concept.pre = self.get_concept_part(pre)
|
||||
if post:
|
||||
concept.post = self.get_concept_part(post)
|
||||
if definition:
|
||||
concept.definition = definition
|
||||
|
||||
return ReturnValueConcept(BaseParser.PREFIX + "some_name", True, ParserResultConcept(value=concept))
|
||||
|
||||
@pytest.mark.parametrize("ret_val, expected", [
|
||||
(
|
||||
ReturnValueConcept(BaseParser.PREFIX + "some_name", True, ParserResultConcept(value=DefConceptNode([]))),
|
||||
True),
|
||||
(ReturnValueConcept(BaseParser.PREFIX + "some_name", False, ParserResultConcept(value=DefConceptNode([]))),
|
||||
False),
|
||||
(ReturnValueConcept(BaseParser.PREFIX + "some_name", True, "not a ParserResultConcept"), False),
|
||||
(ReturnValueConcept(BaseParser.PREFIX + "some_name", True, ParserResultConcept()), False),
|
||||
])
|
||||
def test_i_can_match(self, ret_val, expected):
|
||||
context = self.get_context()
|
||||
assert AddConceptEvaluator().matches(context, ret_val) == expected
|
||||
|
||||
def test_that_the_source_is_correctly_set(self):
|
||||
context = self.get_context()
|
||||
def_concept_return_value = self.get_def_concept(
|
||||
name="hello a",
|
||||
definition=self.get_return_value("hello a", Sequence(StrMatch("hello"), StrMatch("a"))),
|
||||
where="isinstance(a, str )",
|
||||
pre="a is not None",
|
||||
body="print('hello' + a)")
|
||||
|
||||
evaluated = AddConceptEvaluator().eval(context, def_concept_return_value)
|
||||
|
||||
assert evaluated.status
|
||||
assert context.sheerka.isinstance(evaluated.body, BuiltinConcepts.NEW_CONCEPT)
|
||||
|
||||
created_concept = evaluated.body.body
|
||||
assert created_concept.metadata.name == "hello a"
|
||||
assert created_concept.metadata.where == "isinstance(a, str )"
|
||||
assert created_concept.metadata.pre == "a is not None"
|
||||
assert created_concept.metadata.post is None
|
||||
assert created_concept.metadata.body == "print('hello' + a)"
|
||||
assert created_concept.metadata.definition == "hello a"
|
||||
|
||||
def test_that_the_new_concept_is_correctly_saved_in_db(self):
|
||||
context = self.get_context()
|
||||
def_concept_return_value = self.get_def_concept(
|
||||
name="hello a",
|
||||
definition=self.get_return_value("hello a", Sequence(StrMatch("hello"), StrMatch("a"))),
|
||||
where="isinstance(a, str )",
|
||||
pre="a is not None",
|
||||
body="print('hello' + a)")
|
||||
|
||||
# sanity. Make sure that the concept does not already exist
|
||||
from_db = context.sheerka.get("hello " + VARIABLE_PREFIX + "0")
|
||||
assert context.sheerka.isinstance(from_db, BuiltinConcepts.UNKNOWN_CONCEPT)
|
||||
|
||||
AddConceptEvaluator().eval(context, def_concept_return_value)
|
||||
context.sheerka.concepts_cache = {} # reset cache
|
||||
from_db = context.sheerka.get("hello " + VARIABLE_PREFIX + "0")
|
||||
|
||||
assert from_db.metadata.key == f"hello {VARIABLE_PREFIX}0"
|
||||
assert from_db.metadata.name == "hello a"
|
||||
assert from_db.metadata.where == "isinstance(a, str )"
|
||||
assert from_db.metadata.pre == "a is not None"
|
||||
assert from_db.metadata.post is None
|
||||
assert from_db.metadata.body == "print('hello' + a)"
|
||||
assert from_db.metadata.definition == "hello a"
|
||||
assert len(from_db.metadata.props) == 1
|
||||
assert from_db.metadata.props[0] == ("a", None)
|
||||
assert "a" in from_db.props
|
||||
|
||||
assert from_db.compiled == {} # ast is not saved in db
|
||||
|
||||
def test_i_can_get_props_from_python_node(self):
|
||||
ret_val = self.get_concept_part("isinstance(a, str)")
|
||||
context = self.get_context()
|
||||
|
||||
assert AddConceptEvaluator.get_props(context.sheerka, ret_val, ["a"]) == ["a"]
|
||||
|
||||
def test_i_can_get_props_from_another_concept(self):
|
||||
concept = Concept("hello").def_prop("a").def_prop("b")
|
||||
ret_val = ReturnValueConcept(who="some_parser",
|
||||
status=True,
|
||||
value=ParserResultConcept(value=concept))
|
||||
|
||||
assert AddConceptEvaluator.get_props(self.get_context(), ret_val, []) == ["a", "b"]
|
||||
|
||||
def test_i_can_get_props_from_definition(self):
|
||||
parsing_expression = Sequence(ConceptExpression('mult'),
|
||||
ZeroOrMore(Sequence(StrMatch("+"), ConceptExpression("add"))))
|
||||
ret_val = self.get_return_value("mult (('+'|'-') add)?", parsing_expression)
|
||||
|
||||
assert AddConceptEvaluator.get_props(self.get_context(), ret_val, []) == ["add", "mult"]
|
||||
@@ -0,0 +1,102 @@
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import ReturnValueConcept, ParserResultConcept, BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from core.tokenizer import Tokenizer
|
||||
from evaluators.AddConceptInSetEvaluator import AddConceptInSetEvaluator
|
||||
from parsers.DefaultParser import IsaConceptNode, NameNode
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
def get_ret_val(concept_name, concept_set_name):
|
||||
n1 = NameNode(list(Tokenizer(concept_name)))
|
||||
n2 = NameNode(list(Tokenizer(concept_set_name)))
|
||||
|
||||
return ReturnValueConcept("some_name", True, ParserResultConcept(value=IsaConceptNode([], n1, n2)))
|
||||
|
||||
|
||||
class TestAssConceptInSetEvaluator(TestUsingMemoryBasedSheerka):
|
||||
|
||||
@pytest.mark.parametrize("ret_val, expected", [
|
||||
(ReturnValueConcept("some_name", True, ParserResultConcept(value=IsaConceptNode([]))), True),
|
||||
(ReturnValueConcept("some_name", False, ParserResultConcept(value=IsaConceptNode([]))), False),
|
||||
(ReturnValueConcept("some_name", True, "not a ParserResultConcept"), False),
|
||||
(ReturnValueConcept("some_name", True, ParserResultConcept()), False),
|
||||
])
|
||||
def test_i_can_match(self, ret_val, expected):
|
||||
context = self.get_context()
|
||||
assert AddConceptInSetEvaluator().matches(context, ret_val) == expected
|
||||
|
||||
def test_i_cannot_add_if_the_concept_does_not_exists(self):
|
||||
context = self.get_context()
|
||||
|
||||
ret_val = get_ret_val("foo", "bar")
|
||||
res = AddConceptInSetEvaluator().eval(context, ret_val)
|
||||
|
||||
assert not res.status
|
||||
assert context.sheerka.isinstance(res.value, BuiltinConcepts.UNKNOWN_CONCEPT)
|
||||
assert res.value.body == "foo"
|
||||
|
||||
def test_i_cannot_add_if_the_set_does_not_exists(self):
|
||||
context = self.get_context()
|
||||
foo = Concept("foo")
|
||||
context.sheerka.set_id_if_needed(foo, False)
|
||||
context.sheerka.add_in_cache(foo)
|
||||
|
||||
ret_val = get_ret_val("foo", "bar")
|
||||
res = AddConceptInSetEvaluator().eval(context, ret_val)
|
||||
|
||||
assert not res.status
|
||||
assert context.sheerka.isinstance(res.value, BuiltinConcepts.UNKNOWN_CONCEPT)
|
||||
assert res.value.body == "bar"
|
||||
|
||||
def test_i_can_add_concept_to_a_set_of_concept(self):
|
||||
context = self.get_context()
|
||||
foo = Concept("foo")
|
||||
context.sheerka.set_id_if_needed(foo, False)
|
||||
context.sheerka.add_in_cache(foo)
|
||||
|
||||
bar = Concept("bar")
|
||||
context.sheerka.set_id_if_needed(bar, False)
|
||||
context.sheerka.add_in_cache(bar)
|
||||
|
||||
ret_val = get_ret_val("foo", "bar")
|
||||
res = AddConceptInSetEvaluator().eval(context, ret_val)
|
||||
|
||||
assert res.status
|
||||
assert context.sheerka.isinstance(res.value, BuiltinConcepts.SUCCESS)
|
||||
|
||||
def test_i_can_add_concept_with_a_body_to_a_set_of_concept(self):
|
||||
context = self.get_context()
|
||||
foo = Concept("foo", body="1")
|
||||
context.sheerka.set_id_if_needed(foo, False)
|
||||
context.sheerka.add_in_cache(foo)
|
||||
|
||||
bar = Concept("bar")
|
||||
context.sheerka.set_id_if_needed(bar, False)
|
||||
context.sheerka.add_in_cache(bar)
|
||||
|
||||
ret_val = get_ret_val("foo", "bar")
|
||||
res = AddConceptInSetEvaluator().eval(context, ret_val)
|
||||
|
||||
assert res.status
|
||||
assert context.sheerka.isinstance(res.value, BuiltinConcepts.SUCCESS)
|
||||
|
||||
def test_i_cannot_add_the_same_concept_twice(self):
|
||||
context = self.get_context()
|
||||
foo = Concept("foo")
|
||||
context.sheerka.set_id_if_needed(foo, False)
|
||||
context.sheerka.add_in_cache(foo)
|
||||
|
||||
bar = Concept("bar")
|
||||
context.sheerka.set_id_if_needed(bar, False)
|
||||
context.sheerka.add_in_cache(bar)
|
||||
|
||||
ret_val = get_ret_val("foo", "bar")
|
||||
AddConceptInSetEvaluator().eval(context, ret_val)
|
||||
res = AddConceptInSetEvaluator().eval(context, ret_val)
|
||||
|
||||
assert not res.status
|
||||
assert context.sheerka.isinstance(res.value, BuiltinConcepts.CONCEPT_ALREADY_IN_SET)
|
||||
assert res.value.concept == foo
|
||||
assert res.value.concept_set == bar
|
||||
@@ -0,0 +1,117 @@
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import ReturnValueConcept, ParserResultConcept, BuiltinConcepts
|
||||
from core.concept import Concept, ConceptParts
|
||||
from evaluators.ConceptEvaluator import ConceptEvaluator
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
|
||||
|
||||
@pytest.mark.parametrize("ret_val, expected", [
|
||||
(ReturnValueConcept("some_name", True, ParserResultConcept(value=Concept())), True),
|
||||
(ReturnValueConcept("some_name", False, ParserResultConcept(value=Concept())), False),
|
||||
(ReturnValueConcept("some_name", True, ParserResultConcept(value="Not a concept")), False),
|
||||
(ReturnValueConcept("some_name", True, Concept()), False),
|
||||
])
|
||||
def test_i_can_match(self, ret_val, expected):
|
||||
context = self.get_context()
|
||||
assert ConceptEvaluator().matches(context, ret_val) == expected
|
||||
|
||||
def test_i_can_evaluate_concept(self):
|
||||
context = self.get_context()
|
||||
concept = Concept(name="foo",
|
||||
where="1",
|
||||
pre="2",
|
||||
post="3").def_prop("a", "4").def_prop("b", "5")
|
||||
|
||||
evaluator = ConceptEvaluator()
|
||||
item = self.pretval(concept)
|
||||
result = evaluator.eval(context, item)
|
||||
|
||||
assert result.who == evaluator.name
|
||||
assert result.status
|
||||
assert result.value.name == "foo"
|
||||
assert result.value.get_metadata_value(ConceptParts.WHERE) == 1
|
||||
assert result.value.get_metadata_value(ConceptParts.PRE) == 2
|
||||
assert result.value.get_metadata_value(ConceptParts.POST) == 3
|
||||
assert result.value.get_prop("a") == 4
|
||||
assert result.value.get_prop("b") == 5
|
||||
assert result.value.key == "foo"
|
||||
assert result.parents == [item]
|
||||
|
||||
def test_body_is_returned_when_defined_and_requested(self):
|
||||
context = self.get_context()
|
||||
concept = Concept(name="foo",
|
||||
body="'I have a value'",
|
||||
where="1",
|
||||
pre="2",
|
||||
post="3").set_prop("a", "4").set_prop("b", "5")
|
||||
|
||||
evaluator = ConceptEvaluator(return_body=True)
|
||||
item = self.pretval(concept)
|
||||
result = evaluator.eval(context, item)
|
||||
|
||||
assert result.who == evaluator.name
|
||||
assert result.status
|
||||
assert result.value == "I have a value"
|
||||
assert result.parents == [item]
|
||||
|
||||
def test_body_is_not_returned_if_not_requested(self):
|
||||
context = self.get_context()
|
||||
concept = Concept(name="foo",
|
||||
body="'I have a value'",
|
||||
where="1",
|
||||
pre="2",
|
||||
post="3").set_prop("a", "4").set_prop("b", "5")
|
||||
|
||||
evaluator = ConceptEvaluator(return_body=False) # which is the default behaviour
|
||||
item = self.pretval(concept)
|
||||
result = evaluator.eval(context, item)
|
||||
|
||||
assert result.who == evaluator.name
|
||||
assert result.status
|
||||
assert result.value == concept
|
||||
assert result.parents == [item]
|
||||
|
||||
def test_i_can_eval_if_with_the_same_name_is_defined_in_the_context(self):
|
||||
# If we evaluate Concept("foo", body="a").set_prop("a", "'property_a'")
|
||||
# ConceptEvaluator will be called to resolve 'a' while we know that 'a' refers to the string 'property_a'
|
||||
|
||||
context = self.get_context()
|
||||
context.obj = Concept("other").set_prop("foo", "'some_other_value'")
|
||||
concept = Concept(name="foo")
|
||||
|
||||
item = self.pretval(concept)
|
||||
result = ConceptEvaluator().eval(context, item)
|
||||
|
||||
assert result.status
|
||||
assert result.value == "'some_other_value'"
|
||||
|
||||
def test_i_cannot_recognize_a_concept_if_one_of_the_prop_is_unknown(self):
|
||||
context = self.get_context()
|
||||
context.sheerka.add_in_cache(Concept(name="one").init_key())
|
||||
concept_plus = context.sheerka.add_in_cache(Concept(name="a plus b")
|
||||
.def_prop("a", "one")
|
||||
.def_prop("b", "two").init_key())
|
||||
|
||||
evaluator = ConceptEvaluator()
|
||||
item = self.pretval(concept_plus)
|
||||
result = evaluator.eval(context, item)
|
||||
|
||||
assert not result.status
|
||||
assert context.sheerka.isinstance(result.value, BuiltinConcepts.CONCEPT_EVAL_ERROR)
|
||||
assert result.value.concept == concept_plus
|
||||
assert result.value.property_name == "b"
|
||||
assert context.sheerka.isinstance(result.value.error, BuiltinConcepts.TOO_MANY_ERRORS)
|
||||
|
||||
def test_that_error_concepts_are_transformed_into_errors_only_if_the_key_is_different(self):
|
||||
context = self.get_context()
|
||||
|
||||
error_concept = context.sheerka.new(BuiltinConcepts.ERROR)
|
||||
item = self.pretval(error_concept)
|
||||
result = ConceptEvaluator().eval(context, item)
|
||||
|
||||
assert not context.sheerka.is_success(error_concept) # it's indeed an error
|
||||
assert result.status
|
||||
assert result.value == error_concept
|
||||
@@ -0,0 +1,72 @@
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import ReturnValueConcept, BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from evaluators.EvalEvaluator import EvalEvaluator
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
eval_requested = ReturnValueConcept("some_name", True, Concept(key=BuiltinConcepts.CONCEPT_EVAL_REQUESTED))
|
||||
|
||||
|
||||
def retval(obj, who="who", status=True):
|
||||
"""ret_val"""
|
||||
return ReturnValueConcept(who, status, obj)
|
||||
|
||||
|
||||
class TestEvalEvaluator(TestUsingMemoryBasedSheerka):
|
||||
def test_i_can_match_and_eval(self):
|
||||
context = self.get_context()
|
||||
|
||||
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())
|
||||
|
||||
return_values = [
|
||||
ReturnValueConcept("some_name", True, "not to eval"),
|
||||
ReturnValueConcept("some_name", True, Concept(name="not to eval")),
|
||||
ReturnValueConcept("some_name", False, Concept(name="1", body="'not to eval'")),
|
||||
to_eval1,
|
||||
to_eval2,
|
||||
eval_requested
|
||||
]
|
||||
|
||||
evaluator = EvalEvaluator()
|
||||
assert evaluator.matches(context, return_values)
|
||||
|
||||
evaluated = evaluator.eval(context, return_values)
|
||||
assert len(evaluated) == 2
|
||||
assert evaluated[0].value == to_eval1.body.body
|
||||
assert evaluated[0].parents == [to_eval1, eval_requested]
|
||||
|
||||
assert evaluated[1].value == to_eval2.body.body
|
||||
assert evaluated[1].parents == [to_eval2, eval_requested]
|
||||
|
||||
@pytest.mark.parametrize("return_values, expected", [
|
||||
([retval(Concept("foo", body="bar")), eval_requested], True),
|
||||
([retval(Concept("status is false", body="bar"), status=False), eval_requested], True),
|
||||
([retval("string_value"), eval_requested], True),
|
||||
([retval(Concept("no body")), eval_requested], True),
|
||||
([retval(Concept("eval requested missing", body="bar"))], False),
|
||||
])
|
||||
def test_i_cannot_match_if_eval_request_is_not_present(self, return_values, expected):
|
||||
context = self.get_context()
|
||||
assert EvalEvaluator().matches(context, return_values) == expected
|
||||
|
||||
def test_concept_eval_requested_is_reduced_when_nothing_to_reduce(self):
|
||||
context = self.get_context()
|
||||
|
||||
return_values = [
|
||||
ReturnValueConcept("some_name", True, "not to eval"),
|
||||
ReturnValueConcept("some_name", True, Concept(name="not to eval")),
|
||||
ReturnValueConcept("some_name", False, Concept(name="1", body="not to eval")),
|
||||
eval_requested
|
||||
]
|
||||
|
||||
evaluator = EvalEvaluator()
|
||||
assert evaluator.matches(context, return_values)
|
||||
|
||||
evaluated = evaluator.eval(context, return_values)
|
||||
assert evaluated == ReturnValueConcept(
|
||||
"evaluators.Eval",
|
||||
False,
|
||||
context.sheerka.new(BuiltinConcepts.CONCEPT_EVAL_REQUESTED))
|
||||
assert evaluated.parents == [eval_requested]
|
||||
@@ -0,0 +1,104 @@
|
||||
import ast
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import ReturnValueConcept, ParserResultConcept, BuiltinConcepts
|
||||
from core.concept import Concept, ConceptParts, DoNotResolve
|
||||
from evaluators.LexerNodeEvaluator import LexerNodeEvaluator
|
||||
from parsers.ConceptLexerParser import ConceptNode, ConceptLexerParser, StrMatch, UnrecognizedTokensNode, SourceCodeNode
|
||||
from parsers.PythonParser import PythonNode
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
class TestLexerNodeEvaluator(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def from_parsing(self, context, grammar, expression):
|
||||
parser = ConceptLexerParser()
|
||||
parser.initialize(context, grammar)
|
||||
|
||||
ret_val = parser.parse(context, expression)
|
||||
assert ret_val.status
|
||||
return ret_val
|
||||
|
||||
def from_fragments(self, *fragments):
|
||||
nodes = []
|
||||
for fragment in fragments:
|
||||
if isinstance(fragment, str):
|
||||
node = PythonNode(fragment, ast.parse(fragment.strip(), mode="eval"))
|
||||
nodes.append(SourceCodeNode(node, 0, 0, [], fragment))
|
||||
else:
|
||||
nodes.append(ConceptNode(fragment, 0, 0, [], fragment.name))
|
||||
|
||||
return ReturnValueConcept("somme_name", True, ParserResultConcept(value=nodes))
|
||||
|
||||
def init(self, concept, grammar, text):
|
||||
context = self.get_context()
|
||||
if isinstance(concept, list):
|
||||
for c in concept:
|
||||
context.sheerka.add_in_cache(c)
|
||||
else:
|
||||
context.sheerka.add_in_cache(concept)
|
||||
ret_val = self.from_parsing(context, grammar, text)
|
||||
node = ret_val.value.value[0]
|
||||
|
||||
return context, node
|
||||
|
||||
@pytest.mark.parametrize("ret_val, expected", [
|
||||
(ReturnValueConcept("some_name", True, ParserResultConcept(value=[ConceptNode(Concept(), 0, 0)])), True),
|
||||
(ReturnValueConcept("some_name", True, ParserResultConcept(value=ConceptNode(Concept(), 0, 0))), True),
|
||||
(ReturnValueConcept("some_name", True, ParserResultConcept(value=[SourceCodeNode(0, 0, [])])), True),
|
||||
(ReturnValueConcept("some_name", True, ParserResultConcept(value=SourceCodeNode(0, 0, []))), True),
|
||||
(ReturnValueConcept("some_name", True, ParserResultConcept(value=[UnrecognizedTokensNode(0, 0, [])])), False),
|
||||
(ReturnValueConcept("some_name", True, ParserResultConcept(value=UnrecognizedTokensNode(0, 0, []))), False),
|
||||
(ReturnValueConcept("some_name", False, ParserResultConcept(value=[ConceptNode(Concept(), 0, 0)])), False),
|
||||
(ReturnValueConcept("some_name", False, ParserResultConcept(value=ConceptNode(Concept(), 0, 0))), False),
|
||||
(ReturnValueConcept("some_name", False, ParserResultConcept(value=[SourceCodeNode(0, 0, [])])), False),
|
||||
(ReturnValueConcept("some_name", False, ParserResultConcept(value=SourceCodeNode(0, 0, []))), False),
|
||||
(ReturnValueConcept("some_name", True, ParserResultConcept(value="Not a concept node")), False),
|
||||
(ReturnValueConcept("some_name", True, ParserResultConcept(value=["Not a concept node"])), False),
|
||||
(ReturnValueConcept("some_name", True, [ConceptNode(Concept(), 0, 0)]), False),
|
||||
(ReturnValueConcept("some_name", True, ConceptNode(Concept(), 0, 0)), False),
|
||||
])
|
||||
def test_i_can_match(self, ret_val, expected):
|
||||
context = self.get_context()
|
||||
assert LexerNodeEvaluator().matches(context, ret_val) == expected
|
||||
|
||||
def test_concept_is_returned_when_only_one_in_the_list(self):
|
||||
foo = Concept("foo")
|
||||
context = self.get_context()
|
||||
context.sheerka.add_in_cache(foo)
|
||||
|
||||
ret_val = self.from_parsing(context, {foo: StrMatch("foo")}, "foo")
|
||||
|
||||
evaluator = LexerNodeEvaluator()
|
||||
result = evaluator.eval(context, ret_val)
|
||||
wrapper = result.body
|
||||
return_value = result.body.body
|
||||
|
||||
assert result.who == evaluator.name
|
||||
assert result.status
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert wrapper.parser == evaluator
|
||||
assert wrapper.source == "foo"
|
||||
assert return_value == Concept("foo").init_key()
|
||||
assert return_value.compiled[ConceptParts.BODY] == DoNotResolve("foo")
|
||||
assert result.parents == [ret_val]
|
||||
|
||||
def test_concept_python_node_is_returned_when_source_code(self):
|
||||
context = self.get_context()
|
||||
foo = Concept("foo")
|
||||
ret_val = self.from_fragments(foo, " + 1")
|
||||
|
||||
evaluator = LexerNodeEvaluator()
|
||||
result = evaluator.eval(context, ret_val)
|
||||
wrapper = result.body
|
||||
return_value = result.body.body
|
||||
|
||||
assert result.who == evaluator.name
|
||||
assert result.status
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert wrapper.parser == evaluator
|
||||
assert wrapper.source == "foo + 1"
|
||||
|
||||
assert return_value == PythonNode('foo + 1', ast.parse("__C__foo__C__ + 1", mode="eval"))
|
||||
assert return_value.concepts == {"__C__foo__C__": foo}
|
||||
assert result.parents == [ret_val]
|
||||
@@ -0,0 +1,200 @@
|
||||
from core.builtin_concepts import ReturnValueConcept, BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from evaluators.BaseEvaluator import BaseEvaluator
|
||||
from evaluators.MutipleSameSuccessEvaluator import MultipleSameSuccessEvaluator
|
||||
from parsers.BaseParser import BaseParser
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
class TestMultipleSameSuccessEvaluator(TestUsingMemoryBasedSheerka):
|
||||
|
||||
def test_i_can_match_and_eval(self):
|
||||
context = self.get_context()
|
||||
sheerka = context.sheerka
|
||||
|
||||
return_values = [
|
||||
ReturnValueConcept(BaseParser.PREFIX + "some_name", False, "Not relevant"),
|
||||
ReturnValueConcept(BaseParser.PREFIX + "some_name2", False, "Not relevant"),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1", body="value").auto_init()),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="2", body="value").auto_init()),
|
||||
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.REDUCE_REQUESTED))
|
||||
]
|
||||
|
||||
evaluator = MultipleSameSuccessEvaluator()
|
||||
assert evaluator.matches(context, return_values)
|
||||
|
||||
evaluated = evaluator.eval(context, return_values)
|
||||
assert evaluated.status
|
||||
assert evaluated.value == Concept(name="1", body="value").auto_init() # the first concept is returned
|
||||
|
||||
def test_i_can_match_and_eval_when_no_body(self):
|
||||
context = self.get_context()
|
||||
sheerka = context.sheerka
|
||||
|
||||
return_values = [
|
||||
ReturnValueConcept(BaseParser.PREFIX + "some_name", False, "Not relevant"),
|
||||
ReturnValueConcept(BaseParser.PREFIX + "some_name2", False, "Not relevant"),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1").auto_init()),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1").auto_init()),
|
||||
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.REDUCE_REQUESTED))
|
||||
]
|
||||
|
||||
evaluator = MultipleSameSuccessEvaluator()
|
||||
assert evaluator.matches(context, return_values)
|
||||
|
||||
evaluated = evaluator.eval(context, return_values)
|
||||
assert evaluated.status
|
||||
assert evaluated.value == Concept(name="1").auto_init()
|
||||
|
||||
def test_i_can_match_and_eval_when_value_is_not_a_concept(self):
|
||||
context = self.get_context()
|
||||
sheerka = context.sheerka
|
||||
|
||||
return_values = [
|
||||
ReturnValueConcept(BaseParser.PREFIX + "some_name", False, "Not relevant"),
|
||||
ReturnValueConcept(BaseParser.PREFIX + "some_name2", False, "Not relevant"),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, "value"),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, "value"),
|
||||
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.REDUCE_REQUESTED))
|
||||
]
|
||||
|
||||
evaluator = MultipleSameSuccessEvaluator()
|
||||
assert evaluator.matches(context, return_values)
|
||||
|
||||
evaluated = evaluator.eval(context, return_values)
|
||||
assert evaluated.status
|
||||
assert evaluated.value == "value"
|
||||
|
||||
def test_i_can_match_and_eval_when_at_least_one_value_is_a_concept_concept_evaluator_first(self):
|
||||
context = self.get_context()
|
||||
sheerka = context.sheerka
|
||||
|
||||
return_values = [
|
||||
ReturnValueConcept(BaseParser.PREFIX + "some_name", False, "Not relevant"),
|
||||
ReturnValueConcept(BaseParser.PREFIX + "some_name2", False, "Not relevant"),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "Python", True, "value"),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "other", True, "value"),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "Python", True, Concept(name="2", body="value").auto_init()),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "Concept", True, Concept(name="1", body="value").auto_init()),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "Python", True, Concept(name="3", body="value").auto_init()),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "other", True, "value"),
|
||||
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.REDUCE_REQUESTED))
|
||||
]
|
||||
|
||||
evaluator = MultipleSameSuccessEvaluator()
|
||||
assert evaluator.matches(context, return_values)
|
||||
|
||||
evaluated = evaluator.eval(context, return_values)
|
||||
assert evaluated.status
|
||||
assert evaluated.value == Concept(name="1", body="value").auto_init() # the concept is returned, not the value
|
||||
|
||||
def test_i_can_match_and_eval_when_at_least_one_value_is_a_concept_python_evaluator_first(self):
|
||||
context = self.get_context()
|
||||
sheerka = context.sheerka
|
||||
|
||||
return_values = [
|
||||
ReturnValueConcept(BaseParser.PREFIX + "some_name", False, "Not relevant"),
|
||||
ReturnValueConcept(BaseParser.PREFIX + "some_name2", False, "Not relevant"),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "Python", True, "value"),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "other", True, "value"),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "other", True, Concept(name="2", body="value").auto_init()),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "Python", True, Concept(name="1", body="value").auto_init()),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "other", True, Concept(name="3", body="value").auto_init()),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "other", True, "value"),
|
||||
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.REDUCE_REQUESTED))
|
||||
]
|
||||
|
||||
evaluator = MultipleSameSuccessEvaluator()
|
||||
assert evaluator.matches(context, return_values)
|
||||
|
||||
evaluated = evaluator.eval(context, return_values)
|
||||
assert evaluated.status
|
||||
assert evaluated.value == Concept(name="1", body="value").auto_init() # the concept is returned, not the value
|
||||
|
||||
def test_i_can_match_even_if_the_value_are_not_the_same_but_eval_will_fail(self):
|
||||
context = self.get_context()
|
||||
sheerka = context.sheerka
|
||||
|
||||
return_values = [
|
||||
ReturnValueConcept(BaseParser.PREFIX + "some_name", False, "Not relevant"),
|
||||
ReturnValueConcept(BaseParser.PREFIX + "some_name2", False, "Not relevant"),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1", body="value").auto_init()),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="2", body="value2").auto_init()),
|
||||
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.REDUCE_REQUESTED))
|
||||
]
|
||||
|
||||
evaluator = MultipleSameSuccessEvaluator()
|
||||
assert evaluator.matches(context, return_values)
|
||||
assert evaluator.eval(context, return_values) is None
|
||||
|
||||
def test_i_can_match_even_if_the_value_are_not_the_same_but_eval_will_fail_when_no_body(self):
|
||||
context = self.get_context()
|
||||
sheerka = context.sheerka
|
||||
|
||||
return_values = [
|
||||
ReturnValueConcept(BaseParser.PREFIX + "some_name", False, "Not relevant"),
|
||||
ReturnValueConcept(BaseParser.PREFIX + "some_name2", False, "Not relevant"),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1").auto_init()),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="2").auto_init()),
|
||||
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.REDUCE_REQUESTED))
|
||||
]
|
||||
|
||||
evaluator = MultipleSameSuccessEvaluator()
|
||||
assert evaluator.matches(context, return_values)
|
||||
assert evaluator.eval(context, return_values) is None
|
||||
|
||||
def test_i_can_match_if_no_parser(self):
|
||||
context = self.get_context()
|
||||
sheerka = context.sheerka
|
||||
|
||||
return_values = [
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1", body="value").auto_init()),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="2", body="value").auto_init()),
|
||||
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.REDUCE_REQUESTED))
|
||||
]
|
||||
|
||||
assert MultipleSameSuccessEvaluator().matches(context, return_values)
|
||||
|
||||
def test_i_cannot_match_if_not_reduced_requested(self):
|
||||
context = self.get_context()
|
||||
sheerka = context.sheerka
|
||||
|
||||
return_values = [
|
||||
ReturnValueConcept(BaseParser.PREFIX + "some_name", False, "Not relevant"),
|
||||
ReturnValueConcept(BaseParser.PREFIX + "some_name2", False, "Not relevant"),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1", body="value").auto_init()),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="2", body="value").auto_init()),
|
||||
ReturnValueConcept("some_name", True, Concept(name="2", body="value")),
|
||||
# ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.REDUCE_REQUESTED))
|
||||
]
|
||||
|
||||
assert not MultipleSameSuccessEvaluator().matches(context, return_values)
|
||||
|
||||
def test_i_cannot_match_if_only_one_successful_evaluator(self):
|
||||
context = self.get_context()
|
||||
sheerka = context.sheerka
|
||||
|
||||
return_values = [
|
||||
ReturnValueConcept(BaseParser.PREFIX + "some_name", False, "Not relevant"),
|
||||
ReturnValueConcept(BaseParser.PREFIX + "some_name2", False, "Not relevant"),
|
||||
# ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1", body="value")),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="2", body="value").auto_init()),
|
||||
ReturnValueConcept("some_name", True, Concept(name="2", body="value")),
|
||||
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.REDUCE_REQUESTED))
|
||||
]
|
||||
|
||||
assert not MultipleSameSuccessEvaluator().matches(context, return_values)
|
||||
|
||||
def test_i_cannot_match_if_at_least_one_parser_is_successful(self):
|
||||
context = self.get_context()
|
||||
sheerka = context.sheerka
|
||||
|
||||
return_values = [
|
||||
ReturnValueConcept(BaseParser.PREFIX + "some_name", False, "Not relevant"),
|
||||
ReturnValueConcept(BaseParser.PREFIX + "some_name2", True, "Not relevant"),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="1", body="value").auto_init()),
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, Concept(name="2", body="value").auto_init()),
|
||||
ReturnValueConcept("some_name", True, sheerka.new(BuiltinConcepts.REDUCE_REQUESTED))
|
||||
]
|
||||
|
||||
assert not MultipleSameSuccessEvaluator().matches(context, return_values)
|
||||
@@ -0,0 +1,73 @@
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import ReturnValueConcept, BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from evaluators.OneErrorEvaluator import OneErrorEvaluator
|
||||
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
def r(value, status=True):
|
||||
return ReturnValueConcept(value, status, value)
|
||||
|
||||
|
||||
reduce_requested = ReturnValueConcept("some_name", True, Concept(key=BuiltinConcepts.REDUCE_REQUESTED))
|
||||
|
||||
|
||||
class TestOneErrorEvaluator(TestUsingMemoryBasedSheerka):
|
||||
@pytest.mark.parametrize("return_values, expected", [
|
||||
([r("evaluators.one error", False), reduce_requested], True),
|
||||
([r("evaluators.one error", False), r("failed", False), r("failed", False), reduce_requested], True),
|
||||
([r("evaluators.error", False), r("not a parser in success"), reduce_requested], True),
|
||||
([r("evaluators.no reduce required", False), r("failed", False), r("failed", False)], False),
|
||||
([r("evaluators.no reduce required", False)], False),
|
||||
([r("evaluators.error", False), r("evaluators.success"), reduce_requested], False),
|
||||
([r("evaluators.error", False), r("parsers.success"), reduce_requested], False),
|
||||
([r("evaluators.success"), r("not an evaluator in error", False), reduce_requested], False),
|
||||
([r("evaluators.error", False), r("evaluators.another error", False), reduce_requested], False),
|
||||
])
|
||||
def test_i_can_match(self, return_values, expected):
|
||||
context = self.get_context()
|
||||
assert OneErrorEvaluator().matches(context, return_values) == expected
|
||||
|
||||
def test_i_can_eval(self):
|
||||
context = self.get_context()
|
||||
|
||||
return_values = [
|
||||
r("evaluators.one error", False),
|
||||
r("parsers.failed", False),
|
||||
r("parsers.failed", False),
|
||||
reduce_requested
|
||||
]
|
||||
|
||||
evaluator = OneErrorEvaluator()
|
||||
evaluator.matches(context, return_values)
|
||||
res = evaluator.eval(context, return_values)
|
||||
|
||||
assert not res.status
|
||||
assert res.body == "evaluators.one error"
|
||||
assert len(res.parents) == 4
|
||||
|
||||
def test_unwanted_return_values_are_not_eaten(self):
|
||||
context = self.get_context()
|
||||
|
||||
a_successful_concept = r("successful concept")
|
||||
a_concept_in_error = r("concept in error", False)
|
||||
return_values = [
|
||||
r("evaluators.one error", False),
|
||||
r("parsers.failed", False),
|
||||
r("parsers.failed", False),
|
||||
a_successful_concept,
|
||||
a_concept_in_error,
|
||||
reduce_requested
|
||||
]
|
||||
|
||||
evaluator = OneErrorEvaluator()
|
||||
evaluator.matches(context, return_values)
|
||||
res = evaluator.eval(context, return_values)
|
||||
|
||||
assert not res.status
|
||||
assert res.body == "evaluators.one error"
|
||||
assert len(res.parents) == 4
|
||||
|
||||
assert a_successful_concept not in res.parents
|
||||
@@ -0,0 +1,72 @@
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import ReturnValueConcept, BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from evaluators.OneSuccessEvaluator import OneSuccessEvaluator
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
def r(value, status=True):
|
||||
return ReturnValueConcept(value, status, value)
|
||||
|
||||
|
||||
reduce_requested = ReturnValueConcept("some_name", True, Concept(key=BuiltinConcepts.REDUCE_REQUESTED))
|
||||
|
||||
|
||||
class TestOneSuccessEvaluator(TestUsingMemoryBasedSheerka):
|
||||
|
||||
@pytest.mark.parametrize("return_values, expected", [
|
||||
([r("evaluators.one success"), reduce_requested], True),
|
||||
([r("evaluators.one success"), r("failed", False), r("failed", False), reduce_requested], True),
|
||||
([r("evaluators.no reduce required"), r("failed", False), r("failed", False)], False),
|
||||
([r("evaluators.no reduce required")], False),
|
||||
([r("evaluators.failed", False), r("failed", False), r("failed", False), reduce_requested], False),
|
||||
([r("evaluators.failed", False), r("not evaluator success"), reduce_requested], False),
|
||||
([r("evaluators.success"), r("evaluators.another success"), reduce_requested], False),
|
||||
([r("evaluators.one success"), r("other success"), r("failed", False), reduce_requested], True),
|
||||
([r("evaluators.one success"), r("parsers.success"), reduce_requested], False),
|
||||
])
|
||||
def test_i_can_match(self, return_values, expected):
|
||||
context = self.get_context()
|
||||
assert OneSuccessEvaluator().matches(context, return_values) == expected
|
||||
|
||||
def test_i_can_eval(self):
|
||||
context = self.get_context()
|
||||
|
||||
return_values = [
|
||||
r("evaluators.one success"),
|
||||
r("failed", False),
|
||||
r("failed", False),
|
||||
reduce_requested
|
||||
]
|
||||
|
||||
evaluator = OneSuccessEvaluator()
|
||||
matches = evaluator.matches(context, return_values)
|
||||
res = evaluator.eval(context, return_values)
|
||||
|
||||
assert matches
|
||||
assert res.status
|
||||
assert res.body == "evaluators.one success"
|
||||
assert len(res.parents) == 4
|
||||
|
||||
def test_i_do_not_eat_the_other_success(self):
|
||||
context = self.get_context()
|
||||
|
||||
not_a_parser_success = r("other success")
|
||||
return_values = [
|
||||
r("evaluators.one success"),
|
||||
not_a_parser_success,
|
||||
r("failed", False),
|
||||
reduce_requested
|
||||
]
|
||||
|
||||
evaluator = OneSuccessEvaluator()
|
||||
matches = evaluator.matches(context, return_values)
|
||||
res = evaluator.eval(context, return_values)
|
||||
|
||||
assert matches
|
||||
assert res.status
|
||||
assert res.body == "evaluators.one success"
|
||||
assert len(res.parents) == 3
|
||||
|
||||
assert not_a_parser_success not in res.parents
|
||||
@@ -0,0 +1,49 @@
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import BuiltinConcepts, ReturnValueConcept, UserInputConcept
|
||||
from core.concept import Concept
|
||||
from evaluators.PrepareEvalEvaluator import PrepareEvalEvaluator
|
||||
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
r = ReturnValueConcept
|
||||
|
||||
|
||||
class TestPrepareEvalEvaluator(TestUsingMemoryBasedSheerka):
|
||||
|
||||
@pytest.mark.parametrize("ret_val, expected", [
|
||||
(r("name", True, UserInputConcept("eval 1 + 1")), True),
|
||||
(r("name", True, UserInputConcept(" eval 1 + 1")), True),
|
||||
(r("name", True, UserInputConcept("eval")), False),
|
||||
(r("name", True, UserInputConcept("1+1")), False),
|
||||
(r("name", True, UserInputConcept("")), False),
|
||||
(r("name", True, UserInputConcept("eval ")), False),
|
||||
(r("name", True, UserInputConcept([])), False),
|
||||
(r("name", True, Concept("foo")), False),
|
||||
(r("name", True, "not a concept"), False),
|
||||
(r("name", False, UserInputConcept("eval 1 + 1")), False),
|
||||
(r("name", False, UserInputConcept(" eval 1 + 1")), False),
|
||||
])
|
||||
def test_i_can_match(self, ret_val, expected):
|
||||
context = self.get_context()
|
||||
assert PrepareEvalEvaluator().matches(context, ret_val) == expected
|
||||
|
||||
@pytest.mark.parametrize("ret_val, expected", [
|
||||
(r("name", True, UserInputConcept("eval 1 + 1")), "1 + 1"),
|
||||
(r("name", True, UserInputConcept(" eval 1 + 1")), "1 + 1"),
|
||||
])
|
||||
def test_i_can_eval(self, ret_val, expected):
|
||||
context = self.get_context()
|
||||
sheerka = context.sheerka
|
||||
|
||||
prepare_evaluator = PrepareEvalEvaluator()
|
||||
prepare_evaluator.matches(context, ret_val)
|
||||
res = prepare_evaluator.eval(context, ret_val)
|
||||
|
||||
assert len(res) == 2
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(res[0].body, BuiltinConcepts.USER_INPUT)
|
||||
assert res[0].body.body == expected
|
||||
|
||||
assert res[1].status
|
||||
assert sheerka.isinstance(res[1].body, BuiltinConcepts.CONCEPT_EVAL_REQUESTED)
|
||||
@@ -0,0 +1,138 @@
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import ReturnValueConcept, ParserResultConcept, BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from evaluators.PythonEvaluator import PythonEvaluator
|
||||
from parsers.PythonParser import PythonNode, PythonParser
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
def get_context_name(context):
|
||||
return context.name
|
||||
|
||||
|
||||
class TestPythonEvaluator(TestUsingMemoryBasedSheerka):
|
||||
|
||||
@pytest.mark.parametrize("ret_val, expected", [
|
||||
(ReturnValueConcept("some_name", True, ParserResultConcept(value=PythonNode("", None))), True),
|
||||
(ReturnValueConcept("some_name", True, ParserResultConcept(value="other thing")), False),
|
||||
(ReturnValueConcept("some_name", False, "not relevant"), False),
|
||||
(ReturnValueConcept("some_name", True, Concept()), False)
|
||||
])
|
||||
def test_i_can_match(self, ret_val, expected):
|
||||
context = self.get_context()
|
||||
assert PythonEvaluator().matches(context, ret_val) == expected
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("1 + 1", 2),
|
||||
("sheerka.test()", "I have access to Sheerka !"),
|
||||
("a=10\na", 10),
|
||||
])
|
||||
def test_i_can_eval(self, text, expected):
|
||||
context = self.get_context()
|
||||
parsed = PythonParser().parse(context, text)
|
||||
|
||||
evaluated = PythonEvaluator().eval(context, parsed)
|
||||
|
||||
assert evaluated.status
|
||||
assert evaluated.value == expected
|
||||
|
||||
@pytest.mark.parametrize("concept", [
|
||||
Concept("foo"),
|
||||
Concept("foo", body="2"),
|
||||
Concept("foo").set_prop("prop", "'a'"),
|
||||
Concept("foo", body="bar")
|
||||
])
|
||||
def test_i_cannot_eval_simple_concept(self, concept):
|
||||
context = self.get_context()
|
||||
context.sheerka.add_in_cache(Concept("foo"))
|
||||
|
||||
parsed = PythonParser().parse(context, "foo")
|
||||
evaluated = PythonEvaluator().eval(context, parsed)
|
||||
|
||||
assert not evaluated.status
|
||||
assert context.sheerka.isinstance(evaluated.value, BuiltinConcepts.NOT_FOR_ME)
|
||||
|
||||
def test_i_can_eval_expression_with_that_references_concepts(self):
|
||||
"""
|
||||
I can test modules with variables
|
||||
:return:
|
||||
"""
|
||||
context = self.get_context()
|
||||
context.sheerka.add_in_cache(Concept("foo", body="1"))
|
||||
|
||||
parsed = PythonParser().parse(context, "foo + 2")
|
||||
evaluated = PythonEvaluator().eval(context, parsed)
|
||||
|
||||
assert evaluated.status
|
||||
assert evaluated.value == 3
|
||||
|
||||
def test_i_can_eval_module_with_that_references_concepts(self):
|
||||
"""
|
||||
I can test modules with variables
|
||||
:return:
|
||||
"""
|
||||
context = self.get_context()
|
||||
context.sheerka.add_in_cache(Concept("foo"))
|
||||
|
||||
parsed = PythonParser().parse(context, "def a(b):\n return b\na(c:foo:)")
|
||||
evaluated = PythonEvaluator().eval(context, parsed)
|
||||
|
||||
assert evaluated.status
|
||||
assert evaluated.value == Concept("foo").init_key()
|
||||
|
||||
def test_i_can_eval_module_with_that_references_concepts_with_body(self):
|
||||
"""
|
||||
I can test modules with variables
|
||||
:return:
|
||||
"""
|
||||
context = self.get_context()
|
||||
context.sheerka.add_in_cache(Concept("foo", body="2"))
|
||||
|
||||
parsed = PythonParser().parse(context, "def a(b):\n return b\na(foo)")
|
||||
evaluated = PythonEvaluator().eval(context, parsed)
|
||||
|
||||
assert evaluated.status
|
||||
assert evaluated.value == 2
|
||||
|
||||
def test_i_can_eval_concept_token(self):
|
||||
context = self.get_context()
|
||||
context.sheerka.add_in_cache(Concept("foo", body="2"))
|
||||
|
||||
parsed = PythonParser().parse(context, "get_context_name(c:foo:)")
|
||||
python_evaluator = PythonEvaluator()
|
||||
python_evaluator.locals["get_context_name"] = get_context_name
|
||||
evaluated = python_evaluator.eval(context, parsed)
|
||||
|
||||
assert evaluated.status
|
||||
assert evaluated.value == "foo"
|
||||
|
||||
# sanity, does not work otherwise
|
||||
parsed = PythonParser().parse(context, "get_context_name(foo)")
|
||||
python_evaluator = PythonEvaluator()
|
||||
python_evaluator.locals["get_context_name"] = get_context_name
|
||||
evaluated = python_evaluator.eval(context, parsed)
|
||||
|
||||
assert not evaluated.status
|
||||
assert evaluated.body.body.args[0] == "'int' object has no attribute 'name'"
|
||||
|
||||
@pytest.mark.parametrize("text, concept_key, concept_id, use_concept", [
|
||||
("__C__key__C__", "key", None, False),
|
||||
("__C__key__id__C__", "key", "id", False),
|
||||
("__C__USE_CONCEPT__key__id__C__", "key", "id", True),
|
||||
("__C__USE_CONCEPT__key__id__C__", "key", "id", True),
|
||||
])
|
||||
def test_i_can_resolve_name(self, text, concept_key, concept_id, use_concept):
|
||||
context = self.get_context()
|
||||
assert PythonEvaluator().resolve_name(context, text) == (concept_key, concept_id, use_concept)
|
||||
|
||||
@pytest.mark.parametrize("text", [
|
||||
"__C__",
|
||||
"__C__key",
|
||||
"__C__key____",
|
||||
"__C____",
|
||||
"__C__USE_CONCEPT__",
|
||||
])
|
||||
def test_i_cannot_resolve_name(self, text):
|
||||
context = self.get_context()
|
||||
assert PythonEvaluator().resolve_name(context, text) is None
|
||||
@@ -0,0 +1,105 @@
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import ReturnValueConcept, BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from evaluators.TooManySuccessEvaluator import TooManySuccessEvaluator
|
||||
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
def r(name, status=True, value=None):
|
||||
value = value or name
|
||||
return ReturnValueConcept(name, status, value)
|
||||
|
||||
|
||||
reduce_requested = ReturnValueConcept("some_name", True, Concept(key=BuiltinConcepts.REDUCE_REQUESTED))
|
||||
|
||||
|
||||
class TestTooManySuccessEvaluator(TestUsingMemoryBasedSheerka):
|
||||
|
||||
@pytest.mark.parametrize("return_values, expected", [
|
||||
([r("evaluators.success1"), r("evaluators.success2"), reduce_requested], True),
|
||||
([r("evaluators.success1"), r("evaluators.success2"), r("other"), reduce_requested], True),
|
||||
([r("evaluators.success1"), r("evaluators.success2"), r("other", False), reduce_requested], True),
|
||||
([r("evaluators.a", value=Concept("c1", body="1")),
|
||||
r("evaluators.a", value=Concept("c2", body="1")),
|
||||
r("other"),
|
||||
reduce_requested], True),
|
||||
([r("evaluators.a", value=Concept("c1", body="1")),
|
||||
r("evaluators.a", value=Concept("c2", body="1")),
|
||||
r("parsers.other", False),
|
||||
reduce_requested], True),
|
||||
([r("evaluators.a", value=Concept("c1", body="1")),
|
||||
r("evaluators.a", value=Concept("c2", body="1")),
|
||||
r("parsers.other"),
|
||||
reduce_requested], False),
|
||||
([r("evaluators.success1"), reduce_requested], False),
|
||||
([reduce_requested], False),
|
||||
([r("evaluators.success1"), r("evaluators.success2")], False),
|
||||
])
|
||||
def test_i_can_match(self, return_values, expected):
|
||||
context = self.get_context()
|
||||
assert TooManySuccessEvaluator().matches(context, return_values) == expected
|
||||
|
||||
def test_i_can_eval(self):
|
||||
context = self.get_context()
|
||||
|
||||
value1 = r("evaluators.a", value=Concept("c1", body="1"))
|
||||
value2 = r("evaluators.a", value=Concept("c2", body="2"))
|
||||
return_values = [
|
||||
value1,
|
||||
value2,
|
||||
r("other", False),
|
||||
reduce_requested
|
||||
]
|
||||
|
||||
evaluator = TooManySuccessEvaluator()
|
||||
matches = evaluator.matches(context, return_values)
|
||||
res = evaluator.eval(context, return_values)
|
||||
|
||||
assert matches
|
||||
assert not res.status
|
||||
assert context.sheerka.isinstance(res.body, BuiltinConcepts.TOO_MANY_SUCCESS)
|
||||
assert res.body.body == [value1, value2]
|
||||
assert len(res.parents) == 4
|
||||
|
||||
def test_i_can_eval_when_same_success(self):
|
||||
context = self.get_context()
|
||||
|
||||
return_values = [
|
||||
r("evaluators.a", value=Concept("c1", body="1").auto_init()),
|
||||
r("evaluators.a", value=Concept("c2", body="1").auto_init()),
|
||||
r("other", False),
|
||||
reduce_requested
|
||||
]
|
||||
|
||||
evaluator = TooManySuccessEvaluator()
|
||||
matches = evaluator.matches(context, return_values)
|
||||
res = evaluator.eval(context, return_values)
|
||||
|
||||
assert matches
|
||||
assert res is None
|
||||
|
||||
def test_other_success_are_not_reduced(self):
|
||||
context = self.get_context()
|
||||
|
||||
value1 = r("evaluators.a", value=Concept("c1", body="1").auto_init())
|
||||
value2 = r("evaluators.a", value=Concept("c2", body="2").auto_init())
|
||||
other_success = r("other")
|
||||
return_values = [
|
||||
value1,
|
||||
value2,
|
||||
other_success,
|
||||
reduce_requested
|
||||
]
|
||||
|
||||
evaluator = TooManySuccessEvaluator()
|
||||
matches = evaluator.matches(context, return_values)
|
||||
res = evaluator.eval(context, return_values)
|
||||
|
||||
assert matches
|
||||
assert not res.status
|
||||
assert context.sheerka.isinstance(res.body, BuiltinConcepts.TOO_MANY_SUCCESS)
|
||||
assert res.body.body == [value1, value2]
|
||||
assert len(res.parents) == 3
|
||||
assert other_success not in res.parents
|
||||
Reference in New Issue
Block a user