aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-06-20 12:47:17 -0400
committerCraig Jennings <c@cjennings.net>2026-06-20 12:47:17 -0400
commitffb9a7de2f86ef9f1aab84b197ca5806fe657f0b (patch)
tree896dd698ea8f02d48b00985f1e599b7d2e6958d2 /tests
parentc8f63debf96f938547a222797dc72e8c1aa5c8eb (diff)
downloaddotemacs-ffb9a7de2f86ef9f1aab84b197ca5806fe657f0b.tar.gz
dotemacs-ffb9a7de2f86ef9f1aab84b197ca5806fe657f0b.zip
refactor(prog-general): lift cj/find-project-root-file out of :config
The pure project-root file finder lived inside the projectile use-package :config, so it was unreachable under make test. Move it to top level (its forward declaration already existed); cj/open-project-root-todo and cj/project-switch-actions still call it. Adds unit coverage for string regexps, rx forms, no-match, and no-project.
Diffstat (limited to 'tests')
-rw-r--r--tests/test-prog-general--find-project-root-file.el49
1 files changed, 49 insertions, 0 deletions
diff --git a/tests/test-prog-general--find-project-root-file.el b/tests/test-prog-general--find-project-root-file.el
new file mode 100644
index 000000000..97db0b979
--- /dev/null
+++ b/tests/test-prog-general--find-project-root-file.el
@@ -0,0 +1,49 @@
+;;; test-prog-general--find-project-root-file.el --- Tests for cj/find-project-root-file -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; cj/find-project-root-file returns the first file in the current Projectile
+;; project root matching a regexp (string or rx form), case-insensitively. It
+;; was defined inside the projectile use-package :config (unreachable under
+;; `make test'); lifting it to top level makes it unit-testable. projectile's
+;; root and directory-files are mocked at the boundary.
+
+;;; Code:
+
+(require 'ert)
+(require 'cl-lib)
+(require 'seq)
+
+(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
+(require 'prog-general)
+
+(defmacro test-prg--with-root (files &rest body)
+ "Run BODY with projectile-project-root \"/proj/\" and directory-files = FILES."
+ (declare (indent 1))
+ `(cl-letf (((symbol-function 'projectile-project-root) (lambda (&rest _) "/proj/"))
+ ((symbol-function 'directory-files) (lambda (&rest _) ,files)))
+ ,@body))
+
+(ert-deftest test-prg-find-root-file-string-regexp ()
+ "Normal: a string regexp matches case-insensitively."
+ (test-prg--with-root '("README.md" "TODO.org" "src")
+ (should (equal (cj/find-project-root-file "^todo\\.org$") "TODO.org"))))
+
+(ert-deftest test-prg-find-root-file-rx-form ()
+ "Normal: an rx form is converted and matched."
+ (test-prg--with-root '("notes.txt" "todo.md" "x")
+ (should (equal (cj/find-project-root-file
+ '(seq bos "todo." (or "org" "md" "txt") eos))
+ "todo.md"))))
+
+(ert-deftest test-prg-find-root-file-no-match ()
+ "Boundary: no matching file yields nil."
+ (test-prg--with-root '("a.el" "b.el")
+ (should (null (cj/find-project-root-file "^todo\\.org$")))))
+
+(ert-deftest test-prg-find-root-file-no-project ()
+ "Boundary: outside a project (nil root) yields nil."
+ (cl-letf (((symbol-function 'projectile-project-root) (lambda (&rest _) nil)))
+ (should (null (cj/find-project-root-file "^todo\\.org$")))))
+
+(provide 'test-prog-general--find-project-root-file)
+;;; test-prog-general--find-project-root-file.el ends here