import ast import pytest from core.builtin_concepts import ParserResultConcept from core.sheerka import Sheerka, ExecutionContext from core.tokenizer import Tokenizer, LexerError from parsers.PythonParser import PythonNode, PythonParser, PythonErrorNode from sdp.sheerkaDataProvider import Event def get_context(): sheerka = Sheerka(skip_builtins_in_db=True) sheerka.initialize("mem://") return ExecutionContext("test", Event(), sheerka) @pytest.mark.parametrize("text, expected", [ ("1+1", PythonNode("1+1", ast.parse("1+1", mode="eval"))), ("a=10", PythonNode("a=10", ast.parse("a=10", mode="exec"))), ]) def test_i_can_parse_a_simple_expression(text, expected): parser = PythonParser() res = parser.parse(get_context(), text) assert res.status assert res.who == parser.name assert isinstance(res.value, ParserResultConcept) assert res.value.value == expected @pytest.mark.parametrize("text, expected", [ ("1+1", PythonNode("1+1", ast.parse("1+1", mode="eval"))), ("a=10", PythonNode("a=10", ast.parse("a=10", mode="exec"))), ]) def test_i_can_parse_from_tokens(text, expected): parser = PythonParser() tokens = list(Tokenizer(text)) res = parser.parse(get_context(), tokens) assert res.status assert res.who == parser.name assert isinstance(res.value, ParserResultConcept) assert res.value.value == expected @pytest.mark.parametrize("text", [ "1+", "'name", "foo = 'name" ]) def test_i_can_detect_error(text): text = "1+" parser = PythonParser() res = parser.parse(get_context(), text) assert not res.status assert res.who == parser.name assert isinstance(res.value, ParserResultConcept) assert isinstance(res.value.value[0], PythonErrorNode) assert isinstance(res.value.value[0].exception, SyntaxError) @pytest.mark.parametrize("text, error_msg, error_text", [ ("c::", "Concept name not found", ""), ("c:: + 1", "Concept name not found", ""), ]) def test_i_can_detect_lexer_errors(text, error_msg, error_text): parser = PythonParser() res = parser.parse(get_context(), text) assert not res.status assert isinstance(res.body, ParserResultConcept) assert isinstance(res.body.body[0], LexerError) assert res.body.body[0].message == error_msg assert res.body.body[0].text == error_text def test_i_can_parse_a_concept(): text = "c:concept_name: + 1" parser = PythonParser() res = parser.parse(get_context(), text) assert res assert res.value.value == PythonNode( "c:concept_name: + 1", ast.parse("__C__USE_CONCEPT__concept_name__C__+1", mode="eval"))