Files
Sheerka-Old/tests/parsers/test_PythonParser.py

122 lines
4.7 KiB
Python

import ast
import core.utils
import pytest
from core.builtin_concepts import ParserResultConcept, NotForMeConcept, BuiltinConcepts
from core.sheerka.services.SheerkaExecute import ParserInput
from core.tokenizer import LexerError, TokenKind
from parsers.PythonParser import PythonNode, PythonParser, PythonErrorNode, ConceptDetectedError
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
class TestPythonParser(TestUsingMemoryBasedSheerka):
@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(self, text, expected):
parser = PythonParser()
res = parser.parse(self.get_context(), ParserInput(text))
assert res.status
assert res.who == parser.name
assert isinstance(res.value, ParserResultConcept)
assert res.value.value == expected
@pytest.mark.parametrize("text", [
"1+",
"&#é",
])
def test_i_can_detect_python_error(self, text):
parser = PythonParser()
res = parser.parse(self.get_context(), ParserInput(text))
assert not res.status
assert res.who == parser.name
assert isinstance(res.value, NotForMeConcept)
assert res.value.body == text
assert len(res.value.get_value("reason")) == 1
assert isinstance(res.value.get_value("reason")[0], PythonErrorNode)
assert isinstance(res.value.get_value("reason")[0].exception, SyntaxError)
@pytest.mark.parametrize("text, error_msg, error_text", [
("c::", "Concept identifiers not found", ""),
("c:: + 1", "Concept identifiers not found", ""),
])
def test_i_can_detect_lexer_errors(self, text, error_msg, error_text):
parser = PythonParser()
res = parser.parse(self.get_context(), ParserInput(text))
assert not res.status
assert isinstance(res.value, NotForMeConcept)
assert res.value.body == text
assert len(res.value.get_value("reason")) == 1
assert isinstance(res.value.get_value("reason")[0], LexerError)
assert res.value.get_value("reason")[0].message == error_msg
assert res.value.get_value("reason")[0].text == error_text
def test_i_can_parse_a_concept(self):
text = "c:name|id: + 1"
parser = PythonParser()
res = parser.parse(self.get_context(), ParserInput(text))
encoded = core.utils.encode_concept(("name", "id"))
assert res
assert res.value.source == "c:name|id: + 1"
assert res.value.value == PythonNode(
"__C__KEY_name__ID_id__C__ + 1",
ast.parse(encoded + "+1", mode="eval"))
assert len(res.value.value.objects) == 1
assert res.value.value.objects[encoded].type == TokenKind.CONCEPT
assert res.value.value.objects[encoded].value == ("name", "id")
def test_i_can_parse_a_rule(self):
text = "r:name|id: + 1"
parser = PythonParser()
res = parser.parse(self.get_context(), ParserInput(text))
encoded = core.utils.encode_concept(("name", "id"), "R")
assert res
assert res.value.source == "r:name|id: + 1"
assert res.value.value == PythonNode(
"__R__KEY_name__ID_id__R__ + 1",
ast.parse(encoded + "+1", mode="eval"))
assert len(res.value.value.objects) == 1
assert res.value.value.objects[encoded].type == TokenKind.RULE
assert res.value.value.objects[encoded].value == ("name", "id")
def test_i_can_parse_a_rule_2(self):
text = "r:name|id:.name"
parser = PythonParser()
res = parser.parse(self.get_context(), ParserInput(text))
encoded = core.utils.encode_concept(("name", "id"), "R")
assert res
assert res.value.source == "r:name|id:.name"
assert res.value.value == PythonNode(
"__R__KEY_name__ID_id__R__.name",
ast.parse(encoded + ".name", mode="eval"))
assert len(res.value.value.objects) == 1
assert res.value.value.objects[encoded].type == TokenKind.RULE
assert res.value.value.objects[encoded].value == ("name", "id")
@pytest.mark.parametrize("text, expected_id", [
("foo", "foo"),
("c:foo:", "__C__KEY_foo__ID_00None00__C__")
])
def test_i_cannot_parse_simple_concepts(self, text, expected_id):
sheerka, context, foo = self.init_concepts("foo")
parser = PythonParser()
res = parser.parse(context, ParserInput(text))
assert not res.status
assert sheerka.isinstance(res.value, BuiltinConcepts.NOT_FOR_ME)
assert res.value.reason == [ConceptDetectedError(expected_id)]