3 (defvar *current-configuration-stream
* nil
)
5 (defvar *current-asdf-system-name
* nil
)
7 (eval-when (:load-toplevel
:execute
)
8 (when (find-package :asdf
)
9 (defmethod asdf:perform
:around
((operation asdf
:test-op
) (c asdf
:system
))
10 (let ((*current-asdf-system-name
* (asdf:component-name c
)))
11 (call-next-method)))))
13 (defun lift-relative-pathname (pathname &optional
(errorp nil
))
14 "Merges pathname with either the path to the currently loading system
15 \(if there is one\) or the *default-pathname-defaults*."
16 (let* ((asdf-package (find-package :asdf
))
17 (srp-symbol (and asdf-package
18 (find-symbol (symbol-name 'system-relative-pathname
)
20 (srp (and *current-asdf-system-name
* srp-symbol
)))
21 (labels ((try-it (path)
22 (let ((pathname (merge-pathnames pathname path
)))
23 (if errorp
(and pathname
(probe-file pathname
)) pathname
))))
24 (or (and srp
(try-it (funcall srp
*current-asdf-system-name
* "")))
25 (try-it *default-pathname-defaults
*)
27 (and (not asdf-package
)
28 (error "Unable to use :generic configuration option because ASDF is not loaded."))
30 (error "Unable to use :generic configuration option because asdf:system-relative-pathname is not function bound (maybe try updating ASDF?)"))
31 (and (not *current-asdf-system-name
*)
32 (error "Unable to use :generic configuration option because because the current system cannot be determined. Are you using asdf:test-op?"))))))
34 (defun find-generic-test-configuration (&optional
(errorp nil
))
36 (and path
(probe-file path
))))
37 (or (try-it (lift-relative-pathname "lift-local.config" errorp
))
38 (try-it (lift-relative-pathname "lift-standard.config" errorp
))
40 (error "Unable to use :generic configuration file neither lift-local.config nor lift-standard.config can be found.")))))
42 (defun report-summary-pathname ()
43 (unique-filename (generate-report-summary-pathname)))
45 (defmethod generate-report-summary-pathname ()
46 (lift-relative-pathname "test-results/summary.sav"))
49 (generate-report-summary-pathname)
51 (defun run-tests-from-file (path)
52 (let ((real-path (cond ((eq path
:generic
)
54 (find-generic-test-configuration t
)))
58 (error "Unable to find configuration file ~s" path
))
60 (let* ((*package
* *package
*)
62 (result (make-test-result path
:multiple
))
63 (*lift-dribble-pathname
* nil
)
64 (*lift-debug-output
* *debug-io
*)
65 (*lift-standard-output
* *standard-output
*)
66 (*test-break-on-errors?
* nil
)
67 (*test-do-children?
* t
)
68 (*lift-equality-test
* 'equal
)
69 (*test-print-length
* :follow-print
)
70 (*test-print-level
* :follow-print
)
71 (*lift-if-dribble-exists
* :append
)
72 (*test-result
* result
))
73 (%run-tests-from-file path
)))))
75 (defun %run-tests-from-file
(path)
76 (with-open-file (*current-configuration-stream
* path
78 :if-does-not-exist
:error
)
80 (loop while
(not (eq (setf form
(read *current-configuration-stream
*
84 ((error (lambda (c) (format
86 "Error while running ~a from ~a: ~a"
88 (print (get-backtrace c
))
89 (invoke-debugger c
))))
93 (assert (typep name
'symbol
) nil
94 "Each command must be a symbol and ~s is not." name
)
95 (setf args
(massage-arguments args
))
97 ;; check for preferences first (i.e., keywords)
98 ((eq (symbol-package name
)
99 (symbol-package :keyword
))
100 ;; must be a preference
101 (handle-config-preference name args
))
102 ((subtypep (find-testsuite name
)
104 (apply #'run-tests
:suite name
105 :result
*test-result
* args
))
107 (error "Don't understand '~s' while reading from ~s"
109 (values *test-result
*))
111 (defun massage-arguments (args)
112 (loop for arg in args collect
113 (cond ((and (symbolp arg
)
114 (string= (symbol-name arg
) (symbol-name '*standard-output
*)))
118 (defmethod handle-config-preference ((name t
) args
)
119 (error "Unknown preference ~s (with arguments ~s)"
122 (defmethod handle-config-preference ((name (eql :include
)) args
)
123 (%run-tests-from-file
(merge-pathnames (first args
)
124 *current-configuration-stream
*)))
126 (defmethod handle-config-preference ((name (eql :dribble
)) args
)
127 (setf *lift-dribble-pathname
* (first args
)))
129 (defmethod handle-config-preference ((name (eql :debug-output
)) args
)
130 (setf *lift-debug-output
* (first args
)))
132 (defmethod handle-config-preference ((name (eql :standard-output
)) args
)
133 (setf *lift-standard-output
* (first args
)))
135 (defmethod handle-config-preference ((name (eql :break-on-errors?
)) args
)
136 (setf *test-break-on-errors?
* (first args
)))
138 (defmethod handle-config-preference ((name (eql :do-children?
)) args
)
139 (setf *test-do-children?
* (first args
)))
141 (defmethod handle-config-preference ((name (eql :equality-test
)) args
)
142 (setf *lift-equality-test
* (first args
)))
144 (defmethod handle-config-preference ((name (eql :print-length
)) args
)
145 (setf *test-print-length
* (first args
)))
147 (defmethod handle-config-preference ((name (eql :print-level
)) args
)
148 (setf *test-print-level
* (first args
)))
150 (defmethod handle-config-preference ((name (eql :print-suite-names
)) args
)
151 (setf *test-print-testsuite-names
* (first args
)))
153 (defmethod handle-config-preference ((name (eql :print-test-case-names
)) args
)
154 (setf *test-print-test-case-names
* (first args
)))
156 (defmethod handle-config-preference ((name (eql :if-dribble-exists
))
158 (setf *lift-if-dribble-exists
* (first args
)))
160 (defmethod handle-config-preference ((name (eql :report-property
))
162 (setf (test-result-property *test-result
* (first args
)) (second args
)))
164 (defmethod handle-config-preference ((name (eql :profiling-threshold
))
166 (setf *profiling-threshold
* (first args
)))
168 (defmethod handle-config-preference ((name (eql :count-calls-p
))
170 (setf *count-calls-p
* (first args
)))
172 (defmethod handle-config-preference ((name (eql :log-pathname
))
174 (setf *lift-report-pathname
* (first args
)))
176 (defmethod handle-config-preference ((name (eql :build-report
))
178 (declare (ignore args
))
179 (let* ((dest (or (test-result-property *test-result
* :full-pathname
)
180 (asdf:system-relative-pathname
181 (or (test-result-property *test-result
* :relative-to
)
183 (or (test-result-property *test-result
* :name
)
185 (format (or (test-result-property *test-result
* :format
)
187 (unique-name (test-result-property *test-result
* :unique-name
)))
188 (when (and unique-name
(not (streamp dest
)))
189 (setf dest
(unique-filename dest
)))
190 (with-standard-io-syntax
191 (let ((*print-readably
* nil
))
196 "Error ~a while generating report (format ~s) to ~a"
199 "~%~%Backtrace~%~%~s"
200 (get-backtrace c
)))))
202 ((or (streamp dest
) (writable-directory-p dest
))
203 (format *debug-io
* "~&Sending report (format ~s) to ~a"
210 (format *debug-io
* "~&Unable to write report (format ~s) to ~a"