195 lines
6 KiB
Python
195 lines
6 KiB
Python
import types
|
|
from PySide6.QtWidgets import QFileDialog
|
|
from PySide6.QtGui import QTextCursor
|
|
|
|
|
|
from bouquin.theme import ThemeManager, ThemeConfig, Theme
|
|
from bouquin.settings import get_settings
|
|
from bouquin.main_window import MainWindow
|
|
from bouquin.history_dialog import HistoryDialog
|
|
|
|
|
|
def test_tabs_open_and_deduplicate(qtbot, app, tmp_db_cfg, fresh_db):
|
|
# point to the temp encrypted DB
|
|
s = get_settings()
|
|
s.setValue("db/path", str(tmp_db_cfg.path))
|
|
s.setValue("db/key", tmp_db_cfg.key)
|
|
|
|
themes = ThemeManager(app, ThemeConfig(theme=Theme.LIGHT))
|
|
w = MainWindow(themes=themes)
|
|
qtbot.addWidget(w)
|
|
w.show()
|
|
|
|
# first tab is today's date
|
|
date1 = w.calendar.selectedDate()
|
|
initial_count = w.tab_widget.count()
|
|
|
|
# opening the same date should NOT create a new tab
|
|
w._open_date_in_tab(date1)
|
|
assert w.tab_widget.count() == initial_count
|
|
assert w.tab_widget.currentWidget().current_date == date1
|
|
|
|
# opening a different date should create exactly one new tab
|
|
date2 = date1.addDays(1)
|
|
w._open_date_in_tab(date2)
|
|
assert w.tab_widget.count() == initial_count + 1
|
|
assert w.tab_widget.currentWidget().current_date == date2
|
|
|
|
# jumping back to date1 just focuses the existing tab
|
|
w._open_date_in_tab(date1)
|
|
assert w.tab_widget.count() == initial_count + 1
|
|
assert w.tab_widget.currentWidget().current_date == date1
|
|
|
|
|
|
def test_toolbar_signals_dispatch_once_per_click(
|
|
qtbot, app, tmp_db_cfg, fresh_db, monkeypatch
|
|
):
|
|
s = get_settings()
|
|
s.setValue("db/path", str(tmp_db_cfg.path))
|
|
s.setValue("db/key", tmp_db_cfg.key)
|
|
|
|
themes = ThemeManager(app, ThemeConfig(theme=Theme.LIGHT))
|
|
w = MainWindow(themes=themes)
|
|
qtbot.addWidget(w)
|
|
w.show()
|
|
|
|
tb = w.toolBar
|
|
|
|
# Spy on the first tab's editor
|
|
calls1 = {
|
|
"bold": 0,
|
|
"italic": 0,
|
|
"strike": 0,
|
|
"code": 0,
|
|
"heading": 0,
|
|
"bullets": 0,
|
|
"numbers": 0,
|
|
"checkboxes": 0,
|
|
}
|
|
|
|
def mk(key):
|
|
def _spy(self, *a, **k):
|
|
calls1[key] += 1
|
|
|
|
return _spy
|
|
|
|
w.editor.apply_weight = types.MethodType(mk("bold"), w.editor)
|
|
w.editor.apply_italic = types.MethodType(mk("italic"), w.editor)
|
|
w.editor.apply_strikethrough = types.MethodType(mk("strike"), w.editor)
|
|
w.editor.apply_code = types.MethodType(mk("code"), w.editor)
|
|
w.editor.apply_heading = types.MethodType(mk("heading"), w.editor)
|
|
w.editor.toggle_bullets = types.MethodType(mk("bullets"), w.editor)
|
|
w.editor.toggle_numbers = types.MethodType(mk("numbers"), w.editor)
|
|
w.editor.toggle_checkboxes = types.MethodType(mk("checkboxes"), w.editor)
|
|
|
|
# Click all the things once
|
|
tb.boldRequested.emit()
|
|
tb.italicRequested.emit()
|
|
tb.strikeRequested.emit()
|
|
tb.codeRequested.emit()
|
|
tb.headingRequested.emit(24)
|
|
tb.bulletsRequested.emit()
|
|
tb.numbersRequested.emit()
|
|
tb.checkboxesRequested.emit()
|
|
|
|
assert all(v == 1 for v in calls1.values()) # fired once each
|
|
|
|
# Switch to a new tab and make sure clicks go ONLY to the active editor
|
|
date2 = w.calendar.selectedDate().addDays(1)
|
|
w._open_date_in_tab(date2)
|
|
calls2 = {"bold": 0}
|
|
w.editor.apply_weight = types.MethodType(
|
|
lambda self: calls2.__setitem__("bold", calls2["bold"] + 1), w.editor
|
|
)
|
|
|
|
tb.boldRequested.emit()
|
|
assert calls1["bold"] == 1
|
|
assert calls2["bold"] == 1
|
|
|
|
w._open_date_in_tab(date2.addDays(-1)) # back to first tab
|
|
tb.boldRequested.emit()
|
|
assert calls1["bold"] == 2
|
|
assert calls2["bold"] == 1
|
|
|
|
|
|
def test_history_and_insert_image_not_duplicated(
|
|
qtbot, app, tmp_db_cfg, fresh_db, monkeypatch, tmp_path
|
|
):
|
|
s = get_settings()
|
|
s.setValue("db/path", str(tmp_db_cfg.path))
|
|
s.setValue("db/key", tmp_db_cfg.key)
|
|
|
|
themes = ThemeManager(app, ThemeConfig(theme=Theme.LIGHT))
|
|
w = MainWindow(themes=themes)
|
|
qtbot.addWidget(w)
|
|
w.show()
|
|
|
|
# History dialog opens exactly once
|
|
opened = {"count": 0}
|
|
|
|
def fake_exec(self):
|
|
opened["count"] += 1
|
|
return 0 # Rejected
|
|
|
|
monkeypatch.setattr(HistoryDialog, "exec", fake_exec, raising=False)
|
|
w.toolBar.historyRequested.emit()
|
|
assert opened["count"] == 1
|
|
|
|
# Insert image: simulate user selecting one file, and ensure it's inserted once
|
|
dummy = tmp_path / "x.png"
|
|
dummy.write_bytes(b"\x89PNG\r\n\x1a\n")
|
|
inserted = {"count": 0}
|
|
|
|
def fake_insert(self, p):
|
|
inserted["count"] += 1
|
|
|
|
w.editor.insert_image_from_path = types.MethodType(fake_insert, w.editor)
|
|
monkeypatch.setattr(
|
|
QFileDialog,
|
|
"getOpenFileNames",
|
|
lambda *a, **k: ([str(dummy)], "Images (*.png)"),
|
|
raising=False,
|
|
)
|
|
w.toolBar.insertImageRequested.emit()
|
|
assert inserted["count"] == 1
|
|
|
|
|
|
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))
|
|
s.setValue("db/key", tmp_db_cfg.key)
|
|
|
|
themes = ThemeManager(app, ThemeConfig(theme=Theme.LIGHT))
|
|
w = MainWindow(themes=themes)
|
|
qtbot.addWidget(w)
|
|
w.show()
|
|
|
|
w.editor.from_markdown("**bold**\n- [ ] task\n~~strike~~")
|
|
assert w.editor.highlighter is not None
|
|
assert w.editor.highlighter.document() is w.editor.document()
|
|
|
|
|
|
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))
|
|
s.setValue("db/key", tmp_db_cfg.key)
|
|
|
|
themes = ThemeManager(app, ThemeConfig(theme=Theme.LIGHT))
|
|
w = MainWindow(themes=themes)
|
|
qtbot.addWidget(w)
|
|
w.show()
|
|
|
|
# Tab 1 content
|
|
w.editor.from_markdown("alpha bravo charlie")
|
|
w.findBar.show_bar()
|
|
w.findBar.edit.setText("bravo")
|
|
w.findBar.find_next()
|
|
assert w.editor.textCursor().selectedText() == "bravo"
|
|
|
|
# Tab 2 content (contains the query too)
|
|
date2 = w.calendar.selectedDate().addDays(1)
|
|
w._open_date_in_tab(date2)
|
|
w.editor.from_markdown("x bravo y bravo z")
|
|
w.editor.moveCursor(QTextCursor.Start)
|
|
w.findBar.find_next()
|
|
assert w.editor.textCursor().selectedText() == "bravo"
|