0
0
mirror of https://github.com/bec-project/bec_widgets.git synced 2025-07-14 03:31:50 +02:00

fix: add cleanup to console, fix tests for user_script

This commit is contained in:
2024-12-02 16:57:02 +01:00
parent 710d7229a7
commit 9ac4ce73ff
3 changed files with 43 additions and 17 deletions

View File

@ -16,6 +16,7 @@ import sys
import time import time
import pyte import pyte
from bec_lib.logger import bec_logger
from pygments.token import Token from pygments.token import Token
from pyte.screens import History from pyte.screens import History
from qtpy import QtCore, QtGui, QtWidgets 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 from bec_widgets.qt_utils.error_popups import SafeSlot as Slot
logger = bec_logger.logger
ansi_colors = { ansi_colors = {
"black": "#000000", "black": "#000000",
"red": "#CD0000", "red": "#CD0000",
@ -361,6 +364,24 @@ class BECConsole(QtWidgets.QWidget):
def send_ctrl_c(self, timeout=None): def send_ctrl_c(self, timeout=None):
self.term.send_ctrl_c(timeout) 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) cols = pyqtProperty(int, get_cols, set_cols)
rows = pyqtProperty(int, get_rows, set_rows) rows = pyqtProperty(int, get_rows, set_rows)
bgcolor = pyqtProperty(QColor, get_bgcolor, set_bgcolor) bgcolor = pyqtProperty(QColor, get_bgcolor, set_bgcolor)

View File

@ -11,8 +11,7 @@ import bec_lib
from bec_qthemes import material_icon from bec_qthemes import material_icon
from pydantic import BaseModel from pydantic import BaseModel
from pygments.token import Token from pygments.token import Token
from qtpy.QtCore import QSize, Qt, Signal, Slot from qtpy.QtCore import QSize, Signal, Slot
from qtpy.QtGui import QColor
from qtpy.QtWidgets import ( from qtpy.QtWidgets import (
QDialog, QDialog,
QGridLayout, QGridLayout,
@ -71,7 +70,7 @@ class EnchancedQTreeWidget(QTreeWidget):
"""Update the style sheet""" """Update the style sheet"""
name = __class__.__name__ name = __class__.__name__
colors = get_accent_colors() colors = get_accent_colors()
# pylint: ignore=protected-access # pylint: disable=protected-access
color = colors._palette.midlight().color().name() color = colors._palette.midlight().color().name()
self.setStyleSheet( self.setStyleSheet(
f""" f"""
@ -335,6 +334,7 @@ class UserScriptWidget(BECWidget, QWidget):
(Token.Prompt, ""), (Token.Prompt, ""),
) )
self._console.start() self._console.start()
# Comment to not hide the console for debugging
self._console.hide() self._console.hide()
def init_ui(self): def init_ui(self):
@ -347,6 +347,7 @@ class UserScriptWidget(BECWidget, QWidget):
layout.addWidget(self.button_new_script) layout.addWidget(self.button_new_script)
self.layout.addWidget(widget) self.layout.addWidget(widget)
self.layout.addWidget(self.tree_widget) self.layout.addWidget(self.tree_widget)
# Uncomment to show the console for debugging
# self.layout.addWidget(self._console) # self.layout.addWidget(self._console)
self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
@ -409,7 +410,6 @@ class UserScriptWidget(BECWidget, QWidget):
name = name + ".py" name = name + ".py"
fname = os.path.join(self._base_path, name) fname = os.path.join(self._base_path, name)
# Check if file exists on disk # Check if file exists on disk
if os.path.exists(fname): if os.path.exists(fname):
logger.error(f"File {fname} already exists") logger.error(f"File {fname} already exists")
raise FileExistsError(f"File {fname} already exists") raise FileExistsError(f"File {fname} already exists")
@ -447,7 +447,7 @@ class UserScriptWidget(BECWidget, QWidget):
) )
return files return files
@SafeSlot(popup_error=True) @SafeSlot()
def reload_user_scripts(self, *args, **kwargs): def reload_user_scripts(self, *args, **kwargs):
"""Reload the user scripts""" """Reload the user scripts"""
self.client.load_all_user_scripts() self.client.load_all_user_scripts()
@ -536,7 +536,8 @@ if __name__ == "__main__":
set_theme("dark") set_theme("dark")
w = QWidget() w = QWidget()
layout = QVBoxLayout(w) layout = QVBoxLayout(w)
layout.addWidget(DarkModeButton())
layout.addWidget(UserScriptWidget()) layout.addWidget(UserScriptWidget())
w.setFixedHeight(400)
w.setFixedWidth(400)
w.show() w.show()
app.exec_() app.exec_()

View File

@ -17,17 +17,20 @@ def dummy_script_with_args(arg1: str, arg2: int = 0):
pass pass
SCRIPTS = { @pytest.fixture
"dummy_script": {"cls": dummy_script, "fname": "/dummy_path_home_scripts/home_testing.py"}, def SCRIPTS(tmp_path):
"dummy_script_with_args": { """Create dummy script files"""
"cls": dummy_script_with_args, home_script = f"{tmp_path}/dummy_path_home_scripts/home_testing.py"
"fname": "/dummy_path_bec_lib_scripts/bec_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 @pytest.fixture
def user_script_widget(qtbot, mocked_client): def user_script_widget(SCRIPTS, qtbot, mocked_client):
mocked_client._scripts = SCRIPTS mocked_client._scripts = SCRIPTS
files = { files = {
"USER": [SCRIPTS["dummy_script"]["fname"]], "USER": [SCRIPTS["dummy_script"]["fname"]],
@ -43,7 +46,7 @@ def user_script_widget(qtbot, mocked_client):
yield widget 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""" """Test init the user_script widget with dummy scripts from above"""
assert user_script_widget.tree_widget.columnCount() == 2 assert user_script_widget.tree_widget.columnCount() == 2
assert len(user_script_widget.tree_widget.children()[0].children()) == 6 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""" """Test handling open script"""
with mock.patch.object(user_script_widget, "open_script") as mock_open_script: with mock.patch.object(user_script_widget, "open_script") as mock_open_script:
user_script_widget.handle_edit_button_clicked("home_testing") 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): def test_open_script(user_script_widget):