Improve loading error messages with item context and hierarchy path
Add item_load_context() context manager to tum_except.py that enriches ETUMSyntaxError with the item type, name, and parent path instead of replacing the original message with a vague 'missing or wrong parameter'. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import traceback
|
||||
import textwrap
|
||||
from contextlib import contextmanager
|
||||
|
||||
|
||||
class ETUMError(Exception):
|
||||
@@ -67,6 +68,28 @@ class ETUMParamError(ETUMError):
|
||||
return lines
|
||||
|
||||
|
||||
@contextmanager
|
||||
def item_load_context(item_type: str, item_name: str, filename: str = ""):
|
||||
"""Context manager that enriches ETUMSyntaxError with item context during loading.
|
||||
|
||||
Usage in test item __init__:
|
||||
with item_load_context(self.cmd(), self.name(), self.seqFilename()):
|
||||
self.param = self._prms.getParam("param", required=True)
|
||||
"""
|
||||
try:
|
||||
yield
|
||||
except ETUMSyntaxError as e:
|
||||
raise ETUMSyntaxError(
|
||||
f"In '{item_type}' item named '{item_name}':\n{e._message}",
|
||||
filename or e._file,
|
||||
) from e
|
||||
except Exception as e:
|
||||
raise ETUMSyntaxError(
|
||||
f"In '{item_type}' item named '{item_name}':\nUnexpected error: {e}",
|
||||
filename,
|
||||
) from e
|
||||
|
||||
|
||||
def print_exception(exc: ETUMError):
|
||||
if not isinstance(exc, ETUMError):
|
||||
print(traceback.format_exc(4))
|
||||
|
||||
@@ -7,7 +7,7 @@ import libs.testium as tm
|
||||
from interpreter.utils.params import TestItemParams
|
||||
from interpreter.utils.constants import TestItemType as cst_type
|
||||
from interpreter.utils.eval import eval_to_boolean, evaluate, post_evaluate
|
||||
from lib.tum_except import ETUMSyntaxError
|
||||
from lib.tum_except import ETUMSyntaxError, item_load_context
|
||||
|
||||
LOG_TEST_STOP = '<----- step "{}" finished'
|
||||
LOG_TEST_START = '-----> step "{}" started'
|
||||
@@ -131,11 +131,11 @@ class TestItem:
|
||||
if s:
|
||||
try:
|
||||
self.skipped = eval_to_boolean(s)
|
||||
except:
|
||||
except Exception as e:
|
||||
raise ETUMSyntaxError(
|
||||
f"'{self.cmd()}' test item named '{self.name()}':\nskipped expresion can only be a static expression as it is evaluated during loading of TUM : {s}",
|
||||
self.seqFilename(),
|
||||
)
|
||||
) from e
|
||||
# This allow disabling test item directly by using its name inside param.yaml file
|
||||
elif self._name in tm.gd("skipped_test_item", []):
|
||||
self.skipped = True
|
||||
@@ -164,11 +164,13 @@ class TestItem:
|
||||
self.banner = LOG_TEST_START.format(self._name)
|
||||
self.footer = LOG_TEST_STOP.format(self._name)
|
||||
|
||||
except:
|
||||
except ETUMSyntaxError:
|
||||
raise
|
||||
except Exception as e:
|
||||
raise ETUMSyntaxError(
|
||||
f"The '{self.cmd()}' test item named '{self.name()}' has a missing or wrong parameter",
|
||||
f"The '{self.cmd()}' test item named '{self.name()}' has an unexpected loading error: {e}",
|
||||
self.seqFilename(),
|
||||
)
|
||||
) from e
|
||||
|
||||
self.result = TestResult(self, TestValue.FAILURE, "Failure by default")
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
from interpreter.test_items.test_item import (TestItem, test_run)
|
||||
from interpreter.test_items.test_result import TestValue
|
||||
from lib.tum_except import ETUMSyntaxError
|
||||
from lib.tum_except import ETUMSyntaxError, item_load_context
|
||||
import libs.testium as tm
|
||||
from interpreter.utils.constants import TestItemType as cst
|
||||
from interpreter.utils.eval import evaluate
|
||||
@@ -15,21 +15,16 @@ class TestItemCheckValue(TestItem):
|
||||
super().__init__(dict_item, parent, status_queue, filename=filename)
|
||||
self._type = cst.TYPE_CHECK
|
||||
self.is_container = False
|
||||
try:
|
||||
with item_load_context(self.cmd(), self.name(), self.seqFilename()):
|
||||
self._action_list = self._prms.getParamAll('steps', default=[], required=False)
|
||||
if len(self._action_list) > 0:
|
||||
tm.print_warn("'steps' argument of check test item is deprecated and is replaced by 'values'")
|
||||
self._action_list += self._prms.getParamAll('values', default=[], required=False)
|
||||
if len(self._action_list) <= 0:
|
||||
raise ETUMSyntaxError(
|
||||
f" The '{self.cmd()}' test item named '{self.name()}' must have a 'values' parameter",
|
||||
f"Missing required 'values' parameter",
|
||||
self.seqFilename()
|
||||
)
|
||||
except:
|
||||
raise ETUMSyntaxError(
|
||||
f"The '{self.cmd()}' test item named '{self.name()}' (a child of: '{self.parent().name()}') has a missing or wrong parameter",
|
||||
self.seqFilename(),
|
||||
)
|
||||
|
||||
@test_run
|
||||
def execute(self):
|
||||
|
||||
@@ -4,7 +4,7 @@ from interpreter.test_items.test_item import TestItem, test_run
|
||||
from interpreter.test_items.test_result import TestResult, TestValue
|
||||
from interpreter.test_items.dialog_choices_files import choices_dialog
|
||||
import libs.testium as tm
|
||||
from lib.tum_except import ETUMSyntaxError
|
||||
from lib.tum_except import ETUMSyntaxError, item_load_context
|
||||
from interpreter.utils.constants import TestItemType as cst
|
||||
|
||||
|
||||
@@ -14,17 +14,10 @@ class TestItemChoicesDialog(TestItem):
|
||||
super().__init__(dict_item, parent, status_queue, filename=filename)
|
||||
self._type = cst.TYPE_CHOICES_DLG
|
||||
self.is_container = False
|
||||
try:
|
||||
with item_load_context(self.cmd(), self.name(), self.seqFilename()):
|
||||
self._question = self._prms.getParam("question", required=True)
|
||||
self._choices = self._prms.getParam("choices", required=True)
|
||||
self._default_icon = self._prms.getParam(
|
||||
"icon", required=False, default=None
|
||||
)
|
||||
except:
|
||||
raise ETUMSyntaxError(
|
||||
f"The '{self.cmd()}' test item named '{self.name()}' (a child of: '{self.parent().name()}') has a missing or wrong parameter",
|
||||
self.seqFilename()
|
||||
)
|
||||
self._default_icon = self._prms.getParam("icon", required=False, default=None)
|
||||
|
||||
@test_run
|
||||
def execute(self):
|
||||
|
||||
@@ -7,7 +7,7 @@ from interpreter.test_items.test_result import TestResult, TestValue
|
||||
from interpreter.test_items.dialog_image_files import dialog_image
|
||||
import libs.testium as tm
|
||||
from interpreter.utils.constants import TestItemType as cst
|
||||
from lib.tum_except import ETUMSyntaxError
|
||||
from lib.tum_except import ETUMSyntaxError, item_load_context
|
||||
|
||||
|
||||
class TestItemImageDialog(TestItem):
|
||||
@@ -20,14 +20,9 @@ class TestItemImageDialog(TestItem):
|
||||
super().__init__(dict_item, parent, status_queue, filename=filename)
|
||||
self._type = cst.TYPE_IMAGE_DLG
|
||||
self.is_container = False
|
||||
try:
|
||||
with item_load_context(self.cmd(), self.name(), self.seqFilename()):
|
||||
self._question = self._prms.getParam("question", required=True)
|
||||
self._filename = self._prms.getParam("filename", required=True)
|
||||
except:
|
||||
raise ETUMSyntaxError(
|
||||
f"The '{self.cmd()}' test item named '{self.name()}' has a missing or wrong parameter",
|
||||
self.seqFilename(),
|
||||
)
|
||||
|
||||
@test_run
|
||||
def execute(self):
|
||||
|
||||
@@ -5,7 +5,7 @@ import time
|
||||
|
||||
from interpreter.test_items.test_item import (TestItem, test_run)
|
||||
from interpreter.test_items.test_result import (TestResult, TestValue)
|
||||
from lib.tum_except import ETUMSyntaxError
|
||||
from lib.tum_except import ETUMSyntaxError, item_load_context
|
||||
import libs.testium as tm
|
||||
from interpreter.utils.constants import TestItemType as cst
|
||||
|
||||
@@ -19,18 +19,13 @@ class TestItemLet(TestItem):
|
||||
super().__init__(dict_item, parent, status_queue, filename=filename)
|
||||
self._type = cst.TYPE_LET
|
||||
self.is_container = False
|
||||
try:
|
||||
with item_load_context(self.cmd(), self.name(), self.seqFilename()):
|
||||
self._values_list = self._prms.getParamAll('values', default=[], required=False)
|
||||
if len(self._values_list) <= 0:
|
||||
raise ETUMSyntaxError(
|
||||
f"The '{self.cmd()}' test item named '{self.name()}' must have a 'values' parameter",
|
||||
f"Missing required 'values' parameter",
|
||||
self.seqFilename(),
|
||||
)
|
||||
except:
|
||||
raise ETUMSyntaxError(
|
||||
f"The '{self.cmd()}' test item named '{self.name()}' has a missing or wrong parameter",
|
||||
self.seqFilename(),
|
||||
)
|
||||
|
||||
@test_run
|
||||
def execute(self):
|
||||
|
||||
@@ -4,7 +4,7 @@ import traceback
|
||||
import pprint
|
||||
import textwrap
|
||||
|
||||
from lib.tum_except import ETUMSyntaxError, ETUMRuntimeError
|
||||
from lib.tum_except import ETUMSyntaxError, ETUMRuntimeError, item_load_context
|
||||
from interpreter.test_items.test_item import TestItem, test_run
|
||||
from interpreter.test_items.test_result import TestValue
|
||||
import libs.testium as tm
|
||||
@@ -26,16 +26,11 @@ class TestItemLuaFunc(TestItem):
|
||||
super().__init__(dict_item, parent, status_queue, filename=filename)
|
||||
self._type = cst.TYPE_LUA_FUNCTION
|
||||
self.is_container = False
|
||||
try:
|
||||
with item_load_context(self.cmd(), self.name(), self.seqFilename()):
|
||||
self.file_name = self._prms.getParam("file", required=True)
|
||||
self.func_name = self._prms.getParam("func_name", required=True)
|
||||
self.params = self._prms.getParamAll("param")
|
||||
self._context_id = self._prms.getParam("context_id", default=None, processed=False)
|
||||
except:
|
||||
raise ETUMSyntaxError(
|
||||
f"The '{self.cmd()}' test item named '{self.name()}' (child of '{self.parent.name()}') has a missing or wrong parameter",
|
||||
self.seqFilename(),
|
||||
)
|
||||
self._lua_func_proc = LuaFuncExecEngine(tm.gd("lua_bin", ""), api_request, 10)
|
||||
|
||||
def _get_engine(self):
|
||||
|
||||
@@ -6,7 +6,7 @@ from interpreter.test_items.test_item import (TestItem, test_run)
|
||||
from interpreter.test_items.test_result import (TestValue)
|
||||
from interpreter.test_items.dialog_msg_files import msg_dialog
|
||||
from interpreter.utils.constants import TestItemType as cst
|
||||
from lib.tum_except import ETUMSyntaxError
|
||||
from lib.tum_except import ETUMSyntaxError, item_load_context
|
||||
|
||||
class TestItemMsgDialog(TestItem):
|
||||
"""dialog_message item usage.
|
||||
@@ -17,13 +17,8 @@ class TestItemMsgDialog(TestItem):
|
||||
super().__init__(dict_item, parent, status_queue, filename=filename)
|
||||
self._type = cst.TYPE_MESSAGE_DLG
|
||||
self.is_container = False
|
||||
try:
|
||||
self._question = self._prms.getParam('question', required = True)
|
||||
except:
|
||||
raise ETUMSyntaxError(
|
||||
f"The '{self.cmd()}' test item named '{self.name()}' has a missing or wrong parameter",
|
||||
self.seqFilename(),
|
||||
)
|
||||
with item_load_context(self.cmd(), self.name(), self.seqFilename()):
|
||||
self._question = self._prms.getParam('question', required=True)
|
||||
|
||||
@test_run
|
||||
def execute(self):
|
||||
|
||||
@@ -5,7 +5,7 @@ from multiprocessing import Process, Pipe
|
||||
from interpreter.test_items.test_item import (TestItem, test_run)
|
||||
from interpreter.test_items.test_result import (TestResult, TestValue)
|
||||
from interpreter.test_items.dialog_note_files import test_dialog
|
||||
from lib.tum_except import ETUMSyntaxError
|
||||
from lib.tum_except import ETUMSyntaxError, item_load_context
|
||||
import libs.testium as tm
|
||||
from interpreter.utils.constants import TestItemType as cst
|
||||
|
||||
@@ -15,13 +15,8 @@ class TestItemNoteDialog(TestItem):
|
||||
super().__init__(dict_item, parent, status_queue, filename=filename)
|
||||
self._type = cst.TYPE_NOTE_DLG
|
||||
self.is_container = False
|
||||
try:
|
||||
self._question = self._prms.getParam('question', required = True)
|
||||
except:
|
||||
raise ETUMSyntaxError(
|
||||
f"The '{self.cmd()}' test item named '{self.name()}' has a missing or wrong parameter",
|
||||
self.seqFilename(),
|
||||
)
|
||||
with item_load_context(self.cmd(), self.name(), self.seqFilename()):
|
||||
self._question = self._prms.getParam('question', required=True)
|
||||
|
||||
@test_run
|
||||
def execute(self):
|
||||
|
||||
@@ -4,7 +4,7 @@ import time
|
||||
import pprint
|
||||
import textwrap
|
||||
|
||||
from lib.tum_except import ETUMSyntaxError, ETUMRuntimeError
|
||||
from lib.tum_except import ETUMSyntaxError, ETUMRuntimeError, item_load_context
|
||||
from interpreter.test_items.test_item import TestItem, test_run
|
||||
from interpreter.test_items.test_result import TestValue
|
||||
import libs.testium as tm
|
||||
@@ -26,16 +26,11 @@ class TestItemPyFunc(TestItem):
|
||||
super().__init__(dict_item, parent, status_queue, filename=filename)
|
||||
self._type = cst.TYPE_PY_FUNCTION
|
||||
self.is_container = False
|
||||
try:
|
||||
with item_load_context(self.cmd(), self.name(), self.seqFilename()):
|
||||
self.file_name = self._prms.getParam("file", required=True)
|
||||
self.func_name = self._prms.getParam("func_name", required=True)
|
||||
self.params = self._prms.getParamAll("param")
|
||||
self._context_id = self._prms.getParam("context_id", default=None, processed=False)
|
||||
except:
|
||||
raise ETUMSyntaxError(
|
||||
f"The '{self.cmd()}' test item named '{self.name()}' (child of '{self.parent.name()}') has a missing or wrong parameter",
|
||||
self.seqFilename(),
|
||||
)
|
||||
self._py_func_proc = PyFuncExecEngine(tm.gd("python_bin", ""), api_request, 10)
|
||||
|
||||
def _get_engine(self):
|
||||
|
||||
@@ -7,7 +7,7 @@ from PySide6.QtWidgets import QMessageBox
|
||||
from interpreter.test_items.test_item import (TestItem, test_run)
|
||||
from interpreter.test_items.test_result import (TestResult, TestValue)
|
||||
from interpreter.test_items.dialog_question_files import question_dialog
|
||||
from lib.tum_except import ETUMSyntaxError
|
||||
from lib.tum_except import ETUMSyntaxError, item_load_context
|
||||
from interpreter.utils.constants import TestItemType as cst
|
||||
|
||||
class TestItemQuestionDialog(TestItem):
|
||||
@@ -19,13 +19,8 @@ class TestItemQuestionDialog(TestItem):
|
||||
super().__init__(dict_item, parent, status_queue, filename=filename)
|
||||
self._type = cst.TYPE_QUESTION_DLG
|
||||
self.is_container = False
|
||||
try:
|
||||
self._question = self._prms.getParam('question', required = True)
|
||||
except:
|
||||
raise ETUMSyntaxError(
|
||||
f"The '{self.cmd()}' test item named '{self.name()}' has a missing or wrong parameter",
|
||||
self.seqFilename(),
|
||||
)
|
||||
with item_load_context(self.cmd(), self.name(), self.seqFilename()):
|
||||
self._question = self._prms.getParam('question', required=True)
|
||||
|
||||
@test_run
|
||||
def execute(self):
|
||||
|
||||
@@ -10,7 +10,7 @@ from interpreter.test_items.test_item import (TestItem, test_run)
|
||||
from interpreter.test_items.test_result import (TestValue)
|
||||
import libs.testium as tm
|
||||
from interpreter.utils.constants import TestItemType as cst
|
||||
from lib.tum_except import ETUMSyntaxError, ETUMRuntimeError
|
||||
from lib.tum_except import ETUMSyntaxError, ETUMRuntimeError, item_load_context
|
||||
|
||||
|
||||
def nowInBetween(start, end):
|
||||
@@ -30,7 +30,7 @@ class TestItemRun(TestItem):
|
||||
super().__init__(dict_item, parent, status_queue, filename=filename)
|
||||
self._type = cst.TYPE_RUN
|
||||
self.is_container = False
|
||||
try:
|
||||
with item_load_context(self.cmd(), self.name(), self.seqFilename()):
|
||||
self.tum_fime = self._prms.getParam('tum_fime', required=True)
|
||||
self.param_file = self._prms.getParam('param_file', default='')
|
||||
self.python_bin = self._prms.getParam('python_bin', default='')
|
||||
@@ -40,11 +40,6 @@ class TestItemRun(TestItem):
|
||||
self.start_time = self._prms.getParam('start_time')
|
||||
self.end_time = self._prms.getParam('end_time')
|
||||
self.wait_for_exec = self._prms.getParam('wait_for_exec')
|
||||
except:
|
||||
raise ETUMSyntaxError(
|
||||
f"The '{self.cmd()}' test item named '{self.name()}' has a missing or wrong parameter",
|
||||
self.seqFilename(),
|
||||
)
|
||||
|
||||
@test_run
|
||||
def execute(self):
|
||||
|
||||
@@ -4,7 +4,7 @@ import traceback
|
||||
from functools import wraps
|
||||
|
||||
import libs.testium as tm
|
||||
from lib.tum_except import ETUMSyntaxError
|
||||
from lib.tum_except import ETUMSyntaxError, item_load_context
|
||||
from interpreter.test_items.test_item import TestItem, test_run
|
||||
from interpreter.test_items.test_result import TestResult, TestValue
|
||||
from interpreter.test_items.item_actions import TestItemActions
|
||||
@@ -108,17 +108,12 @@ class TestItemPlotActionPeriodic(TestItemPlotAction):
|
||||
)
|
||||
|
||||
# Periodic function call
|
||||
try:
|
||||
with item_load_context(self.cmd(), self.name(), self.seqFilename()):
|
||||
self.period = self._prms.getParam("period", required=True)
|
||||
self.file_name = self._prms.getParam("file", required=True)
|
||||
self.func_name = self._prms.getParam("func_name", required=True)
|
||||
self.params = self._prms.getParamAll("param")
|
||||
self.post_eval = self._prms.getParam("eval", default="")
|
||||
except:
|
||||
raise ETUMSyntaxError(
|
||||
f"The '{self.cmd()}' test item named '{self.name()}' 'periodic' action settings syntax error",
|
||||
self.seqFilename(),
|
||||
)
|
||||
|
||||
@test_run
|
||||
def execute(self):
|
||||
|
||||
@@ -7,7 +7,7 @@ from interpreter.test_items.test_item import (TestItem, test_run)
|
||||
from interpreter.test_items.test_result import (TestValue)
|
||||
from interpreter.test_items.dialog_sleep_files import dialog_sleep
|
||||
from interpreter.utils.constants import TestItemType as cst
|
||||
from lib.tum_except import ETUMSyntaxError, ETUMRuntimeError
|
||||
from lib.tum_except import ETUMSyntaxError, ETUMRuntimeError, item_load_context
|
||||
|
||||
class TestItemSleep(TestItem):
|
||||
"""sleep item usage.
|
||||
@@ -19,14 +19,9 @@ class TestItemSleep(TestItem):
|
||||
super().__init__(dict_item, parent, status_queue, filename=filename)
|
||||
self._type = cst.TYPE_SLEEP
|
||||
self.is_container = False
|
||||
try:
|
||||
self._timeout = self._prms.getParam('timeout', required = True)
|
||||
with item_load_context(self.cmd(), self.name(), self.seqFilename()):
|
||||
self._timeout = self._prms.getParam('timeout', required=True)
|
||||
self._has_dialog = self._prms.getParam('dialog', default=False)
|
||||
except:
|
||||
raise ETUMSyntaxError(
|
||||
f"The '{self.cmd()}' test item named '{self.name()}' has a missing or wrong parameter",
|
||||
self.seqFilename(),
|
||||
)
|
||||
|
||||
@test_run
|
||||
def execute(self):
|
||||
|
||||
@@ -6,7 +6,7 @@ from interpreter.test_items.test_item import (TestItem, test_run)
|
||||
from interpreter.test_items.test_result import (TestResult, TestValue)
|
||||
from interpreter.test_items.tested_references_files import tested_refs_dialog
|
||||
import libs.testium as tm
|
||||
from lib.tum_except import ETUMSyntaxError
|
||||
from lib.tum_except import ETUMSyntaxError, item_load_context
|
||||
from interpreter.utils.constants import TestItemType as cst
|
||||
|
||||
class TestItemTestedRefsDialog(TestItem):
|
||||
@@ -15,14 +15,9 @@ class TestItemTestedRefsDialog(TestItem):
|
||||
super().__init__(dict_item, parent, status_queue, filename=filename)
|
||||
self._type = cst.TYPE_REFERENCE_DLG
|
||||
self.is_container = False
|
||||
try:
|
||||
with item_load_context(self.cmd(), self.name(), self.seqFilename()):
|
||||
self._question = self._prms.getParam('question', required=True)
|
||||
self._init_values = self._prms.getParamAll('reference', required=False, processed=True)
|
||||
except:
|
||||
raise ETUMSyntaxError(
|
||||
f"The '{self.cmd()}' test item named '{self.name()}' has a missing or wrong parameter",
|
||||
self.seqFilename(),
|
||||
)
|
||||
|
||||
@test_run
|
||||
def execute(self):
|
||||
|
||||
@@ -6,7 +6,7 @@ from interpreter.test_items.test_item import (TestItem, test_run)
|
||||
from interpreter.test_items.test_result import (TestResult, TestValue)
|
||||
from interpreter.test_items.dialog_value_files import test_dialog
|
||||
import libs.testium as tm
|
||||
from lib.tum_except import ETUMSyntaxError
|
||||
from lib.tum_except import ETUMSyntaxError, item_load_context
|
||||
from interpreter.utils.constants import TestItemType as cst
|
||||
|
||||
class TestItemValueDialog(TestItem):
|
||||
@@ -18,14 +18,9 @@ class TestItemValueDialog(TestItem):
|
||||
super().__init__(dict_item, parent, status_queue, filename=filename)
|
||||
self._type = cst.TYPE_VALUE_DLG
|
||||
self.is_container = False
|
||||
try:
|
||||
self._question = self._prms.getParam('question', required = True)
|
||||
with item_load_context(self.cmd(), self.name(), self.seqFilename()):
|
||||
self._question = self._prms.getParam('question', required=True)
|
||||
self._default = self._prms.getParam('default', '')
|
||||
except:
|
||||
raise ETUMSyntaxError(
|
||||
f"The '{self.cmd()}' test item named '{self.name()}' has a missing or wrong parameter",
|
||||
self.seqFilename(),
|
||||
)
|
||||
|
||||
@test_run
|
||||
def execute(self):
|
||||
|
||||
@@ -3,9 +3,7 @@ import datetime
|
||||
from queue import Queue
|
||||
from interpreter.utils.params import expanse
|
||||
import libs.testium as tm
|
||||
from lib.tum_except import (
|
||||
ETUMSyntaxError,
|
||||
)
|
||||
from lib.tum_except import ETUMSyntaxError
|
||||
import interpreter.utils.settings as prefs
|
||||
from interpreter.test_report.test_report import TestReport
|
||||
from interpreter.utils.py_func_exec import PyFuncExecEngine
|
||||
@@ -19,6 +17,17 @@ from interpreter.test_items.item_actions import TestItemActions
|
||||
from interpreter.test_items.test_result import TestValue
|
||||
|
||||
|
||||
def _build_item_path(item) -> str:
|
||||
"""Build a breadcrumb path like 'main > Group > sub-group' from an item to root."""
|
||||
parts = []
|
||||
current = item
|
||||
while current is not None:
|
||||
name = current.name()
|
||||
parts.append(name if name else f"[{current.type()}]")
|
||||
current = current.parent()
|
||||
return " > ".join(reversed(parts))
|
||||
|
||||
|
||||
class TestSet:
|
||||
def __init__(
|
||||
self,
|
||||
@@ -479,12 +488,19 @@ class TestSet:
|
||||
action_name = cst.FOLDED_CHAR + it.item_cmd
|
||||
|
||||
seq_filename = action[action_name]["seq_filename"]
|
||||
item = (it.item_class)(
|
||||
action[action_name],
|
||||
tree_parent,
|
||||
self.status_queue,
|
||||
filename=seq_filename
|
||||
)
|
||||
try:
|
||||
item = (it.item_class)(
|
||||
action[action_name],
|
||||
tree_parent,
|
||||
self.status_queue,
|
||||
filename=seq_filename
|
||||
)
|
||||
except ETUMSyntaxError as e:
|
||||
path = _build_item_path(tree_parent)
|
||||
raise ETUMSyntaxError(
|
||||
f"In: {path}\n{e._message}",
|
||||
e._file or seq_filename,
|
||||
) from e
|
||||
item.is_folded = is_folded
|
||||
child = {}
|
||||
# case where the test item loads itself its descendants
|
||||
|
||||
Reference in New Issue
Block a user