diff options
| -rw-r--r-- | org-drill.el | 37 | ||||
| -rw-r--r-- | tests/test-org-drill-determine-next-interval-sm2.el | 92 | ||||
| -rw-r--r-- | tests/testutil-scheduler.el | 14 |
3 files changed, 75 insertions, 68 deletions
diff --git a/org-drill.el b/org-drill.el index fd6f24e..7046ade 100644 --- a/org-drill.el +++ b/org-drill.el @@ -1232,13 +1232,12 @@ caller passes the scheduler's next-interval there)." (org-drill-round-float (org-drill-card-state-ease state) 3)))) ;;; SM2 Algorithm ============================================================= -(defun org-drill-determine-next-interval-sm2 (last-interval n ef quality - failures meanq total-repeats) - "Arguments: -- LAST-INTERVAL -- the number of days since the item was last reviewed. -- REPEATS -- the number of times the item has been successfully reviewed -- EF -- the \\='easiness factor\\=' -- QUALITY -- 0 to 5 +(defun org-drill-determine-next-interval-sm2 (state quality) + "Return the SM2 schedule for STATE after a review of recall QUALITY (0-5). + +STATE is an `org-drill-card-state' carrying LAST-INTERVAL, REPETITIONS, +EASE (the \\='easiness factor\\='), FAILURES, MEANQ and TOTAL-REPEATS. +QUALITY is the rating just entered. Returns a list: (INTERVAL REPEATS EF FAILURES MEAN TOTAL-REPEATS OFMATRIX), where: @@ -1246,6 +1245,12 @@ Returns a list: - REPEATS is incremented by 1. - EF is modified based on the recall quality for the item. - OF-MATRIX is not modified." + (let ((last-interval (org-drill-card-state-last-interval state)) + (n (org-drill-card-state-repetitions state)) + (ef (org-drill-card-state-ease state)) + (failures (org-drill-card-state-failures state)) + (meanq (org-drill-card-state-meanq state)) + (total-repeats (org-drill-card-state-total-repeats state))) (if (zerop n) (setq n 1)) (if (null ef) (setq ef 2.5)) (setq meanq (if meanq @@ -1282,7 +1287,7 @@ Returns a list: (1+ n) next-ef failures meanq (1+ total-repeats) - org-drill-sm5-optimal-factor-matrix)))) + org-drill-sm5-optimal-factor-matrix))))) ;;; SM5 Algorithm ============================================================= (defun org-drill-modify-e-factor (ef quality) @@ -1520,13 +1525,7 @@ item will be scheduled exactly this many days into the future." (org-drill-card-state-failures state) (org-drill-card-state-meanq state) (org-drill-card-state-total-repeats state) ofmatrix)) - (sm2 (org-drill-determine-next-interval-sm2 - (org-drill-card-state-last-interval state) - (org-drill-card-state-repetitions state) - (org-drill-card-state-ease state) quality - (org-drill-card-state-failures state) - (org-drill-card-state-meanq state) - (org-drill-card-state-total-repeats state))) + (sm2 (org-drill-determine-next-interval-sm2 state quality)) (simple8 (org-drill-determine-next-interval-simple8 (org-drill-card-state-last-interval state) (org-drill-card-state-repetitions state) @@ -1590,13 +1589,7 @@ of QUALITY." (org-drill-card-state-meanq state) (org-drill-card-state-total-repeats state) org-drill-sm5-optimal-factor-matrix)) - (sm2 (org-drill-determine-next-interval-sm2 - (org-drill-card-state-last-interval state) - (org-drill-card-state-repetitions state) - (org-drill-card-state-ease state) quality - (org-drill-card-state-failures state) - (org-drill-card-state-meanq state) - (org-drill-card-state-total-repeats state))) + (sm2 (org-drill-determine-next-interval-sm2 state quality)) (simple8 (org-drill-determine-next-interval-simple8 (org-drill-card-state-last-interval state) (org-drill-card-state-repetitions state) diff --git a/tests/test-org-drill-determine-next-interval-sm2.el b/tests/test-org-drill-determine-next-interval-sm2.el index 8405968..b367f33 100644 --- a/tests/test-org-drill-determine-next-interval-sm2.el +++ b/tests/test-org-drill-determine-next-interval-sm2.el @@ -12,7 +12,7 @@ ;; - Failure count and statistics ;; ;; Function signature: -;; (org-drill-determine-next-interval-sm2 last-interval n ef quality +;; (test-scheduler--call-sm2 last-interval n ef quality ;; failures meanq total-repeats) ;; ;; Returns: (INTERVAL REPEATS EF FAILURES MEAN TOTAL-REPEATS OFMATRIX) @@ -41,7 +41,7 @@ (ert-deftest test-org-drill-determine-next-interval-sm2-normal-first-review-quality-4 () "Test first successful review with quality 4. First review (n=1) should return interval of 1 day." - (let* ((result (org-drill-determine-next-interval-sm2 0 1 nil 4 0 nil 0)) + (let* ((result (test-scheduler--call-sm2 0 1 nil 4 0 nil 0)) (interval (test-scheduler--extract-interval result)) (repeats (test-scheduler--extract-repeats result)) (ef (test-scheduler--extract-ef result))) @@ -53,7 +53,7 @@ First review (n=1) should return interval of 1 day." "Test second successful review with quality 4. Second review (n=2) should return interval of 6 days (no random noise)." (let ((org-drill-add-random-noise-to-intervals-p nil)) - (let* ((result (org-drill-determine-next-interval-sm2 1 2 2.5 4 0 nil 0)) + (let* ((result (test-scheduler--call-sm2 1 2 2.5 4 0 nil 0)) (interval (test-scheduler--extract-interval result)) (repeats (test-scheduler--extract-repeats result))) (should (= interval 6)) @@ -65,7 +65,7 @@ Third review (n=3) uses formula: last-interval * EF." (let ((org-drill-add-random-noise-to-intervals-p nil)) (let* ((ef 2.5) (last-interval 6) - (result (org-drill-determine-next-interval-sm2 last-interval 3 ef 4 0 nil 0)) + (result (test-scheduler--call-sm2 last-interval 3 ef 4 0 nil 0)) (interval (test-scheduler--extract-interval result)) (new-ef (test-scheduler--extract-ef result))) ;; Interval should be approximately last-interval * new-ef @@ -76,7 +76,7 @@ Third review (n=3) uses formula: last-interval * EF." "Test review with perfect recall (quality 5). Quality 5 should increase EF and result in longer intervals." (let ((org-drill-add-random-noise-to-intervals-p nil)) - (let* ((result (org-drill-determine-next-interval-sm2 10 3 2.5 5 0 nil 0)) + (let* ((result (test-scheduler--call-sm2 10 3 2.5 5 0 nil 0)) (ef (test-scheduler--extract-ef result))) ;; Quality 5 should maintain or increase EF (should (>= ef 2.5))))) @@ -85,7 +85,7 @@ Quality 5 should increase EF and result in longer intervals." "Test review with adequate recall (quality 3). Quality 3 should maintain relatively stable EF." (let ((org-drill-add-random-noise-to-intervals-p nil)) - (let* ((result (org-drill-determine-next-interval-sm2 10 3 2.5 3 0 nil 0)) + (let* ((result (test-scheduler--call-sm2 10 3 2.5 3 0 nil 0)) (ef (test-scheduler--extract-ef result))) ;; Quality 3 should result in moderate EF (should (> ef test-sm2-min-ef)) @@ -96,7 +96,7 @@ Quality 3 should maintain relatively stable EF." (ert-deftest test-org-drill-determine-next-interval-sm2-normal-failure-quality-0 () "Test failed review with quality 0. Quality 0 (<= org-drill-failure-quality) should reset interval to -1." - (let* ((result (org-drill-determine-next-interval-sm2 10 3 2.5 0 0 nil 0)) + (let* ((result (test-scheduler--call-sm2 10 3 2.5 0 0 nil 0)) (interval (test-scheduler--extract-interval result)) (repeats (test-scheduler--extract-repeats result)) (ef (test-scheduler--extract-ef result)) @@ -109,7 +109,7 @@ Quality 0 (<= org-drill-failure-quality) should reset interval to -1." (ert-deftest test-org-drill-determine-next-interval-sm2-normal-failure-quality-1 () "Test failed review with quality 1. Quality 1 (<= org-drill-failure-quality) should reset interval." - (let* ((result (org-drill-determine-next-interval-sm2 15 5 2.6 1 2 3.5 10)) + (let* ((result (test-scheduler--call-sm2 15 5 2.6 1 2 3.5 10)) (interval (test-scheduler--extract-interval result)) (ef (test-scheduler--extract-ef result)) (failures (test-scheduler--extract-failures result))) @@ -120,7 +120,7 @@ Quality 1 (<= org-drill-failure-quality) should reset interval." (ert-deftest test-org-drill-determine-next-interval-sm2-normal-failure-quality-2 () "Test failed review with quality 2. Quality 2 (= org-drill-failure-quality default) should reset interval." - (let* ((result (org-drill-determine-next-interval-sm2 10 3 2.5 2 0 nil 0)) + (let* ((result (test-scheduler--call-sm2 10 3 2.5 2 0 nil 0)) (interval (test-scheduler--extract-interval result))) (should (= interval -1)))) @@ -128,14 +128,14 @@ Quality 2 (= org-drill-failure-quality default) should reset interval." (ert-deftest test-org-drill-determine-next-interval-sm2-boundary-nil-ef-uses-default () "Test that nil EF defaults to 2.5." - (let* ((result (org-drill-determine-next-interval-sm2 0 1 nil 4 0 nil 0)) + (let* ((result (test-scheduler--call-sm2 0 1 nil 4 0 nil 0)) (ef (test-scheduler--extract-ef result))) (should ef) ; EF should be set (modified from default 2.5) (should (> ef 0)))) (ert-deftest test-org-drill-determine-next-interval-sm2-boundary-zero-n-becomes-one () "Test that n=0 is treated as n=1." - (let* ((result (org-drill-determine-next-interval-sm2 0 0 2.5 4 0 nil 0)) + (let* ((result (test-scheduler--call-sm2 0 0 2.5 4 0 nil 0)) (interval (test-scheduler--extract-interval result)) (repeats (test-scheduler--extract-repeats result))) (should (= interval 1)) ; First review interval @@ -144,7 +144,7 @@ Quality 2 (= org-drill-failure-quality default) should reset interval." (ert-deftest test-org-drill-determine-next-interval-sm2-boundary-nil-meanq-uses-quality () "Test that nil meanq initializes to current quality." (let* ((quality 4) - (result (org-drill-determine-next-interval-sm2 0 1 2.5 quality 0 nil 0)) + (result (test-scheduler--call-sm2 0 1 2.5 quality 0 nil 0)) (meanq (test-scheduler--extract-meanq result))) (should (= meanq quality)))) @@ -153,13 +153,13 @@ Quality 2 (= org-drill-failure-quality default) should reset interval." (ert-deftest test-org-drill-determine-next-interval-sm2-boundary-quality-5-maximum () "Test maximum quality (5) - perfect recall." (let ((org-drill-add-random-noise-to-intervals-p nil)) - (let* ((result (org-drill-determine-next-interval-sm2 1 2 2.5 5 0 nil 0)) + (let* ((result (test-scheduler--call-sm2 1 2 2.5 5 0 nil 0)) (interval (test-scheduler--extract-interval result))) (should (= interval 6))))) ; Second review with quality 5 (ert-deftest test-org-drill-determine-next-interval-sm2-boundary-quality-0-minimum () "Test minimum quality (0) - complete failure." - (let* ((result (org-drill-determine-next-interval-sm2 10 3 2.5 0 0 nil 0)) + (let* ((result (test-scheduler--call-sm2 10 3 2.5 0 0 nil 0)) (interval (test-scheduler--extract-interval result))) (should (= interval -1)))) ; Failed review @@ -167,7 +167,7 @@ Quality 2 (= org-drill-failure-quality default) should reset interval." (ert-deftest test-org-drill-determine-next-interval-sm2-boundary-n-equals-1 () "Test first successful review (n=1) returns interval of 1." - (let* ((result (org-drill-determine-next-interval-sm2 0 1 2.5 4 0 nil 0)) + (let* ((result (test-scheduler--call-sm2 0 1 2.5 4 0 nil 0)) (interval (test-scheduler--extract-interval result))) (should (= interval 1)))) @@ -175,7 +175,7 @@ Quality 2 (= org-drill-failure-quality default) should reset interval." "Test second review (n=2) with no random noise. Should return interval of 6 days regardless of quality (if passing)." (let ((org-drill-add-random-noise-to-intervals-p nil)) - (let* ((result (org-drill-determine-next-interval-sm2 1 2 2.5 4 0 nil 0)) + (let* ((result (test-scheduler--call-sm2 1 2 2.5 4 0 nil 0)) (interval (test-scheduler--extract-interval result))) (should (= interval 6))))) @@ -183,9 +183,9 @@ Should return interval of 6 days regardless of quality (if passing)." "Test second review (n=2) with random noise enabled. Interval should vary by quality, with quality 5 having highest base interval (6)." (let ((org-drill-add-random-noise-to-intervals-p t)) - (let* ((result-q5 (org-drill-determine-next-interval-sm2 1 2 2.5 5 0 nil 0)) - (result-q4 (org-drill-determine-next-interval-sm2 1 2 2.5 4 0 nil 0)) - (result-q3 (org-drill-determine-next-interval-sm2 1 2 2.5 3 0 nil 0)) + (let* ((result-q5 (test-scheduler--call-sm2 1 2 2.5 5 0 nil 0)) + (result-q4 (test-scheduler--call-sm2 1 2 2.5 4 0 nil 0)) + (result-q3 (test-scheduler--call-sm2 1 2 2.5 3 0 nil 0)) (interval-q5 (test-scheduler--extract-interval result-q5)) (interval-q4 (test-scheduler--extract-interval result-q4)) (interval-q3 (test-scheduler--extract-interval result-q3))) @@ -206,7 +206,7 @@ meanq = (quality + meanq * total-repeats) / (total-repeats + 1)" (let* ((quality 4) (meanq 3.0) (total-repeats 10) - (result (org-drill-determine-next-interval-sm2 10 3 2.5 quality 0 meanq total-repeats)) + (result (test-scheduler--call-sm2 10 3 2.5 quality 0 meanq total-repeats)) (new-meanq (test-scheduler--extract-meanq result)) (expected-meanq (/ (+ quality (* meanq total-repeats 1.0)) (1+ total-repeats)))) @@ -217,7 +217,7 @@ meanq = (quality + meanq * total-repeats) / (total-repeats + 1)" (ert-deftest test-org-drill-determine-next-interval-sm2-boundary-ef-minimum-floor () "Test that EF floor of 1.3 is applied to input EF when it's below 1.3. If input EF < 1.3, org-drill-modify-e-factor returns 1.3 exactly." - (let* ((result (org-drill-determine-next-interval-sm2 10 3 1.0 4 0 nil 0)) + (let* ((result (test-scheduler--call-sm2 10 3 1.0 4 0 nil 0)) (ef (test-scheduler--extract-ef result))) ;; Input EF was 1.0 < 1.3, so it should be raised to 1.3 first, ;; then modified based on quality 4 (which increases EF) @@ -228,7 +228,7 @@ If input EF < 1.3, org-drill-modify-e-factor returns 1.3 exactly." (ert-deftest test-org-drill-determine-next-interval-sm2-boundary-total-repeats-increments () "Test that total-repeats is always incremented by 1." (let* ((total-repeats 42) - (result (org-drill-determine-next-interval-sm2 10 3 2.5 4 0 3.5 total-repeats)) + (result (test-scheduler--call-sm2 10 3 2.5 4 0 3.5 total-repeats)) (new-total (test-scheduler--extract-total-repeats result))) (should (= new-total (1+ total-repeats))))) @@ -237,7 +237,7 @@ If input EF < 1.3, org-drill-modify-e-factor returns 1.3 exactly." (ert-deftest test-org-drill-determine-next-interval-sm2-normal-return-value-structure () "Test that return value has correct structure. Should return 7-element list: (INTERVAL REPEATS EF FAILURES MEAN TOTAL-REPEATS OFMATRIX)" - (let ((result (org-drill-determine-next-interval-sm2 10 3 2.5 4 0 3.5 10))) + (let ((result (test-scheduler--call-sm2 10 3 2.5 4 0 3.5 10))) (should (listp result)) (should (= (length result) 7)) ;; Verify first 6 elements are numbers @@ -257,7 +257,7 @@ Should return 7-element list: (INTERVAL REPEATS EF FAILURES MEAN TOTAL-REPEATS O "Test that higher quality results in higher EF (or maintains it). Quality 5 should result in EF >= initial EF." (let* ((initial-ef 2.5) - (result (org-drill-determine-next-interval-sm2 10 3 initial-ef 5 0 nil 0)) + (result (test-scheduler--call-sm2 10 3 initial-ef 5 0 nil 0)) (new-ef (test-scheduler--extract-ef result))) (should (>= new-ef initial-ef)))) @@ -265,7 +265,7 @@ Quality 5 should result in EF >= initial EF." "Test that low quality results in decreased EF. Quality 3 should result in EF < initial EF." (let* ((initial-ef 2.5) - (result (org-drill-determine-next-interval-sm2 10 3 initial-ef 3 0 nil 0)) + (result (test-scheduler--call-sm2 10 3 initial-ef 3 0 nil 0)) (new-ef (test-scheduler--extract-ef result))) (should (< new-ef initial-ef)))) @@ -274,10 +274,10 @@ Quality 3 should result in EF < initial EF." Third review interval should be significantly larger than second." (let ((org-drill-add-random-noise-to-intervals-p nil)) (let* ((ef 2.5) - (result-2nd (org-drill-determine-next-interval-sm2 1 2 ef 4 0 nil 0)) + (result-2nd (test-scheduler--call-sm2 1 2 ef 4 0 nil 0)) (interval-2nd (test-scheduler--extract-interval result-2nd)) (ef-2nd (test-scheduler--extract-ef result-2nd)) - (result-3rd (org-drill-determine-next-interval-sm2 interval-2nd 3 ef-2nd 4 0 nil 1)) + (result-3rd (test-scheduler--call-sm2 interval-2nd 3 ef-2nd 4 0 nil 1)) (interval-3rd (test-scheduler--extract-interval result-3rd))) (should (> interval-3rd (* interval-2nd 1.5)))))) ; Significant growth @@ -287,7 +287,7 @@ Third review interval should be significantly larger than second." "Test SM2 with very high repeat count (1000 reviews). Algorithm should remain stable with extreme n values." (let ((org-drill-add-random-noise-to-intervals-p nil)) - (let* ((result (org-drill-determine-next-interval-sm2 365 1000 2.5 4 0 4.0 1000)) + (let* ((result (test-scheduler--call-sm2 365 1000 2.5 4 0 4.0 1000)) (interval (test-scheduler--extract-interval result)) (repeats (test-scheduler--extract-repeats result)) (ef (test-scheduler--extract-ef result))) @@ -300,7 +300,7 @@ Algorithm should remain stable with extreme n values." "Test SM2 with very long last interval (10 years = 3650 days). Algorithm should handle extreme intervals without overflow." (let ((org-drill-add-random-noise-to-intervals-p nil)) - (let* ((result (org-drill-determine-next-interval-sm2 3650 100 2.5 4 0 4.0 100)) + (let* ((result (test-scheduler--call-sm2 3650 100 2.5 4 0 4.0 100)) (interval (test-scheduler--extract-interval result))) (should (numberp interval)) (should (> interval 0))))) @@ -309,7 +309,7 @@ Algorithm should handle extreme intervals without overflow." "Test SM2 with very high failure count (100+ failures). Failure count should be tracked correctly even at extreme values." (let* ((failures 100) - (result (org-drill-determine-next-interval-sm2 10 3 2.5 0 failures 3.0 150)) + (result (test-scheduler--call-sm2 10 3 2.5 0 failures 3.0 150)) (new-failures (test-scheduler--extract-failures result))) (should (= new-failures (1+ failures))))) @@ -317,21 +317,21 @@ Failure count should be tracked correctly even at extreme values." "Test SM2 with very high total-repeats (10000+). Total repeats should increment correctly even at extreme values." (let* ((total-repeats 10000) - (result (org-drill-determine-next-interval-sm2 10 3 2.5 4 0 4.0 total-repeats)) + (result (test-scheduler--call-sm2 10 3 2.5 4 0 4.0 total-repeats)) (new-total (test-scheduler--extract-total-repeats result))) (should (= new-total (1+ total-repeats))))) (ert-deftest test-org-drill-determine-next-interval-sm2-boundary-ef-just-above-floor () "Test SM2 with EF just above minimum floor (1.31). EF should be maintained or modified normally, not clamped." - (let* ((result (org-drill-determine-next-interval-sm2 10 3 1.31 4 0 4.0 10)) + (let* ((result (test-scheduler--call-sm2 10 3 1.31 4 0 4.0 10)) (ef (test-scheduler--extract-ef result))) (should (>= ef test-sm2-min-ef)))) (ert-deftest test-org-drill-determine-next-interval-sm2-boundary-ef-at-floor () "Test SM2 with EF exactly at minimum floor (1.3). EF at floor with quality 4 should increase slightly." - (let* ((result (org-drill-determine-next-interval-sm2 10 3 1.3 4 0 4.0 10)) + (let* ((result (test-scheduler--call-sm2 10 3 1.3 4 0 4.0 10)) (ef (test-scheduler--extract-ef result))) (should (>= ef test-sm2-min-ef)))) @@ -340,7 +340,7 @@ EF at floor with quality 4 should increase slightly." Perfect recall should not reset failures, but should calculate normal interval." (let ((org-drill-add-random-noise-to-intervals-p nil)) (let* ((failures 50) - (result (org-drill-determine-next-interval-sm2 10 3 2.5 5 failures 3.0 100)) + (result (test-scheduler--call-sm2 10 3 2.5 5 failures 3.0 100)) (interval (test-scheduler--extract-interval result)) (new-failures (test-scheduler--extract-failures result))) (should (> interval 0)) @@ -349,7 +349,7 @@ Perfect recall should not reset failures, but should calculate normal interval." (ert-deftest test-org-drill-determine-next-interval-sm2-boundary-failure-after-long-streak () "Test complete failure (quality 0) after long successful streak. Failure should reset interval to -1 regardless of previous success." - (let* ((result (org-drill-determine-next-interval-sm2 365 100 2.8 0 0 4.5 100)) + (let* ((result (test-scheduler--call-sm2 365 100 2.8 0 0 4.5 100)) (interval (test-scheduler--extract-interval result)) (repeats (test-scheduler--extract-repeats result)) (failures (test-scheduler--extract-failures result))) @@ -360,7 +360,7 @@ Failure should reset interval to -1 regardless of previous success." (ert-deftest test-org-drill-determine-next-interval-sm2-boundary-meanq-at-maximum () "Test SM2 with meanq at maximum (5.0). High quality review with already-perfect meanq." - (let* ((result (org-drill-determine-next-interval-sm2 10 3 2.5 5 0 5.0 100)) + (let* ((result (test-scheduler--call-sm2 10 3 2.5 5 0 5.0 100)) (meanq (test-scheduler--extract-meanq result))) (should (<= meanq 5.0)) (should (>= meanq 4.5)))) ; Should remain very high @@ -368,7 +368,7 @@ High quality review with already-perfect meanq." (ert-deftest test-org-drill-determine-next-interval-sm2-boundary-meanq-at-minimum () "Test SM2 with meanq at minimum (0.0). Low quality history with poor current recall." - (let* ((result (org-drill-determine-next-interval-sm2 10 3 2.5 3 5 0.0 100)) + (let* ((result (test-scheduler--call-sm2 10 3 2.5 3 5 0.0 100)) (meanq (test-scheduler--extract-meanq result))) (should (>= meanq 0.0)) (should (<= meanq 1.0)))) ; Should remain low with quality 3 @@ -378,7 +378,7 @@ Low quality history with poor current recall." Indicates item reviewed many times but poorly recalled." (let* ((total-repeats 1000) (meanq 2.0) - (result (org-drill-determine-next-interval-sm2 5 10 1.5 3 20 meanq total-repeats)) + (result (test-scheduler--call-sm2 5 10 1.5 3 20 meanq total-repeats)) (new-meanq (test-scheduler--extract-meanq result))) (should (numberp new-meanq)) ;; meanq should remain low given poor history @@ -387,7 +387,7 @@ Indicates item reviewed many times but poorly recalled." (ert-deftest test-org-drill-determine-next-interval-sm2-boundary-zero-last-interval () "Test SM2 with zero last-interval. Should handle as first review (n=1 case)." - (let* ((result (org-drill-determine-next-interval-sm2 0 1 2.5 4 0 4.0 0)) + (let* ((result (test-scheduler--call-sm2 0 1 2.5 4 0 4.0 0)) (interval (test-scheduler--extract-interval result))) (should (= interval 1)))) @@ -395,8 +395,8 @@ Should handle as first review (n=1 case)." "Test SM2 with float last-interval vs integer. Algorithm should handle both correctly." (let ((org-drill-add-random-noise-to-intervals-p nil)) - (let* ((result-float (org-drill-determine-next-interval-sm2 10.5 3 2.5 4 0 4.0 10)) - (result-int (org-drill-determine-next-interval-sm2 10 3 2.5 4 0 4.0 10)) + (let* ((result-float (test-scheduler--call-sm2 10.5 3 2.5 4 0 4.0 10)) + (result-int (test-scheduler--call-sm2 10 3 2.5 4 0 4.0 10)) (interval-float (test-scheduler--extract-interval result-float)) (interval-int (test-scheduler--extract-interval result-int))) (should (numberp interval-float)) @@ -408,9 +408,9 @@ Algorithm should handle both correctly." (ert-deftest test-org-drill-determine-next-interval-sm2-boundary-alternating-quality-pattern () "Test SM2 behavior with alternating quality (5, 0, 5, 0 pattern). Simulates inconsistent learning." - (let* ((result-1 (org-drill-determine-next-interval-sm2 1 2 2.5 5 0 5.0 1)) + (let* ((result-1 (test-scheduler--call-sm2 1 2 2.5 5 0 5.0 1)) (ef-1 (test-scheduler--extract-ef result-1)) - (result-2 (org-drill-determine-next-interval-sm2 6 3 ef-1 0 0 4.5 2)) + (result-2 (test-scheduler--call-sm2 6 3 ef-1 0 0 4.5 2)) (interval-2 (test-scheduler--extract-interval result-2)) (failures-2 (test-scheduler--extract-failures result-2))) ;; After perfect then fail, should reset interval @@ -442,18 +442,18 @@ quirk drops into a blocking debugger in batch mode, so a bare (ert-deftest test-org-drill-determine-next-interval-sm2-error-quality-above-max () "Quality above the 0-5 range trips the quality assertion." (test-scheduler--should-cl-assert - (org-drill-determine-next-interval-sm2 1 2 2.5 6 0 4.0 1))) + (test-scheduler--call-sm2 1 2 2.5 6 0 4.0 1))) (ert-deftest test-org-drill-determine-next-interval-sm2-error-quality-below-min () "Quality below the 0-5 range trips the quality assertion." (test-scheduler--should-cl-assert - (org-drill-determine-next-interval-sm2 1 2 2.5 -1 0 4.0 1))) + (test-scheduler--call-sm2 1 2 2.5 -1 0 4.0 1))) (ert-deftest test-org-drill-determine-next-interval-sm2-error-negative-n () "A negative repeat count trips the (> n 0) assertion. Note n=0 is normalized to 1 before the assert, so zero is not an error case." (test-scheduler--should-cl-assert - (org-drill-determine-next-interval-sm2 1 -1 2.5 4 0 4.0 1))) + (test-scheduler--call-sm2 1 -1 2.5 4 0 4.0 1))) (provide 'test-org-drill-determine-next-interval-sm2) ;;; test-org-drill-determine-next-interval-sm2.el ends here diff --git a/tests/testutil-scheduler.el b/tests/testutil-scheduler.el index 72811e8..70204b4 100644 --- a/tests/testutil-scheduler.el +++ b/tests/testutil-scheduler.el @@ -43,5 +43,19 @@ Use this name in Simple8 tests where the field is called `ease' not `ef'." "Extract the optimal-factor matrix (position 6) from an SM5 RESULT list." (nth 6 result)) +;;;; Call adapters +;; The schedulers now take an `org-drill-card-state' plus QUALITY rather than a +;; long positional list (org-drill #147). These adapters pack the positional +;; args into the struct so the test call sites keep reading as the documented +;; algorithm inputs, making each migration a one-symbol rename at the call. + +(defun test-scheduler--call-sm2 (last-interval n ef quality failures meanq total-repeats) + "Call the SM2 scheduler from positional args, packing them into a card-state." + (org-drill-determine-next-interval-sm2 + (make-org-drill-card-state + :last-interval last-interval :repetitions n :ease ef + :failures failures :meanq meanq :total-repeats total-repeats) + quality)) + (provide 'testutil-scheduler) ;;; testutil-scheduler.el ends here |
