aboutsummaryrefslogtreecommitdiff
path: root/tests/test-org-refile-config--scan-dir.el
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-24 07:21:44 -0500
committerCraig Jennings <c@cjennings.net>2026-05-24 07:21:44 -0500
commit12fb0108ba217f06fb9d40da8431d49540650402 (patch)
tree4d2c6630b3a6bc8f13de45697bc88ba89a257389 /tests/test-org-refile-config--scan-dir.el
parentbc9652752c231e8634a90c875ed6d206ff172458 (diff)
downloaddotemacs-12fb0108ba217f06fb9d40da8431d49540650402.tar.gz
dotemacs-12fb0108ba217f06fb9d40da8431d49540650402.zip
fix(org): surface directory-scan failures instead of crashing or hiding them
The refile target scan caught permission-denied and silently dropped the directory, and would crash outright on a missing root (only permission-denied was caught, so a missing code-dir/projects-dir raised file-missing and aborted the whole build). The agenda build had the same crash: cj/add-files-to-org-agenda-files-list called directory-files on projects-dir with no existence check. Extracted cj/--org-refile-scan-dir, which warns (display-warning) and returns nil for a missing, unreadable, or permission-denied root so the rest of the scan continues. Guarded the agenda scan the same way. Both now log a concise warning naming the skipped directory rather than failing silently or fatally. Also fixed a latent bug surfaced here: org-refile-targets was never declared special, so under make compile cj/org-refile-in-file let-bound it lexically and the scoped targets never reached org-refile. Added (defvar org-refile-targets) so the binding stays dynamic when byte-compiled. Tests cover the helper (missing/permission-denied/normal) and the agenda missing-dir guard.
Diffstat (limited to 'tests/test-org-refile-config--scan-dir.el')
-rw-r--r--tests/test-org-refile-config--scan-dir.el57
1 files changed, 57 insertions, 0 deletions
diff --git a/tests/test-org-refile-config--scan-dir.el b/tests/test-org-refile-config--scan-dir.el
new file mode 100644
index 00000000..184fa98e
--- /dev/null
+++ b/tests/test-org-refile-config--scan-dir.el
@@ -0,0 +1,57 @@
+;;; test-org-refile-config--scan-dir.el --- Tests for refile dir scan -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; Unit tests for cj/--org-refile-scan-dir, which lists the todo.org files
+;; under one root for the refile-target scan. A missing, unreadable, or
+;; permission-denied root must be non-fatal: it logs a warning and returns
+;; nil so the rest of the scan continues, instead of silently swallowing the
+;; failure or crashing on a missing directory.
+
+;;; Code:
+
+(require 'ert)
+(require 'cl-lib)
+
+(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
+(require 'org-refile-config)
+
+;;; Normal Cases
+
+(ert-deftest test-org-refile-scan-dir-normal-finds-todo ()
+ "Normal: a readable directory with a todo.org returns it."
+ (let ((dir (make-temp-file "cj-refile-scan-" t)))
+ (unwind-protect
+ (progn
+ (write-region "* TODO x\n" nil (expand-file-name "todo.org" dir))
+ (let ((found (cj/--org-refile-scan-dir dir)))
+ (should (= 1 (length found)))
+ (should (string-suffix-p "todo.org" (car found)))))
+ (delete-directory dir t))))
+
+;;; Boundary Cases
+
+(ert-deftest test-org-refile-scan-dir-boundary-missing-warns-and-returns-nil ()
+ "Boundary: a missing directory warns and returns nil, without erroring."
+ (let ((warned nil))
+ (cl-letf (((symbol-function 'display-warning)
+ (lambda (&rest _) (setq warned t))))
+ (should (null (cj/--org-refile-scan-dir "/no/such/cj-refile/dir/")))
+ (should warned))))
+
+;;; Error Cases
+
+(ert-deftest test-org-refile-scan-dir-error-permission-denied-warns-and-returns-nil ()
+ "Error: a permission-denied during the scan warns and returns nil."
+ (let ((dir (make-temp-file "cj-refile-perm-" t))
+ (warned nil))
+ (unwind-protect
+ (cl-letf (((symbol-function 'directory-files-recursively)
+ (lambda (&rest _) (signal 'permission-denied (list dir))))
+ ((symbol-function 'display-warning)
+ (lambda (&rest _) (setq warned t))))
+ (should (null (cj/--org-refile-scan-dir dir)))
+ (should warned))
+ (delete-directory dir t))))
+
+(provide 'test-org-refile-config--scan-dir)
+;;; test-org-refile-config--scan-dir.el ends here