diff --git a/core/editor.py b/core/editor.py index 1054ccd..898aef4 100644 --- a/core/editor.py +++ b/core/editor.py @@ -109,11 +109,17 @@ def __init__(self, editor: "CodeEditor", parent=None): editor.textChanged.connect(self._invalidate_cache) editor.cursorPositionChanged.connect(self.update) - editor.blockCountChanged.connect(lambda _count: self._invalidate_cache()) + editor.blockCountChanged.connect(self._block_count_changed) editor.updateRequest.connect(self._editor_update_requested) - editor.verticalScrollBar().valueChanged.connect(lambda _value: self.update()) + editor.verticalScrollBar().valueChanged.connect(self._scroll_value_changed) editor.document().contentsChanged.connect(self._invalidate_cache) + def _block_count_changed(self, _count): + self._invalidate_cache() + + def _scroll_value_changed(self, _value): + self.update() + def _editor_update_requested(self, _rect, _dy): """Zeichnet die Vorschau nach Scroll- und Viewport-Updates neu.""" self.update() diff --git a/features/project_view.py b/features/project_view.py index a2590d3..311f843 100644 --- a/features/project_view.py +++ b/features/project_view.py @@ -222,7 +222,7 @@ def _setup_ui(self): "Öffnet den Dialog zum Bereitstellen und Committen von Git-Änderungen." ) self.btn_commit.setEnabled(False) - self.btn_commit.clicked.connect(lambda: self.open_commit_dialog()) + self.btn_commit.clicked.connect(self._on_commit_clicked) header.addWidget(self.btn_commit) layout.addLayout(header) @@ -338,6 +338,9 @@ def _setup_ui(self): layout.addWidget(self.tree) + def _on_commit_clicked(self, _checked=False): + self.open_commit_dialog() + def set_workspace(self, workspace: Optional[WorkspaceManager]): """Verbindet die ProjectView mit dem WorkspaceManager.""" if self._workspace is not None: diff --git a/tests/test_minimap.py b/tests/test_minimap.py index 7b33753..b3fa374 100644 --- a/tests/test_minimap.py +++ b/tests/test_minimap.py @@ -2,6 +2,9 @@ # -*- coding: utf-8 -*- """Tests für CodeBox-Minimap und ihre Editor-Einstellung.""" +import gc +import weakref + import pytest from PySide6.QtWidgets import QApplication @@ -47,6 +50,23 @@ def test_minimap_navigation_and_visibility(qapp): editor.close() +def test_minimap_signal_connections_release_closed_editor(qapp): + references = [] + for _ in range(3): + editor = CodeEditor() + editor.setPlainText("first\nsecond") + assert editor.minimap._document_lines() == ["first", "second"] + editor.appendPlainText("third") + assert editor.minimap._cached_lines is None + assert editor.minimap._document_lines() == ["first", "second", "third"] + references.append(weakref.ref(editor)) + editor.close() + del editor + gc.collect() + qapp.processEvents() + assert all(reference() is None for reference in references) + + def test_main_window_applies_minimap_setting(qapp, tmp_path, monkeypatch): settings_file = tmp_path / "settings.json" monkeypatch.setattr("config._SETTINGS_FILE", settings_file) diff --git a/tests/test_project_view.py b/tests/test_project_view.py index a3a94b4..9f3f084 100644 --- a/tests/test_project_view.py +++ b/tests/test_project_view.py @@ -1,4 +1,6 @@ """Regressionstests für ProjectView und Pfadsync im Hauptfenster.""" +import gc +import weakref from unittest.mock import patch from PySide6.QtWidgets import QApplication @@ -11,6 +13,23 @@ def _ensure_app(): return QApplication.instance() or QApplication([]) +def test_commit_button_dispatch_and_closed_view_collection(): + app = _ensure_app() + references = [] + for _ in range(3): + view = ProjectView() + with patch.object(view, "open_commit_dialog") as open_dialog: + view.btn_commit.setEnabled(True) + view.btn_commit.click() + open_dialog.assert_called_once_with() + references.append(weakref.ref(view)) + view.close() + del view + gc.collect() + app.processEvents() + assert all(reference() is None for reference in references) + + def test_new_file_in_shows_error_on_write_failure(tmp_path): """Regression (B-008): _new_file_in() muss OSError abfangen und eine Fehlermeldung zeigen, statt die Ausnahme unkontrolliert zu propagieren."""