Merge remote-tracking branch 'cl-fiveam/master'
authorMarco Baringer <mb@bese.it>
Sat, 9 Feb 2013 11:05:53 +0000 (12:05 +0100)
committerMarco Baringer <mb@bese.it>
Sat, 9 Feb 2013 11:05:53 +0000 (12:05 +0100)
Conflicts:
src/test.lisp

Update docstring for 5am:test to point to 5am:def-test

1  2 
src/test.lisp

diff --combined src/test.lisp
  
  (defvar *test*
    (make-hash-table :test 'eql)
 -  "Lookup table mapping test (and test suite)
 -  names to objects.")
 -
 -(defun get-test (key &optional default)
 -  (gethash key *test* default))
 +  "Lookup table mapping test (and test suite) names to objects.")
 +
 +(defun get-test (key &key default error)
 +  "Finds the test named KEY. If KEY is a testable-object (a test case
 +or a test suite) then we just return KEY, otherwise we look for a test
 +named KEY in the *TEST* hash table."
 +  (if (testable-object-p key)
 +      key
 +      (multiple-value-bind (value foundp)
 +          (gethash key *test*)
 +        (if foundp
 +            value
 +            (if error
 +                (error "Unable to find test named ~S." key)
 +                default)))))
  
  (defun (setf get-test) (value key)
    (setf (gethash key *test*) value))
          collect test))
  
  (defmacro test (name &body body)
-   "Deprecated. See DEF-TEST."
-   (simple-style-warning "~A is OBSOLETE! Use ~A instead." 'test 'def-test)
 -  "Create a test named NAME. If NAME is a list it must be of the
 -form:
 -
 -  (name &key depends-on suite fixture compile-at profile)
 -
 -NAME is the symbol which names the test.
 -
 -DEPENDS-ON is a list of the form:
 -
 - (AND . test-names) - This test is run only if all of the tests
 - in TEST-NAMES have passed, otherwise a single test-skipped
 - result is generated.
 -
 - (OR . test-names) - If any of TEST-NAMES has passed this test is
 - run, otherwise a test-skipped result is generated.
 -
 - (NOT test-name) - This is test is run only if TEST-NAME failed.
 -
 -AND, OR and NOT can be combined to produce complex dependencies.
 -
 -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.
 -
 -FIXTURE specifies a fixture to wrap the body in.
 -
 -If PROFILE is T profiling information will be collected as well."
++  "Alias for DEF-TEST."
    (destructuring-bind (name &rest args)
        (ensure-list name)
      `(def-test ,name (,@args) ,@body)))
  
 -(defmacro def-test (name (&key depends-on (suite '*suite* suite-p) fixture
 -                            (compile-at :run-time) profile)
 +(defmacro def-test (name (&key (suite nil suite-p)
 +                               fixture
 +                               (compile-at :run-time)
 +                               depends-on
 +                               profile)
                      &body body)
    "Create a test named NAME.
  
 -NAME is the symbol which names the test.
 +NAME (a symbol)::
 +  The name of the test.
 +
 +SUITE (a test name)::
 +  The suite to put the test under. It defaults to *SUITE* (which
 +  itself defaults to the default global suite).
  
 -DEPENDS-ON is a list of the form:
 +FIXTURE::
 +  The name of the fixture to use for this test. See `WITH-FIXTURE` for
 +  details on fixtures.
  
 - (AND . test-names) - This test is run only if all of the tests
 - in TEST-NAMES have passed, otherwise a single test-skipped
 - result is generated.
 +COMPILE-AT (a keyword)::
 +  When the body of this test should be compiled. By default, or when
 +  `:compile-at` is `:run-time`, test bodies are only compiled before
 +  they are run. Set this to to `:definition-time` to force
 +  compilation, and errors/warnings, to be done at compile time.
  
 - (OR . test-names) - If any of TEST-NAMES has passed this test is
 - run, otherwise a test-skipped result is generated.
 +DEPENDS-ON::
 +  A list, or a symbol, which specifies the relationship between this
 +  test and other tests. These conditions, `AND`, `OR` and `NOT` can be
 +  combined to produce complex dependencies (whethere this is something
 +  you should actually be doing is a question for another day).
  
 - (NOT test-name) - This is test is run only if TEST-NAME failed.
 +  `(and &rest TEST-NAMES)`:::
 +    This test is run only if all of the tests in TEST-NAMES have
 +    passed, otherwise a single test-skipped result is generated.
  
 -AND, OR and NOT can be combined to produce complex dependencies.
 +  `(or &rest TEST-NAMES)`:::
 +    If any of TEST-NAMES has passed this test is run, otherwise a
 +    test-skipped result is generated.
  
 -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.
 +  `(NOT TEST-NAME`:::
 +    This is test is run only if TEST-NAME failed.
  
 -FIXTURE specifies a fixture to wrap the body in.
 +  __a-symbol__:::
 +    Shorthand for `(AND a-symbol)`
  
 -If PROFILE is T profiling information will be collected as well."
 +PROFILE::
 +  When non-`NIL` profiling information will be collected as well."
    (check-type compile-at (member :run-time :definition-time))
    (multiple-value-bind (forms decls docstring)
        (parse-body body :documentation t :whole name)
      (let* ((description (or docstring ""))
             (body-forms (append decls forms))
             (suite-form (if suite-p
 -                           `(get-test ',suite)
 -                           (or suite '*suite*)))
 -           (effective-body (if fixture
 -                               (destructuring-bind (name &rest args)
 -                                   (ensure-list fixture)
 -                                 `((with-fixture ,name ,args ,@body-forms)))
 -                               body-forms)))
 +                           (if suite
 +                               `(get-test ',suite)
 +                               nil)
 +                           '*suite*))
 +           (effective-body (let* ((test-fixture fixture)
 +                                  (suite-fixture (if suite-p
 +                                                     (if suite
 +                                                         (fixture (get-test suite :error t))
 +                                                         nil)
 +                                                     (if *suite*
 +                                                         (fixture *suite*)
 +                                                         nil)))
 +                                  (effective-fixture (or test-fixture suite-fixture)))
 +                             (if effective-fixture
 +                                 (destructuring-bind (name &rest args)
 +                                     (ensure-list effective-fixture)
 +                                   `((with-fixture ,name ,args ,@body-forms)))
 +                                 body-forms))))
        `(progn
 -         (register-test ',name ,description ',effective-body ,suite-form ',depends-on ,compile-at ,profile)
 +         (register-test :name ',name
 +                        :description ,description
 +                        :body ',effective-body
 +                        :suite ,suite-form
 +                        :depends-on ',depends-on
 +                        :compile-at ,compile-at
 +                        :profile ,profile)
           (when *run-test-when-defined*
             (run! ',name))
           ',name))))
  
 -(defun register-test (name description body suite depends-on compile-at profile)
 +(defun register-test (&key name description body suite depends-on compile-at profile)
 +  (remove-from-suites name)
    (let ((lambda-name
            (format-symbol t "%~A-~A" '#:test name))
          (inner-lambda-name
                           :description description
                           :depends-on depends-on
                           :collect-profiling-info profile))
 -    (setf (gethash name (tests suite)) name)))
 +    (when suite
 +      (setf (gethash name (tests (get-test suite :error t))) name))))
  
  (defvar *run-test-when-defined* nil
    "When non-NIL tests are run as soon as they are defined.")