Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Junit formatter for Midje.

  • Loading branch information...
commit db9cea77f3c9e3719014c24f4ebfb192ce8d6bba 1 parent b5cc711
@josephwilk josephwilk authored
View
88 src/midje/emission/plugins/junit.clj
@@ -0,0 +1,88 @@
+(ns ^{:doc "JUnit formatter for Midje output"}
+ midje.emission.plugins.junit
+ (:use
+ [midje.emission.util])
+ (:require [midje.data.fact :as fact]
+ [midje.emission.state :as state]
+ [midje.emission.plugins.silence :as silence]
+ [midje.emission.plugins.default-failure-lines :as lines]
+ [clojure.string :as str]
+ [clojure.xml :as xml :only [emit-element]]))
+
+(def report-file "report.xml")
+
+(defn log-fn []
+ (fn [text] (spit report-file text :append true)))
+
+(defn- log [string]
+ (let [log-fn (log-fn)]
+ (log-fn string)))
+
+(defn- reset-log []
+ (spit report-file ""))
+
+(defn def-fact-cache []
+ (defonce last-fact (atom {})))
+
+(defn- fact-name [fact]
+ (or (fact/name fact)
+ (fact/description fact)
+ (str (fact/file fact) ":" (fact/line fact))))
+
+(defn pass []
+ (log
+ (with-out-str
+ (xml/emit-element @last-fact))))
+
+(defn- testcase-with-failure [failure-map]
+ (let [testcase @last-fact
+ failure-content (str "<![CDATA[" (apply str (lines/summarize failure-map)) "]]>")
+ fail-type (:type failure-map)
+ fail-element {:tag :failure
+ :content [failure-content]
+ :attrs {:type fail-type}}
+ testcase-with-failure (assoc testcase :content [fail-element])]
+ testcase-with-failure))
+
+(defn escape [s]
+ (if s
+ (str/escape s {\' "\\'"})
+ ""))
+
+(defn fail [failure-map]
+ (let [testcase (testcase-with-failure failure-map)]
+ ; FIXME: currently there is a bug in midje that prevents us emitting this map as xml
+ ;(xml/emit-element testcase)
+
+ (log (str "<testcase classname='" (-> testcase :attrs :classname) "' name='" (-> testcase :attrs :name) "'>\n"))
+ (log (str "<failure type='" (-> testcase :content first :attrs :type) "'>"))
+ (log (-> testcase :content first :content :first))
+ (log "</failure>\n")
+ (log "</testcase>")))
+
+(defn starting-to-check-fact [fact]
+ (let [fact-namespace (str (fact/namespace fact))
+ fact-name (fact-name fact)]
+ (reset! last-fact {:tag :testcase
+ :attrs {:classname (escape fact-namespace) :name (escape fact-name)}})))
+
+(defn starting-fact-stream []
+ (def-fact-cache)
+ (reset-log)
+ (log "<testsuite>"))
+
+(defn finishing-fact-stream [midje-counters clojure-test-map]
+ (log "</testsuite>"))
+
+(defn make-map [& keys]
+ (zipmap keys
+ (map #(ns-resolve *ns* (symbol (name %))) keys)))
+
+(def emission-map (merge silence/emission-map
+ (make-map :fail
+ :pass
+ :starting-fact-stream
+ :finishing-fact-stream
+ :starting-to-check-fact)))
+
+(state/install-emission-map emission-map)
View
53 test/midje/emission/plugins/t_junit.clj
@@ -0,0 +1,53 @@
+(ns midje.emission.plugins.t-junit
+ (:use [midje sweet util test-util])
+ (:require [midje.emission.plugins.junit :as plugin]
+ [midje.config :as config]
+ [midje.emission.plugins.default-failure-lines :as failure-lines]))
+
+(defn innocuously [key & args]
+ (config/with-augmented-config {:emitter 'midje.emission.plugins.junit
+ :print-level :print-facts}
+ (captured-output (apply (key plugin/emission-map) args))))
+
+(def test-fact
+ (with-meta (fn[]) {:midje/name "named" :midje/description "desc" :midje/namespace "blah"}))
+
+(def test-failure-map
+ {:type :some-prerequisites-were-called-the-wrong-number-of-times,
+ :namespace "midje.emission.plugins.t-junit"})
+
+(fact "starting a fact stream opens a <testsuite>"
+ (innocuously :starting-fact-stream) => (contains "<testsuite>")
+ (provided
+ (plugin/log-fn) => #(println %)))
+
+(fact "closing a fact stream closes </testsuite>"
+ (plugin/def-fact-cache)
+
+ (innocuously :finishing-fact-stream {} {}) => (contains "</testsuite>")
+ (provided
+ (plugin/log-fn) => #(println %)))
+
+(fact "pass produces a <testcase> tag"
+ (plugin/def-fact-cache)
+ (plugin/starting-to-check-fact test-fact)
+
+ (innocuously :pass) => (contains "<testcase classname='blah' name='named'/>")
+ (provided
+ (plugin/log-fn) => #(println %)))
+
+(fact "failure produces a <testcase> tag"
+ (plugin/def-fact-cache)
+ (plugin/starting-to-check-fact test-fact)
+
+ (innocuously :fail test-failure-map) => (contains "<testcase classname='blah' name='named'>")
+ (provided
+ (plugin/log-fn) => #(println %)))
+
+(fact "failure also produces a <failure> tag"
+ (plugin/def-fact-cache)
+ (plugin/starting-to-check-fact test-fact)
+
+ (innocuously :fail test-failure-map) => (contains "<failure type=':some-prerequisites-were-called-the-wrong-number-of-times'>")
+ (provided
+ (plugin/log-fn) => #(println %)))
Please sign in to comment.
Something went wrong with that request. Please try again.