222 lines
8.3 KiB
Python
222 lines
8.3 KiB
Python
from core.builtin_concepts import BuiltinConcepts
|
|
from core.concept import Concept, CMV
|
|
from core.tokenizer import Tokenizer
|
|
from parsers.ExactConceptParser import ExactConceptParser
|
|
|
|
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
|
|
|
|
|
def variable_def(concept, prop_name):
|
|
for name, value in concept.metadata.variables:
|
|
if name == prop_name:
|
|
return value
|
|
|
|
return None
|
|
|
|
|
|
def get_concept(name, variables=None):
|
|
c = Concept(name=name)
|
|
if variables:
|
|
for v in variables:
|
|
c.def_var(v)
|
|
c.init_key()
|
|
return c
|
|
|
|
|
|
class TestExactConceptParser(TestUsingMemoryBasedSheerka):
|
|
|
|
def test_i_can_compute_combinations(self):
|
|
parser = ExactConceptParser()
|
|
res = parser.combinations(["foo", "bar", "baz"])
|
|
|
|
assert res == {('foo', 'bar', 'baz'),
|
|
('__var__0', 'bar', 'baz'),
|
|
('foo', '__var__0', 'baz'),
|
|
('foo', 'bar', '__var__0'),
|
|
('__var__0', '__var__1', 'baz'),
|
|
('__var__0', 'bar', '__var__1'),
|
|
('foo', '__var__0', '__var__1'),
|
|
('__var__0', '__var__1', '__var__2')}
|
|
|
|
def test_i_can_compute_combinations_with_duplicates(self):
|
|
parser = ExactConceptParser()
|
|
res = parser.combinations(["foo", "bar", "foo"])
|
|
|
|
assert res == {('foo', 'bar', 'foo'),
|
|
('__var__0', 'bar', '__var__0'),
|
|
('foo', '__var__0', 'foo'),
|
|
('__var__0', '__var__1', '__var__0'),
|
|
('__var__1', '__var__0', '__var__1')}
|
|
# TODO: the last tuple is not possible, so the algo can be improved
|
|
|
|
def test_i_can_parse_a_simple_concept(self):
|
|
sheerka = self.get_sheerka(singleton=True)
|
|
context = self.get_context(sheerka)
|
|
concept = self.create_and_add_in_cache_concept(sheerka, "hello world")
|
|
|
|
source = "hello world"
|
|
results = ExactConceptParser().parse(context, source)
|
|
concept_found = results[0].value.value
|
|
|
|
assert len(results) == 1
|
|
assert results[0].status
|
|
assert concept_found == concept
|
|
assert not concept_found.metadata.need_validation
|
|
assert not concept_found.metadata.is_evaluated
|
|
|
|
def test_i_can_parse_concepts_defined_several_times(self):
|
|
sheerka = self.get_sheerka(singleton=True)
|
|
context = self.get_context(sheerka)
|
|
self.create_and_add_in_cache_concept(sheerka, "hello world")
|
|
self.create_and_add_in_cache_concept(sheerka, "hello a", variables=["a"])
|
|
|
|
source = "hello world"
|
|
results = ExactConceptParser().parse(context, source)
|
|
|
|
assert len(results) == 2
|
|
results = sorted(results, key=lambda x: x.value.value.name) # because of the usage of sets
|
|
|
|
assert results[0].status
|
|
assert results[0].value.value.name == "hello a"
|
|
assert variable_def(results[0].value.value, "a") == "world"
|
|
assert results[0].value.value.metadata.need_validation
|
|
|
|
assert results[1].status
|
|
assert results[1].value.value.name == "hello world"
|
|
assert not results[1].value.value.metadata.need_validation
|
|
|
|
def test_i_can_parse_a_concept_with_variables(self):
|
|
sheerka = self.get_sheerka(singleton=True)
|
|
context = self.get_context(sheerka)
|
|
concept = self.create_and_add_in_cache_concept(sheerka, "a + b", ["a", "b"])
|
|
|
|
source = "10 + 5"
|
|
results = ExactConceptParser().parse(context, source)
|
|
|
|
assert len(results) == 1
|
|
assert results[0].status
|
|
|
|
concept_found = results[0].value.value
|
|
assert concept_found == CMV(concept, a="10", b="5")
|
|
assert concept_found.metadata.need_validation
|
|
assert not concept_found.metadata.is_evaluated
|
|
|
|
def test_i_can_parse_a_concept_with_duplicate_variables(self):
|
|
sheerka = self.get_sheerka(singleton=True)
|
|
context = self.get_context(sheerka)
|
|
concept = self.create_and_add_in_cache_concept(sheerka, "a + b + a", ["a", "b"])
|
|
|
|
source = "10 + 5 + 10"
|
|
results = ExactConceptParser(max_word_size=5).parse(context, source)
|
|
|
|
assert len(results) == 1
|
|
assert results[0].status
|
|
|
|
concept_found = results[0].value.value
|
|
assert concept_found == CMV(concept, a="10", b="5")
|
|
assert concept_found.metadata.need_validation
|
|
|
|
def test_i_can_parse_concept_when_defined_using_from_def(self):
|
|
sheerka, context, plus = self.init_concepts(
|
|
self.from_def_concept("+", "a + b", ["a", "b"])
|
|
)
|
|
|
|
source = "10 + 5"
|
|
results = ExactConceptParser().parse(context, source)
|
|
concept_found = results[0].value.value
|
|
|
|
assert len(results) == 1
|
|
assert results[0].status
|
|
assert concept_found == CMV(plus, a="10", b="5")
|
|
assert concept_found.metadata.need_validation
|
|
assert not concept_found.metadata.is_evaluated
|
|
|
|
def test_i_can_parse_concept_token(self):
|
|
sheerka, context, foo = self.init_concepts("foo")
|
|
|
|
source = "c:foo:"
|
|
results = ExactConceptParser().parse(context, source)
|
|
concept_found = results[0].value.value
|
|
|
|
assert len(results) == 1
|
|
assert results[0].status
|
|
assert concept_found == foo
|
|
assert not concept_found.metadata.need_validation
|
|
assert concept_found.metadata.is_evaluated
|
|
|
|
def test_i_can_parse_concept_with_concept_tokens(self):
|
|
sheerka, context, one, two, plus = self.init_concepts(
|
|
"one",
|
|
"two",
|
|
self.from_def_concept("plus", "a plus b", ["a", "b"])
|
|
)
|
|
|
|
source = "c:one: plus c:two:"
|
|
results = ExactConceptParser().parse(context, source)
|
|
concept_found = results[0].value.value
|
|
|
|
assert len(results) == 1
|
|
assert results[0].status
|
|
assert concept_found == CMV(plus, a="c:one:", b="c:two:")
|
|
assert concept_found.metadata.need_validation
|
|
assert not concept_found.metadata.is_evaluated
|
|
|
|
def test_i_can_parse_when_expression_contains_keyword(self):
|
|
sheerka, context, isa, def_concept = self.init_concepts(
|
|
Concept("c is a concept").def_var("c"),
|
|
Concept("def concept a").def_var("a"),
|
|
)
|
|
|
|
source = "z is a concept"
|
|
results = ExactConceptParser().parse(context, source)
|
|
concept_found = results[0].value.value
|
|
|
|
assert len(results) == 1
|
|
assert results[0].status
|
|
assert concept_found == CMV(isa, c="z")
|
|
assert concept_found.metadata.need_validation
|
|
assert not concept_found.metadata.is_evaluated
|
|
|
|
source = "def concept z"
|
|
results = ExactConceptParser().parse(context, source)
|
|
concept_found = results[0].value.value
|
|
|
|
assert len(results) == 1
|
|
assert results[0].status
|
|
assert concept_found == CMV(def_concept, a="z")
|
|
assert concept_found.metadata.need_validation
|
|
assert not concept_found.metadata.is_evaluated
|
|
|
|
def test_i_can_manage_unknown_concept(self):
|
|
context = self.get_context(self.get_sheerka(singleton=True))
|
|
source = "def concept hello" # this is not a concept by itself
|
|
res = ExactConceptParser().parse(context, source)
|
|
|
|
assert not res.status
|
|
assert context.sheerka.isinstance(res.value, BuiltinConcepts.UNKNOWN_CONCEPT)
|
|
assert res.value.body == "def concept hello"
|
|
|
|
def test_i_can_detect_concepts_too_long(self):
|
|
context = self.get_context(self.get_sheerka(singleton=True))
|
|
source = "a very but finally too long concept"
|
|
res = ExactConceptParser().parse(context, source)
|
|
|
|
assert not res.status
|
|
assert context.sheerka.isinstance(res.value, BuiltinConcepts.NOT_FOR_ME)
|
|
assert context.sheerka.isinstance(res.value.reason, BuiltinConcepts.CONCEPT_TOO_LONG)
|
|
assert res.value.reason.body == source
|
|
assert res.value.body == source
|
|
|
|
def test_i_can_detect_concept_from_tokens(self):
|
|
context = self.get_context(self.get_sheerka(singleton=True))
|
|
concept = get_concept("hello world", [])
|
|
context.sheerka.add_in_cache(concept)
|
|
|
|
source = "hello world"
|
|
results = ExactConceptParser().parse(context, list(Tokenizer(source)))
|
|
|
|
assert len(results) == 1
|
|
assert results[0].status
|
|
assert results[0].value.value == concept
|
|
assert not results[0].value.value.metadata.need_validation
|