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.MultipleConceptsParser import MultipleConceptsParser from parsers.PythonParser import PythonNode, PythonErrorNode from parsers.PythonWithConceptsParser import PythonWithConceptsParser from sdp.sheerkaDataProvider import Event multiple_concepts_parser = MultipleConceptsParser() 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=multiple_concepts_parser, 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)