rlm@10
|
1 ; Copyright (c) Rich Hickey. All rights reserved.
|
rlm@10
|
2 ; The use and distribution terms for this software are covered by the
|
rlm@10
|
3 ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
|
rlm@10
|
4 ; which can be found in the file epl-v10.html at the root of this distribution.
|
rlm@10
|
5 ; By using this software in any fashion, you are agreeing to be bound by
|
rlm@10
|
6 ; the terms of this license.
|
rlm@10
|
7 ; You must not remove this notice, or any other, from this software.
|
rlm@10
|
8
|
rlm@10
|
9 ;;; test_is/tap.clj: Extension to test for TAP output
|
rlm@10
|
10
|
rlm@10
|
11 ;; by Stuart Sierra
|
rlm@10
|
12 ;; March 31, 2009
|
rlm@10
|
13
|
rlm@10
|
14 ;; Inspired by ClojureCheck by Meikel Brandmeyer:
|
rlm@10
|
15 ;; http://kotka.de/projects/clojure/clojurecheck.html
|
rlm@10
|
16
|
rlm@10
|
17
|
rlm@10
|
18 ;; DOCUMENTATION
|
rlm@10
|
19 ;;
|
rlm@10
|
20
|
rlm@10
|
21
|
rlm@10
|
22
|
rlm@10
|
23 (ns ^{:doc "clojure.test extensions for the Test Anything Protocol (TAP)
|
rlm@10
|
24
|
rlm@10
|
25 TAP is a simple text-based syntax for reporting test results. TAP
|
rlm@10
|
26 was originally develped for Perl, and now has implementations in
|
rlm@10
|
27 several languages. For more information on TAP, see
|
rlm@10
|
28 http://testanything.org/ and
|
rlm@10
|
29 http://search.cpan.org/~petdance/TAP-1.0.0/TAP.pm
|
rlm@10
|
30
|
rlm@10
|
31 To use this library, wrap any calls to
|
rlm@10
|
32 clojure.test/run-tests in the with-tap-output macro,
|
rlm@10
|
33 like this:
|
rlm@10
|
34
|
rlm@10
|
35 (use 'clojure.test)
|
rlm@10
|
36 (use 'clojure.test.tap)
|
rlm@10
|
37
|
rlm@10
|
38 (with-tap-output
|
rlm@10
|
39 (run-tests 'my.cool.library))"
|
rlm@10
|
40 :author "Stuart Sierra"}
|
rlm@10
|
41 clojure.test.tap
|
rlm@10
|
42 (:require [clojure.test :as t]
|
rlm@10
|
43 [clojure.stacktrace :as stack]))
|
rlm@10
|
44
|
rlm@10
|
45 (defn print-tap-plan
|
rlm@10
|
46 "Prints a TAP plan line like '1..n'. n is the number of tests"
|
rlm@10
|
47 {:added "1.1"}
|
rlm@10
|
48 [n]
|
rlm@10
|
49 (println (str "1.." n)))
|
rlm@10
|
50
|
rlm@10
|
51 (defn print-tap-diagnostic
|
rlm@10
|
52 "Prints a TAP diagnostic line. data is a (possibly multi-line)
|
rlm@10
|
53 string."
|
rlm@10
|
54 {:added "1.1"}
|
rlm@10
|
55 [data]
|
rlm@10
|
56 (doseq [line (.split ^String data "\n")]
|
rlm@10
|
57 (println "#" line)))
|
rlm@10
|
58
|
rlm@10
|
59 (defn print-tap-pass
|
rlm@10
|
60 "Prints a TAP 'ok' line. msg is a string, with no line breaks"
|
rlm@10
|
61 {:added "1.1"}
|
rlm@10
|
62 [msg]
|
rlm@10
|
63 (println "ok" msg))
|
rlm@10
|
64
|
rlm@10
|
65 (defn print-tap-fail
|
rlm@10
|
66 "Prints a TAP 'not ok' line. msg is a string, with no line breaks"
|
rlm@10
|
67 {:added "1.1"}
|
rlm@10
|
68 [msg]
|
rlm@10
|
69 (println "not ok" msg))
|
rlm@10
|
70
|
rlm@10
|
71 ;; This multimethod will override test/report
|
rlm@10
|
72 (defmulti tap-report (fn [data] (:type data)))
|
rlm@10
|
73
|
rlm@10
|
74 (defmethod tap-report :default [data]
|
rlm@10
|
75 (t/with-test-out
|
rlm@10
|
76 (print-tap-diagnostic (pr-str data))))
|
rlm@10
|
77
|
rlm@10
|
78 (defmethod tap-report :pass [data]
|
rlm@10
|
79 (t/with-test-out
|
rlm@10
|
80 (t/inc-report-counter :pass)
|
rlm@10
|
81 (print-tap-pass (t/testing-vars-str))
|
rlm@10
|
82 (when (seq t/*testing-contexts*)
|
rlm@10
|
83 (print-tap-diagnostic (t/testing-contexts-str)))
|
rlm@10
|
84 (when (:message data)
|
rlm@10
|
85 (print-tap-diagnostic (:message data)))
|
rlm@10
|
86 (print-tap-diagnostic (str "expected:" (pr-str (:expected data))))
|
rlm@10
|
87 (print-tap-diagnostic (str " actual:" (pr-str (:actual data))))))
|
rlm@10
|
88
|
rlm@10
|
89 (defmethod tap-report :error [data]
|
rlm@10
|
90 (t/with-test-out
|
rlm@10
|
91 (t/inc-report-counter :error)
|
rlm@10
|
92 (print-tap-fail (t/testing-vars-str))
|
rlm@10
|
93 (when (seq t/*testing-contexts*)
|
rlm@10
|
94 (print-tap-diagnostic (t/testing-contexts-str)))
|
rlm@10
|
95 (when (:message data)
|
rlm@10
|
96 (print-tap-diagnostic (:message data)))
|
rlm@10
|
97 (print-tap-diagnostic "expected:" (pr-str (:expected data)))
|
rlm@10
|
98 (print-tap-diagnostic " actual: ")
|
rlm@10
|
99 (print-tap-diagnostic
|
rlm@10
|
100 (with-out-str
|
rlm@10
|
101 (if (instance? Throwable (:actual data))
|
rlm@10
|
102 (stack/print-cause-trace (:actual data) t/*stack-trace-depth*)
|
rlm@10
|
103 (prn (:actual data)))))))
|
rlm@10
|
104
|
rlm@10
|
105 (defmethod tap-report :summary [data]
|
rlm@10
|
106 (t/with-test-out
|
rlm@10
|
107 (print-tap-plan (+ (:pass data) (:fail data) (:error data)))))
|
rlm@10
|
108
|
rlm@10
|
109
|
rlm@10
|
110 (defmacro with-tap-output
|
rlm@10
|
111 "Execute body with modified test reporting functions that produce
|
rlm@10
|
112 TAP output"
|
rlm@10
|
113 {:added "1.1"}
|
rlm@10
|
114 [& body]
|
rlm@10
|
115 `(binding [t/report tap-report]
|
rlm@10
|
116 ~@body))
|