Skip to content
Fetching contributors…
Cannot retrieve contributors at this time
63 lines (59 sloc) 1.82 KB
(ns lazytest.expect
(:import (lazytest ExpectationFailed)))
(defn- local-bindings
"Returns a map of the names of local bindings to their values."
[env]
(reduce (fn [m sym] (assoc m `'~sym sym))
{} (keys env)))
(defn- function-call?
"True if form is a list representing a normal function call."
[form]
(and (seq? form)
(let [sym (first form)]
(and (symbol? sym)
(let [v (resolve sym)]
(and (var? v)
(bound? v)
(not (:macro (meta v)))
(let [f (var-get v)]
(fn? f))))))))
(defmacro expect
"Evaluates expression. If it returns logical true, returns that
result. If the expression returns logical false, throws
lazytest.ExpectationFailed with an attached map describing the
reason for failure. Metadata on expr and on the 'expect' form
itself will be merged into the failure map."
([expr] `(expect nil ~expr))
([docstring expr]
(if (function-call? expr)
;; Normal function call
`(let [doc# ~docstring
f# ~(first expr)
args# (list ~@(rest expr))
result# (apply f# args#)]
(or result#
(throw (ExpectationFailed.
(merge '~(meta &form)
'~(meta expr)
{:form '~expr
:locals ~(local-bindings &env)
:bindings (get-thread-bindings)
:evaluated (list* f# args#)
:result result#
:file ~*file*
:ns '~(ns-name *ns*)}
(when doc# {:doc doc#}))))))
;; Unknown type of expression
`(let [doc# ~docstring
result# ~expr]
(or result#
(throw (ExpectationFailed.
(merge '~(meta &form)
'~(meta expr)
{:form '~expr
:locals ~(local-bindings &env)
:bindings (get-thread-bindings)
:result result#
:file ~*file*
:ns '~(ns-name *ns*)}
(when doc# {:doc doc#})))))))))
Something went wrong with that request. Please try again.