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 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 == 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.name) # because of the usage of sets assert results[0].status assert results[0].value.name == "hello a" assert results[0].value.props["a"].value == "world" assert results[1].status assert results[1].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 assert results[0].value.key == concept.key assert results[0].value.props["a"].value == "10" assert results[0].value.props["b"].value == "5" def test_i_can_recognize_a_concept_with_duplicate_variables(): context = get_context() concept = get_concept("a + b + a", ["a", "b"]) context.sheerka.concepts_cache[concept.key] = concept source = "10 + 5 + 10" results = ExactConceptParser().parse(context, source) assert len(results) == 1 assert results[0].status assert results[0].value.key == concept.key assert results[0].value.props["a"].value == "10" assert results[0].value.props["b"].value == "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.obj == "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.obj == "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 == concept def get_context(): sheerka = Sheerka(skip_builtins_in_db=True) sheerka.initialize("mem://") return ExecutionContext("sheerka", "xxxx", sheerka) def get_concept(name, variables): c = Concept(name=name) if variables: for v in variables: c.props[v] = Property(v, None) c.init_key() return c