Files
Sheerka-Old/tests/evaluators/test_ValidateConceptEvaluator.py
kodjo 87cab44fb8 Fixed #125: SheerkaErrorManager
Fixed #135: Change services service priorities
Fixed #136: ErrorManager: Implement recognize_error
Fixed #137: BNFNodeParser : Error when parsing regex with sub parsers
Fixed #138: get_last_errors(): real errors sources are lost
Fixed #139: OneError return value removes the origin of the error
Fixed #140: Concept variables are not correctly handled when parsing sub expression
Fixed #143: Implement has_unknown_concepts()
2021-10-28 14:04:41 +02:00

201 lines
8.8 KiB
Python

import pytest
from core.builtin_concepts import ParserResultConcept
from core.builtin_concepts_ids import BuiltinConcepts
from core.concept import Concept
from core.sheerka.services.SheerkaExecute import ParserInput
from evaluators.BaseEvaluator import BaseEvaluator
from evaluators.ValidateConceptEvaluator import ValidateConceptEvaluator
from parsers.BaseNodeParser import ConceptNode
from parsers.BaseParser import BaseParser
from parsers.BnfNodeParser import BnfNodeParser
from parsers.ExactConceptParser import ExactConceptParser
from parsers.SyaNodeParser import SyaNodeParser
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
from tests.evaluators.EvaluatorTestsUtils import p_ret_val, pr_ret_val, ret_val
class TestValidateConceptEvaluator(TestUsingMemoryBasedSheerka):
@pytest.mark.parametrize("return_value, need_validation, expected", [
(pr_ret_val(Concept("foo", where="something"), status=True), True, True),
(pr_ret_val(Concept("foo", pre="something"), status=True), True, True),
(pr_ret_val(Concept("foo", where="something"), status=True), False, False),
(pr_ret_val(Concept("foo", pre="something"), status=True), False, False),
(pr_ret_val(Concept("foo"), status=True), True, False),
(pr_ret_val(Concept("foo"), status=True), True, False),
(pr_ret_val(Concept("foo", where=None), status=True), True, False),
(pr_ret_val(Concept("foo", pre=None), status=True), True, False),
(pr_ret_val(Concept("foo", where=""), status=True), True, False),
(pr_ret_val(Concept("foo", pre=""), status=True), True, False),
(pr_ret_val(Concept("foo", where="something"), status=False), True, False),
(pr_ret_val(Concept("foo", pre="something"), status=False), True, False),
(pr_ret_val("Not a concept", status=True), True, False),
(pr_ret_val("Not a concept", status=False), True, False),
(p_ret_val("Not a parser result", status=True), True, False),
(p_ret_val("Not a parser result", status=False), True, False),
])
def test_i_can_match(self, return_value, need_validation, expected):
sheerka, context = self.init_concepts()
evaluator = ValidateConceptEvaluator()
if (sheerka.isinstance(return_value.body, BuiltinConcepts.PARSER_RESULT) and
isinstance(return_value.body.body, Concept)):
return_value.body.body.get_hints().need_validation = need_validation
assert evaluator.matches(context, return_value) == expected
def test_i_cannot_match_when_the_return_value_is_not_a_direct_parsing_result(self):
# I match only if the return_value comes from a parser (not from an after_parsing evaluator)
sheerka, context = self.init_concepts()
concept = Concept("foo", pre="something")
parser_result = ParserResultConcept(BaseParser.get_name("parser"), source=concept.name, value=concept)
return_value = ret_val(value=parser_result, who="evaluators.something", status=True)
return_value.body.body.get_hints().need_validation = True
evaluator = ValidateConceptEvaluator()
assert not evaluator.matches(context, return_value)
@pytest.mark.parametrize("concept", [
Concept("foo", pre="False"),
Concept("foo", where="False"),
])
def test_i_can_eval_when_constraint_is_false(self, concept):
sheerka, context, foo = self.init_concepts(concept)
ret_val = pr_ret_val(foo, status=True)
res = ValidateConceptEvaluator().eval(context, ret_val)
assert not res.status
assert res.who == BaseEvaluator.PREFIX + ValidateConceptEvaluator.NAME
assert sheerka.isinstance(res.body, BuiltinConcepts.FILTERED)
assert res.body.body == foo
@pytest.mark.parametrize("concept", [
Concept("foo"),
Concept("foo", pre="True"),
Concept("foo", where="True"),
])
def test_i_can_eval_when_constraint_is_true_or_when_no_constrain(self, concept):
sheerka, context, foo = self.init_concepts(concept)
ret_val = pr_ret_val(foo, status=True)
res = ValidateConceptEvaluator().eval(context, ret_val)
assert res is None
@pytest.mark.parametrize("concept", [
Concept("foo"),
Concept("foo", pre="True"),
Concept("foo", where="True"),
])
def test_i_can_eval_when_constraint_is_true_or_when_no_constrain_use_copy(self, concept):
sheerka, context, foo = self.init_concepts(concept)
foo.get_hints().use_copy = True
ret_val = pr_ret_val(foo, status=True)
res = ValidateConceptEvaluator().eval(context, ret_val)
assert res.status
assert res.who == BaseEvaluator.PREFIX + ValidateConceptEvaluator.NAME
assert res.body.body.id == foo.id
assert not res.body.body.get_hints().use_copy
def test_i_can_eval_when_is_question(self):
sheerka, context, foo = self.init_concepts(Concept("foo", pre="is_question()"))
ret_val = pr_ret_val(foo, status=True)
res = ValidateConceptEvaluator().eval(context, ret_val)
assert not res.status
context.add_to_protected_hints(BuiltinConcepts.EVAL_QUESTION_REQUESTED)
res = ValidateConceptEvaluator().eval(context, ret_val)
assert res is None
def test_i_can_eval_when_unknown_variables_but_no_constraint(self):
sheerka, context, foo = self.init_concepts(Concept("a plus b").def_var("a").def_var("b"))
ret_val = pr_ret_val(foo, status=True)
res = ValidateConceptEvaluator().eval(context, ret_val)
assert res is None
def test_i_can_eval_when_unknown_variables(self):
# ValidateConceptEvaluator must filter only if all the variables are known
# In this example, 'b' is not set, so the return_value must not be filtered
sheerka, context, foo = self.init_concepts(
Concept("a plus b", where="isinstance(b, int)").def_var("a", "10").def_var("b"))
ret_val = pr_ret_val(foo, status=True)
res = ValidateConceptEvaluator().eval(context, ret_val)
assert res is None
def test_i_can_eval_when_constraint_on_variable_fails(self):
sheerka, context, foo = self.init_concepts(
Concept("a plus b", where="isinstance(b, int)").def_var("a").def_var("b", "'a string'"))
ret_val = pr_ret_val(foo, status=True)
res = ValidateConceptEvaluator().eval(context, ret_val)
assert not res.status
def test_i_can_eval_bnf_concepts(self):
sheerka, context, quantify_x = self.init_concepts(
Concept("quantify x", definition="('one'|'two') x", where="x != 'one'").def_var("x"),
create_new=True)
evaluator = ValidateConceptEvaluator()
# success
ret_val = BnfNodeParser().parse(context, ParserInput("one 'two'"))
assert evaluator.matches(context, ret_val)
res = evaluator.eval(context, ret_val)
assert isinstance(res.body.body, list)
assert len(res.body.body) == 1
assert isinstance(res.body.body[0], ConceptNode)
assert res.body.body[0].concept.id == ret_val.body.body[0].concept.id
# failure
ret_val = BnfNodeParser().parse(context, ParserInput("one 'one'"))
assert evaluator.matches(context, ret_val)
res = evaluator.eval(context, ret_val)
assert not res.status
assert sheerka.isinstance(res.body, BuiltinConcepts.FILTERED)
assert res.body.body == ret_val.body.body
def test_i_can_eval_sya_concepts(self):
sheerka, context, quantify_x = self.init_concepts(
Concept("a plus b", where="a < 10").def_var("a").def_var("b"),
create_new=True)
evaluator = ValidateConceptEvaluator()
# success
ret_val = SyaNodeParser().parse(context, ParserInput("5 plus 3"))
assert evaluator.matches(context, ret_val)
res = evaluator.eval(context, ret_val)
assert isinstance(res.body.body, list)
assert len(res.body.body) == 1
assert isinstance(res.body.body[0], ConceptNode)
assert res.body.body[0].concept.id == ret_val.body.body[0].concept.id
# failure
ret_val = SyaNodeParser().parse(context, ParserInput("15 plus 3"))
assert evaluator.matches(context, ret_val)
res = evaluator.eval(context, ret_val)
assert not res.status
assert sheerka.isinstance(res.body, BuiltinConcepts.FILTERED)
assert res.body.body == ret_val.body.body
def test_i_can_eval_exact_parser_concepts(self):
sheerka, context, explain_x = self.init_concepts(
Concept("explain x", where="isinstance(x, int)").def_var("x")
)
evaluator = ValidateConceptEvaluator()
ret_val = ExactConceptParser().parse(context, ParserInput("explain 1"))[0]
assert evaluator.matches(context, ret_val)
res = evaluator.eval(context, ret_val)
assert sheerka.isinstance(res.body.body, explain_x)