-
Notifications
You must be signed in to change notification settings - Fork 129
Customizing reporting
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 pathname
Note: 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-future
configuration 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-fact
is 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-facts
or withlein midje
).
-
:starting-fact-stream (always called)
A fact stream is a series of zero or more facts to be checked.
% lein midje
and the repl tool functionsload-facts
,check-facts
, andrecheck-fact
start 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 midje
or(load-facts)
, clojure.testdeftests
are 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
(5
in this case) -
:actual
(3
in this case)
-
-
:actual-result-should-not-have-matched-expected-value
From, for example,
(fact (+ 1 2) =not=> (+ 1 2)
- :expected-result (
3
in this case) - :actual (
3
in 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
(3
in 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
(3
in this case)
-
-
:some-prerequisites-were-called-the-wrong-number-of-times
-
:expected-count
A number or sequence. :actual-count
-
:expected-result-form
-
-
:prerequisite-was-called-with-unexpected-arguments
TBD: It's complicated.
-
:parse-error
-
:notes
Text about the error.
-
-
:exception-during-parsing
-
:macro-form
The form being translated when the exception happened. -
:stacktrace
A stacktrace, filtered down to Midje functions. (Still largely useless)
-