aboutsummaryrefslogtreecommitdiff
path: root/tests/test-org-drill-part-of-drill-entry-p.el
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2025-11-13 11:36:06 -0600
committerCraig Jennings <c@cjennings.net>2025-11-13 11:36:06 -0600
commitcf182d001f66164232b8735bad43eb07121109c6 (patch)
treea70cc6f6d16a2c4cbb67c6850e59728158f3f383 /tests/test-org-drill-part-of-drill-entry-p.el
parent87e74a3a6ccf5b05b760e9f8beec9a78886ab076 (diff)
downloadorg-drill-cf182d001f66164232b8735bad43eb07121109c6.tar.gz
org-drill-cf182d001f66164232b8735bad43eb07121109c6.zip
test: Add Phase 1 foundation tests for critical functions
- Add unit tests for org-drill-entry-p (14 tests) - Add unit tests for org-drill-part-of-drill-entry-p (14 tests) - Add unit tests for SM2 scheduling algorithm (23 tests) - Add integration test for basic drill workflow (11 tests) - Update Makefile to support test-*.el naming pattern - Rename org-drill-test.el to test-org-drill.el for consistency Total: 65 tests, all passing
Diffstat (limited to 'tests/test-org-drill-part-of-drill-entry-p.el')
-rw-r--r--tests/test-org-drill-part-of-drill-entry-p.el231
1 files changed, 231 insertions, 0 deletions
diff --git a/tests/test-org-drill-part-of-drill-entry-p.el b/tests/test-org-drill-part-of-drill-entry-p.el
new file mode 100644
index 0000000..c9a09b8
--- /dev/null
+++ b/tests/test-org-drill-part-of-drill-entry-p.el
@@ -0,0 +1,231 @@
+;;; test-org-drill-part-of-drill-entry-p.el --- Tests for org-drill-part-of-drill-entry-p
+
+;;; Commentary:
+;; Unit tests for org-drill-part-of-drill-entry-p, which determines if point
+;; is at a drill entry heading OR within a subheading that inherits the drill tag.
+;;
+;; This function differs from org-drill-entry-p in that it checks BOTH:
+;; 1. Direct drill tag on current heading (via org-drill-entry-p)
+;; 2. Inherited drill tag from parent headings (via org-get-tags)
+
+;;; Code:
+
+(require 'ert)
+(require 'assess)
+(require 'org-drill)
+
+;;; Test Data
+
+(defconst test-org-drill-part-of-drill-entry-p-parent-drill
+ "* Parent heading :drill:
+
+Parent content.
+
+** Child heading
+
+Child content.
+
+*** Grandchild heading
+
+Grandchild content."
+ "Drill entry with nested children that inherit the tag.")
+
+(defconst test-org-drill-part-of-drill-entry-p-no-drill
+ "* Parent heading
+
+Parent content.
+
+** Child heading
+
+Child content."
+ "Headings without drill tag.")
+
+(defconst test-org-drill-part-of-drill-entry-p-child-has-drill
+ "* Parent heading
+
+Parent content.
+
+** Child heading :drill:
+
+Child content."
+ "Child has drill tag, parent doesn't.")
+
+(defconst test-org-drill-part-of-drill-entry-p-deep-nesting
+ "* Level 1 :drill:
+
+Content 1.
+
+** Level 2
+
+Content 2.
+
+*** Level 3
+
+Content 3.
+
+**** Level 4
+
+Content 4."
+ "Deeply nested structure with drill tag on top level.")
+
+;;; Helper Functions
+
+(defun test-org-drill-part-of-drill-entry-p--with-org-buffer (content callback)
+ "Execute CALLBACK in temporary org-mode buffer with CONTENT."
+ (with-temp-buffer
+ (org-mode)
+ (insert content)
+ (goto-char (point-min))
+ (funcall callback)))
+
+;;; Normal Cases
+
+(ert-deftest test-org-drill-part-of-drill-entry-p-normal-at-parent-returns-true ()
+ "Test that function returns true when at parent heading with drill tag."
+ (test-org-drill-part-of-drill-entry-p--with-org-buffer
+ test-org-drill-part-of-drill-entry-p-parent-drill
+ (lambda ()
+ ;; Point at parent heading
+ (should (org-drill-part-of-drill-entry-p)))))
+
+(ert-deftest test-org-drill-part-of-drill-entry-p-normal-at-child-returns-true ()
+ "Test that function returns true when at child heading that inherits drill tag."
+ (test-org-drill-part-of-drill-entry-p--with-org-buffer
+ test-org-drill-part-of-drill-entry-p-parent-drill
+ (lambda ()
+ ;; Move to child heading
+ (re-search-forward "^\\*\\* Child heading")
+ (beginning-of-line)
+ (should (org-drill-part-of-drill-entry-p)))))
+
+(ert-deftest test-org-drill-part-of-drill-entry-p-normal-no-drill-returns-nil ()
+ "Test that function returns nil when no drill tag present or inherited."
+ (test-org-drill-part-of-drill-entry-p--with-org-buffer
+ test-org-drill-part-of-drill-entry-p-no-drill
+ (lambda ()
+ (should-not (org-drill-part-of-drill-entry-p)))))
+
+(ert-deftest test-org-drill-part-of-drill-entry-p-normal-child-not-parent-has-drill ()
+ "Test when child has drill tag but parent doesn't.
+Child heading itself should return true."
+ (test-org-drill-part-of-drill-entry-p--with-org-buffer
+ test-org-drill-part-of-drill-entry-p-child-has-drill
+ (lambda ()
+ ;; Move to child heading with drill tag
+ (re-search-forward "^\\*\\* Child heading")
+ (beginning-of-line)
+ (should (org-drill-part-of-drill-entry-p)))))
+
+(ert-deftest test-org-drill-part-of-drill-entry-p-normal-parent-no-drill-returns-nil ()
+ "Test that parent without drill tag returns nil."
+ (test-org-drill-part-of-drill-entry-p--with-org-buffer
+ test-org-drill-part-of-drill-entry-p-child-has-drill
+ (lambda ()
+ ;; At parent heading (no drill tag)
+ (should-not (org-drill-part-of-drill-entry-p)))))
+
+;;; Boundary Cases
+
+(ert-deftest test-org-drill-part-of-drill-entry-p-boundary-grandchild-inherits ()
+ "Test that grandchild heading inherits drill tag from grandparent."
+ (test-org-drill-part-of-drill-entry-p--with-org-buffer
+ test-org-drill-part-of-drill-entry-p-parent-drill
+ (lambda ()
+ ;; Move to grandchild heading
+ (re-search-forward "^\\*\\*\\* Grandchild heading")
+ (beginning-of-line)
+ (should (org-drill-part-of-drill-entry-p)))))
+
+(ert-deftest test-org-drill-part-of-drill-entry-p-boundary-deep-nesting-all-inherit ()
+ "Test that deeply nested headings all inherit drill tag.
+All levels 2, 3, and 4 should return true."
+ (test-org-drill-part-of-drill-entry-p--with-org-buffer
+ test-org-drill-part-of-drill-entry-p-deep-nesting
+ (lambda ()
+ ;; Test level 2
+ (re-search-forward "^\\*\\* Level 2")
+ (beginning-of-line)
+ (should (org-drill-part-of-drill-entry-p))
+
+ ;; Test level 3
+ (re-search-forward "^\\*\\*\\* Level 3")
+ (beginning-of-line)
+ (should (org-drill-part-of-drill-entry-p))
+
+ ;; Test level 4
+ (re-search-forward "^\\*\\*\\*\\* Level 4")
+ (beginning-of-line)
+ (should (org-drill-part-of-drill-entry-p)))))
+
+(ert-deftest test-org-drill-part-of-drill-entry-p-boundary-point-in-child-body ()
+ "Test behavior when point is in child body text.
+Should still detect inherited drill tag."
+ (test-org-drill-part-of-drill-entry-p--with-org-buffer
+ test-org-drill-part-of-drill-entry-p-parent-drill
+ (lambda ()
+ ;; Move to child body content
+ (re-search-forward "Child content")
+ (beginning-of-line)
+ (should (org-drill-part-of-drill-entry-p)))))
+
+(ert-deftest test-org-drill-part-of-drill-entry-p-boundary-empty-child-heading ()
+ "Test child heading with no content still inherits drill tag."
+ (test-org-drill-part-of-drill-entry-p--with-org-buffer
+ "* Parent :drill:\n** Child\n"
+ (lambda ()
+ (re-search-forward "^\\*\\* Child")
+ (beginning-of-line)
+ (should (org-drill-part-of-drill-entry-p)))))
+
+;;; Error Cases
+
+(ert-deftest test-org-drill-part-of-drill-entry-p-error-empty-buffer ()
+ "Test behavior in empty buffer.
+Should not error, just return nil."
+ (with-temp-buffer
+ (org-mode)
+ (should-not (org-drill-part-of-drill-entry-p))))
+
+(ert-deftest test-org-drill-part-of-drill-entry-p-error-no-headings ()
+ "Test behavior in buffer with only text, no headings."
+ (test-org-drill-part-of-drill-entry-p--with-org-buffer
+ "Just some text without any headings."
+ (lambda ()
+ (should-not (org-drill-part-of-drill-entry-p)))))
+
+(ert-deftest test-org-drill-part-of-drill-entry-p-error-point-before-first-heading ()
+ "Test behavior when point is before any headings."
+ (test-org-drill-part-of-drill-entry-p--with-org-buffer
+ "Some preamble text\n\n* Heading :drill:\n\nContent"
+ (lambda ()
+ ;; Point at preamble
+ (goto-char (point-min))
+ (should-not (org-drill-part-of-drill-entry-p)))))
+
+;;; Comparison Tests (org-drill-entry-p vs org-drill-part-of-drill-entry-p)
+
+(ert-deftest test-org-drill-part-of-drill-entry-p-comparison-child-differs ()
+ "Test that org-drill-entry-p and org-drill-part-of-drill-entry-p differ at child.
+At child heading: entry-p returns nil, part-of returns true."
+ (test-org-drill-part-of-drill-entry-p--with-org-buffer
+ test-org-drill-part-of-drill-entry-p-parent-drill
+ (lambda ()
+ ;; Move to child heading
+ (re-search-forward "^\\*\\* Child heading")
+ (beginning-of-line)
+ ;; org-drill-entry-p should be nil (no direct tag)
+ (should-not (org-drill-entry-p))
+ ;; org-drill-part-of-drill-entry-p should be true (inherited tag)
+ (should (org-drill-part-of-drill-entry-p)))))
+
+(ert-deftest test-org-drill-part-of-drill-entry-p-comparison-parent-same ()
+ "Test that both functions return true at parent heading with drill tag."
+ (test-org-drill-part-of-drill-entry-p--with-org-buffer
+ test-org-drill-part-of-drill-entry-p-parent-drill
+ (lambda ()
+ ;; At parent heading
+ (should (org-drill-entry-p))
+ (should (org-drill-part-of-drill-entry-p)))))
+
+(provide 'test-org-drill-part-of-drill-entry-p)
+;;; test-org-drill-part-of-drill-entry-p.el ends here