-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathunit-test.lisp
49 lines (40 loc) · 1.36 KB
/
unit-test.lisp
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
(defpackage jvm.unit-test
(:use common-lisp)
(:nicknames jvm.unit-test)
(:export deftest
close-to
check
check-equal
run-test-suite))
(in-package jvm.unit-test)
(defvar *test-name* nil)
(defvar *test-names* nil)
(defmacro with-gensyms (syms &body body)
`(let ,(mapcar #'(lambda (s) (list s '(gensym))) syms)
,@body))
(defmacro deftest (name parameters &body body)
"Define a test function. Within a test function we can call
other test functions or use 'check' to run individual test
cases."
`(defun ,name ,parameters
(let ((*test-name* ,name))
,@body)))
(defmacro check (&body forms)
"Run each expression in 'forms' as a test case."
`(combine-results
,@(loop for f in forms collect `(report-result ,f ',f))))
(defmacro combine-results (&body forms)
"Combine the results (as booleans) of evaluating 'forms' in order."
(with-gensyms (result)
`(let ((,result t))
,@(loop for f in forms collect `(unless ,f (setf ,result nil)))
,result)))
(defun report-result (result form)
"Report the results of a single test case. Called by 'check'."
(format t "~:[FAIL~;pass~] ... ~a: ~a~%" result *test-name* form)
result)
(defun close-to (expected value accuracy)
(< (abs (- expected value)) accuracy))
(defun run-test-suite ()
(dolist (name *test-names*)
(funcall name)))