Skip to content

Commit 6b3277b

Browse files
author
dnolen
committed
copy over spec tests from Clojure
1 parent 561940f commit 6b3277b

File tree

1 file changed

+145
-1
lines changed

1 file changed

+145
-1
lines changed

src/test/cljs/cljs/spec_test.cljs

Lines changed: 145 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
(ns cljs.spec-test
22
(:require [cljs.spec :as s]
3-
[cljs.test :as test :refer-macros [deftest is run-tests]]))
3+
[cljs.test :as test :refer-macros [deftest is are run-tests]]))
44

55
(s/def ::even? (s/and number? even?))
66
(s/def ::odd? (s/and number? odd?))
@@ -56,3 +56,147 @@
5656
(deftest test-conform-unform
5757
(let [xs [42 11 13 15 {:a 1 :b 2 :c 3} 1 2 3 42 43 44 11]]
5858
(is (= xs (s/unform s2 (s/conform s2 xs))))))
59+
60+
;; Copied from Clojure spec tests
61+
62+
(def even-count? #(even? (count %)))
63+
64+
(defn submap?
65+
"Is m1 a subset of m2?"
66+
[m1 m2]
67+
(if (and (map? m1) (map? m2))
68+
(every? (fn [[k v]] (and (contains? m2 k)
69+
(submap? v (get m2 k))))
70+
m1)
71+
(= m1 m2)))
72+
73+
(deftest conform-explain
74+
(let [a (s/and #(> % 5) #(< % 10))
75+
o (s/or :s string? :k keyword?)
76+
c (s/cat :a string? :b keyword?)
77+
either (s/alt :a string? :b keyword?)
78+
star (s/* keyword?)
79+
plus (s/+ keyword?)
80+
opt (s/? keyword?)
81+
andre (s/& (s/* keyword?) even-count?)
82+
m (s/map-of keyword? string?)
83+
mkeys (s/map-of (s/and keyword? (s/conformer name)) any?)
84+
mkeys2 (s/map-of (s/and keyword? (s/conformer name)) any? :conform-keys true)
85+
s (s/coll-of (s/spec (s/cat :tag keyword? :val any?)) :kind list?)
86+
v (s/coll-of keyword? :kind vector?)
87+
coll (s/coll-of keyword?)
88+
lrange (s/int-in 7 42)
89+
;drange (s/double-in :infinite? false :NaN? false :min 3.1 :max 3.2)
90+
irange (s/inst-in #inst "1939" #inst "1946")
91+
]
92+
(are [spec x conformed ed]
93+
(let [co (s/conform spec x)
94+
e (::s/problems (s/explain-data spec x))]
95+
(when (not= conformed co) (println "conform fail\n\texpect=" conformed "\n\tactual=" co))
96+
(when (not (every? true? (map submap? ed e)))
97+
(println "explain failures\n\texpect=" ed "\n\tactual failures=" e "\n\tsubmap?=" (map submap? ed e)))
98+
(and (= conformed co) (every? true? (map submap? ed e))))
99+
100+
lrange 7 7 nil
101+
lrange 8 8 nil
102+
lrange 42 ::s/invalid [{:pred '(int-in-range? 7 42 %), :val 42}]
103+
104+
irange #inst "1938" ::s/invalid [{:pred '(inst-in-range? #inst "1939-01-01T00:00:00.000-00:00" #inst "1946-01-01T00:00:00.000-00:00" %), :val #inst "1938"}]
105+
irange #inst "1942" #inst "1942" nil
106+
irange #inst "1946" ::s/invalid [{:pred '(inst-in-range? #inst "1939-01-01T00:00:00.000-00:00" #inst "1946-01-01T00:00:00.000-00:00" %), :val #inst "1946"}]
107+
108+
;drange 3.0 ::s/invalid [{:pred '(<= 3.1 %), :val 3.0}]
109+
;drange 3.1 3.1 nil
110+
;drange 3.2 3.2 nil
111+
;drange Double/POSITIVE_INFINITY ::s/invalid [{:pred '(not (isInfinite %)), :val Double/POSITIVE_INFINITY}]
112+
;; can't use equality-based test for Double/NaN
113+
;; drange Double/NaN ::s/invalid {[] {:pred '(not (isNaN %)), :val Double/NaN}}
114+
115+
keyword? :k :k nil
116+
keyword? nil ::s/invalid [{:pred ::s/unknown :val nil}]
117+
keyword? "abc" ::s/invalid [{:pred ::s/unknown :val "abc"}]
118+
119+
a 6 6 nil
120+
a 3 ::s/invalid '[{:pred (> % 5), :val 3}]
121+
a 20 ::s/invalid '[{:pred (< % 10), :val 20}]
122+
;a nil "java.lang.NullPointerException" "java.lang.NullPointerException"
123+
;a :k "java.lang.ClassCastException" "java.lang.ClassCastException"
124+
125+
o "a" [:s "a"] nil
126+
o :a [:k :a] nil
127+
o 'a ::s/invalid '[{:pred string?, :val a, :path [:s]} {:pred keyword?, :val a :path [:k]}]
128+
129+
c nil ::s/invalid '[{:reason "Insufficient input", :pred string?, :val (), :path [:a]}]
130+
c [] ::s/invalid '[{:reason "Insufficient input", :pred string?, :val (), :path [:a]}]
131+
c [:a] ::s/invalid '[{:pred string?, :val :a, :path [:a], :in [0]}]
132+
c ["a"] ::s/invalid '[{:reason "Insufficient input", :pred keyword?, :val (), :path [:b]}]
133+
c ["s" :k] '{:a "s" :b :k} nil
134+
c ["s" :k 5] ::s/invalid '[{:reason "Extra input", :pred (cat :a string? :b keyword?), :val (5)}]
135+
136+
;; TODO: prevents termination for some reason - David
137+
;(s/cat) nil {} nil
138+
;(s/cat) [5] ::s/invalid '[{:reason "Extra input", :pred (cat), :val (5), :in [0]}]
139+
140+
either nil ::s/invalid '[{:reason "Insufficient input", :pred (alt :a string? :b keyword?), :val () :via []}]
141+
either [] ::s/invalid '[{:reason "Insufficient input", :pred (alt :a string? :b keyword?), :val () :via []}]
142+
either [:k] [:b :k] nil
143+
either ["s"] [:a "s"] nil
144+
either [:b "s"] ::s/invalid '[{:reason "Extra input", :pred (alt :a string? :b keyword?), :val ("s") :via []}]
145+
146+
star nil [] nil
147+
star [] [] nil
148+
star [:k] [:k] nil
149+
star [:k1 :k2] [:k1 :k2] nil
150+
star [:k1 :k2 "x"] ::s/invalid '[{:pred keyword?, :val "x" :via []}]
151+
star ["a"] ::s/invalid '[{:pred keyword?, :val "a" :via []}]
152+
153+
plus nil ::s/invalid '[{:reason "Insufficient input", :pred keyword?, :val () :via []}]
154+
plus [] ::s/invalid '[{:reason "Insufficient input", :pred keyword?, :val () :via []}]
155+
plus [:k] [:k] nil
156+
plus [:k1 :k2] [:k1 :k2] nil
157+
plus [:k1 :k2 "x"] ::s/invalid '[{:pred keyword?, :val "x", :in [2]}]
158+
plus ["a"] ::s/invalid '[{:pred keyword?, :val "a" :via []}]
159+
160+
opt nil nil nil
161+
opt [] nil nil
162+
opt :k ::s/invalid '[{:pred (? keyword?), :val :k}]
163+
opt [:k] :k nil
164+
opt [:k1 :k2] ::s/invalid '[{:reason "Extra input", :pred (? keyword?), :val (:k2)}]
165+
opt [:k1 :k2 "x"] ::s/invalid '[{:reason "Extra input", :pred (? keyword?), :val (:k2 "x")}]
166+
opt ["a"] ::s/invalid '[{:pred keyword?, :val "a"}]
167+
168+
andre nil nil nil
169+
andre [] nil nil
170+
andre :k ::s/invalid '[{:pred (& (* keyword?) even-count?), :val :k}]
171+
andre [:k] ::s/invalid '[{:pred even-count?, :val [:k]}]
172+
andre [:j :k] [:j :k] nil
173+
174+
m nil ::s/invalid '[{:pred map?, :val nil}]
175+
m {} {} nil
176+
m {:a "b"} {:a "b"} nil
177+
178+
mkeys nil ::s/invalid '[{:pred map?, :val nil}]
179+
mkeys {} {} nil
180+
mkeys {:a 1 :b 2} {:a 1 :b 2} nil
181+
182+
mkeys2 nil ::s/invalid '[{:pred map?, :val nil}]
183+
mkeys2 {} {} nil
184+
mkeys2 {:a 1 :b 2} {"a" 1 "b" 2} nil
185+
186+
s '([:a 1] [:b "2"]) '({:tag :a :val 1} {:tag :b :val "2"}) nil
187+
188+
v [:a :b] [:a :b] nil
189+
v '(:a :b) ::s/invalid '[{:pred vector? :val (:a :b)}]
190+
191+
coll nil ::s/invalid '[{:path [], :pred coll?, :val nil, :via [], :in []}]
192+
coll [] [] nil
193+
coll [:a] [:a] nil
194+
coll [:a :b] [:a :b] nil
195+
;;coll [:a "b"] ::s/invalid '[{:pred (coll-checker keyword?), :val [:a b]}]
196+
)))
197+
198+
(comment
199+
200+
(run-tests)
201+
202+
)

0 commit comments

Comments
 (0)