Improved PythonEvaluator when dealing with concept class
This commit is contained in:
@@ -122,3 +122,18 @@ class BaseTest:
|
||||
concept.bnf = expression or StrMatch(name)
|
||||
concept.metadata.definition_type = DEFINITION_TYPE_BNF
|
||||
return concept
|
||||
|
||||
@staticmethod
|
||||
def def_concept(name, definition, variables=None, **kwargs):
|
||||
concept = Concept(name=name, definition=definition, definition_type=DEFINITION_TYPE_DEF)
|
||||
if variables:
|
||||
for v in variables:
|
||||
concept.def_var(v)
|
||||
|
||||
if kwargs:
|
||||
for k, v in kwargs.items():
|
||||
if k in ("body", "pre", "post", "where"):
|
||||
setattr(concept.metadata, k, v)
|
||||
else:
|
||||
concept.metadata.variables[k] = v
|
||||
return concept
|
||||
|
||||
@@ -139,6 +139,23 @@ class TestSheerkaCreateNewConcept(TestUsingMemoryBasedSheerka):
|
||||
|
||||
assert res.status
|
||||
|
||||
def test_i_can_get_by_name_when_created_with_def_definition(self):
|
||||
sheerka = self.get_sheerka(cache_only=False)
|
||||
context = self.get_context(sheerka)
|
||||
concept = self.def_concept("plus", "a plus b", ["a", "b"])
|
||||
|
||||
res = sheerka.create_new_concept(context, concept)
|
||||
|
||||
assert res.status
|
||||
assert sheerka.get_by_name(concept.name) == concept
|
||||
assert sheerka.get_by_name(concept.metadata.definition) == concept
|
||||
|
||||
concept = Concept(name="foo", definition="foo", definition_type=DEFINITION_TYPE_DEF)
|
||||
res = sheerka.create_new_concept(context, concept)
|
||||
|
||||
assert res.status
|
||||
assert sheerka.get_by_name(concept.name) == concept # it's not a list, ie the entry is not duplicated
|
||||
|
||||
|
||||
class TestSheerkaCreateNewConceptFileBased(TestUsingFileBasedSheerka):
|
||||
def test_i_can_add_several_concepts(self):
|
||||
|
||||
@@ -4,6 +4,7 @@ import pytest
|
||||
from core.builtin_concepts import BuiltinConcepts, ReturnValueConcept, UserInputConcept
|
||||
from core.concept import Concept, PROPERTIES_TO_SERIALIZE, ConceptParts
|
||||
from core.sheerka.Sheerka import Sheerka, BASE_NODE_PARSER_CLASS
|
||||
from core.tokenizer import Token, TokenKind, Tokenizer
|
||||
|
||||
from tests.TestUsingFileBasedSheerka import TestUsingFileBasedSheerka
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
@@ -274,6 +275,55 @@ class TestSheerkaUsingMemoryBasedSheerka(TestUsingMemoryBasedSheerka):
|
||||
sheerka = self.get_sheerka()
|
||||
assert not sheerka.is_success(sheerka.new(BuiltinConcepts.TOO_MANY_SUCCESS))
|
||||
|
||||
@pytest.mark.parametrize("concept, expected", [
|
||||
(None, None),
|
||||
("foo", ["foo", "foo2"]),
|
||||
("bar", "bar"),
|
||||
("1001", "foo"), # by id take precedence over by name
|
||||
("plus", "plus"),
|
||||
("a mult b", "mult"),
|
||||
("unknown", None),
|
||||
|
||||
# by tuple
|
||||
((None, None), None),
|
||||
(("foo", None), ["foo", "foo2"]),
|
||||
(("foo", "1002"), "foo2"),
|
||||
((None, "1001"), "foo"),
|
||||
(("plus", None), "plus"),
|
||||
(("1001", None), "1001"),
|
||||
(("unknown", None), None),
|
||||
((None, "unknown"), None),
|
||||
#
|
||||
# by token
|
||||
(Token(TokenKind.CONCEPT, (None, None), 0, 0, 0), None),
|
||||
(Token(TokenKind.CONCEPT, ("foo", None), 0, 0, 0), ["foo", "foo2"]),
|
||||
|
||||
])
|
||||
def test_i_can_resolve_concept(self, concept, expected):
|
||||
sheerka, context, *concepts = self.init_concepts(
|
||||
"foo",
|
||||
Concept("foo", body="another one"),
|
||||
"bar",
|
||||
self.def_concept("plus", "a plus b", ["a", "b"]),
|
||||
Concept("a mult b").def_var("a").def_var("b"),
|
||||
Concept("1001"),
|
||||
)
|
||||
|
||||
cmap = {k: concepts[i] for i, k in enumerate(["foo", "foo2", "bar", "plus", "mult", "1001"])}
|
||||
cmap[None] = None
|
||||
|
||||
if isinstance(expected, list):
|
||||
assert sheerka.resolve(concept) == [cmap[e] for e in expected]
|
||||
else:
|
||||
assert sheerka.resolve(concept) == cmap[expected]
|
||||
|
||||
def test_i_can_resolve_when_searching_by_definition(self):
|
||||
sheerka, context, plus = self.init_concepts(
|
||||
self.def_concept("plus", "a plus b", ["a", "b"]),
|
||||
create_new=True
|
||||
)
|
||||
|
||||
assert sheerka.resolve("a plus b") == plus
|
||||
|
||||
class TestSheerkaUsingFileBasedSheerka(TestUsingFileBasedSheerka):
|
||||
|
||||
|
||||
@@ -198,7 +198,6 @@ def test_encode_concept_key_id():
|
||||
assert core.utils.encode_concept(("key", "id")) == "__C__KEY_key__ID_id__C__"
|
||||
assert core.utils.encode_concept((None, "id")) == "__C__KEY_00None00__ID_id__C__"
|
||||
assert core.utils.encode_concept(("key", None)) == "__C__KEY_key__ID_00None00__C__"
|
||||
assert core.utils.encode_concept(("key", "id"), True) == "__C__USE_CONCEPT__KEY_key__ID_id__C__"
|
||||
assert core.utils.encode_concept(("k + y", "id")) == "__C__KEY_k000y__ID_id__C__"
|
||||
|
||||
concept = Concept("foo").init_key()
|
||||
@@ -209,7 +208,6 @@ def test_encode_concept_key_id():
|
||||
|
||||
|
||||
def test_decode_concept_key_id():
|
||||
assert core.utils.decode_concept("__C__KEY_key__ID_id__C__") == ("key", "id", False)
|
||||
assert core.utils.decode_concept("__C__KEY_00None00__ID_id__C__") == (None, "id", False)
|
||||
assert core.utils.decode_concept("__C__KEY_key__ID_00None00__C__") == ("key", None, False)
|
||||
assert core.utils.decode_concept("__C__USE_CONCEPT__KEY_key__ID_id__C__") == ("key", "id", True)
|
||||
assert core.utils.decode_concept("__C__KEY_key__ID_id__C__") == ("key", "id")
|
||||
assert core.utils.decode_concept("__C__KEY_00None00__ID_id__C__") == (None, "id")
|
||||
assert core.utils.decode_concept("__C__KEY_key__ID_00None00__C__") == ("key", None)
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import ReturnValueConcept, ParserResultConcept, BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from core.concept import Concept, DEFINITION_TYPE_DEF
|
||||
from evaluators.PythonEvaluator import PythonEvaluator
|
||||
from parsers.PythonParser import PythonNode, PythonParser
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
def get_context_name(context):
|
||||
return context.name
|
||||
def get_concept_name(concept):
|
||||
return concept.name
|
||||
|
||||
|
||||
class TestPythonEvaluator(TestUsingMemoryBasedSheerka):
|
||||
@@ -118,23 +118,38 @@ class TestPythonEvaluator(TestUsingMemoryBasedSheerka):
|
||||
context = self.get_context()
|
||||
context.sheerka.add_in_cache(Concept("foo", body="2"))
|
||||
|
||||
parsed = PythonParser().parse(context, "get_context_name(c:foo:)")
|
||||
parsed = PythonParser().parse(context, "get_concept_name(c:foo:)")
|
||||
python_evaluator = PythonEvaluator()
|
||||
python_evaluator.locals["get_context_name"] = get_context_name
|
||||
python_evaluator.locals["get_concept_name"] = get_concept_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)")
|
||||
parsed = PythonParser().parse(context, "get_concept_name(foo)")
|
||||
python_evaluator = PythonEvaluator()
|
||||
python_evaluator.locals["get_context_name"] = get_context_name
|
||||
python_evaluator.locals["get_concept_name"] = get_concept_name
|
||||
evaluated = python_evaluator.eval(context, parsed)
|
||||
|
||||
assert not evaluated.status
|
||||
assert evaluated.body.body.args[0] == "'int' object has no attribute 'name'"
|
||||
|
||||
def test_i_can_call_function_with_complex_concepts(self):
|
||||
sheerka, context, plus, mult = self.init_concepts(
|
||||
self.def_concept("plus", "a plus b", ["a", "b"]),
|
||||
self.def_concept("mult", "a mult b", ["a", "b"]),
|
||||
)
|
||||
|
||||
parsed = PythonParser().parse(context, "is_greater_than(BuiltinConcepts.PRECEDENCE, mult, plus)")
|
||||
python_evaluator = PythonEvaluator()
|
||||
|
||||
evaluated = python_evaluator.eval(context, parsed)
|
||||
|
||||
assert evaluated.status
|
||||
assert sheerka.get_concepts_weights(BuiltinConcepts.PRECEDENCE) == {'1001': 1, '1002': 2}
|
||||
|
||||
|
||||
# @pytest.mark.parametrize("text, concept_key, concept_id, use_concept", [
|
||||
# ("__C__key__C__", "key", None, False),
|
||||
# ("__C__key__id__C__", "key", "id", False),
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import ast
|
||||
|
||||
import core.utils
|
||||
import pytest
|
||||
from core.builtin_concepts import ParserResultConcept, NotForMeConcept
|
||||
from core.tokenizer import Tokenizer, LexerError
|
||||
from parsers.PythonParser import PythonNode, PythonParser, PythonErrorNode
|
||||
import core.utils
|
||||
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
@@ -72,12 +73,16 @@ class TestPythonParser(TestUsingMemoryBasedSheerka):
|
||||
assert res.value.get_value("reason")[0].text == error_text
|
||||
|
||||
def test_i_can_parse_a_concept(self):
|
||||
text = "c:name|key: + 1"
|
||||
text = "c:name|id: + 1"
|
||||
|
||||
parser = PythonParser()
|
||||
res = parser.parse(self.get_context(), text)
|
||||
encoded = core.utils.encode_concept(("name", "id"))
|
||||
|
||||
assert res
|
||||
assert res.value.value == PythonNode(
|
||||
"c:name|key: + 1",
|
||||
ast.parse(core.utils.encode_concept(("name", "key"), True) + "+1", mode="eval"))
|
||||
"c:name|id: + 1",
|
||||
ast.parse(encoded + "+1", mode="eval"))
|
||||
assert res.value.value.concepts == {
|
||||
encoded: ("name", "id")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user