1 ;;;_ tinydb/persist/tests.el --- tests for persist
5 ;; Copyright (C) 2010 Tom Breton (Tehom)
7 ;; Author: Tom Breton (Tehom) <tehom@panix.com>
8 ;; Keywords: lisp, maint, internal
10 ;; This file is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; This file is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
32 (require 'tinydb
/persist
)
33 (require 'emtest
/testhelp
/tagnames
)
34 (require 'emtest
/testhelp
/mocks
/filebuf
)
35 (require 'emtest
/testhelp
/testpoint
)
37 (defconst persist
:th
:examples-dir
38 (emtb:expand-filename-by-load-file
"examples/")
39 "Directory where examples are" )
44 ;;The roles here are out of sync
45 (defconst tinydb
/persist
:thd
:examples
46 (emtg:define
+ ;;xmp:b5d33625-bd1d-49d3-9c56-148b699eba99
47 ((project emtest
)(library persist
))
48 (group ((type filename
))
50 (expand-file-name "1" persist
:th
:examples-dir
))
52 (expand-file-name "2" persist
:th
:examples-dir
)))
54 (group ((creation-time before
))
55 (item ((type data
)) '(1 10 500)))
57 (group ((creation-time now
))
58 (item ((type data
)) '(56 25 17)))))
61 ;;;_ , tinydb/buffer Same tests on the alist wrt files
63 (emt:deftest-3 tinydb
/buffer
65 (emtg:with tinydb
/persist
:thd
:examples
66 ((project emtest
)(library persist
))
69 (tinydb-persist-make-q
71 (emtg (type filename
)(role master
))
76 "Situation: The file exists; we know what data it contains.")
78 ;;Test that we can read it.
79 (emt:doc
"Operation: Get that data.")
80 (emt:doc
"Result: The data is what we expect.")
83 (tinydb-get-obj filetq
)
84 (emtg (type data
)(creation-time before
)))))))
86 (emtg:with tinydb
/persist
:thd
:examples
87 ((project emtest
)(library persist
))
88 (emtb:with-file-f
(:absent t
) filename
93 (tinydb-persist-make-q
99 (emt:doc
"Situation: The file doesn't already exist.")
100 (emt:doc
"Param: The eager-save flag is nil.")
101 (emt:doc
"Operation: read from the filetq.")
102 (emt:doc
"Result: It returns the initial value.")
106 (tinydb-get-obj filetq
)
109 ;;The file still doesn't exist, because it was not
110 ;;eager-save and no operation we did should have
112 (emt:doc
"Check: Whether the file exists now.")
113 (emt:doc
"Result: It returns the initial value.")
115 (not (file-exists-p filename
))
120 ;;;_ , tinydb/buffer/alist/mutate
121 (emt:deftest-3 tinydb
/buffer
/alist
/mutate
124 (emtg:with tinydb
/persist
:thd
:examples
125 ((project emtest
)(library persist
))
127 (:file
(emtg (role master
)(type filename
)))
129 (emt:doc
"Situation: Read a persisting object.")
130 (emt:doc
"Operation: Set a different value. Read it as if fresh.")
131 (emt:doc
"Afterwards: It retains the new value.")
135 (tinydb-persist-make-q
141 ;;Validate: We got the expected original value.
144 (tinydb-get-obj filetq
)
145 (emtg (creation-time before
)(type data
)))
148 ;;Set it to the new value.
151 (emtg (creation-time now
)(type data
)))
153 ;;The new value is immediately available.
155 ((value (tinydb-get-obj filetq
)))
159 (emtg (creation-time now
)(type data
)))
165 (emtg:with tinydb
/persist
:thd
:examples
166 ((project emtest
)(library persist
))
167 (emtb:with-file-f
(:absent t
) filename
170 (initial-value '(12)) ;;Distinct from nil
172 (tinydb-persist-make-q
178 (emt:doc
"Situation: The file doesn't yet exist.")
179 (emt:doc
"Situation: The eager-save flag is set.")
181 ;;Eager save causes the file to exist.
182 (emt:doc
"Afterwards: File now exists.")
184 (file-exists-p filename
)
187 (emt:doc
"Afterwards: file's contents are the initial value.")
189 ((text (emtb:file-contents-absname filename
))
190 (obj (if text
(read text
))))
192 (equal obj initial-value
)
194 (emt:doc
"Operation: Read it.")
195 (emt:doc
"Result: It returns the initial value.")
198 (tinydb-get-obj filetq
)
204 ;;;_ , tinydb/buffer/update
205 (emt:deftest-3 tinydb
/buffer
/update
208 (emt:doc
"Operation: Try to write a different value that fails the
210 (emt:doc
"Result: Signal an error.")
211 (emt:doc
"Afterwards: Read it as if fresh. It still has the old value.")
212 (emtg:with tinydb
/persist
:thd
:examples
223 (tinydb-persist-make-q filename
'nil t
#'listp
)))
224 (emt:doc
"Operation: Try to save a value that fails the type predicate.")
225 (tinydb-set-obj filetq
'not-a-list
)
226 (emt:doc
"Result: Object still has the old value.")
229 (tinydb-get-obj filetq
)
232 (creation-time before
))))
236 (emt:doc
"Operation: Try to write a value that can't be read - In fact, a
238 (emt:doc
"Result: Signal an error.
240 (emt:doc
"Afterwards: Read it as if fresh. It still has the old value.")
241 (emtg:with tinydb
/persist
:thd
:examples
252 (tinydb-persist-make-q filename
'nil t
#'listp
)))
253 (emt:doc
"Operation: Try to save a value that can't be read.")
254 (tinydb-set-obj filetq
256 (emt:doc
"Result: Object still has the old value.")
259 (tinydb-get-obj filetq
)
262 (creation-time before
))))
266 (defun persist:th
:make-usual-tq
(initial)
274 #'(lambda (old-obj obj
)
276 ;;Type predicate that always passes
281 ;;;_ , tinydb-alist-push
282 (emt:deftest-3 tinydb-alist-push
285 (emt:doc
"Proves: Can write to it (via `tinydb-alist-push').")
291 (persist:th
:make-usual-tq
293 (tinydb-alist-push tq
'a
12)
294 (tinydb-q-do-pending tq
)
298 '((a .
12) (b .
144)))
303 ;;;_ , tinydb-alist-assoc
304 (emt:deftest-3 tinydb-alist-assoc
307 (emt:doc
"Proves: Can read from it via `tinydb-alist-assoc'.")
313 (persist:th
:make-usual-tq
316 (tinydb-alist-assoc tq
'a
)))
329 ;;;_ , Reentrancy tests
331 ;;These tests are theoretically sensitive to processor speed, but the
332 ;;specified durations are extremely generous so there shouldn't be a
334 (emt:deftest-3 tinydb
/reentrancy
337 (emt:doc
"Proves: Timer events can run during sleep-for.")
340 (run-with-timer 0.1 nil
352 (assq 'timed recorded
)
355 (assq 'delayed recorded
)
360 (assq 'timed recorded
)))
363 (assq 'delayed recorded
)))
365 (time-subtract delayed-ran-at timed-ran-at
)))
367 (time-less-p time-diff
368 (seconds-to-time 0.99))
372 (seconds-to-time 0.8)
378 (emt:doc
"Proves: Validates the testing mechanism with sit-for vs a
384 (run-with-timer 0.2 nil
386 (push "Start 2" list
)
388 (push "End 2" list
)))
389 (push "Start test" list
)
391 (push "End test" list
)
395 '("Start test" "Start 2" "End 2" "End test"))
400 (emt:doc
"Proves: Validates the testing mechanism with multiple run-with-timers.
401 (which somehow nests their sit-for calls)")
406 (run-with-timer 0.1 nil
408 (push "Start 1" list
)
411 (push "End 1" list
)))
412 (run-with-timer 0.2 nil
414 (push "Start 2" list
)
417 (push "End 2" list
)))
418 (push "Start test" list
)
420 (push "End test" list
)
424 '("Start test" "Start 1" "Start 2" "End 2" "End 1" "End test"))
429 (emt:doc
"Proves: Can see the internal object (at all).")
435 (persist:th
:make-usual-tq
438 (tinydb-q-will-call tq t
454 (emt:doc
"Proves: Calling `tinydb-q-will-call' recursively in handler
456 FIX ME: This logic has changed. Now it's only reads that require
464 (persist:th
:make-usual-tq
466 (push "Start test" list
)
467 (tinydb-q-will-call tq nil
472 (tinydb-q-will-call tq t
#'identity
))
474 (push "End test" list
)
478 '("Start test" "End test"))
489 (emt:doc
"Proves: Can write asynchronously to it.")
495 (persist:th
:make-usual-tq
497 (push "Start test" list
)
498 (run-with-timer 0.1 nil
501 (push "Start 1" list
)
502 (tinydb-q-will-call tq nil
507 (throw 'tinydb-q-new-obj
511 (run-with-timer 0.2 nil
514 (push "Start 2" list
)
515 (tinydb-q-will-call tq nil
519 (throw 'tinydb-q-new-obj
524 (tinydb-q-do-pending tq
)
525 (push "End test" list
)
529 '("Start test" "Start 1" "Start 2" "End 1" "End test"))
543 (provide 'tinydb
/persist
/tests
)
545 ;;;_ * Local emacs vars.
546 ;;;_ + Local variables:
551 ;;; tinydb/persist/tests.el ends here