1
1
(ns cljs.spec-test
2
2
(: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]]))
4
4
5
5
(s/def ::even? (s/and number? even?))
6
6
(s/def ::odd? (s/and number? odd?))
56
56
(deftest test-conform-unform
57
57
(let [xs [42 11 13 15 {:a 1 :b 2 :c 3 } 1 2 3 42 43 44 11 ]]
58
58
(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\t expect=" conformed " \n\t actual=" co))
96
+ (when (not (every? true ? (map submap? ed e)))
97
+ (println " explain failures\n\t expect=" ed " \n\t actual failures=" e " \n\t submap?=" (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