From 93fa9a6bb7f5153101a663dee8ba141f726ddc6f Mon Sep 17 00:00:00 2001 From: Max Penet Date: Mon, 6 Jan 2025 13:03:46 +0100 Subject: [PATCH 1/4] merge + closed bugfix --- src/exoscale/coax.cljc | 18 +++++------------- test/exoscale/coax_test.cljc | 5 +++++ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/exoscale/coax.cljc b/src/exoscale/coax.cljc index c9868bd..16dd1f2 100644 --- a/src/exoscale/coax.cljc +++ b/src/exoscale/coax.cljc @@ -127,20 +127,12 @@ (defn gen-coerce-merge [[_ & spec-forms]] - (fn [x opts] + (fn [x {:as opts :keys [closed]}] (if (map? x) - (reduce (fn [m spec-form] - ;; for every spec-form coerce to new value; - ;; we need to compare key by key what changed so that - ;; defaults do not overwrite coerced values - (into m - (keep (fn [[spec v]] - ;; new-val doesn't match default, keep it - (when-not (= (get x spec) v) - [spec v]))) - (coerce spec-form x (assoc opts :closed true)))) - x - spec-forms) + (into {} + (map (fn [spec-form] + (coerce spec-form x (assoc opts :closed closed)))) + spec-forms) :exoscale.coax/invalid))) (defn gen-coerce-nilable diff --git a/test/exoscale/coax_test.cljc b/test/exoscale/coax_test.cljc index 23c3fd6..500121d 100644 --- a/test/exoscale/coax_test.cljc +++ b/test/exoscale/coax_test.cljc @@ -420,6 +420,11 @@ (sc/coerce ::merge2 {::foo "1" :foo "1" :bar "1" :c {:a 2}})) "Leave out ok vals") + (is (= {::foo 1 :bar "1" :foo 1} + (sc/coerce ::merge2 {::foo "1" :foo "1" :bar "1" :c {:a 2}} + {:closed true})) + "Remove extras") + (is (= "garbage" (sc/coerce ::merge "garbage")) "garbage is passthrough") From d7c7737d43b197f9ae6b6eac5e96cf9bbfcca8ef Mon Sep 17 00:00:00 2001 From: Max Penet Date: Mon, 6 Jan 2025 13:11:56 +0100 Subject: [PATCH 2/4] fixup! merge + closed bugfix --- src/exoscale/coax.cljc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/exoscale/coax.cljc b/src/exoscale/coax.cljc index 16dd1f2..1f2dbeb 100644 --- a/src/exoscale/coax.cljc +++ b/src/exoscale/coax.cljc @@ -129,9 +129,9 @@ [[_ & spec-forms]] (fn [x {:as opts :keys [closed]}] (if (map? x) - (into {} + (into (cond-> x closed empty) (map (fn [spec-form] - (coerce spec-form x (assoc opts :closed closed)))) + (coerce spec-form x (assoc opts :closed true)))) spec-forms) :exoscale.coax/invalid))) From 50d2e7ccc3aa4c031d7c6fe4e6a0823fe5409085 Mon Sep 17 00:00:00 2001 From: Max Penet Date: Mon, 6 Jan 2025 14:31:53 +0100 Subject: [PATCH 3/4] fixup! merge + closed bugfix --- src/exoscale/coax.cljc | 19 +++++++++++++++---- test/exoscale/coax_test.cljc | 7 +++++-- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/exoscale/coax.cljc b/src/exoscale/coax.cljc index 1f2dbeb..b0c9547 100644 --- a/src/exoscale/coax.cljc +++ b/src/exoscale/coax.cljc @@ -129,10 +129,21 @@ [[_ & spec-forms]] (fn [x {:as opts :keys [closed]}] (if (map? x) - (into (cond-> x closed empty) - (map (fn [spec-form] - (coerce spec-form x (assoc opts :closed true)))) - spec-forms) + (if closed + (into {} + (map (fn [spec-form] + (coerce spec-form x (assoc opts :closed true)))) + spec-forms) + ;; not closed, we also have to ensure we don't overwrite values with + ;; more loose specs towards the end of the args (ex `any?` + (reduce (fn [m spec-form] + (into m + (remove (fn [[k v]] + (= (get x k) v))) + (coerce spec-form x (assoc opts :closed true)))) + x + spec-forms)) + :exoscale.coax/invalid))) (defn gen-coerce-nilable diff --git a/test/exoscale/coax_test.cljc b/test/exoscale/coax_test.cljc index 500121d..7fd0044 100644 --- a/test/exoscale/coax_test.cljc +++ b/test/exoscale/coax_test.cljc @@ -373,6 +373,9 @@ (deftest test-or-conditions-in-unqualified-keys (is (= (sc/coerce ::unqualified {:foo "1" :bar "hi"}) + {:foo 1 :bar "hi"})) + + (is (= (sc/coerce ::unqualified {:foo "1" :bar "hi"} {:closed true}) {:foo 1 :bar "hi"}))) (deftest test-closed-keys @@ -402,7 +405,7 @@ any?)) (is (= {:foo 1 :bar "1" :c {:a 2}} (sc/coerce ::merge {:foo "1" :bar 1 :c {:a 2}})) - "Coerce new vals appropriately") + "Coerce new vals appropriately 1") (is (= {:foo 1 :bar "1" :c {:a 2}} (sc/coerce ::merge {:foo 1 :bar "1" :c {:a 2}})) @@ -410,7 +413,7 @@ (is (= {:foo 1 :bar "1" :c {:a 2}} (sc/coerce ::merge {:foo "1" :bar 1 :c {:a 2}})) - "Coerce new vals appropriately") + "Coerce new vals appropriately 2") (s/def ::merge2 (s/merge (s/keys :req [::foo]) ::unqualified)) From 8cefae1d5edf6fd5a70432b14e6e58d273d46a14 Mon Sep 17 00:00:00 2001 From: Max Penet Date: Mon, 6 Jan 2025 14:34:01 +0100 Subject: [PATCH 4/4] fixup! merge + closed bugfix --- test/exoscale/coax_test.cljc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/exoscale/coax_test.cljc b/test/exoscale/coax_test.cljc index 7fd0044..61d0215 100644 --- a/test/exoscale/coax_test.cljc +++ b/test/exoscale/coax_test.cljc @@ -418,8 +418,7 @@ (s/def ::merge2 (s/merge (s/keys :req [::foo]) ::unqualified)) - (is (= {::foo 1 :bar "1" :c {:a 2} - :foo 1} + (is (= {::foo 1 :bar "1" :c {:a 2} :foo 1} (sc/coerce ::merge2 {::foo "1" :foo "1" :bar "1" :c {:a 2}})) "Leave out ok vals")