Add tests for time deltas
[8sync.git] / tests.scm
1 #!/usr/bin/guile \
2 -s
3 !#
4
5 (define-module (tests test-core)
6   #:use-module (srfi srfi-64)
7   #:use-module (ice-9 q)
8   #:use-module (ice-9 receive)
9   #:use-module (loopy agenda))
10
11 (test-begin "tests")
12
13 \f
14 ;; Timer tests
15 ;; ===========
16
17 (test-assert (time-= '(1 . 1) '(1 . 1)))
18 (test-assert (not (time-= '(1 . 1) '(1 . 0))))
19 (test-assert (not (time-= '(0 . 1) '(1 . 1))))
20
21 (test-assert (time-< '(1 . 1) '(1 . 2)))
22 (test-assert (time-< '(7 . 2) '(8 . 2)))
23 (test-assert (not (time-< '(7 . 2) '(7 . 2))))
24 (test-assert (not (time-< '(7 . 8) '(7 . 2))))
25 (test-assert (not (time-< '(8 . 2) '(7 . 2))))
26
27 (let ((tdelta (make-time-delta 8)))
28   (test-assert (time-delta? tdelta))
29   (test-eqv (time-delta-sec tdelta) 8)
30   (test-eqv (time-delta-usec tdelta) 0)
31   (test-equal
32       (time-+ '(2 . 3) tdelta)
33     '(10 . 3)))
34
35 (let ((tdelta (make-time-delta 10 1)))
36   (test-assert (time-delta? tdelta))
37   (test-eqv (time-delta-sec tdelta) 10)
38   (test-eqv (time-delta-usec tdelta) 1)
39   (test-equal
40       (time-+ '(2 . 3) tdelta)
41     '(12 . 4)))
42
43
44 \f
45 ;;; Schedule tests
46 ;;; ==============
47
48 ;; helpers
49 (define (assert-times-expected time-segments expected-times)
50   (test-equal (map time-segment-time time-segments)
51     expected-times))
52
53 (define a-proc (const 'a))
54 (define b-proc (const 'b))
55 (define c-proc (const 'c))
56 (define d-proc (const 'd))
57 (define e-proc (const 'e))
58 (define f-proc (const 'f))
59
60 (define sched (make-schedule))
61 (test-assert (schedule-empty? sched))
62
63 ;; Add a segment at (10 . 0)
64 (schedule-add! 10 a-proc sched)
65 (test-assert (not (schedule-empty? sched)))
66 (test-equal (length (schedule-segments sched)) 1)
67 (test-equal (time-segment-time (car (schedule-segments sched)))
68   '(10 . 0))
69 (test-equal (q-length (time-segment-queue (car (schedule-segments sched))))
70   1)
71 (test-eq (q-front (time-segment-queue (car (schedule-segments sched))))
72   a-proc)
73 (test-eq (q-rear (time-segment-queue (car (schedule-segments sched))))
74   a-proc)
75 (test-eq ((q-front (time-segment-queue (car (schedule-segments sched)))))
76   'a) ;; why not
77 (assert-times-expected (schedule-segments sched)
78                        '((10 . 0)))
79
80 ;; Add another segment at (10 . 0)
81 (schedule-add! '(10 . 0) b-proc sched)
82 (test-assert (not (schedule-empty? sched)))
83 (test-equal (length (schedule-segments sched)) 1)
84 (test-equal (time-segment-time (car (schedule-segments sched)))
85   '(10 . 0))
86 (test-equal (q-length (time-segment-queue (car (schedule-segments sched))))
87   2)
88 (test-eq (q-front (time-segment-queue (car (schedule-segments sched))))
89   a-proc)
90 (test-eq (q-rear (time-segment-queue (car (schedule-segments sched))))
91   b-proc)
92 (assert-times-expected (schedule-segments sched)
93                        '((10 . 0)))
94
95 ;; Add a segment to (11 . 0), (8 . 1) and (10 . 10)
96 (schedule-add! 11 c-proc sched)
97 (schedule-add! '(8 . 1) d-proc sched)
98 (schedule-add! '(10 . 10) e-proc sched)
99 (test-assert (not (schedule-empty? sched)))
100 (test-equal (length (schedule-segments sched)) 4)
101 (assert-times-expected (schedule-segments sched)
102                        '((8 . 1) (10 . 0) (10 . 10) (11 . 0)))
103
104 ;; Splitting 
105 (define (test-split-at schedule time expected-before expected-after)
106   (receive (segments-before segments-after)
107       (schedule-segments-split schedule time)
108     (assert-times-expected segments-before expected-before)
109     (assert-times-expected segments-after expected-after)))
110
111 (test-split-at sched 0
112                '()
113                '((8 . 1) (10 . 0) (10 . 10) (11 . 0)))
114 (test-split-at sched '(8 . 0)
115                '()
116                '((8 . 1) (10 . 0) (10 . 10) (11 . 0)))
117 (test-split-at sched '(8 . 1)
118                '((8 . 1))
119                '((10 . 0) (10 . 10) (11 . 0)))
120 (test-split-at sched 9
121                '((8 . 1))
122                '((10 . 0) (10 . 10) (11 . 0)))
123 (test-split-at sched 10
124                '((8 . 1) (10 . 0))
125                '((10 . 10) (11 . 0)))
126 (test-split-at sched 9000
127                '((8 . 1) (10 . 0) (10 . 10) (11 . 0))
128                '())
129 (test-split-at sched '(9000 . 1)    ; over nine thousaaaaaaand
130                '((8 . 1) (10 . 0) (10 . 10) (11 . 0))
131                '())
132
133 ;; Break off half of those and do some tests on them
134 (define some-extracted
135   (schedule-extract-until! sched 10))
136 (assert-times-expected some-extracted '((8 . 1) (10 . 0)))
137 (assert-times-expected (schedule-segments sched) '((10 . 10) (11 . 0)))
138 (define first-extracted-queue
139   (time-segment-queue (car some-extracted)))
140 (define second-extracted-queue
141   (time-segment-queue (cadr some-extracted)))
142 (test-assert (not (q-empty? first-extracted-queue)))
143 (test-equal ((deq! first-extracted-queue)) 'd)
144 (test-assert (q-empty? first-extracted-queue))
145
146 (test-assert (not (q-empty? second-extracted-queue)))
147 (test-equal ((deq! second-extracted-queue)) 'a)
148 (test-equal ((deq! second-extracted-queue)) 'b)
149 (test-assert (q-empty? second-extracted-queue))
150
151 ;; Add one more and test flattening to a queue
152 (test-assert (not (schedule-empty? sched)))
153 (schedule-add! '(10 . 10) f-proc sched)
154 (define remaining-segments
155   (schedule-extract-until! sched '(9000 . 1)))
156 (test-assert (schedule-empty? sched))
157 (define some-queue (make-q))
158 (enq! some-queue (const 'ho-ho))
159 (enq! some-queue (const 'ha-ha))
160 (add-segments-contents-to-queue! remaining-segments some-queue)
161 (test-assert (not (q-empty? some-queue)))
162 (test-equal 'ho-ho ((deq! some-queue)))
163 (test-equal 'ha-ha ((deq! some-queue)))
164 (test-equal 'e ((deq! some-queue)))
165 (test-equal 'f ((deq! some-queue)))
166 (test-equal 'c ((deq! some-queue)))
167 (test-assert (q-empty? some-queue))
168
169 ;; ... whew!
170
171 ;; Run/wrap request stuff
172 ;; ----------------------
173
174 (let ((wrapped (wrap (+ 1 2))))
175   (test-assert (procedure? wrapped))
176   (test-equal (wrapped) 3))
177
178 (let ((run-two-squared (run (lambda () (* 2 2)))))
179   (test-assert (run-request? run-two-squared))
180   (test-assert (procedure? (run-request-proc run-two-squared)))
181   (test-equal ((run-request-proc run-two-squared)) 4)
182   (test-eq (run-request-when run-two-squared) #f))
183
184 (let ((run-two-squared (run (lambda () (* 2 2)) '(88 . 0))))
185   (test-assert (run-request? run-two-squared))
186   (test-assert (procedure? (run-request-proc run-two-squared)))
187   (test-equal ((run-request-proc run-two-squared)) 4)
188   (test-equal (run-request-when run-two-squared) '(88 . 0)))
189
190 (let ((run-two-squared (run-wrap (* 2 2))))
191   (test-assert (run-request? run-two-squared))
192   (test-assert (procedure? (run-request-proc run-two-squared)))
193   (test-equal ((run-request-proc run-two-squared)) 4)
194   (test-eq (run-request-when run-two-squared) #f))
195
196 (let ((run-two-squared (run-wrap-at (* 2 2) '(88 . 0))))
197   (test-assert (run-request? run-two-squared))
198   (test-assert (procedure? (run-request-proc run-two-squared)))
199   (test-equal ((run-request-proc run-two-squared)) 4)
200   (test-equal (run-request-when run-two-squared) '(88 . 0)))
201
202
203 ;;; Agenda tests
204 ;;; ------------
205
206 ;; helpers
207
208 (define (speak-it)
209   (let ((messages '()))
210     (lambda* (#:optional message)
211       (if message (set! messages (append messages (list message))))
212       messages)))
213
214 ;; the dummy test
215
216 (define speaker (speak-it))
217
218 (define (dummy-func)
219   (speaker "I'm a dummy\n"))
220
221 (define (run-dummy)
222   (speaker "I bet I can make you say you're a dummy!\n")
223   (run dummy-func))
224
225 (let ((q (make-q)))
226   (set! speaker (speak-it))  ; reset the speaker
227   (enq! q run-dummy)
228   (start-agenda (make-agenda #:queue q)
229                 (true-after-n-times 2))
230   (test-equal (speaker)
231     '("I bet I can make you say you're a dummy!\n"
232       "I'm a dummy\n")))
233
234 ;; should only do the first one after one round though
235 (let ((q (make-q)))
236   (set! speaker (speak-it))  ; reset the speaker
237   (enq! q run-dummy)
238   (start-agenda (make-agenda #:queue q)
239                 (true-after-n-times 1))
240   (test-equal (speaker)
241     '("I bet I can make you say you're a dummy!\n")))
242
243
244 ;; End tests
245
246 (test-end "tests")
247 ;; (test-exit)
248