Fix tests, add vulture_ignorelist.py, fix markdown_editor highlighter bug

This commit is contained in:
Miguel Jacq 2025-11-14 16:16:27 +11:00
parent f6e10dccac
commit 02a60ca656
Signed by: mig5
GPG key ID: 59B3F0C24135C6A9
14 changed files with 2277 additions and 61 deletions

View file

@ -15,7 +15,7 @@ jobs:
run: |
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
black pyflakes3
black pyflakes3 vulture
- name: Run linters
run: |
@ -23,3 +23,4 @@ jobs:
black --diff --check tests/*
pyflakes3 bouquin/*
pyflakes3 tests/*
vulture

View file

@ -73,9 +73,10 @@ class MarkdownEditor(QTextEdit):
def setDocument(self, doc):
super().setDocument(doc)
# reattach the highlighter to the new document
if hasattr(self, "highlighter") and self.highlighter:
self.highlighter.setDocument(self.document())
# Recreate the highlighter for the new document
# (the old one gets deleted with the old document)
if hasattr(self, "highlighter") and hasattr(self, "theme_manager"):
self.highlighter = MarkdownHighlighter(self.document(), self.theme_manager)
self._apply_line_spacing()
self._apply_code_block_spacing()
QTimer.singleShot(0, self._update_code_block_row_backgrounds)
@ -97,7 +98,7 @@ class MarkdownEditor(QTextEdit):
line = block.text()
pos_in_block = c.position() - block.position()
# Transform markldown checkboxes and 'TODO' to unicode checkboxes
# Transform markdown checkboxes and 'TODO' to unicode checkboxes
def transform_line(s: str) -> str:
s = s.replace(
f"- {self._CHECK_CHECKED_STORAGE} ",

View file

@ -31,6 +31,9 @@ pyproject-appimage = "^4.2"
script = "bouquin"
output = "Bouquin.AppImage"
[tool.vulture]
paths = ["bouquin", "vulture_ignorelist.py"]
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

View file

@ -16,7 +16,6 @@ def editor(app, qtbot):
return ed
@pytest.mark.gui
def test_findbar_basic_navigation(qtbot, editor):
editor.from_markdown("alpha\nbeta\nalpha\nGamma\n")
editor.moveCursor(QTextCursor.Start)
@ -113,7 +112,6 @@ def test_update_highlight_clear_when_empty(qtbot, editor):
assert not editor.extraSelections()
@pytest.mark.gui
def test_maybe_hide_and_wrap_prev(qtbot, editor):
editor.setPlainText("a a a")
fb = FindBar(editor=editor, shortcut_parent=editor)

View file

@ -1,11 +1,9 @@
import pytest
from PySide6.QtCore import QEvent
from PySide6.QtWidgets import QWidget
from bouquin.lock_overlay import LockOverlay
from bouquin.theme import ThemeManager, ThemeConfig, Theme
@pytest.mark.gui
def test_lock_overlay_reacts_to_theme(app, qtbot):
host = QWidget()
qtbot.addWidget(host)

View file

@ -10,11 +10,12 @@ from bouquin.settings import get_settings
from bouquin.key_prompt import KeyPrompt
from bouquin.db import DBConfig, DBManager
from PySide6.QtCore import QEvent, QDate, QTimer, Qt, QPoint, QRect
from PySide6.QtWidgets import QTableView, QApplication, QWidget, QMessageBox
from PySide6.QtWidgets import QTableView, QApplication, QWidget, QMessageBox, QDialog
from PySide6.QtGui import QMouseEvent, QKeyEvent, QTextCursor, QCloseEvent
from unittest.mock import Mock, patch
@pytest.mark.gui
def test_main_window_loads_and_saves(qtbot, app, tmp_db_cfg, fresh_db):
s = get_settings()
s.setValue("db/path", str(tmp_db_cfg.path))
@ -79,7 +80,6 @@ def test_load_yesterday_todos_moves_items(qtbot, app, tmp_db_cfg, fresh_db):
assert "carry me" not in y_txt or "- [ ]" not in y_txt
@pytest.mark.gui
def test_open_docs_and_bugs_warning(qtbot, app, fresh_db, tmp_path, monkeypatch):
themes = ThemeManager(app, ThemeConfig(theme=Theme.LIGHT))
w = MainWindow(themes=themes)
@ -113,7 +113,6 @@ def test_open_docs_and_bugs_warning(qtbot, app, fresh_db, tmp_path, monkeypatch)
assert called["docs"] and called["bugs"]
@pytest.mark.gui
def test_export_success_and_error(qtbot, app, fresh_db, tmp_path, monkeypatch):
# Seed some content
fresh_db.save_new_version("2001-01-01", "alpha", "n1")
@ -190,7 +189,6 @@ def test_export_success_and_error(qtbot, app, fresh_db, tmp_path, monkeypatch):
assert errs["hit"]
@pytest.mark.gui
def test_backup_path(qtbot, app, fresh_db, tmp_path, monkeypatch):
themes = ThemeManager(app, ThemeConfig(theme=Theme.LIGHT))
@ -248,7 +246,6 @@ def test_backup_path(qtbot, app, fresh_db, tmp_path, monkeypatch):
assert str(dest.with_suffix(".db")) in hit["text"]
@pytest.mark.gui
def test_close_tab_edges_and_autosave(qtbot, app, fresh_db, monkeypatch):
themes = ThemeManager(app, ThemeConfig(theme=Theme.LIGHT))
from bouquin.settings import get_settings
@ -283,7 +280,6 @@ def test_close_tab_edges_and_autosave(qtbot, app, fresh_db, monkeypatch):
monkeypatch.delattr(w, "_save_editor_content", raising=False)
@pytest.mark.gui
def test_restore_window_position_variants(qtbot, app, fresh_db, monkeypatch):
themes = ThemeManager(app, ThemeConfig(theme=Theme.LIGHT))
w = MainWindow(themes=themes)
@ -329,7 +325,6 @@ def test_restore_window_position_variants(qtbot, app, fresh_db, monkeypatch):
assert called["max"]
@pytest.mark.gui
def test_calendar_pos_mapping_and_context_menu(qtbot, app, fresh_db, monkeypatch):
# Seed DB so refresh marks does something
fresh_db.save_new_version("2021-08-15", "note", "")
@ -402,7 +397,6 @@ def test_calendar_pos_mapping_and_context_menu(qtbot, app, fresh_db, monkeypatch
w._show_calendar_context_menu(cal_pos)
@pytest.mark.gui
def test_event_filter_keypress_starts_idle_timer(qtbot, app):
themes = ThemeManager(app, ThemeConfig(theme=Theme.LIGHT))
w = MainWindow(themes=themes)
@ -1027,7 +1021,6 @@ def test_rect_on_any_screen_false(qtbot, tmp_db_cfg, app, monkeypatch):
assert not w._rect_on_any_screen(far)
@pytest.mark.gui
def test_reorder_tabs_with_undated_page_stays_last(qtbot, app, tmp_db_cfg, monkeypatch):
w = _make_main_window(tmp_db_cfg, app, monkeypatch)
qtbot.addWidget(w)
@ -1103,7 +1096,6 @@ def test_on_tab_changed_early_and_stop_guard(qtbot, app, tmp_db_cfg, monkeypatch
w._on_tab_changed(1) # should not raise
@pytest.mark.gui
def test_show_calendar_context_menu_no_action(qtbot, app, tmp_db_cfg, monkeypatch):
w = _make_main_window(tmp_db_cfg, app, monkeypatch)
qtbot.addWidget(w)
@ -1124,7 +1116,6 @@ def test_show_calendar_context_menu_no_action(qtbot, app, tmp_db_cfg, monkeypatc
assert w.tab_widget.count() == before
@pytest.mark.gui
def test_export_cancel_then_empty_filename(
qtbot, app, tmp_db_cfg, monkeypatch, tmp_path
):
@ -1187,7 +1178,6 @@ def test_export_cancel_then_empty_filename(
w._export() # returns early at filename check
@pytest.mark.gui
def test_set_editor_markdown_preserve_view_preserves(
qtbot, app, tmp_db_cfg, monkeypatch
):
@ -1212,7 +1202,6 @@ def test_set_editor_markdown_preserve_view_preserves(
assert w.editor.to_markdown().endswith("extra\n")
@pytest.mark.gui
def test_load_date_into_editor_with_extra_data_forces_save(
qtbot, app, tmp_db_cfg, monkeypatch
):
@ -1230,7 +1219,6 @@ def test_load_date_into_editor_with_extra_data_forces_save(
assert called["iso"] == "2020-01-01" and called["explicit"] is True
@pytest.mark.gui
def test_reorder_tabs_moves_and_undated(qtbot, app, tmp_db_cfg, monkeypatch):
"""Covers moveTab for both dated and undated buckets."""
w = _make_main_window(tmp_db_cfg, app, monkeypatch)
@ -1324,7 +1312,6 @@ def test_date_from_calendar_no_first_or_last(qtbot, app, tmp_db_cfg, monkeypatch
assert w._date_from_calendar_pos(QPoint(5, 5)) is None
@pytest.mark.gui
def test_save_editor_content_returns_if_no_conn(qtbot, app, tmp_db_cfg, monkeypatch):
"""Covers DB not connected branch."""
w = _make_main_window(tmp_db_cfg, app, monkeypatch)
@ -1337,7 +1324,6 @@ def test_save_editor_content_returns_if_no_conn(qtbot, app, tmp_db_cfg, monkeypa
w._save_editor_content(w.editor)
@pytest.mark.gui
def test_on_date_changed_stops_timer_and_saves_prev_when_dirty(
qtbot, app, tmp_db_cfg, monkeypatch
):
@ -1370,7 +1356,6 @@ def test_on_date_changed_stops_timer_and_saves_prev_when_dirty(
assert saved["iso"] == "2024-01-01"
@pytest.mark.gui
def test_bind_toolbar_idempotent(qtbot, app, tmp_db_cfg, monkeypatch):
"""Covers early return when toolbar is already bound."""
w = _make_main_window(tmp_db_cfg, app, monkeypatch)
@ -1380,7 +1365,6 @@ def test_bind_toolbar_idempotent(qtbot, app, tmp_db_cfg, monkeypatch):
w._bind_toolbar()
@pytest.mark.gui
def test_on_insert_image_no_selection_returns(qtbot, app, tmp_db_cfg, monkeypatch):
"""Covers the early return when user selects no files."""
w = _make_main_window(tmp_db_cfg, app, monkeypatch)
@ -1420,7 +1404,6 @@ def test_apply_idle_minutes_starts_when_unlocked(qtbot, app, tmp_db_cfg, monkeyp
assert hit["start"]
@pytest.mark.gui
def test_close_event_handles_settings_failures(qtbot, app, tmp_db_cfg, monkeypatch):
"""
Covers exception swallowing around settings writes & ensures close proceeds
@ -1488,3 +1471,328 @@ def test_closeEvent_swallows_exceptions(qtbot, app, tmp_db_cfg, monkeypatch):
w.closeEvent(ev)
assert called["save"] and called["close"]
# ============================================================================
# Tag Save Handler Tests (lines 1050-1068)
# ============================================================================
def test_main_window_do_tag_save_with_editor(app, fresh_db, tmp_db_cfg, monkeypatch):
"""Test _do_tag_save when editor has current_date"""
# Skip the key prompt
monkeypatch.setattr(
"bouquin.main_window.KeyPrompt",
lambda *args, **kwargs: Mock(exec=lambda: True, key=lambda: tmp_db_cfg.key),
)
themes = ThemeManager(app, ThemeConfig(theme=Theme.LIGHT))
window = MainWindow(themes)
# Set a date on the editor
date = QDate(2024, 1, 15)
window.editor.current_date = date
window.editor.from_markdown("Test content")
# Call _do_tag_save
window._do_tag_save()
# Should have saved
fresh_db.get_entry("2024-01-15")
# May or may not have content depending on timing, but should not crash
assert True
def test_main_window_do_tag_save_no_editor(app, fresh_db, tmp_db_cfg, monkeypatch):
"""Test _do_tag_save when editor doesn't have current_date"""
monkeypatch.setattr(
"bouquin.main_window.KeyPrompt",
lambda *args, **kwargs: Mock(exec=lambda: True, key=lambda: tmp_db_cfg.key),
)
themes = ThemeManager(app, ThemeConfig(theme=Theme.LIGHT))
window = MainWindow(themes)
# Remove current_date attribute
if hasattr(window.editor, "current_date"):
delattr(window.editor, "current_date")
# Call _do_tag_save - should handle gracefully
window._do_tag_save()
assert True
def test_main_window_on_tag_added_triggers_deferred_save(
app, fresh_db, tmp_db_cfg, monkeypatch
):
"""Test that _on_tag_added defers the save (lines 1043-1048)"""
monkeypatch.setattr(
"bouquin.main_window.KeyPrompt",
lambda *args, **kwargs: Mock(exec=lambda: True, key=lambda: tmp_db_cfg.key),
)
themes = ThemeManager(app, ThemeConfig(theme=Theme.LIGHT))
window = MainWindow(themes)
# Mock QTimer.singleShot
with patch("PySide6.QtCore.QTimer.singleShot") as mock_timer:
window._on_tag_added()
# Should have called singleShot
mock_timer.assert_called_once()
args = mock_timer.call_args[0]
assert args[0] == 0 # Delay of 0
assert callable(args[1]) # Callback function
# ============================================================================
# Tag Activation Tests (lines 1070-1080)
# ============================================================================
def test_main_window_on_tag_activated_with_date(app, fresh_db, tmp_db_cfg, monkeypatch):
"""Test _on_tag_activated when passed a date string"""
monkeypatch.setattr(
"bouquin.main_window.KeyPrompt",
lambda *args, **kwargs: Mock(exec=lambda: True, key=lambda: tmp_db_cfg.key),
)
themes = ThemeManager(app, ThemeConfig(theme=Theme.LIGHT))
window = MainWindow(themes)
# Mock _load_selected_date
window._load_selected_date = Mock()
# Call with date format
window._on_tag_activated("2024-01-15")
# Should have called _load_selected_date
window._load_selected_date.assert_called_once_with("2024-01-15")
def test_main_window_on_tag_activated_with_tag_name(
app, fresh_db, tmp_db_cfg, monkeypatch
):
"""Test _on_tag_activated when passed a tag name"""
monkeypatch.setattr(
"bouquin.main_window.KeyPrompt",
lambda *args, **kwargs: Mock(exec=lambda: True, key=lambda: tmp_db_cfg.key),
)
themes = ThemeManager(app, ThemeConfig(theme=Theme.LIGHT))
window = MainWindow(themes)
# Mock the tag browser dialog (it's imported locally in the method)
with patch("bouquin.tag_browser.TagBrowserDialog") as mock_dialog:
mock_instance = Mock()
mock_instance.openDateRequested = Mock()
mock_instance.exec.return_value = QDialog.Accepted
mock_dialog.return_value = mock_instance
# Call with tag name
window._on_tag_activated("worktag")
# Should have opened dialog
mock_dialog.assert_called_once()
# Check focus_tag was passed
call_kwargs = mock_dialog.call_args[1]
assert call_kwargs.get("focus_tag") == "worktag"
# ============================================================================
# Settings Path Change Tests (lines 1105-1116)
# ============================================================================
def test_main_window_settings_path_change_success(
app, fresh_db, tmp_db_cfg, tmp_path, monkeypatch
):
"""Test changing database path in settings"""
monkeypatch.setattr(
"bouquin.main_window.KeyPrompt",
lambda *args, **kwargs: Mock(exec=lambda: True, key=lambda: tmp_db_cfg.key),
)
themes = ThemeManager(app, ThemeConfig(theme=Theme.LIGHT))
window = MainWindow(themes)
new_path = tmp_path / "new.db"
# Mock the settings dialog
with patch("bouquin.main_window.SettingsDialog") as mock_dialog:
mock_instance = Mock()
mock_instance.exec.return_value = QDialog.Accepted
# Create a new config with different path
new_cfg = Mock()
new_cfg.path = str(new_path)
new_cfg.key = tmp_db_cfg.key
new_cfg.idle_minutes = 15
new_cfg.theme = "light"
new_cfg.move_todos = True
new_cfg.locale = "en"
mock_instance.config = new_cfg
mock_dialog.return_value = mock_instance
# Mock _prompt_for_key_until_valid to return True
window._prompt_for_key_until_valid = Mock(return_value=True)
# Also mock _load_selected_date and _refresh_calendar_marks since we don't have a real DB connection
window._load_selected_date = Mock()
window._refresh_calendar_marks = Mock()
# Open settings
window._open_settings()
# Path should have changed
assert window.cfg.path == str(new_path)
def test_main_window_settings_path_change_failure(
app, fresh_db, tmp_db_cfg, tmp_path, monkeypatch
):
"""Test failed database path change shows warning (lines 1108-1113)"""
monkeypatch.setattr(
"bouquin.main_window.KeyPrompt",
lambda *args, **kwargs: Mock(exec=lambda: True, key=lambda: tmp_db_cfg.key),
)
themes = ThemeManager(app, ThemeConfig(theme=Theme.LIGHT))
window = MainWindow(themes)
new_path = tmp_path / "new.db"
# Mock the settings dialog
with patch("bouquin.main_window.SettingsDialog") as mock_dialog:
mock_instance = Mock()
mock_instance.exec.return_value = QDialog.Accepted
new_cfg = Mock()
new_cfg.path = str(new_path)
new_cfg.key = tmp_db_cfg.key
new_cfg.idle_minutes = 15
new_cfg.theme = "light"
new_cfg.move_todos = True
new_cfg.locale = "en"
mock_instance.config = new_cfg
mock_dialog.return_value = mock_instance
# Mock _prompt_for_key_until_valid to return False (failure)
window._prompt_for_key_until_valid = Mock(return_value=False)
# Mock QMessageBox.warning
with patch.object(QMessageBox, "warning") as mock_warning:
# Open settings
window._open_settings()
# Warning should have been shown
mock_warning.assert_called_once()
def test_main_window_settings_no_path_change(app, fresh_db, tmp_db_cfg, monkeypatch):
"""Test settings change without path change (lines 1105 condition False)"""
monkeypatch.setattr(
"bouquin.main_window.KeyPrompt",
lambda *args, **kwargs: Mock(exec=lambda: True, key=lambda: tmp_db_cfg.key),
)
themes = ThemeManager(app, ThemeConfig(theme=Theme.LIGHT))
window = MainWindow(themes)
old_path = window.cfg.path
# Mock the settings dialog
with patch("bouquin.main_window.SettingsDialog") as mock_dialog:
mock_instance = Mock()
mock_instance.exec.return_value = QDialog.Accepted
# Create config with SAME path
new_cfg = Mock()
new_cfg.path = old_path
new_cfg.key = tmp_db_cfg.key
new_cfg.idle_minutes = 20 # Changed
new_cfg.theme = "dark" # Changed
new_cfg.move_todos = False # Changed
new_cfg.locale = "fr" # Changed
mock_instance.config = new_cfg
mock_dialog.return_value = mock_instance
# Open settings
window._open_settings()
# Settings should be updated but path didn't change
assert window.cfg.idle_minutes == 20
assert window.cfg.theme == "dark"
assert window.cfg.path == old_path
def test_main_window_settings_cancelled(app, fresh_db, tmp_db_cfg, monkeypatch):
"""Test cancelling settings dialog (line 1085-1086)"""
monkeypatch.setattr(
"bouquin.main_window.KeyPrompt",
lambda *args, **kwargs: Mock(exec=lambda: True, key=lambda: tmp_db_cfg.key),
)
themes = ThemeManager(app, ThemeConfig(theme=Theme.LIGHT))
window = MainWindow(themes)
old_theme = window.cfg.theme
# Mock the settings dialog to be rejected
with patch("bouquin.main_window.SettingsDialog") as mock_dialog:
mock_instance = Mock()
mock_instance.exec.return_value = QDialog.Rejected
mock_dialog.return_value = mock_instance
# Open settings
window._open_settings()
# Settings should NOT change
assert window.cfg.theme == old_theme
# ============================================================================
# Update Tag Views Tests (lines 1039-1041)
# ============================================================================
def test_main_window_update_tag_views_for_date(app, fresh_db, tmp_db_cfg, monkeypatch):
"""Test _update_tag_views_for_date"""
monkeypatch.setattr(
"bouquin.main_window.KeyPrompt",
lambda *args, **kwargs: Mock(exec=lambda: True, key=lambda: tmp_db_cfg.key),
)
themes = ThemeManager(app, ThemeConfig(theme=Theme.LIGHT))
window = MainWindow(themes)
# Set tags for a date
fresh_db.set_tags_for_page("2024-01-15", ["test"])
# Update tag views
window._update_tag_views_for_date("2024-01-15")
# Tags widget should have been updated
assert window.tags._current_date == "2024-01-15"
def test_main_window_update_tag_views_no_tags_widget(
app, fresh_db, tmp_db_cfg, monkeypatch
):
"""Test _update_tag_views_for_date when tags widget doesn't exist"""
monkeypatch.setattr(
"bouquin.main_window.KeyPrompt",
lambda *args, **kwargs: Mock(exec=lambda: True, key=lambda: tmp_db_cfg.key),
)
themes = ThemeManager(app, ThemeConfig(theme=Theme.LIGHT))
window = MainWindow(themes)
# Remove tags widget
delattr(window, "tags")
# Should handle gracefully
window._update_tag_views_for_date("2024-01-15")
assert True

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,3 @@
import pytest
from bouquin.search import Search
from PySide6.QtWidgets import QListWidgetItem
@ -80,7 +79,6 @@ def test_make_html_snippet_variants(qtbot, fresh_db):
assert "<b>delta</b>" in frag
@pytest.mark.gui
def test_search_error_path_and_empty_snippet(qtbot, fresh_db, monkeypatch):
s = Search(fresh_db)
qtbot.addWidget(s)
@ -92,7 +90,6 @@ def test_search_error_path_and_empty_snippet(qtbot, fresh_db, monkeypatch):
assert frag == "" and not left and not right
@pytest.mark.gui
def test_populate_results_shows_both_ellipses(qtbot, fresh_db):
s = Search(fresh_db)
qtbot.addWidget(s)

View file

@ -1,5 +1,3 @@
import pytest
from bouquin.db import DBManager, DBConfig
from bouquin.key_prompt import KeyPrompt
import bouquin.settings_dialog as sd
@ -10,7 +8,6 @@ from PySide6.QtCore import QTimer
from PySide6.QtWidgets import QApplication, QMessageBox, QWidget, QDialog
@pytest.mark.gui
def test_settings_dialog_config_roundtrip(qtbot, tmp_db_cfg, fresh_db, tmp_path):
# Provide a parent that exposes a real ThemeManager (dialog calls parent().themes.set(...))
app = QApplication.instance()
@ -206,7 +203,6 @@ def test_settings_compact_error(qtbot, app, monkeypatch, tmp_db_cfg, fresh_db):
assert called["text"]
@pytest.mark.gui
def test_settings_browse_sets_path(qtbot, app, tmp_path, fresh_db, monkeypatch):
parent = QWidget()
parent.themes = ThemeManager(app, ThemeConfig(theme=Theme.LIGHT))

View file

@ -1,5 +1,4 @@
import types
import pytest
from PySide6.QtWidgets import QFileDialog
from PySide6.QtGui import QTextCursor
@ -10,7 +9,6 @@ from bouquin.main_window import MainWindow
from bouquin.history_dialog import HistoryDialog
@pytest.mark.gui
def test_tabs_open_and_deduplicate(qtbot, app, tmp_db_cfg, fresh_db):
# point to the temp encrypted DB
s = get_settings()
@ -43,7 +41,6 @@ def test_tabs_open_and_deduplicate(qtbot, app, tmp_db_cfg, fresh_db):
assert w.tab_widget.currentWidget().current_date == date1
@pytest.mark.gui
def test_toolbar_signals_dispatch_once_per_click(
qtbot, app, tmp_db_cfg, fresh_db, monkeypatch
):
@ -115,7 +112,6 @@ def test_toolbar_signals_dispatch_once_per_click(
assert calls2["bold"] == 1
@pytest.mark.gui
def test_history_and_insert_image_not_duplicated(
qtbot, app, tmp_db_cfg, fresh_db, monkeypatch, tmp_path
):
@ -158,7 +154,6 @@ def test_history_and_insert_image_not_duplicated(
assert inserted["count"] == 1
@pytest.mark.gui
def test_highlighter_attached_after_text_load(qtbot, app, tmp_db_cfg, fresh_db):
s = get_settings()
s.setValue("db/path", str(tmp_db_cfg.path))
@ -174,7 +169,6 @@ def test_highlighter_attached_after_text_load(qtbot, app, tmp_db_cfg, fresh_db):
assert w.editor.highlighter.document() is w.editor.document()
@pytest.mark.gui
def test_findbar_works_for_current_tab(qtbot, app, tmp_db_cfg, fresh_db):
s = get_settings()
s.setValue("db/path", str(tmp_db_cfg.path))

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,3 @@
import pytest
from PySide6.QtGui import QPalette
from PySide6.QtWidgets import QApplication, QCalendarWidget, QWidget
@ -15,7 +14,6 @@ def test_theme_manager_apply_light_and_dark(app):
assert isinstance(app.palette(), QPalette)
@pytest.mark.gui
def test_theme_manager_system_roundtrip(app, qtbot):
cfg = ThemeConfig(theme=Theme.SYSTEM)
mgr = ThemeManager(app, cfg)

View file

@ -14,7 +14,6 @@ def editor(app, qtbot):
return ed
@pytest.mark.gui
def test_toolbar_signals_and_styling(qtbot, editor):
host = QWidget()
qtbot.addWidget(host)

22
vulture_ignorelist.py Normal file
View file

@ -0,0 +1,22 @@
from bouquin.flow_layout import FlowLayout
from bouquin.markdown_editor import MarkdownEditor
from bouquin.markdown_highlighter import MarkdownHighlighter
from bouquin.db import DBManager
DBManager.row_factory
FlowLayout.itemAt
FlowLayout.expandingDirections
FlowLayout.hasHeightForWidth
FlowLayout.heightForWidth
MarkdownEditor.apply_weight
MarkdownEditor.apply_italic
MarkdownEditor.apply_strikethrough
MarkdownEditor.apply_code
MarkdownEditor.apply_heading
MarkdownEditor.toggle_bullets
MarkdownEditor.toggle_numbers
MarkdownEditor.toggle_checkboxes
MarkdownHighlighter.highlightBlock