Extract of a service layer for TestSetController
This commit is contained in:
71
src/testium/main_win/test_controller_service.py
Normal file
71
src/testium/main_win/test_controller_service.py
Normal file
@@ -0,0 +1,71 @@
|
||||
from interpreter.utils.test_ctrl import TestSetController
|
||||
|
||||
|
||||
class TestControllerService:
|
||||
"""Typed interface over TestSetController, decoupling the UI from raw RPC strings."""
|
||||
|
||||
def __init__(self, controller: TestSetController) -> None:
|
||||
self._ctrl = controller
|
||||
|
||||
# --- Lifecycle ---
|
||||
|
||||
def stop(self) -> None:
|
||||
self._ctrl.control("stop")
|
||||
|
||||
def close(self) -> None:
|
||||
self._ctrl.control("close")
|
||||
|
||||
def execute(self) -> None:
|
||||
self._ctrl.control("execute")
|
||||
|
||||
def loaded(self, timeout: float = None) -> bool:
|
||||
return self._ctrl.control("loaded", timeout=timeout)
|
||||
|
||||
def clear(self) -> None:
|
||||
self._ctrl.clear()
|
||||
|
||||
# --- Execution control ---
|
||||
|
||||
def pause(self) -> None:
|
||||
self._ctrl.control("pause")
|
||||
|
||||
def cont(self) -> None:
|
||||
self._ctrl.control("cont")
|
||||
|
||||
# --- Breakpoints ---
|
||||
|
||||
def add_breakpoint(self, item_id) -> None:
|
||||
self._ctrl.control("add_breakpoint", item_id=item_id)
|
||||
|
||||
def del_breakpoint(self, item_id) -> None:
|
||||
self._ctrl.control("del_breakpoint", item_id=item_id)
|
||||
|
||||
# --- Tree data ---
|
||||
|
||||
def tree(self) -> dict:
|
||||
return self._ctrl.control("tree")
|
||||
|
||||
# --- Item state ---
|
||||
|
||||
def get_enabled_state(self, item_id) -> bool:
|
||||
return self._ctrl.control("enabled_state", item_id=item_id)
|
||||
|
||||
def set_enabled_state(self, item_id, state: bool, unitary: bool = False) -> None:
|
||||
self._ctrl.control("set_enabled_state", item_id=item_id, enabled_state=state, unitary=unitary)
|
||||
|
||||
def check_uncheck_all(self, checked: bool) -> None:
|
||||
self._ctrl.control("check_uncheck_all", checked=checked)
|
||||
|
||||
def get_skipped_state(self, item_id) -> bool:
|
||||
return self._ctrl.control("skipped_state", item_id=item_id)
|
||||
|
||||
# --- Configuration ---
|
||||
|
||||
def process_param(self, param: str) -> str:
|
||||
return self._ctrl.control("process_param", param=param)
|
||||
|
||||
def set_report(self, rep_path: str, rep_type: str, pattern: list) -> None:
|
||||
self._ctrl.control("report", rep_path=rep_path, rep_type=rep_type, pattern=pattern)
|
||||
|
||||
def set_test_outputs(self, outputs: list) -> None:
|
||||
self._ctrl.control("set_test_outputs", outputs=outputs)
|
||||
@@ -11,7 +11,7 @@ from time import (time)
|
||||
|
||||
from main_win.test_tree_items.common import (TEST_COLS, TEST_COLS_WITH_TIME)
|
||||
from lib.tum_except import (ETUMFileError, ETUMSyntaxError)
|
||||
from interpreter.utils.test_ctrl import TestSetController
|
||||
from main_win.test_controller_service import TestControllerService
|
||||
from main_win.test_tree_items.test_tree_git import QTestTreeItemGit
|
||||
|
||||
# to be removed in the future and replaced by a more "sexy" mechanism
|
||||
@@ -122,11 +122,11 @@ class QTestTree(QTreeWidget):
|
||||
|
||||
self.header().sectionResized.connect(self.resized)
|
||||
|
||||
def updateTestSetItemState(self, tree_item, tst_ctrl: TestSetController, state, unitary=False):
|
||||
def updateTestSetItemState(self, tree_item, tst_ctrl: TestControllerService, state, unitary=False):
|
||||
id = tree_item.id
|
||||
tst_ctrl.control("set_enabled_state", item_id=id, enabled_state=state, unitary=unitary)
|
||||
tst_ctrl.set_enabled_state(id, state, unitary=unitary)
|
||||
|
||||
def updateTreeCheckState(self, tree_item, tst_ctrl: TestSetController):
|
||||
def updateTreeCheckState(self, tree_item, tst_ctrl: TestControllerService):
|
||||
# treat the case of the invisible root
|
||||
if tree_item is self.root:
|
||||
for i in range(self.root.childCount()):
|
||||
@@ -137,9 +137,9 @@ class QTestTree(QTreeWidget):
|
||||
self.updateTestSetItemState(tree_item, tst_ctrl, state)
|
||||
self.synchronizeEnabledState(tst_ctrl)
|
||||
|
||||
def checkUncheckAll(self, tst_ctrl: TestSetController, isChecked):
|
||||
def checkUncheckAll(self, tst_ctrl: TestControllerService, isChecked):
|
||||
# test_set.enableDisableAll(test_set.rootItem(), isChecked)
|
||||
tst_ctrl.control("check_uncheck_all", checked=isChecked)
|
||||
tst_ctrl.check_uncheck_all(isChecked)
|
||||
self.synchronizeEnabledState(tst_ctrl)
|
||||
|
||||
def __foldRecursively(self, tree_item, is_fold):
|
||||
@@ -158,10 +158,10 @@ class QTestTree(QTreeWidget):
|
||||
def foldAll(self, is_fold):
|
||||
self.__foldRecursively(self.root, is_fold)
|
||||
|
||||
def __synchronizeEnabledStateRecursively(self, tree_item, tst_ctrl: TestSetController):
|
||||
def __synchronizeEnabledStateRecursively(self, tree_item, tst_ctrl: TestControllerService):
|
||||
for i in range(tree_item.childCount()):
|
||||
id = tree_item.child(i).id
|
||||
checked = tst_ctrl.control("enabled_state", item_id=id)
|
||||
checked = tst_ctrl.get_enabled_state(id)
|
||||
if checked:
|
||||
tree_item.child(i).setCheckState(self.cols['name']['index'],
|
||||
Qt.Checked)
|
||||
@@ -171,14 +171,14 @@ class QTestTree(QTreeWidget):
|
||||
self.__synchronizeEnabledStateRecursively(
|
||||
tree_item.child(i), tst_ctrl)
|
||||
|
||||
def updateTreeSkipState(self, tst_ctrl: TestSetController):
|
||||
def updateTreeSkipState(self, tst_ctrl: TestControllerService):
|
||||
self.__updateTreeSkipStateRecursively(self.root, tst_ctrl)
|
||||
|
||||
def __updateTreeSkipStateRecursively(self, tree_item, tst_ctrl: TestSetController):
|
||||
def __updateTreeSkipStateRecursively(self, tree_item, tst_ctrl: TestControllerService):
|
||||
for i in range(tree_item.childCount()):
|
||||
id = tree_item.child(i).id
|
||||
# skipped = test_set.getSkippedState(id)
|
||||
skipped = tst_ctrl.control("skipped_state", item_id=id)
|
||||
skipped = tst_ctrl.get_skipped_state(id)
|
||||
if skipped:
|
||||
tree_item.child(i).setDisabled(True)
|
||||
tree_item.child(i).setExpanded(False)
|
||||
@@ -195,7 +195,7 @@ class QTestTree(QTreeWidget):
|
||||
tree_item.child(i)._is_skipped = True
|
||||
self.__skipRecursively(tree_item.child(i))
|
||||
|
||||
def synchronizeEnabledState(self, tst_ctrl: TestSetController):
|
||||
def synchronizeEnabledState(self, tst_ctrl: TestControllerService):
|
||||
self.__synchronizeEnabledStateRecursively(self.root, tst_ctrl)
|
||||
|
||||
def __enableRecursively(self, tree_item):
|
||||
@@ -347,7 +347,7 @@ class QTestTree(QTreeWidget):
|
||||
if root.child(i).childCount() > 0:
|
||||
self.addCheckBoxes(root.child(i))
|
||||
|
||||
def showCheckBoxes(self, checklist, tst_ctrl: TestSetController):
|
||||
def showCheckBoxes(self, checklist, tst_ctrl: TestControllerService):
|
||||
self.addCheckBoxes()
|
||||
self.restoreCheckList(checklist, tst_ctrl)
|
||||
|
||||
@@ -382,12 +382,12 @@ class QTestTree(QTreeWidget):
|
||||
checklist.append((i.checkState(0) == Qt.Checked))
|
||||
return checklist
|
||||
|
||||
def restoreCheckList(self, checklist, tst_ctrl: TestSetController):
|
||||
def restoreCheckList(self, checklist, tst_ctrl: TestControllerService):
|
||||
itemlist = reversed(list(self.root))
|
||||
for item in itemlist:
|
||||
state = checklist.pop(len(checklist)-1)
|
||||
if item is not self.root:
|
||||
skipped = tst_ctrl.control("skipped_state", item_id=item.id)
|
||||
skipped = tst_ctrl.get_skipped_state(item.id)
|
||||
if skipped:
|
||||
item.setDisabled(True)
|
||||
for i in range(item.childCount()):
|
||||
|
||||
@@ -39,6 +39,7 @@ from main_win.test_run.thread_output import ThreadTestOutput
|
||||
from lib.string_queue import StringQueue
|
||||
from interpreter.process import TestProcess
|
||||
from interpreter.utils.test_ctrl import TestSetController
|
||||
from main_win.test_controller_service import TestControllerService
|
||||
from interpreter.utils.icons import icon_prefix
|
||||
|
||||
from main_win.test_run.outlog import OutLog
|
||||
@@ -181,6 +182,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||
self.debug = debug
|
||||
self.test_proc = None
|
||||
self.ts_controller = None
|
||||
self.test_service = None
|
||||
self.threadTestStatus = None
|
||||
self._test_started = False
|
||||
self._test_paused = False
|
||||
@@ -380,7 +382,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||
checkList = prefs.settings.value(prefs.SettingsItem("checkList", list), [])
|
||||
if checkList is not None:
|
||||
if len(checkList) == self.treeTests.getItemCount():
|
||||
self.treeTests.restoreCheckList(checkList, self.ts_controller)
|
||||
self.treeTests.restoreCheckList(checkList, self.test_service)
|
||||
|
||||
else:
|
||||
tm.print_info(
|
||||
@@ -436,11 +438,13 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||
and self.test_proc.is_alive()
|
||||
and (self.ts_controller is not None)
|
||||
):
|
||||
self.ts_controller.control("stop")
|
||||
self.ts_controller.control("close")
|
||||
self.test_service.stop()
|
||||
self.test_service.close()
|
||||
self.test_proc.join()
|
||||
del self.test_proc
|
||||
self.test_proc = None
|
||||
del self.test_service
|
||||
self.test_service = None
|
||||
del self.ts_controller
|
||||
self.ts_controller = None
|
||||
|
||||
@@ -466,12 +470,12 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||
# Test to be paused
|
||||
if self._test_started:
|
||||
if not self._test_paused:
|
||||
self.ts_controller.control("pause")
|
||||
self.test_service.pause()
|
||||
self.startPauseTimer()
|
||||
else:
|
||||
|
||||
# Test to be continued
|
||||
self.ts_controller.control("cont")
|
||||
self.test_service.cont()
|
||||
self.timerPause.stop()
|
||||
self.timerPause.state = False
|
||||
self.on_timerPause()
|
||||
@@ -488,9 +492,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||
try:
|
||||
if not os.path.isabs(log_file):
|
||||
default_path = prefs.settings.log_path
|
||||
default_path = self.ts_controller.control(
|
||||
"process_param", param=default_path
|
||||
)
|
||||
default_path = self.test_service.process_param(default_path)
|
||||
log_file = os.path.join(default_path, log_file)
|
||||
# if the directory does not exist
|
||||
if not os.path.exists(os.path.dirname(log_file)):
|
||||
@@ -521,15 +523,8 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||
self.logFileName = self.logFileHandler.name
|
||||
|
||||
# Report file definition
|
||||
rep_file = self.ts_controller.control(
|
||||
"process_param", param=self.reportFileName
|
||||
)
|
||||
self.ts_controller.control(
|
||||
"report",
|
||||
rep_path=rep_file,
|
||||
rep_type=self.report_type,
|
||||
pattern=self.report_pattern,
|
||||
)
|
||||
rep_file = self.test_service.process_param(self.reportFileName)
|
||||
self.test_service.set_report(rep_file, self.report_type, self.report_pattern)
|
||||
self.adaptInterfaceDuringTest()
|
||||
self.treeTests.clearAllStatus()
|
||||
try:
|
||||
@@ -539,9 +534,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||
self.timer.setInterval(100)
|
||||
self.timer.start()
|
||||
# Add the log file to the std test_outputs
|
||||
self.ts_controller.control("set_test_outputs", outputs=[self.logFileName])
|
||||
self.test_service.set_test_outputs([self.logFileName])
|
||||
# Launch the test
|
||||
self.ts_controller.control("execute")
|
||||
self.test_service.execute()
|
||||
except:
|
||||
print(traceback.format_exc())
|
||||
self.restoreInterfaceAfterTest()
|
||||
@@ -566,7 +561,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||
|
||||
@Slot()
|
||||
def on_actionStop_test_triggered(self):
|
||||
self.ts_controller.control("stop")
|
||||
self.test_service.stop()
|
||||
|
||||
def save_settings(self):
|
||||
prefs.settings.set_value(
|
||||
@@ -709,9 +704,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||
self.disconnect_signals()
|
||||
try:
|
||||
if state == Qt.Checked:
|
||||
self.treeTests.checkUncheckAll(self.ts_controller, True)
|
||||
self.treeTests.checkUncheckAll(self.test_service, True)
|
||||
elif state == Qt.Unchecked:
|
||||
self.treeTests.checkUncheckAll(self.ts_controller, False)
|
||||
self.treeTests.checkUncheckAll(self.test_service, False)
|
||||
finally:
|
||||
self.reconnect_signals()
|
||||
|
||||
@@ -719,7 +714,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||
self.checkSelect.setCheckState(Qt.PartiallyChecked)
|
||||
self.disconnect_signals()
|
||||
try:
|
||||
self.treeTests.updateTreeCheckState(item, self.ts_controller)
|
||||
self.treeTests.updateTreeCheckState(item, self.test_service)
|
||||
finally:
|
||||
self.reconnect_signals()
|
||||
|
||||
@@ -772,9 +767,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||
isBrkpointCol = item.setBreakpointIfCol(col)
|
||||
if isBrkpointCol:
|
||||
if item.isBreakpoint():
|
||||
self.ts_controller.control("add_breakpoint", item_id=item.id)
|
||||
self.test_service.add_breakpoint(item.id)
|
||||
else:
|
||||
self.ts_controller.control("del_breakpoint", item_id=item.id)
|
||||
self.test_service.del_breakpoint(item.id)
|
||||
return
|
||||
|
||||
s = sys.platform
|
||||
@@ -789,9 +784,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||
item = self.treeTests.currentItem()
|
||||
add_breakpoint = item.setBreakpoint()
|
||||
if add_breakpoint:
|
||||
self.ts_controller.control("add_breakpoint", item_id=item.id)
|
||||
self.test_service.add_breakpoint(item.id)
|
||||
else:
|
||||
self.ts_controller.control("del_breakpoint", item_id=item.id)
|
||||
self.test_service.del_breakpoint(item.id)
|
||||
|
||||
def on_F1Pressed(self):
|
||||
item = self.treeTests.currentItem()
|
||||
@@ -919,7 +914,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||
else:
|
||||
# production mode
|
||||
if hasattr(self, "treeTests"):
|
||||
self.treeTests.checkUncheckAll(self.ts_controller, True)
|
||||
self.treeTests.checkUncheckAll(self.test_service, True)
|
||||
self.disconnect_signals()
|
||||
self.treeTests.removeCheckBoxes()
|
||||
self.reconnect_signals()
|
||||
@@ -1005,6 +1000,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||
|
||||
self.testFile = None
|
||||
self.ts_controller = TestSetController()
|
||||
self.test_service = TestControllerService(self.ts_controller)
|
||||
self.test_proc = TestProcess(
|
||||
file_name,
|
||||
self.status_queue,
|
||||
@@ -1016,14 +1012,16 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||
self.test_proc.start()
|
||||
while self.test_proc.is_alive():
|
||||
try:
|
||||
if self.ts_controller.control("loaded", timeout=1.0):
|
||||
if self.test_service.loaded(timeout=1.0):
|
||||
break
|
||||
except Empty:
|
||||
self.ts_controller.clear()
|
||||
self.test_service.clear()
|
||||
|
||||
if not self.test_proc.is_alive():
|
||||
del self.test_proc
|
||||
self.test_proc = None
|
||||
del self.test_service
|
||||
self.test_service = None
|
||||
del self.ts_controller
|
||||
self.ts_controller = None
|
||||
|
||||
@@ -1031,13 +1029,13 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||
"Test could not be loaded (test process crashed for any reason)"
|
||||
)
|
||||
|
||||
test_data = self.ts_controller.control("tree")
|
||||
test_data = self.test_service.tree()
|
||||
self.treeTests.clear()
|
||||
self.treeTests.loadTestRecursively(
|
||||
self.treeTests.invisibleRootItem(), test_data
|
||||
)
|
||||
self.treeTests.setFoldDefault()
|
||||
self.treeTests.updateTreeSkipState(self.ts_controller)
|
||||
self.treeTests.updateTreeSkipState(self.test_service)
|
||||
|
||||
self.checkSelect.setChecked(True)
|
||||
self.testFile = file_name
|
||||
@@ -1115,7 +1113,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||
self.logSettingsBox.setEnabled(True)
|
||||
if prefs.settings.show_checkboxes:
|
||||
self.checkSelect.setEnabled(True)
|
||||
self.treeTests.showCheckBoxes(self._checklist, self.ts_controller)
|
||||
self.treeTests.showCheckBoxes(self._checklist, self.test_service)
|
||||
self.checkFold.setEnabled(True)
|
||||
self.treeTests.setChildrenEnabled()
|
||||
self.reconnect_signals()
|
||||
|
||||
Reference in New Issue
Block a user