Skip to content
marick edited this page Apr 27, 2013 · 9 revisions

Short version

In your source:

(fact :slow ...) ; Runs slowly
(fact "a core fact" :core)
(fact "metadata map" {:priority 5})

In the repl:

(load-facts :core)    ; Load-and-check only the core facts

(load-facts :all)                ; ":all" is not a metadata key. Loads all namespaces.
(check-facts :core)              ; Check a subset
(check-facts (complement :core)  ; Check the other facts.

With lein repl:

% lein midje :filter core -slow ; select tests that are "core" or not "slow"

Details

Defining metadata

Metadata is ( <string> | <name> | <keyword> | <map> )*.

A map is merged onto a compiled fact's metadata.

A keyword :foo is equivalent to {:foo true}.

A string "foo" is equivalent to {:midje/description "foo"}.

A symbol foo is equivalent to {:midje/name "foo")}.

Note that metadata is auto-quoted. In the following, neither the name nor the map value need be quoted:

user=> (fact fred-fact {:key value})
true
user=> (:key (meta (last-fact-checked)))
"fred-fact"
user=> (:key (meta (last-fact-checked)))
value

In addition to :midje/name and :midje/description, there is other automatic metadata. They're all defined here:

:midje/description
The fact's outermost doc string, if given. It is the description that is printed when a fact fails.

:midje/name
The name of the fact. If a symbol is given in the metadata position, the string name of that symbol becomes the name. Otherwise, if a doc string is given, it becomes the name. Otherwise, there is no name. (Names are relevant to redefining facts when reloading. See the compendium.)

:midje/file, :midje/line, midje/namespace:
These identify the source of the fact. The line number is that of the beginning of the fact. The namespace is the symbol name of the enclosing namespace, not the namespace itself.

:midje/source: The original source of the fact.

:midje/guid: A unique identifier constructed from the body of the fact (excluding metadata). It's used to detect when new fact definition is the same as one that's already been seen.

Here are examples of :midje/description and :midje/name:

;; "doc string" is both the name and the description.
(fact "doc string" ...)

;; The string "cons" is the name. There is no description.
(fact cons ...)

;; The string "cons" is the name. "Cons tests" is the description.
(fact "Cons tests" cons 
  ...)

Fact nesting

With the exception of the :midje/description (which is used to compose failure messages), metadata in interior facts is ignored. You cannot, for example, choose to run only one sub-fact of an outer fact.

You might want a number of tests that are all integration tests. You might not want to put :integration metadata on each one. You can avoid that in two ways. First, you could wrap all the facts in an outermost fact:

(fact :integration
  (fact ...)
  (fact ...)
  ...)

That's a good solution if you only ever want to check all the integration facts together. It's not if you want to check individual facts. In such cases, use fact-group:

(fact-group :integration
  (fact ...)
  (fact {:speed :slow} ...)
)

The fact-group metadata is merged with the individual facts' metadata.

Tabular facts

Tabular facts can take metadata. It can be placed either after the tabular token or the enclosed fact token. That is, the following two constructs mean the same thing:

(tabular "arithmetic" :foundation
  (fact 
     (+ ?a ?b) => ?c)
     ?a     ?b    ?c
     1      2     3
     2      2     4)

(tabular 
  (fact "arithmetic" :foundation
     (+ ?a ?b) => ?c)
     ?a     ?b    ?c
     1      2     3
     2      2     4)
Clone this wiki locally