Skip to content
marick edited this page Feb 12, 2013 · 3 revisions

The quintessential fact makes a truth claim about some function in your program. Since sweeping truth claims are hard for a computer program to verify, facts contain concrete predictions that Midje can check. If the predictions come true, you gain confidence in the original claim.

As far as the implementation goes, a fact is a form that contains prediction forms. Here's a fact with one prediction:

(fact (+ 1 1) => 2)

Facts can have more than one prediction, and those predictions can be nested inside other code. Most typical are predictions inside a let:

(fact
  (let [expected 2]
     (+ 1 1) => expected
     (* 2 1) => expected
     (- 3 1) => expected))

Facts can have descriptions (doc strings) that are printed as a part of a failure message:

user=> (fact "Twice two is three"
         (* 2 2) => 3)
FAIL "Twice two is three" at (NO_SOURCE_PATH:2)
    Expected: 3
      Actual: 4
false

Notice that the result of the fact is false. The result is true only if all predictions come true.

Facts can be nested arbitrarily deeply:

user=> (facts "about arithmetic" 
         (fact "there is addition"
           (+ 1 1) => 2)
         (fact "about subtraction"
           (- 1 1) => 0)
         ;; Couldn't think of a fact name for this...
         1 => pos?
         -1 => neg?)
true

Notice that the outermost structure was named facts. That's not required: it's just a synonym for fact.

All the nested descriptions are used to create the failure output:

user=> (facts "about arithmetic"
         (fact "twice two is three"
           (+ 2 2) => 3))

FAIL "about arithmetic - twice two is three" at (NO_SOURCE_PATH:3)

Facts can be tabular. That looks like this:

(tabular "ways to arrive at 2"
  (fact
    (?op ?left ?right) => 2)
  ?op ?left ?right
   +    1     1
   *    1     2
   /    4     2)
true

That form has three parts: the symbol tabular (and optional description), an ordinary fact with particular symbols marked as special, and a table of value-for-special-symbol substitutions. (The description can be on either the tabular or the fact.)

The above tabular fact is actually expanded into two facts: one where 0 is substituted for ?n, and one where 2 is substituted. In the case of a failure, the output lists the substitutions.

Facts can have metadata. Here, for example, is metadata tagging a slow test:

(fact "check Takeuchi's number" :slow ...)

Both lein-midje and the repl tools can be told to skip :slow tests (or to run only slow tests).

Sometimes you want to use a fact as a "todo". That can be written like this:

user=> (future-fact (time np) => polynomial?)

WORK TO DO at (NO_SOURCE_PATH:1)

If the fact has a description, that will also be printed.

Clone this wiki locally