diff src/clojure/test.clj @ 10:ef7dbbd6452c

added clojure source goodness
author Robert McIntyre <rlm@mit.edu>
date Sat, 21 Aug 2010 06:25:44 -0400
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/clojure/test.clj	Sat Aug 21 06:25:44 2010 -0400
     1.3 @@ -0,0 +1,758 @@
     1.4 +;   Copyright (c) Rich Hickey. All rights reserved.
     1.5 +;   The use and distribution terms for this software are covered by the
     1.6 +;   Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
     1.7 +;   which can be found in the file epl-v10.html at the root of this distribution.
     1.8 +;   By using this software in any fashion, you are agreeing to be bound by
     1.9 +;   the terms of this license.
    1.10 +;   You must not remove this notice, or any other, from this software.
    1.11 +
    1.12 +;;; test.clj: test framework for Clojure
    1.13 +
    1.14 +;; by Stuart Sierra
    1.15 +;; March 28, 2009
    1.16 +
    1.17 +;; Thanks to Chas Emerick, Allen Rohner, and Stuart Halloway for
    1.18 +;; contributions and suggestions.
    1.19 +
    1.20 +(ns 
    1.21 +  ^{:author "Stuart Sierra, with contributions and suggestions by 
    1.22 +  Chas Emerick, Allen Rohner, and Stuart Halloway",
    1.23 +     :doc "A unit testing framework.
    1.24 +
    1.25 +   ASSERTIONS
    1.26 +
    1.27 +   The core of the library is the \"is\" macro, which lets you make
    1.28 +   assertions of any arbitrary expression:
    1.29 +
    1.30 +   (is (= 4 (+ 2 2)))
    1.31 +   (is (instance? Integer 256))
    1.32 +   (is (.startsWith \"abcde\" \"ab\"))
    1.33 +
    1.34 +   You can type an \"is\" expression directly at the REPL, which will
    1.35 +   print a message if it fails.
    1.36 +
    1.37 +       user> (is (= 5 (+ 2 2)))
    1.38 +
    1.39 +       FAIL in  (:1)
    1.40 +       expected: (= 5 (+ 2 2))
    1.41 +         actual: (not (= 5 4))
    1.42 +       false
    1.43 +
    1.44 +   The \"expected:\" line shows you the original expression, and the
    1.45 +   \"actual:\" shows you what actually happened.  In this case, it
    1.46 +   shows that (+ 2 2) returned 4, which is not = to 5.  Finally, the
    1.47 +   \"false\" on the last line is the value returned from the
    1.48 +   expression.  The \"is\" macro always returns the result of the
    1.49 +   inner expression.
    1.50 +
    1.51 +   There are two special assertions for testing exceptions.  The
    1.52 +   \"(is (thrown? c ...))\" form tests if an exception of class c is
    1.53 +   thrown:
    1.54 +
    1.55 +   (is (thrown? ArithmeticException (/ 1 0))) 
    1.56 +
    1.57 +   \"(is (thrown-with-msg? c re ...))\" does the same thing and also
    1.58 +   tests that the message on the exception matches the regular
    1.59 +   expression re:
    1.60 +
    1.61 +   (is (thrown-with-msg? ArithmeticException #\"Divide by zero\"
    1.62 +                         (/ 1 0)))
    1.63 +
    1.64 +   DOCUMENTING TESTS
    1.65 +
    1.66 +   \"is\" takes an optional second argument, a string describing the
    1.67 +   assertion.  This message will be included in the error report.
    1.68 +
    1.69 +   (is (= 5 (+ 2 2)) \"Crazy arithmetic\")
    1.70 +
    1.71 +   In addition, you can document groups of assertions with the
    1.72 +   \"testing\" macro, which takes a string followed by any number of
    1.73 +   assertions.  The string will be included in failure reports.
    1.74 +   Calls to \"testing\" may be nested, and all of the strings will be
    1.75 +   joined together with spaces in the final report, in a style
    1.76 +   similar to RSpec <http://rspec.info/>
    1.77 +
    1.78 +   (testing \"Arithmetic\"
    1.79 +     (testing \"with positive integers\"
    1.80 +       (is (= 4 (+ 2 2)))
    1.81 +       (is (= 7 (+ 3 4))))
    1.82 +     (testing \"with negative integers\"
    1.83 +       (is (= -4 (+ -2 -2)))
    1.84 +       (is (= -1 (+ 3 -4)))))
    1.85 +
    1.86 +   Note that, unlike RSpec, the \"testing\" macro may only be used
    1.87 +   INSIDE a \"deftest\" or \"with-test\" form (see below).
    1.88 +
    1.89 +
    1.90 +   DEFINING TESTS
    1.91 +
    1.92 +   There are two ways to define tests.  The \"with-test\" macro takes
    1.93 +   a defn or def form as its first argument, followed by any number
    1.94 +   of assertions.  The tests will be stored as metadata on the
    1.95 +   definition.
    1.96 +
    1.97 +   (with-test
    1.98 +       (defn my-function [x y]
    1.99 +         (+ x y))
   1.100 +     (is (= 4 (my-function 2 2)))
   1.101 +     (is (= 7 (my-function 3 4))))
   1.102 +
   1.103 +   As of Clojure SVN rev. 1221, this does not work with defmacro.
   1.104 +   See http://code.google.com/p/clojure/issues/detail?id=51
   1.105 +
   1.106 +   The other way lets you define tests separately from the rest of
   1.107 +   your code, even in a different namespace:
   1.108 +
   1.109 +   (deftest addition
   1.110 +     (is (= 4 (+ 2 2)))
   1.111 +     (is (= 7 (+ 3 4))))
   1.112 +
   1.113 +   (deftest subtraction
   1.114 +     (is (= 1 (- 4 3)))
   1.115 +     (is (= 3 (- 7 4))))
   1.116 +
   1.117 +   This creates functions named \"addition\" and \"subtraction\", which
   1.118 +   can be called like any other function.  Therefore, tests can be
   1.119 +   grouped and composed, in a style similar to the test framework in
   1.120 +   Peter Seibel's \"Practical Common Lisp\"
   1.121 +   <http://www.gigamonkeys.com/book/practical-building-a-unit-test-framework.html>
   1.122 +
   1.123 +   (deftest arithmetic
   1.124 +     (addition)
   1.125 +     (subtraction))
   1.126 +
   1.127 +   The names of the nested tests will be joined in a list, like
   1.128 +   \"(arithmetic addition)\", in failure reports.  You can use nested
   1.129 +   tests to set up a context shared by several tests.
   1.130 +
   1.131 +
   1.132 +   RUNNING TESTS
   1.133 +
   1.134 +   Run tests with the function \"(run-tests namespaces...)\":
   1.135 +
   1.136 +   (run-tests 'your.namespace 'some.other.namespace)
   1.137 +
   1.138 +   If you don't specify any namespaces, the current namespace is
   1.139 +   used.  To run all tests in all namespaces, use \"(run-all-tests)\".
   1.140 +
   1.141 +   By default, these functions will search for all tests defined in
   1.142 +   a namespace and run them in an undefined order.  However, if you
   1.143 +   are composing tests, as in the \"arithmetic\" example above, you
   1.144 +   probably do not want the \"addition\" and \"subtraction\" tests run
   1.145 +   separately.  In that case, you must define a special function
   1.146 +   named \"test-ns-hook\" that runs your tests in the correct order:
   1.147 +
   1.148 +   (defn test-ns-hook []
   1.149 +     (arithmetic))
   1.150 +
   1.151 +
   1.152 +   OMITTING TESTS FROM PRODUCTION CODE
   1.153 +
   1.154 +   You can bind the variable \"*load-tests*\" to false when loading or
   1.155 +   compiling code in production.  This will prevent any tests from
   1.156 +   being created by \"with-test\" or \"deftest\".
   1.157 +
   1.158 +
   1.159 +   FIXTURES (new)
   1.160 +
   1.161 +   Fixtures allow you to run code before and after tests, to set up
   1.162 +   the context in which tests should be run.
   1.163 +
   1.164 +   A fixture is just a function that calls another function passed as
   1.165 +   an argument.  It looks like this:
   1.166 +
   1.167 +   (defn my-fixture [f]
   1.168 +      Perform setup, establish bindings, whatever.
   1.169 +     (f)  Then call the function we were passed.
   1.170 +      Tear-down / clean-up code here.
   1.171 +    )
   1.172 +
   1.173 +   Fixtures are attached to namespaces in one of two ways.  \"each\"
   1.174 +   fixtures are run repeatedly, once for each test function created
   1.175 +   with \"deftest\" or \"with-test\".  \"each\" fixtures are useful for
   1.176 +   establishing a consistent before/after state for each test, like
   1.177 +   clearing out database tables.
   1.178 +
   1.179 +   \"each\" fixtures can be attached to the current namespace like this:
   1.180 +   (use-fixtures :each fixture1 fixture2 ...)
   1.181 +   The fixture1, fixture2 are just functions like the example above.
   1.182 +   They can also be anonymous functions, like this:
   1.183 +   (use-fixtures :each (fn [f] setup... (f) cleanup...))
   1.184 +
   1.185 +   The other kind of fixture, a \"once\" fixture, is only run once,
   1.186 +   around ALL the tests in the namespace.  \"once\" fixtures are useful
   1.187 +   for tasks that only need to be performed once, like establishing
   1.188 +   database connections, or for time-consuming tasks.
   1.189 +
   1.190 +   Attach \"once\" fixtures to the current namespace like this:
   1.191 +   (use-fixtures :once fixture1 fixture2 ...)
   1.192 +
   1.193 +
   1.194 +   SAVING TEST OUTPUT TO A FILE
   1.195 +
   1.196 +   All the test reporting functions write to the var *test-out*.  By
   1.197 +   default, this is the same as *out*, but you can rebind it to any
   1.198 +   PrintWriter.  For example, it could be a file opened with
   1.199 +   clojure.java.io/writer.
   1.200 +
   1.201 +
   1.202 +   EXTENDING TEST-IS (ADVANCED)
   1.203 +
   1.204 +   You can extend the behavior of the \"is\" macro by defining new
   1.205 +   methods for the \"assert-expr\" multimethod.  These methods are
   1.206 +   called during expansion of the \"is\" macro, so they should return
   1.207 +   quoted forms to be evaluated.
   1.208 +
   1.209 +   You can plug in your own test-reporting framework by rebinding
   1.210 +   the \"report\" function: (report event)
   1.211 +
   1.212 +   The 'event' argument is a map.  It will always have a :type key,
   1.213 +   whose value will be a keyword signaling the type of event being
   1.214 +   reported.  Standard events with :type value of :pass, :fail, and
   1.215 +   :error are called when an assertion passes, fails, and throws an
   1.216 +   exception, respectively.  In that case, the event will also have
   1.217 +   the following keys:
   1.218 +
   1.219 +     :expected   The form that was expected to be true
   1.220 +     :actual     A form representing what actually occurred
   1.221 +     :message    The string message given as an argument to 'is'
   1.222 +
   1.223 +   The \"testing\" strings will be a list in \"*testing-contexts*\", and
   1.224 +   the vars being tested will be a list in \"*testing-vars*\".
   1.225 +
   1.226 +   Your \"report\" function should wrap any printing calls in the
   1.227 +   \"with-test-out\" macro, which rebinds *out* to the current value
   1.228 +   of *test-out*.
   1.229 +
   1.230 +   For additional event types, see the examples in the code.
   1.231 +"}
   1.232 +  clojure.test
   1.233 +  (:require [clojure.template :as temp]
   1.234 +            [clojure.stacktrace :as stack]))
   1.235 +
   1.236 +;; Nothing is marked "private" here, so you can rebind things to plug
   1.237 +;; in your own testing or reporting frameworks.
   1.238 +
   1.239 +
   1.240 +;;; USER-MODIFIABLE GLOBALS
   1.241 +
   1.242 +(defonce
   1.243 +  ^{:doc "True by default.  If set to false, no test functions will
   1.244 +   be created by deftest, set-test, or with-test.  Use this to omit
   1.245 +   tests when compiling or loading production code."
   1.246 +    :added "1.1"}
   1.247 +  *load-tests* true)
   1.248 +
   1.249 +(def
   1.250 + ^{:doc "The maximum depth of stack traces to print when an Exception
   1.251 +  is thrown during a test.  Defaults to nil, which means print the 
   1.252 +  complete stack trace."
   1.253 +   :added "1.1"}
   1.254 + *stack-trace-depth* nil)
   1.255 +
   1.256 +
   1.257 +;;; GLOBALS USED BY THE REPORTING FUNCTIONS
   1.258 +
   1.259 +(def *report-counters* nil)	  ; bound to a ref of a map in test-ns
   1.260 +
   1.261 +(def *initial-report-counters*  ; used to initialize *report-counters*
   1.262 +     {:test 0, :pass 0, :fail 0, :error 0})
   1.263 +
   1.264 +(def *testing-vars* (list))  ; bound to hierarchy of vars being tested
   1.265 +
   1.266 +(def *testing-contexts* (list)) ; bound to hierarchy of "testing" strings
   1.267 +
   1.268 +(def *test-out* *out*)         ; PrintWriter for test reporting output
   1.269 +
   1.270 +(defmacro with-test-out
   1.271 +  "Runs body with *out* bound to the value of *test-out*."
   1.272 +  {:added "1.1"}
   1.273 +  [& body]
   1.274 +  `(binding [*out* *test-out*]
   1.275 +     ~@body))
   1.276 +
   1.277 +;;; UTILITIES FOR REPORTING FUNCTIONS
   1.278 +
   1.279 +(defn file-position
   1.280 +  "Returns a vector [filename line-number] for the nth call up the
   1.281 +  stack.
   1.282 +
   1.283 +  Deprecated in 1.2: The information needed for test reporting is
   1.284 +  now on :file and :line keys in the result map."
   1.285 +  {:added "1.1"
   1.286 +   :deprecated "1.2"}
   1.287 +  [n]
   1.288 +  (let [^StackTraceElement s (nth (.getStackTrace (new java.lang.Throwable)) n)]
   1.289 +    [(.getFileName s) (.getLineNumber s)]))
   1.290 +
   1.291 +(defn testing-vars-str
   1.292 +  "Returns a string representation of the current test.  Renders names
   1.293 +  in *testing-vars* as a list, then the source file and line of
   1.294 +  current assertion."
   1.295 +  {:added "1.1"}
   1.296 +  [m]
   1.297 +  (let [{:keys [file line]} m]
   1.298 +    (str
   1.299 +     ;; Uncomment to include namespace in failure report:
   1.300 +     ;;(ns-name (:ns (meta (first *testing-vars*)))) "/ "
   1.301 +     (reverse (map #(:name (meta %)) *testing-vars*))
   1.302 +     " (" file ":" line ")")))
   1.303 +
   1.304 +(defn testing-contexts-str
   1.305 +  "Returns a string representation of the current test context. Joins
   1.306 +  strings in *testing-contexts* with spaces."
   1.307 +  {:added "1.1"}
   1.308 +  []
   1.309 +  (apply str (interpose " " (reverse *testing-contexts*))))
   1.310 +
   1.311 +(defn inc-report-counter
   1.312 +  "Increments the named counter in *report-counters*, a ref to a map.
   1.313 +  Does nothing if *report-counters* is nil."
   1.314 +  {:added "1.1"}
   1.315 +  [name]
   1.316 +  (when *report-counters*
   1.317 +    (dosync (commute *report-counters* assoc name
   1.318 +                     (inc (or (*report-counters* name) 0))))))
   1.319 +
   1.320 +;;; TEST RESULT REPORTING
   1.321 +
   1.322 +(defmulti
   1.323 +  ^{:doc "Generic reporting function, may be overridden to plug in
   1.324 +   different report formats (e.g., TAP, JUnit).  Assertions such as
   1.325 +   'is' call 'report' to indicate results.  The argument given to
   1.326 +   'report' will be a map with a :type key.  See the documentation at
   1.327 +   the top of test_is.clj for more information on the types of
   1.328 +   arguments for 'report'."
   1.329 +     :dynamic true
   1.330 +     :added "1.1"}
   1.331 +  report :type)
   1.332 +
   1.333 +(defn- file-and-line 
   1.334 +  [exception depth]
   1.335 +  (let [^StackTraceElement s (nth (.getStackTrace exception) depth)]
   1.336 +    {:file (.getFileName s) :line (.getLineNumber s)}))
   1.337 +
   1.338 +(defn do-report
   1.339 +  "Add file and line information to a test result and call report.
   1.340 +   If you are writing a custom assert-expr method, call this function
   1.341 +   to pass test results to report."
   1.342 +  {:added "1.2"}
   1.343 +  [m]
   1.344 +  (report
   1.345 +   (case
   1.346 +    (:type m)
   1.347 +    :fail (merge (file-and-line (new java.lang.Throwable) 1) m)
   1.348 +    :error (merge (file-and-line (:actual m) 0) m) 
   1.349 +    m)))
   1.350 +
   1.351 +(defmethod report :default [m]
   1.352 +  (with-test-out (prn m)))
   1.353 +
   1.354 +(defmethod report :pass [m]
   1.355 +  (with-test-out (inc-report-counter :pass)))
   1.356 +
   1.357 +(defmethod report :fail [m]
   1.358 +  (with-test-out
   1.359 +    (inc-report-counter :fail)
   1.360 +    (println "\nFAIL in" (testing-vars-str m))
   1.361 +    (when (seq *testing-contexts*) (println (testing-contexts-str)))
   1.362 +    (when-let [message (:message m)] (println message))
   1.363 +    (println "expected:" (pr-str (:expected m)))
   1.364 +    (println "  actual:" (pr-str (:actual m)))))
   1.365 +
   1.366 +(defmethod report :error [m]
   1.367 +  (with-test-out
   1.368 +   (inc-report-counter :error)
   1.369 +   (println "\nERROR in" (testing-vars-str m))
   1.370 +   (when (seq *testing-contexts*) (println (testing-contexts-str)))
   1.371 +   (when-let [message (:message m)] (println message))
   1.372 +   (println "expected:" (pr-str (:expected m)))
   1.373 +   (print "  actual: ")
   1.374 +   (let [actual (:actual m)]
   1.375 +     (if (instance? Throwable actual)
   1.376 +       (stack/print-cause-trace actual *stack-trace-depth*)
   1.377 +       (prn actual)))))
   1.378 +
   1.379 +(defmethod report :summary [m]
   1.380 +  (with-test-out
   1.381 +   (println "\nRan" (:test m) "tests containing"
   1.382 +            (+ (:pass m) (:fail m) (:error m)) "assertions.")
   1.383 +   (println (:fail m) "failures," (:error m) "errors.")))
   1.384 +
   1.385 +(defmethod report :begin-test-ns [m]
   1.386 +  (with-test-out
   1.387 +   (println "\nTesting" (ns-name (:ns m)))))
   1.388 +
   1.389 +;; Ignore these message types:
   1.390 +(defmethod report :end-test-ns [m])
   1.391 +(defmethod report :begin-test-var [m])
   1.392 +(defmethod report :end-test-var [m])
   1.393 +
   1.394 +
   1.395 +
   1.396 +;;; UTILITIES FOR ASSERTIONS
   1.397 +
   1.398 +(defn get-possibly-unbound-var
   1.399 +  "Like var-get but returns nil if the var is unbound."
   1.400 +  {:added "1.1"}
   1.401 +  [v]
   1.402 +  (try (var-get v)
   1.403 +       (catch IllegalStateException e
   1.404 +         nil)))
   1.405 +
   1.406 +(defn function?
   1.407 +  "Returns true if argument is a function or a symbol that resolves to
   1.408 +  a function (not a macro)."
   1.409 +  {:added "1.1"}
   1.410 +  [x]
   1.411 +  (if (symbol? x)
   1.412 +    (when-let [v (resolve x)]
   1.413 +      (when-let [value (get-possibly-unbound-var v)]
   1.414 +        (and (fn? value)
   1.415 +             (not (:macro (meta v))))))
   1.416 +    (fn? x)))
   1.417 +
   1.418 +(defn assert-predicate
   1.419 +  "Returns generic assertion code for any functional predicate.  The
   1.420 +  'expected' argument to 'report' will contains the original form, the
   1.421 +  'actual' argument will contain the form with all its sub-forms
   1.422 +  evaluated.  If the predicate returns false, the 'actual' form will
   1.423 +  be wrapped in (not...)."
   1.424 +  {:added "1.1"}
   1.425 +  [msg form]
   1.426 +  (let [args (rest form)
   1.427 +        pred (first form)]
   1.428 +    `(let [values# (list ~@args)
   1.429 +           result# (apply ~pred values#)]
   1.430 +       (if result#
   1.431 +         (do-report {:type :pass, :message ~msg,
   1.432 +                  :expected '~form, :actual (cons ~pred values#)})
   1.433 +         (do-report {:type :fail, :message ~msg,
   1.434 +                  :expected '~form, :actual (list '~'not (cons '~pred values#))}))
   1.435 +       result#)))
   1.436 +
   1.437 +(defn assert-any
   1.438 +  "Returns generic assertion code for any test, including macros, Java
   1.439 +  method calls, or isolated symbols."
   1.440 +  {:added "1.1"}
   1.441 +  [msg form]
   1.442 +  `(let [value# ~form]
   1.443 +     (if value#
   1.444 +       (do-report {:type :pass, :message ~msg,
   1.445 +                :expected '~form, :actual value#})
   1.446 +       (do-report {:type :fail, :message ~msg,
   1.447 +                :expected '~form, :actual value#}))
   1.448 +     value#))
   1.449 +
   1.450 +
   1.451 +
   1.452 +;;; ASSERTION METHODS
   1.453 +
   1.454 +;; You don't call these, but you can add methods to extend the 'is'
   1.455 +;; macro.  These define different kinds of tests, based on the first
   1.456 +;; symbol in the test expression.
   1.457 +
   1.458 +(defmulti assert-expr 
   1.459 +  (fn [msg form]
   1.460 +    (cond
   1.461 +      (nil? form) :always-fail
   1.462 +      (seq? form) (first form)
   1.463 +      :else :default)))
   1.464 +
   1.465 +(defmethod assert-expr :always-fail [msg form]
   1.466 +  ;; nil test: always fail
   1.467 +  `(do-report {:type :fail, :message ~msg}))
   1.468 +
   1.469 +(defmethod assert-expr :default [msg form]
   1.470 +  (if (and (sequential? form) (function? (first form)))
   1.471 +    (assert-predicate msg form)
   1.472 +    (assert-any msg form)))
   1.473 +
   1.474 +(defmethod assert-expr 'instance? [msg form]
   1.475 +  ;; Test if x is an instance of y.
   1.476 +  `(let [klass# ~(nth form 1)
   1.477 +         object# ~(nth form 2)]
   1.478 +     (let [result# (instance? klass# object#)]
   1.479 +       (if result#
   1.480 +         (do-report {:type :pass, :message ~msg,
   1.481 +                  :expected '~form, :actual (class object#)})
   1.482 +         (do-report {:type :fail, :message ~msg,
   1.483 +                  :expected '~form, :actual (class object#)}))
   1.484 +       result#)))
   1.485 +
   1.486 +(defmethod assert-expr 'thrown? [msg form]
   1.487 +  ;; (is (thrown? c expr))
   1.488 +  ;; Asserts that evaluating expr throws an exception of class c.
   1.489 +  ;; Returns the exception thrown.
   1.490 +  (let [klass (second form)
   1.491 +        body (nthnext form 2)]
   1.492 +    `(try ~@body
   1.493 +          (do-report {:type :fail, :message ~msg,
   1.494 +                   :expected '~form, :actual nil})
   1.495 +          (catch ~klass e#
   1.496 +            (do-report {:type :pass, :message ~msg,
   1.497 +                     :expected '~form, :actual e#})
   1.498 +            e#))))
   1.499 +
   1.500 +(defmethod assert-expr 'thrown-with-msg? [msg form]
   1.501 +  ;; (is (thrown-with-msg? c re expr))
   1.502 +  ;; Asserts that evaluating expr throws an exception of class c.
   1.503 +  ;; Also asserts that the message string of the exception matches
   1.504 +  ;; (with re-find) the regular expression re.
   1.505 +  (let [klass (nth form 1)
   1.506 +        re (nth form 2)
   1.507 +        body (nthnext form 3)]
   1.508 +    `(try ~@body
   1.509 +          (do-report {:type :fail, :message ~msg, :expected '~form, :actual nil})
   1.510 +          (catch ~klass e#
   1.511 +            (let [m# (.getMessage e#)]
   1.512 +              (if (re-find ~re m#)
   1.513 +                (do-report {:type :pass, :message ~msg,
   1.514 +                         :expected '~form, :actual e#})
   1.515 +                (do-report {:type :fail, :message ~msg,
   1.516 +                         :expected '~form, :actual e#})))
   1.517 +            e#))))
   1.518 +
   1.519 +
   1.520 +(defmacro try-expr
   1.521 +  "Used by the 'is' macro to catch unexpected exceptions.
   1.522 +  You don't call this."
   1.523 +  {:added "1.1"}
   1.524 +  [msg form]
   1.525 +  `(try ~(assert-expr msg form)
   1.526 +        (catch Throwable t#
   1.527 +          (do-report {:type :error, :message ~msg,
   1.528 +                      :expected '~form, :actual t#}))))
   1.529 +
   1.530 +
   1.531 +
   1.532 +;;; ASSERTION MACROS
   1.533 +
   1.534 +;; You use these in your tests.
   1.535 +
   1.536 +(defmacro is
   1.537 +  "Generic assertion macro.  'form' is any predicate test.
   1.538 +  'msg' is an optional message to attach to the assertion.
   1.539 +  
   1.540 +  Example: (is (= 4 (+ 2 2)) \"Two plus two should be 4\")
   1.541 +
   1.542 +  Special forms:
   1.543 +
   1.544 +  (is (thrown? c body)) checks that an instance of c is thrown from
   1.545 +  body, fails if not; then returns the thing thrown.
   1.546 +
   1.547 +  (is (thrown-with-msg? c re body)) checks that an instance of c is
   1.548 +  thrown AND that the message on the exception matches (with
   1.549 +  re-find) the regular expression re."
   1.550 +  {:added "1.1"} 
   1.551 +  ([form] `(is ~form nil))
   1.552 +  ([form msg] `(try-expr ~msg ~form)))
   1.553 +
   1.554 +(defmacro are
   1.555 +  "Checks multiple assertions with a template expression.
   1.556 +  See clojure.template/do-template for an explanation of
   1.557 +  templates.
   1.558 +
   1.559 +  Example: (are [x y] (= x y)  
   1.560 +                2 (+ 1 1)
   1.561 +                4 (* 2 2))
   1.562 +  Expands to: 
   1.563 +           (do (is (= 2 (+ 1 1)))
   1.564 +               (is (= 4 (* 2 2))))
   1.565 +
   1.566 +  Note: This breaks some reporting features, such as line numbers."
   1.567 +  {:added "1.1"}
   1.568 +  [argv expr & args]
   1.569 +  `(temp/do-template ~argv (is ~expr) ~@args))
   1.570 +
   1.571 +(defmacro testing
   1.572 +  "Adds a new string to the list of testing contexts.  May be nested,
   1.573 +  but must occur inside a test function (deftest)."
   1.574 +  {:added "1.1"}
   1.575 +  [string & body]
   1.576 +  `(binding [*testing-contexts* (conj *testing-contexts* ~string)]
   1.577 +     ~@body))
   1.578 +
   1.579 +
   1.580 +
   1.581 +;;; DEFINING TESTS
   1.582 +
   1.583 +(defmacro with-test
   1.584 +  "Takes any definition form (that returns a Var) as the first argument.
   1.585 +  Remaining body goes in the :test metadata function for that Var.
   1.586 +
   1.587 +  When *load-tests* is false, only evaluates the definition, ignoring
   1.588 +  the tests."
   1.589 +  {:added "1.1"}
   1.590 +  [definition & body]
   1.591 +  (if *load-tests*
   1.592 +    `(doto ~definition (alter-meta! assoc :test (fn [] ~@body)))
   1.593 +    definition))
   1.594 +
   1.595 +
   1.596 +(defmacro deftest
   1.597 +  "Defines a test function with no arguments.  Test functions may call
   1.598 +  other tests, so tests may be composed.  If you compose tests, you
   1.599 +  should also define a function named test-ns-hook; run-tests will
   1.600 +  call test-ns-hook instead of testing all vars.
   1.601 +
   1.602 +  Note: Actually, the test body goes in the :test metadata on the var,
   1.603 +  and the real function (the value of the var) calls test-var on
   1.604 +  itself.
   1.605 +
   1.606 +  When *load-tests* is false, deftest is ignored."
   1.607 +  {:added "1.1"}
   1.608 +  [name & body]
   1.609 +  (when *load-tests*
   1.610 +    `(def ~(vary-meta name assoc :test `(fn [] ~@body))
   1.611 +          (fn [] (test-var (var ~name))))))
   1.612 +
   1.613 +(defmacro deftest-
   1.614 +  "Like deftest but creates a private var."
   1.615 +  {:added "1.1"}
   1.616 +  [name & body]
   1.617 +  (when *load-tests*
   1.618 +    `(def ~(vary-meta name assoc :test `(fn [] ~@body) :private true)
   1.619 +          (fn [] (test-var (var ~name))))))
   1.620 +
   1.621 +
   1.622 +(defmacro set-test
   1.623 +  "Experimental.
   1.624 +  Sets :test metadata of the named var to a fn with the given body.
   1.625 +  The var must already exist.  Does not modify the value of the var.
   1.626 +
   1.627 +  When *load-tests* is false, set-test is ignored."
   1.628 +  {:added "1.1"}
   1.629 +  [name & body]
   1.630 +  (when *load-tests*
   1.631 +    `(alter-meta! (var ~name) assoc :test (fn [] ~@body))))
   1.632 +
   1.633 +
   1.634 +
   1.635 +;;; DEFINING FIXTURES
   1.636 +
   1.637 +(defn- add-ns-meta
   1.638 +  "Adds elements in coll to the current namespace metadata as the
   1.639 +  value of key."
   1.640 +  {:added "1.1"}
   1.641 +  [key coll]
   1.642 +  (alter-meta! *ns* assoc key coll))
   1.643 +
   1.644 +(defmulti use-fixtures
   1.645 +  "Wrap test runs in a fixture function to perform setup and
   1.646 +  teardown. Using a fixture-type of :each wraps every test
   1.647 +  individually, while:once wraps the whole run in a single function."
   1.648 +  {:added "1.1"}
   1.649 +  (fn [fixture-type & args] fixture-type))
   1.650 +
   1.651 +(defmethod use-fixtures :each [fixture-type & args]
   1.652 +  (add-ns-meta ::each-fixtures args))
   1.653 +
   1.654 +(defmethod use-fixtures :once [fixture-type & args]
   1.655 +  (add-ns-meta ::once-fixtures args))
   1.656 +
   1.657 +(defn- default-fixture
   1.658 +  "The default, empty, fixture function.  Just calls its argument."
   1.659 +  {:added "1.1"}
   1.660 +  [f]
   1.661 +  (f))
   1.662 +
   1.663 +(defn compose-fixtures
   1.664 +  "Composes two fixture functions, creating a new fixture function
   1.665 +  that combines their behavior."
   1.666 +  {:added "1.1"}
   1.667 +  [f1 f2]
   1.668 +  (fn [g] (f1 (fn [] (f2 g)))))
   1.669 +
   1.670 +(defn join-fixtures
   1.671 +  "Composes a collection of fixtures, in order.  Always returns a valid
   1.672 +  fixture function, even if the collection is empty."
   1.673 +  {:added "1.1"}
   1.674 +  [fixtures]
   1.675 +  (reduce compose-fixtures default-fixture fixtures))
   1.676 +
   1.677 +
   1.678 +
   1.679 +
   1.680 +;;; RUNNING TESTS: LOW-LEVEL FUNCTIONS
   1.681 +
   1.682 +(defn test-var
   1.683 +  "If v has a function in its :test metadata, calls that function,
   1.684 +  with *testing-vars* bound to (conj *testing-vars* v)."
   1.685 +  {:dynamic true, :added "1.1"}
   1.686 +  [v]
   1.687 +  (when-let [t (:test (meta v))]
   1.688 +    (binding [*testing-vars* (conj *testing-vars* v)]
   1.689 +      (do-report {:type :begin-test-var, :var v})
   1.690 +      (inc-report-counter :test)
   1.691 +      (try (t)
   1.692 +           (catch Throwable e
   1.693 +             (do-report {:type :error, :message "Uncaught exception, not in assertion."
   1.694 +                      :expected nil, :actual e})))
   1.695 +      (do-report {:type :end-test-var, :var v}))))
   1.696 +
   1.697 +(defn test-all-vars
   1.698 +  "Calls test-var on every var interned in the namespace, with fixtures."
   1.699 +  {:added "1.1"}
   1.700 +  [ns]
   1.701 +  (let [once-fixture-fn (join-fixtures (::once-fixtures (meta ns)))
   1.702 +        each-fixture-fn (join-fixtures (::each-fixtures (meta ns)))]
   1.703 +    (once-fixture-fn
   1.704 +     (fn []
   1.705 +       (doseq [v (vals (ns-interns ns))]
   1.706 +         (when (:test (meta v))
   1.707 +           (each-fixture-fn (fn [] (test-var v)))))))))
   1.708 +
   1.709 +(defn test-ns
   1.710 +  "If the namespace defines a function named test-ns-hook, calls that.
   1.711 +  Otherwise, calls test-all-vars on the namespace.  'ns' is a
   1.712 +  namespace object or a symbol.
   1.713 +
   1.714 +  Internally binds *report-counters* to a ref initialized to
   1.715 +  *inital-report-counters*.  Returns the final, dereferenced state of
   1.716 +  *report-counters*."
   1.717 +  {:added "1.1"}
   1.718 +  [ns]
   1.719 +  (binding [*report-counters* (ref *initial-report-counters*)]
   1.720 +    (let [ns-obj (the-ns ns)]
   1.721 +      (do-report {:type :begin-test-ns, :ns ns-obj})
   1.722 +      ;; If the namespace has a test-ns-hook function, call that:
   1.723 +      (if-let [v (find-var (symbol (str (ns-name ns-obj)) "test-ns-hook"))]
   1.724 +	((var-get v))
   1.725 +        ;; Otherwise, just test every var in the namespace.
   1.726 +        (test-all-vars ns-obj))
   1.727 +      (do-report {:type :end-test-ns, :ns ns-obj}))
   1.728 +    @*report-counters*))
   1.729 +
   1.730 +
   1.731 +
   1.732 +;;; RUNNING TESTS: HIGH-LEVEL FUNCTIONS
   1.733 +
   1.734 +(defn run-tests
   1.735 +  "Runs all tests in the given namespaces; prints results.
   1.736 +  Defaults to current namespace if none given.  Returns a map
   1.737 +  summarizing test results."
   1.738 +  {:added "1.1"}
   1.739 +  ([] (run-tests *ns*))
   1.740 +  ([& namespaces]
   1.741 +     (let [summary (assoc (apply merge-with + (map test-ns namespaces))
   1.742 +                     :type :summary)]
   1.743 +       (do-report summary)
   1.744 +       summary)))
   1.745 +
   1.746 +(defn run-all-tests
   1.747 +  "Runs all tests in all namespaces; prints results.
   1.748 +  Optional argument is a regular expression; only namespaces with
   1.749 +  names matching the regular expression (with re-matches) will be
   1.750 +  tested."
   1.751 +  {:added "1.1"}
   1.752 +  ([] (apply run-tests (all-ns)))
   1.753 +  ([re] (apply run-tests (filter #(re-matches re (name (ns-name %))) (all-ns)))))
   1.754 +
   1.755 +(defn successful?
   1.756 +  "Returns true if the given test summary indicates all tests
   1.757 +  were successful, false otherwise."
   1.758 +  {:added "1.1"}
   1.759 +  [summary]
   1.760 +  (and (zero? (:fail summary 0))
   1.761 +       (zero? (:error summary 0))))