import pytest from core.builtin_concepts import ReturnValueConcept, ParserResultConcept from core.concept import Concept from core.sheerka import Sheerka, ExecutionContext from evaluators.ConceptNodeEvaluator import ConceptNodeEvaluator from parsers.ConceptLexerParser import ConceptNode, ConceptLexerParser, Sequence, TerminalNode, \ StrMatch, Optional, OrderedChoice, ZeroOrMore, UnrecognizedTokensNode, ConceptMatch from sdp.sheerkaDataProvider import Event def get_context(): sheerka = Sheerka(skip_builtins_in_db=True) sheerka.initialize("mem://") return ExecutionContext("test", Event(), sheerka) def get_return_value(context, grammar, expression): parser = ConceptLexerParser() parser.initialize(context, grammar) ret_val = parser.parse(context, expression) assert ret_val.status return ret_val def init(concept, grammar, text): context = get_context() if isinstance(concept, list): for c in concept: context.sheerka.add_in_cache(c) else: context.sheerka.add_in_cache(concept) ret_val = get_return_value(context, grammar, text) node = ret_val.value.value[0] return context, node @pytest.mark.parametrize("ret_val, expected", [ (ReturnValueConcept("some_name", True, ParserResultConcept(value=[ConceptNode(Concept(), 0, 0)])), True), (ReturnValueConcept("some_name", True, ParserResultConcept(value=ConceptNode(Concept(), 0, 0))), True), (ReturnValueConcept("some_name", True, ParserResultConcept(value=[UnrecognizedTokensNode(0, 0, [])])), True), (ReturnValueConcept("some_name", True, ParserResultConcept(value=UnrecognizedTokensNode(0, 0, []))), True), (ReturnValueConcept("some_name", False, ParserResultConcept(value=[ConceptNode(Concept(), 0, 0)])), False), (ReturnValueConcept("some_name", False, ParserResultConcept(value=ConceptNode(Concept(), 0, 0))), False), (ReturnValueConcept("some_name", False, ParserResultConcept(value=[UnrecognizedTokensNode(0, 0, [])])), False), (ReturnValueConcept("some_name", False, ParserResultConcept(value=UnrecognizedTokensNode(0, 0, []))), False), (ReturnValueConcept("some_name", True, ParserResultConcept(value="Not a concept node")), False), (ReturnValueConcept("some_name", True, ParserResultConcept(value=["Not a concept node"])), False), (ReturnValueConcept("some_name", True, [ConceptNode(Concept(), 0, 0)]), False), (ReturnValueConcept("some_name", True, ConceptNode(Concept(), 0, 0)), False), ]) def test_i_can_match(ret_val, expected): context = get_context() assert ConceptNodeEvaluator().matches(context, ret_val) == expected def test_parser_result_of_concept_is_returned_when_list_of_one_concept_node(): foo = Concept("foo") context = get_context() context.sheerka.add_in_cache(foo) evaluator = ConceptNodeEvaluator() ret_val = get_return_value(context, {foo: StrMatch("foo")}, "foo") result = evaluator.eval(context, ret_val) assert result.who == evaluator.name assert result.status assert result.value == ParserResultConcept( evaluator, "foo", Concept("foo", body="'foo'").init_key(), None) assert result.parents == [ret_val] def test_concept_property_is_correctly_updated_for_str_match(): foo = Concept("foo") grammar = {foo: StrMatch("foo", rule_name="variable")} context, node = init(foo, grammar, "foo") updated = ConceptNodeEvaluator().finalize_concept(context.sheerka, node.concept, node.underlying) assert "variable" in updated.props assert updated.props["variable"].value == "'foo'" assert updated.body == "'foo'" def test_concept_property_is_correctly_updated_for_sequence(): foo = Concept("foo") grammar = {foo: Sequence("one", "two", rule_name="variable")} context, node = init(foo, grammar, "one two") updated = ConceptNodeEvaluator().finalize_concept( context.sheerka, context.sheerka.new(node.concept.key), node.underlying) assert "variable" in updated.props assert updated.props["variable"].value == "'one two'" assert updated.body == "'one two'" def test_concept_property_is_updated_for_str_in_sequence(): foo = Concept("foo") grammar = {foo: Sequence(StrMatch("one", rule_name="s1"), StrMatch("two", rule_name="s2"), rule_name="variable")} context, node = init(foo, grammar, "one two") updated = ConceptNodeEvaluator().finalize_concept( context.sheerka, context.sheerka.new(node.concept.key), node.underlying) assert updated.props["variable"].value == "'one two'" assert updated.props["s1"].value == "'one'" assert updated.props["s2"].value == "'two'" assert updated.body == "'one two'" def test_concept_property_is_correctly_updated_for_optional(): foo = Concept("foo") grammar = {foo: Sequence("one", Optional("two", rule_name="o"), rule_name="variable")} context, node = init(foo, grammar, "one two") updated = ConceptNodeEvaluator().finalize_concept( context.sheerka, context.sheerka.new(node.concept.key), node.underlying) assert "variable" in updated.props assert updated.props["variable"].value == "'one two'" assert updated.props["o"].value == "'two'" assert updated.body == "'one two'" def test_concept_property_is_correctly_updated_for_zero_or_more(): foo = Concept("foo") grammar = {foo: ZeroOrMore("one", rule_name="variable")} context, node = init(foo, grammar, "one one one") updated = ConceptNodeEvaluator().finalize_concept( context.sheerka, context.sheerka.new(node.concept.key), node.underlying) assert "variable" in updated.props assert updated.props["variable"].value == "'one one one'" assert updated.body == "'one one one'" def test_concept_property_is_correctly_updated_when_list_of_properties(): foo = Concept("foo") grammar = {foo: Sequence(StrMatch("one", rule_name="s"), StrMatch("two", rule_name="s"), rule_name="variable")} context, node = init(foo, grammar, "one two") updated = ConceptNodeEvaluator().finalize_concept( context.sheerka, context.sheerka.new(node.concept.key), node.underlying) assert updated.props["variable"].value == "'one two'" assert updated.props["s"].value == ["'one'", "'two'"] assert updated.body == "'one two'" def test_concept_property_is_correctly_updated_when_another_concept(): foo = Concept("foo") bar = Concept("bar") grammar = { foo: Sequence("one", "two", rule_name="var"), bar: Sequence(foo, "three", "four", rule_name="var")} context, node = init([foo, bar], grammar, "one two three four") updated = ConceptNodeEvaluator().finalize_concept( context.sheerka, context.sheerka.new(node.concept.key), node.underlying) assert updated.body == "foo 'three four'" assert updated.props["var"].value == "foo 'three four'" assert updated.props["foo"].value == Concept("foo", body="'one two'").set_prop("var", "'one two'").init_key() def test_concept_property_is_correctly_updated_when_concept_recursion_using_optional(): number = Concept("number") add = Concept("add") grammar = { number: OrderedChoice("one", "two"), add: Sequence(number, Optional(Sequence(OrderedChoice("plus", "minus", rule_name="op"), add))) } context, node = init([number, add], grammar, "one plus two") updated = ConceptNodeEvaluator().finalize_concept( context.sheerka, context.sheerka.new(node.concept.key), node.underlying) assert updated.props["number"].value == Concept("number", body="'one'").init_key() assert updated.props["op"].value == "'plus'" expected_add = Concept("add", body="number"). \ set_prop("number", Concept("number", body="'two'").init_key()). \ init_key() assert updated.props["add"].value == expected_add def test_concept_property_is_correctly_updated_when_concept_recursion_using_zero_or_more(): number = Concept("number") add = Concept("add") grammar = { number: OrderedChoice("one", "two", 'three'), add: Sequence(number, ZeroOrMore(Sequence(OrderedChoice("plus", "minus", rule_name="op"), number))) } context, node = init([number, add], grammar, "one plus two minus three") updated = ConceptNodeEvaluator().finalize_concept( context.sheerka, context.sheerka.new(node.concept.key), node.underlying, init_empty_body=True) assert updated.props["number"].value == [Concept("number", body="'one'").init_key(), Concept("number", body="'two'").init_key(), Concept("number", body="'three'").init_key()] assert updated.props["op"].value == ["'plus'", "'minus'"]