File tree Expand file tree Collapse file tree 3 files changed +37
-4
lines changed Expand file tree Collapse file tree 3 files changed +37
-4
lines changed Original file line number Diff line number Diff line change 1+ ## NEXT
2+ * [ #449 ] ( https://github.com/plumatic/schema/issues/453 ) : Preserve ` s/enum ` order during printing
3+
14## 1.4.1 (` 2022-09-29 ` )
25 * [ #449 ] ( https://github.com/plumatic/schema/issues/449 ) : Fix bad jsdoc
36
Original file line number Diff line number Diff line change 284284
285285; ;; enum (in a set of allowed values)
286286
287+ ; ; breaks if :vs is set manually without reconstructing via s/enum
288+ (defn- usually-ordered-enum-form [{:keys [vs] :as enum}]
289+ (or (-> enum meta ::form-hint (get vs) force)
290+ (cons 'enum vs)))
291+
287292(macros/defrecord-schema EnumSchema [vs]
288293 Schema
289294 (spec [this] (leaf/leaf-spec (spec/precondition this #(contains? vs %) #(list vs %))))
290- (explain [this] (cons ' enum vs )))
295+ (explain [this] (usually-ordered- enum-form this )))
291296
292297(clojure.core/defn enum
293298 " A value that must be = to some element of vs."
294299 [& vs]
295- (EnumSchema. (set vs)))
296-
300+ (let [svs (set vs)]
301+ ; ; TODO it would be nice to use the (EnumSchema. vs _meta _ext) ctor but it doesn't work yet in bb
302+ ; ; https://github.com/babashka/sci/issues/928
303+ (-> (EnumSchema. svs)
304+ (with-meta {::form-hint {svs (delay (seq (into ['enum] (distinct ) vs)))}}))))
297305
298306; ;; pred (matches all values for which p? returns truthy)
299307
Original file line number Diff line number Diff line change 133133 (valid! schema 1 )
134134 (invalid! schema :c )
135135 (invalid! (s/enum :a ) 2 " (not (#{:a} 2))" )
136- (is (= '(1 :a :b enum) (sort-by str (s/explain schema))))))
136+ (is (= '(enum :a :b 1 ) (s/explain schema))))
137+ (is (= (cons 'enum (range 1000 )) (s/explain (apply s/enum (range 1000 )))))
138+ (testing " prints as if (distinct vs), which preserves original order"
139+ (is (= '(enum 1 2 3 4 ) (s/explain (s/enum 1 2 1 3 1 4 )))))
140+ (testing " equality still works if implementation details are exploited"
141+ (is (= (update (s/enum 1 2 3 ) :vs conj 4 )
142+ (update (s/enum 1 2 3 4 5 ) :vs disj 5 ))))
143+ (testing " still prints correctly (albeit unordered) if implementation details are exploited"
144+ (dotimes [_ 100 ]
145+ (let [[a b c] (repeatedly #(rand-nth
146+ [(gensym )
147+ (str (gensym ))
148+ (keyword (gensym ))]))
149+ _ (assert (distinct? a b c))
150+ e (s/enum a b)
151+ _ (testing " prints in order"
152+ (is (= (list 'enum a b) (s/explain e))))
153+ e (update e :vs conj c)
154+ _ (testing " adding an extra entry using implementation details just prints using the set's order"
155+ (is (= (cons 'enum (:vs e)) (s/explain e))))
156+ e (update e :vs disj c)
157+ _ (testing " resetting :vs preserves the original printing order"
158+ (is (= (list 'enum a b) (s/explain (update e :vs disj c)))))]))))
137159
138160(deftest pred-test
139161 (let [schema (s/pred odd? 'odd?)]
You can’t perform that action at this time.
0 commit comments