 (ns com.stuartsierra.lazytest2)
+
+;;; PROTOCOLS
+
+(defprotocol TestInvokable
+  (invoke-test [t active]))
+
+(defprotocol Successful
+  (success? [r]))
+
+
+;;; Results
+
+(deftype TestResults [source children]
+  Successful (success? [] (every? success? children)))
+
+(deftype TestPassed [source states]
+  Successful (success? [] true))
+
+(deftype TestFailed [source states]
+  Successful (success? [] false))
+
+(deftype TestThrown [source states throwable]
+  Successful (success? [] false))
+
+
+;;; Contexts
 
 (deftype Context [parents before after])
 

                          ~@after))]
        `(def ~name (Context ~contexts ~before-fn ~after-fn '~m nil))))))

(defprotocol TestInvokable
  (invoke-test [t active]))

(deftype TestResults [source children])

(deftype TestPassed [source states])

(deftype TestFailed [source states])

(deftype TestThrown [source states throwable])

(deftype ContextualAssertion [contexts pred] :as this
  TestInvokable

               nxt))
      `(SimpleContainer ~r))))

(defmacro given
  "A series of assertions using values from contexts.
  bindings is a vector of name-value pairs, like let, where each value
  is a context created with defcontext.  A string will be attached
  as :doc metadata on the following assertion."
  [bindings & assertions]
  (assert (vector? bindings))
  (assert (even? (count bindings)))
  (let [pairs (partition 2 bindings)
