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