Fixed BNF concept evaluations
This commit is contained in:
@@ -9,9 +9,17 @@ from parsers.BaseParser import BaseParser
|
||||
("'hello' 'world'", "'hello' 'world'"),
|
||||
("def concept a from", "def concept a from"),
|
||||
("()[]{}1=1.5+-/*><&é", "()[]{}1=1.5+-/*><&é"),
|
||||
("execute(c:concept_name:)", "execute(__C__concept_name__C__)")
|
||||
("execute(c:concept_name:)", "execute(c:concept_name:)")
|
||||
|
||||
])
|
||||
def test_i_can_get_text_from_tokens(text, expected_text):
|
||||
tokens = list(Tokenizer(text))
|
||||
assert BaseParser.get_text_from_tokens(tokens) == expected_text
|
||||
|
||||
|
||||
@pytest.mark.parametrize("text, custom, expected_text", [
|
||||
("execute(c:concept_name:)", {TokenKind.CONCEPT: lambda t: f"__C__{t.value}"}, "execute(__C__concept_name)")
|
||||
])
|
||||
def test_i_can_get_text_from_tokens_with_custom_switcher(text, custom, expected_text):
|
||||
tokens = list(Tokenizer(text))
|
||||
assert BaseParser.get_text_from_tokens(tokens, custom) == expected_text
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
import pytest
|
||||
|
||||
from core.builtin_concepts import ReturnValueConcept, ParserResultConcept
|
||||
from core.concept import Concept
|
||||
from core.sheerka import Sheerka, ExecutionContext
|
||||
from evaluators.BaseEvaluator import BaseEvaluator
|
||||
from evaluators.ConceptComposerEvaluator import ConceptComposerEvaluator
|
||||
from parsers.BaseParser import BaseParser
|
||||
from parsers.ConceptLexerParser import ConceptNode, ConceptLexerParser, Sequence
|
||||
from sdp.sheerkaDataProvider import Event
|
||||
|
||||
concept_lexer_name = ConceptLexerParser().name
|
||||
|
||||
|
||||
def get_context():
|
||||
sheerka = Sheerka(skip_builtins_in_db=True)
|
||||
sheerka.initialize("mem://")
|
||||
return ExecutionContext("test", Event(), sheerka)
|
||||
|
||||
|
||||
def get_return_values(context, grammar, expression):
|
||||
parser = ConceptLexerParser()
|
||||
parser.initialize(context, grammar)
|
||||
|
||||
ret_val = parser.parse(context, expression)
|
||||
assert not ret_val.status
|
||||
return [ret_val]
|
||||
|
||||
|
||||
def init(concepts, grammar, expression):
|
||||
context = get_context()
|
||||
for c in concepts:
|
||||
context.sheerka.add_in_cache(c)
|
||||
return_values = get_return_values(context, grammar, expression)
|
||||
|
||||
return context, return_values
|
||||
|
||||
|
||||
@pytest.mark.parametrize("return_values, expected", [
|
||||
([
|
||||
ReturnValueConcept(BaseParser.PREFIX + "some_name", False, "in error"),
|
||||
ReturnValueConcept(concept_lexer_name, False, ParserResultConcept(value=[ConceptNode(Concept(), 0, 0)])),
|
||||
ReturnValueConcept("not a parser", True, "some value"),
|
||||
], True),
|
||||
([
|
||||
ReturnValueConcept(concept_lexer_name, False, ParserResultConcept(value=[ConceptNode(Concept(), 0, 0)])),
|
||||
], True),
|
||||
([
|
||||
ReturnValueConcept(BaseParser.PREFIX + "some_name", True, "not in error"),
|
||||
ReturnValueConcept(concept_lexer_name, False, ParserResultConcept(value=[ConceptNode(Concept(), 0, 0)])),
|
||||
], False),
|
||||
([
|
||||
ReturnValueConcept(BaseParser.PREFIX + "some_name", False, "in error"),
|
||||
ReturnValueConcept(concept_lexer_name, True, ParserResultConcept(value=[ConceptNode(Concept(), 0, 0)])),
|
||||
], False),
|
||||
([
|
||||
ReturnValueConcept(BaseParser.PREFIX + "some_name", False, "in error"),
|
||||
ReturnValueConcept(concept_lexer_name, False, "some value"),
|
||||
], False),
|
||||
([
|
||||
ReturnValueConcept(BaseParser.PREFIX + "some_name", False, "in error"),
|
||||
ReturnValueConcept(concept_lexer_name, False, ParserResultConcept(value=["not a concept"])),
|
||||
], False),
|
||||
([
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", False, "evaluator in error"),
|
||||
ReturnValueConcept(concept_lexer_name, False, ParserResultConcept(value=[ConceptNode(Concept(), 0, 0)])),
|
||||
ReturnValueConcept("not a parser", True, "some value"),
|
||||
], False),
|
||||
([
|
||||
ReturnValueConcept(BaseEvaluator.PREFIX + "some_name", True, "evaluator"),
|
||||
ReturnValueConcept(concept_lexer_name, False, ParserResultConcept(value=[ConceptNode(Concept(), 0, 0)])),
|
||||
ReturnValueConcept("not a parser", True, "some value"),
|
||||
], False),
|
||||
])
|
||||
def test_i_can_match(return_values, expected):
|
||||
context = get_context()
|
||||
assert ConceptComposerEvaluator().matches(context, return_values) == expected
|
||||
|
||||
|
||||
def test_i_can_eval_simple_concepts():
|
||||
foo = Concept("foo", body="'foo'")
|
||||
bar = Concept("bar", body="'bar'")
|
||||
grammar = {}
|
||||
context, return_values = init([foo, bar], grammar, "bar foo")
|
||||
|
||||
composer = ConceptComposerEvaluator()
|
||||
assert composer.matches(context, return_values)
|
||||
|
||||
ret_val = composer.eval(context, return_values)
|
||||
assert ret_val.status
|
||||
assert ret_val.who == composer.name
|
||||
assert ret_val.value == [Concept("bar", body="bar").init_key(), Concept("foo", body="foo").init_key()]
|
||||
assert ret_val.value[0].metadata.is_evaluated
|
||||
assert ret_val.value[1].metadata.is_evaluated
|
||||
assert ret_val.parents == [return_values[0]]
|
||||
|
||||
|
||||
def test_i_can_eval_simple_concepts_when_some_are_bnf():
|
||||
foo = Concept("foo", body="'foo'")
|
||||
bar = Concept("bar", body="'bar'")
|
||||
grammar = {foo: "foo"}
|
||||
context, return_values = init([foo, bar], grammar, "bar foo")
|
||||
|
||||
composer = ConceptComposerEvaluator()
|
||||
assert composer.matches(context, return_values)
|
||||
|
||||
ret_val = composer.eval(context, return_values)
|
||||
assert ret_val.status
|
||||
assert ret_val.who == composer.name
|
||||
assert ret_val.value == [Concept("bar", body="bar").init_key(), Concept("foo", body="foo").init_key()]
|
||||
assert ret_val.value[0].metadata.is_evaluated
|
||||
assert ret_val.value[1].metadata.is_evaluated
|
||||
assert ret_val.parents == [return_values[0]]
|
||||
|
||||
|
||||
def test_i_can_eval_simple_concept_and_text():
|
||||
foo = Concept("foo", body="'foo'")
|
||||
grammar = {}
|
||||
context, return_values = init([foo], grammar, "'bar' foo")
|
||||
|
||||
composer = ConceptComposerEvaluator()
|
||||
assert composer.matches(context, return_values)
|
||||
|
||||
ret_val = composer.eval(context, return_values)
|
||||
assert ret_val.status
|
||||
assert ret_val.who == composer.name
|
||||
assert ret_val.value == "bar foo"
|
||||
assert ret_val.parents == [return_values[0]]
|
||||
@@ -5,7 +5,7 @@ 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
|
||||
StrMatch, Optional, OrderedChoice, ZeroOrMore, UnrecognizedTokensNode, ConceptMatch
|
||||
from sdp.sheerkaDataProvider import Event
|
||||
|
||||
|
||||
@@ -15,23 +15,26 @@ def get_context():
|
||||
return ExecutionContext("test", Event(), sheerka)
|
||||
|
||||
|
||||
def get_return_value(nodes, source):
|
||||
return ReturnValueConcept(
|
||||
"some_name",
|
||||
True,
|
||||
ParserResultConcept(parser=ConceptLexerParser(),
|
||||
source=source,
|
||||
value=nodes,
|
||||
try_parsed=nodes))
|
||||
|
||||
|
||||
def get_concept_node(context, grammar, expression):
|
||||
def get_return_value(context, grammar, expression):
|
||||
parser = ConceptLexerParser()
|
||||
parser.initialize(context, grammar)
|
||||
|
||||
res = parser.parse(context, expression)
|
||||
assert res.status
|
||||
return res.value.value[0]
|
||||
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", [
|
||||
@@ -53,174 +56,172 @@ def test_i_can_match(ret_val, expected):
|
||||
assert ConceptNodeEvaluator().matches(context, ret_val) == expected
|
||||
|
||||
|
||||
def test_concept_is_returned_when_list_of_one_concept_node():
|
||||
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()
|
||||
node = ConceptNode(foo, 0, 0, underlying=TerminalNode(StrMatch("foo"), 0, 0, "foo"))
|
||||
ret_val = get_return_value(context, {foo: StrMatch("foo")}, "foo")
|
||||
|
||||
ret_val = get_return_value([node], "h")
|
||||
result = evaluator.eval(context, ret_val)
|
||||
|
||||
assert result.who == evaluator.name
|
||||
assert result.status
|
||||
assert result.value == Concept("foo", body="foo").init_key()
|
||||
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():
|
||||
context = get_context()
|
||||
|
||||
foo = Concept("foo")
|
||||
concept_node = get_concept_node(context, {foo: StrMatch("foo", rule_name="variable")}, "foo")
|
||||
updated = ConceptNodeEvaluator().update_concept(context.sheerka, concept_node.concept, concept_node.underlying)
|
||||
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.props["variable"].value == "'foo'"
|
||||
assert updated.body == "'foo'"
|
||||
|
||||
|
||||
def test_concept_property_is_correctly_updated_for_sequence():
|
||||
context = get_context()
|
||||
|
||||
foo = Concept("foo")
|
||||
grammar = {foo: Sequence("one", "two", rule_name="variable")}
|
||||
concept_node = get_concept_node(context, grammar, "one two")
|
||||
updated = ConceptNodeEvaluator().update_concept(context.sheerka, concept_node.concept, concept_node.underlying)
|
||||
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["variable"].value == "'one two'"
|
||||
assert updated.body == "'one two'"
|
||||
|
||||
|
||||
def test_concept_property_is_updated_for_str_in_sequence():
|
||||
context = get_context()
|
||||
|
||||
foo = Concept("foo")
|
||||
grammar = {foo: Sequence(StrMatch("one", rule_name="s1"), StrMatch("two", rule_name="s2"), rule_name="variable")}
|
||||
concept_node = get_concept_node(context, grammar, "one two")
|
||||
context, node = init(foo, grammar, "one two")
|
||||
|
||||
updated = ConceptNodeEvaluator().update_concept(context.sheerka, concept_node.concept, concept_node.underlying)
|
||||
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.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():
|
||||
context = get_context()
|
||||
|
||||
foo = Concept("foo")
|
||||
grammar = {foo: Sequence("one", Optional("two", rule_name="o"), rule_name="variable")}
|
||||
concept_node = get_concept_node(context, grammar, "one two")
|
||||
context, node = init(foo, grammar, "one two")
|
||||
|
||||
updated = ConceptNodeEvaluator().update_concept(
|
||||
updated = ConceptNodeEvaluator().finalize_concept(
|
||||
context.sheerka,
|
||||
context.sheerka.new(concept_node.concept.key),
|
||||
concept_node.underlying)
|
||||
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.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():
|
||||
context = get_context()
|
||||
|
||||
foo = Concept("foo")
|
||||
grammar = {foo: ZeroOrMore("one", rule_name="variable")}
|
||||
concept_node = get_concept_node(context, grammar, "one one one")
|
||||
context, node = init(foo, grammar, "one one one")
|
||||
|
||||
updated = ConceptNodeEvaluator().update_concept(
|
||||
updated = ConceptNodeEvaluator().finalize_concept(
|
||||
context.sheerka,
|
||||
context.sheerka.new(concept_node.concept.key),
|
||||
concept_node.underlying)
|
||||
context.sheerka.new(node.concept.key),
|
||||
node.underlying)
|
||||
|
||||
assert "variable" in updated.props
|
||||
assert updated.props["variable"].value == "one one one"
|
||||
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():
|
||||
context = get_context()
|
||||
|
||||
foo = Concept("foo")
|
||||
grammar = {foo: Sequence(StrMatch("one", rule_name="s"), StrMatch("two", rule_name="s"), rule_name="variable")}
|
||||
concept_node = get_concept_node(context, grammar, "one two")
|
||||
context, node = init(foo, grammar, "one two")
|
||||
|
||||
updated = ConceptNodeEvaluator().update_concept(
|
||||
updated = ConceptNodeEvaluator().finalize_concept(
|
||||
context.sheerka,
|
||||
context.sheerka.new(concept_node.concept.key),
|
||||
concept_node.underlying)
|
||||
context.sheerka.new(node.concept.key),
|
||||
node.underlying)
|
||||
|
||||
assert updated.props["variable"].value == "one two"
|
||||
assert updated.props["s"].value == ["one", "two"]
|
||||
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():
|
||||
context = get_context()
|
||||
|
||||
foo = Concept("foo")
|
||||
bar = Concept("bar")
|
||||
context.sheerka.add_in_cache(foo)
|
||||
context.sheerka.add_in_cache(bar)
|
||||
grammar = {
|
||||
foo: Sequence("one", "two", rule_name="var"),
|
||||
bar: Sequence(foo, "three", rule_name="var")}
|
||||
concept_node = get_concept_node(context, grammar, "one two three")
|
||||
bar: Sequence(foo, "three", "four", rule_name="var")}
|
||||
context, node = init([foo, bar], grammar, "one two three four")
|
||||
|
||||
updated = ConceptNodeEvaluator().update_concept(
|
||||
updated = ConceptNodeEvaluator().finalize_concept(
|
||||
context.sheerka,
|
||||
context.sheerka.new(concept_node.concept.key),
|
||||
concept_node.underlying)
|
||||
context.sheerka.new(node.concept.key),
|
||||
node.underlying)
|
||||
|
||||
assert updated.props["var"].value == "one two three"
|
||||
assert updated.props["foo"].value == Concept("foo", body="one two").set_prop("var", "one two").init_key()
|
||||
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():
|
||||
context = get_context()
|
||||
|
||||
number = Concept("number")
|
||||
add = Concept("add")
|
||||
context.sheerka.add_in_cache(number)
|
||||
context.sheerka.add_in_cache(add)
|
||||
grammar = {
|
||||
number: OrderedChoice("one", "two"),
|
||||
add: Sequence(number, Optional(Sequence(OrderedChoice("plus", "minus", rule_name="op"), add)))
|
||||
}
|
||||
concept_node = get_concept_node(context, grammar, "one plus two")
|
||||
context, node = init([number, add], grammar, "one plus two")
|
||||
|
||||
updated = ConceptNodeEvaluator().update_concept(
|
||||
updated = ConceptNodeEvaluator().finalize_concept(
|
||||
context.sheerka,
|
||||
context.sheerka.new(concept_node.concept.key),
|
||||
concept_node.underlying)
|
||||
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="two").set_prop("number", Concept("number", body="two").init_key()).init_key()
|
||||
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():
|
||||
context = get_context()
|
||||
|
||||
number = Concept("number")
|
||||
add = Concept("add")
|
||||
context.sheerka.add_in_cache(number)
|
||||
context.sheerka.add_in_cache(add)
|
||||
grammar = {
|
||||
number: OrderedChoice("one", "two", 'three'),
|
||||
add: Sequence(number, ZeroOrMore(Sequence(OrderedChoice("plus", "minus", rule_name="op"), number)))
|
||||
}
|
||||
concept_node = get_concept_node(context, grammar, "one plus two minus three")
|
||||
context, node = init([number, add], grammar, "one plus two minus three")
|
||||
|
||||
updated = ConceptNodeEvaluator().update_concept(
|
||||
updated = ConceptNodeEvaluator().finalize_concept(
|
||||
context.sheerka,
|
||||
context.sheerka.new(concept_node.concept.key),
|
||||
concept_node.underlying,
|
||||
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"]
|
||||
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'"]
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ def test_i_can_eval_concept_token():
|
||||
assert evaluated.status
|
||||
assert evaluated.value == "foo"
|
||||
|
||||
# sanity, to make sure that otherwise foo is resolved to '2'
|
||||
# sanity, does not work otherwise
|
||||
parsed = PythonParser().parse(context, "get_context_name(foo)")
|
||||
python_evaluator = PythonEvaluator()
|
||||
python_evaluator.locals["get_context_name"] = get_context_name
|
||||
|
||||
+49
-31
@@ -332,6 +332,7 @@ def test_i_cannot_instantiate_when_properties_are_not_recognized():
|
||||
(Concept("name", body=["foo"]), True, "foo"),
|
||||
(Concept("name", body=Concept("foo")), False, Concept("foo")),
|
||||
(Concept("name", body=Concept("foo", body="value")), False, "value"),
|
||||
(Concept("name", body=Concept("foo", body=Concept("bar", body="value"))), False, "value"),
|
||||
(Concept("name", body=Concept("foo", body=ReturnValueConcept(value="return_value"))), False, "return_value"),
|
||||
])
|
||||
def test_i_can_get_value(concept, reduce_simple_list, expected):
|
||||
@@ -404,7 +405,7 @@ def test_i_can_evaluate_the_other_metadata(expr, expected):
|
||||
|
||||
|
||||
@pytest.mark.parametrize("expr, expected", [
|
||||
(None, None),
|
||||
# (None, None),
|
||||
("", ""),
|
||||
("1", 1),
|
||||
("1+1", 2),
|
||||
@@ -450,6 +451,7 @@ def test_i_can_evaluate_when_another_concept_is_referenced():
|
||||
assert sheerka.isinstance(evaluated.body, concept_a)
|
||||
assert id(evaluated.body) != id(concept_a)
|
||||
assert evaluated.metadata.is_evaluated
|
||||
assert evaluated.body.metadata.is_evaluated
|
||||
|
||||
|
||||
def test_i_can_evaluate_when_the_referenced_concept_has_a_body():
|
||||
@@ -461,34 +463,50 @@ def test_i_can_evaluate_when_the_referenced_concept_has_a_body():
|
||||
evaluated = sheerka.evaluate_concept(get_context(sheerka), concept)
|
||||
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == 1
|
||||
assert not concept_a.metadata.is_evaluated #
|
||||
assert evaluated.body == Concept("a", body=1).init_key()
|
||||
assert not concept_a.metadata.is_evaluated
|
||||
assert evaluated.metadata.is_evaluated
|
||||
|
||||
|
||||
def test_i_can_evaluate_concept_of_concept_when_the_leaf_has_a_body():
|
||||
sheerka = get_sheerka()
|
||||
sheerka.add_in_cache(Concept(name="a", body="'a'").init_key())
|
||||
sheerka.add_in_cache(Concept(name="b", body="a").init_key())
|
||||
sheerka.add_in_cache(Concept(name="c", body="b").init_key())
|
||||
concept_d = sheerka.add_in_cache(Concept(name="d", body="c").init_key())
|
||||
sheerka.add_in_cache(Concept(name="a", body="'a'"))
|
||||
sheerka.add_in_cache(Concept(name="b", body="a"))
|
||||
sheerka.add_in_cache(Concept(name="c", body="b"))
|
||||
concept_d = sheerka.add_in_cache(Concept(name="d", body="c"))
|
||||
|
||||
evaluated = sheerka.evaluate_concept(get_context(sheerka), concept_d)
|
||||
|
||||
assert evaluated.key == concept_d.key
|
||||
assert evaluated.body == 'a'
|
||||
assert evaluated.body == Concept(
|
||||
name="c",
|
||||
body=Concept(
|
||||
name="b",
|
||||
body=Concept(
|
||||
name="a",
|
||||
body="a").init_key()).init_key()).init_key()
|
||||
assert sheerka.value(evaluated) == 'a'
|
||||
assert evaluated.metadata.is_evaluated
|
||||
|
||||
|
||||
def test_i_can_evaluate_concept_of_concept_does_not_have_a_body():
|
||||
sheerka = get_sheerka()
|
||||
concept_a = sheerka.add_in_cache(Concept(name="a").init_key())
|
||||
sheerka.add_in_cache(Concept(name="b", body="a").init_key())
|
||||
sheerka.add_in_cache(Concept(name="c", body="b").init_key())
|
||||
concept_d = sheerka.add_in_cache(Concept(name="d", body="c").init_key())
|
||||
sheerka.add_in_cache(Concept(name="a"))
|
||||
sheerka.add_in_cache(Concept(name="b", body="a"))
|
||||
sheerka.add_in_cache(Concept(name="c", body="b"))
|
||||
concept_d = sheerka.add_in_cache(Concept(name="d", body="c"))
|
||||
|
||||
evaluated = sheerka.evaluate_concept(get_context(sheerka), concept_d)
|
||||
|
||||
assert evaluated.key == concept_d.key
|
||||
assert sheerka.isinstance(evaluated.body, concept_a)
|
||||
assert evaluated.body == Concept(
|
||||
name="c",
|
||||
body=Concept(
|
||||
name="b",
|
||||
body=Concept(
|
||||
name="a").init_key()).init_key()).init_key()
|
||||
assert sheerka.value(evaluated) == Concept(name="a").init_key()
|
||||
assert evaluated.metadata.is_evaluated
|
||||
|
||||
|
||||
def test_i_can_evaluate_concept_when_properties_reference_others_concepts():
|
||||
@@ -509,9 +527,9 @@ def test_i_can_evaluate_concept_when_properties_reference_others_concepts_2():
|
||||
:return:
|
||||
"""
|
||||
sheerka = get_sheerka()
|
||||
concept_a = sheerka.add_in_cache(Concept(name="a").init_key())
|
||||
concept_a = sheerka.add_in_cache(Concept(name="a"))
|
||||
|
||||
concept = Concept("foo", body="concept_a").set_prop("concept_a", "a").init_key()
|
||||
concept = Concept("foo", body="concept_a").set_prop("concept_a", "a")
|
||||
evaluated = sheerka.evaluate_concept(get_context(sheerka), concept)
|
||||
|
||||
assert evaluated.key == concept.key
|
||||
@@ -520,10 +538,10 @@ def test_i_can_evaluate_concept_when_properties_reference_others_concepts_2():
|
||||
|
||||
def test_i_can_evaluate_concept_when_properties_reference_others_concepts_with_body():
|
||||
sheerka = get_sheerka()
|
||||
sheerka.add_in_cache(Concept(name="a", body="1").init_key())
|
||||
sheerka.add_in_cache(Concept(name="b", body="2").init_key())
|
||||
sheerka.add_in_cache(Concept(name="a", body="1"))
|
||||
sheerka.add_in_cache(Concept(name="b", body="2"))
|
||||
|
||||
concept = Concept("foo", body="propA + propB").set_prop("propA", "a").set_prop("propB", "b").init_key()
|
||||
concept = Concept("foo", body="propA + propB").set_prop("propA", "a").set_prop("propB", "b")
|
||||
evaluated = sheerka.evaluate_concept(get_context(sheerka), concept)
|
||||
|
||||
assert evaluated.key == concept.key
|
||||
@@ -542,33 +560,33 @@ def test_i_can_reference_sheerka():
|
||||
|
||||
def test_properties_values_takes_precedence_over_the_outside_world():
|
||||
sheerka = get_sheerka()
|
||||
sheerka.add_in_cache(Concept(name="a", body="'concept_a'").init_key())
|
||||
sheerka.add_in_cache(Concept(name="b", body="'concept_b'").init_key())
|
||||
sheerka.add_in_cache(Concept(name="a", body="'concept_a'"))
|
||||
sheerka.add_in_cache(Concept(name="b", body="'concept_b'"))
|
||||
|
||||
concept = Concept("foo", body="a").init_key()
|
||||
concept = Concept("foo", body="a")
|
||||
evaluated = sheerka.evaluate_concept(get_context(sheerka), concept)
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == 'concept_a' # this test was already done
|
||||
assert evaluated.body == Concept(name="a", body="concept_a").init_key() # this test was already done
|
||||
|
||||
# so check this one.
|
||||
concept = Concept("foo", body="a").set_prop("a", "'property_a'").init_key()
|
||||
concept = Concept("foo", body="a").set_prop("a", "'property_a'")
|
||||
evaluated = sheerka.evaluate_concept(get_context(sheerka), concept)
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == 'property_a'
|
||||
|
||||
# or this one.
|
||||
concept = Concept("foo", body="a").set_prop("a", "b").init_key()
|
||||
concept = Concept("foo", body="a").set_prop("a", "b")
|
||||
evaluated = sheerka.evaluate_concept(get_context(sheerka), concept)
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == 'concept_b'
|
||||
assert evaluated.body == Concept(name="b", body="concept_b").init_key()
|
||||
|
||||
|
||||
def test_properties_values_takes_precedence():
|
||||
sheerka = get_sheerka()
|
||||
sheerka.add_in_cache(Concept(name="a", body="'concept_a'").init_key())
|
||||
sheerka.add_in_cache(Concept(name="b", body="'concept_b'").init_key())
|
||||
sheerka.add_in_cache(Concept(name="a", body="'concept_a'"))
|
||||
sheerka.add_in_cache(Concept(name="b", body="'concept_b'"))
|
||||
|
||||
concept = Concept("foo", body="a + b").set_prop("a", "'prop_a'").init_key()
|
||||
concept = Concept("foo", body="a + b").set_prop("a", "'prop_a'")
|
||||
evaluated = sheerka.evaluate_concept(get_context(sheerka), concept)
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == 'prop_aconcept_b'
|
||||
@@ -576,9 +594,9 @@ def test_properties_values_takes_precedence():
|
||||
|
||||
def test_i_can_reference_sub_property_of_a_property():
|
||||
sheerka = get_sheerka()
|
||||
sheerka.add_in_cache(Concept(name="concept_a").set_prop("subProp", "'sub_a'").init_key())
|
||||
sheerka.add_in_cache(Concept(name="concept_a").set_prop("subProp", "'sub_a'"))
|
||||
|
||||
concept = Concept("foo", body="a.props['subProp'].value").set_prop("a", "concept_a").init_key()
|
||||
concept = Concept("foo", body="a.props['subProp'].value").set_prop("a", "concept_a")
|
||||
evaluated = sheerka.evaluate_concept(get_context(sheerka), concept)
|
||||
assert evaluated.key == concept.key
|
||||
assert evaluated.body == 'sub_a'
|
||||
@@ -587,7 +605,7 @@ def test_i_can_reference_sub_property_of_a_property():
|
||||
def test_i_cannot_evaluate_concept_if_property_is_in_error():
|
||||
sheerka = get_sheerka()
|
||||
|
||||
concept = Concept(name="concept_a").set_prop("subProp", "undef_concept").init_key()
|
||||
concept = Concept(name="concept_a").set_prop("subProp", "undef_concept")
|
||||
evaluated = sheerka.evaluate_concept(get_context(sheerka), concept)
|
||||
assert sheerka.isinstance(evaluated, BuiltinConcepts.CONCEPT_EVAL_ERROR)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Make sure that the evaluators works as expected
|
||||
from core.builtin_concepts import BuiltinConcepts, SuccessConcept
|
||||
from core.builtin_concepts import BuiltinConcepts
|
||||
from core.concept import Concept
|
||||
from core.sheerka import Sheerka, ExecutionContext
|
||||
from evaluators.BaseEvaluator import OneReturnValueEvaluator, BaseEvaluator, AllReturnValuesEvaluator
|
||||
@@ -157,7 +157,7 @@ class EvaluatorAllReduceFooBar(EvaluatorAllWithPriority):
|
||||
|
||||
def eval(self, context, return_values):
|
||||
super().eval(context, return_values)
|
||||
ret = get_ret_val(context.sheerka, SuccessConcept())
|
||||
ret = get_ret_val(context.sheerka, context.sheerka.new(BuiltinConcepts.SUCCESS))
|
||||
ret.parents = return_values
|
||||
return ret
|
||||
|
||||
|
||||
@@ -240,13 +240,17 @@ def test_i_can_eval_concept_with_variable():
|
||||
|
||||
def test_i_can_eval_concept_with_variable_and_python_as_body():
|
||||
sheerka = get_sheerka()
|
||||
sheerka.add_in_cache(Concept(name="hello a", body="'hello ' + a").set_prop("a"))
|
||||
hello_a = sheerka.add_in_cache(Concept(name="hello a", body="'hello ' + a").set_prop("a"))
|
||||
sheerka.add_in_cache(Concept(name="foo", body="'foo'"))
|
||||
|
||||
res = sheerka.evaluate_user_input("hello foo")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].value, "hello foo"
|
||||
assert sheerka.isinstance(res[0].value, hello_a)
|
||||
assert res[0].value.body == "hello foo"
|
||||
assert res[0].value.metadata.is_evaluated
|
||||
assert res[0].value.props["a"].value == Concept(name="foo", body="foo").init_key()
|
||||
assert res[0].value.props["a"].value.metadata.is_evaluated
|
||||
|
||||
|
||||
def test_i_can_eval_duplicate_concepts_with_same_value():
|
||||
@@ -259,7 +263,7 @@ def test_i_can_eval_duplicate_concepts_with_same_value():
|
||||
res = sheerka.evaluate_user_input("hello foo")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].value, "hello foo"
|
||||
assert res[0].value.body == "hello foo"
|
||||
assert res[0].who == sheerka.get_evaluator_name(MultipleSameSuccessEvaluator.NAME)
|
||||
|
||||
|
||||
@@ -362,7 +366,11 @@ def test_i_can_eval_bnf_definitions_with_variables():
|
||||
return_value = res[0].value
|
||||
|
||||
assert sheerka.isinstance(return_value, concept_b)
|
||||
assert return_value.props["a"] == Property("a", sheerka.new(concept_a.key, body="one"))
|
||||
assert return_value.body == "one three"
|
||||
assert return_value.metadata.is_evaluated
|
||||
|
||||
assert return_value.props["a"] == Property("a", sheerka.new(concept_a.key, body="one").init_key())
|
||||
assert return_value.props["a"].value.metadata.is_evaluated
|
||||
|
||||
|
||||
def test_i_can_eval_bnf_definitions_from_separate_instances():
|
||||
@@ -390,6 +398,8 @@ def test_i_can_eval_bnf_definitions_from_separate_instances():
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(res[0].value, concept_b)
|
||||
assert res[0].value.body == "one two three"
|
||||
assert res[0].value.props["a"] == Property("a", sheerka.new(concept_a.key, body="one two").init_key())
|
||||
|
||||
|
||||
def test_i_can_say_that_a_concept_isa_another_concept():
|
||||
@@ -398,6 +408,7 @@ def test_i_can_say_that_a_concept_isa_another_concept():
|
||||
sheerka.evaluate_user_input("def concept bar")
|
||||
|
||||
res = sheerka.evaluate_user_input("foo isa bar")
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert sheerka.isinstance(res[0].body, BuiltinConcepts.SUCCESS)
|
||||
|
||||
@@ -436,3 +447,40 @@ def test_i_can_manage_tokenizer_error(text):
|
||||
assert len(res) > 1
|
||||
for r in [r for r in res if r.who.startswith("parsers.")]:
|
||||
assert not r.status
|
||||
|
||||
|
||||
def test_i_can_recognize_concept_from_string():
|
||||
sheerka = get_sheerka()
|
||||
sheerka.add_in_cache(Concept("one", body="1"))
|
||||
|
||||
res = sheerka.evaluate_user_input("'one'")
|
||||
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].body == "one"
|
||||
|
||||
res = sheerka.evaluate_user_input("eval 'one'")
|
||||
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].body == "one"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("expression", [
|
||||
"def concept twenties from bnf 'twenty' (one | two)=unit as 20 + unit",
|
||||
"def concept twenties from bnf 'twenty' (one | two)=unit as twenty + unit",
|
||||
"def concept twenties from bnf twenty (one | two)=unit as 20 + unit",
|
||||
"def concept twenties from bnf twenty (one | two)=unit as twenty + unit",
|
||||
])
|
||||
def test_i_can_evaluate_bnf_concepts(expression):
|
||||
sheerka = get_sheerka()
|
||||
|
||||
sheerka.evaluate_user_input("def concept one as 1")
|
||||
sheerka.evaluate_user_input("def concept two as 2")
|
||||
sheerka.evaluate_user_input("def concept twenty as 20")
|
||||
sheerka.evaluate_user_input(expression)
|
||||
res = sheerka.evaluate_user_input("eval twenty one")
|
||||
|
||||
assert len(res) == 1
|
||||
assert res[0].status
|
||||
assert res[0].body == 21
|
||||
|
||||
@@ -125,6 +125,11 @@ def test_i_can_strip_eof():
|
||||
assert actual == expected
|
||||
|
||||
|
||||
def test_i_can_escape():
|
||||
actual = core.utils.escape_char("hello 'world' my friend", "'")
|
||||
assert actual == "hello \\'world\\' my friend"
|
||||
|
||||
|
||||
def get_tokens(lst):
|
||||
res = []
|
||||
for e in lst:
|
||||
|
||||
Reference in New Issue
Block a user