from core.builtin_concepts_ids import BuiltinConcepts from core.concept import Concept from core.global_symbols import OBJECTS_COUNTER_KEY from core.sheerka.services.SheerkaExecute import ParserInput from core.tokenizer import Token, TokenKind from parsers.BaseExpressionParser import ExprNode, NameExprNode from parsers.ExpressionParser import ExpressionParser from parsers.PythonParser import PythonNode from parsers.TokenExpressionParser import NoTokenExprFound, TokenExpressionParser from sheerkapython.python_wrapper import Expando from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka class TestTokenExpressionParser(TestUsingMemoryBasedSheerka): def init_parser(self, my_map=None, create_new=False): if my_map is None: my_map = {} sheerka, context, *updated_concepts = self.init_test().with_concepts( *my_map.values(), create_new=create_new).unpack() parser = TokenExpressionParser() return sheerka, context, parser @staticmethod def get_parser_input(context, expression): expr_parser = ExpressionParser(auto_compile=False) parsed_ret = expr_parser.parse(context, ParserInput(expression)) parsed = parsed_ret.body.body token_expr = Token(TokenKind.EXPR, parsed, 0, 1, 1) return ParserInput(None, [token_expr]) def test_i_cannot_parse_empty_string(self): sheerka, context, parser = self.init_parser() res = parser.parse(context, ParserInput("")) assert not res.status assert sheerka.isinstance(res.body, BuiltinConcepts.IS_EMPTY) def test_i_cannot_parse_when_no_token_expression(self): sheerka, context, parser = self.init_parser() parser_input = ParserInput("not an ExprNode") res = parser.parse(context, parser_input) assert not res.status assert sheerka.isinstance(res.body, BuiltinConcepts.NOT_FOR_ME) assert res.body.body == parser_input assert isinstance(res.body.reason, NoTokenExprFound) def test_i_cannot_parse_when_too_many_token_expression(self): sheerka, context, parser = self.init_parser() expr = NameExprNode(0, 0, [Token(TokenKind.IDENTIFIER, "hello", 0, 1, 1)]) token_expr = Token(TokenKind.EXPR, expr, 0, 1, 1) parser_input = ParserInput(None, [token_expr, token_expr]) res = parser.parse(context, parser_input) assert not res.status assert sheerka.isinstance(res.body, BuiltinConcepts.NOT_FOR_ME) assert res.body.body == parser_input assert isinstance(res.body.reason, NoTokenExprFound) def test_i_can_parse_simple_expression(self): sheerka, context, parser = self.init_parser() parser_input = self.get_parser_input(context, "a + b") res = parser.parse(context, parser_input) assert len(res) == 1 assert res[0].status assert res[0].who == "parsers.TokenExpr" assert sheerka.isinstance(res[0].body, BuiltinConcepts.PARSER_RESULT) assert isinstance(res[0].body.body, PythonNode) def test_i_can_parse_when_concept(self): concepts_map = {"foo": Concept("foo x").def_var("x")} sheerka, context, parser = self.init_parser(concepts_map, True) parser_input = self.get_parser_input(context, "foo a") res = parser.parse(context, parser_input) assert len(res) == 1 assert res[0].status assert sheerka.isinstance(res[0].body, BuiltinConcepts.PARSER_RESULT) assert isinstance(res[0].body.body, PythonNode) python_node = res[0].body.body assert python_node.source == "call_concept(__o_00__, x=a)" def test_i_can_parse_when_concept_using_object_counter(self): concepts_map = {"foo": Concept("foo x").def_var("x")} sheerka, context, parser = self.init_parser(concepts_map, True) parser_input = self.get_parser_input(context, "foo a") objects_counter_entry = Expando(OBJECTS_COUNTER_KEY, {"value": 10}) context.add_to_short_term_memory(OBJECTS_COUNTER_KEY, objects_counter_entry) res = parser.parse(context, parser_input) assert len(res) == 1 assert res[0].status assert sheerka.isinstance(res[0].body, BuiltinConcepts.PARSER_RESULT) assert isinstance(res[0].body.body, PythonNode) python_node = res[0].body.body assert python_node.source == "call_concept(__o_10__, x=a)" objects_counter_entry = context.get_from_short_term_memory(OBJECTS_COUNTER_KEY) assert objects_counter_entry.value == 11 def test_i_can_parse_simple_expression_when_is_question_is_set(self): sheerka, context, parser = self.init_parser() context.add_to_protected_hints(BuiltinConcepts.EVAL_QUESTION_REQUESTED) parser_input = self.get_parser_input(context, "a + b") res = parser.parse(context, parser_input) assert res.status assert res.who == "parsers.TokenExpr" assert sheerka.isinstance(res.body, BuiltinConcepts.PARSER_RESULT) assert isinstance(res.body.body, ExprNode) assert res.body.body.compiled is not None def test_i_can_parse_when_concept_and_is_question_is_set(self): concepts_map = {"isa": Concept("x is a y", pre="is_question()").def_var("x").def_var("y")} sheerka, context, parser = self.init_parser(concepts_map, True) context.add_to_protected_hints(BuiltinConcepts.EVAL_QUESTION_REQUESTED) parser_input = self.get_parser_input(context, "a is a b") objects_counter_entry = Expando(OBJECTS_COUNTER_KEY, {"value": 10}) context.add_to_short_term_memory(OBJECTS_COUNTER_KEY, objects_counter_entry) res = parser.parse(context, parser_input) assert res.status assert sheerka.isinstance(res.body, BuiltinConcepts.PARSER_RESULT) assert isinstance(res.body.body, ExprNode) expr_node = res.body.body compiled_0 = expr_node.compiled[0] assert compiled_0.return_value.body.body.source == "evaluate_question(__o_10__, x=a, y=b)" objects_counter_entry = context.get_from_short_term_memory(OBJECTS_COUNTER_KEY) assert objects_counter_entry.value == 11 def test_obj_counter_is_not_updated_when_error(self): concepts_map = {} sheerka, context, parser = self.init_parser(concepts_map, True) parser_input = self.get_parser_input(context, "foo a") objects_counter_entry = Expando(OBJECTS_COUNTER_KEY, {"value": 10}) context.add_to_short_term_memory(OBJECTS_COUNTER_KEY, objects_counter_entry) res = parser.parse(context, parser_input) assert not res.status assert sheerka.isinstance(res.body, BuiltinConcepts.ERROR) objects_counter_entry = context.get_from_short_term_memory(OBJECTS_COUNTER_KEY) assert objects_counter_entry.value == 10 def test_obj_counter_is_not_updated_when_error_and_is_question_is_set(self): concepts_map = {} sheerka, context, parser = self.init_parser(concepts_map, True) context.add_to_protected_hints(BuiltinConcepts.EVAL_QUESTION_REQUESTED) parser_input = self.get_parser_input(context, "a is a b") objects_counter_entry = Expando(OBJECTS_COUNTER_KEY, {"value": 10}) context.add_to_short_term_memory(OBJECTS_COUNTER_KEY, objects_counter_entry) res = parser.parse(context, parser_input) assert not res.status assert sheerka.isinstance(res.body, BuiltinConcepts.ERROR) objects_counter_entry = context.get_from_short_term_memory(OBJECTS_COUNTER_KEY) assert objects_counter_entry.value == 10