Reimplemented explain feature

This commit is contained in:
2020-06-04 18:43:15 +02:00
parent c498b394e3
commit d7573f095f
27 changed files with 1673 additions and 1161 deletions
+255 -48
View File
@@ -3,7 +3,8 @@ from dataclasses import dataclass
import pytest
from core.builtin_concepts import BuiltinConcepts
from core.concept import Concept, ConceptParts
from parsers.ExpressionParser import TrueNode, LambdaNode
from core.sheerka.services.SheerkaFilter import Pipe, SheerkaFilter
from printer.Formatter import Formatter, BraceToken
from printer.SheerkaPrinter import FormatInstructions
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
@@ -149,7 +150,43 @@ class TestSheerkaPrinter(TestUsingMemoryBasedSheerka):
(None)level33
"""
def test_i_can_format_concept(self, capsys):
def test_i_can_format_l_concepts_using_default_format_l_definition(self, capsys):
# default format_l definition
# for all obj of a given type
sheerka = self.get_sheerka()
foo = Concept("foo a b").def_var("a").def_var("b").init_key()
foo.set_value("a", "value a").set_value("b", "value b")
foo.set_value(ConceptParts.BODY, "body")
sheerka.set_id_if_needed(foo, False)
sheerka.printer_handler.register_format_l(foo, "DEFAULT:{id}-{name}-{key}-{body}-{a}-{b}")
sheerka.print(foo)
captured = capsys.readouterr()
assert captured.out == "DEFAULT:1001-foo a b-foo __var__0 __var__1-body-value a-value b\n"
def test_i_can_format_l_concepts_using_context_format_l_definition(self, capsys):
# context format_l definition
# for all obj of a given type in the current print call
sheerka = self.get_sheerka()
foo = Concept("foo a b").def_var("a").def_var("b").init_key()
foo.set_value("a", "value a").set_value("b", "value b")
foo.set_value(ConceptParts.BODY, "body")
sheerka.set_id_if_needed(foo, False)
sheerka.printer_handler.register_format_l(foo, "DEFAULT:{id}-{name}-{key}-{body}-{a}-{b}")
context_instructions = FormatInstructions().set_format_l(foo, "CONTEXT:{id}-{name}-{key}-{body}-{a}-{b}")
sheerka.print(foo, context_instructions)
captured = capsys.readouterr()
assert captured.out == "CONTEXT:1001-foo a b-foo __var__0 __var__1-body-value a-value b\n"
def test_i_can_format_l_concepts_using_item_format_l_definition(self, capsys):
# item format_l definition
# for the item only
sheerka = self.get_sheerka()
foo = Concept("foo a b").def_var("a").def_var("b").init_key()
foo.set_value("a", "value a").set_value("b", "value b")
@@ -157,12 +194,16 @@ class TestSheerkaPrinter(TestUsingMemoryBasedSheerka):
sheerka.set_id_if_needed(foo, False)
sheerka.printer_handler.register_format_l(foo, "{id}-{name}-{key}-{body}-{a}-{b}")
context_instructions = FormatInstructions().set_format_l(foo, "CONTEXT:{id}-{name}-{key}-{body}-{a}-{b}")
item_instructions = FormatInstructions().set_format_l(foo, "ITEM:{id}-{name}-{key}-{body}-{a}-{b}")
sheerka.print(foo)
foo.set_prop(BuiltinConcepts.FORMAT_INSTRUCTIONS, item_instructions)
sheerka.print(foo, context_instructions)
captured = capsys.readouterr()
assert captured.out == "1001-foo a b-foo __var__0 __var__1-body-value a-value b\n"
assert captured.out == "ITEM:1001-foo a b-foo __var__0 __var__1-body-value a-value b\n"
def test_i_can_format_object(self, capsys):
def test_i_can_format_l_objects(self, capsys):
sheerka = self.get_sheerka()
foo = Obj("value a", "value b")
@@ -172,6 +213,21 @@ class TestSheerkaPrinter(TestUsingMemoryBasedSheerka):
captured = capsys.readouterr()
assert captured.out == "value a-value b\n"
def test_i_can_format_l_execution_context(self, capsys):
# In this test, no format_l definition is provided
# The system knows how to format ExecutionContext
sheerka = self.get_sheerka()
context = self.get_context(sheerka)
execution_context = context.push("test_sheerka_printer", "Testing Execution Context Printing")
ret_val = sheerka.ret("test_sheerka_printer", True, sheerka.new(BuiltinConcepts.SUCCESS))
execution_context.add_values(return_value=ret_val)
ec = execution_context.as_bag()
sheerka.print(execution_context)
captured = capsys.readouterr()
assert captured.out == f"[{ec['id']:3}] {ec['desc']} ({ec['status']})\n"
def test_i_can_register_a_custom_format_by_its_name(self, capsys):
sheerka = self.get_sheerka()
foo = Obj("value a", "value b")
@@ -182,80 +238,196 @@ class TestSheerkaPrinter(TestUsingMemoryBasedSheerka):
captured = capsys.readouterr()
assert captured.out == "value a-value b\n"
def test_i_can_define_format_in_print_instruction(self, capsys):
sheerka = self.get_sheerka()
foo = Obj("value a", "value b")
def test_i_can_format_d_concepts_using_default_definition(self, capsys):
sheerka, context, foo = self.init_concepts(Concept("foo a b").def_var("a").def_var("b"))
foo_1 = sheerka.new(foo.key, a="value a", b="value b")
foo_2 = sheerka.new(foo.key, a="value c", b="value d")
lst = [foo_1, foo_2]
instructions = FormatInstructions().set_format_l("tests.core.test_sheerka_printer.Obj", "{a}-{b}")
sheerka.print(foo, instructions)
sheerka.printer_handler.register_format_d(foo, {"a": "DEFAULT:{a}", "b": "DEFAULT:{b}"})
sheerka.print(lst)
captured = capsys.readouterr()
assert captured.out == "value a-value b\n"
assert captured.out == """(1001)foo a b
a: DEFAULT:'value a'
b: DEFAULT:'value b'
(1001)foo a b
a: DEFAULT:'value c'
b: DEFAULT:'value d'
"""
def test_format_print_instruction_override_register_format(self, capsys):
sheerka = self.get_sheerka()
foo = Obj("value a", "value b")
def test_i_can_format_d_concepts_using_context_definition(self, capsys):
sheerka, context, foo = self.init_concepts(Concept("foo a b").def_var("a").def_var("b"))
foo_1 = sheerka.new(foo.key, a="value a", b="value b")
foo_2 = sheerka.new(foo.key, a="value c", b="value d")
lst = [foo_1, foo_2]
sheerka.printer_handler.register_format_l("tests.core.test_sheerka_printer.Obj", "{a}-{b}")
instructions = FormatInstructions().set_format_l("tests.core.test_sheerka_printer.Obj", "a={a} <> b={b}")
sheerka.print(foo, instructions)
sheerka.printer_handler.register_format_d(foo, {"a": "DEFAULT:{a}", "b": "DEFAULT:{b}"})
context_instructions = FormatInstructions().set_format_d(foo, {"a": "CONTEXT:{a}", "b": "CONTEXT:{b}"})
sheerka.print(lst, context_instructions)
captured = capsys.readouterr()
assert captured.out == "a=value a <> b=value b\n"
assert captured.out == """(1001)foo a b
a: CONTEXT:'value a'
b: CONTEXT:'value b'
(1001)foo a b
a: CONTEXT:'value c'
b: CONTEXT:'value d'
"""
def test_i_can_format_d(self, capsys):
def test_i_can_format_d_concepts_using_item_definition(self, capsys):
sheerka, context, foo = self.init_concepts(Concept("foo a b").def_var("a").def_var("b"))
item_instructions = FormatInstructions().set_format_d(foo, {"a": "ITEM:{a}", "b": "ITEM:{b}"})
foo.set_format_instructions(item_instructions)
foo_1 = sheerka.new(foo.key, a="value a", b="value b")
foo_2 = sheerka.new(foo.key, a="value c", b="value d")
lst = [foo_1, foo_2]
sheerka.printer_handler.register_format_d(foo, {"a": "DEFAULT:{a}", "b": "DEFAULT:{b}"})
context_instructions = FormatInstructions().set_format_d(foo, {"a": "CONTEXT:{a}", "b": "CONTEXT:{b}"})
# Note that this time, foo has a format instruction defined
sheerka.print(lst, context_instructions)
captured = capsys.readouterr()
assert captured.out == """(1001)foo a b
a: ITEM:'value a'
b: ITEM:'value b'
(1001)foo a b
a: ITEM:'value c'
b: ITEM:'value d'
"""
def test_i_can_format_d_objects(self, capsys):
sheerka = self.get_sheerka()
foo = [Obj("value a", "value b"), Obj("value c", "value d")]
sheerka.printer_handler.register_format_d(TrueNode(), ["a", "b"])
sheerka.printer_handler.register_format_d(Obj, {"a": "CUSTOM:{a}", "b": "CUSTOM:{b}"})
sheerka.print(foo)
captured = capsys.readouterr()
assert captured.out == """Obj(a='value a', b='value b')
a: value a
b: value b
a: CUSTOM:'value a'
b: CUSTOM:'value b'
Obj(a='value c', b='value d')
a: value c
b: value d
a: CUSTOM:'value c'
b: CUSTOM:'value d'
"""
def test_i_can_format_d_with_only_a_list_of_properties(self, capsys):
sheerka = self.get_sheerka()
foo = [Obj("value a", "value b"), Obj("value c", "value d")]
sheerka.printer_handler.register_format_d(Obj, ["a", "b"])
sheerka.print(foo)
captured = capsys.readouterr()
assert captured.out == """Obj(a='value a', b='value b')
a: 'value a'
b: 'value b'
Obj(a='value c', b='value d')
a: 'value c'
b: 'value d'
"""
def test_i_can_format_d_and_align_properties(self, capsys):
sheerka = self.get_sheerka()
foo = [ObjLongProp("value a", "value b"), ObjLongProp("value c", "value d")]
sheerka.printer_handler.register_format_d(TrueNode(), ["first_property_name", "second"])
sheerka.printer_handler.register_format_d(ObjLongProp, ["first_property_name", "second"])
sheerka.print(foo)
captured = capsys.readouterr()
assert captured.out == """ObjLongProp(first_property_name='value a', second='value b')
first_property_name: value a
second : value b
first_property_name: 'value a'
second : 'value b'
ObjLongProp(first_property_name='value c', second='value d')
first_property_name: value c
second : value d
first_property_name: 'value c'
second : 'value d'
"""
def test_i_can_format_d_all_properties_of_a_concept(self, capsys):
sheerka, context, foo = self.init_concepts(Concept("foo a b").def_var("a").def_var("b"))
foo_1 = sheerka.new(foo.key, a="value a", b="value b")
foo_2 = sheerka.new(foo.key, a="value c", b="value d")
lst = [foo_1, foo_2]
sheerka.printer_handler.register_format_d(foo)
sheerka.print(lst)
captured = capsys.readouterr()
assert captured.out == """(1001)foo a b
a : 'value a'
var.a: *name 'var' is not defined*
b : 'value b'
var.b: *name 'var' is not defined*
id : '1001'
name : 'foo a b'
key : 'foo __var__0 __var__1'
body : __NOT_INITIALIZED
self : (1001)foo a b
(1001)foo a b
a : 'value c'
var.a: *name 'var' is not defined*
b : 'value d'
var.b: *name 'var' is not defined*
id : '1001'
name : 'foo a b'
key : 'foo __var__0 __var__1'
body : __NOT_INITIALIZED
self : (1001)foo a b
"""
def test_i_can_format_d_when_dictionary(self, capsys):
sheerka, context, foo = self.init_concepts(Concept("foo a b").def_var("a").def_var("b"))
dict_value = {
"a": "value a",
"beta": {"b1": 10, "b2": Obj("10", 15), "b3": ["items", "in", "a", "list"]},
"gamma": {"list": ["'quoted string'", '"double" \'single\'', "c3"], "empty": []},
"epsilon": ["a", "b", "c"],
"g": {"tuple": ("tuple-a", "tuple-b", "tuple-b"), "empty": tuple()},
"h": {"set": {"set-a"}, "empty": set()},
}
foo_1 = sheerka.new(foo.key, a="value a", b=dict_value)
lst = [foo_1]
sheerka.printer_handler.register_format_d(foo)
sheerka.print(lst)
captured = capsys.readouterr()
assert captured.out == """(1001)foo a b
a : 'value a'
var.a: *name 'var' is not defined*
b : {'a' : 'value a'
'beta' : {'b1': 10
'b2': Obj(a='10', b=15)
'b3': ['items',
'in',
'a',
'list']}
'gamma' : {'list' : ["'quoted string'",
""double" 'single'",
'c3']
'empty': []}
'epsilon': ['a',
'b',
'c']
'g' : {'tuple': ('tuple-a',
'tuple-b',
'tuple-b')
'empty': ()}
'h' : {'set' : {'set-a'}
'empty': {}}}
var.b: *name 'var' is not defined*
id : '1001'
name : 'foo a b'
key : 'foo __var__0 __var__1'
body : __NOT_INITIALIZED
self : (1001)foo a b
"""
def test_i_can_manage_when_property_does_not_exist(self, capsys):
sheerka = self.get_sheerka()
foo = Obj("value a", "value b")
sheerka.printer_handler.register_format_d(TrueNode(), ["foo", "bar"])
sheerka.printer_handler.register_format_d(Obj, ["foo", "bar"])
sheerka.print(foo)
captured = capsys.readouterr()
assert captured.out == """Obj(a='value a', b='value b')
foo: *Undefined*
bar: *Undefined*
"""
def test_i_can_select_the_object_to_format_d(self, capsys):
sheerka = self.get_sheerka()
foo = [Obj("value a", "value b"), ObjLongProp("value c", "value d")]
sheerka.printer_handler.register_format_d(LambdaNode(lambda o: isinstance(o, Obj)), ["a", "b"])
sheerka.print(foo)
captured = capsys.readouterr()
assert captured.out == """Obj(a='value a', b='value b')
a: value a
b: value b
ObjLongProp(first_property_name='value c', second='value d')
foo: *name 'foo' is not defined*
bar: *name 'bar' is not defined*
"""
@pytest.mark.parametrize("template, expected", [
@@ -265,7 +437,6 @@ ObjLongProp(first_property_name='value c', second='value d')
("{b}\\+", "value b+\n"),
("+", "+\n"),
("\\+", "\\+\n"),
("+\\", "+\\\n"),
])
def test_i_can_concat_print_instruction_and_register_format(self, capsys, template, expected):
sheerka = self.get_sheerka()
@@ -277,3 +448,39 @@ ObjLongProp(first_property_name='value c', second='value d')
sheerka.print(foo, instructions)
captured = capsys.readouterr()
assert captured.out == expected
def test_i_can_manage_exception_when_printing(self, capsys):
sheerka = self.get_sheerka()
filter_service = SheerkaFilter(sheerka)
predicate = "self='two'" # it should be self=='two'
items = ["one", "two", "three"] | Pipe(filter_service.pipe_filter)(predicate)
sheerka.print(items)
captured = capsys.readouterr()
assert captured.out == "\x1b[31mSyntaxError: invalid syntax\nself='two'\n ^\x1b[0m\n"
@pytest.mark.parametrize("template, expected", [
(None, []),
("", []),
("foo", []),
("{foo}", [BraceToken(0, 4, -1)]),
("xxx{foo}yyy", [BraceToken(3, 7, -1)]),
("{foo}{bar}-{baz}", [BraceToken(0, 4, -1), BraceToken(5, 9, -1), BraceToken(11, 15, -1)]),
("xxx{{foo}}yyy", []),
("xxx{{foo}yyy", []),
("xxx{yyy", []),
("xxx{", []),
])
def test_i_can_get_braces(self, template, expected):
assert list(Formatter.braces(template)) == expected
@pytest.mark.parametrize("template, expected", [
(None, None),
("", ""),
("foo", "foo"),
("{foo}", "{format_obj(foo, 0)}"),
("{foo : >16}", "{format_obj(foo , 0): >16}"),
("{foo : >16}{bar}xxx{baz}", "{format_obj(foo , 0): >16}{format_obj(bar, 0)}xxx{format_obj(baz, 0)}"),
])
def test_i_can_inject_format_obj(self, template, expected):
assert Formatter.inject_format_obj(template, 0) == expected