Minor whitespace/documentation fixes
[fiveam.git] / t / tests.lisp
1 ;;;; -*- Mode: Lisp; indent-tabs-mode: nil -*-
2
3 (in-package :it.bese.fiveam)
4
5 (in-suite :it.bese.fiveam)
6
7 (def-suite test-suite
8     :description "Suite for tests which should fail."
9     :in nil)
10
11 (defmacro with-test-results ((results test-name) &body body)
12   `(let ((,results (with-*test-dribble* nil (run ',test-name))))
13      ,@body))
14
15 (def-fixture null-fixture ()
16   `(progn ,@(&body)))
17
18 ;;;; Test the checks
19
20 (def-test is1 (:suite test-suite)
21   (is (plusp 1))
22   (is (< 0 1))
23   (is (not (plusp -1)))
24   (is (not (< 1 0)))
25   (is-true t)
26   (is-false nil))
27
28 (def-test is2 (:suite test-suite :fixture null-fixture)
29   (is (plusp 0))
30   (is (< 0 -1))
31   (is (not (plusp 1)))
32   (is (not (< 0 1)))
33   (is-true nil)
34   (is-false t))
35
36 (def-test is (:profile t)
37   (with-test-results (results is1)
38     (is (= 6 (length results)))
39     (is (every #'test-passed-p results)))
40   (with-test-results (results is2)
41     (is (= 6 (length results)))
42     (is (every #'test-failure-p results))))
43
44 (def-test signals/finishes ()
45   (signals error
46     (error "an error"))
47   (finishes
48    (signals error
49     (error "an error"))))
50
51 (def-test pass ()
52   (pass))
53
54 (def-test fail1 (:suite test-suite)
55   (fail "This is supposed to fail"))
56
57 (def-test fail ()
58   (with-test-results (results fail1)
59     (is (= 1 (length results)))
60     (is (test-failure-p (first results)))))
61
62 ;;;; non top level checks
63
64 (def-test foo-bar ()
65   (let ((state 0))
66     (is (= 0 state))
67     (is (= 1 (incf state)))))
68
69 ;;;; Test dependencies
70
71 (def-test ok (:suite test-suite)
72   (pass))
73
74 (def-test not-ok (:suite test-suite)
75   (fail "This is supposed to fail."))
76
77 (def-test and1 (:depends-on (and ok not-ok) :suite test-suite)
78   (fail))
79
80 (def-test and2 (:depends-on (and ok) :suite test-suite)
81   (pass))
82
83 (def-test dep-and ()
84   (with-test-results (results and1)
85     (is (= 3 (length results)))
86     ;; we should have one skippedw one failed and one passed
87     (is (some #'test-passed-p results))
88     (is (some #'test-skipped-p results))
89     (is (some #'test-failure-p results)))
90   (with-test-results (results and2)
91     (is (= 2 (length results)))
92     (is (every #'test-passed-p results))))
93
94 (def-test or1 (:depends-on (or ok not-ok) :suite test-suite)
95   (pass))
96
97 (def-test or2 (:depends-on (or not-ok ok) :suite test-suite)
98   (pass))
99
100 (def-test dep-or ()
101   (with-test-results (results or1)
102     (is (= 2 (length results)))
103     (is (every #'test-passed-p results)))
104   (with-test-results (results or2)
105     (is (= 3 (length results)))
106     (is (= 2 (length (remove-if-not #'test-passed-p results))))))
107
108 (def-test not1 (:depends-on (not not-ok) :suite test-suite)
109   (pass))
110
111 (def-test not2 (:depends-on (not ok) :suite test-suite)
112   (fail))
113
114 (def-test not ()
115   (with-test-results (results not1)
116     (is (= 2 (length results)))
117     (is (some #'test-passed-p results))
118     (is (some #'test-failure-p results)))
119   (with-test-results (results not2)
120     (is (= 2 (length results)))
121     (is (some #'test-passed-p results))
122     (is (some #'test-skipped-p results))))
123
124 (def-test nested-logic (:depends-on (and ok (not not-ok) (not not-ok))
125                     :suite test-suite)
126   (pass))
127
128 (def-test dep-nested ()
129   (with-test-results (results nested-logic)
130     (is (= 3 (length results)))
131     (is (= 2 (length (remove-if-not #'test-passed-p results))))
132     (is (= 1 (length (remove-if-not #'test-failure-p results))))))
133
134 (def-test circular-0 (:depends-on (and circular-1 circular-2 or1) 
135                       :suite test-suite)
136   (fail "we depend on a circular dependency, we should not be tested."))
137
138 (def-test circular-1 (:depends-on (and circular-2)
139                       :suite test-suite)
140   (fail "we have a circular depednency, we should not be tested."))
141
142 (def-test circular-2 (:depends-on (and circular-1)
143                       :suite test-suite)
144   (fail "we have a circular depednency, we should not be tested."))
145
146 (def-test circular ()
147   (signals circular-dependency
148     (run 'circular-0))
149   (signals circular-dependency
150     (run 'circular-1))
151   (signals circular-dependency
152     (run 'circular-2)))
153
154 (def-suite before-test-suite :description "Suite for before test" :in nil)
155
156 (def-test before-0 (:suite before-test-suite)
157   (pass))
158
159 (def-test before-1 (:depends-on (:before before-0)
160                     :suite before-test-suite)
161   (fail))
162
163 (def-suite before-test-suite-2 :description "Suite for before test" :in nil)
164
165 (def-test before-2 (:depends-on (:before before-3)
166                     :suite before-test-suite-2)
167   (pass))
168
169 (def-test before-3 (:suite before-test-suite-2)
170   (pass))
171
172 (def-test before ()
173   (with-test-results (results before-test-suite)
174     (is (some #'test-skipped-p results)))
175   
176   (with-test-results (results before-test-suite-2)
177     (is (every #'test-passed-p results))))
178
179 ;;;; dependencies with symbol
180 (def-test dep-with-symbol-first (:suite test-suite)
181   (pass))
182
183 (def-test dep-with-symbol-dependencies-not-met (:depends-on (not dep-with-symbol-first)
184                                             :suite test-suite)
185   (fail "Error in the test of the test, this should not ever happen"))
186
187 (def-test dep-with-symbol-depends-on-ok (:depends-on dep-with-symbol-first :suite test-suite)
188   (pass))
189
190 (def-test dep-with-symbol-depends-on-failed-dependency (:depends-on dep-with-symbol-dependencies-not-met
191                                                     :suite test-suite)
192   (fail "No, I should not be tested becuase I depend on a test that in its turn has a failed dependecy."))
193
194 (def-test dependencies-with-symbol ()
195   (with-test-results (results dep-with-symbol-first)
196     (is (some #'test-passed-p results)))
197
198   (with-test-results (results dep-with-symbol-depends-on-ok)
199     (is (some #'test-passed-p results)))
200
201   (with-test-results (results dep-with-symbol-dependencies-not-met)
202     (is (some #'test-skipped-p results)))
203
204   ;; No failure here, because it means the test was run.
205   (with-test-results (results dep-with-symbol-depends-on-failed-dependency)
206     (is (not (some #'test-failure-p results)))))
207
208
209 ;;;; test for-all
210
211 (def-test gen-integer ()
212   (for-all ((a (gen-integer)))
213     (is (integerp a))))
214
215 (def-test for-all-guarded ()
216   (for-all ((less (gen-integer))
217             (more (gen-integer) (< less more)))
218     (is (< less more))))
219
220 (def-test gen-float ()
221   (macrolet ((test-gen-float (type)
222                `(for-all ((unbounded (gen-float :type ',type))
223                           (bounded   (gen-float :type ',type :bound 42)))
224                   (is (typep unbounded ',type))
225                   (is (typep bounded ',type))
226                   (is (<= (abs bounded) 42)))))
227     (test-gen-float single-float)
228     (test-gen-float short-float)
229     (test-gen-float double-float)
230     (test-gen-float long-float)
231
232     (for-all ((value (gen-float :type 'single-float :min 1 :max 2)))
233       (is (typep value 'single-float))
234       (is (<= (coerce 1 'single-float) value (coerce 2 'single-float))))))
235
236 (def-test gen-character ()
237   (for-all ((c (gen-character)))
238     (is (characterp c)))
239   (for-all ((c (gen-character :code (gen-integer :min 32 :max 40))))
240     (is (characterp c))
241     (member c (list #\Space #\! #\" #\# #\$ #\% #\& #\' #\())))
242
243 (def-test gen-string ()
244   (for-all ((s (gen-string)))
245     (is (stringp s)))
246   (for-all ((s (gen-string :length (gen-integer :min 0 :max 2))))
247     (is (<= (length s) 2)))
248   (for-all ((s (gen-string :elements (gen-character :code (gen-integer :min 0 :max 0))
249                            :length (constantly 2))))
250     (is (= 2 (length s)))
251     (is (every (curry #'char= #\Null) s))))
252
253 (defun dummy-mv-generator ()
254   (lambda ()
255     (list 1 1)))
256
257 (def-test for-all-destructuring-bind ()
258   (for-all (((a b) (dummy-mv-generator)))
259     (is (= 1 a))
260     (is (= 1 b))))
261
262 (def-test introspection ()
263   (is (= (length (list-all-suites))
264          (hash-table-count *suites*))))
265
266 (defvar *special-variable* nil)
267
268 (def-fixture fixture-for-suite (value)
269   (progn
270     (setf *special-variable* value)
271     (&body)))
272
273 (def-suite suite-with-fixture :fixture (fixture-for-suite 42) :in :it.bese.fiveam)
274
275 (def-test test-with-suite-fixture (:suite suite-with-fixture)
276   (is (= 42 *special-variable*)))
277
278 (def-test add-remove-test-from-suite ()
279   (let ((*test* (make-hash-table :test 'eql))
280         (*suites* (make-hash-table :test 'eql)))
281     (def-suite empty :in nil)
282     (in-suite empty)
283     (is (null (get-test 'foo)))
284
285     (def-test foo (:suite nil) t)
286     (is-true (get-test 'foo))
287     (is-false (gethash 'foo (tests *suite*)))
288
289     (def-test foo () t)
290     (is-true (gethash 'foo (tests *suite*)))
291
292     (def-test foo (:suite nil) t)
293     (is-false (gethash 'foo (tests *suite*)))))