aboutsummaryrefslogtreecommitdiff
path: root/tests/test-org-drill-determine-next-interval-sm5.el
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-04-29 09:20:08 -0500
committerCraig Jennings <c@cjennings.net>2026-04-29 09:20:08 -0500
commitf707f95d80ace08db2b65a17f2e391a5edaa278e (patch)
treebf4cb48b3399cceaa8f2b345ebd00bcf7abdf7e6 /tests/test-org-drill-determine-next-interval-sm5.el
parentbc8167388ce076c5b2a690c4d1e63c8dc82d6dfe (diff)
downloadorg-drill-f707f95d80ace08db2b65a17f2e391a5edaa278e.tar.gz
org-drill-f707f95d80ace08db2b65a17f2e391a5edaa278e.zip
refactor: extract shared scheduler test extractors
Three test files (SM2, SM5, and the upcoming Simple8) all extract the same fields from a scheduler result list. Pull the shared extractors into tests/testutil-scheduler.el so each algorithm's test file can use them. Position 2 holds an EF in SM2 and SM5 and an EASE in Simple8. Both names are exposed as aliases pointing at the same nth position so each call site reads accurately. SM2 and SM5 test files now require testutil-scheduler and call the shared helpers. 69 of 69 scheduler tests still green. Full unit suite at 180 of 180.
Diffstat (limited to 'tests/test-org-drill-determine-next-interval-sm5.el')
-rw-r--r--tests/test-org-drill-determine-next-interval-sm5.el118
1 files changed, 46 insertions, 72 deletions
diff --git a/tests/test-org-drill-determine-next-interval-sm5.el b/tests/test-org-drill-determine-next-interval-sm5.el
index dc64c7d..4e4cb7e 100644
--- a/tests/test-org-drill-determine-next-interval-sm5.el
+++ b/tests/test-org-drill-determine-next-interval-sm5.el
@@ -24,6 +24,10 @@
(require 'assess)
(require 'org-drill)
+(add-to-list 'load-path
+ (file-name-directory (or load-file-name buffer-file-name)))
+(require 'testutil-scheduler)
+
;;; Test Data and Constants
(defconst test-sm5-default-ef 2.5
@@ -33,45 +37,15 @@
"Minimum easiness factor.
The SM5 floor is shared with SM2 via `org-drill-modify-e-factor'.")
-;;; Helper Functions
-
-(defun test-sm5--extract-interval (result)
- "Extract interval from SM5 result list."
- (nth 0 result))
-
-(defun test-sm5--extract-repeats (result)
- "Extract repeats from SM5 result list."
- (nth 1 result))
-
-(defun test-sm5--extract-ef (result)
- "Extract easiness factor from SM5 result list."
- (nth 2 result))
-
-(defun test-sm5--extract-failures (result)
- "Extract failures from SM5 result list."
- (nth 3 result))
-
-(defun test-sm5--extract-meanq (result)
- "Extract mean quality from SM5 result list."
- (nth 4 result))
-
-(defun test-sm5--extract-total-repeats (result)
- "Extract total repeats from SM5 result list."
- (nth 5 result))
-
-(defun test-sm5--extract-of-matrix (result)
- "Extract optimal-factor matrix from SM5 result list."
- (nth 6 result))
-
;;; Normal Cases - Successful Reviews
(ert-deftest test-org-drill-determine-next-interval-sm5-normal-first-review-quality-4 ()
"Normal: first successful review with quality 4 returns positive interval and increments repeats."
(let ((org-drill-add-random-noise-to-intervals-p nil))
(let* ((result (org-drill-determine-next-interval-sm5 0 1 nil 4 0 nil 0 nil nil))
- (interval (test-sm5--extract-interval result))
- (repeats (test-sm5--extract-repeats result))
- (ef (test-sm5--extract-ef result)))
+ (interval (test-scheduler--extract-interval result))
+ (repeats (test-scheduler--extract-repeats result))
+ (ef (test-scheduler--extract-ef result)))
(should (> interval 0))
(should (= repeats 2))
(should ef))))
@@ -80,8 +54,8 @@ The SM5 floor is shared with SM2 via `org-drill-modify-e-factor'.")
"Normal: second successful review with quality 4 increments repeats to 3."
(let ((org-drill-add-random-noise-to-intervals-p nil))
(let* ((result (org-drill-determine-next-interval-sm5 1 2 2.5 4 0 nil 0 nil nil))
- (interval (test-sm5--extract-interval result))
- (repeats (test-sm5--extract-repeats result)))
+ (interval (test-scheduler--extract-interval result))
+ (repeats (test-scheduler--extract-repeats result)))
(should (> interval 0))
(should (= repeats 3)))))
@@ -89,8 +63,8 @@ The SM5 floor is shared with SM2 via `org-drill-modify-e-factor'.")
"Normal: third successful review uses OF-matrix lookup and returns positive interval."
(let ((org-drill-add-random-noise-to-intervals-p nil))
(let* ((result (org-drill-determine-next-interval-sm5 6 3 2.5 4 0 nil 0 nil nil))
- (interval (test-sm5--extract-interval result))
- (repeats (test-sm5--extract-repeats result)))
+ (interval (test-scheduler--extract-interval result))
+ (repeats (test-scheduler--extract-repeats result)))
(should (> interval 0))
(should (= repeats 4)))))
@@ -98,24 +72,24 @@ The SM5 floor is shared with SM2 via `org-drill-modify-e-factor'.")
"Normal: quality 5 maintains or increases EF on successful path."
(let ((org-drill-add-random-noise-to-intervals-p nil))
(let* ((result (org-drill-determine-next-interval-sm5 10 3 2.5 5 0 nil 0 nil nil))
- (ef (test-sm5--extract-ef result)))
+ (ef (test-scheduler--extract-ef result)))
(should (>= ef 2.5)))))
(ert-deftest test-org-drill-determine-next-interval-sm5-normal-quality-3-adequate-recall ()
"Normal: quality 3 decreases EF below initial but keeps it above the floor."
(let ((org-drill-add-random-noise-to-intervals-p nil))
(let* ((result (org-drill-determine-next-interval-sm5 10 3 2.5 3 0 nil 0 nil nil))
- (ef (test-sm5--extract-ef result)))
+ (ef (test-scheduler--extract-ef result)))
(should (> ef test-sm5-min-ef))
(should (< ef 2.5)))))
(ert-deftest test-org-drill-determine-next-interval-sm5-normal-failure-quality-0 ()
"Normal: failed review with quality 0 resets interval to -1, repeats to 1, increments failures."
(let* ((result (org-drill-determine-next-interval-sm5 10 3 2.5 0 0 nil 0 nil nil))
- (interval (test-sm5--extract-interval result))
- (repeats (test-sm5--extract-repeats result))
- (ef (test-sm5--extract-ef result))
- (failures (test-sm5--extract-failures result)))
+ (interval (test-scheduler--extract-interval result))
+ (repeats (test-scheduler--extract-repeats result))
+ (ef (test-scheduler--extract-ef result))
+ (failures (test-scheduler--extract-failures result)))
(should (= interval -1))
(should (= repeats 1))
(should (= ef 2.5))
@@ -124,9 +98,9 @@ The SM5 floor is shared with SM2 via `org-drill-modify-e-factor'.")
(ert-deftest test-org-drill-determine-next-interval-sm5-normal-failure-quality-1 ()
"Normal: failed review with quality 1 resets interval, preserves input EF, increments failures."
(let* ((result (org-drill-determine-next-interval-sm5 15 5 2.6 1 2 3.5 10 nil nil))
- (interval (test-sm5--extract-interval result))
- (ef (test-sm5--extract-ef result))
- (failures (test-sm5--extract-failures result)))
+ (interval (test-scheduler--extract-interval result))
+ (ef (test-scheduler--extract-ef result))
+ (failures (test-scheduler--extract-failures result)))
(should (= interval -1))
(should (= ef 2.6))
(should (= failures 3))))
@@ -134,14 +108,14 @@ The SM5 floor is shared with SM2 via `org-drill-modify-e-factor'.")
(ert-deftest test-org-drill-determine-next-interval-sm5-normal-failure-quality-2 ()
"Normal: quality 2 (= default org-drill-failure-quality) triggers failure path."
(let* ((result (org-drill-determine-next-interval-sm5 10 3 2.5 2 0 nil 0 nil nil))
- (interval (test-sm5--extract-interval result)))
+ (interval (test-scheduler--extract-interval result)))
(should (= interval -1))))
(ert-deftest test-org-drill-determine-next-interval-sm5-normal-failure-preserves-old-ef ()
"Normal: SM5 failure path returns the input EF (OLD-EF), not the modified one."
(let* ((input-ef 2.7)
(result (org-drill-determine-next-interval-sm5 10 3 input-ef 0 0 nil 0 nil nil))
- (returned-ef (test-sm5--extract-ef result)))
+ (returned-ef (test-scheduler--extract-ef result)))
;; modify-e-factor would have computed a different value, but the failure
;; branch returns old-ef, which is the input ef.
(should (= returned-ef input-ef))))
@@ -151,7 +125,7 @@ The SM5 floor is shared with SM2 via `org-drill-modify-e-factor'.")
(ert-deftest test-org-drill-determine-next-interval-sm5-boundary-nil-ef-uses-default ()
"Boundary: nil EF defaults to 2.5."
(let* ((result (org-drill-determine-next-interval-sm5 0 1 nil 4 0 nil 0 nil nil))
- (ef (test-sm5--extract-ef result)))
+ (ef (test-scheduler--extract-ef result)))
(should ef)
(should (> ef 0))))
@@ -159,27 +133,27 @@ The SM5 floor is shared with SM2 via `org-drill-modify-e-factor'.")
"Boundary: n=0 is treated as n=1, so returned repeats is 2."
(let ((org-drill-add-random-noise-to-intervals-p nil))
(let* ((result (org-drill-determine-next-interval-sm5 0 0 2.5 4 0 nil 0 nil nil))
- (repeats (test-sm5--extract-repeats result)))
+ (repeats (test-scheduler--extract-repeats result)))
(should (= repeats 2)))))
(ert-deftest test-org-drill-determine-next-interval-sm5-boundary-nil-meanq-uses-quality ()
"Boundary: nil meanq initializes to current quality."
(let* ((quality 4)
(result (org-drill-determine-next-interval-sm5 0 1 2.5 quality 0 nil 0 nil nil))
- (meanq (test-sm5--extract-meanq result)))
+ (meanq (test-scheduler--extract-meanq result)))
(should (= meanq quality))))
(ert-deftest test-org-drill-determine-next-interval-sm5-boundary-quality-5-maximum ()
"Boundary: maximum quality 5 is accepted and produces a positive interval."
(let ((org-drill-add-random-noise-to-intervals-p nil))
(let* ((result (org-drill-determine-next-interval-sm5 1 2 2.5 5 0 nil 0 nil nil))
- (interval (test-sm5--extract-interval result)))
+ (interval (test-scheduler--extract-interval result)))
(should (> interval 0)))))
(ert-deftest test-org-drill-determine-next-interval-sm5-boundary-quality-0-minimum ()
"Boundary: minimum quality 0 triggers the failure path with interval -1."
(let* ((result (org-drill-determine-next-interval-sm5 10 3 2.5 0 0 nil 0 nil nil))
- (interval (test-sm5--extract-interval result)))
+ (interval (test-scheduler--extract-interval result)))
(should (= interval -1))))
(ert-deftest test-org-drill-determine-next-interval-sm5-boundary-meanq-weighted-average ()
@@ -188,7 +162,7 @@ The SM5 floor is shared with SM2 via `org-drill-modify-e-factor'.")
(meanq 3.0)
(total-repeats 10)
(result (org-drill-determine-next-interval-sm5 10 3 2.5 quality 0 meanq total-repeats nil nil))
- (new-meanq (test-sm5--extract-meanq result))
+ (new-meanq (test-scheduler--extract-meanq result))
(expected (/ (+ quality (* meanq total-repeats 1.0))
(1+ total-repeats))))
(should (< (abs (- new-meanq expected)) 0.0001))))
@@ -197,14 +171,14 @@ The SM5 floor is shared with SM2 via `org-drill-modify-e-factor'.")
"Boundary: input EF below 1.3 is raised to 1.3 by org-drill-modify-e-factor."
(let ((org-drill-add-random-noise-to-intervals-p nil))
(let* ((result (org-drill-determine-next-interval-sm5 10 3 1.0 4 0 nil 0 nil nil))
- (ef (test-sm5--extract-ef result)))
+ (ef (test-scheduler--extract-ef result)))
(should (>= ef test-sm5-min-ef)))))
(ert-deftest test-org-drill-determine-next-interval-sm5-boundary-ef-at-floor ()
"Boundary: EF exactly at floor (1.3) does not crash and remains >= 1.3 with quality 4."
(let ((org-drill-add-random-noise-to-intervals-p nil))
(let* ((result (org-drill-determine-next-interval-sm5 10 3 1.3 4 0 4.0 10 nil nil))
- (ef (test-sm5--extract-ef result)))
+ (ef (test-scheduler--extract-ef result)))
(should (>= ef test-sm5-min-ef)))))
(ert-deftest test-org-drill-determine-next-interval-sm5-boundary-total-repeats-increments ()
@@ -212,13 +186,13 @@ The SM5 floor is shared with SM2 via `org-drill-modify-e-factor'.")
(let* ((total-repeats 42)
(result-success (org-drill-determine-next-interval-sm5 10 3 2.5 4 0 3.5 total-repeats nil nil))
(result-failure (org-drill-determine-next-interval-sm5 10 3 2.5 0 0 3.5 total-repeats nil nil)))
- (should (= (test-sm5--extract-total-repeats result-success) (1+ total-repeats)))
- (should (= (test-sm5--extract-total-repeats result-failure) (1+ total-repeats)))))
+ (should (= (test-scheduler--extract-total-repeats result-success) (1+ total-repeats)))
+ (should (= (test-scheduler--extract-total-repeats result-failure) (1+ total-repeats)))))
(ert-deftest test-org-drill-determine-next-interval-sm5-boundary-nil-of-matrix-uses-default ()
"Boundary: nil of-matrix defaults to org-drill-sm5-optimal-factor-matrix and returns a list."
(let* ((result (org-drill-determine-next-interval-sm5 0 1 2.5 4 0 nil 0 nil nil))
- (matrix (test-sm5--extract-of-matrix result)))
+ (matrix (test-scheduler--extract-of-matrix result)))
(should (listp matrix))))
(ert-deftest test-org-drill-determine-next-interval-sm5-boundary-input-matrix-not-mutated ()
@@ -235,7 +209,7 @@ The SM5 floor is shared with SM2 via `org-drill-modify-e-factor'.")
"Boundary: nil delta-days (the default) skips the early-review adjustment."
(let ((org-drill-add-random-noise-to-intervals-p nil))
(let* ((result (org-drill-determine-next-interval-sm5 6 3 2.5 4 0 nil 0 nil nil))
- (interval (test-sm5--extract-interval result)))
+ (interval (test-scheduler--extract-interval result)))
(should (numberp interval))
(should (> interval 0)))))
@@ -245,8 +219,8 @@ The SM5 floor is shared with SM2 via `org-drill-modify-e-factor'.")
(org-drill-adjust-intervals-for-early-and-late-repetitions-p t))
(let* ((result-late (org-drill-determine-next-interval-sm5 6 3 2.5 4 0 nil 0 nil 5))
(result-no-delta (org-drill-determine-next-interval-sm5 6 3 2.5 4 0 nil 0 nil nil))
- (interval-late (test-sm5--extract-interval result-late))
- (interval-no-delta (test-sm5--extract-interval result-no-delta)))
+ (interval-late (test-scheduler--extract-interval result-late))
+ (interval-no-delta (test-scheduler--extract-interval result-no-delta)))
(should (= interval-late interval-no-delta)))))
(ert-deftest test-org-drill-determine-next-interval-sm5-boundary-delta-days-negative-flag-disabled ()
@@ -255,8 +229,8 @@ The SM5 floor is shared with SM2 via `org-drill-modify-e-factor'.")
(org-drill-adjust-intervals-for-early-and-late-repetitions-p nil))
(let* ((result-no-adjust (org-drill-determine-next-interval-sm5 6 3 2.5 4 0 nil 0 nil -5))
(result-no-delta (org-drill-determine-next-interval-sm5 6 3 2.5 4 0 nil 0 nil nil))
- (interval-no-adjust (test-sm5--extract-interval result-no-adjust))
- (interval-no-delta (test-sm5--extract-interval result-no-delta)))
+ (interval-no-adjust (test-scheduler--extract-interval result-no-adjust))
+ (interval-no-delta (test-scheduler--extract-interval result-no-delta)))
(should (= interval-no-adjust interval-no-delta)))))
(ert-deftest test-org-drill-determine-next-interval-sm5-boundary-delta-days-negative-flag-enabled ()
@@ -264,7 +238,7 @@ The SM5 floor is shared with SM2 via `org-drill-modify-e-factor'.")
(let ((org-drill-add-random-noise-to-intervals-p nil)
(org-drill-adjust-intervals-for-early-and-late-repetitions-p t))
(let* ((result (org-drill-determine-next-interval-sm5 6 3 2.5 4 0 nil 0 nil -5))
- (interval (test-sm5--extract-interval result)))
+ (interval (test-scheduler--extract-interval result)))
(should (numberp interval))
(should (> interval 0)))))
@@ -304,32 +278,32 @@ The SM5 floor is shared with SM2 via `org-drill-modify-e-factor'.")
"Algorithm: quality 5 results in EF >= initial EF on the success path."
(let* ((initial-ef 2.5)
(result (org-drill-determine-next-interval-sm5 10 3 initial-ef 5 0 nil 0 nil nil))
- (new-ef (test-sm5--extract-ef result)))
+ (new-ef (test-scheduler--extract-ef result)))
(should (>= new-ef initial-ef))))
(ert-deftest test-org-drill-determine-next-interval-sm5-algorithm-ef-decreases-with-quality-3 ()
"Algorithm: quality 3 results in EF < initial EF on the success path."
(let* ((initial-ef 2.5)
(result (org-drill-determine-next-interval-sm5 10 3 initial-ef 3 0 nil 0 nil nil))
- (new-ef (test-sm5--extract-ef result)))
+ (new-ef (test-scheduler--extract-ef result)))
(should (< new-ef initial-ef))))
(ert-deftest test-org-drill-determine-next-interval-sm5-algorithm-interval-grows-over-successive-reviews ()
"Algorithm: successive successful quality-4 reviews produce strictly growing intervals."
(let ((org-drill-add-random-noise-to-intervals-p nil))
(let* ((result-2 (org-drill-determine-next-interval-sm5 1 2 2.5 4 0 nil 0 nil nil))
- (interval-2 (test-sm5--extract-interval result-2))
- (ef-2 (test-sm5--extract-ef result-2))
- (matrix-2 (test-sm5--extract-of-matrix result-2))
+ (interval-2 (test-scheduler--extract-interval result-2))
+ (ef-2 (test-scheduler--extract-ef result-2))
+ (matrix-2 (test-scheduler--extract-of-matrix result-2))
(result-3 (org-drill-determine-next-interval-sm5 interval-2 3 ef-2 4 0 nil 1 matrix-2 nil))
- (interval-3 (test-sm5--extract-interval result-3)))
+ (interval-3 (test-scheduler--extract-interval result-3)))
(should (> interval-3 interval-2)))))
(ert-deftest test-org-drill-determine-next-interval-sm5-algorithm-of-matrix-gains-entry ()
"Algorithm: of-matrix gains an entry for n after a successful call, preserving prior entries."
(let* ((input-matrix '((10 (1.0 . 1.0))))
(result (org-drill-determine-next-interval-sm5 0 1 2.5 4 0 nil 0 input-matrix nil))
- (output-matrix (test-sm5--extract-of-matrix result)))
+ (output-matrix (test-scheduler--extract-of-matrix result)))
(should (assoc 1 output-matrix)) ; new entry for n=1 was added
(should (assoc 10 output-matrix)))) ; unrelated entry for n=10 preserved