Fixed BNF concept evaluations

This commit is contained in:
2020-01-03 19:19:57 +01:00
parent adcbc6bb2e
commit ffd98d7407
20 changed files with 682 additions and 237 deletions
+9 -1
View File
@@ -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
+128
View File
@@ -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]]
+94 -93
View File
@@ -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'"]
+1 -1
View File
@@ -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
View File
@@ -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)
+2 -2
View File
@@ -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
+52 -4
View File
@@ -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
+5
View File
@@ -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: