blob: 6359689f94f4dc0b02b1ef6518705808e4a997c8 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
;;; test-org-spec-links.el --- docs/specs org-id resolution -*- lexical-binding: t; -*-
;;; Commentary:
;; Tests for the docs/specs spec-file scanner behind org-id link
;; resolution (org-spec-links.el). Projects are directories carrying
;; .ai/protocols.org; each contributes its docs/specs/*.org files. The
;; scanner takes explicit base dirs so the tests run against a sandbox.
;;; Code:
(require 'ert)
(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory))
(require 'org-spec-links)
;; org-id may never load in batch; declare its var special so the
;; let-binding below is dynamic, not a silent lexical shadow.
(defvar org-id-extra-files)
(defun test-org-spec-links--make-sandbox ()
"Build a sandbox: two projects, one with specs, one without; one non-project."
(let ((base (make-temp-file "spec-links-" t)))
;; p1: a project with two spec files
(make-directory (expand-file-name "p1/.ai" base) t)
(write-region "" nil (expand-file-name "p1/.ai/protocols.org" base))
(make-directory (expand-file-name "p1/docs/specs" base) t)
(write-region "" nil (expand-file-name "p1/docs/specs/a-spec.org" base))
(write-region "" nil (expand-file-name "p1/docs/specs/b-spec.org" base))
;; p2: a project with no docs/specs
(make-directory (expand-file-name "p2/.ai" base) t)
(write-region "" nil (expand-file-name "p2/.ai/protocols.org" base))
;; p3: not a project (no protocols.org) but has docs/specs
(make-directory (expand-file-name "p3/docs/specs" base) t)
(write-region "" nil (expand-file-name "p3/docs/specs/c-spec.org" base))
base))
(ert-deftest test-org-spec-links-scanner-finds-project-specs ()
"Normal: spec files from protocols-carrying projects only, absolute paths."
(let ((base (test-org-spec-links--make-sandbox)))
(unwind-protect
(let ((files (cj/--org-spec-files (list base))))
(should (= (length files) 2))
(should (cl-every #'file-name-absolute-p files))
(should (seq-find (lambda (f) (string-suffix-p "p1/docs/specs/a-spec.org" f)) files))
(should (seq-find (lambda (f) (string-suffix-p "p1/docs/specs/b-spec.org" f)) files))
(should-not (seq-find (lambda (f) (string-match-p "p3" f)) files)))
(delete-directory base t))))
(ert-deftest test-org-spec-links-scanner-empty-base ()
"Boundary: a base dir with no projects yields nil."
(let ((base (make-temp-file "spec-links-empty-" t)))
(unwind-protect
(should-not (cj/--org-spec-files (list base)))
(delete-directory base t))))
(ert-deftest test-org-spec-links-scanner-missing-base ()
"Error: a non-existent base dir is skipped without signaling."
(should-not (cj/--org-spec-files '("/nonexistent/base/dir"))))
(ert-deftest test-org-spec-links-refresh-sets-extra-files ()
"Normal: the refresh command points org-id-extra-files at the scan result."
(let* ((base (test-org-spec-links--make-sandbox))
(org-id-extra-files nil)
;; the default scan appends user-emacs-directory; point it into
;; the sandbox so the real config's specs don't leak in
(user-emacs-directory (expand-file-name "p2/" base)))
(unwind-protect
(cl-letf (((symbol-function 'cj/--org-spec-project-base-dirs)
(lambda () (list base)))
;; org-id may be absent in batch; the update step is mocked.
((symbol-function 'org-id-update-id-locations)
(lambda (&rest _) nil)))
(cj/org-id-refresh-spec-locations)
(should (= (length org-id-extra-files) 2)))
(delete-directory base t))))
(provide 'test-org-spec-links)
;;; test-org-spec-links.el ends here
|