mirror of
https://github.com/bec-project/bec_widgets.git
synced 2026-07-24 20:23:01 +02:00
fix: add zoom level functionality to BecConsole and related tests
This commit is contained in:
@@ -50,6 +50,7 @@ class _TerminalOwnerInfo:
|
||||
terminal_id: str = ""
|
||||
initialized: bool = False
|
||||
persist_session: bool = False
|
||||
zoom_level: int = 0
|
||||
fallback_holder: QWidget | None = None
|
||||
|
||||
|
||||
@@ -75,20 +76,32 @@ class BecConsoleRegistry:
|
||||
return
|
||||
app.aboutToQuit.connect(self.clear, Qt.ConnectionType.UniqueConnection)
|
||||
|
||||
@staticmethod
|
||||
def _apply_zoom_level(term: BecTerminal, zoom_level: int) -> None:
|
||||
if zoom_level > 0:
|
||||
for _ in range(zoom_level):
|
||||
term.zoom_in()
|
||||
elif zoom_level < 0:
|
||||
for _ in range(-zoom_level):
|
||||
term.zoom_out()
|
||||
|
||||
@staticmethod
|
||||
def _new_terminal_info(console: BecConsole) -> _TerminalOwnerInfo:
|
||||
term = _BecTermClass()
|
||||
BecConsoleRegistry._apply_zoom_level(term, console.default_zoom_level)
|
||||
return _TerminalOwnerInfo(
|
||||
registered_console_ids={console.console_id},
|
||||
owner_console_id=console.console_id,
|
||||
instance=term,
|
||||
terminal_id=console.terminal_id,
|
||||
persist_session=console.persist_terminal_session,
|
||||
zoom_level=console.default_zoom_level,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _replace_terminal(info: _TerminalOwnerInfo, console: BecConsole) -> None:
|
||||
info.instance = _BecTermClass()
|
||||
BecConsoleRegistry._apply_zoom_level(info.instance, info.zoom_level)
|
||||
info.initialized = False
|
||||
info.owner_console_id = console.console_id
|
||||
info.registered_console_ids.add(console.console_id)
|
||||
@@ -334,6 +347,27 @@ class BecConsoleRegistry:
|
||||
return None
|
||||
return info.instance
|
||||
|
||||
def change_zoom(self, term_id: str, delta: int) -> int | None:
|
||||
"""Apply a relative zoom change to the tracked terminal and return the resulting level."""
|
||||
info = self._terminal_registry.get(term_id)
|
||||
if info is None or not self._is_valid_qobject(info.instance) or delta == 0:
|
||||
return None
|
||||
|
||||
if delta > 0:
|
||||
for _ in range(delta):
|
||||
info.instance.zoom_in()
|
||||
else:
|
||||
for _ in range(-delta):
|
||||
info.instance.zoom_out()
|
||||
info.zoom_level += delta
|
||||
return info.zoom_level
|
||||
|
||||
def zoom_level(self, term_id: str) -> int:
|
||||
info = self._terminal_registry.get(term_id)
|
||||
if info is None:
|
||||
return 0
|
||||
return info.zoom_level
|
||||
|
||||
def owner_is_visible(self, term_id: str) -> bool:
|
||||
"""
|
||||
Check if the owner of an instance is currently visible.
|
||||
@@ -381,6 +415,7 @@ class BecConsole(BECWidget, QWidget):
|
||||
PLUGIN = True
|
||||
ICON_NAME = "terminal"
|
||||
persist_terminal_session = False
|
||||
default_zoom_level = 1
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -497,6 +532,18 @@ class BecConsole(BECWidget, QWidget):
|
||||
if term:
|
||||
term.write(data, send_return)
|
||||
|
||||
@property
|
||||
def zoom_level(self) -> int:
|
||||
return _bec_console_registry.zoom_level(self.terminal_id)
|
||||
|
||||
def zoom_in(self) -> int | None:
|
||||
"""Increase the tracked zoom level for the shared terminal session."""
|
||||
return _bec_console_registry.change_zoom(self.terminal_id, 1)
|
||||
|
||||
def zoom_out(self) -> int | None:
|
||||
"""Decrease the tracked zoom level for the shared terminal session."""
|
||||
return _bec_console_registry.change_zoom(self.terminal_id, -1)
|
||||
|
||||
def _ensure_startup_started(self):
|
||||
if not self.startup_cmd or not _bec_console_registry.should_initialize(self):
|
||||
return
|
||||
|
||||
@@ -54,6 +54,7 @@ def test_bec_console_initialization(console_widget: BecConsole):
|
||||
assert console_widget.terminal_id == "test_terminal"
|
||||
assert console_widget._mode == ConsoleMode.ACTIVE
|
||||
assert console_widget.term is not None
|
||||
assert console_widget.zoom_level == 1
|
||||
assert console_widget._overlay.isHidden()
|
||||
console_widget.show()
|
||||
assert console_widget.isVisible()
|
||||
@@ -126,6 +127,7 @@ def test_bec_shell_initialization(qtbot):
|
||||
assert widget.console_id == "bec_shell"
|
||||
assert widget.terminal_id == "bec_shell"
|
||||
assert widget.startup_cmd is not None
|
||||
assert widget.zoom_level == 1
|
||||
|
||||
|
||||
def test_bec_console_write(console_widget):
|
||||
@@ -152,6 +154,89 @@ def test_bec_console_write_can_target_shared_terminal_without_ownership(qtbot):
|
||||
mock_write.assert_called_once_with("test command", True)
|
||||
|
||||
|
||||
def test_bec_console_zoom_tracks_shared_terminal_without_ownership(qtbot):
|
||||
owner = BecConsole(client=mocked_client, gui_id="zoom_owner", terminal_id="shared_zoom")
|
||||
follower = BecConsole(client=mocked_client, gui_id="zoom_follower", terminal_id="shared_zoom")
|
||||
qtbot.addWidget(owner)
|
||||
qtbot.addWidget(follower)
|
||||
|
||||
owner.take_terminal_ownership()
|
||||
assert owner.term is not None
|
||||
|
||||
with (
|
||||
mock.patch.object(owner.term, "zoom_in") as mock_zoom_in,
|
||||
mock.patch.object(owner.term, "zoom_out") as mock_zoom_out,
|
||||
):
|
||||
assert follower.zoom_in() == 2
|
||||
assert follower.zoom_level == 2
|
||||
mock_zoom_in.assert_called_once_with()
|
||||
|
||||
assert follower.zoom_out() == 1
|
||||
assert follower.zoom_level == 1
|
||||
mock_zoom_out.assert_called_once_with()
|
||||
|
||||
|
||||
def test_bec_console_reapplies_zoom_level_when_terminal_is_recreated(qtbot, monkeypatch):
|
||||
class RecordingTerminal(QWidget):
|
||||
zoom_in_calls = 0
|
||||
zoom_out_calls = 0
|
||||
|
||||
def write(self, text: str, add_newline: bool = True):
|
||||
return None
|
||||
|
||||
def zoom_in(self):
|
||||
type(self).zoom_in_calls += 1
|
||||
|
||||
def zoom_out(self):
|
||||
type(self).zoom_out_calls += 1
|
||||
|
||||
def send_ctrl_c(self):
|
||||
return None
|
||||
|
||||
monkeypatch.setattr(bec_console_module, "_BecTermClass", RecordingTerminal)
|
||||
|
||||
widget = BecConsole(client=mocked_client, gui_id="zoom_recreate", terminal_id="zoom_recreate")
|
||||
qtbot.addWidget(widget)
|
||||
|
||||
widget.zoom_in()
|
||||
widget.zoom_in()
|
||||
assert widget.zoom_level == 3
|
||||
assert RecordingTerminal.zoom_in_calls == 3
|
||||
|
||||
_bec_console_registry._terminal_registry[widget.terminal_id].instance = None
|
||||
widget.take_terminal_ownership()
|
||||
|
||||
assert widget.zoom_level == 3
|
||||
assert RecordingTerminal.zoom_in_calls == 6
|
||||
|
||||
|
||||
def test_bec_console_starts_with_default_zoom_level(qtbot, monkeypatch):
|
||||
class RecordingTerminal(QWidget):
|
||||
zoom_in_calls = 0
|
||||
zoom_out_calls = 0
|
||||
|
||||
def write(self, text: str, add_newline: bool = True):
|
||||
return None
|
||||
|
||||
def zoom_in(self):
|
||||
type(self).zoom_in_calls += 1
|
||||
|
||||
def zoom_out(self):
|
||||
type(self).zoom_out_calls += 1
|
||||
|
||||
def send_ctrl_c(self):
|
||||
return None
|
||||
|
||||
monkeypatch.setattr(bec_console_module, "_BecTermClass", RecordingTerminal)
|
||||
|
||||
widget = BecConsole(client=mocked_client, gui_id="console_zoom_default", terminal_id="zoom_default")
|
||||
qtbot.addWidget(widget)
|
||||
|
||||
assert widget.zoom_level == 1
|
||||
assert RecordingTerminal.zoom_in_calls == 1
|
||||
assert RecordingTerminal.zoom_out_calls == 0
|
||||
|
||||
|
||||
def test_is_owner(console_widget: BecConsole):
|
||||
assert _bec_console_registry.is_owner(console_widget)
|
||||
mock_console = mock.MagicMock()
|
||||
|
||||
@@ -104,7 +104,13 @@ class TestDeveloperViewInitialization:
|
||||
|
||||
# Check for expected toolbar actions
|
||||
toolbar_components = developer_view.toolbar.components
|
||||
expected_actions = ["save", "save_as", "run", "stop", "vim"]
|
||||
expected_actions = [
|
||||
"save",
|
||||
"save_as",
|
||||
"run",
|
||||
"stop",
|
||||
"vim",
|
||||
]
|
||||
|
||||
for action_name in expected_actions:
|
||||
assert toolbar_components.exists(action_name)
|
||||
|
||||
Reference in New Issue
Block a user