blob: 2022e0d4a3398eb0f56308e727778fb85b48f4df (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
;;; test-org-drill-statistics-primitives.el --- Tests for primitives statistics -*- lexical-binding: t; -*-
;;; Commentary:
;; ERT tests for the org-drill statistics dashboard primitives block.
;;; Code:
(require 'ert)
(require 'org-drill)
(require 'cl-lib)
(require 'org)
;;; Tests for statistics primitives. Require 'org-drill and 'cl-lib.
;;; Fixtures are deterministic: start-time values are fixed floats, and
;;; day numbers are derived, never hardcoded against today's date.
(defun test-org-drill-statistics--make-record (start-time algorithm)
"Build a minimal `org-drill-session-record' for tests.
START-TIME is a float; ALGORITHM is a symbol. Other slots get inert
placeholder values sufficient for the primitive under test."
(make-org-drill-session-record
:start-time start-time
:end-time (+ start-time 60.0)
:scope 'directory
:algorithm algorithm
:qualities (vector 5 4 3)
:pass-percent 67
:new-count 1
:mature-count 1
:failed-count 1
:cram-mode nil))
;;; org-drill-statistics--today-day
(ert-deftest test-org-drill-statistics-today-day-matches-time-to-days ()
"`--today-day' equals `time-to-days' of the current time."
(should (= (org-drill-statistics--today-day)
(time-to-days (current-time)))))
(ert-deftest test-org-drill-statistics-today-day-redefinable ()
"`--today-day' can be redefined to a fixed day for deterministic tests."
(cl-letf (((symbol-function 'org-drill-statistics--today-day)
(lambda () 700000)))
(should (= (org-drill-statistics--today-day) 700000))))
;;; org-drill-statistics--record-day
(ert-deftest test-org-drill-statistics-record-day-derives-from-start-time ()
"`--record-day' returns the day number of the record's start time."
(let* ((now (float-time))
(record (test-org-drill-statistics--make-record now 'sm5)))
(should (= (org-drill-statistics--record-day record)
(time-to-days (seconds-to-time now))))))
(ert-deftest test-org-drill-statistics-record-day-earlier-is-smaller ()
"A record started a day earlier has a day number one less."
(let* ((now (float-time))
(today (test-org-drill-statistics--make-record now 'sm5))
(yesterday (test-org-drill-statistics--make-record
(- now 86400.0) 'sm5)))
(should (= (- (org-drill-statistics--record-day today)
(org-drill-statistics--record-day yesterday))
1))))
;;; org-drill-statistics--filter-log
(ert-deftest test-org-drill-statistics-filter-log-nil-returns-all ()
"Filtering with nil algorithm returns the log unchanged."
(let ((log (list (test-org-drill-statistics--make-record 100.0 'sm5)
(test-org-drill-statistics--make-record 200.0 'simple8))))
(should (equal (org-drill-statistics--filter-log log nil) log))))
(ert-deftest test-org-drill-statistics-filter-log-keeps-matching ()
"Filtering keeps only records whose algorithm matches."
(let* ((a (test-org-drill-statistics--make-record 100.0 'sm5))
(b (test-org-drill-statistics--make-record 200.0 'simple8))
(c (test-org-drill-statistics--make-record 300.0 'sm5))
(log (list a b c))
(result (org-drill-statistics--filter-log log 'sm5)))
(should (equal result (list a c)))))
(ert-deftest test-org-drill-statistics-filter-log-no-match-returns-empty ()
"Filtering on an absent algorithm returns an empty list."
(let ((log (list (test-org-drill-statistics--make-record 100.0 'sm5))))
(should (null (org-drill-statistics--filter-log log 'simple8)))))
(ert-deftest test-org-drill-statistics-filter-log-empty-log ()
"Filtering an empty log returns an empty list for any algorithm."
(should (null (org-drill-statistics--filter-log nil 'sm5)))
(should (null (org-drill-statistics--filter-log nil nil))))
(ert-deftest test-org-drill-statistics-filter-log-does-not-mutate ()
"Filtering leaves the input list intact."
(let* ((log (list (test-org-drill-statistics--make-record 100.0 'sm5)
(test-org-drill-statistics--make-record 200.0 'simple8)))
(copy (copy-sequence log)))
(org-drill-statistics--filter-log log 'sm5)
(should (equal log copy))))
;;; org-drill-statistics--log-since
(ert-deftest test-org-drill-statistics-log-since-keeps-at-or-after-cutoff ()
"Records at or after the cutoff are kept; earlier ones dropped."
(let* ((before (test-org-drill-statistics--make-record 100.0 'sm5))
(at (test-org-drill-statistics--make-record 200.0 'sm5))
(after (test-org-drill-statistics--make-record 300.0 'sm5))
(log (list before at after))
(result (org-drill-statistics--log-since log 200.0)))
(should (equal result (list at after)))))
(ert-deftest test-org-drill-statistics-log-since-all-before-cutoff ()
"When every record predates the cutoff, the result is empty."
(let ((log (list (test-org-drill-statistics--make-record 100.0 'sm5)
(test-org-drill-statistics--make-record 150.0 'sm5))))
(should (null (org-drill-statistics--log-since log 200.0)))))
(ert-deftest test-org-drill-statistics-log-since-all-after-cutoff ()
"When every record is at or after the cutoff, all are kept."
(let* ((log (list (test-org-drill-statistics--make-record 300.0 'sm5)
(test-org-drill-statistics--make-record 400.0 'sm5)))
(result (org-drill-statistics--log-since log 200.0)))
(should (equal result log))))
(ert-deftest test-org-drill-statistics-log-since-empty-log ()
"Filtering an empty log by cutoff returns an empty list."
(should (null (org-drill-statistics--log-since nil 200.0))))
(ert-deftest test-org-drill-statistics-log-since-does-not-mutate ()
"Cutoff filtering leaves the input list intact."
(let* ((log (list (test-org-drill-statistics--make-record 100.0 'sm5)
(test-org-drill-statistics--make-record 300.0 'sm5)))
(copy (copy-sequence log)))
(org-drill-statistics--log-since log 200.0)
(should (equal log copy))))
(provide 'test-org-drill-statistics-primitives)
;;; test-org-drill-statistics-primitives.el ends here
|