Fixed error when desc() returns multiple results

This commit is contained in:
2020-12-04 17:37:06 +01:00
parent 8b86998225
commit d364878ddb
16 changed files with 408 additions and 19 deletions
+11
View File
@@ -25,3 +25,14 @@ def concept x has a y as hasa(x,y) pre is_question()
# no need to auto eval as it's a question # no need to auto eval as it's a question
def concept x has an y as hasa(x,y) pre is_question() def concept x has an y as hasa(x,y) pre is_question()
# no need to auto eval as it's a question # no need to auto eval as it's a question
# default
def concept male
def concept female
def concept man
man is a male
def concept woman
woman is a female
def concept human
man is a human
woman is a human
+8
View File
@@ -106,6 +106,7 @@ class BuiltinConcepts:
# formatting # formatting
TO_LIST = "__TO_LIST" TO_LIST = "__TO_LIST"
TO_DICT = "__TO_DICT" TO_DICT = "__TO_DICT"
TO_MULTI = "__TO_MULTI" # used when there are multiple output to display
AllBuiltinConcepts = [v for n, v in BuiltinConcepts.__dict__.items() if not n.startswith("__")] AllBuiltinConcepts = [v for n, v in BuiltinConcepts.__dict__.items() if not n.startswith("__")]
@@ -178,6 +179,13 @@ BuiltinContainers = [
BuiltinConcepts.EXPLANATION, BuiltinConcepts.EXPLANATION,
BuiltinConcepts.TO_LIST, BuiltinConcepts.TO_LIST,
BuiltinConcepts.TO_DICT, BuiltinConcepts.TO_DICT,
BuiltinConcepts.TO_MULTI,
]
BuiltinOutConcepts = [
BuiltinConcepts.TO_LIST,
BuiltinConcepts.TO_DICT,
BuiltinConcepts.TO_MULTI,
] ]
""" """
+13
View File
@@ -916,6 +916,19 @@ class Sheerka(Concept):
return a.key == b_key return a.key == b_key
@staticmethod
def isin(a, b):
"""
True if the concept is the list
:param a:
:param b:
:return:
"""
if not isinstance(a, Concept):
return False
return a.key in b
@staticmethod @staticmethod
def get_unknown(metadata): def get_unknown(metadata):
""" """
@@ -8,6 +8,7 @@ from core.sheerka.ExecutionContext import ExecutionContext
from core.sheerka.services.sheerka_service import BaseService from core.sheerka.services.sheerka_service import BaseService
from core.utils import CONSOLE_COLORS_MAP as CCM, CONSOLE_COLUMNS, PRIMITIVES_TYPES from core.utils import CONSOLE_COLORS_MAP as CCM, CONSOLE_COLUMNS, PRIMITIVES_TYPES
from core.utils import evaluate_expression, as_bag from core.utils import evaluate_expression, as_bag
from parsers.BaseNodeParser import SourceCodeWithConceptNode, UnrecognizedTokensNode
pp = pprint.PrettyPrinter(indent=2, width=CONSOLE_COLUMNS) pp = pprint.PrettyPrinter(indent=2, width=CONSOLE_COLUMNS)
@@ -15,7 +16,7 @@ NotFound = "** Not Found **"
class ConceptDebugObj: class ConceptDebugObj:
def __init__(self, concept): def __init__(self, concept, **kwargs):
self.concept = concept self.concept = concept
self.attrs = concept.as_debug_bag(lambda x: ConceptDebugObj(x), True) self.attrs = concept.as_debug_bag(lambda x: ConceptDebugObj(x), True)
@@ -46,12 +47,37 @@ class ConceptDebugObj:
class ConceptNodeDebugObj: class ConceptNodeDebugObj:
def __init__(self, concept_node): def __init__(self, concept_node, **kwargs):
self.concept_node = concept_node self.concept_node = concept_node
self.concept_debug = ConceptDebugObj(concept_node.concept) self.concept_debug = ConceptDebugObj(concept_node.concept)
def __repr__(self): def __repr__(self):
return f"ConceptNode({self.concept_debug.concept_repr()})" return f"ConceptNodeDbg({self.concept_debug.concept_repr()})"
class SourceCodeWithConceptNodeDebugObj:
def __init__(self, source_code_node, **kwargs):
self.source_code_node = source_code_node
def __repr__(self):
debug_repr = SheerkaDebugManager.get_debug_repr
res = f"SourceCodeNodeDbg('{debug_repr(self.source_code_node.first, inside_source_code=True)}' "
first = True
for node in self.source_code_node.nodes:
res += (", " if not first else "") + str(debug_repr(node))
first = False
return res + f" '{debug_repr(self.source_code_node.last, inside_source_code=True)}')"
class UnrecognizedTokensNodeDebugOjb:
def __init__(self, unrec_node, **kwargs):
self.unrec_node = unrec_node
self.inside_source_code = kwargs.get("inside_source_code", False)
def __repr__(self):
if self.inside_source_code:
return self.unrec_node.source
return f"UnrecNodeDbg('{self.unrec_node.source}')"
class BaseDebugLogger: class BaseDebugLogger:
@@ -678,16 +704,21 @@ class SheerkaDebugManager(BaseService):
return self.get_inner_values(obj.body, **kwargs) return self.get_inner_values(obj.body, **kwargs)
def get_debug_repr(self, obj, **kwargs): @staticmethod
def get_debug_repr(obj, **kwargs):
if kwargs.get("as_bag", False): if kwargs.get("as_bag", False):
forced_props = self.get_concept_forced_props(obj) if isinstance(obj, Concept) else None forced_props = SheerkaDebugManager.get_concept_forced_props(obj) if isinstance(obj, Concept) else None
return self.as_debug_bag(obj, True, forced_props) return SheerkaDebugManager.as_debug_bag(obj, True, forced_props)
from parsers.BaseNodeParser import ConceptNode from parsers.BaseNodeParser import ConceptNode
if isinstance(obj, Concept): if isinstance(obj, Concept):
return ConceptDebugObj(obj) return ConceptDebugObj(obj, **kwargs)
elif isinstance(obj, ConceptNode): elif isinstance(obj, ConceptNode):
return ConceptNodeDebugObj(obj) return ConceptNodeDebugObj(obj, **kwargs)
elif isinstance(obj, SourceCodeWithConceptNode):
return SourceCodeWithConceptNodeDebugObj(obj, **kwargs)
elif isinstance(obj, UnrecognizedTokensNode):
return UnrecognizedTokensNodeDebugOjb(obj, **kwargs)
else: else:
return obj return obj
+1 -1
View File
@@ -16,7 +16,7 @@ class SheerkaOut(BaseService):
self.sheerka.bind_service_method(self.process_return_values, False) self.sheerka.bind_service_method(self.process_return_values, False)
def create_out_tree(self, context, obj): def create_out_tree(self, context, obj):
debugger = context.get_debugger("Out.visitor", "create_out_tree") debugger = context.get_debugger("Visitor", "create_out_tree")
return self.create_out_tree_recursive(context, {'__obj': obj}, DeveloperVisitor(self, debugger, set(), 0)) return self.create_out_tree_recursive(context, {'__obj': obj}, DeveloperVisitor(self, debugger, set(), 0))
def create_out_tree_recursive(self, context, bag, visitor): def create_out_tree_recursive(self, context, bag, visitor):
@@ -119,7 +119,9 @@ class FormatAstList(FormatAstNode):
def clone(self, **kwargs): def clone(self, **kwargs):
return super().clone( return super().clone(
FormatAstList(self.variable), FormatAstList(self.variable),
("items_prop", "recurse_on", "recursion_depth", "debug", "prefix", "suffix", "show_index", "index", "items"), (
"items_prop", "recurse_on", "recursion_depth", "debug", "prefix", "suffix", "show_index", "index",
"items"),
**kwargs) **kwargs)
@@ -177,6 +179,25 @@ class FormatAstSequence(FormatAstNode):
**kwargs) **kwargs)
@dataclass
class FormatAstMulti(FormatAstNode):
"""
Used when there are multiple out to print, but they are not related
Just print them one by one
"""
variable: str
items: list = None
def __repr__(self):
return f"FormatAstMulti({self.variable}, items={self.items})"
def clone(self, **kwargs):
return super().clone(
FormatAstMulti(self.variable),
("items",),
**kwargs)
class FormatRuleParser(IterParser): class FormatRuleParser(IterParser):
@staticmethod @staticmethod
@@ -318,6 +339,8 @@ class FormatRuleParser(IterParser):
return self.return_list(args, kwargs) return self.return_list(args, kwargs)
elif func_name.value == "dict": elif func_name.value == "dict":
return self.return_dict(args, kwargs) return self.return_dict(args, kwargs)
elif func_name.value == "multi":
return self.return_multi(args, kwargs)
return FormatAstFunction(func_name.value, self.to_text(args), self.to_text(kwargs)) return FormatAstFunction(func_name.value, self.to_text(args), self.to_text(kwargs))
@@ -461,6 +484,17 @@ class FormatRuleParser(IterParser):
return FormatAstDict(variable_name, **kwargs_parameters) return FormatAstDict(variable_name, **kwargs_parameters)
def return_multi(self, args, kwargs):
if len(kwargs) > 0:
self.error_sink = FormatRuleSyntaxError("keyword arguments are not supported", None)
return None
if len(args) > 1:
self.error_sink = FormatRuleSyntaxError("too many positional arguments", args[1][0])
return None
return FormatAstMulti(get_text_from_tokens(args[0]))
@dataclass() @dataclass()
class RulePredicate: class RulePredicate:
@@ -620,25 +654,43 @@ class SheerkaRuleManager(BaseService):
def init_builtin_rules(self, context): def init_builtin_rules(self, context):
# self.sheerka.init_log.debug("Initializing default rules") # self.sheerka.init_log.debug("Initializing default rules")
rules = [ rules = [
# [0] Rule #1 Rule #2 in debug
Rule("print", "Print return values", "__rets", "list(__rets)"), Rule("print", "Print return values", "__rets", "list(__rets)"),
# [1] Rule #2 in debug
Rule("print", "Print ReturnValue", Rule("print", "Print ReturnValue",
"__ret", "__ret",
"\\ReturnValue(who={__ret.who}, status={__ret.status}, value={__ret.value})"), "\\ReturnValue(who={__ret.who}, status={__ret.status}, value={__ret.value})"),
# [2] Rule #3 in debug
Rule("print", "Failed ReturnValue in red", Rule("print", "Failed ReturnValue in red",
"__ret and not __ret.status", "__ret and not __ret.status",
"red(__ret)"), "red(__ret)"),
# [3] Rule #4 in debug
Rule("print", "List explanations", Rule("print", "List explanations",
"isinstance(__ret_container, BuiltinConcepts.EXPLANATION)", "isinstance(__ret_container, BuiltinConcepts.EXPLANATION)",
"blue(__ret_container.digest) : {__ret_container.command}\nlist(__ret_container)"), "blue(__ret_container.digest) : {__ret_container.command}\nlist(__ret_container)"),
# [4] Rule #5 in debug
Rule("print", "Print ExecutionContext", Rule("print", "Print ExecutionContext",
"isinstance(__obj, ExecutionContext)", "isinstance(__obj, ExecutionContext)",
"[{id:3}] {__tab}{desc} ({status})"), "[{id:3}] {__tab}{desc} ({status})"),
# [6] Rule #7 in debug
Rule("print", "Display formatted list", Rule("print", "Display formatted list",
"isinstance(__ret_container, BuiltinConcepts.TO_LIST)", "isinstance(__ret_container, BuiltinConcepts.TO_LIST)",
"list(__ret_container)"), "list(__ret_container)"),
# [7] Rule #8 in debug
Rule("print", "Display formatted dict", Rule("print", "Display formatted dict",
"isinstance(__ret_container, BuiltinConcepts.TO_DICT)", "isinstance(__ret_container, BuiltinConcepts.TO_DICT)",
"dict(__ret_container)"), "dict(__ret_container)"),
# [8] Rule #9 in debug
Rule("print", "Display multiple outputs",
"isinstance(__ret_container, BuiltinConcepts.TO_MULTI)",
"multi(__ret_container)"),
] ]
for r in rules: for r in rules:
@@ -648,6 +700,10 @@ class SheerkaRuleManager(BaseService):
self.sheerka.set_is_less_than(context, BuiltinConcepts.PRECEDENCE, rules[1], rules[3], RULE_COMPARISON_CONTEXT) self.sheerka.set_is_less_than(context, BuiltinConcepts.PRECEDENCE, rules[1], rules[3], RULE_COMPARISON_CONTEXT)
self.sheerka.set_is_less_than(context, BuiltinConcepts.PRECEDENCE, rules[1], rules[5], RULE_COMPARISON_CONTEXT) self.sheerka.set_is_less_than(context, BuiltinConcepts.PRECEDENCE, rules[1], rules[5], RULE_COMPARISON_CONTEXT)
self.sheerka.set_is_less_than(context, BuiltinConcepts.PRECEDENCE, rules[1], rules[6], RULE_COMPARISON_CONTEXT) self.sheerka.set_is_less_than(context, BuiltinConcepts.PRECEDENCE, rules[1], rules[6], RULE_COMPARISON_CONTEXT)
self.sheerka.set_is_greater_than(context, BuiltinConcepts.PRECEDENCE, rules[7], rules[6],
RULE_COMPARISON_CONTEXT)
self.sheerka.set_is_greater_than(context, BuiltinConcepts.PRECEDENCE, rules[7], rules[5],
RULE_COMPARISON_CONTEXT)
self.sheerka.set_is_greatest(context, BuiltinConcepts.PRECEDENCE, rules[0], RULE_COMPARISON_CONTEXT) self.sheerka.set_is_greatest(context, BuiltinConcepts.PRECEDENCE, rules[0], RULE_COMPARISON_CONTEXT)
def get_rule_by_id(self, rule_id): def get_rule_by_id(self, rule_id):
+44
View File
@@ -0,0 +1,44 @@
from core.builtin_concepts import BuiltinConcepts, BuiltinOutConcepts
from evaluators.BaseEvaluator import AllReturnValuesEvaluator
from parsers.BaseParser import BaseParser
class MultipleOutEvaluator(AllReturnValuesEvaluator):
"""
Used to filter the responses
when too many success but these success are different output to print
"""
NAME = "MultipleOut"
def __init__(self):
super().__init__(self.NAME, [BuiltinConcepts.AFTER_EVALUATION], 61)
self.success = []
def reset(self):
super().reset()
self.success.clear()
def matches(self, context, return_values):
to_process = False
for ret in return_values:
if ret.status and ret.who.startswith(BaseParser.PREFIX):
return False
elif ret.status and context.sheerka.isinstance(ret.body, BuiltinConcepts.REDUCE_REQUESTED):
to_process = True
self.eaten.append(ret)
elif ret.status and ret.who.startswith(self.PREFIX):
if context.sheerka.isin(ret.body, BuiltinOutConcepts):
self.success.append(ret)
self.eaten.append(ret)
else:
return False
elif not ret.status:
self.eaten.append(ret)
return to_process and len(self.success) > 1
def eval(self, context, return_values):
to_multi = context.sheerka.new(BuiltinConcepts.TO_MULTI, body=[r.body for r in self.success])
return context.sheerka.ret(self.name, True, to_multi, parents=self.eaten)
+3
View File
@@ -100,6 +100,9 @@ class AsStrVisitor(OutVisitor):
result += format_ast.suffix result += format_ast.suffix
return result return result
def visit_FormatAstMulti(self, format_ast):
return "\n".join(self.visit(item) for item in format_ast.items)
@staticmethod @staticmethod
def debug_activated(node): def debug_activated(node):
return isinstance(node, FormatAstNode) and hasattr(node, "debug") and node.debug return isinstance(node, FormatAstNode) and hasattr(node, "debug") and node.debug
+3
View File
@@ -51,3 +51,6 @@ class ConsoleVisitor(AsStrVisitor):
visitor = AsStrVisitor(expand, width=self.console_width) visitor = AsStrVisitor(expand, width=self.console_width)
res = visitor.visit_FormatAstDict(format_ast) res = visitor.visit_FormatAstDict(format_ast)
self.out(res) self.out(res)
def visit_FormatAstMulti(self, format_ast):
self.out(super().visit_FormatAstMulti(format_ast))
+24
View File
@@ -26,6 +26,8 @@ class DeveloperVisitor:
return visit_method(context, format_ast, bag) return visit_method(context, format_ast, bag)
def generic_visit(self, context, format_ast, bag): def generic_visit(self, context, format_ast, bag):
name = format_ast.__class__.__name__
self.debugger.debug_log(f"method '{name}' is not implemented", is_error=True)
pass pass
def visit_FormatAstRawText(self, context, format_ast, bag): def visit_FormatAstRawText(self, context, format_ast, bag):
@@ -191,6 +193,28 @@ class DeveloperVisitor:
format_ast.variable + "." + error.args[0] format_ast.variable + "." + error.args[0]
return FormatAstVariableNotFound(var_name) return FormatAstVariableNotFound(var_name)
def visit_FormatAstMulti(self, context, format_ast, bag):
if self.debugger.is_enabled():
debug_bag = {"format_ast": format_ast, "bag": bag}
self.debugger.debug_log(f"Entering visit_FormatAstMulti with {debug_bag}")
try:
value = evaluate_expression(format_ast.variable, bag)
res = []
for item in value.body:
sub_bag = {"__obj": item, format_ast.variable: item}
visitor = DeveloperVisitor(self.sheerka_out, self.debugger, set(), self.list_recursion_depth)
res.append(self.sheerka_out.create_out_tree_recursive(context, sub_bag, visitor))
format_ast.items = res
return format_ast
except NameError as error:
self.debugger.debug_log(error, is_error=True)
var_name = format_ast.variable if error.args[0] == format_ast.variable else \
format_ast.variable + "." + error.args[0]
return FormatAstVariableNotFound(var_name)
@staticmethod @staticmethod
def get_recurse_info(obj, recursion_depth, recurse_on): def get_recurse_info(obj, recursion_depth, recurse_on):
depth, on = 0, None depth, on = 0, None
+3 -2
View File
@@ -7,7 +7,7 @@ from core.global_symbols import RULE_COMPARISON_CONTEXT
from core.rule import Rule from core.rule import Rule
from core.sheerka.services.SheerkaRuleManager import SheerkaRuleManager, FormatRuleParser, \ from core.sheerka.services.SheerkaRuleManager import SheerkaRuleManager, FormatRuleParser, \
FormatAstRawText, FormatAstVariable, FormatAstSequence, FormatAstFunction, \ FormatAstRawText, FormatAstVariable, FormatAstSequence, FormatAstFunction, \
FormatRuleSyntaxError, FormatAstList, UnexpectedEof, FormatAstColor, RulePredicate, FormatAstDict FormatRuleSyntaxError, FormatAstList, UnexpectedEof, FormatAstColor, RulePredicate, FormatAstDict, FormatAstMulti
from core.tokenizer import Token, TokenKind from core.tokenizer import Token, TokenKind
from parsers.BaseNodeParser import SourceCodeWithConceptNode, SourceCodeNode from parsers.BaseNodeParser import SourceCodeWithConceptNode, SourceCodeNode
from parsers.PythonParser import PythonNode from parsers.PythonParser import PythonNode
@@ -114,7 +114,8 @@ class TestSheerkaRuleManager(TestUsingMemoryBasedSheerka):
(r"\not_a_function(a={var})", seq([raw("not_a_function(a="), var("var"), raw(")")])), (r"\not_a_function(a={var})", seq([raw("not_a_function(a="), var("var"), raw(")")])),
("dict(var_name)", FormatAstDict("var_name")), ("dict(var_name)", FormatAstDict("var_name")),
("dict(var_name, items_prop='props')", FormatAstDict("var_name", items_prop='props')), ("dict(var_name, items_prop='props')", FormatAstDict("var_name", items_prop='props')),
("dict(var_name, debug=True)", FormatAstDict("var_name", debug=True, prefix="{", suffix="}")) ("dict(var_name, debug=True)", FormatAstDict("var_name", debug=True, prefix="{", suffix="}")),
("multi(var_name)", FormatAstMulti("var_name")),
]) ])
def test_i_can_parse_format_rule(self, text, expected): def test_i_can_parse_format_rule(self, text, expected):
assert FormatRuleParser(text).parse() == expected assert FormatRuleParser(text).parse() == expected
+50
View File
@@ -0,0 +1,50 @@
from core.builtin_concepts import ReturnValueConcept, BuiltinConcepts
from core.concept import Concept
from evaluators.BaseEvaluator import BaseEvaluator
from parsers.BaseParser import BaseParser
reduced_requested = ReturnValueConcept("Sheerka", True, Concept(name=BuiltinConcepts.REDUCE_REQUESTED,
key=BuiltinConcepts.REDUCE_REQUESTED))
def ret_val(value="value", who="who", status=True):
return ReturnValueConcept(who, status, value)
def p_ret_val(value="value", parser="parser", status=True):
return ReturnValueConcept(BaseParser.PREFIX + parser, status, value)
def e_ret_val(value="value", evaluator="evaluator", status=True):
return ReturnValueConcept(BaseEvaluator.PREFIX + evaluator, status, value)
def p_ret_val_false(value="value", parser="parser"):
return p_ret_val(value, parser, status=False)
def p_ret_val_true(value="value", parser="parser"):
return p_ret_val(value, parser, status=True)
def e_ret_val_false(value="value", parser="parser"):
return e_ret_val(value, parser, status=False)
def e_ret_val_true(value="value", parser="parser"):
return e_ret_val(value, parser, status=True)
def e_ret_val_new(key, evaluator="evaluator", status=True, **kwargs):
body = new_concept(key, **kwargs)
return e_ret_val(body, evaluator, status)
def new_concept(key, **kwargs):
res = Concept(key=key, name=key, is_builtin=False, is_unique=False)
for k, v in kwargs.items():
to_use = "#" + k + "#" if k in ("body", "pre", "post", "ret") else k
res.set_value(to_use, v)
res.get_metadata().is_evaluated = True
return res
@@ -0,0 +1,55 @@
import pytest
from core.builtin_concepts import BuiltinConcepts
from evaluators.MultipleOutEvaluator import MultipleOutEvaluator
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
from tests.evaluators.EvaluatorTestsUtils import reduced_requested, e_ret_val_new, p_ret_val_false, p_ret_val_true, \
e_ret_val_false, e_ret_val
class TestMultipleOutEvaluator(TestUsingMemoryBasedSheerka):
@pytest.mark.parametrize("return_values, expected", [
([reduced_requested,
e_ret_val_new(BuiltinConcepts.TO_DICT, body={}),
e_ret_val_new(BuiltinConcepts.TO_DICT, body={}),
p_ret_val_false("value"),
e_ret_val_false()], True),
# only one to_dict
([reduced_requested, e_ret_val_new(BuiltinConcepts.TO_DICT, body={})], False),
# reduce request missing
([e_ret_val_new(BuiltinConcepts.TO_DICT, body={}), e_ret_val_new(BuiltinConcepts.TO_DICT, body={})], False),
# parser result not evaluated
([reduced_requested,
e_ret_val_new(BuiltinConcepts.TO_DICT, body={}),
e_ret_val_new(BuiltinConcepts.TO_DICT, body={}),
p_ret_val_true("value")], False),
])
def test_i_can_match(self, return_values, expected):
sheerka, context = self.init_concepts()
evaluator = MultipleOutEvaluator()
assert evaluator.matches(context, return_values) == expected
def test_i_can_eval(self):
sheerka, context = self.init_concepts()
evaluator = MultipleOutEvaluator()
first_out = sheerka.new(BuiltinConcepts.TO_DICT, body={"a": 1})
second_out = sheerka.new(BuiltinConcepts.TO_DICT, body={"b": 1})
return_values = [reduced_requested,
e_ret_val(first_out),
e_ret_val(second_out),
p_ret_val_false("value"),
e_ret_val_false()]
evaluator.matches(context, return_values)
res = evaluator.eval(context, return_values)
assert sheerka.isinstance(res, BuiltinConcepts.RETURN_VALUE)
assert res.body == sheerka.new(BuiltinConcepts.TO_MULTI, body=[first_out, second_out])
assert res.parents == return_values
+38
View File
@@ -14,3 +14,41 @@ class TestSheerkaNonRegDisplay(TestUsingMemoryBasedSheerka):
captured = capsys.readouterr() captured = capsys.readouterr()
assert captured.out == "ReturnValue(who=evaluators.OneSuccess, status=True, value=(1001)one)\n" assert captured.out == "ReturnValue(who=evaluators.OneSuccess, status=True, value=(1001)one)\n"
def test_i_can_display_multiple_concepts_description(self, capsys):
init = [
"def concept foo as 1",
"def concept foo as 2",
]
sheerka = self.init_scenario(init)
capsys.readouterr()
sheerka.enable_process_return_values = True
sheerka.evaluate_user_input("desc(foo)")
captured = capsys.readouterr()
assert captured.out == """id : 1001
name : foo
key : foo
definition: None
type : None
body : 1
where : None
pre : None
post : None
ret : None
vars : []
props : {}
id : 1002
name : foo
key : foo
definition: None
type : None
body : 2
where : None
pre : None
post : None
ret : None
vars : []
props : {}
"""
+13
View File
@@ -1183,6 +1183,19 @@ as:
assert sheerka.get_attr(res[0].body, sheerka.new("size")) == sheerka.new("little") assert sheerka.get_attr(res[0].body, sheerka.new("size")) == sheerka.new("little")
assert sheerka.get_attr(res[0].body, sheerka.new("adjective")) == sheerka.new("beautiful") assert sheerka.get_attr(res[0].body, sheerka.new("adjective")) == sheerka.new("beautiful")
def test_i_can_display_multiple_concepts_using_desc_command(self):
init = [
"def concept foo as 1",
"def concept foo as 2",
]
sheerka = self.init_scenario(init)
res = sheerka.evaluate_user_input("desc(foo)")
assert len(res) == 1
assert res[0].status
assert sheerka.isinstance(res[0].body, BuiltinConcepts.TO_MULTI)
class TestSheerkaNonRegFile(TestUsingFileBasedSheerka): class TestSheerkaNonRegFile(TestUsingFileBasedSheerka):
def test_i_can_def_several_concepts(self): def test_i_can_def_several_concepts(self):
+46 -7
View File
@@ -1,6 +1,7 @@
from core.builtin_concepts import BuiltinConcepts
from core.sheerka.services.SheerkaDebugManager import NullDebugLogger from core.sheerka.services.SheerkaDebugManager import NullDebugLogger
from core.sheerka.services.SheerkaOut import SheerkaOut from core.sheerka.services.SheerkaOut import SheerkaOut
from core.sheerka.services.SheerkaRuleManager import FormatAstList, FormatAstVariable from core.sheerka.services.SheerkaRuleManager import FormatAstList, FormatAstVariable, FormatAstDict, FormatAstMulti
from out.DeveloperVisitor import DeveloperVisitor from out.DeveloperVisitor import DeveloperVisitor
from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka from tests.TestUsingMemoryBasedSheerka import TestUsingMemoryBasedSheerka
@@ -12,10 +13,10 @@ class TestDeveloperVisitor(TestUsingMemoryBasedSheerka):
service_out = sheerka.services[SheerkaOut.NAME] service_out = sheerka.services[SheerkaOut.NAME]
dev_visitor = DeveloperVisitor(service_out, NullDebugLogger(), set(), 0) dev_visitor = DeveloperVisitor(service_out, NullDebugLogger(), set(), 0)
bag = {"a": ["a", "b", "c"]} bag = {"to_format": ["a", "b", "c"]}
res = dev_visitor.visit(context, FormatAstList("a"), bag) res = dev_visitor.visit(context, FormatAstList("to_format"), bag)
assert res == FormatAstList(variable="a", items=[ assert res == FormatAstList(variable="to_format", items=[
FormatAstVariable(name="__item", index=0, value="a"), FormatAstVariable(name="__item", index=0, value="a"),
FormatAstVariable(name="__item", index=1, value="b"), FormatAstVariable(name="__item", index=1, value="b"),
FormatAstVariable(name="__item", index=2, value="c"), FormatAstVariable(name="__item", index=2, value="c"),
@@ -26,10 +27,10 @@ class TestDeveloperVisitor(TestUsingMemoryBasedSheerka):
service_out = sheerka.services[SheerkaOut.NAME] service_out = sheerka.services[SheerkaOut.NAME]
dev_visitor = DeveloperVisitor(service_out, NullDebugLogger(), set(), 0) dev_visitor = DeveloperVisitor(service_out, NullDebugLogger(), set(), 0)
bag = {"a": [["a1", "a2"], ["b1"]]} bag = {"to_format": [["a1", "a2"], ["b1"]]}
res = dev_visitor.visit(context, FormatAstList("a"), bag) res = dev_visitor.visit(context, FormatAstList("to_format"), bag)
assert res == FormatAstList(variable="a", items=[ assert res == FormatAstList(variable="to_format", items=[
FormatAstList(variable="__item", index=0, debug=True, prefix='[', suffix=']', items=[ FormatAstList(variable="__item", index=0, debug=True, prefix='[', suffix=']', items=[
FormatAstVariable(name="__item", index=0, debug=True, value="a1"), FormatAstVariable(name="__item", index=0, debug=True, value="a1"),
FormatAstVariable(name="__item", index=1, debug=True, value="a2"), FormatAstVariable(name="__item", index=1, debug=True, value="a2"),
@@ -38,3 +39,41 @@ class TestDeveloperVisitor(TestUsingMemoryBasedSheerka):
FormatAstVariable(name="__item", index=0, debug=True, value="b1"), FormatAstVariable(name="__item", index=0, debug=True, value="b1"),
]), ]),
]) ])
def test_i_can_develop_dict(self):
sheerka, context = self.init_concepts()
service_out = sheerka.services[SheerkaOut.NAME]
dev_visitor = DeveloperVisitor(service_out, NullDebugLogger(), set(), 0)
bag = {"to_format": {"a": "value1", "b": 3.14}}
res = dev_visitor.visit(context, FormatAstDict("to_format"), bag)
assert res == FormatAstDict(variable='to_format', items=[
(FormatAstVariable(name='__key', index=0, value='a'),
FormatAstVariable(name='__value', index='a', value='value1')),
(FormatAstVariable(name='__key', index=1, value='b'),
FormatAstVariable(name='__value', index='b', value=3.14))])
def test_i_can_develop_multi(self):
sheerka, context, *rules = self.init_format_rules(
("isinstance(to_format, BuiltinConcepts.TO_DICT)", "dict(to_format)"))
service_out = sheerka.services[SheerkaOut.NAME]
dev_visitor = DeveloperVisitor(service_out, NullDebugLogger(), set(), 0)
item1 = sheerka.new(BuiltinConcepts.TO_DICT, body={"a1": "value1"})
item2 = sheerka.new(BuiltinConcepts.TO_DICT, body={"a2": "value2"})
bag = {"to_format": sheerka.new(BuiltinConcepts.TO_MULTI, body=[item1, item2])}
res = dev_visitor.visit(context, FormatAstMulti("to_format"), bag)
assert res == FormatAstMulti("to_format", items=[
FormatAstDict(variable='to_format', items=[
(FormatAstVariable(name='__key', index=0, value='a1'),
FormatAstVariable(name='__value', index='a1', value='value1'))]),
FormatAstDict(variable='to_format', items=[
(FormatAstVariable(name='__key', index=0, value='a2'),
FormatAstVariable(name='__value', index='a2', value='value2'))])
])