fix: add zoom level functionality to BecConsole and related tests

This commit is contained in:
2026-07-07 15:05:44 +02:00
committed by wakonig_k
parent e530cbaa41
commit 6d08f02d64
3 changed files with 139 additions and 1 deletions
@@ -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
+85
View File
@@ -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()
+7 -1
View File
@@ -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)