diff options
| author | Craig Jennings <c@cjennings.net> | 2026-04-30 09:25:18 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-04-30 09:25:18 -0500 |
| commit | 467a6d63f44ba835a94e7580adff9ff6b2b1a1eb (patch) | |
| tree | 1399981f7689280884229a96acce6225dbd2aefd /tests/test-config-utilities--validate-timestamps-in-buffer.el | |
| parent | f90a087d5025952f0ca1b81d322f29891a40e540 (diff) | |
| download | dotemacs-467a6d63f44ba835a94e7580adff9ff6b2b1a1eb.tar.gz dotemacs-467a6d63f44ba835a94e7580adff9ff6b2b1a1eb.zip | |
test(config-utilities): cover validate-timestamps and format-report helpers
Two test files covering the extracted timestamp-validation helpers.
cj/--validate-timestamps-in-buffer (8 tests): empty buffer no-op,
buffer with no timestamps, buffer with all valid timestamps,
DEADLINE flagged with "DEADLINE" property, SCHEDULED flagged with
"SCHEDULED", inline-timestamp flagged with "inline timestamp",
multiple invalid collected in document order, mixed valid+invalid
returning only the invalid one. Tests use real org parsing and
mock org-time-string-to-absolute at the boundary so an arbitrary
timestamp can be marked invalid for a given test.
cj/--format-validation-report-section (4 tests): no-entries says
"No invalid timestamps found", single-entry produces the file: link
+ Property/Type + Invalid timestamp lines, multiple-entry preserves
input order, every section ends with a trailing blank line.
Diffstat (limited to 'tests/test-config-utilities--validate-timestamps-in-buffer.el')
| -rw-r--r-- | tests/test-config-utilities--validate-timestamps-in-buffer.el | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/tests/test-config-utilities--validate-timestamps-in-buffer.el b/tests/test-config-utilities--validate-timestamps-in-buffer.el new file mode 100644 index 00000000..8ca51a55 --- /dev/null +++ b/tests/test-config-utilities--validate-timestamps-in-buffer.el @@ -0,0 +1,130 @@ +;;; test-config-utilities--validate-timestamps-in-buffer.el --- Tests for cj/--validate-timestamps-in-buffer -*- lexical-binding: t; -*- + +;;; Commentary: +;; Tests for `cj/--validate-timestamps-in-buffer'. The function walks +;; an org buffer's headlines, checks DEADLINE/SCHEDULED/TIMESTAMP +;; properties plus inline timestamps, and returns a list of tuples +;; for every timestamp where `org-time-string-to-absolute' returns +;; nil. Tests use real org parsing on real timestamps and mock the +;; validator at the boundary so an arbitrary timestamp can be marked +;; invalid for the test. + +;;; Code: + +(require 'ert) +(require 'cl-lib) + +(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory)) +(require 'config-utilities) +(require 'org) +(require 'org-element) + +(defmacro test-config-utilities--with-org-buffer (content &rest body) + "Run BODY in a temp buffer holding CONTENT in `org-mode'." + (declare (indent 1) (debug t)) + `(with-temp-buffer + (let ((org-mode-hook nil)) + (insert ,content) + (org-mode) + ,@body))) + +(defmacro test-config-utilities--with-invalid-timestamps (invalid-set &rest body) + "Run BODY with `org-time-string-to-absolute' returning nil for any +timestamp string in INVALID-SET, normal behaviour otherwise." + (declare (indent 1) (debug t)) + `(let ((--invalid-set ,invalid-set) + (--orig (symbol-function 'org-time-string-to-absolute))) + (cl-letf (((symbol-function 'org-time-string-to-absolute) + (lambda (s &rest args) + (if (member s --invalid-set) + (error "test-mocked invalid timestamp: %s" s) + (apply --orig s args))))) + ,@body))) + +(ert-deftest test-config-utilities-validate-buffer-no-timestamps-returns-empty () + "Boundary: a buffer with no timestamps returns an empty list." + (test-config-utilities--with-org-buffer "* Heading\nJust prose.\n" + (should-not (cj/--validate-timestamps-in-buffer "/x.org")))) + +(ert-deftest test-config-utilities-validate-buffer-empty-buffer-returns-empty () + "Boundary: an empty buffer returns an empty list." + (test-config-utilities--with-org-buffer "" + (should-not (cj/--validate-timestamps-in-buffer "/x.org")))) + +(ert-deftest test-config-utilities-validate-buffer-valid-timestamps-returns-empty () + "Normal: every valid timestamp passes; the result is empty." + (test-config-utilities--with-org-buffer + "* Headline +DEADLINE: <2026-04-30 Thu> +" + (should-not (cj/--validate-timestamps-in-buffer "/x.org")))) + +(ert-deftest test-config-utilities-validate-buffer-deadline-flagged-when-invalid () + "Normal: an invalid DEADLINE is flagged with property \"DEADLINE\"." + (test-config-utilities--with-org-buffer + "* Bad +DEADLINE: <2026-04-30 Thu> +" + (test-config-utilities--with-invalid-timestamps '("<2026-04-30 Thu>") + (let ((result (cj/--validate-timestamps-in-buffer "/x.org"))) + (should (= 1 (length result))) + (cl-destructuring-bind (file _pos head prop ts) (car result) + (should (equal file "/x.org")) + (should (equal head "Bad")) + (should (equal prop "DEADLINE")) + (should (equal ts "<2026-04-30 Thu>"))))))) + +(ert-deftest test-config-utilities-validate-buffer-scheduled-flagged-when-invalid () + "Normal: an invalid SCHEDULED is flagged with property \"SCHEDULED\"." + (test-config-utilities--with-org-buffer + "* Sched +SCHEDULED: <2026-05-01 Fri> +" + (test-config-utilities--with-invalid-timestamps '("<2026-05-01 Fri>") + (let ((result (cj/--validate-timestamps-in-buffer "/x.org"))) + (should (= 1 (length result))) + (should (equal "SCHEDULED" (nth 3 (car result)))))))) + +(ert-deftest test-config-utilities-validate-buffer-inline-flagged-as-inline () + "Normal: an invalid inline timestamp in headline contents is flagged +with property \"inline timestamp\"." + (test-config-utilities--with-org-buffer + "* Body has timestamp +Some prose mentioning <2026-06-01 Mon> in passing. +" + (test-config-utilities--with-invalid-timestamps '("<2026-06-01 Mon>") + (let ((result (cj/--validate-timestamps-in-buffer "/x.org"))) + (should (= 1 (length result))) + (should (equal "inline timestamp" (nth 3 (car result)))))))) + +(ert-deftest test-config-utilities-validate-buffer-multiple-invalid-collected-in-order () + "Normal: multiple invalid timestamps are returned in document order." + (test-config-utilities--with-org-buffer + "* First +DEADLINE: <2026-01-01 Thu> +* Second +SCHEDULED: <2026-02-02 Mon> +" + (test-config-utilities--with-invalid-timestamps + '("<2026-01-01 Thu>" "<2026-02-02 Mon>") + (let ((result (cj/--validate-timestamps-in-buffer "/x.org"))) + (should (= 2 (length result))) + (should (equal "First" (nth 2 (nth 0 result)))) + (should (equal "Second" (nth 2 (nth 1 result)))))))) + +(ert-deftest test-config-utilities-validate-buffer-mixed-valid-and-invalid () + "Boundary: buffer with one valid and one invalid timestamp returns +only the invalid one." + (test-config-utilities--with-org-buffer + "* Good +DEADLINE: <2026-04-30 Thu> +* Bad +DEADLINE: <2026-12-25 Fri> +" + (test-config-utilities--with-invalid-timestamps '("<2026-12-25 Fri>") + (let ((result (cj/--validate-timestamps-in-buffer "/x.org"))) + (should (= 1 (length result))) + (should (equal "Bad" (nth 2 (car result)))))))) + +(provide 'test-config-utilities--validate-timestamps-in-buffer) +;;; test-config-utilities--validate-timestamps-in-buffer.el ends here |
