summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-14 03:26:10 -0500
committerCraig Jennings <c@cjennings.net>2026-05-14 03:26:10 -0500
commit7ed4c84e2e97a737ac2286376c89dc4b55cc884b (patch)
tree7c4de005d5529ca5120f725414ebc92814184881
parent54616242ab2bebb6efb6660c311df0127a82f962 (diff)
downloaddotemacs-7ed4c84e2e97a737ac2286376c89dc4b55cc884b.tar.gz
dotemacs-7ed4c84e2e97a737ac2286376c89dc4b55cc884b.zip
test(org-noter-config): cover document path, find/create, session, start, insert
Sibling tests covered the preferred-split, title-to-slug, notes-template, and in-document / in-notes-file predicates. This batch fills in the rest: - `cj/org-noter--get-document-path`: pdf-view-mode uses buffer-file-name, nov-mode uses `nov-file-name`, unrelated mode returns nil. - `cj/org-noter--extract-document-title`: strips the extension. - `cj/org-noter--find-notes-file`: returns the file containing the doc-path, nil when no doc or no match. - `cj/org-noter--create-notes-file`: writes the template when absent. - `cj/org-noter--session-active-p`: nil when unbound, non-nil when set. - `cj/org-noter--toggle-notes-window`: deletes when visible, requests start when hidden. - `cj/org-noter-start`: routes through the cond -- toggle in doc+session, switch-window in notes+session, message elsewhere. - `cj/org-noter-insert-note-dwim`: with active session inserts directly; without one, starts then inserts. org-noter / pdf-view / nov / org-id primitives are stubbed.
-rw-r--r--tests/test-org-noter-config-commands.el243
1 files changed, 243 insertions, 0 deletions
diff --git a/tests/test-org-noter-config-commands.el b/tests/test-org-noter-config-commands.el
new file mode 100644
index 00000000..8860af06
--- /dev/null
+++ b/tests/test-org-noter-config-commands.el
@@ -0,0 +1,243 @@
+;;; test-org-noter-config-commands.el --- Tests for org-noter-config command + helper functions -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; Sibling tests cover the preferred-split helper, the title-to-slug
+;; helper, the notes-template generator, and the in-document /
+;; in-notes-file predicates. This file fills in:
+;;
+;; cj/org-noter--get-document-path
+;; cj/org-noter--extract-document-title
+;; cj/org-noter--find-notes-file
+;; cj/org-noter--create-notes-file
+;; cj/org-noter--session-active-p
+;; cj/org-noter--toggle-notes-window
+;; cj/org-noter-start
+;; cj/org-noter-insert-note-dwim
+;;
+;; org-noter / pdf-view / nov primitives are stubbed.
+
+;;; Code:
+
+(require 'ert)
+(require 'cl-lib)
+
+(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
+(require 'org-noter-config)
+
+;; Top-level dynamic vars some of the helpers reference.
+(defvar org-noter--session nil
+ "Stub for `org-noter--session' (org-noter not loaded here).")
+(defvar nov-file-name nil
+ "Stub for `nov-file-name' (nov.el not loaded here).")
+(defvar pdf-view-display-size nil
+ "Stub for `pdf-view-display-size'.")
+
+;;; cj/org-noter--get-document-path
+
+(ert-deftest test-org-noter-get-document-path-pdf-mode-uses-buffer-file ()
+ "Normal: in pdf-view-mode the buffer-file-name is the doc path."
+ (cl-letf (((symbol-function 'derived-mode-p)
+ (lambda (&rest modes) (memq 'pdf-view-mode modes))))
+ (with-temp-buffer
+ (setq buffer-file-name "/tmp/whitepaper.pdf")
+ (should (equal (cj/org-noter--get-document-path) "/tmp/whitepaper.pdf"))
+ (setq buffer-file-name nil))))
+
+(ert-deftest test-org-noter-get-document-path-nov-mode-uses-nov-file-name ()
+ "Normal: in nov-mode the variable `nov-file-name' is the doc path."
+ (cl-letf (((symbol-function 'derived-mode-p)
+ (lambda (&rest modes) (memq 'nov-mode modes))))
+ (let ((nov-file-name "/tmp/book.epub"))
+ (should (equal (cj/org-noter--get-document-path) "/tmp/book.epub")))))
+
+(ert-deftest test-org-noter-get-document-path-unknown-mode-returns-nil ()
+ "Boundary: an unrelated major mode returns nil."
+ (cl-letf (((symbol-function 'derived-mode-p) (lambda (&rest _) nil)))
+ (should-not (cj/org-noter--get-document-path))))
+
+;;; cj/org-noter--extract-document-title
+
+(ert-deftest test-org-noter-extract-document-title-strips-extension ()
+ "Normal: the title is the basename without extension."
+ (cl-letf (((symbol-function 'cj/org-noter--get-document-path)
+ (lambda () "/tmp/papers/quantum-2024.pdf")))
+ (should (equal (cj/org-noter--extract-document-title) "quantum-2024"))))
+
+;;; cj/org-noter--find-notes-file
+
+(ert-deftest test-org-noter-find-notes-file-returns-matching-file ()
+ "Normal: a notes file whose body mentions the doc-path is returned."
+ (let* ((dir (make-temp-file "test-org-noter-find-" t))
+ (notes (expand-file-name "notes-on-foo.org" dir))
+ (doc "/tmp/papers/foo.pdf")
+ (cj/org-noter-notes-directory dir))
+ (unwind-protect
+ (progn
+ (with-temp-file notes
+ (insert ":PROPERTIES:\n:NOTER_DOCUMENT: " doc "\n:END:\n"))
+ (cl-letf (((symbol-function 'cj/org-noter--get-document-path)
+ (lambda () doc)))
+ (should (equal (cj/org-noter--find-notes-file) notes))))
+ (delete-directory dir t))))
+
+(ert-deftest test-org-noter-find-notes-file-nil-when-no-doc-path ()
+ "Boundary: with no current document, find returns nil."
+ (cl-letf (((symbol-function 'cj/org-noter--get-document-path)
+ (lambda () nil)))
+ (should-not (cj/org-noter--find-notes-file))))
+
+(ert-deftest test-org-noter-find-notes-file-nil-when-no-match ()
+ "Boundary: a directory with notes files that don't match returns nil."
+ (let* ((dir (make-temp-file "test-org-noter-find-" t))
+ (cj/org-noter-notes-directory dir))
+ (unwind-protect
+ (progn
+ (with-temp-file (expand-file-name "unrelated.org" dir)
+ (insert "* Notes about something else\n"))
+ (cl-letf (((symbol-function 'cj/org-noter--get-document-path)
+ (lambda () "/tmp/different.pdf")))
+ (should-not (cj/org-noter--find-notes-file))))
+ (delete-directory dir t))))
+
+;;; cj/org-noter--create-notes-file
+
+(ert-deftest test-org-noter-create-notes-file-writes-template-when-absent ()
+ "Normal: a new doc gets a new notes file with the template content."
+ (let* ((dir (make-temp-file "test-org-noter-create-" t))
+ (cj/org-noter-notes-directory dir)
+ (doc "/tmp/papers/great-book.pdf"))
+ (unwind-protect
+ (cl-letf (((symbol-function 'cj/org-noter--get-document-path)
+ (lambda () doc))
+ ((symbol-function 'read-string)
+ (lambda (&rest _) "great-book"))
+ ;; The template uses `org-id-uuid' (org-id not loaded here).
+ ((symbol-function 'org-id-uuid)
+ (lambda () "00000000-0000-0000-0000-000000000000"))
+ ((symbol-function 'find-file-noselect)
+ (lambda (f) (get-buffer-create (concat "*test-" f "*")))))
+ (let ((path (cj/org-noter--create-notes-file)))
+ (should (file-exists-p path))
+ (with-temp-buffer
+ (insert-file-contents path)
+ (should (string-match-p (regexp-quote doc) (buffer-string))))))
+ (delete-directory dir t))))
+
+;;; cj/org-noter--session-active-p
+
+(ert-deftest test-org-noter-session-active-p-nil-when-unbound ()
+ "Boundary: with `org-noter--session' nil, predicate returns nil."
+ (let ((org-noter--session nil))
+ (should-not (cj/org-noter--session-active-p))))
+
+(ert-deftest test-org-noter-session-active-p-non-nil-when-set ()
+ "Normal: with `org-noter--session' set, predicate returns non-nil."
+ (let ((org-noter--session 'active-session))
+ (should (cj/org-noter--session-active-p))))
+
+;;; cj/org-noter--toggle-notes-window
+
+(ert-deftest test-org-noter-toggle-notes-window-closes-when-visible ()
+ "Normal: a visible notes window gets deleted."
+ (let ((deleted nil))
+ (cl-letf (((symbol-function 'org-noter--get-notes-window)
+ (lambda (&rest _) 'fake-window))
+ ((symbol-function 'delete-window)
+ (lambda (w) (setq deleted w)))
+ ((symbol-function 'derived-mode-p) (lambda (&rest _) nil)))
+ (cj/org-noter--toggle-notes-window))
+ (should (eq deleted 'fake-window))))
+
+(ert-deftest test-org-noter-toggle-notes-window-opens-when-hidden ()
+ "Normal: when no notes window exists, `start' is requested."
+ (let ((requested-mode nil))
+ (cl-letf (((symbol-function 'org-noter--get-notes-window)
+ (lambda (&optional flag)
+ (if flag (setq requested-mode flag) nil)))
+ ((symbol-function 'derived-mode-p) (lambda (&rest _) nil)))
+ (cj/org-noter--toggle-notes-window))
+ (should (eq requested-mode 'start))))
+
+;;; cj/org-noter-start
+
+(ert-deftest test-org-noter-start-in-document-with-session-toggles-notes ()
+ "Normal: in a document with an active session, start toggles the notes window."
+ (let ((toggled nil))
+ (cl-letf (((symbol-function 'cj/org-noter--in-document-p)
+ (lambda () t))
+ ((symbol-function 'cj/org-noter--in-notes-file-p)
+ (lambda () nil))
+ ((symbol-function 'cj/org-noter--session-active-p)
+ (lambda () t))
+ ((symbol-function 'cj/org-noter--toggle-notes-window)
+ (lambda () (setq toggled t))))
+ (cj/org-noter-start))
+ (should toggled)))
+
+(ert-deftest test-org-noter-start-in-notes-file-with-session-switches-window ()
+ "Normal: in a notes file with active session, switch to doc window."
+ (let ((selected nil))
+ (cl-letf (((symbol-function 'cj/org-noter--in-document-p)
+ (lambda () nil))
+ ((symbol-function 'cj/org-noter--in-notes-file-p)
+ (lambda () t))
+ ((symbol-function 'cj/org-noter--session-active-p)
+ (lambda () t))
+ ((symbol-function 'org-noter--get-doc-window)
+ (lambda () 'doc-win))
+ ((symbol-function 'select-window)
+ (lambda (w) (setq selected w))))
+ (cj/org-noter-start))
+ (should (eq selected 'doc-win))))
+
+(ert-deftest test-org-noter-start-elsewhere-messages ()
+ "Boundary: outside any noter context, the function messages."
+ (let ((msg nil))
+ (cl-letf (((symbol-function 'cj/org-noter--in-document-p)
+ (lambda () nil))
+ ((symbol-function 'cj/org-noter--in-notes-file-p)
+ (lambda () nil))
+ ((symbol-function 'message)
+ (lambda (fmt &rest args)
+ (setq msg (apply #'format fmt args)))))
+ (cj/org-noter-start))
+ (should (string-match-p "Not in a document" msg))))
+
+;;; cj/org-noter-insert-note-dwim
+
+(ert-deftest test-org-noter-insert-note-dwim-inserts-when-session-active ()
+ "Normal: with an active session, insert-note is called directly."
+ (let ((inserted nil)
+ (started nil))
+ (cl-letf (((symbol-function 'cj/org-noter--session-active-p)
+ (lambda () t))
+ ((symbol-function 'cj/org-noter-start)
+ (lambda () (setq started t)))
+ ((symbol-function 'org-noter-insert-note)
+ (lambda () (setq inserted t))))
+ (cj/org-noter-insert-note-dwim))
+ (should inserted)
+ ;; Doesn't try to start a session when one's already active.
+ (should-not started)))
+
+(ert-deftest test-org-noter-insert-note-dwim-starts-then-inserts-when-no-session ()
+ "Normal: without a session, the function starts one and then inserts."
+ (let ((session-state nil) ; flipped to t when start "succeeds"
+ (inserted nil)
+ (selected nil))
+ (cl-letf (((symbol-function 'cj/org-noter--session-active-p)
+ (lambda () session-state))
+ ((symbol-function 'cj/org-noter-start)
+ (lambda () (setq session-state t)))
+ ((symbol-function 'org-noter--get-doc-window)
+ (lambda () 'doc-win))
+ ((symbol-function 'select-window)
+ (lambda (w) (setq selected w)))
+ ((symbol-function 'org-noter-insert-note)
+ (lambda () (setq inserted t))))
+ (cj/org-noter-insert-note-dwim))
+ (should (eq selected 'doc-win))
+ (should inserted)))
+
+(provide 'test-org-noter-config-commands)
+;;; test-org-noter-config-commands.el ends here