blob: 49eddb04fcf57e0bac5ab936e5a207f84e483f42 (
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
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
|