Fixed #20: I can parse simple concepts

This commit is contained in:
2023-07-09 18:08:47 +02:00
parent ba397b0b72
commit 57f9ce2bbb
44 changed files with 2462 additions and 149 deletions
+55 -9
View File
@@ -5,11 +5,10 @@ from common.global_symbols import NotInit
from conftest import NewOntology
from core.BuiltinConcepts import BuiltinConcepts
from core.concept import ConceptDefaultProps
from core.error import ErrorContext
from core.python_fragment import PythonFragment
from helpers import define_new_concept, get_concept, get_concepts, get_metadata
from services.SheerkaConceptEvaluator import ConceptEvaluator
from services.SheerkaPython import EvaluationRef
from services.SheerkaConceptEvaluator import ConceptEvaluator, InfiniteRecursion, TooManyErrors
from services.SheerkaPython import ObjectRef
class TestConceptManager(BaseTest):
@@ -77,8 +76,8 @@ class TestConceptManager(BaseTest):
compiled = service._build_attributes(context, metadata)
pf = getattr(compiled, ConceptDefaultProps.BODY)
assert isinstance(pf, PythonFragment)
assert pf.namespace == {"a": EvaluationRef("self", "a"),
"b": EvaluationRef("self", "b")}
assert pf.namespace == {"a": ObjectRef("self", "a"),
"b": ObjectRef("self", "b")}
def test_i_can_manage_parsing_errors(self, context, service):
metadata = get_metadata(
@@ -98,7 +97,7 @@ class TestConceptManager(BaseTest):
assert pf.source_code == "NotInit"
error = getattr(compiled, ConceptDefaultProps.BODY)
assert isinstance(error, ErrorContext)
assert isinstance(error, TooManyErrors)
def test_i_can_eval_concept_attributes(self, context, service):
with NewOntology(context, "test_i_can_eval_concept_attributes"):
@@ -225,6 +224,9 @@ class TestConceptManager(BaseTest):
assert context.sheerka.objvalue(qux) == 1
def test_concept_variables_precede_global_concepts(self, context, service):
# In this test, there is a variable named "foo"
# Its value is the concept 'bar'
# So when the body is evaluated, we expected Concept(bar), not Concept(foo)
with NewOntology(context, "test_concept_variables_precede_global_concepts"):
foo, bar, baz = get_concepts(context,
get_concept("foo"),
@@ -237,6 +239,20 @@ class TestConceptManager(BaseTest):
assert context.sheerka.isinstance(res, baz)
assert context.sheerka.isinstance(res.body, bar)
def test_concept_variables_precede_global_concept_during_computation(self, context, service):
# In this test, there is a variable named "foo" and a concept also named "foo"
# When evaluated, foo + 1 must use the variable 'foo', not the Concept("foo")
with NewOntology(context, "test_concept_variables_precede_global_concepts"):
foo, bar = get_concepts(context,
get_concept("foo", body="2"),
get_concept("bar", body="foo + 1", variables=(("foo", "1"),)),
use_sheerka=True)
res = service.evaluate_concept(context, bar)
assert context.sheerka.isinstance(res, bar)
assert context.sheerka.objvalue(res) == 2
def test_i_can_evaluate_concept_when_variables_reference_others_concepts_with_body(self, context, service):
with NewOntology(context, "test_i_can_evaluate_concept_when_variables_reference_others_concepts_with_body"):
foo, bar, baz = get_concepts(context,
@@ -463,6 +479,7 @@ class TestConceptManager(BaseTest):
res = service.evaluate_concept(context, foo)
assert context.sheerka.isinstance(res, BuiltinConcepts.EVALUATION_ERROR)
assert context.sheerka.isinstance(res.concept, foo)
assert isinstance(res.reason, InfiniteRecursion)
assert res.reason.ids == [foo.id, bar.id, baz.id]
def test_i_can_detect_sub_infinite_loop(self, context, service):
@@ -476,6 +493,7 @@ class TestConceptManager(BaseTest):
res = service.evaluate_concept(context, foo)
assert context.sheerka.isinstance(res, BuiltinConcepts.EVALUATION_ERROR)
assert context.sheerka.isinstance(res.concept, bar)
assert isinstance(res.reason, InfiniteRecursion)
assert res.reason.ids == [bar.id, baz.id]
def test_i_can_detect_auto_infinite_loop(self, context, service):
@@ -487,10 +505,11 @@ class TestConceptManager(BaseTest):
res = service.evaluate_concept(context, foo)
assert context.sheerka.isinstance(res, BuiltinConcepts.EVALUATION_ERROR)
assert context.sheerka.isinstance(res.concept, foo)
assert isinstance(res.reason, InfiniteRecursion)
assert res.reason.ids == [foo.id]
def test_i_can_select_the_valid_result_when_multiple_choice_invalid_concept(self, context, service):
with NewOntology(context, "test_i_can_select_the_valid_result_when_multiple_choice"):
with NewOntology(context, "test_i_can_select_the_valid_result_when_multiple_choice_invalid_concept"):
foo, two_ok, two_nok = get_concepts(context,
get_concept("foo", body="two"),
get_concept("two", body="1 +"), # has to come before the other 'two'
@@ -502,7 +521,7 @@ class TestConceptManager(BaseTest):
assert context.sheerka.objvalue(foo) == 2
def test_i_can_select_the_valid_result_when_multiple_choice_evaluation_error(self, context, service):
with NewOntology(context, "test_i_can_select_the_valid_result_when_multiple_choice"):
with NewOntology(context, "test_i_can_select_the_valid_result_when_multiple_choice_evaluation_error"):
foo, two_ok, two_nok = get_concepts(context,
get_concept("foo", body="two"),
get_concept("two", body="1 / 0"), # has to come before the other 'two'
@@ -529,8 +548,35 @@ class TestConceptManager(BaseTest):
with NewOntology(context, "test_i_do_not_use_ret_in_case_of_error"):
foo, baz = get_concepts(context,
get_concept("foo"),
get_concept("baz", body="foo", ret="bar"),
get_concept("baz", body="foo", ret="bar"), # Concept("bar") is not defined
use_sheerka=True)
res = service.evaluate_concept(context, baz)
assert context.sheerka.isinstance(res, BuiltinConcepts.EVALUATION_ERROR)
@pytest.mark.skip("Cannot remove concept")
def test_i_do_not_use_ret_in_case_of_error_when_concept_was_removed(self, context, service):
# Make sure that ret is not returned in case of UNKNOWN_CONCEPT error message
foo, bar, baz = get_concepts(context,
get_concept("foo"),
get_concept("bar"),
get_concept("baz", body="foo", ret="bar"), # Concept("bar") is not defined
use_sheerka=True)
service.evaluate_concept(context, baz) # creates the compiled for Concept("baz")
context.sheerka.remove_concept(bar) # Concept("bar") no longer exists, but compiled for "baz" remains the same
res = service.evaluate_concept(context, baz)
assert context.sheerka.isinstance(res, BuiltinConcepts.EVALUATION_ERROR)
assert "#ret#" in res.reason
assert res.reason["#ret#"].value == context.sheerka.newn(BuiltinConcepts.UNKNOWN_CONCEPT, requested="bar")
def test_i_cannot_evaluate_when_error(self, context, service):
with NewOntology(context, "test_i_cannot_evaluate_when_error"):
foo, = get_concepts(context,
get_concept("foo", body="I am a concept"), # "one" does not exist
use_sheerka=True)
res = service.evaluate_concept(context, foo)
assert context.sheerka.isinstance(res, BuiltinConcepts.INVALID_CONCEPT)