Skip to content

Commit a60126b

Browse files
authored
merge + closed bugfix (#32)
1 parent 7e99a50 commit a60126b

File tree

2 files changed

+26
-16
lines changed

2 files changed

+26
-16
lines changed

src/exoscale/coax.cljc

+15-12
Original file line numberDiff line numberDiff line change
@@ -127,20 +127,23 @@
127127

128128
(defn gen-coerce-merge
129129
[[_ & spec-forms]]
130-
(fn [x opts]
130+
(fn [x {:as opts :keys [closed]}]
131131
(if (map? x)
132-
(reduce (fn [m spec-form]
133-
;; for every spec-form coerce to new value;
134-
;; we need to compare key by key what changed so that
135-
;; defaults do not overwrite coerced values
136-
(into m
137-
(keep (fn [[spec v]]
138-
;; new-val doesn't match default, keep it
139-
(when-not (= (get x spec) v)
140-
[spec v])))
141-
(coerce spec-form x (assoc opts :closed true))))
142-
x
132+
(if closed
133+
(into {}
134+
(map (fn [spec-form]
135+
(coerce spec-form x (assoc opts :closed true))))
143136
spec-forms)
137+
;; not closed, we also have to ensure we don't overwrite values with
138+
;; more loose specs towards the end of the args (ex `any?`
139+
(reduce (fn [m spec-form]
140+
(into m
141+
(remove (fn [[k v]]
142+
(= (get x k) v)))
143+
(coerce spec-form x (assoc opts :closed true))))
144+
x
145+
spec-forms))
146+
144147
:exoscale.coax/invalid)))
145148

146149
(defn gen-coerce-nilable

test/exoscale/coax_test.cljc

+11-4
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,9 @@
373373

374374
(deftest test-or-conditions-in-unqualified-keys
375375
(is (= (sc/coerce ::unqualified {:foo "1" :bar "hi"})
376+
{:foo 1 :bar "hi"}))
377+
378+
(is (= (sc/coerce ::unqualified {:foo "1" :bar "hi"} {:closed true})
376379
{:foo 1 :bar "hi"})))
377380

378381
(deftest test-closed-keys
@@ -402,24 +405,28 @@
402405
any?))
403406
(is (= {:foo 1 :bar "1" :c {:a 2}}
404407
(sc/coerce ::merge {:foo "1" :bar 1 :c {:a 2}}))
405-
"Coerce new vals appropriately")
408+
"Coerce new vals appropriately 1")
406409

407410
(is (= {:foo 1 :bar "1" :c {:a 2}}
408411
(sc/coerce ::merge {:foo 1 :bar "1" :c {:a 2}}))
409412
"Leave out ok vals")
410413

411414
(is (= {:foo 1 :bar "1" :c {:a 2}}
412415
(sc/coerce ::merge {:foo "1" :bar 1 :c {:a 2}}))
413-
"Coerce new vals appropriately")
416+
"Coerce new vals appropriately 2")
414417

415418
(s/def ::merge2 (s/merge (s/keys :req [::foo])
416419
::unqualified))
417420

418-
(is (= {::foo 1 :bar "1" :c {:a 2}
419-
:foo 1}
421+
(is (= {::foo 1 :bar "1" :c {:a 2} :foo 1}
420422
(sc/coerce ::merge2 {::foo "1" :foo "1" :bar "1" :c {:a 2}}))
421423
"Leave out ok vals")
422424

425+
(is (= {::foo 1 :bar "1" :foo 1}
426+
(sc/coerce ::merge2 {::foo "1" :foo "1" :bar "1" :c {:a 2}}
427+
{:closed true}))
428+
"Remove extras")
429+
423430
(is (= "garbage" (sc/coerce ::merge "garbage"))
424431
"garbage is passthrough")
425432

0 commit comments

Comments
 (0)