Refactored sheerka class: splitted to use sub handlers. Refactored unit tests to use classes.

This commit is contained in:
2020-01-22 17:49:28 +01:00
parent 821614a6c4
commit c489a38ebc
120 changed files with 7947 additions and 8190 deletions
View File
@@ -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
+117
View File
@@ -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
+72
View File
@@ -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]
+104
View File
@@ -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)
+138
View File
@@ -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