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?))
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\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