From 9ac4ce73ffbde4c7881b72a10e2b8e62b77cde83 Mon Sep 17 00:00:00 2001 From: appel_c Date: Mon, 2 Dec 2024 16:57:02 +0100 Subject: [PATCH] fix: add cleanup to console, fix tests for user_script --- .../widgets/editors/console/console.py | 21 +++++++++++++++ .../editors/user_script/user_script.py | 13 +++++----- tests/unit_tests/test_user_script.py | 26 +++++++++++-------- 3 files changed, 43 insertions(+), 17 deletions(-) diff --git a/bec_widgets/widgets/editors/console/console.py b/bec_widgets/widgets/editors/console/console.py index b83bc444..9a7a196b 100644 --- a/bec_widgets/widgets/editors/console/console.py +++ b/bec_widgets/widgets/editors/console/console.py @@ -16,6 +16,7 @@ import sys import time import pyte +from bec_lib.logger import bec_logger from pygments.token import Token from pyte.screens import History from qtpy import QtCore, QtGui, QtWidgets @@ -27,6 +28,8 @@ from qtpy.QtWidgets import QApplication, QHBoxLayout, QScrollBar, QSizePolicy from bec_widgets.qt_utils.error_popups import SafeSlot as Slot +logger = bec_logger.logger + ansi_colors = { "black": "#000000", "red": "#CD0000", @@ -361,6 +364,24 @@ class BECConsole(QtWidgets.QWidget): def send_ctrl_c(self, timeout=None): self.term.send_ctrl_c(timeout) + def cleanup(self): + """Cleanup the terminal""" + self.execute_command("\x03") # Ctrl-C + self.execute_command("exit()") + timeout = 5 + interval = 0.1 + timer = 0 + # os.close(self.term.fd) + while self.term.fd is not None: + time.sleep(interval) + timer += interval + if timer > 0.8 * timeout: + logger.warning(f"Terminal still cleaning up after {timer:.1f} seconds") + if timer > timeout: + logger.error(f"Terminal cleanup timed out after {timeout} seconds") + break + self.deleteLater() + cols = pyqtProperty(int, get_cols, set_cols) rows = pyqtProperty(int, get_rows, set_rows) bgcolor = pyqtProperty(QColor, get_bgcolor, set_bgcolor) diff --git a/bec_widgets/widgets/editors/user_script/user_script.py b/bec_widgets/widgets/editors/user_script/user_script.py index 87987d9e..795f0559 100644 --- a/bec_widgets/widgets/editors/user_script/user_script.py +++ b/bec_widgets/widgets/editors/user_script/user_script.py @@ -11,8 +11,7 @@ import bec_lib from bec_qthemes import material_icon from pydantic import BaseModel from pygments.token import Token -from qtpy.QtCore import QSize, Qt, Signal, Slot -from qtpy.QtGui import QColor +from qtpy.QtCore import QSize, Signal, Slot from qtpy.QtWidgets import ( QDialog, QGridLayout, @@ -71,7 +70,7 @@ class EnchancedQTreeWidget(QTreeWidget): """Update the style sheet""" name = __class__.__name__ colors = get_accent_colors() - # pylint: ignore=protected-access + # pylint: disable=protected-access color = colors._palette.midlight().color().name() self.setStyleSheet( f""" @@ -335,6 +334,7 @@ class UserScriptWidget(BECWidget, QWidget): (Token.Prompt, "❯❯"), ) self._console.start() + # Comment to not hide the console for debugging self._console.hide() def init_ui(self): @@ -347,6 +347,7 @@ class UserScriptWidget(BECWidget, QWidget): layout.addWidget(self.button_new_script) self.layout.addWidget(widget) self.layout.addWidget(self.tree_widget) + # Uncomment to show the console for debugging # self.layout.addWidget(self._console) self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) @@ -409,7 +410,6 @@ class UserScriptWidget(BECWidget, QWidget): name = name + ".py" fname = os.path.join(self._base_path, name) # Check if file exists on disk - if os.path.exists(fname): logger.error(f"File {fname} already exists") raise FileExistsError(f"File {fname} already exists") @@ -447,7 +447,7 @@ class UserScriptWidget(BECWidget, QWidget): ) return files - @SafeSlot(popup_error=True) + @SafeSlot() def reload_user_scripts(self, *args, **kwargs): """Reload the user scripts""" self.client.load_all_user_scripts() @@ -536,7 +536,8 @@ if __name__ == "__main__": set_theme("dark") w = QWidget() layout = QVBoxLayout(w) - layout.addWidget(DarkModeButton()) layout.addWidget(UserScriptWidget()) + w.setFixedHeight(400) + w.setFixedWidth(400) w.show() app.exec_() diff --git a/tests/unit_tests/test_user_script.py b/tests/unit_tests/test_user_script.py index 5a5dd579..323bc5d1 100644 --- a/tests/unit_tests/test_user_script.py +++ b/tests/unit_tests/test_user_script.py @@ -17,17 +17,20 @@ def dummy_script_with_args(arg1: str, arg2: int = 0): pass -SCRIPTS = { - "dummy_script": {"cls": dummy_script, "fname": "/dummy_path_home_scripts/home_testing.py"}, - "dummy_script_with_args": { - "cls": dummy_script_with_args, - "fname": "/dummy_path_bec_lib_scripts/bec_testing.py", - }, -} +@pytest.fixture +def SCRIPTS(tmp_path): + """Create dummy script files""" + home_script = f"{tmp_path}/dummy_path_home_scripts/home_testing.py" + bec_script = f"{tmp_path}/dummy_path_bec_lib_scripts/bec_testing.py" + rtr = { + "dummy_script": {"cls": dummy_script, "fname": home_script}, + "dummy_script_with_args": {"cls": dummy_script_with_args, "fname": bec_script}, + } + return rtr @pytest.fixture -def user_script_widget(qtbot, mocked_client): +def user_script_widget(SCRIPTS, qtbot, mocked_client): mocked_client._scripts = SCRIPTS files = { "USER": [SCRIPTS["dummy_script"]["fname"]], @@ -43,7 +46,7 @@ def user_script_widget(qtbot, mocked_client): yield widget -def test_user_script_widget_start_up(user_script_widget): +def test_user_script_widget_start_up(SCRIPTS, user_script_widget): """Test init the user_script widget with dummy scripts from above""" assert user_script_widget.tree_widget.columnCount() == 2 assert len(user_script_widget.tree_widget.children()[0].children()) == 6 @@ -71,11 +74,12 @@ def test_user_script_widget_start_up(user_script_widget): ] -def test_handle_open_script(user_script_widget): +def test_handle_open_script(SCRIPTS, user_script_widget): """Test handling open script""" with mock.patch.object(user_script_widget, "open_script") as mock_open_script: user_script_widget.handle_edit_button_clicked("home_testing") - mock_open_script.assert_called_once_with("/dummy_path_home_scripts/home_testing.py") + fp = SCRIPTS["dummy_script"]["fname"] + mock_open_script.assert_called_once_with(fp) def test_open_script(user_script_widget):