228 lines
8.7 KiB
Python
228 lines
8.7 KiB
Python
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'"]
|
|
|