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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user