aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/test-org-drill-prompt-and-misc.el53
-rw-r--r--tests/test-org-drill-statistics-render-attention.el12
-rw-r--r--tests/test-org-drill-statistics-source-buffer.el174
3 files changed, 234 insertions, 5 deletions
diff --git a/tests/test-org-drill-prompt-and-misc.el b/tests/test-org-drill-prompt-and-misc.el
index 968ad57..5b42f6b 100644
--- a/tests/test-org-drill-prompt-and-misc.el
+++ b/tests/test-org-drill-prompt-and-misc.el
@@ -140,6 +140,59 @@
(org-drill-progress-message 42 50)
(should (string-match-p "42" got-message)))))
+;;;; org-drill outline path in the drill prompt (m.galimski patch)
+
+(ert-deftest test-org-drill--outline-path-string-nested ()
+ "A nested entry yields its ancestor path, bracketed and arrow-joined."
+ (with-temp-buffer
+ (insert "* Spanish\n** Greetings\n*** Hola :drill:\nhola = hello\n")
+ (org-mode)
+ (goto-char (point-min))
+ (search-forward "Hola")
+ (should (equal (org-drill--outline-path-string) "[Spanish > Greetings] "))))
+
+(ert-deftest test-org-drill--outline-path-string-top-level-empty ()
+ "A top-level entry has no ancestors, so the path string is empty."
+ (with-temp-buffer
+ (insert "* Hola :drill:\nhola = hello\n")
+ (org-mode)
+ (goto-char (point-min))
+ (should (equal (org-drill--outline-path-string) ""))))
+
+(ert-deftest test-org-drill--make-minibuffer-prompt-omits-path-by-default ()
+ "With the defcustom off, the outline path is absent from the prompt."
+ (with-temp-buffer
+ (let ((org-startup-folded nil)
+ (org-drill-show-outline-path-during-drill nil))
+ (insert "* Spanish\n** Greetings\n*** Hola :drill:\nhola = hello\n")
+ (org-mode)
+ (goto-char (point-min))
+ (search-forward "Hola")
+ (with-fixed-now
+ (let* ((session (org-drill-session))
+ (prompt (substring-no-properties
+ (org-drill--make-minibuffer-prompt session "test"))))
+ (should-not (string-match-p "Greetings" prompt)))))))
+
+(ert-deftest test-org-drill--make-minibuffer-prompt-shows-path-when-on ()
+ "With the defcustom on, the prompt carries the bracketed outline path."
+ (with-temp-buffer
+ (let ((org-startup-folded nil)
+ (org-drill-show-outline-path-during-drill t))
+ (insert "* Spanish\n** Greetings\n*** Hola :drill:\nhola = hello\n")
+ (org-mode)
+ (goto-char (point-min))
+ (search-forward "Hola")
+ (with-fixed-now
+ (let* ((session (org-drill-session))
+ (prompt (substring-no-properties
+ (org-drill--make-minibuffer-prompt session "test"))))
+ (should (string-match-p "\\[Spanish > Greetings\\]" prompt)))))))
+
+(ert-deftest test-org-drill-show-outline-path-defaults-off ()
+ "The outline-path defcustom ships nil so the prompt is unchanged by default."
+ (should (eq nil (default-value 'org-drill-show-outline-path-during-drill))))
+
(provide 'test-org-drill-prompt-and-misc)
;;; test-org-drill-prompt-and-misc.el ends here
diff --git a/tests/test-org-drill-statistics-render-attention.el b/tests/test-org-drill-statistics-render-attention.el
index b3f2375..4adcfcc 100644
--- a/tests/test-org-drill-statistics-render-attention.el
+++ b/tests/test-org-drill-statistics-render-attention.el
@@ -65,8 +65,9 @@ current time so the fixture never hardcodes today."
(test-org-drill-stats--attn-fixture)
(let ((out (org-drill-statistics--render-attention 'file)))
(should (string-match-p "| Card |" out))
- (should (string-match-p "\\[\\[org-drill-card:[0-9]+\\]\\[Leech 00\\]\\]"
- out)))))
+ (should (string-match-p
+ "\\[\\[org-drill-card:[0-9]+@[^]]*\\]\\[Leech 00\\]\\]"
+ out)))))
(ert-deftest test-org-drill-statistics-attention-cap-and-footer ()
"Twelve leeches over a 10 cap show 10 rows and a +2 more footer."
@@ -126,15 +127,16 @@ current time so the fixture never hardcodes today."
(ert-deftest test-org-drill-statistics-card-link-sanitizes-brackets ()
"Closing brackets in a heading cannot terminate the link early."
(let ((link (org-drill-statistics--card-link "a]] b" 42)))
- (should (string-prefix-p "[[org-drill-card:42][" link))
+ (should (string-prefix-p "[[org-drill-card:42@][" link))
(should (string-suffix-p "]]" link))
(should-not (string-match-p "a]] b" link))))
(ert-deftest test-org-drill-statistics-card-link-empty-heading-fallback ()
"An empty heading falls back to a position-based description."
(let ((link (org-drill-statistics--card-link "" 99)))
- (should (string-match-p "\\[\\[org-drill-card:99\\]\\[card at 99\\]\\]"
- link))))
+ (should (string-match-p
+ "\\[\\[org-drill-card:99@[^]]*\\]\\[card at 99\\]\\]"
+ link))))
(provide 'test-org-drill-statistics-render-attention)
diff --git a/tests/test-org-drill-statistics-source-buffer.el b/tests/test-org-drill-statistics-source-buffer.el
new file mode 100644
index 0000000..5732b63
--- /dev/null
+++ b/tests/test-org-drill-statistics-source-buffer.el
@@ -0,0 +1,174 @@
+;;; test-org-drill-statistics-source-buffer.el --- Dashboard source-buffer tests -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; ERT tests for the statistics dashboard's source-buffer plumbing and
+;; the org-drill-card link type. The dashboard must scan the deck the
+;; command was invoked from, not its own buffer, and its card links must
+;; be followable.
+
+;;; Code:
+
+(require 'ert)
+(require 'org-drill)
+(require 'org)
+
+(defmacro org-drill-statistics-source-test--with-deck (var &rest body)
+ "Run BODY with VAR bound to a live org deck buffer holding two drill cards."
+ (declare (indent 1))
+ `(let ((,var (generate-new-buffer "*source-deck*")))
+ (unwind-protect
+ (with-current-buffer ,var
+ (org-mode)
+ (insert "* Card one :drill:\nBody one.\n"
+ "* Card two :drill:\nBody two.\n")
+ (goto-char (point-min))
+ ,@body)
+ (when (buffer-live-p ,var) (kill-buffer ,var)))))
+
+;;; Normal cases
+
+(ert-deftest test-org-drill-statistics-render-counts-source-deck-cards ()
+ "Rendering into the dashboard counts the cards of the source deck.
+With the default file scope, the card scans must run in the source
+buffer, not the dashboard buffer being rendered into."
+ (org-drill-statistics-source-test--with-deck deck
+ (let ((dash (generate-new-buffer "*dash-test*"))
+ (org-drill-scope 'file)
+ (org-drill-session-log nil))
+ (unwind-protect
+ (progn
+ (with-current-buffer dash (org-mode))
+ (org-drill-statistics--render dash 'file "last 90d" nil deck)
+ (with-current-buffer dash
+ (goto-char (point-min))
+ ;; Overview table data row: | total | new | mature | lapsed |
+ (should (search-forward "| 2 | " nil t))))
+ (kill-buffer dash)))))
+
+(ert-deftest test-org-drill-statistics-refresh-uses-stored-source ()
+ "Refresh from inside the dashboard re-scans the stored source deck."
+ (org-drill-statistics-source-test--with-deck deck
+ (let ((dash (generate-new-buffer "*dash-test*"))
+ (org-drill-scope 'file)
+ (org-drill-session-log nil))
+ (unwind-protect
+ (progn
+ (with-current-buffer dash (org-mode))
+ (org-drill-statistics--render dash 'file "last 90d" nil deck)
+ (with-current-buffer dash
+ (org-drill-statistics-refresh)
+ (goto-char (point-min))
+ (should (search-forward "| 2 | " nil t))))
+ (kill-buffer dash)))))
+
+(ert-deftest test-org-drill-statistics-card-link-type-is-registered ()
+ "The org-drill-card link type has a follow handler registered."
+ (should (functionp (org-link-get-parameter "org-drill-card" :follow))))
+
+(ert-deftest test-org-drill-statistics-card-link-encodes-file ()
+ "Card links carry the file identity after the position."
+ (let ((link (org-drill-statistics--card-link "Heading" 42 "/tmp/deck.org")))
+ (should (string-prefix-p "[[org-drill-card:42@/tmp/deck.org][" link))))
+
+(ert-deftest test-org-drill-statistics-follow-jumps-to-file-position ()
+ "Following a card link visits the file and moves point to the position."
+ (let* ((file (make-temp-file "org-drill-follow-test" nil ".org"
+ "* Card one :drill:\nBody.\n"))
+ (buf nil))
+ (unwind-protect
+ (progn
+ (org-drill-statistics--follow-card-link (format "1@%s" file))
+ (setq buf (current-buffer))
+ (should (equal (buffer-file-name) file))
+ (should (= (point) 1)))
+ (when (and buf (buffer-live-p buf)) (kill-buffer buf))
+ (delete-file file))))
+
+;;; Boundary cases
+
+(ert-deftest test-org-drill-statistics-render-empty-deck-counts-zero ()
+ "An empty source deck renders a zero-card overview, not an error."
+ (let ((deck (generate-new-buffer "*empty-deck*"))
+ (dash (generate-new-buffer "*dash-test*"))
+ (org-drill-scope 'file)
+ (org-drill-session-log nil))
+ (unwind-protect
+ (progn
+ (with-current-buffer deck (org-mode))
+ (with-current-buffer dash (org-mode))
+ (org-drill-statistics--render dash 'file "last 90d" nil deck)
+ (with-current-buffer dash
+ (goto-char (point-min))
+ (should (search-forward "| 0 | " nil t))))
+ (kill-buffer deck)
+ (kill-buffer dash))))
+
+(ert-deftest test-org-drill-statistics-card-link-empty-file-omits-identity ()
+ "A card link built with no file still carries the position."
+ (let ((link (org-drill-statistics--card-link "Heading" 7 nil)))
+ (should (string-prefix-p "[[org-drill-card:7@][" link))))
+
+(ert-deftest test-org-drill-statistics-export-cards-from-source-deck ()
+ "CSV export scans the stored source deck, not the dashboard buffer."
+ (org-drill-statistics-source-test--with-deck deck
+ (let ((dash (generate-new-buffer "*dash-test*"))
+ (dir (make-temp-file "org-drill-export-test" t))
+ (org-drill-scope 'file)
+ (org-drill-session-log nil))
+ (unwind-protect
+ (progn
+ (with-current-buffer dash (org-mode))
+ (org-drill-statistics--render dash 'file "last 90d" nil deck)
+ (with-current-buffer dash
+ (org-drill-statistics-export-csv dir))
+ (with-temp-buffer
+ (insert-file-contents (expand-file-name "cards.csv" dir))
+ ;; Header plus one row per deck card.
+ (should (= 3 (count-lines (point-min) (point-max))))))
+ (kill-buffer dash)
+ (delete-directory dir t)))))
+
+(ert-deftest test-org-drill-statistics-follow-clamps-position-floor ()
+ "A zero or garbage position clamps to buffer start instead of erroring."
+ (let* ((file (make-temp-file "org-drill-follow-clamp" nil ".org"
+ "* Card :drill:\n"))
+ (buf nil))
+ (unwind-protect
+ (progn
+ (org-drill-statistics--follow-card-link (format "0@%s" file))
+ (setq buf (current-buffer))
+ (should (= (point) 1)))
+ (when (and buf (buffer-live-p buf)) (kill-buffer buf))
+ (delete-file file))))
+
+;;; Error cases
+
+(ert-deftest test-org-drill-statistics-refresh-dead-source-signals-user-error ()
+ "Refresh after the source deck is killed signals a clear user-error."
+ (let ((dash (generate-new-buffer "*dash-test*"))
+ (deck (generate-new-buffer "*doomed-deck*"))
+ (org-drill-scope 'file)
+ (org-drill-session-log nil))
+ (unwind-protect
+ (progn
+ (with-current-buffer deck
+ (org-mode)
+ (insert "* Card :drill:\n"))
+ (with-current-buffer dash (org-mode))
+ (org-drill-statistics--render dash 'file "last 90d" nil deck)
+ (kill-buffer deck)
+ (with-current-buffer dash
+ (should-error (org-drill-statistics-refresh)
+ :type 'user-error)))
+ (when (buffer-live-p deck) (kill-buffer deck))
+ (kill-buffer dash))))
+
+(ert-deftest test-org-drill-statistics-follow-dead-source-signals-user-error ()
+ "Following a bufferless link with no live source signals a user-error."
+ (with-temp-buffer
+ ;; No dashboard source var set in this buffer; empty file identity.
+ (should-error (org-drill-statistics--follow-card-link "5@")
+ :type 'user-error)))
+
+(provide 'test-org-drill-statistics-source-buffer)
+;;; test-org-drill-statistics-source-buffer.el ends here