aboutsummaryrefslogtreecommitdiff
path: root/tests/test-org-drill-statistics-quality-histogram.el
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-31 08:35:16 -0500
committerCraig Jennings <c@cjennings.net>2026-05-31 08:35:16 -0500
commit26cc4472dea261a1ad13fbee8fb6a91b019f77bb (patch)
treea7063337b05c3ea278a5b910d0f1420de033dfe8 /tests/test-org-drill-statistics-quality-histogram.el
parent532ce532465834ce06238648ba1490c48bed29ca (diff)
downloadorg-drill-26cc4472dea261a1ad13fbee8fb6a91b019f77bb.tar.gz
org-drill-26cc4472dea261a1ad13fbee8fb6a91b019f77bb.zip
feat: add the org-drill statistics dashboard renderer
Step 1 shipped the session-log data layer. This is the renderer on top of it. org-drill-statistics opens a read-only dashboard with five sections: an overview (card counts plus a last-session recap), trends (reviews-per-day and pass-rate-per-day quadrant-block sparklines over the trend window, plus a 12-week table), a quality histogram, a needs-attention view (leech candidates, long-overdue, and forgotten-new cards), and a 7-day forecast counted from SCHEDULED dates. A buffer-wide filter (scope, range, algorithm) sits in the header and cycles with s/r/a. The other keys are q to bury, g to refresh, e for the CSV-export hook that lands next, and RET to follow the card link at point. The aggregation math lives in pure helpers (day-bucketing, sparkline scaling, weekly aggregates, the histogram, the attention selectors, forecast bucketing). The render helpers are thin string formatters over them, so the logic is unit-tested independently of the UI. New defcustoms tune the views: org-drill-statistics-trend-days, -forecast-days, -attention-row-limit, and -leech-quality-threshold. I added require 'calendar for the Monday week-start arithmetic in the weekly aggregates. CSV export and the manual and README entries are the step-3 follow-on.
Diffstat (limited to 'tests/test-org-drill-statistics-quality-histogram.el')
-rw-r--r--tests/test-org-drill-statistics-quality-histogram.el100
1 files changed, 100 insertions, 0 deletions
diff --git a/tests/test-org-drill-statistics-quality-histogram.el b/tests/test-org-drill-statistics-quality-histogram.el
new file mode 100644
index 0000000..7a66314
--- /dev/null
+++ b/tests/test-org-drill-statistics-quality-histogram.el
@@ -0,0 +1,100 @@
+;;; test-org-drill-statistics-quality-histogram.el --- Tests for quality-histogram statistics -*- lexical-binding: t; -*-
+
+;;; Commentary:
+;; ERT tests for the org-drill statistics dashboard quality-histogram block.
+
+;;; Code:
+
+(require 'ert)
+(require 'org-drill)
+(require 'cl-lib)
+(require 'org)
+
+(defun test-org-drill-statistics--make-record (qualities)
+ "Build a minimal `org-drill-session-record' carrying QUALITIES.
+QUALITIES is a vector of ints. Other slots are filled with inert
+defaults so the histogram tests stay focused on the qualities slot."
+ (make-org-drill-session-record
+ :start-time 0.0
+ :end-time 0.0
+ :scope nil
+ :algorithm 'sm5
+ :qualities qualities
+ :pass-percent 0
+ :new-count 0
+ :mature-count 0
+ :failed-count 0
+ :cram-mode nil))
+
+;; Normal cases.
+
+(ert-deftest test-org-drill-statistics-quality-histogram-single-record ()
+ "A single record's qualities are tallied into the right buckets."
+ (let* ((record (test-org-drill-statistics--make-record [0 3 3 5 3]))
+ (result (org-drill-statistics--quality-histogram (list record))))
+ (should (equal result [1 0 0 3 0 1]))))
+
+(ert-deftest test-org-drill-statistics-quality-histogram-multiple-records ()
+ "Counts sum across every record in the log."
+ (let* ((r1 (test-org-drill-statistics--make-record [0 1 2]))
+ (r2 (test-org-drill-statistics--make-record [3 4 5]))
+ (r3 (test-org-drill-statistics--make-record [0 5 5]))
+ (result (org-drill-statistics--quality-histogram (list r1 r2 r3))))
+ (should (equal result [2 1 1 1 1 3]))))
+
+(ert-deftest test-org-drill-statistics-quality-histogram-all-same-quality ()
+ "A record with every entry the same quality concentrates in one bucket."
+ (let* ((record (test-org-drill-statistics--make-record [4 4 4 4]))
+ (result (org-drill-statistics--quality-histogram (list record))))
+ (should (equal result [0 0 0 0 4 0]))))
+
+;; Boundary cases.
+
+(ert-deftest test-org-drill-statistics-quality-histogram-empty-log ()
+ "An empty log yields an all-zero histogram, never nil."
+ (let ((result (org-drill-statistics--quality-histogram '())))
+ (should (equal result [0 0 0 0 0 0]))))
+
+(ert-deftest test-org-drill-statistics-quality-histogram-empty-qualities ()
+ "A record with an empty qualities vector contributes nothing."
+ (let* ((record (test-org-drill-statistics--make-record []))
+ (result (org-drill-statistics--quality-histogram (list record))))
+ (should (equal result [0 0 0 0 0 0]))))
+
+(ert-deftest test-org-drill-statistics-quality-histogram-nil-qualities ()
+ "A record whose qualities slot is nil is skipped without error."
+ (let* ((r1 (test-org-drill-statistics--make-record nil))
+ (r2 (test-org-drill-statistics--make-record [2 2]))
+ (result (org-drill-statistics--quality-histogram (list r1 r2))))
+ (should (equal result [0 0 2 0 0 0]))))
+
+(ert-deftest test-org-drill-statistics-quality-histogram-extreme-buckets ()
+ "Quality 0 and quality 5, the range endpoints, both land correctly."
+ (let* ((record (test-org-drill-statistics--make-record [0 0 5 5 5]))
+ (result (org-drill-statistics--quality-histogram (list record))))
+ (should (equal result [2 0 0 0 0 3]))))
+
+;; Error cases.
+
+(ert-deftest test-org-drill-statistics-quality-histogram-out-of-range-ignored ()
+ "Qualities outside 0..5 are dropped, valid ones still counted."
+ (let* ((record (test-org-drill-statistics--make-record [-1 6 3 99 2]))
+ (result (org-drill-statistics--quality-histogram (list record))))
+ (should (equal result [0 0 1 1 0 0]))))
+
+(ert-deftest test-org-drill-statistics-quality-histogram-non-integer-ignored ()
+ "Non-integer quality entries are ignored rather than signalling."
+ (let* ((record (test-org-drill-statistics--make-record [2 nil 2.5 3]))
+ (result (org-drill-statistics--quality-histogram (list record))))
+ (should (equal result [0 0 1 1 0 0]))))
+
+(ert-deftest test-org-drill-statistics-quality-histogram-does-not-mutate-input ()
+ "The qualities vectors are read, never written."
+ (let* ((qualities (vector 1 2 3))
+ (record (test-org-drill-statistics--make-record qualities)))
+ (org-drill-statistics--quality-histogram (list record))
+ (should (equal qualities [1 2 3]))))
+
+(provide 'test-org-drill-statistics-quality-histogram)
+
+;;; test-org-drill-statistics-quality-histogram.el ends here