diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-05 04:55:37 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-05 04:55:37 -0500 |
| commit | 861a82ba96dba41f9eab8f3a61e8af32ba8a4bf8 (patch) | |
| tree | 63f05a4cc995783effc8f88abc0024b146511372 | |
| parent | 8cea3e2a928d6b41929c13c44343b9ebb7fd1aac (diff) | |
| download | org-drill-861a82ba96dba41f9eab8f3a61e8af32ba8a4bf8.tar.gz org-drill-861a82ba96dba41f9eab8f3a61e8af32ba8a4bf8.zip | |
test: prompt-for-string, leitner-capture, and resume coverage
7 ERT tests covering the last batch of testable smaller helpers:
- presentation-prompt-for-string: stores typed answer in
session->drill-answer, uses default prompt when arg is nil
- map-leitner-capture: unboxed entry goes to unboxed list, box-3
entry goes to boxed list, box>5 (graduated) skipped, non-drill
entry silently skipped
- org-drill-resume: with pending entries, calls org-drill resume-p=t
| -rw-r--r-- | tests/test-org-drill-final-helpers.el | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/tests/test-org-drill-final-helpers.el b/tests/test-org-drill-final-helpers.el new file mode 100644 index 0000000..c9cb0a3 --- /dev/null +++ b/tests/test-org-drill-final-helpers.el @@ -0,0 +1,143 @@ +;;; test-org-drill-final-helpers.el --- Tests for prompt-for-string, leitner capture, and resume -*- lexical-binding: t; -*- + +;;; Commentary: +;; Final batch of unit tests for: +;; +;; - `org-drill-presentation-prompt-for-string': typed-answer prompt +;; (uses `read-string'). +;; - `org-drill-map-leitner-capture': classifies a leitner-tagged entry +;; into either boxed or unboxed lists based on DRILL_LEITNER_BOX. +;; - `org-drill-resume': continues a suspended session. + +;;; Code: + +(require 'ert) +(require 'cl-lib) +(require 'org) +(require 'org-drill) + +;;;; Helpers + +(defmacro with-org-buffer (content &rest body) + (declare (indent 1)) + `(with-temp-buffer + (let ((org-startup-folded nil)) + (insert ,content) + (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 make-marker-at (pos) + (let ((m (make-marker))) (set-marker m pos) m)) + +;;;; org-drill-presentation-prompt-for-string + +(ert-deftest test-prompt-for-string-stores-typed-answer-in-session () + "The string the user typed is captured into session->drill-answer." + (with-org-buffer "* Question :drill:\nbody\n" + (let ((session (org-drill-session))) + (cl-letf (((symbol-function 'read-string) + (lambda (&rest _) "user-typed-this"))) + (org-drill-presentation-prompt-for-string session "Type:") + (should (equal "user-typed-this" (oref session drill-answer))))))) + +(ert-deftest test-prompt-for-string-uses-default-prompt-when-nil () + (with-org-buffer "* Question :drill:\nbody\n" + (let ((session (org-drill-session)) + (passed-prompt nil)) + (cl-letf (((symbol-function 'read-string) + (lambda (prompt &rest _) + (setq passed-prompt prompt) "x"))) + (org-drill-presentation-prompt-for-string session nil) + (should (string-match-p "Type your answer" passed-prompt)))))) + +;;;; org-drill-map-leitner-capture + +(defmacro with-leitner-tempfile-buffer (content &rest body) + "Run BODY in a tempfile-backed org buffer with CONTENT and the +leitner tag bound as the active question tag (so org-drill-entry-p +matches leitner-tagged entries)." + (declare (indent 1)) + `(let ((tmpfile (make-temp-file "org-drill-test-" nil ".org"))) + (unwind-protect + (with-current-buffer (find-file-noselect tmpfile) + (let ((org-startup-folded nil) + (org-drill-question-tag org-drill-leitner-tag)) + (insert ,content) + (goto-char (point-min)) + ,@body)) + (when (file-exists-p tmpfile) (delete-file tmpfile))))) + +(ert-deftest test-map-leitner-capture-unboxed-entry-pushed-to-unboxed-list () + "An entry without DRILL_LEITNER_BOX goes into org-drill-leitner-unboxed-entries." + (with-leitner-tempfile-buffer "* Question :leitner:\n" + (let ((session (org-drill-session)) + (org-drill-leitner-boxed-entries nil) + (org-drill-leitner-unboxed-entries nil)) + (cl-letf (((symbol-function 'org-drill-progress-message) #'ignore) + ((symbol-function 'sit-for) #'ignore)) + (org-drill-map-leitner-capture session) + (should (= 1 (length org-drill-leitner-unboxed-entries))) + (should (null org-drill-leitner-boxed-entries)))))) + +(ert-deftest test-map-leitner-capture-box-3-entry-pushed-to-boxed-list () + "An entry with DRILL_LEITNER_BOX = 3 goes into the boxed list." + (with-leitner-tempfile-buffer + "* Question :leitner:\n:PROPERTIES:\n:DRILL_LEITNER_BOX: 3\n:END:\n" + (let ((session (org-drill-session)) + (org-drill-leitner-boxed-entries nil) + (org-drill-leitner-unboxed-entries nil)) + (cl-letf (((symbol-function 'org-drill-progress-message) #'ignore) + ((symbol-function 'sit-for) #'ignore)) + (org-drill-map-leitner-capture session) + (should (= 1 (length org-drill-leitner-boxed-entries))) + (should (null org-drill-leitner-unboxed-entries)))))) + +(ert-deftest test-map-leitner-capture-box-greater-than-5-skipped () + "An entry with DRILL_LEITNER_BOX > 5 (already graduated) is captured into neither list." + (with-leitner-tempfile-buffer + "* Question :leitner:\n:PROPERTIES:\n:DRILL_LEITNER_BOX: 6\n:END:\n" + (let ((session (org-drill-session)) + (org-drill-leitner-boxed-entries nil) + (org-drill-leitner-unboxed-entries nil)) + (cl-letf (((symbol-function 'org-drill-progress-message) #'ignore) + ((symbol-function 'sit-for) #'ignore)) + (org-drill-map-leitner-capture session) + (should (null org-drill-leitner-boxed-entries)) + (should (null org-drill-leitner-unboxed-entries)))))) + +(ert-deftest test-map-leitner-capture-non-drill-entry-skipped () + "Non-drill entries (no :drill: tag inheritance) are skipped silently." + (with-org-buffer "* Plain heading\n" + (let ((session (org-drill-session)) + (org-drill-leitner-boxed-entries nil) + (org-drill-leitner-unboxed-entries nil)) + (cl-letf (((symbol-function 'org-drill-progress-message) #'ignore) + ((symbol-function 'sit-for) #'ignore)) + (org-drill-map-leitner-capture session) + (should (null org-drill-leitner-unboxed-entries)) + (should (null org-drill-leitner-boxed-entries)))))) + +;;;; org-drill-resume + +(ert-deftest test-org-drill-resume-pending-entries-resumes () + "When the prior session has pending entries, resume calls org-drill +with resume-p=t." + (let ((session (org-drill-session)) + (org-drill-args nil)) + (oset session new-entries (list (make-marker-at 1))) + (oset session start-time (float-time (current-time))) + (let ((org-drill-last-session session)) + (cl-letf (((symbol-function 'org-drill) + (lambda (&rest args) (setq org-drill-args args)))) + (org-drill-resume) + (should (eq t (nth 2 org-drill-args))))))) + +(provide 'test-org-drill-final-helpers) + +;;; test-org-drill-final-helpers.el ends here |
