import pytest from base import BaseParserTest from core.BuiltinConcepts import BuiltinConcepts from core.error import ErrorContext from evaluators.PythonParser import PythonParser from helpers import _rv, _rvf from parsers.ParserInput import ParserInput class TestPythonParser(BaseParserTest): @pytest.fixture() def evaluator(self, sheerka): return sheerka.evaluators[PythonParser.NAME] def test_i_can_match(self, sheerka, context, evaluator): ret_val = _rv(sheerka.newn(BuiltinConcepts.PARSER_INPUT, pi=ParserInput("a command"))) assert evaluator.matches(context, ret_val).status is True ret_val = _rv(sheerka.newn(BuiltinConcepts.UNKNOWN_CONCEPT)) # it responds to USER_INPUT only assert evaluator.matches(context, ret_val).status is False ret_val = _rvf(sheerka.newn(BuiltinConcepts.PARSER_INPUT, pi=ParserInput("a command"))) # status should be true assert evaluator.matches(context, ret_val).status is False @pytest.mark.parametrize("text", [ "1 + 1", "a = 20" ]) def test_i_can_parse_python(self, sheerka, context, evaluator, text): start = self.get_parser_input(context, text) res = evaluator.eval(context, None, start) assert res.eaten == [start] assert len(res.new) == 1 ret_val = res.new[0] assert ret_val.status is True assert sheerka.isinstance(ret_val.value, BuiltinConcepts.PYTHON_CODE) assert ret_val.parents == [start] def test_invalid_python_are_rejected(self, sheerka, context, evaluator): text = "1 + " start = self.get_parser_input(context, text) res = evaluator.eval(context, None, start) assert res.eaten == [] assert len(res.new) == 1 ret_val = res.new[0] assert ret_val.status is False assert isinstance(ret_val.value, ErrorContext) assert ret_val.parents == [start] def test_i_can_detect_concepts(self, sheerka, context, evaluator): start = self.get_parser_input(context, "c:one: + c:two:") res = evaluator.eval(context, None, start) assert res.eaten == [start] assert len(res.new) == 1 ret_val = res.new[0] assert ret_val.status is True assert sheerka.isinstance(ret_val.value, BuiltinConcepts.PYTHON_CODE) assert ret_val.parents == [start] assert len(ret_val.value.pf.namespace) == 2 assert ret_val.value.pf.namespace["__C__KEY_one__ID_00None00__C__"].value == ("one", None) assert ret_val.value.pf.namespace["__C__KEY_two__ID_00None00__C__"].value == ("two", None)