Skip to content

Commit 6a91708

Browse files
committed
Fixes #2 by adding direct spec support
1 parent fa31fb6 commit 6a91708

File tree

2 files changed

+25
-27
lines changed

2 files changed

+25
-27
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Version 1.1.0 in progress
22

3+
* An expectation can now use a qualified keyword spec to test conformance of the actual value. Failures are reported with the spec explanation. #2
34
* If Paul Stadig's Humane Test Output is available (on the classpath), failure reporting is automatically made compatible with it. Expectations that use data structure "equality" (the `=?` extension to `is`) will produce "humane" output for failures, showing differences. #1
45

56
# Initial version 1.0.1

src/expectations/clojure/test.clj

+24-27
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,41 @@
3131
(defmacro more-> [& _] (bad-usage "more->"))
3232
(defmacro more [& _] (bad-usage "more"))
3333

34+
(defn spec? [e]
35+
(and (keyword? e)
36+
(try
37+
(require 'clojure.spec.alpha)
38+
(when-let [get-spec (resolve 'clojure.spec.alpha/get-spec)]
39+
(boolean (get-spec e)))
40+
(catch Throwable _))))
41+
3442
;; smart equality extension to clojure.test assertion -- if the expected form
3543
;; is a predicate (function) then the assertion is equivalent to (is (e a))
3644
;; rather than (is (= e a)) and we need the type check done at runtime, not
3745
;; as part of the macro translation layer
3846
(defmethod t/assert-expr '=? [msg form]
3947
;; (is (=? val-or-pred expr))
40-
(let [[_ e a] form]
48+
(let [[_ e a] form
49+
conform? (spec? e)
50+
valid? (when conform? (resolve 'clojure.spec.alpha/valid?))
51+
explain-str? (when conform? (resolve 'clojure.spec.alpha/explain-str))]
4152
`(let [e# ~e
4253
a# ~a
43-
r# (if (fn? e#) (e# a#) (= e# a#))
44-
humane?# (and humane-test-output? (not (fn? e#)))]
54+
r# (cond ~conform?
55+
(~valid? e# a#)
56+
(fn? e#)
57+
(e# a#)
58+
:else
59+
(= e# a#))
60+
humane?# (and humane-test-output? (not (fn? e#)) (not ~conform?))]
4561
(if r#
4662
(t/do-report {:type :pass, :message ~msg,
4763
:expected '~form, :actual (if (fn? e#)
4864
(list '~e a#)
4965
a#)})
50-
(t/do-report {:type :fail, :message ~msg,
66+
(t/do-report {:type :fail, :message (if ~conform?
67+
(~explain-str? e# a#)
68+
~msg)
5169
:diffs (if humane?#
5270
[[a# (take 2 (data/diff e# a#))]]
5371
[])
@@ -64,10 +82,7 @@
6482
"Wrapper for forms that might throw an exception so exception class names
6583
can be used as predicates. This is only needed for more-> so that you can
6684
thread exceptions into code that can parse information out of them, to be
67-
used with various expect predicates.
68-
69-
TODO: revisit this to see if wrapping the whole expect with try/catch will
70-
allow this to be omitted."
85+
used with various expect predicates."
7186
[form]
7287
`(try ~form (catch Throwable t# t#)))
7388

@@ -82,25 +97,7 @@
8297
(swap! store update (:type m) (fnil conj []) m)))
8398

8499
(defmacro expect
85-
"Translate Expectations DSL to clojure.test language.
86-
87-
Things implemented so far:
88-
* simple predicate test
89-
* class test
90-
* exception test
91-
* regex test
92-
* simple equality
93-
* from-each actual
94-
* in actual
95-
* more-of expected
96-
* more-> expected
97-
* more expected
98-
* side-effects (copied from Expectations)
99-
100-
Things to implement:
101-
* redef-state ?
102-
* freeze-time
103-
* context / in-context ?"
100+
"Translate Expectations DSL to clojure.test language."
104101
([a] `(t/is ~a))
105102
([e a] `(expect ~e ~a true ~e))
106103
([e a ex?] `(expect ~e ~a ~ex? ~e))

0 commit comments

Comments
 (0)