First version of explain. Creating a new parser was a wrong approach. Need to reimplement
This commit is contained in:
@@ -31,7 +31,7 @@ class TestSheerkaHistoryManager(TestUsingMemoryBasedSheerka):
|
||||
hist("xxx", False),
|
||||
hist("one", True),
|
||||
hist("def concept one as 1", True),
|
||||
hist("Initializing Sheerka.", True)]
|
||||
hist("Initializing Sheerka.", None)]
|
||||
|
||||
h = list(sheerka.history(2))
|
||||
assert h == [
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
from core.concept import Concept, ConceptParts
|
||||
from core.sheerka.Services.SheerkaVariableManager import SheerkaVariableManager
|
||||
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
class TestSheerkaVariable(TestUsingMemoryBasedSheerka):
|
||||
def test_i_can_record_and_load_a_constant(self):
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
|
||||
sheerka.record(context, "TestSheerkaVariable", "my_variable", 1)
|
||||
res = sheerka.load("TestSheerkaVariable", "my_variable")
|
||||
assert res == 1
|
||||
|
||||
assert sheerka.sdp.exists(SheerkaVariableManager.VARIABLES_ENTRY, "TestSheerkaVariable.my_variable")
|
||||
loaded = sheerka.sdp.get(SheerkaVariableManager.VARIABLES_ENTRY, "TestSheerkaVariable.my_variable")
|
||||
assert loaded.event_id == context.event.get_digest()
|
||||
assert loaded.key == "my_variable"
|
||||
assert loaded.value == 1
|
||||
assert loaded.who == "TestSheerkaVariable"
|
||||
assert loaded.parents is None
|
||||
|
||||
def test_i_can_record_and_load_a_concept(self):
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
|
||||
concept = Concept("foo").set_prop("a", "alpha").set_metadata_value(ConceptParts.BODY, 3.14)
|
||||
|
||||
sheerka.record(context, "TestSheerkaVariable", "my_variable", concept)
|
||||
res = sheerka.load("TestSheerkaVariable", "my_variable")
|
||||
|
||||
assert res == concept
|
||||
assert res.body == concept.body
|
||||
|
||||
def test_i_can_get_the_parent_when_modified(self):
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
|
||||
sheerka.record(context, "TestSheerkaVariable", "my_variable", 1)
|
||||
sheerka.record(context, "TestSheerkaVariable", "my_variable", 2)
|
||||
res = sheerka.load("TestSheerkaVariable", "my_variable")
|
||||
assert res == 2
|
||||
|
||||
loaded = sheerka.sdp.get(SheerkaVariableManager.VARIABLES_ENTRY, "TestSheerkaVariable.my_variable")
|
||||
assert loaded.event_id == context.event.get_digest()
|
||||
assert loaded.key == "my_variable"
|
||||
assert loaded.value == 2
|
||||
assert loaded.who == "TestSheerkaVariable"
|
||||
assert loaded.parents == ['8c9ada7bf488d84229f6539f76042431638f16d600fe3b7ec7e7161043a40d59']
|
||||
|
||||
parent = sheerka.sdp.load_obj(loaded.parents[0])
|
||||
assert parent.event_id == context.event.get_digest()
|
||||
assert parent.key == "my_variable"
|
||||
assert parent.value == 1
|
||||
assert parent.who == "TestSheerkaVariable"
|
||||
assert parent.parents is None
|
||||
|
||||
def test_variable_is_not_persisted_if_the_value_is_the_same(self):
|
||||
sheerka = self.get_sheerka()
|
||||
context = self.get_context(sheerka)
|
||||
|
||||
sheerka.record(context, "TestSheerkaVariable", "my_variable", 1)
|
||||
sheerka.record(context, "TestSheerkaVariable", "my_variable", 1)
|
||||
|
||||
loaded = sheerka.sdp.get(SheerkaVariableManager.VARIABLES_ENTRY, "TestSheerkaVariable.my_variable")
|
||||
assert loaded.event_id == context.event.get_digest()
|
||||
assert loaded.key == "my_variable"
|
||||
assert loaded.value == 1
|
||||
assert loaded.who == "TestSheerkaVariable"
|
||||
assert loaded.parents is None
|
||||
@@ -0,0 +1,278 @@
|
||||
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 printer.SheerkaPrinter import FormatInstructions
|
||||
|
||||
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
|
||||
|
||||
|
||||
@dataclass
|
||||
class Obj:
|
||||
a: object
|
||||
b: object
|
||||
|
||||
|
||||
@dataclass()
|
||||
class ObjLongProp:
|
||||
first_property_name: object
|
||||
second: object
|
||||
|
||||
|
||||
class TestSheerkaPrinter(TestUsingMemoryBasedSheerka):
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
("Hello world!", "Hello world!\n"),
|
||||
("%black%%red%%green%%yellow%%reset%", "\x1b[30m\x1b[31m\x1b[32m\x1b[33m\x1b[0m\n"),
|
||||
("%blue%%magenta%%cyan%%white%%reset%", "\x1b[34m\x1b[35m\x1b[36m\x1b[37m\x1b[0m\n"),
|
||||
(["Hello", "world!"], "Hello\nworld!\n"),
|
||||
(("Hello", "world!"), "Hello\nworld!\n"),
|
||||
])
|
||||
def test_i_can_print(self, capsys, text, expected):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka.print(text)
|
||||
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == expected
|
||||
|
||||
def test_i_can_disable_color(self, capsys):
|
||||
sheerka = self.get_sheerka()
|
||||
sheerka.print("%red%Hello world !%reset%", FormatInstructions(no_color=True))
|
||||
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == "Hello world !\n"
|
||||
|
||||
def test_i_can_print_concept(self, capsys):
|
||||
sheerka = self.get_sheerka()
|
||||
foo = Concept("foo a b").def_prop("a").def_prop("b")
|
||||
sheerka.print(foo)
|
||||
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == str(foo) + "\n"
|
||||
|
||||
def test_i_can_use_custom_format(self, capsys):
|
||||
sheerka = self.get_sheerka()
|
||||
foo = Concept("foo a b").def_prop("a").def_prop("b").init_key()
|
||||
sheerka.printer_handler.register_custom_printer(
|
||||
foo,
|
||||
lambda printer, instr, item: printer.fp(instr, f"foo a={item.a}, b={item.b}"))
|
||||
foo.set_prop("a", "value a").set_prop("b", "value b")
|
||||
sheerka.print(foo)
|
||||
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == "foo a=value a, b=value b\n"
|
||||
|
||||
def test_i_can_print_and_recurse(self, capsys):
|
||||
sheerka = self.get_sheerka()
|
||||
level3 = Concept("level3")
|
||||
level2 = Concept("level2").set_metadata_value(ConceptParts.BODY, level3)
|
||||
level1 = Concept("level1").set_metadata_value(ConceptParts.BODY, level2)
|
||||
|
||||
sheerka.print(level1)
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == f"{level1}\n"
|
||||
|
||||
sheerka.print(level1, FormatInstructions().set_recurse("body", 1))
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == f"{level1}\n {level2}\n"
|
||||
|
||||
sheerka.print(level1, FormatInstructions().set_recurse("body", 2))
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == f"{level1}\n {level2}\n {level3}\n"
|
||||
|
||||
sheerka.print(level1, FormatInstructions().set_recurse("body", 10))
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == f"{level1}\n {level2}\n {level3}\n"
|
||||
|
||||
def test_i_can_print_and_recurse_list(self, capsys):
|
||||
sheerka = self.get_sheerka()
|
||||
level31 = Concept("level31")
|
||||
level32 = Concept("level32")
|
||||
level33 = Concept("level33")
|
||||
level21 = Concept("level21").set_metadata_value(ConceptParts.BODY, [level31, level32])
|
||||
level22 = Concept("level22").set_metadata_value(ConceptParts.BODY, [level33])
|
||||
level1 = Concept("level1").set_metadata_value(ConceptParts.BODY, [level21, level22])
|
||||
|
||||
sheerka.print(level1)
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == f"{level1}\n"
|
||||
|
||||
sheerka.print(level1, FormatInstructions().set_recurse("body", 1))
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == f"{level1}\n {level21}\n {level22}\n"
|
||||
|
||||
sheerka.print(level1, FormatInstructions().set_recurse("body", 3))
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == f"{level1}\n {level21}\n {level31}\n {level32}\n {level22}\n {level33}\n"
|
||||
|
||||
def test_explanation_concept_can_control_recursion(self, capsys):
|
||||
sheerka = self.get_sheerka()
|
||||
level31 = Concept("level31")
|
||||
level32 = Concept("level32")
|
||||
level33 = Concept("level33")
|
||||
level21 = Concept("level21").set_metadata_value(ConceptParts.BODY, [level31, level32])
|
||||
level22 = Concept("level22").set_metadata_value(ConceptParts.BODY, [level33])
|
||||
level1 = Concept("level1").set_metadata_value(ConceptParts.BODY, [level21, level22])
|
||||
|
||||
instructions = FormatInstructions(no_color=True)
|
||||
explanation = sheerka.new(
|
||||
BuiltinConcepts.EXPLANATION,
|
||||
digest="digest",
|
||||
command="command",
|
||||
title="title",
|
||||
instructions=instructions,
|
||||
body=[level1])
|
||||
|
||||
sheerka.print(explanation)
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == f"digest : command\n(None)level1\n"
|
||||
|
||||
instructions = FormatInstructions(no_color=True).set_recurse("body", 2)
|
||||
explanation = sheerka.new(
|
||||
BuiltinConcepts.EXPLANATION,
|
||||
digest="digest",
|
||||
command="command",
|
||||
title="title",
|
||||
instructions=instructions,
|
||||
body=[level1])
|
||||
|
||||
sheerka.print(explanation)
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == """digest : command
|
||||
(None)level1
|
||||
(None)level21
|
||||
(None)level31
|
||||
(None)level32
|
||||
(None)level22
|
||||
(None)level33
|
||||
"""
|
||||
|
||||
def test_i_can_format_concept(self, capsys):
|
||||
sheerka = self.get_sheerka()
|
||||
foo = Concept("foo a b").def_prop("a").def_prop("b").init_key()
|
||||
foo.set_prop("a", "value a").set_prop("b", "value b")
|
||||
foo.set_metadata_value(ConceptParts.BODY, "body")
|
||||
sheerka.set_id_if_needed(foo, False)
|
||||
|
||||
sheerka.printer_handler.register_format_l(foo, "{id}-{name}-{key}-{body}-{a}-{b}")
|
||||
|
||||
sheerka.print(foo)
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == "1001-foo a b-foo __var__0 __var__1-body-value a-value b\n"
|
||||
|
||||
def test_i_can_format_object(self, capsys):
|
||||
sheerka = self.get_sheerka()
|
||||
foo = Obj("value a", "value b")
|
||||
|
||||
sheerka.printer_handler.register_format_l(foo, "{a}-{b}")
|
||||
|
||||
sheerka.print(foo)
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == "value a-value b\n"
|
||||
|
||||
def test_i_can_register_a_custom_format_by_its_name(self, capsys):
|
||||
sheerka = self.get_sheerka()
|
||||
foo = Obj("value a", "value b")
|
||||
|
||||
sheerka.printer_handler.register_format_l("tests.core.test_sheerka_printer.Obj", "{a}-{b}")
|
||||
|
||||
sheerka.print(foo)
|
||||
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")
|
||||
|
||||
instructions = FormatInstructions().set_format_l("tests.core.test_sheerka_printer.Obj", "{a}-{b}")
|
||||
|
||||
sheerka.print(foo, instructions)
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == "value a-value b\n"
|
||||
|
||||
def test_format_print_instruction_override_register_format(self, capsys):
|
||||
sheerka = self.get_sheerka()
|
||||
foo = Obj("value a", "value b")
|
||||
|
||||
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)
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == "a=value a <> b=value b\n"
|
||||
|
||||
def test_i_can_format_d(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.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.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
|
||||
ObjLongProp(first_property_name='value c', second='value d')
|
||||
first_property_name: value c
|
||||
second : value d
|
||||
"""
|
||||
|
||||
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.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')
|
||||
"""
|
||||
|
||||
@pytest.mark.parametrize("template, expected", [
|
||||
("+-{b}", "value a-value b\n"),
|
||||
("{b}-+", "value b-value a\n"),
|
||||
("\\+{b}", "+value b\n"),
|
||||
("{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()
|
||||
foo = Obj("value a", "value b")
|
||||
|
||||
sheerka.printer_handler.register_format_l("tests.core.test_sheerka_printer.Obj", "{a}")
|
||||
instructions = FormatInstructions().set_format_l("tests.core.test_sheerka_printer.Obj", template)
|
||||
|
||||
sheerka.print(foo, instructions)
|
||||
captured = capsys.readouterr()
|
||||
assert captured.out == expected
|
||||
@@ -4,7 +4,7 @@ from core.tokenizer import Tokenizer, Token, TokenKind, LexerError, Keywords
|
||||
|
||||
def test_i_can_tokenize():
|
||||
source = "+*-/{}[]() ,;:.?\n\n\r\r\r\nidentifier_0\t \t10.15 10 'string\n' \"another string\"=|&<>c:name:"
|
||||
source += "$£€!_identifier°~_^\\`#"
|
||||
source += "$£€!_identifier°~_^\\`==#"
|
||||
tokens = list(Tokenizer(source))
|
||||
assert tokens[0] == Token(TokenKind.PLUS, "+", 0, 1, 1)
|
||||
assert tokens[1] == Token(TokenKind.STAR, "*", 1, 1, 2)
|
||||
@@ -52,9 +52,10 @@ def test_i_can_tokenize():
|
||||
assert tokens[43] == Token(TokenKind.CARAT, '^', 106, 6, 48)
|
||||
assert tokens[44] == Token(TokenKind.BACK_SLASH, '\\', 107, 6, 49)
|
||||
assert tokens[45] == Token(TokenKind.BACK_QUOTE, '`', 108, 6, 50)
|
||||
assert tokens[46] == Token(TokenKind.HASH, '#', 109, 6, 51)
|
||||
assert tokens[46] == Token(TokenKind.EQUALSEQUALS, '==', 109, 6, 51)
|
||||
assert tokens[47] == Token(TokenKind.HASH, '#', 111, 6, 53)
|
||||
|
||||
assert tokens[47] == Token(TokenKind.EOF, '', 110, 6, 52)
|
||||
assert tokens[48] == Token(TokenKind.EOF, '', 112, 6, 54)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("text, expected", [
|
||||
@@ -74,6 +75,19 @@ def test_i_can_tokenize_identifiers(text, expected):
|
||||
assert comparison == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize("text", [
|
||||
"123abc",
|
||||
"123",
|
||||
"abc",
|
||||
"abc123"
|
||||
])
|
||||
def test_i_can_parse_word(text):
|
||||
tokens = list(Tokenizer(text, parse_word=True))
|
||||
assert tokens[0].type == TokenKind.WORD
|
||||
assert tokens[0].value == text
|
||||
assert tokens[1].index == len(text)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("text, message, error_text, index, line, column", [
|
||||
("'string", "Missing Trailing quote", "'string", 7, 1, 8),
|
||||
('"string', "Missing Trailing quote", '"string', 7, 1, 8),
|
||||
|
||||
Reference in New Issue
Block a user