+(defmacro is-every (predicate &body clauses)
+ "The input is either a list of lists, or a list of pairs. Generates (is (,predicate ,expr ,value))
+ for each pair of elements or (is (,predicate ,expr ,value) ,@reason) for each list."
+ `(progn
+ ,@(if (every #'consp clauses)
+ (loop for (expected actual &rest reason) in clauses
+ collect `(is (,predicate ,expected ,actual) ,@reason))
+ (progn
+ (assert (evenp (list-length clauses)))
+ (loop for (expr value) on clauses by #'cddr
+ collect `(is (,predicate ,expr ,value)))))))
+