Fixed #55 : DefConceptParser: failed to recognize concept

Fixed #62 : DefConceptParser: parsing error
Fixed #64 : DefConceptParser: Failed to parse when too many concept keyword
Fixed #65 : DefConceptParser : Add auto_eval keyword
Fixed #66 : DefConceptParser : Add def_var keyword
Fixed #67 : Add get_errors()
This commit is contained in:
2021-04-13 15:15:17 +02:00
parent 81e67147e9
commit bef5f3208c
17 changed files with 838 additions and 235 deletions
+2 -2
View File
@@ -45,7 +45,7 @@ class InitTestHelper:
c.get_metadata().definition_type = DEFINITION_TYPE_BNF
else:
raise Exception(f"Error in bnf definition '{c.get_metadata().definition}'",
self.sheerka.get_error(res))
self.sheerka.get_errors(res))
if create_new:
self.sheerka.create_new_concept(self.context, c)
@@ -89,7 +89,7 @@ class InitTestHelper:
res = self.sheerka.create_new_rule(self.context, rule)
if not res.status:
raise Exception(f"Error in rule definition '{res.body}'",
self.sheerka.get_error(res))
self.sheerka.get_errors(res))
self.items.append(res.body.body)
else:
self.items.append(rule)
+136 -2
View File
@@ -3,13 +3,14 @@ import os
import pytest
from conftest import SHEERKA_TEST_FOLDER
from core.builtin_concepts import BuiltinConcepts, ReturnValueConcept, UserInputConcept
from core.builtin_concepts import BuiltinConcepts, ReturnValueConcept, UserInputConcept, UnknownConcept
from core.builtin_concepts_ids import AllBuiltinConcepts
from core.concept import Concept, PROPERTIES_TO_SERIALIZE, ConceptParts, get_concept_attrs
from core.global_symbols import NotInit
from core.sheerka.Sheerka import Sheerka, BASE_NODE_PARSER_CLASS
from core.sheerka.services.SheerkaConceptManager import SheerkaConceptManager
from core.sheerka.services.SheerkaConceptManager import SheerkaConceptManager, ValueNotFound
from core.tokenizer import Token, TokenKind
from parsers.PythonParser import PythonErrorNode
from tests.TestUsingFileBasedSheerka import TestUsingFileBasedSheerka
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
@@ -425,6 +426,139 @@ class TestSheerkaUsingMemoryBasedSheerka(TestUsingMemoryBasedSheerka):
assert not res.status
assert sheerka.isinstance(res.body, BuiltinConcepts.ONTOLOGY_ALREADY_DEFINED)
@pytest.mark.parametrize("obj, expected", [
("a string", []),
(True, []),
(False, []),
(Concept("foo"), []),
(Concept("foo", body=False).auto_init(), []),
(UnknownConcept(), [UnknownConcept()]),
(Concept("foo", body=UnknownConcept()).auto_init(), [UnknownConcept()]),
(PythonErrorNode("msg", None), [PythonErrorNode("msg", None)])
])
def test_i_can_get_error_for_simple_objects(self, obj, expected):
sheerka, context = self.init_test().unpack()
assert sheerka.get_errors(obj) == expected
def test_i_can_get_error_when_builtin_concept_in_error(self):
sheerka, context = self.init_test().unpack()
obj = sheerka.new(BuiltinConcepts.ONTOLOGY_ALREADY_DEFINED)
assert sheerka.get_errors(obj) == [obj]
def test_i_can_get_error_when_return_value(self):
sheerka, context = self.init_test().unpack()
error = sheerka.err("an error")
ret_val = ReturnValueConcept("Test", False, sheerka.err("an error"))
assert sheerka.get_errors(ret_val) == [error]
def test_i_can_get_inner_error(self):
sheerka, context = self.init_test().unpack()
error = sheerka.err("an error")
ret_val = ReturnValueConcept("Test", False, sheerka.err("an error"))
assert sheerka.get_errors(ret_val) == [error]
def test_i_can_get_error_when_embedded_errors(self):
sheerka, context = self.init_test().unpack()
concept_eval_error = sheerka.new(BuiltinConcepts.CONCEPT_EVAL_ERROR)
unknown_concept = sheerka.new(BuiltinConcepts.UNKNOWN_CONCEPT)
not_an_error = sheerka.new(BuiltinConcepts.AUTO_EVAL)
error = sheerka.err([concept_eval_error, unknown_concept, not_an_error])
ret_val = ReturnValueConcept("Test", False, error)
errors_found = sheerka.get_errors(ret_val)
assert errors_found == [error, concept_eval_error, unknown_concept]
def test_i_can_get_error_from_list(self):
sheerka, context = self.init_test().unpack()
concept_eval_error = sheerka.new(BuiltinConcepts.CONCEPT_EVAL_ERROR)
unknown_concept = sheerka.new(BuiltinConcepts.UNKNOWN_CONCEPT)
not_an_error = sheerka.new(BuiltinConcepts.AUTO_EVAL)
error = sheerka.err([concept_eval_error, unknown_concept, not_an_error])
ret_val_1 = ReturnValueConcept("Test", False, error)
python_error = PythonErrorNode("msg", Exception())
value_not_found = ValueNotFound("item", "value")
multiple_error = sheerka.new(BuiltinConcepts.MULTIPLE_ERRORS, body=[python_error, value_not_found])
ret_val_2 = ReturnValueConcept("Test", False, multiple_error)
errors_found = sheerka.get_errors([ret_val_1, ret_val_2])
assert errors_found == [error, concept_eval_error, unknown_concept,
multiple_error, python_error, value_not_found]
def test_i_can_filter_error_by_concept_key(self):
sheerka, context = self.init_test().unpack()
concept_eval_error = sheerka.new(BuiltinConcepts.CONCEPT_EVAL_ERROR)
unknown_concept = sheerka.new(BuiltinConcepts.UNKNOWN_CONCEPT)
python_error = PythonErrorNode("msg", Exception())
error = sheerka.err([concept_eval_error, unknown_concept, python_error])
ret_val = ReturnValueConcept("Test", False, error)
errors_found = sheerka.get_errors(ret_val, __type=BuiltinConcepts.CONCEPT_EVAL_ERROR)
assert errors_found == [concept_eval_error]
def test_i_can_filter_error_by_class_name(self):
sheerka, context = self.init_test().unpack()
concept_eval_error = sheerka.new(BuiltinConcepts.CONCEPT_EVAL_ERROR)
unknown_concept = sheerka.new(BuiltinConcepts.UNKNOWN_CONCEPT)
python_error = PythonErrorNode("msg", Exception())
error = sheerka.err([concept_eval_error, unknown_concept, python_error])
ret_val = ReturnValueConcept("Test", False, error)
errors_found = sheerka.get_errors(ret_val, __type="PythonErrorNode")
assert errors_found == [python_error]
def test_i_can_filter_error_by_concept_attribute(self):
sheerka, context = self.init_test().unpack()
concept_eval_error = sheerka.new(BuiltinConcepts.CONCEPT_EVAL_ERROR)
unknown_concept = sheerka.new(BuiltinConcepts.UNKNOWN_CONCEPT, concept_ref="a_concept_ref")
python_error = PythonErrorNode("msg", Exception())
error = sheerka.err([concept_eval_error, unknown_concept, python_error])
ret_val = ReturnValueConcept("Test", False, error)
errors_found = sheerka.get_errors(ret_val, concept_ref="a_concept_ref")
assert errors_found == [unknown_concept]
def test_i_can_filter_error_by_class_attribute(self):
sheerka, context = self.init_test().unpack()
concept_eval_error = sheerka.new(BuiltinConcepts.CONCEPT_EVAL_ERROR)
unknown_concept = sheerka.new(BuiltinConcepts.UNKNOWN_CONCEPT, concept_ref="a_concept_ref")
python_error = PythonErrorNode("error source", Exception())
error = sheerka.err([concept_eval_error, unknown_concept, python_error])
ret_val = ReturnValueConcept("Test", False, error)
errors_found = sheerka.get_errors(ret_val, source="error source")
assert errors_found == [python_error]
def test_i_can_filter_error_on_multiple_criteria(self):
sheerka, context = self.init_test().unpack()
concept_eval_error = sheerka.new(BuiltinConcepts.CONCEPT_EVAL_ERROR)
unknown_concept = sheerka.new(BuiltinConcepts.UNKNOWN_CONCEPT, concept_ref="a_concept_ref")
value_not_found = ValueNotFound("an_item", "a value")
error = sheerka.err([concept_eval_error, unknown_concept, value_not_found])
ret_val = ReturnValueConcept("Test", False, error)
errors_found = sheerka.get_errors(ret_val, __type="ValueNotFound", item="an_item", value="a value")
assert errors_found == [value_not_found]
def test_i_cannot_get_error_when_return_value_s_status_is_true(self):
sheerka, context = self.init_test().unpack()
ret_val = ReturnValueConcept("Test", True, sheerka.err("an error"))
assert sheerka.get_errors(ret_val) == []
class TestSheerkaUsingFileBasedSheerka(TestUsingFileBasedSheerka):
+115 -58
View File
@@ -7,7 +7,7 @@ from core.concept import VARIABLE_PREFIX, Concept, DEFINITION_TYPE_BNF, DEFINITI
from core.sheerka.services.SheerkaConceptManager import NoFirstTokenError
from core.sheerka.services.SheerkaExecute import ParserInput
from core.tokenizer import Tokenizer
from evaluators.DefConceptEvaluator import DefConceptEvaluator
from evaluators.DefConceptEvaluator import DefConceptEvaluator, PossibleVariable, CertainVariable
from parsers.BaseParser import BaseParser
from parsers.BnfDefinitionParser import BnfDefinitionParser
from parsers.BnfNodeParser import Sequence, StrMatch, ZeroOrMore, ConceptExpression, VariableExpression
@@ -144,20 +144,112 @@ class TestDefConceptEvaluator(TestUsingMemoryBasedSheerka):
assert created_concept.get_metadata().definition == "hello a"
assert created_concept.get_metadata().definition_type == "def"
def test_i_can_add_concept_with_the_correct_variables_when_referencing_other_concepts(self):
@pytest.mark.parametrize("expression, name, expected", [
("isinstance(a, str)", "a b", {"a"}),
("a.location = b", "a is in b", {"a", "b"}),
("a.location = b", "'a' is in b", {"b"}),
("date.today()", "what is the date", set()),
("a.location", "where is a", {"a"})
])
def test_i_can_get_variables_from_python_node_when_long_name(self, expression, name, expected):
ret_val = self.get_concept_part(expression)
context = self.get_context()
def_concept_return_value = self.get_def_concept(
name="x plus y",
where=self.pretval(Concept("u is a v").def_var("u").def_var("v"), source="x is a number"),
body=self.pretval(Concept("add a b").def_var("a").def_var("b"), source="add x y"), )
evaluated = DefConceptEvaluator().eval(context, def_concept_return_value)
resolved_expected = [PossibleVariable(e) for e in expected]
assert DefConceptEvaluator.get_variables(context, ret_val, name.split()) == resolved_expected
def test_i_can_get_variables_when_keywords(self):
sheerka, context = self.init_concepts()
def_concept = self.get_def_concept("condition pre").value.value
name_to_use = DefConceptEvaluator.get_name_to_use(def_concept)
concept_part = self.get_concept_part("pre")
assert DefConceptEvaluator.get_variables(context, concept_part, name_to_use) == [PossibleVariable("pre")]
def test_i_can_get_variable_when_rule_is_defined(self):
sheerka, context = self.init_test().unpack()
def_concept_parser = DefConceptParser()
parsed_ret_val = def_concept_parser.parse(context, ParserInput("def concept rule x as r:|x:"))
assert parsed_ret_val.status # sanity check
evaluated = DefConceptEvaluator().eval(context, parsed_ret_val)
assert evaluated.status
assert evaluated.body.body.key == "rule __var__0"
assert evaluated.body.body.get_metadata().variables == [("x", None)]
def test_i_cannot_get_variables_from_python_node_when_name_has_only_one_token(self):
ret_val = self.get_concept_part("isinstance(a, str)")
context = self.get_context()
assert DefConceptEvaluator.get_variables(context, ret_val, ["a"]) == []
def test_i_can_get_variables_from_definition(self):
parsing_expression = Sequence(ConceptExpression('mult'),
ZeroOrMore(Sequence(StrMatch("+"), ConceptExpression("add"))))
ret_val = self.get_return_value("mult (('+'|'-') add)?", parsing_expression)
expected = [CertainVariable("mult"), CertainVariable("add")]
assert DefConceptEvaluator.get_variables(self.get_context(), ret_val, []) == expected
def test_i_can_get_variable_from_bnf_definition_2(self):
sheerka, context, one, two = self.init_concepts("one", "two")
text = "def concept twenties from bnf 'twenty' (one|two)=unit as 20 + unit"
def_ret_val = DefConceptParser().parse(context, ParserInput(text))
concept_definition = def_ret_val.value.body.definition
expected = [CertainVariable("unit"), CertainVariable("one"), CertainVariable("two")]
assert DefConceptEvaluator.get_variables(context, concept_definition, []) == expected
def test_i_can_recognize_variables_when_referencing_other_concepts(self):
sheerka, context, isa_concept = self.init_concepts(Concept("x is an y").def_var("x").def_var("y"))
text = "def concept what x is y pre is_question() where x is an adjective as get_attr(x, y)"
def_ret_val = DefConceptParser().parse(context, ParserInput(text))
evaluated = DefConceptEvaluator().eval(context, def_ret_val)
new_concept = evaluated.body.body
assert evaluated.status
assert context.sheerka.isinstance(evaluated.body, BuiltinConcepts.NEW_CONCEPT)
assert new_concept.get_metadata().variables == [('x', None), ('y', None)]
created_concept = evaluated.body.body
assert created_concept.get_metadata().variables == [("x", None), ("y", None)]
def test_i_can_recognize_variables_when_given_in_concept_definition(self):
sheerka, context = self.init_test().unpack()
text = "def concept a plus b as a + b def_var plus"
def_ret_val = DefConceptParser().parse(context, ParserInput(text))
evaluated = DefConceptEvaluator().eval(context, def_ret_val)
new_concept = evaluated.body.body
assert evaluated.status
assert new_concept.get_metadata().variables == [('plus', None)]
def test_i_can_recognize_variables_when_referencing_other_concepts_with_variable_mapping(self):
sheerka, context, number, isa, add = self.init_concepts(
"number",
Concept("u is a v").def_var("u").def_var("v"),
Concept("add a b").def_var("a").def_var("b")
)
text = "def concept x plus y where x is a number as add x y"
def_ret_val = DefConceptParser().parse(context, ParserInput(text))
evaluated = DefConceptEvaluator().eval(context, def_ret_val)
new_concept = evaluated.body.body
assert evaluated.status
assert new_concept.get_metadata().variables == [('x', None), ('y', None)]
def test_i_do_no_mixed_up_concept_and_variable_name(self):
sheerka, context, activate_debug = self.init_concepts(Concept("activate debug"))
text = "def concept debug on as activate debug"
def_ret_val = DefConceptParser().parse(context, ParserInput(text))
evaluated = DefConceptEvaluator().eval(context, def_ret_val)
new_concept = evaluated.body.body
assert evaluated.status
assert new_concept.get_metadata().variables == []
def test_other_concepts_are_not_variables(self):
sheerka, context, *concepts = self.init_test().with_concepts("little", "size", create_new=True).unpack()
@@ -166,7 +258,7 @@ class TestDefConceptEvaluator(TestUsingMemoryBasedSheerka):
name_to_use = DefConceptEvaluator.get_name_to_use(def_concept_node)
concept_part = self.get_concept_part("set_attr(x, size, little)")
assert DefConceptEvaluator.get_variables(context, concept_part, name_to_use) == {"x"}
assert DefConceptEvaluator.get_variables(context, concept_part, name_to_use) == [PossibleVariable("x")]
def test_that_the_new_concept_is_correctly_saved_in_db(self):
context = self.get_context()
@@ -199,41 +291,6 @@ class TestDefConceptEvaluator(TestUsingMemoryBasedSheerka):
assert from_db.get_compiled() == {} # ast is not saved in db
@pytest.mark.parametrize("expression, name, expected", [
("isinstance(a, str)", "a b", {"a"}),
("a.location = b", "a is in b", {"a", "b"}),
("a.location = b", "'a' is in b", {"b"}),
("date.today()", "what is the date", set()),
("a.location", "where is a", {"a"})
])
def test_i_can_get_variables_from_python_node_when_long_name(self, expression, name, expected):
ret_val = self.get_concept_part(expression)
context = self.get_context()
assert DefConceptEvaluator.get_variables(context, ret_val, name.split()) == expected
def test_i_can_get_variables_when_keywords(self):
sheerka, context = self.init_concepts()
def_concept = self.get_def_concept("condition pre").value.value
name_to_use = DefConceptEvaluator.get_name_to_use(def_concept)
concept_part = self.get_concept_part("pre")
assert DefConceptEvaluator.get_variables(context, concept_part, name_to_use) == {"pre"}
def test_i_cannot_get_variables_from_python_node_when_name_has_only_one_token(self):
ret_val = self.get_concept_part("isinstance(a, str)")
context = self.get_context()
assert DefConceptEvaluator.get_variables(context, ret_val, ["a"]) == set()
def test_i_can_get_variables_from_definition(self):
parsing_expression = Sequence(ConceptExpression('mult'),
ZeroOrMore(Sequence(StrMatch("+"), ConceptExpression("add"))))
ret_val = self.get_return_value("mult (('+'|'-') add)?", parsing_expression)
assert DefConceptEvaluator.get_variables(self.get_context(), ret_val, []) == {"add", "mult"}
def test_concept_that_references_itself_is_correctly_created(self):
context = self.get_context()
def_concept_as_return_value = self.get_def_concept("foo", body="foo")
@@ -247,18 +304,6 @@ class TestDefConceptEvaluator(TestUsingMemoryBasedSheerka):
assert new_concept.values() == {}
assert new_concept.get_metadata().variables == []
def test_i_can_get_variable_when_rule_is_defined(self):
sheerka, context = self.init_test().unpack()
def_concept_parser = DefConceptParser()
parsed_ret_val = def_concept_parser.parse(context, ParserInput("def concept rule x as r:|x:"))
assert parsed_ret_val.status # sanity check
evaluated = DefConceptEvaluator().eval(context, parsed_ret_val)
assert evaluated.status
assert evaluated.body.body.key == "rule __var__0"
assert evaluated.body.body.get_metadata().variables == [("x", None)]
def test_i_can_recognize_variable_when_keyword_argument(self):
sheerka, context = self.init_test().unpack()
def_concept_parser = DefConceptParser()
@@ -309,7 +354,19 @@ class TestDefConceptEvaluator(TestUsingMemoryBasedSheerka):
assert created_concept.get_metadata().variables == [("x", None)]
assert created_concept._bnf == Sequence(StrMatch("hello"), VariableExpression("x"))
def test_i_can_eval_when_auto_eval_is_true(self):
sheerka, context = self.init_test().unpack()
def_ret_val = DefConceptParser().parse(context, ParserInput("def concept foo auto_eval True"))
evaluated = DefConceptEvaluator().eval(context, def_ret_val)
assert evaluated.status
assert context.sheerka.isinstance(evaluated.body, BuiltinConcepts.NEW_CONCEPT)
created_concept = evaluated.body.body
assert sheerka.get_property(created_concept, BuiltinConcepts.ISA) == {sheerka.new(BuiltinConcepts.AUTO_EVAL)}
def test_i_cannot_eval_bnf_concept_with_unknown_variable(self):
# testing MandatoryVariable
context = self.get_context()
def_ret_val = DefConceptParser().parse(context, ParserInput("def concept name from bnf unknown foo"))
evaluated = DefConceptEvaluator().eval(context, def_ret_val)
+2 -2
View File
@@ -683,12 +683,12 @@ as:
assert len(res) == 1
assert not res[0].status
assert sheerka.isinstance(res[0].body, BuiltinConcepts.MULTIPLE_ERRORS)
assert str(BuiltinConcepts.CONDITION_FAILED) in [error.key for error in sheerka.get_error(res[0].body.body)]
assert str(BuiltinConcepts.CONDITION_FAILED) in [error.key for error in sheerka.get_errors(res[0].body.body)]
res = sheerka.evaluate_user_input("eval twenty three")
assert len(res) == 1
assert not res[0].status
assert str(BuiltinConcepts.CONDITION_FAILED) in [error.key for error in sheerka.get_error(res[0].body.body)]
assert str(BuiltinConcepts.CONDITION_FAILED) in [error.key for error in sheerka.get_errors(res[0].body.body)]
def test_i_can_manage_some_type_of_infinite_recursion(self):
sheerka = self.get_sheerka()
+26 -10
View File
@@ -7,14 +7,23 @@ from parsers.BaseParser import UnexpectedEofParsingError, UnexpectedTokenParsing
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
def get_tokens(items):
return [list(Tokenizer(item, yield_eof=False))[0] for item in items]
class TestBaseCustomGrammarParser(TestUsingMemoryBasedSheerka):
@staticmethod
def compare_results(actual, expected, compare_str=False):
resolved_expected = {}
for k, v in expected.items():
tokens = list(Tokenizer(v, yield_eof=False))
resolved_expected[k] = [tokens[0]] + tokens[2:]
if isinstance(v, str):
# case like {Keywords.DEF_VAR: "def_var var1 def_var var2"}
tokens = list(Tokenizer(v, yield_eof=False))
resolved_expected[k] = [tokens[0]] + tokens[2:]
else:
# case like {Keywords.DEF_VAR: get_tokens(["def_var", "var1", "var2"])}
resolved_expected[k] = v
def get_better_representation(value):
better_repr = {}
@@ -23,6 +32,7 @@ class TestBaseCustomGrammarParser(TestUsingMemoryBasedSheerka):
better_repr[k] = [tokens[0].repr_value, value]
return better_repr
# it's easier to compare two list of string
actual_to_compare = get_better_representation(actual)
expected_to_compare = get_better_representation(resolved_expected)
@@ -67,6 +77,20 @@ func(a)
res = parser.get_parts(["when"])
self.compare_results(res, expected)
@pytest.mark.parametrize("text, allow_multiple, expected", [
("def_var var1 def_var var2", {}, {Keywords.DEF_VAR: "def_var var1 def_var var2"}),
("def_var var1 def_var var2", {"def_var"}, {Keywords.DEF_VAR: get_tokens(["def_var", "var1", "var2"])}),
("def_var x y z def_var var2", {"def_var"}, {Keywords.DEF_VAR: get_tokens(["def_var", "'x y z'", "var2"])}),
("def_var 'x y z' def_var var2", {"def_var"}, {Keywords.DEF_VAR: get_tokens(["def_var", "'x y z'", "var2"])}),
("def_var var1 def_var x y z def_var var2", {"def_var"},
{Keywords.DEF_VAR: get_tokens(["def_var", "var1", "'x y z'", "var2"])}),
])
def test_i_can_get_parts_when_allow_multiple_is_set(self, text, allow_multiple, expected):
sheerka, context, parser = self.init_parser(text)
res = parser.get_parts(["def_var"], allow_multiple=allow_multiple)
self.compare_results(res, expected)
@pytest.mark.parametrize("text", [
"",
"no keyword",
@@ -88,14 +112,6 @@ func(a)
"when",
[Keywords.PRINT])]
def test_i_can_detect_when_a_keyword_appears_several_times(self):
sheerka, context, parser = self.init_parser("print hello when True print True")
parser.get_parts(["print"])
assert len(parser.error_sink) == 1
assert isinstance(parser.error_sink[0], SyntaxErrorNode)
assert parser.error_sink[0].message == "Too many 'print' declarations."
@pytest.mark.parametrize("text", [
"print",
"print ",
+75 -1
View File
@@ -12,7 +12,7 @@ from parsers.BaseParser import UnexpectedEofParsingError
from parsers.BnfDefinitionParser import BnfDefinitionParser
from parsers.BnfNodeParser import OrderedChoice, ConceptExpression, StrMatch, Sequence, RegExMatch, OneOrMore, \
VariableExpression
from parsers.DefConceptParser import DefConceptParser, NameNode, SyntaxErrorNode
from parsers.DefConceptParser import DefConceptParser, NameNode, SyntaxErrorNode, CannotHandleParsingError
from parsers.DefConceptParser import UnexpectedTokenParsingError, DefConceptNode
from parsers.FunctionParser import FunctionParser
from parsers.PythonParser import PythonParser, PythonNode
@@ -636,3 +636,77 @@ from give me the date !
assert res.value.source == text
assert isinstance(res.value, ParserResultConcept)
assert node == expected
def test_i_can_parse_when_multiple_keyword_and_no_ambiguity(self):
sheerka, context, parser, *concepts = self.init_parser()
res = parser.parse(context, ParserInput("def concept x is a concept"))
assert res.status
@pytest.mark.parametrize("text, expected", [
("def concept foo auto_eval True", True),
("def concept foo auto_eval true", True),
("def concept foo auto_eval False", False),
("def concept foo auto_eval false", False),
])
def test_i_can_parse_auto_eval(self, text, expected):
sheerka, context, parser, *concepts = self.init_parser()
res = parser.parse(context, ParserInput(text))
def_concept_node = res.value.value
assert res.status
assert res.who == parser.name
assert res.value.source == text
assert isinstance(res.value, ParserResultConcept)
assert def_concept_node.auto_eval == expected
@pytest.mark.parametrize("text", [
"def concept foo auto_eval",
"def concept foo auto_eval as 1"
])
def test_i_cannot_parse_when_missing_auto_eval_value(self, text):
sheerka, context, parser, *concepts = self.init_parser()
res = parser.parse(context, ParserInput(text))
assert not res.status
assert sheerka.isinstance(res.value, BuiltinConcepts.ERROR)
assert sheerka.has_error(res, __type="SyntaxErrorNode", message="Empty 'auto_eval' declaration.")
def test_i_cannot_parse_when_wrong_auto_eval_value(self):
sheerka, context, parser, *concepts = self.init_parser()
text = "def concept foo auto_eval wrong_value"
res = parser.parse(context, ParserInput(text))
assert not res.status
assert sheerka.isinstance(res.value, BuiltinConcepts.ERROR)
assert isinstance(res.value.body[0], CannotHandleParsingError)
@pytest.mark.parametrize("text, expected", [
("def concept foo def_var var", ["var"]),
("def concept foo def_var var1 def_var var2", ["var1", "var2"]),
("def concept foo def_var var1 def_var long var name def_var var2", ["var1", "long var name", "var2"]),
])
def test_i_can_parse_variable_definition(self, text, expected):
sheerka, context, parser, *concepts = self.init_parser()
res = parser.parse(context, ParserInput(text))
def_concept_node = res.value.value
assert res.status
assert res.who == parser.name
assert res.value.source == text
assert isinstance(res.value, ParserResultConcept)
assert def_concept_node.variables == expected
@pytest.mark.parametrize("text", [
"def concept foo def_var",
"def concept foo def_var as 1"
])
def test_i_cannot_parse_variable_definition_when_missing_value(self, text):
sheerka, context, parser, *concepts = self.init_parser()
res = parser.parse(context, ParserInput(text))
assert not res.status
assert sheerka.isinstance(res.value, BuiltinConcepts.ERROR)
assert sheerka.has_error(res, __type="SyntaxErrorNode", message="Empty 'def_var' declaration.")