Skip to content

Commit e6abaa7

Browse files
anmonteirodnolen
authored andcommitted
CLJS-1978: port CLJ-2035
1 parent 6f4b313 commit e6abaa7

File tree

3 files changed

+46
-5
lines changed

3 files changed

+46
-5
lines changed

src/main/cljs/cljs/spec.cljc

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,15 @@
201201
[& pred-forms]
202202
`(and-spec-impl '~(mapv #(res &env %) pred-forms) ~(vec pred-forms) nil))
203203

204+
(defn- res-kind
205+
[env opts]
206+
(let [{kind :kind :as mopts} opts]
207+
(->>
208+
(if kind
209+
(assoc mopts :kind `~(res env kind))
210+
mopts)
211+
(mapcat identity))))
212+
204213
(defmacro every
205214
"takes a pred and validates collection elements against that pred.
206215
@@ -231,7 +240,11 @@
231240
See also - coll-of, every-kv
232241
"
233242
[pred & {:keys [into kind count max-count min-count distinct gen-max gen-into gen] :as opts}]
234-
(let [nopts (-> opts (dissoc :gen) (assoc ::kind-form `'~(res &env (:kind opts))))
243+
(let [desc (::describe opts)
244+
nopts (-> opts
245+
(dissoc :gen ::describe)
246+
(assoc ::kind-form `'~(res &env (:kind opts))
247+
::describe (clojure.core/or desc `'(every ~(res &env pred) ~@(res-kind &env opts)))))
235248
gx (gensym)
236249
cpreds (cond-> [(list (clojure.core/or kind `coll?) gx)]
237250
count (conj `(= ~count (c/bounded-count ~count ~gx)))
@@ -253,7 +266,8 @@
253266
See also - map-of"
254267

255268
[kpred vpred & opts]
256-
`(every (tuple ~kpred ~vpred) ::kfn (fn [i# v#] (nth v# 0)) :into {} ~@opts))
269+
(let [desc `(every-kv ~(res &env kpred) ~(res &env vpred) ~@(res-kind &env opts))]
270+
`(every (tuple ~kpred ~vpred) ::kfn (fn [i# v#] (nth v# 0)) :into {} ::describe '~desc ~@opts)))
257271

258272
(defmacro coll-of
259273
"Returns a spec for a collection of items satisfying pred. Unlike
@@ -267,7 +281,8 @@
267281
268282
See also - every, map-of"
269283
[pred & opts]
270-
`(every ~pred ::conform-all true ~@opts))
284+
(let [desc `(coll-of ~(res &env pred) ~@(res-kind &env opts))]
285+
`(every ~pred ::conform-all true ::describe '~desc ~@opts)))
271286

272287
(defmacro map-of
273288
"Returns a spec for a map whose keys satisfy kpred and vals satisfy
@@ -280,7 +295,8 @@
280295
281296
See also - every-kv"
282297
[kpred vpred & opts]
283-
`(every-kv ~kpred ~vpred ::conform-all true :kind map? ~@opts))
298+
(let [desc `(map-of ~(res &env kpred) ~(res &env vpred) ~@(res-kind &env opts))]
299+
`(every-kv ~kpred ~vpred ::conform-all true :kind map? ::describe '~desc ~@opts)))
284300

285301
(defmacro *
286302
"Returns a regex op that matches zero or more values matching

src/main/cljs/cljs/spec.cljs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,7 @@
793793
"Do not call this directly, use 'every', 'every-kv', 'coll-of' or 'map-of'"
794794
([form pred opts] (every-impl form pred opts nil))
795795
([form pred {gen-into :into
796+
describe-form ::describe
796797
:keys [kind ::kind-form count max-count min-count distinct gen-max ::kfn ::cpred
797798
conform-keys ::conform-all]
798799
:or {gen-max 20}
@@ -906,7 +907,7 @@
906907
(gen/vector pgen 0 gen-max))))))))
907908

908909
(with-gen* [_ gfn] (every-impl form pred opts gfn))
909-
(describe* [_] `(every ~form ~@(mapcat identity opts)))))))
910+
(describe* [_] (c/or describe-form `(every ~(s/res form) ~@(mapcat identity opts))))))))
910911

911912
;;;;;;;;;;;;;;;;;;;;;;; regex ;;;;;;;;;;;;;;;;;;;
912913
;;See:

src/test/cljs/cljs/spec_test.cljs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,30 @@
241241
;;coll [:a "b"] ::s/invalid '[{:pred (coll-checker keyword?), :val [:a b]}]
242242
)))
243243

244+
(deftest coll-form
245+
(are [spec form]
246+
(= (s/form spec) form)
247+
(s/map-of int? any?)
248+
'(cljs.spec/map-of cljs.core/int? cljs.core/any?)
249+
250+
(s/coll-of int?)
251+
'(cljs.spec/coll-of cljs.core/int?)
252+
253+
(s/every-kv int? int?)
254+
'(cljs.spec/every-kv cljs.core/int? cljs.core/int?)
255+
256+
(s/every int?)
257+
'(cljs.spec/every cljs.core/int?)
258+
259+
(s/coll-of (s/tuple (s/tuple int?)))
260+
'(cljs.spec/coll-of (cljs.spec/tuple (cljs.spec/tuple cljs.core/int?)))
261+
262+
(s/coll-of int? :kind vector?)
263+
'(cljs.spec/coll-of cljs.core/int? :kind cljs.core/vector?)
264+
265+
(s/coll-of int? :gen #(gen/return [1 2]))
266+
'(cljs.spec/coll-of cljs.core/int? :gen (fn* [] (gen/return [1 2])))))
267+
244268
(comment
245269

246270
(run-tests)

0 commit comments

Comments
 (0)