Added bnf when adding a new concept + Started logging filtering
This commit is contained in:
@@ -0,0 +1,181 @@
|
||||
import ast
|
||||
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import ReturnValueConcept, ParserResultConcept, BuiltinConcepts
|
||||
from core.concept import VARIABLE_PREFIX, ConceptParts, Concept
|
||||
from core.sheerka import Sheerka, ExecutionContext
|
||||
from core.tokenizer import Tokenizer
|
||||
from evaluators.AddConceptEvaluator import AddConceptEvaluator
|
||||
from parsers.BaseParser import BaseParser
|
||||
from parsers.ConceptLexerParser import Sequence, RegexParser, StrMatch, ZeroOrMore, ConceptMatch
|
||||
from parsers.DefaultParser import DefConceptNode, NameNode
|
||||
from parsers.ExactConceptParser import ExactConceptParser
|
||||
from parsers.PythonParser import PythonNode, PythonParser
|
||||
|
||||
|
||||
def get_context():
|
||||
sheerka = Sheerka(skip_builtins_in_db=True)
|
||||
sheerka.initialize("mem://")
|
||||
return ExecutionContext("test", "xxx", sheerka)
|
||||
|
||||
|
||||
def get_concept(name, where=None, pre=None, post=None, body=None, definition=None):
|
||||
concept = DefConceptNode([], name=NameNode(list(Tokenizer(name))))
|
||||
|
||||
if body:
|
||||
concept.body = get_concept_part(body)
|
||||
if where:
|
||||
concept.where = get_concept_part(where)
|
||||
if pre:
|
||||
concept.pre = get_concept_part(pre)
|
||||
if post:
|
||||
concept.post = get_concept_part(post)
|
||||
if definition:
|
||||
concept.definition = definition
|
||||
|
||||
return ReturnValueConcept(BaseParser.PREFIX + "some_name", True, ParserResultConcept(value=concept))
|
||||
|
||||
|
||||
def get_concept_part(part):
|
||||
if isinstance(part, str):
|
||||
node = PythonNode(part, ast.parse(part, mode="eval"))
|
||||
return ReturnValueConcept(
|
||||
who="Parsers:DefaultParser",
|
||||
status=True,
|
||||
value=ParserResultConcept(
|
||||
source=part,
|
||||
parser=PythonParser(),
|
||||
value=node))
|
||||
|
||||
if isinstance(part, PythonNode):
|
||||
return ReturnValueConcept(
|
||||
who="Parsers:DefaultParser",
|
||||
status=True,
|
||||
value=ParserResultConcept(
|
||||
source=part.source,
|
||||
parser=PythonParser(),
|
||||
value=part))
|
||||
|
||||
if isinstance(part, ReturnValueConcept):
|
||||
return part
|
||||
|
||||
|
||||
def get_concept_definition(source, parsing_expression):
|
||||
return ReturnValueConcept(
|
||||
who="Parsers:RegexParser",
|
||||
status=True,
|
||||
value=ParserResultConcept(
|
||||
source=source,
|
||||
parser=RegexParser(),
|
||||
value=parsing_expression
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@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(ret_val, expected):
|
||||
context = get_context()
|
||||
assert AddConceptEvaluator().matches(context, ret_val) == expected
|
||||
|
||||
|
||||
def test_that_the_source_is_correctly_set():
|
||||
context = get_context()
|
||||
def_concept_return_value = get_concept(
|
||||
name="hello a",
|
||||
definition=get_concept_definition("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_ast_is_correctly_initialized():
|
||||
context = get_context()
|
||||
def_concept_return_value = get_concept(
|
||||
name="hello a",
|
||||
definition=get_concept_definition("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 ConceptParts.WHERE in created_concept.cached_asts
|
||||
assert ConceptParts.PRE in created_concept.cached_asts
|
||||
assert ConceptParts.BODY in created_concept.cached_asts
|
||||
assert ConceptParts.POST not in created_concept.cached_asts
|
||||
|
||||
|
||||
def test_that_the_new_concept_is_correctly_saved():
|
||||
context = get_context()
|
||||
def_concept_return_value = get_concept(
|
||||
name="hello a",
|
||||
definition=get_concept_definition("hello a", Sequence(StrMatch("hello"), StrMatch("a"))),
|
||||
where="isinstance(a, str )",
|
||||
pre="a is not None",
|
||||
body="print('hello' + a)")
|
||||
|
||||
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.props) == 1
|
||||
assert "a" in from_db.props
|
||||
|
||||
assert from_db.cached_asts == {} # ast is not saved in db
|
||||
|
||||
|
||||
def test_i_can_get_props_from_python_node():
|
||||
ret_val = get_concept_part("isinstance(a, str)")
|
||||
context = get_context()
|
||||
|
||||
assert AddConceptEvaluator.get_props(context.sheerka, ret_val, ["a"]) == ["a"]
|
||||
|
||||
|
||||
def test_i_can_get_props_from_another_concept():
|
||||
concept = Concept("hello").set_prop("a").set_prop("b")
|
||||
ret_val = ReturnValueConcept(who="some_parser",
|
||||
status=True,
|
||||
value=ParserResultConcept(value=concept))
|
||||
|
||||
assert AddConceptEvaluator.get_props(get_context(), ret_val, []) == ["a", "b"]
|
||||
|
||||
|
||||
def test_i_can_get_props_from_definition():
|
||||
parsing_expression = Sequence(ConceptMatch('mult'), ZeroOrMore(Sequence(StrMatch("+"), ConceptMatch("add"))))
|
||||
ret_val = get_concept_definition("mult (('+'|'-') add)?", parsing_expression)
|
||||
|
||||
assert AddConceptEvaluator.get_props(get_context(), ret_val, []) == ["add", "mult"]
|
||||
Reference in New Issue
Block a user