Added :fixture argument to TEST macro
[fiveam.git] / src / test.lisp
index 7d763d1..33fa7c8 100644 (file)
 ;;;; collection of tests and test suites.
 
 (deflookup-table test
+  :at-redefinition nil
   :documentation "Lookup table mapping test (and test suite)
   names to objects.")
 
+(defun test-names ()
+  (loop for test being the hash-keys of *test*
+        collect test))
+
 (defmacro test (name &body body)
   "Create a test named NAME. If NAME is a list it must be of the
 form:
 
-  (name &key depends-on suite)
+  (name &key depends-on suite fixture compile-at)
 
 NAME is the symbol which names the test.
 
@@ -40,19 +45,33 @@ If DEPENDS-ON is a symbol it is interpreted as `(AND
 ,depends-on), this is accomadate the common case of one test
 depending on another.
 
-SUITE defaults to the current value of *SUITE*."
-  (destructuring-bind (name &key depends-on (suite nil suite-supplied-p))
+SUITE defaults to the current value of *SUITE*.
+
+FIXTURE specifies a fixtrue to wrap the body in."
+  (destructuring-bind (name &key depends-on (suite nil suite-supplied-p)
+                                 (compile-at :run-time) fixture)
       (ensure-list name)
-    (let (description)
-      (setf description (if (stringp (car body))
-                           (pop body)
-                           ""))
+    (declare (type (member :run-time :definition-time) compile-at))
+    (let ((description (if (stringp (car body))
+                           (pop body)
+                           ""))
+          (effective-body (if fixture
+                              (destructuring-bind (name &rest args)
+                                  (ensure-list fixture)
+                                `((with-fixture ,name ,args ,@body)))
+                              body)))
       `(progn
         (setf (get-test ',name) (make-instance 'test-case
                                                 :name ',name
+                                                :runtime-package ,*package*
                                                 :test-lambda
                                                 (lambda ()
-                                                  (funcall (compile nil '(lambda () ,@body))))
+                                                  ,@ (ecase compile-at
+                                                       (:run-time `((funcall
+                                                                     (let ((*package* (find-package ',(package-name *package*))))
+                                                                       (compile nil '(lambda ()
+                                                                                      ,@effective-body))))))
+                                                       (:definition-time effective-body)))
                                                 :description ,description
                                                 :depends-on ',depends-on))
         ,(if suite-supplied-p
@@ -60,8 +79,13 @@ SUITE defaults to the current value of *SUITE*."
                     ',name)
              `(setf (gethash ',name (tests (or *suite* (get-test 'NIL))))
                     ',name))
+         (when *run-test-when-defined*
+           (run! ',name))
         ',name))))
 
+(defvar *run-test-when-defined* nil
+  "When non-NIL tests are run as soon as they are defined.")
+
 ;; Copyright (c) 2002-2003, Edward Marco Baringer
 ;; All rights reserved. 
 ;;