I can also get concept by name

This commit is contained in:
2020-03-10 15:05:03 +01:00
parent 1bde97b5e3
commit a2bbd2eec2
13 changed files with 341 additions and 106 deletions
+30 -1
View File
@@ -1,5 +1,5 @@
from core.builtin_concepts import BuiltinConcepts
from core.concept import PROPERTIES_TO_SERIALIZE, Concept
from core.concept import PROPERTIES_TO_SERIALIZE, Concept, DEFINITION_TYPE_DEF
from core.sheerka.Sheerka import Sheerka
from sdp.sheerkaDataProvider import SheerkaDataProvider
@@ -25,10 +25,38 @@ class TestSheerkaCreateNewConcept(TestUsingMemoryBasedSheerka):
assert concept.key in sheerka.cache_by_key
assert concept.id in sheerka.cache_by_id
assert concept.name in sheerka.cache_by_name
assert sheerka.sdp.io.exists(
sheerka.sdp.io.get_obj_path(SheerkaDataProvider.ObjectsFolder, concept_found.get_origin()))
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_HASH_ENTRY, concept.get_definition_hash())
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_ID_ENTRY, concept.id)
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_NAME_ENTRY, concept.name)
assert sheerka.sdp.exists(Sheerka.CONCEPTS_ENTRY, concept.key)
def test_i_can_add_a_concept_when_name_differs_from_the_key(self):
sheerka = self.get_sheerka()
concept = Concept("greetings", definition="hello a", definition_type=DEFINITION_TYPE_DEF).def_prop("a")
res = sheerka.create_new_concept(self.get_context(sheerka), concept)
assert res.status
assert sheerka.isinstance(res.value, BuiltinConcepts.NEW_CONCEPT)
concept_found = res.value.body
for prop in PROPERTIES_TO_SERIALIZE:
assert getattr(concept_found.metadata, prop) == getattr(concept.metadata, prop)
assert concept_found.key == "hello __var__0"
assert concept_found.id == "1001"
assert concept.key in sheerka.cache_by_key
assert concept.id in sheerka.cache_by_id
assert concept.name in sheerka.cache_by_name
assert sheerka.sdp.io.exists(
sheerka.sdp.io.get_obj_path(SheerkaDataProvider.ObjectsFolder, concept_found.get_origin()))
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_HASH_ENTRY, concept.get_definition_hash())
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_ID_ENTRY, concept.id)
assert sheerka.sdp.exists(Sheerka.CONCEPTS_BY_NAME_ENTRY, concept.name)
assert sheerka.sdp.exists(Sheerka.CONCEPTS_ENTRY, concept.key)
def test_i_cannot_add_the_same_concept_twice(self):
@@ -200,3 +228,4 @@ class TestSheerkaCreateNewConcept(TestUsingMemoryBasedSheerka):
assert res.status
+10 -3
View File
@@ -11,9 +11,9 @@ class TestSheerkaModifyConcept(TestUsingMemoryBasedSheerka):
sheerka, context, foo, bar = self.init_concepts("foo", "bar", create_new=True)
foo_instance = sheerka.new("foo")
foo_instance.metadata.body = "value"
foo_instance.set_prop(BuiltinConcepts.ISA, bar)
foo_instance.set_metadata_value(ConceptParts.BODY, "body value")
foo_instance.metadata.body = "value" # modify metadata
foo_instance.set_prop(BuiltinConcepts.ISA, bar) # modify property
foo_instance.set_metadata_value(ConceptParts.BODY, "body value") # modify value
res = sheerka.modify_concept(context, foo_instance)
assert res.status
@@ -36,6 +36,13 @@ class TestSheerkaModifyConcept(TestUsingMemoryBasedSheerka):
assert foo_from_sheerka.get_prop(BuiltinConcepts.ISA) == bar
assert foo_from_sheerka.body == "body value"
# test that ref by name is updated
sheerka.reset_cache()
foo_from_sheerka = sheerka.get_by_name(foo.name)
assert foo_from_sheerka.metadata.body == "value"
assert foo_from_sheerka.get_prop(BuiltinConcepts.ISA) == bar
assert foo_from_sheerka.body == "body value"
# test that ref by hash is updated
foo_from_sdp = sheerka.sdp.get(Sheerka.CONCEPTS_BY_HASH_ENTRY, foo_instance.get_definition_hash())
assert foo_from_sdp.metadata.body == "value"
+20 -1
View File
@@ -1,6 +1,6 @@
import pytest
from core.concept import Concept, ConceptParts
from core.concept import Concept, ConceptParts, DEFINITION_TYPE_DEF
@pytest.mark.parametrize("name, properties, expected", [
@@ -29,6 +29,25 @@ def test_i_can_compute_the_key(name, properties, expected):
assert concept.key == expected
def test_i_can_compute_the_key_when_from_definition():
# if definition is not defined, use the name
concept = Concept()
concept.metadata.name = "hello a"
concept.metadata.props = [("a", None)]
concept.init_key()
assert concept.key == "hello __var__0"
# if definition is defined, use it
concept = Concept()
concept.metadata.name = "greetings"
concept.metadata.definition = "hello a"
concept.metadata.definition_type = DEFINITION_TYPE_DEF
concept.metadata.props = [("a", None)]
concept.init_key()
assert concept.key == "hello __var__0"
def test_key_does_not_use_variable_when_definition_is_set():
concept = Concept("plus").def_prop('plus')
+44 -13
View File
@@ -52,21 +52,25 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
)
)
def get_def_concept(self, name, where=None, pre=None, post=None, body=None, definition=None):
concept = DefConceptNode([], name=NameNode(list(Tokenizer(name))))
def get_def_concept(self, name, where=None, pre=None, post=None, body=None, definition=None, bnf_def=None):
def_concept = DefConceptNode([], name=NameNode(list(Tokenizer(name))))
if body:
concept.body = self.get_concept_part(body)
def_concept.body = self.get_concept_part(body)
if where:
concept.where = self.get_concept_part(where)
def_concept.where = self.get_concept_part(where)
if pre:
concept.pre = self.get_concept_part(pre)
def_concept.pre = self.get_concept_part(pre)
if post:
concept.post = self.get_concept_part(post)
def_concept.post = self.get_concept_part(post)
if bnf_def:
def_concept.definition = bnf_def
def_concept.definition_type = "bnf"
if definition:
concept.definition = definition
def_concept.definition = NameNode(list(Tokenizer(definition)))
def_concept.definition_type = "def"
return ReturnValueConcept(BaseParser.PREFIX + "some_name", True, ParserResultConcept(value=concept))
return ReturnValueConcept(BaseParser.PREFIX + "some_name", True, ParserResultConcept(value=def_concept))
@pytest.mark.parametrize("ret_val, expected", [
(ReturnValueConcept(BaseParser.PREFIX + "some_name", True, ParserResultConcept(value=DefConceptNode([]))),
@@ -80,11 +84,11 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
context = self.get_context()
assert AddConceptEvaluator().matches(context, ret_val) == expected
def test_that_the_source_is_correctly_set(self):
def test_that_the_source_is_correctly_set_for_bnf_concept(self):
context = self.get_context()
def_concept_return_value = self.get_def_concept(
name="hello a",
definition=self.get_return_value("hello a", Sequence(StrMatch("hello"), StrMatch("a"))),
bnf_def=self.get_return_value("hello a", Sequence(StrMatch("hello"), StrMatch("a"))),
where="isinstance(a, str )",
pre="a is not None",
body="print('hello' + a)")
@@ -96,17 +100,43 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
created_concept = evaluated.body.body
assert created_concept.metadata.name == "hello a"
assert created_concept.metadata.key == "hello __var__0"
assert created_concept.metadata.where == "isinstance(a, str )"
assert created_concept.metadata.pre == "a is not None"
assert created_concept.metadata.post is None
assert created_concept.metadata.body == "print('hello' + a)"
assert created_concept.metadata.definition == "hello a"
assert created_concept.metadata.definition_type == "bnf"
def test_that_the_source_is_correctly_set_for_concept_with_simple_definition(self):
context = self.get_context()
def_concept_return_value = self.get_def_concept(
name="greetings",
definition="hello a",
where="isinstance(a, str )",
pre="a is not None",
body="print('hello' + a)")
evaluated = AddConceptEvaluator().eval(context, def_concept_return_value)
assert evaluated.status
assert context.sheerka.isinstance(evaluated.body, BuiltinConcepts.NEW_CONCEPT)
created_concept = evaluated.body.body
assert created_concept.metadata.name == "greetings"
assert created_concept.metadata.key == "hello __var__0"
assert created_concept.metadata.where == "isinstance(a, str )"
assert created_concept.metadata.pre == "a is not None"
assert created_concept.metadata.post is None
assert created_concept.metadata.body == "print('hello' + a)"
assert created_concept.metadata.definition == "hello a"
assert created_concept.metadata.definition_type == "def"
def test_that_the_new_concept_is_correctly_saved_in_db(self):
context = self.get_context()
def_concept_return_value = self.get_def_concept(
name="hello a",
definition=self.get_return_value("hello a", Sequence(StrMatch("hello"), StrMatch("a"))),
bnf_def=self.get_return_value("hello a", Sequence(StrMatch("hello"), StrMatch("a"))),
where="isinstance(a, str )",
pre="a is not None",
body="print('hello' + a)")
@@ -126,6 +156,7 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
assert from_db.metadata.post is None
assert from_db.metadata.body == "print('hello' + a)"
assert from_db.metadata.definition == "hello a"
assert from_db.metadata.definition_type == "bnf"
assert len(from_db.metadata.props) == 1
assert from_db.metadata.props[0] == ("a", None)
assert "a" in from_db.props
@@ -150,14 +181,14 @@ class TestAddConceptEvaluator(TestUsingMemoryBasedSheerka):
status=True,
value=ParserResultConcept(value=concept))
assert AddConceptEvaluator.get_props(self.get_context(), ret_val, []) == ["a", "b"]
assert AddConceptEvaluator.get_props(self.get_sheerka(), ret_val, []) == ["a", "b"]
def test_i_can_get_props_from_definition(self):
parsing_expression = Sequence(ConceptExpression('mult'),
ZeroOrMore(Sequence(StrMatch("+"), ConceptExpression("add"))))
ret_val = self.get_return_value("mult (('+'|'-') add)?", parsing_expression)
assert AddConceptEvaluator.get_props(self.get_context(), ret_val, []) == ["add", "mult"]
assert AddConceptEvaluator.get_props(self.get_sheerka(), ret_val, []) == ["add", "mult"]
def test_concept_that_references_itself_is_correctly_created(self):
context = self.get_context()
+24
View File
@@ -359,6 +359,30 @@ as:
assert evaluated.body == "one two three"
assert evaluated.props["a"] == Property("a", sheerka.new(concept_a.key, body="one two").init_key())
@pytest.mark.parametrize("user_input", [
"def concept greetings from def hello a where a",
"def concept greetings from hello a where a"])
def test_i_can_recognize_a_concept_defined_using_from_def(self, user_input):
sheerka = self.get_sheerka()
greetings = sheerka.evaluate_user_input(user_input)[0].body.body
res = sheerka.evaluate_user_input("hello 'foo'")
assert len(res) == 1
assert res[0].status
concept_found = res[0].value
assert sheerka.isinstance(concept_found, greetings)
assert concept_found.get_prop("a") == "foo"
assert concept_found.metadata.need_validation
res = sheerka.evaluate_user_input("greetings")
assert len(res) == 1
assert res[0].status
concept_found = res[0].value
assert sheerka.isinstance(concept_found, greetings)
assert concept_found.get_prop("a") is None
assert not concept_found.metadata.need_validation
@pytest.mark.parametrize("desc, definitions", [
("Simple form", [
"def concept one as 1",
+31 -8
View File
@@ -2,7 +2,7 @@ import pytest
import ast
from core.builtin_concepts import ParserResultConcept, BuiltinConcepts, ReturnValueConcept
from core.concept import Concept
from core.concept import Concept, DEFINITION_TYPE_BNF, DEFINITION_TYPE_DEF
from parsers.ConceptLexerParser import OrderedChoice, StrMatch, ConceptExpression
from parsers.PythonParser import PythonParser, PythonNode
from core.tokenizer import Keywords, Tokenizer, LexerError
@@ -13,7 +13,7 @@ from parsers.BnfParser import BnfParser
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
def get_def_concept(name, where=None, pre=None, post=None, body=None, definition=None):
def get_def_concept(name, where=None, pre=None, post=None, body=None, definition=None, bnf_def=None):
def_concept = DefConceptNode([], name=NameNode(list(Tokenizer(name))))
if body:
@@ -24,11 +24,15 @@ def get_def_concept(name, where=None, pre=None, post=None, body=None, definition
def_concept.pre = get_concept_part(pre)
if post:
def_concept.post = get_concept_part(post)
if definition:
if bnf_def:
def_concept.definition = ReturnValueConcept(
"parsers.Bnf",
True,
definition)
bnf_def)
def_concept.definition_type = DEFINITION_TYPE_BNF
if definition:
def_concept.definition = NameNode(list(Tokenizer(definition)))
def_concept.definition_type = DEFINITION_TYPE_DEF
return def_concept
@@ -237,7 +241,7 @@ def concept add one to a as
assert not res.status
assert return_value.value == [SyntaxErrorNode([], "Newline are not allowed in name.")]
def test_i_can_parse_def_concept_from_regex(self):
def test_i_can_parse_def_concept_from_bnf(self):
context = self.get_context()
a_concept = Concept("a_concept")
context.sheerka.add_in_cache(a_concept)
@@ -248,7 +252,7 @@ def concept add one to a as
node = res.value.value
definition = OrderedChoice(ConceptExpression(a_concept, rule_name="a_concept"), StrMatch("a_string"))
parser_result = ParserResultConcept(BnfParser(), "a_concept | 'a_string'", definition, definition)
expected = get_def_concept(name="name", body="__definition[0]", definition=parser_result)
expected = get_def_concept(name="name", body="__definition[0]", bnf_def=parser_result)
assert res.status
assert res.who == parser.name
@@ -267,8 +271,12 @@ def concept add one to a as
assert not parser.has_error
def test_i_can_detect_empty_bnf_declaration(self):
text = "def concept name from bnf as __definition[0]"
@pytest.mark.parametrize("text", [
"def concept name from bnf as here is my body",
"def concept name from def as here is my body",
"def concept name from as here is my body"
])
def test_i_can_detect_empty_bnf_declaration(self, text):
parser = DefaultParser()
res = parser.parse(self.get_context(), text)
@@ -276,6 +284,21 @@ def concept add one to a as
assert not res.status
assert res.value.value[0] == SyntaxErrorNode([], "Empty declaration")
@pytest.mark.parametrize("text", [
"def concept addition from a plus b as a + b",
"def concept addition from def a plus b as a + b"])
def test_i_can_def_concept_from_definition(self, text):
parser = DefaultParser()
res = parser.parse(self.get_context(), text)
expected = get_def_concept("addition", definition="a plus b", body="a + b")
node = res.value.value
assert res.status
assert res.who == parser.name
assert res.value.source == text
assert isinstance(res.value, ParserResultConcept)
assert node == expected
def test_i_can_detect_not_for_me(self):
text = "hello world"
context = self.get_context()