from core.builtin_concepts import BuiltinConcepts from core.concept import Concept, Property from core.sheerka import Sheerka, ExecutionContext from core.tokenizer import Tokenizer from parsers.ExactConceptParser import ExactConceptParser from sdp.sheerkaDataProvider import Event def metadata_prop(concept, prop_name): for name, value in concept.metadata.props: if name == prop_name: return value return None def test_i_can_compute_combinations(): 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(): 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_recognize_a_simple_concept(): context = get_context() concept = get_concept("hello world", []) context.sheerka.add_in_cache(concept) source = "hello world" results = ExactConceptParser().parse(context, source) assert len(results) == 1 assert results[0].status assert results[0].value.value == concept def test_i_can_recognize_concepts_defined_several_times(): context = get_context() context.sheerka.add_in_cache(get_concept("hello world", [])) context.sheerka.add_in_cache(get_concept("hello a", ["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 metadata_prop(results[0].value.value, "a") == "world" assert results[1].status assert results[1].value.value.name == "hello world" def test_i_can_recognize_a_concept_with_variables(): context = get_context() concept = get_concept("a + b", ["a", "b"]) context.sheerka.add_in_cache(concept) 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.key == concept.key assert metadata_prop(concept_found, "a") == "10" assert metadata_prop(concept_found, "b") == "5" def test_i_can_recognize_a_concept_with_duplicate_variables(): context = get_context() concept = get_concept("a + b + a", ["a", "b"]) context.sheerka.cache_by_key[concept.key] = concept source = "10 + 5 + 10" results = ExactConceptParser().parse(context, source) assert len(results) == 1 assert results[0].status concept_found = results[0].value.value assert concept_found.key == concept.key assert metadata_prop(concept_found, "a") == "10" assert metadata_prop(concept_found, "b") == "5" def test_i_can_manage_unknown_concept(): context = get_context() source = "def concept hello world" # 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 world" def test_i_can_detect_concepts_too_long(): context = get_context() source = "a very very long concept that cannot be an unique one" res = ExactConceptParser().parse(context, source) assert not res.status assert context.sheerka.isinstance(res.value, BuiltinConcepts.CONCEPT_TOO_LONG) assert res.value.body == "a very very long concept that cannot be an unique one" def test_i_can_detect_concept_from_tokens(): context = get_context() 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 def get_context(): sheerka = Sheerka(skip_builtins_in_db=True) sheerka.initialize("mem://") return ExecutionContext("sheerka", Event(), sheerka) def get_concept(name, variables): c = Concept(name=name) if variables: for v in variables: c.def_prop(v) c.init_key() return c