aboutsummaryrefslogtreecommitdiff
path: root/tests/test-org-drill-migrate-from-source.el
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-05 14:10:30 -0500
committerCraig Jennings <c@cjennings.net>2026-05-05 14:10:30 -0500
commit9206de07d7bb1e549aacada300f637aee1b620e9 (patch)
tree540be33fc8d4e155bdc21ac8ca23d2eb8372b6e0 /tests/test-org-drill-migrate-from-source.el
parent0d32f8f6df9406c12306d97592446408ba7984e3 (diff)
downloadorg-drill-9206de07d7bb1e549aacada300f637aee1b620e9.tar.gz
org-drill-9206de07d7bb1e549aacada300f637aee1b620e9.zip
test: cover --setup-display, --restore-display, --migrate-from-source, scope=directory
I added unit tests for the display-state helpers (capture text scale, variable-pitch, modeline; restore them on session exit), the directory branch of `org-drill-current-scope', and `--migrate-from-source''s three-branch cond (matching ID, no ID, ignore-new-items). Coverage moved from 81.8% to 82.4%.
Diffstat (limited to 'tests/test-org-drill-migrate-from-source.el')
-rw-r--r--tests/test-org-drill-migrate-from-source.el99
1 files changed, 99 insertions, 0 deletions
diff --git a/tests/test-org-drill-migrate-from-source.el b/tests/test-org-drill-migrate-from-source.el
new file mode 100644
index 0000000..7b3d4ab
--- /dev/null
+++ b/tests/test-org-drill-migrate-from-source.el
@@ -0,0 +1,99 @@
+;;; test-org-drill-migrate-from-source.el --- Tests for --migrate-from-source -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; Tests for `org-drill--migrate-from-source', which walks SRC and copies
+;; scheduling data into matching DEST entries (matched by ID). The cond
+;; has three branches:
+;;
+;; - SRC entry has no ID, or isn't a drill entry → skip
+;; - SRC entry's ID matches a DEST ID → copy scheduling, drop from table
+;; - SRC entry has an ID with no DEST match → either copy as new item, or
+;; skip when ignore-new-items-p is t
+
+;;; Code:
+
+(require 'ert)
+(require 'cl-lib)
+(require 'org)
+(require 'org-drill)
+
+(defmacro with-two-org-tempfiles (src-content dest-content &rest body)
+ "Run BODY with SRC-BUF and DEST-BUF bound to org-mode buffers.
+SRC-CONTENT is loaded into SRC-BUF, DEST-CONTENT into DEST-BUF."
+ (declare (indent 2))
+ `(let ((src-file (make-temp-file "org-drill-mig-src-" nil ".org"))
+ (dest-file (make-temp-file "org-drill-mig-dst-" nil ".org"))
+ src-buf dest-buf)
+ (unwind-protect
+ (progn
+ (setq src-buf (find-file-noselect src-file))
+ (setq dest-buf (find-file-noselect dest-file))
+ (with-current-buffer src-buf
+ (let ((org-startup-folded nil))
+ (insert ,src-content)
+ (org-mode)))
+ (with-current-buffer dest-buf
+ (let ((org-startup-folded nil))
+ (insert ,dest-content)
+ (org-mode)))
+ ,@body)
+ (when (file-exists-p src-file) (delete-file src-file))
+ (when (file-exists-p dest-file) (delete-file dest-file)))))
+
+(ert-deftest test-migrate-matching-id-copies-scheduling ()
+ "When SRC has an ID matching DEST, scheduling lands on DEST."
+ (with-two-org-tempfiles
+ "* Card :drill:\n:PROPERTIES:\n:ID: shared\n:DRILL_LAST_INTERVAL: 12.0\n:DRILL_TOTAL_REPEATS: 4\n:DRILL_REPEATS_SINCE_FAIL: 3\n:DRILL_FAILURE_COUNT: 1\n:DRILL_AVERAGE_QUALITY: 3.5\n:DRILL_EASE: 2.5\n:END:\n"
+ "* Card :drill:\n:PROPERTIES:\n:ID: shared\n:END:\n"
+ (clrhash org-drill-dest-id-table)
+ (org-drill--build-dest-id-table dest-buf)
+ (should (gethash "shared" org-drill-dest-id-table))
+ (cl-letf (((symbol-function 'org-drill-progress-message) #'ignore))
+ (org-drill--migrate-from-source src-buf dest-buf nil))
+ ;; ID was consumed off the table.
+ (should-not (gethash "shared" org-drill-dest-id-table))
+ ;; DEST got the scheduling data.
+ (with-current-buffer dest-buf
+ (goto-char (point-min))
+ (should (equal "12.0" (org-entry-get (point) "DRILL_LAST_INTERVAL")))
+ (should (equal "4" (org-entry-get (point) "DRILL_TOTAL_REPEATS"))))))
+
+(ert-deftest test-migrate-no-id-on-src-is-skipped ()
+ "SRC entries without an ID don't touch DEST and don't drain the table."
+ (with-two-org-tempfiles
+ "* Card :drill:\n:PROPERTIES:\n:DRILL_LAST_INTERVAL: 5.0\n:END:\n"
+ "* Card :drill:\n:PROPERTIES:\n:ID: untouched\n:END:\n"
+ (clrhash org-drill-dest-id-table)
+ (org-drill--build-dest-id-table dest-buf)
+ (cl-letf (((symbol-function 'org-drill-progress-message) #'ignore))
+ (org-drill--migrate-from-source src-buf dest-buf nil))
+ (should (gethash "untouched" org-drill-dest-id-table))))
+
+(ert-deftest test-migrate-non-drill-entry-skipped ()
+ "Non-drill entries in SRC are skipped even when they have an ID."
+ (with-two-org-tempfiles
+ "* Note (no drill tag)\n:PROPERTIES:\n:ID: shared\n:END:\n"
+ "* Card :drill:\n:PROPERTIES:\n:ID: shared\n:END:\n"
+ (clrhash org-drill-dest-id-table)
+ (org-drill--build-dest-id-table dest-buf)
+ (cl-letf (((symbol-function 'org-drill-progress-message) #'ignore))
+ (org-drill--migrate-from-source src-buf dest-buf nil))
+ ;; Non-drill SRC didn't match, so the ID stays in the table.
+ (should (gethash "shared" org-drill-dest-id-table))))
+
+(ert-deftest test-migrate-ignore-new-items-skips-unmatched-src ()
+ "When ignore-new-items-p is t, unmatched SRC entries don't get copied."
+ (with-two-org-tempfiles
+ "* New card :drill:\n:PROPERTIES:\n:ID: src-only\n:END:\n"
+ "* Existing :drill:\n:PROPERTIES:\n:ID: dest-only\n:END:\n"
+ (clrhash org-drill-dest-id-table)
+ (org-drill--build-dest-id-table dest-buf)
+ (cl-letf (((symbol-function 'org-drill-progress-message) #'ignore)
+ ((symbol-function 'org-drill-copy-entry-to-other-buffer)
+ (lambda (&rest _) (error "should not be called"))))
+ (org-drill--migrate-from-source src-buf dest-buf t))
+ ;; dest-only is still in the table because nothing migrated to consume it.
+ (should (gethash "dest-only" org-drill-dest-id-table))))
+
+(provide 'test-org-drill-migrate-from-source)
+;;; test-org-drill-migrate-from-source.el ends here