diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-14 03:26:10 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-14 03:26:10 -0500 |
| commit | 7ed4c84e2e97a737ac2286376c89dc4b55cc884b (patch) | |
| tree | 7c4de005d5529ca5120f725414ebc92814184881 | |
| parent | 54616242ab2bebb6efb6660c311df0127a82f962 (diff) | |
| download | dotemacs-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.el | 243 |
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 |
