Enhanced complex concepts handling
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
import ast
|
||||
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import ParserResultConcept, BuiltinConcepts, ReturnValueConcept
|
||||
from core.concept import Concept
|
||||
from core.sheerka import Sheerka, ExecutionContext
|
||||
from core.tokenizer import Token, TokenKind, Tokenizer
|
||||
from parsers.ConceptLexerParser import ConceptNode, UnrecognizedTokensNode
|
||||
from parsers.PythonParser import PythonNode, PythonErrorNode
|
||||
from parsers.PythonWithConceptsParser import PythonWithConceptsParser
|
||||
from sdp.sheerkaDataProvider import Event
|
||||
|
||||
|
||||
def get_context():
|
||||
sheerka = Sheerka(skip_builtins_in_db=True)
|
||||
sheerka.initialize("mem://")
|
||||
return ExecutionContext("test", Event(), sheerka)
|
||||
|
||||
|
||||
def get_ret_from(*args):
|
||||
result = []
|
||||
index = 0
|
||||
for item in args:
|
||||
if isinstance(item, Concept):
|
||||
tokens = [Token(TokenKind.IDENTIFIER, item.name, 0, 0, 0)]
|
||||
result.append(ConceptNode(item, index, index, tokens, item.name))
|
||||
index += 1
|
||||
else:
|
||||
tokens = list(Tokenizer(item))
|
||||
result.append(UnrecognizedTokensNode(index, index + len(tokens) - 1, tokens))
|
||||
index += len(tokens)
|
||||
|
||||
return ReturnValueConcept("who", False, ParserResultConcept(parser="name", value=result))
|
||||
|
||||
|
||||
def to_str_ast(expression):
|
||||
return PythonNode.get_dump(ast.parse(expression, mode="eval"))
|
||||
|
||||
|
||||
@pytest.mark.parametrize("text", [
|
||||
"not parser result",
|
||||
ParserResultConcept(value="not a list"),
|
||||
ParserResultConcept(value=[]),
|
||||
ParserResultConcept(value=["not a Node"]),
|
||||
])
|
||||
def test_not_interested(text):
|
||||
context = get_context()
|
||||
|
||||
res = PythonWithConceptsParser().parse(context, text)
|
||||
assert res is None
|
||||
|
||||
|
||||
def test_i_can_parse_concepts_and_python():
|
||||
context = get_context()
|
||||
foo = Concept("foo")
|
||||
input_return_value = get_ret_from(foo, " + 1")
|
||||
|
||||
parser = PythonWithConceptsParser()
|
||||
result = parser.parse(context, input_return_value.body)
|
||||
wrapper = result.value
|
||||
return_value = result.value.value
|
||||
|
||||
assert result.status
|
||||
assert result.who == parser.name
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert wrapper.source == "foo + 1"
|
||||
assert isinstance(return_value, PythonNode)
|
||||
assert return_value.source == "foo + 1"
|
||||
assert return_value.get_dump(return_value.ast_) == to_str_ast("__C__foo__C__ + 1")
|
||||
assert return_value.concepts["__C__foo__C__"] == foo
|
||||
|
||||
|
||||
def test_i_can_parse_concepts_and_python_when_concept_is_known():
|
||||
context = get_context()
|
||||
foo = Concept("foo")
|
||||
foo = context.sheerka.create_new_concept(context, foo).body.body
|
||||
input_return_value = get_ret_from(foo, " + 1")
|
||||
|
||||
parser = PythonWithConceptsParser()
|
||||
result = parser.parse(context, input_return_value.body)
|
||||
wrapper = result.value
|
||||
return_value = result.value.value
|
||||
|
||||
assert result.status
|
||||
assert result.who == parser.name
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert wrapper.source == "foo + 1"
|
||||
assert isinstance(return_value, PythonNode)
|
||||
assert return_value.source == "foo + 1"
|
||||
assert return_value.get_dump(return_value.ast_) == to_str_ast("__C__foo__1001__C__ + 1")
|
||||
assert return_value.concepts["__C__foo__1001__C__"] == foo
|
||||
|
||||
|
||||
def test_i_can_parse_when_concept_name_has_invalid_characters():
|
||||
context = get_context()
|
||||
foo = Concept("foo et > (,")
|
||||
foo = context.sheerka.create_new_concept(context, foo).body.body
|
||||
input_return_value = get_ret_from(foo, " + 1")
|
||||
|
||||
parser = PythonWithConceptsParser()
|
||||
result = parser.parse(context, input_return_value.body)
|
||||
return_value = result.value.value
|
||||
|
||||
assert result.status
|
||||
assert return_value.concepts["__C__foo0et000000__1001__C__"] == foo
|
||||
|
||||
|
||||
def test_python_ids_mappings_are_correct_when_concepts_with_the_same_name():
|
||||
context = get_context()
|
||||
foo1 = Concept("foo")
|
||||
foo2 = Concept("foo")
|
||||
foo3 = context.sheerka.create_new_concept(context, Concept("foo", body="foo3")).body.body
|
||||
foo4 = context.sheerka.create_new_concept(context, Concept("foo", body="foo4")).body.body
|
||||
|
||||
input_return_value = get_ret_from(foo1, "+", foo2, "+", foo3, "+", foo4)
|
||||
|
||||
parser = PythonWithConceptsParser()
|
||||
result = parser.parse(context, input_return_value.body)
|
||||
return_value = result.value.value
|
||||
|
||||
assert result.status
|
||||
assert return_value.concepts["__C__foo__C__"] == foo1
|
||||
assert return_value.concepts["__C__foo_1__C__"] == foo2
|
||||
assert return_value.concepts["__C__foo__1001__C__"] == foo3
|
||||
assert return_value.concepts["__C__foo__1002__C__"] == foo4
|
||||
|
||||
|
||||
def test_i_cannot_parse_if_syntax_error():
|
||||
context = get_context()
|
||||
foo = Concept("foo")
|
||||
foo = context.sheerka.create_new_concept(context, foo).body.body
|
||||
input_return_value = get_ret_from(foo, " + ")
|
||||
|
||||
parser = PythonWithConceptsParser()
|
||||
result = parser.parse(context, input_return_value.body)
|
||||
wrapper = result.value
|
||||
return_value = result.value.value
|
||||
|
||||
assert not result.status
|
||||
assert context.sheerka.isinstance(wrapper, BuiltinConcepts.PARSER_RESULT)
|
||||
assert isinstance(return_value[0], PythonErrorNode)
|
||||
Reference in New Issue
Block a user