familiar.alpha.test

Experimental testing constructs for Clojure(Script).

### TEST DOUBLES

Clojure's `with-redefs` and `with-redefs-fn` provide a foundation for
injecting function doubles when testing.  `clojure.test` does not, however,
provide any support for leveraging `with-redef{s,-fn}` to handle multiple
invocations of a function.

familiar introduces a lightweight (imposing as few restrictions as possible)
and pragmatic (acknowledging that it is sometimes desirable to exploit
`with-redef{s,fn}` when refactoring code into a more testable, injection-based
form is not) function double construct that attempts to do just that.

The entry point into this system is the `FnDouble`, an invocable record that
can be used directly in a `with-redefs` binding as the target function.  But
the `FnDouble` is really just a dispatcher to a strategy that actually handles
the how invocations are processed.

Strategies are thus the mechanism by which the desired testing behaviour can
be achieved.

For example, the `FnDoubleSequentialInvocationStategy` validates a particular
sequence of function invocations.  Invocations are described in the form of a
predicate and return element, with the predicate being used as an
"expectation" for the invocation.  Both the predicate and the return
element (if it is a function) are passed a `FnDoubleInvocationData` record,
through which the invocation arguments may be inspected.

Other strategies may be implemented to provide matching based on arguments, or
even a combination of strict sequence and matching; that is: verify
invocations according to the sequence, unless matched.

FnDoubleInvocation

protocol

members

invoke

(invoke this invocation-data)

FnDoubleSequentialInvocationStategy

protocol

members

exhausted

(exhausted fn-double-sequential-invocation-strategy)
Assert (using `clojure.test/is`) that all of the invocations in the
sequence have been issued; typically called at the end of a test.

exhausted?

(exhausted? fn-double-sequential-invocation-strategy)
Return true if all invocations in the sequence were , otherwise false