diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-05 04:29:32 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-05 04:29:32 -0500 |
| commit | 08fbd97864ef86ed127e0d6a5fb3005c53db47f8 (patch) | |
| tree | affe7ca6e0867828bfa3256faee5349306b56267 | |
| parent | b2cc4d1645b378043a971906b5ebc34d3c92b544 (diff) | |
| download | org-drill-08fbd97864ef86ed127e0d6a5fb3005c53db47f8.tar.gz org-drill-08fbd97864ef86ed127e0d6a5fb3005c53db47f8.zip | |
test: add coverage for org-drill-smart-reschedule
6 ERT tests covering all four days-ahead branches:
- 0 → unschedule (treat as new again)
- negative → schedule today (current-time)
- positive → schedule N days ahead
- nil → use the algorithm-computed next-interval (locks in the
numberp guard fix)
Plus property side-effects: writes DRILL_LAST_INTERVAL / EASE /
TOTAL_REPEATS via store-item-data, and TOTAL_REPEATS increments on
each call.
| -rw-r--r-- | tests/test-org-drill-smart-reschedule.el | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/tests/test-org-drill-smart-reschedule.el b/tests/test-org-drill-smart-reschedule.el new file mode 100644 index 0000000..49eddb0 --- /dev/null +++ b/tests/test-org-drill-smart-reschedule.el @@ -0,0 +1,119 @@ +;;; test-org-drill-smart-reschedule.el --- Tests for smart-reschedule -*- lexical-binding: t; -*- + +;;; Commentary: +;; Tests for `org-drill-smart-reschedule', the function that runs after a +;; user rates a card. It updates the card's DRILL_* properties via +;; store-item-data and then sets a fresh SCHEDULED stamp. +;; +;; Three days-ahead branches: +;; +;; - 0 → unschedule (treat as new again) +;; - <0 → schedule for today (right now) +;; - >0 → schedule N days from today +;; - nil → use the algorithm-computed next-interval (this branch was +;; broken before the fix — `(= 0 nil)' errored). +;; +;; The user-facing contract: rate a card, see the next-review date +;; advance to a sensible point. + +;;; Code: + +(require 'ert) +(require 'cl-lib) +(require 'org) +(require 'org-drill) + +;;;; Helpers + +(defmacro with-fresh-drill-entry (&rest body) + (declare (indent 0)) + `(with-temp-buffer + (let ((org-startup-folded nil)) + (insert "* Question :drill:\n") + (org-mode) + (goto-char (point-min)) + ,@body))) + +(defmacro with-fixed-now (&rest body) + `(cl-letf (((symbol-function 'current-time) + (lambda () (encode-time 0 0 12 5 5 2026)))) + ,@body)) + +(defun current-scheduled-time-string () + "Return SCHEDULED stamp on entry at point or nil." + (org-entry-get (point) "SCHEDULED")) + +;;;; Branch: days-ahead = 0 (unschedule) + +(ert-deftest test-org-drill-smart-reschedule-zero-days-ahead-unschedules () + "Passing 0 removes the SCHEDULED stamp — the entry is treated as new again." + (with-fresh-drill-entry + (org-schedule nil "2026-05-01") + (with-fixed-now + (org-drill-smart-reschedule 4 0)) + (should (null (current-scheduled-time-string))))) + +;;;; Branch: days-ahead < 0 (today) + +(ert-deftest test-org-drill-smart-reschedule-negative-schedules-today () + "Negative days-ahead schedules for current-time (today)." + (with-fresh-drill-entry + (with-fixed-now + (org-drill-smart-reschedule 4 -1)) + (let ((scheduled (current-scheduled-time-string))) + (should scheduled) + ;; Scheduled stamp matches today's date. + (should (string-match-p "2026-05-05" scheduled))))) + +;;;; Branch: days-ahead > 0 (N days from today) + +(ert-deftest test-org-drill-smart-reschedule-positive-schedules-n-days-ahead () + "Positive days-ahead schedules exactly N days into the future." + (with-fresh-drill-entry + (with-fixed-now + (org-drill-smart-reschedule 4 7)) + (let ((scheduled (current-scheduled-time-string))) + (should scheduled) + ;; 2026-05-05 + 7 days = 2026-05-12. + (should (string-match-p "2026-05-12" scheduled))))) + +;;;; Branch: days-ahead = nil (use algorithm) + +(ert-deftest test-org-drill-smart-reschedule-nil-days-ahead-uses-algorithm () + "Without days-ahead, fall back to the scheduler's computed next-interval. +Pre-fix this branch crashed with `Wrong type argument: number-or-marker-p, nil' +because the cond compared nil with `=' before the type-guard." + (with-fresh-drill-entry + (with-fixed-now + ;; Should not error. The scheduled date should be in the future + ;; (some sensible interval). + (org-drill-smart-reschedule 5) + (let ((scheduled (current-scheduled-time-string))) + (should scheduled))))) + +;;;; Property side-effects + +(ert-deftest test-org-drill-smart-reschedule-writes-drill-properties () + "Rescheduling also writes DRILL_* properties via store-item-data." + (with-fresh-drill-entry + (with-fixed-now + (org-drill-smart-reschedule 5 7)) + (should (org-entry-get (point) "DRILL_LAST_INTERVAL")) + (should (org-entry-get (point) "DRILL_TOTAL_REPEATS")) + (should (org-entry-get (point) "DRILL_EASE")))) + +(ert-deftest test-org-drill-smart-reschedule-increments-total-repeats () + "Each rating increments DRILL_TOTAL_REPEATS." + (with-fresh-drill-entry + (with-fixed-now + (org-drill-smart-reschedule 4 7) + (let ((after-first (string-to-number + (org-entry-get (point) "DRILL_TOTAL_REPEATS")))) + (org-drill-smart-reschedule 4 7) + (let ((after-second (string-to-number + (org-entry-get (point) "DRILL_TOTAL_REPEATS")))) + (should (= (1+ after-first) after-second))))))) + +(provide 'test-org-drill-smart-reschedule) + +;;; test-org-drill-smart-reschedule.el ends here |
