Customizing reporting - eunmin/Midje GitHub Wiki
You can change the way Midje produces output. Currently, there are only two emitters:
-
midje.emission.plugins.default: The default -
midje.emission.plugins.silence: No output. The same effect as setting the print level to:print-nothing.
You can create your own plugin by writing a namespace that
implements some or all of nine reporting functions. One of
those functions, fail, must handle eight different kinds
of failures. You can replace some or all of the
failure-handling functions.
Once you've written your namespace, you can refer to it in a configuration file with a line like one of these three:
(change-defaults :emitter 'myproj.emitter) ; a namespace in your project
(change-defaults :emitter "resources/emitter.clj") ; a file in your project, relative to the project root
(change-defaults :emitter "/Users/marick/stuff/emitter.clj") ; a file with its absolute pathnameNote: This interface is experimental. The purpose of this documentation is to tempt you to collaborate with me on writing a plugin, thus improving the interface. Mail me.
Here is an example of an emitter that overrides the finishing-top-level-fact
function to print something:
(ns ^{:doc "Adding an emitter that brags about fact results"}
example.pass-emitter
(:require [midje.emission.plugins.util :as util]
[midje.data.fact :as fact]
[midje.emission.plugins.default :as default]
[midje.emission.state :as state]))
(defn finishing-top-level-fact [fact]
(util/emit-one-line (format "Dude! `%s` at line %d of %s totally finished!"
(fact/name fact)
(fact/line fact)
(fact/file fact)))
;; Plugins are not responsible for keeping track of successes and
;; failures. That happens independently, and you gain access to the
;; counts through the `midje.emission.state` namespace.
(util/emit-one-line (format "We're up to %d passing checks!"
(state/output-counters:midje-passes))))
;; The emission map is how you hook your functions into the
;; system. It also makes it convenient to "inherit" from an
;; existing map.
(def emission-map (assoc default/emission-map
:finishing-top-level-fact finishing-top-level-fact))
;; Here's where the installation happens.
(state/install-emission-map emission-map)Plugins are not responsible for obeying the [[print level|print levels]]. Plugin functions won't be called if the print level is too low. The following shows the lowest print level at which the function is called.
-
:pass
:print-summary... is called when a check succeeds. It takes no arguments.
-
:fail
:print-summary... takes a map of information, which differs depending on the type of failure. See below.
-
:future-fact
:print-summary... takes a fact's or
=future=>check's description (a string) and a position (a filename / line number pair). Note that the description may be nil.Even if the print level is high enough, the
:visible-futureconfiguration setting might prevent the function from being called.
-
:starting-to-check-top-level-fact
:print-facts... is given a fact as its only argument. Facts are functions adorned with metadata.
Tabular facts count as top-level facts. They have N facts nested within them, one for each table row.
-
:finishing-top-level-fact
:print-facts... is called when all the checks in the fact have been completed. It is given the fact as its argument.
-
:starting-to-check-fact
:print-facts... is given a fact as its argument. It is called for all facts, not just a top-level fact.
For top-level-facts,
:starting-to-check-top-level-factis called first, then:starting-to-check-fact.
-
:finishing-fact
:print-facts... is given a fact as an argument. For a top-level fact, it is called first, and then
:finishing-top-level-fact.
-
:possible-new-namespace
:print-namespaces... is called for each top-level fact (before
:finishing-top-level-fact). Its argument is the namespace in which the fact was defined.For the sake of better error messages, it is also called just before Midje starts loading a namespace (as with the repl tools function
load-factsor withlein midje).
-
:starting-fact-stream (always called)
A fact stream is a series of zero or more facts to be checked.
% lein midjeand the repl tool functionsload-facts,check-facts, andrecheck-factstart fact streams. That's when this function is called. It takes no arguments.At the beginning of a fact stream, the pass/fail counters are reset to zero. This happens after
:forget-everything, so that you can capture the values if you desperately want to.
-
:finishing-fact-stream
:print-normally... is called when a fact stream has been checked.
When a fact stream is checked by
lein midjeor(load-facts), clojure.testdeftestsare also checked. In that case, the results are passed in as a single argument. The results are an ordinary clojure.test results map (:pass,:fail,:error, and:test), plus an additional key,:lines, that captures the test output.In other cases, no argument is given.
fail is passed different maps, depending on the details of the failure. The type of failure is always the :type key in the map.
-
:actual-result-did-not-match-expected-value
From, for example,
(fact (+ 1 2) => (+ 1 5))-
:expected-result(5in this case) -
:actual(3in this case)
-
-
:actual-result-should-not-have-matched-expected-value
From, for example,
(fact (+ 1 2) =not=> (+ 1 2)- :expected-result (
3in this case) - :actual (
3in this case)
- :expected-result (
-
:actual-result-did-not-match-checker
From, for example,
(+ 1 2) => (roughly 10000)-
:expected-result-form((roughly 10000)in this case) -
:actual(3in this case) -
:intermediate-results(a sequence of Clojure forms from chatty checkers -
:notes(a sequence of strings)
-
-
:actual-result-should-not-have-matched-checker
From, for example,
(+ 1 2) =not=> (roughly 3)-
:expected-result-form((roughly 3)in this case) -
:actual(3in this case)
-
-
:some-prerequisites-were-called-the-wrong-number-of-times
-
:expected-countA number or sequence. :actual-count-
:expected-result-form
-
-
:prerequisite-was-called-with-unexpected-arguments
TBD: It's complicated.
-
:parse-error
-
:notesText about the error.
-
-
:exception-during-parsing
-
:macro-formThe form being translated when the exception happened. -
:stacktraceA stacktrace, filtered down to Midje functions. (Still largely useless)
-