holado 0.2.5__py3-none-any.whl → 0.2.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of holado might be problematic. Click here for more details.
- holado/__init__.py +9 -1
- holado/common/handlers/object.py +2 -1
- holado/common/handlers/undefined.py +16 -6
- {holado-0.2.5.dist-info → holado-0.2.7.dist-info}/METADATA +1 -1
- {holado-0.2.5.dist-info → holado-0.2.7.dist-info}/RECORD +32 -31
- holado_core/common/block/scope_steps.py +2 -2
- holado_core/common/resource/persisted_method_to_call_manager.py +18 -5
- holado_core/common/tools/tools.py +26 -9
- holado_core/tests/behave/steps/common/tables_steps.py +1 -1
- holado_helper/initialize_holado.py +72 -0
- holado_helper/script/action.py +21 -9
- holado_helper/script/initialize_script.py +3 -23
- holado_helper/script/script.py +2 -2
- holado_protobuf/ipc/protobuf/protobuf_messages.py +1 -1
- holado_scripting/common/tools/evaluate_parameters.py +23 -5
- holado_scripting/common/tools/expression_evaluator.py +115 -113
- holado_scripting/tests/behave/steps/scenario/if_steps.py +2 -2
- holado_scripting/text/interpreter/functions/function_hex_to_bytes.py +1 -1
- holado_scripting/text/interpreter/text_interpreter.py +20 -21
- holado_test/behave/behave_environment.py +31 -12
- holado_test/scenario/step_tools.py +11 -12
- holado_test/scenario/tester_tools.py +3 -1
- holado_value/common/tables/comparators/table_2_value_table_cell_comparator.py +3 -2
- holado_value/common/tables/converters/value_table_converter.py +1 -1
- holado_value/common/tables/value_table_cell.py +5 -1
- holado_value/common/tools/value.py +56 -33
- holado_value/common/tools/value_types.py +6 -0
- test_holado/features/NonReg/{ipc → holado_binary}/bit_series.feature +13 -0
- test_holado/features/NonReg/test_steps/common.feature +1 -1
- {holado-0.2.5.dist-info → holado-0.2.7.dist-info}/WHEEL +0 -0
- {holado-0.2.5.dist-info → holado-0.2.7.dist-info}/licenses/LICENSE +0 -0
- /test_holado/features/NonReg/{ipc → holado_binary}/bit_series.error.feature +0 -0
|
@@ -60,12 +60,11 @@ class TextInterpreter(TextInspecter):
|
|
|
60
60
|
if str_to_interpret is None:
|
|
61
61
|
return None
|
|
62
62
|
|
|
63
|
-
if Tools.do_log(logger, logging.TRACE): # @UndefinedVariable
|
|
64
|
-
|
|
65
|
-
logger.trace("Interpreting '{}'...".format(str_to_interpret))
|
|
63
|
+
if Tools.do_log(logger, logging.TRACE, max_log_level=log_level): # @UndefinedVariable
|
|
64
|
+
logger.log(Tools.do_log_level(logging.TRACE, log_level), "Interpreting '{}'...".format(str_to_interpret)) # @UndefinedVariable
|
|
66
65
|
|
|
67
66
|
# Interpret and get result as object
|
|
68
|
-
res, _ = self.__interpret(str_to_interpret, eval_params=eval_params)
|
|
67
|
+
res, _ = self.__interpret(str_to_interpret, eval_params=eval_params, log_level=log_level)
|
|
69
68
|
|
|
70
69
|
if Tools.do_log_if_objects_are_different(logger, log_level, str_to_interpret, res):
|
|
71
70
|
logger.log(log_level, "Interpreting '{}' -> [{}] (type: {})".format(str_to_interpret, res, type(res)))
|
|
@@ -82,18 +81,17 @@ class TextInterpreter(TextInspecter):
|
|
|
82
81
|
if str_to_interpret is None:
|
|
83
82
|
return None
|
|
84
83
|
|
|
85
|
-
if Tools.do_log(logger, logging.TRACE): # @UndefinedVariable
|
|
86
|
-
|
|
87
|
-
logger.trace("Interpreting sections in '{}'...".format(str_to_interpret))
|
|
84
|
+
if Tools.do_log(logger, logging.TRACE, max_log_level=log_level): # @UndefinedVariable
|
|
85
|
+
logger.log(Tools.do_log_level(logging.TRACE, log_level), "Interpreting sections in '{}'...".format(str_to_interpret)) # @UndefinedVariable
|
|
88
86
|
|
|
89
87
|
# Interpret and get result as object
|
|
90
|
-
res, locals_ = self.__interpret(str_to_interpret, replace_sections_by_variables=True, eval_params=eval_params)
|
|
88
|
+
res, locals_ = self.__interpret(str_to_interpret, replace_sections_by_variables=True, eval_params=eval_params, log_level=log_level)
|
|
91
89
|
|
|
92
90
|
if Tools.do_log_if_objects_are_different(logger, log_level, str_to_interpret, res):
|
|
93
91
|
logger.log(log_level, f"Interpreting sections in '{str_to_interpret}' -> [{res}] (type: {type(res)}, locals: {locals_})")
|
|
94
92
|
return res, locals_
|
|
95
93
|
|
|
96
|
-
def __interpret(self, str_to_interpret, replace_sections_by_variables=False, eval_params=EvaluateParameters.default_without_raise()):
|
|
94
|
+
def __interpret(self, str_to_interpret, replace_sections_by_variables=False, eval_params=EvaluateParameters.default_without_raise(), log_level=logging.DEBUG):
|
|
97
95
|
res = None
|
|
98
96
|
locals_ = {}
|
|
99
97
|
|
|
@@ -103,7 +101,7 @@ class TextInterpreter(TextInspecter):
|
|
|
103
101
|
r_match = self.__regex_to_be_interpreted.match(str_to_interpret)
|
|
104
102
|
if r_match:
|
|
105
103
|
str_under_interpret = r_match.group(1).strip()
|
|
106
|
-
res = self.__interpret_text(str_under_interpret, eval_params=eval_params)
|
|
104
|
+
res = self.__interpret_text(str_under_interpret, eval_params=eval_params, log_level=log_level)
|
|
107
105
|
# Text is not interpretable ; expect it will be the case later
|
|
108
106
|
if res == str_under_interpret:
|
|
109
107
|
res = str_to_interpret
|
|
@@ -112,19 +110,20 @@ class TextInterpreter(TextInspecter):
|
|
|
112
110
|
else:
|
|
113
111
|
raise TechnicalException(f"Failed to find interpret section whereas its indexes were found")
|
|
114
112
|
else:
|
|
115
|
-
res, locals_ = self.__find_and_interpret_sections(str_to_interpret, replace_sections_by_variables=replace_sections_by_variables, eval_params=eval_params)
|
|
113
|
+
res, locals_ = self.__find_and_interpret_sections(str_to_interpret, replace_sections_by_variables=replace_sections_by_variables, eval_params=eval_params, log_level=log_level)
|
|
116
114
|
|
|
117
115
|
return res, locals_
|
|
118
116
|
|
|
119
|
-
def __interpret_text(self, text, eval_params=EvaluateParameters.default_without_raise()):
|
|
117
|
+
def __interpret_text(self, text, eval_params=EvaluateParameters.default_without_raise(), log_level=logging.DEBUG): # @UndefinedVariable
|
|
120
118
|
# Manage functions
|
|
121
119
|
if self._has_function(text, with_interpreted=False):
|
|
122
|
-
return self.__evaluate_function(text, eval_params=eval_params)
|
|
120
|
+
return self.__evaluate_function(text, eval_params=eval_params, log_level=log_level)
|
|
123
121
|
|
|
124
122
|
# Manage evaluation
|
|
125
|
-
|
|
123
|
+
_, res = self._expression_evaluator.evaluate_expression(text, eval_params=eval_params, log_level=Tools.do_log_level(log_level, logging.TRACE)) # @UndefinedVariable
|
|
124
|
+
return res
|
|
126
125
|
|
|
127
|
-
def __find_and_interpret_sections(self, str_to_interpret, replace_sections_by_variables=False, eval_params=EvaluateParameters.default_without_raise()):
|
|
126
|
+
def __find_and_interpret_sections(self, str_to_interpret, replace_sections_by_variables=False, eval_params=EvaluateParameters.default_without_raise(), log_level=logging.DEBUG):
|
|
128
127
|
res = str_to_interpret
|
|
129
128
|
locals_ = {}
|
|
130
129
|
|
|
@@ -145,7 +144,7 @@ class TextInterpreter(TextInspecter):
|
|
|
145
144
|
sub_str = res[ind_beg:ind_end]
|
|
146
145
|
|
|
147
146
|
# Interpret sub-section
|
|
148
|
-
interpreted_value = self.interpret(sub_str, eval_params=eval_params)
|
|
147
|
+
interpreted_value = self.interpret(sub_str, eval_params=eval_params, log_level=log_level)
|
|
149
148
|
|
|
150
149
|
# Manage sections that aren't interpretable
|
|
151
150
|
interpreted_str = f"{interpreted_value}"
|
|
@@ -170,7 +169,7 @@ class TextInterpreter(TextInspecter):
|
|
|
170
169
|
|
|
171
170
|
return res, locals_
|
|
172
171
|
|
|
173
|
-
def __evaluate_function(self, fct_str, eval_params=EvaluateParameters.default_without_raise()):
|
|
172
|
+
def __evaluate_function(self, fct_str, eval_params=EvaluateParameters.default_without_raise(), log_level=logging.DEBUG):
|
|
174
173
|
func_name, args_str = self._get_function_and_args_strings(fct_str, with_interpreted=False)
|
|
175
174
|
func = self._get_function(func_name) if func_name is not None else None
|
|
176
175
|
if func is None:
|
|
@@ -178,8 +177,8 @@ class TextInterpreter(TextInspecter):
|
|
|
178
177
|
|
|
179
178
|
args = self._get_args(args_str)
|
|
180
179
|
|
|
181
|
-
if Tools.do_log(logger, logging.TRACE): # @UndefinedVariable
|
|
182
|
-
logger.
|
|
180
|
+
if Tools.do_log(logger, logging.TRACE, max_log_level=log_level): # @UndefinedVariable
|
|
181
|
+
logger.log(Tools.do_log_level(logging.TRACE, max_log_level=log_level), f"Evaluating function '{func_name}' with args {args}") # @UndefinedVariable
|
|
183
182
|
# logger.trace(f"Evaluating function '{func_name}' with args {args} (eval_params: {eval_params})", stack_info=True)
|
|
184
183
|
try:
|
|
185
184
|
res = func.apply(args)
|
|
@@ -189,8 +188,8 @@ class TextInterpreter(TextInspecter):
|
|
|
189
188
|
else:
|
|
190
189
|
res = fct_str
|
|
191
190
|
|
|
192
|
-
if Tools.do_log(logger,
|
|
193
|
-
logger.
|
|
191
|
+
if Tools.do_log(logger, log_level):
|
|
192
|
+
logger.log(log_level, f"Evaluate function [{fct_str}] => [{func_name}({', '.join(args)})] => [{res}] (type: {Typing.get_object_class_fullname(res)})")
|
|
194
193
|
return res
|
|
195
194
|
|
|
196
195
|
def __register_default_functions(self, dynamic_text_manager):
|
|
@@ -22,6 +22,8 @@ from holado_test.behave.scenario.behave_step_tools import BehaveStepTools
|
|
|
22
22
|
from holado_test.scenario.step_tools import StepTools
|
|
23
23
|
from holado_test.test_config import TestConfig
|
|
24
24
|
import time
|
|
25
|
+
from behave.model_core import Status
|
|
26
|
+
from holado.common.handlers.undefined import undefined_value
|
|
25
27
|
|
|
26
28
|
|
|
27
29
|
logger = logging.getLogger(__name__)
|
|
@@ -107,23 +109,40 @@ def after_step(context, step):
|
|
|
107
109
|
# Session context
|
|
108
110
|
SessionContext.instance().after_step(step)
|
|
109
111
|
|
|
110
|
-
# Log
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
var_step_descr = StepTools.evaluate_variable_name(step_descr)
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
112
|
+
# Log step result
|
|
113
|
+
step_descr = __step_description(step)
|
|
114
|
+
try:
|
|
115
|
+
var_step_descr = StepTools.evaluate_variable_name(step_descr, log_level=logging.NOTSET)
|
|
116
|
+
except:
|
|
117
|
+
var_step_descr = "[ERROR during evaluation]"
|
|
118
|
+
try:
|
|
119
|
+
interpreted_step_descr = StepTools.evaluate_string_parameter(step_descr, log_level=logging.NOTSET)
|
|
120
|
+
except:
|
|
121
|
+
interpreted_step_descr = "[ERROR during interpretation]"
|
|
122
|
+
if step.status in [Status.failed, Status.error] or interpreted_step_descr != step_descr or var_step_descr != interpreted_step_descr:
|
|
123
|
+
msg = "Step {}:\n step:\n{}{}{}".format(
|
|
124
|
+
step.status.name, Tools.indent_string(8, step_descr),
|
|
117
125
|
"" if interpreted_step_descr == step_descr else "\n interpreted step:\n{}".format(Tools.indent_string(8, interpreted_step_descr)),
|
|
118
|
-
"" if var_step_descr == interpreted_step_descr else "\n partially interpreted step:\n{}".format(Tools.indent_string(8, var_step_descr))
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
126
|
+
"" if var_step_descr == interpreted_step_descr else "\n partially interpreted step:\n{}".format(Tools.indent_string(8, var_step_descr)) )
|
|
127
|
+
|
|
128
|
+
if step.status in [Status.failed, Status.error]:
|
|
129
|
+
msg += "\n error:\n{}\n step attributes:\n{}".format(
|
|
130
|
+
Tools.indent_string(8, __step_error(step)),
|
|
131
|
+
Tools.indent_string(8, __step_attributes(step)) )
|
|
132
|
+
if step.hook_failed:
|
|
133
|
+
msg += "\n Hook failed"
|
|
134
|
+
elif '\n' in step_descr:
|
|
135
|
+
msg = "Step {}:\n{}".format(step.status.name, Tools.indent_string(4, step_descr))
|
|
136
|
+
else:
|
|
137
|
+
msg = "Step {}: {}".format(step.status.name, step_descr)
|
|
138
|
+
|
|
139
|
+
if step.status in [Status.failed, Status.error]:
|
|
123
140
|
logger.error(msg)
|
|
124
141
|
|
|
125
142
|
if TestConfig.wait_on_step_failure_s > 0:
|
|
126
143
|
time.sleep(TestConfig.wait_on_step_failure_s)
|
|
144
|
+
else:
|
|
145
|
+
logger.debug(msg)
|
|
127
146
|
except:
|
|
128
147
|
logger.exception(f"Hook error (step: {step})")
|
|
129
148
|
raise
|
|
@@ -78,7 +78,6 @@ class StepTools(object):
|
|
|
78
78
|
res = text.encode('latin-1').decode('unicode-escape')
|
|
79
79
|
|
|
80
80
|
if Tools.do_log(logger, logging.TRACE): # @UndefinedVariable
|
|
81
|
-
|
|
82
81
|
logger.trace("unescaping string [{}] -> [{}]".format(text, res))
|
|
83
82
|
return res
|
|
84
83
|
|
|
@@ -88,8 +87,8 @@ class StepTools(object):
|
|
|
88
87
|
|
|
89
88
|
@staticmethod
|
|
90
89
|
def evaluate_string_parameter(text_param, do_interpret=True, log_level=logging.DEBUG):
|
|
91
|
-
eval_params = EvaluateParameters.default().with_interpret(do_interpret).with_eval(False)
|
|
92
|
-
res = StepTools._get_expression_evaluator().evaluate_expression(text_param, eval_params=eval_params, log_level=logging.TRACE) # @UndefinedVariable
|
|
90
|
+
eval_params = EvaluateParameters.default().with_interpret(do_interpret).with_eval(False).with_result_type(str)
|
|
91
|
+
_, res = StepTools._get_expression_evaluator().evaluate_expression(text_param, eval_params=eval_params, log_level=Tools.do_log_level(log_level, logging.TRACE)) # @UndefinedVariable
|
|
93
92
|
if Tools.do_log_if_objects_are_different(logger, log_level, text_param, res):
|
|
94
93
|
logger.log(log_level, "evaluate_string_parameter: [{}] -> [{}]".format(text_param, res))
|
|
95
94
|
return res
|
|
@@ -99,8 +98,8 @@ class StepTools(object):
|
|
|
99
98
|
if text_param is None:
|
|
100
99
|
return None
|
|
101
100
|
|
|
102
|
-
eval_params = EvaluateParameters.default_without_eval(False)
|
|
103
|
-
res = StepTools._get_text_interpreter().interpret(text_param, eval_params=eval_params, log_level=logging.TRACE) # @UndefinedVariable
|
|
101
|
+
eval_params = EvaluateParameters.default_without_eval(False).with_result_type(str)
|
|
102
|
+
res = StepTools._get_text_interpreter().interpret(text_param, eval_params=eval_params, log_level=Tools.do_log_level(log_level, logging.TRACE)) # @UndefinedVariable
|
|
104
103
|
if Tools.do_log_if_objects_are_different(logger, log_level, text_param, res):
|
|
105
104
|
logger.log(log_level, f"evaluate_variable_name: [{text_param}] -> [{res}] (type: {Typing.get_object_class_fullname(res)})")
|
|
106
105
|
return res
|
|
@@ -111,7 +110,7 @@ class StepTools(object):
|
|
|
111
110
|
return None
|
|
112
111
|
|
|
113
112
|
eval_params = EvaluateParameters.default_without_eval(False)
|
|
114
|
-
res = StepTools._get_expression_evaluator().evaluate_expression(text_param, eval_params=eval_params, log_level=logging.TRACE) # @UndefinedVariable
|
|
113
|
+
_, res = StepTools._get_expression_evaluator().evaluate_expression(text_param, eval_params=eval_params, log_level=Tools.do_log_level(log_level, logging.TRACE)) # @UndefinedVariable
|
|
115
114
|
if Tools.do_log_if_objects_are_different(logger, log_level, text_param, res):
|
|
116
115
|
logger.log(log_level, f"evaluate_variable_name: [{text_param}] -> [{res}] (type: {Typing.get_object_class_fullname(res)})")
|
|
117
116
|
return res
|
|
@@ -122,14 +121,14 @@ class StepTools(object):
|
|
|
122
121
|
return None
|
|
123
122
|
|
|
124
123
|
eval_params = EvaluateParameters.default().with_raise_on_eval_error(False)
|
|
125
|
-
res = StepTools._get_expression_evaluator().evaluate_expression(text_param, eval_params=eval_params, log_level=logging.TRACE) # @UndefinedVariable
|
|
124
|
+
_, res = StepTools._get_expression_evaluator().evaluate_expression(text_param, eval_params=eval_params, log_level=Tools.do_log_level(log_level, logging.TRACE)) # @UndefinedVariable
|
|
126
125
|
if Tools.do_log_if_objects_are_different(logger, log_level, text_param, res):
|
|
127
126
|
logger.log(log_level, f"evaluate_scenario_parameter: [{text_param}] -> [{res}] (type: {Typing.get_object_class_fullname(res)})")
|
|
128
127
|
return res
|
|
129
128
|
|
|
130
129
|
@staticmethod
|
|
131
130
|
def evaluate_list_scenario_parameter(text_param, param_name, log_level=logging.DEBUG):
|
|
132
|
-
res = StepTools.evaluate_scenario_parameter(text_param)
|
|
131
|
+
res = StepTools.evaluate_scenario_parameter(text_param, log_level=log_level)
|
|
133
132
|
if isinstance(res, str):
|
|
134
133
|
regex = re.compile(r"^\s*\[(.*)\]\s*$")
|
|
135
134
|
m = regex.match(res)
|
|
@@ -294,8 +293,8 @@ class StepTools(object):
|
|
|
294
293
|
@classmethod
|
|
295
294
|
def has_table_header(cls, table):
|
|
296
295
|
"""
|
|
297
|
-
Return True if scenario table has a header (for
|
|
298
|
-
For
|
|
296
|
+
Return True if scenario table has a header (for HolAdo framework).
|
|
297
|
+
For HolAdo framework, table header names are all texts without quotes.
|
|
299
298
|
"""
|
|
300
299
|
internal_header = cls._get_table_header(table)
|
|
301
300
|
if internal_header is None:
|
|
@@ -303,7 +302,7 @@ class StepTools(object):
|
|
|
303
302
|
|
|
304
303
|
for cell in internal_header:
|
|
305
304
|
scell = ValueTableCell(cell)
|
|
306
|
-
if scell.value_type
|
|
305
|
+
if not ( scell.content_type == ValueTypes.Symbol and scell.value_type == ValueTypes.String ):
|
|
307
306
|
return False
|
|
308
307
|
|
|
309
308
|
return True
|
|
@@ -402,7 +401,7 @@ class StepTools(object):
|
|
|
402
401
|
def format_steps_with(cls, steps, format_with_list):
|
|
403
402
|
res = steps
|
|
404
403
|
for form in format_with_list:
|
|
405
|
-
form_eval = cls._get_expression_evaluator().evaluate_expression(form)
|
|
404
|
+
_, form_eval = cls._get_expression_evaluator().evaluate_expression(form, log_level=logging.TRACE) # @UndefinedVariable
|
|
406
405
|
if form_eval == form:
|
|
407
406
|
raise FunctionalException(f"Not able to evaluation expression [{form}]. Is missing its initialization ?")
|
|
408
407
|
res = res.replace(f"${{{form}}}", str(form_eval))
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
from holado.common.context.session_context import SessionContext
|
|
15
15
|
import logging
|
|
16
16
|
from holado_core.common.tables.table import Table
|
|
17
|
+
from holado_core.common.tools.tools import Tools
|
|
17
18
|
|
|
18
19
|
logger = logging.getLogger(__name__)
|
|
19
20
|
|
|
@@ -47,6 +48,7 @@ class TesterTools(object):
|
|
|
47
48
|
if isinstance(obj, Table):
|
|
48
49
|
res = obj.represent()
|
|
49
50
|
else:
|
|
50
|
-
res = str(obj)
|
|
51
|
+
# res = str(obj)
|
|
52
|
+
res = Tools.represent_object(obj)
|
|
51
53
|
return res
|
|
52
54
|
|
|
@@ -107,7 +107,8 @@ class Table2ValueTable_CellComparator(TableCellComparator):
|
|
|
107
107
|
|
|
108
108
|
cause = None
|
|
109
109
|
try:
|
|
110
|
-
value_type = cell_2.value_type
|
|
110
|
+
# value_type = cell_2.value_type
|
|
111
|
+
value_type = cell_2.content_type
|
|
111
112
|
if value_type == ValueTypes.NotApplicable:
|
|
112
113
|
res = True
|
|
113
114
|
elif value_type == ValueTypes.Null:
|
|
@@ -121,7 +122,7 @@ class Table2ValueTable_CellComparator(TableCellComparator):
|
|
|
121
122
|
res = comparator.equals(cell_1_value, cell_2_value, is_obtained_vs_expected=is_obtained_vs_expected, raise_exception=raise_exception)
|
|
122
123
|
elif value_type == ValueTypes.Merged:
|
|
123
124
|
return super().equals(cell_1, cell_2, is_obtained_vs_expected, raise_exception)
|
|
124
|
-
elif
|
|
125
|
+
elif ValueTypes.is_string(value_type):
|
|
125
126
|
res = self._equals_string(cell_1, cell_2, is_obtained_vs_expected, raise_exception)
|
|
126
127
|
elif value_type == ValueTypes.Symbol:
|
|
127
128
|
res = self._equals_symbol(cell_1, cell_2, is_obtained_vs_expected, raise_exception)
|
|
@@ -158,7 +158,7 @@ class ValueTableConverter(TableConverter):
|
|
|
158
158
|
|
|
159
159
|
if row.get_cell(1).value_type in [ValueTypes.NotApplicable, ValueTypes.Merged]:
|
|
160
160
|
pass
|
|
161
|
-
elif row.get_cell(1).value_type
|
|
161
|
+
elif ValueTypes.is_string(row.get_cell(1).value_type):
|
|
162
162
|
name = row.get_cell(0).value
|
|
163
163
|
value = row.get_cell(1).value
|
|
164
164
|
|
|
@@ -31,7 +31,7 @@ class ValueTableCell(TableCell):
|
|
|
31
31
|
super().__init__(cell_content)
|
|
32
32
|
|
|
33
33
|
self.__value = Value(original_value=cell_content, value=cell_value, do_eval_once=do_eval_once)
|
|
34
|
-
self.content = self.__value.
|
|
34
|
+
self.content = self.__value.original_value
|
|
35
35
|
|
|
36
36
|
def __eq__(self, other):
|
|
37
37
|
self._verify_valid_compared_object(other)
|
|
@@ -51,6 +51,10 @@ class ValueTableCell(TableCell):
|
|
|
51
51
|
def string_content(self):
|
|
52
52
|
return self.__value.string_value
|
|
53
53
|
|
|
54
|
+
@property
|
|
55
|
+
def content_type(self):
|
|
56
|
+
return self.__value.original_value_type
|
|
57
|
+
|
|
54
58
|
@property
|
|
55
59
|
def value_type(self):
|
|
56
60
|
return self.__value.value_type
|
|
@@ -20,7 +20,7 @@ from holado_value.common.tools.value_types import ValueTypes
|
|
|
20
20
|
from functools import total_ordering
|
|
21
21
|
from holado_scripting.common.tools.evaluate_parameters import EvaluateParameters
|
|
22
22
|
from holado.holado_config import Config
|
|
23
|
-
from holado.common.handlers.undefined import undefined_value
|
|
23
|
+
from holado.common.handlers.undefined import undefined_value, undefined_argument, to_be_defined, not_applicable, is_undefined
|
|
24
24
|
from holado_python.standard_library.typing import Typing
|
|
25
25
|
|
|
26
26
|
logger = logging.getLogger(__name__)
|
|
@@ -29,26 +29,27 @@ logger = logging.getLogger(__name__)
|
|
|
29
29
|
@total_ordering
|
|
30
30
|
class Value(object):
|
|
31
31
|
|
|
32
|
-
def __init__(self, original_value=
|
|
32
|
+
def __init__(self, original_value=undefined_argument, value=undefined_argument, do_eval_once=True, eval_params=undefined_argument):
|
|
33
33
|
"""
|
|
34
34
|
@summary: Constructor
|
|
35
|
-
@param original_value: Original value - can be a string or any object
|
|
35
|
+
@param original_value: Original value (before value expression evaluation) - can be a string or any object
|
|
36
36
|
@param value: Value - can be a string or any object
|
|
37
37
|
"""
|
|
38
|
-
self.
|
|
39
|
-
self.
|
|
40
|
-
self.
|
|
38
|
+
self.__original_value = to_be_defined
|
|
39
|
+
self.__value = to_be_defined
|
|
40
|
+
self.__value_type = None
|
|
41
41
|
|
|
42
42
|
# Manage value evaluation
|
|
43
|
-
self.__value_to_eval =
|
|
44
|
-
self.
|
|
43
|
+
self.__value_to_eval = to_be_defined
|
|
44
|
+
self.__evaluated_value = to_be_defined
|
|
45
|
+
self.__evaluated_value_type = to_be_defined
|
|
45
46
|
# By default, raise on interpret and variable evaluation error, but not on eval error
|
|
46
|
-
self.__eval_params_default = eval_params if eval_params is not
|
|
47
|
+
self.__eval_params_default = eval_params if eval_params is not undefined_argument else EvaluateParameters.default().with_raise_on_eval_error(False)
|
|
47
48
|
self.__do_eval_once = do_eval_once
|
|
48
49
|
|
|
49
50
|
self.__extract_value_information(original_value, value)
|
|
50
51
|
if Tools.do_log(logger, logging.TRACE): # @UndefinedVariable
|
|
51
|
-
logger.trace(f"New Value:
|
|
52
|
+
logger.trace(f"New Value: original_value=[{self.__original_value}] ; type=[{self.__value_type.name}] ; value=[{self.__value}] ; value_to_eval=[{self.__value_to_eval}]")
|
|
52
53
|
|
|
53
54
|
def _verify_valid_compared_object(self, other, raise_exception=True):
|
|
54
55
|
res = isinstance(other, Value)
|
|
@@ -73,7 +74,7 @@ class Value(object):
|
|
|
73
74
|
def string_value(self):
|
|
74
75
|
value = self.get_value()
|
|
75
76
|
|
|
76
|
-
if value
|
|
77
|
+
if value in [undefined_value, not_applicable]:
|
|
77
78
|
return Config.NOT_APPLICABLE_SYMBOL
|
|
78
79
|
if value is None:
|
|
79
80
|
return Config.NONE_SYMBOL
|
|
@@ -81,15 +82,22 @@ class Value(object):
|
|
|
81
82
|
return str(value)
|
|
82
83
|
|
|
83
84
|
@property
|
|
84
|
-
def
|
|
85
|
+
def original_value(self):
|
|
85
86
|
"""
|
|
86
87
|
@summary: Return the original value
|
|
87
88
|
"""
|
|
88
|
-
return self.
|
|
89
|
+
return self.__original_value
|
|
90
|
+
|
|
91
|
+
@property
|
|
92
|
+
def original_value_type(self):
|
|
93
|
+
"""
|
|
94
|
+
@summary: Return the original value type
|
|
95
|
+
"""
|
|
96
|
+
return self.__value_type
|
|
89
97
|
|
|
90
98
|
@property
|
|
91
99
|
def value_type(self):
|
|
92
|
-
return self.
|
|
100
|
+
return self.get_value_type()
|
|
93
101
|
|
|
94
102
|
@property
|
|
95
103
|
def value_before_eval(self):
|
|
@@ -105,56 +113,71 @@ class Value(object):
|
|
|
105
113
|
"""
|
|
106
114
|
return self.get_value(raise_if_undefined=True)
|
|
107
115
|
|
|
108
|
-
def get_value(self, raise_if_undefined=False, eval_params=
|
|
116
|
+
def get_value(self, raise_if_undefined=False, eval_params=undefined_argument):
|
|
109
117
|
if self.__value_to_eval is not undefined_value:
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
self.__value_evaluated = self.__get_expression_evaluator().evaluate_expression_of_information(self.__type, self.__value_to_eval, eval_params=eval_params)
|
|
113
|
-
res = self.__value_evaluated
|
|
118
|
+
self.__evaluate_value_if_needed(eval_params=eval_params)
|
|
119
|
+
res = self.__evaluated_value
|
|
114
120
|
else:
|
|
115
121
|
res = self.__value
|
|
116
122
|
|
|
117
|
-
if res
|
|
123
|
+
if is_undefined(res) and raise_if_undefined:
|
|
118
124
|
msg = "Value is undefined"
|
|
119
125
|
if self.value_type == ValueTypes.NotApplicable:
|
|
120
126
|
msg += " (Not Applicable)"
|
|
121
|
-
raise ValueError(f"Value is undefined (value type: {self.value_type.name} ; original value: [{self.
|
|
127
|
+
raise ValueError(f"Value is undefined (value type: {self.value_type.name} ; original value: [{self.original_value}] (type: {Typing.get_object_class_fullname(self.original_value)}))")
|
|
128
|
+
return res
|
|
129
|
+
|
|
130
|
+
def get_value_type(self, eval_params=undefined_argument):
|
|
131
|
+
if self.__value_to_eval is not undefined_value:
|
|
132
|
+
self.__evaluate_value_if_needed(eval_params=eval_params)
|
|
133
|
+
res = self.__evaluated_value_type
|
|
134
|
+
else:
|
|
135
|
+
res = self.__value_type
|
|
122
136
|
return res
|
|
123
137
|
|
|
138
|
+
def __evaluate_value_if_needed(self, eval_params=undefined_argument):
|
|
139
|
+
if self.__evaluated_value is to_be_defined or not self.__do_eval_once:
|
|
140
|
+
eval_params = eval_params if eval_params is not undefined_argument else self.__eval_params_default
|
|
141
|
+
if ValueTypes.is_string(self.__value_type):
|
|
142
|
+
eval_params = eval_params.with_result_type(str)
|
|
143
|
+
self.__evaluated_value_type, self.__evaluated_value = self.__get_expression_evaluator().evaluate_expression_of_information(self.__value_type, self.__value_to_eval, eval_params=eval_params)
|
|
144
|
+
|
|
124
145
|
def represent(self, indent = 0, do_evaluation = False):
|
|
125
146
|
res_list = []
|
|
126
147
|
|
|
127
148
|
res_list.append(Tools.get_indent_string(indent))
|
|
128
149
|
|
|
129
|
-
if
|
|
150
|
+
if ValueTypes.is_string(self.__value_type):
|
|
130
151
|
if do_evaluation:
|
|
131
152
|
res_list.append("'")
|
|
132
153
|
res_list.append(self.string_value)
|
|
133
154
|
res_list.append("'")
|
|
134
155
|
else:
|
|
135
|
-
res_list.append(str(self.
|
|
136
|
-
elif self.
|
|
156
|
+
res_list.append(str(self.original_value))
|
|
157
|
+
elif self.__value_type in [ValueTypes.Boolean, ValueTypes.Integer, ValueTypes.Float, ValueTypes.Null, ValueTypes.NotApplicable, ValueTypes.Symbol, ValueTypes.Generic]:
|
|
137
158
|
if do_evaluation:
|
|
138
159
|
res_list.append(self.string_value)
|
|
139
160
|
else:
|
|
140
|
-
res_list.append(str(self.
|
|
161
|
+
res_list.append(str(self.original_value))
|
|
141
162
|
else:
|
|
142
|
-
raise TechnicalException("Unmanaged value type '{}'".format(self.
|
|
163
|
+
raise TechnicalException("Unmanaged value type '{}'".format(self.__value_type.name))
|
|
143
164
|
|
|
144
165
|
return "".join(res_list)
|
|
145
166
|
|
|
146
|
-
def __extract_value_information(self,
|
|
167
|
+
def __extract_value_information(self, original_value, value):
|
|
147
168
|
# Define original value
|
|
148
|
-
if
|
|
149
|
-
self.
|
|
150
|
-
elif value is not
|
|
169
|
+
if original_value is not undefined_argument and not (original_value in [undefined_value, None] and value not in [undefined_argument, undefined_value, None]):
|
|
170
|
+
self.__original_value = original_value
|
|
171
|
+
elif value is not undefined_argument:
|
|
151
172
|
if value is not None and isinstance(value, str):
|
|
152
|
-
self.
|
|
173
|
+
self.__original_value = f"'{value}'"
|
|
153
174
|
else:
|
|
154
|
-
self.
|
|
175
|
+
self.__original_value = value
|
|
155
176
|
|
|
156
177
|
# Define value information from original value
|
|
157
|
-
self.
|
|
178
|
+
self.__value_type, self.__value, self.__value_to_eval = self.__get_expression_evaluator().extract_expression_information(self.original_value)
|
|
179
|
+
if Tools.do_log(logger, logging.TRACE): # @UndefinedVariable
|
|
180
|
+
logger.trace(f"extracted value info: {self.__value_type=}, {self.__value=}, {self.__value_to_eval=}")
|
|
158
181
|
|
|
159
182
|
def __get_expression_evaluator(self):
|
|
160
183
|
if SessionContext.instance().has_scenario_context():
|
|
@@ -32,4 +32,10 @@ class ValueTypes(AutoNumber):
|
|
|
32
32
|
Merged = ()
|
|
33
33
|
Symbol = ()
|
|
34
34
|
Generic = ()
|
|
35
|
+
|
|
36
|
+
@classmethod
|
|
37
|
+
def is_string(cls, value_type):
|
|
38
|
+
return value_type in [ValueTypes.String, ValueTypes.DynamicString, ValueTypes.ThreadDynamicString, ValueTypes.UniqueString]
|
|
39
|
+
|
|
40
|
+
|
|
35
41
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
@go_nogo
|
|
4
4
|
Feature: Test bit_series module
|
|
5
5
|
|
|
6
|
+
@to_hexadecimal_string
|
|
6
7
|
Scenario: Create and convert bit-series to hexa
|
|
7
8
|
Given BIT_SERIES = bit series
|
|
8
9
|
| Name | Bit length | Type | Value |
|
|
@@ -24,6 +25,9 @@ Feature: Test bit_series module
|
|
|
24
25
|
Given RAW_TM = convert bit series BIT_SERIES to hexadecimal string
|
|
25
26
|
Then RAW_TM == '99FFFFAE1B'
|
|
26
27
|
|
|
28
|
+
|
|
29
|
+
@to_hexadecimal_string
|
|
30
|
+
@padding
|
|
27
31
|
Scenario: Create and convert to hexa bit-series of bit length out of bytes array length
|
|
28
32
|
Given BIT_SERIES = bit series
|
|
29
33
|
| Name | Bit length | Type | Value |
|
|
@@ -56,6 +60,8 @@ Feature: Test bit_series module
|
|
|
56
60
|
Given RAW_TM = convert bit series BIT_SERIES to hexadecimal string (right padded)
|
|
57
61
|
Then RAW_TM == '92'
|
|
58
62
|
|
|
63
|
+
|
|
64
|
+
@from_hexadecimal_string
|
|
59
65
|
Scenario: Create a bit-series from hexa
|
|
60
66
|
Given BIT_SERIES = bit series
|
|
61
67
|
| Name | Bit length | Type |
|
|
@@ -71,6 +77,9 @@ Feature: Test bit_series module
|
|
|
71
77
|
| 'F3' | 2 | int | 0 |
|
|
72
78
|
| 'F4' | 2 | int | 2 |
|
|
73
79
|
|
|
80
|
+
|
|
81
|
+
@from_hexadecimal_string
|
|
82
|
+
@padding
|
|
74
83
|
Scenario: Create from hexa bit-series of bit length out of bytes array length
|
|
75
84
|
Given BIT_SERIES = bit series
|
|
76
85
|
| Name | Bit length | Type |
|
|
@@ -99,6 +108,8 @@ Feature: Test bit_series module
|
|
|
99
108
|
| 'F2' | 1 | int | 1 |
|
|
100
109
|
| 'F3' | 1 | int | 1 |
|
|
101
110
|
|
|
111
|
+
|
|
112
|
+
@is_bit_series
|
|
102
113
|
Scenario: Verify hexa string is bit series
|
|
103
114
|
Then hexadecimal string '92' is bit series
|
|
104
115
|
| Name | Bit length | Type | Value |
|
|
@@ -107,6 +118,8 @@ Feature: Test bit_series module
|
|
|
107
118
|
| 'F3' | 2 | int | 0 |
|
|
108
119
|
| 'F4' | 2 | int | 2 |
|
|
109
120
|
|
|
121
|
+
|
|
122
|
+
@set_field
|
|
110
123
|
Scenario: Set bit-series field by variable expression
|
|
111
124
|
Given BIT_SERIES = bit series
|
|
112
125
|
| Name | Bit length | Type | Value |
|
|
File without changes
|
|
File without changes
|
|
File without changes
|