diff options
| author | Craig Jennings <c@cjennings.net> | 2025-11-13 11:36:06 -0600 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2025-11-13 11:36:06 -0600 |
| commit | cf182d001f66164232b8735bad43eb07121109c6 (patch) | |
| tree | a70cc6f6d16a2c4cbb67c6850e59728158f3f383 /tests/test-org-drill-part-of-drill-entry-p.el | |
| parent | 87e74a3a6ccf5b05b760e9f8beec9a78886ab076 (diff) | |
| download | org-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.el | 231 |
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 |
