Skip to content

Commit 28d72f4

Browse files
authored
Merge pull request #1158 from metosin/ref-var-path-1106
fix: explain :path of ref schemas
2 parents 5e18221 + 52367ff commit 28d72f4

File tree

5 files changed

+61
-5
lines changed

5 files changed

+61
-5
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Malli is in well matured [alpha](README.md#alpha).
1919
* Docs: elaborate optional-keys and required-keys [#1117](https://github.com/metosin/malli/pull/1117)
2020
* **BREAKING** Output of `parse` now uses new `malli.core.Tag` and `malli.core.Tags` records for `:orn`, `:multi`, `:altn`, `:catn` etc. [#1123](https://github.com/metosin/malli/issues/1123) [#1153](https://github.com/metosin/malli/issues/1153)
2121
* See [Parsing](#parsing-values) and [Unparsing](#unparsing-values) for docs.
22+
* FIX: `:path` when explaining `:ref` errors [#1106](https://github.com/metosin/malli/issues/1106)
2223

2324
## 0.17.0 (2024-12-08)
2425

src/malli/core.cljc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1732,7 +1732,7 @@
17321732
(let [validator (-memoize (fn [] (-validator (rf))))]
17331733
(fn [x] ((validator) x))))
17341734
(-explainer [_ path]
1735-
(let [explainer (-memoize (fn [] (-explainer (rf) (conj path 0))))]
1735+
(let [explainer (-memoize (fn [] (-explainer (rf) (into path [0 0]))))]
17361736
(fn [x in acc] ((explainer) x in acc))))
17371737
(-parser [_] (->parser -parser))
17381738
(-unparser [_] (->parser -unparser))

test/malli/core_test.cljc

+36-2
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,19 @@
625625

626626
(testing "ref schemas"
627627

628+
(let [schema [:ref {:registry {::referred [:map [:foo :int]]}} ::referred]]
629+
(is (nil? (m/explain schema {:foo 2})))
630+
(testing "explain path"
631+
(let [exp (m/explain schema {:foo "2"})]
632+
(is (results= {:value {:foo "2"}
633+
:schema schema
634+
:errors [{:in [:foo]
635+
:path [0 0 :foo]
636+
:schema :int
637+
:value "2"}]}
638+
exp))
639+
(is (form= :int (mu/get-in schema (-> exp :errors first :path)))))))
640+
628641
(testing "invalid refs fail"
629642
(is (thrown?
630643
#?(:clj Exception, :cljs js/Error)
@@ -641,7 +654,7 @@
641654
(is (results= {:schema ConsCell
642655
:value [1 [2]]
643656
:errors [{:in [1]
644-
:path [0 0 0 1 0 0]
657+
:path [0 0 0 1 0 0 0]
645658
:schema (mu/get-in ConsCell [0 0 0])
646659
:type :malli.core/tuple-size
647660
:value [2]}]}
@@ -3359,7 +3372,28 @@
33593372

33603373
(testing "it works"
33613374
(is (= User (m/form schema)))
3362-
(is (every? (m/validator schema) (mg/sample schema {:seed 100}))))))
3375+
(is (every? (m/validator schema) (mg/sample schema {:seed 100}))))
3376+
3377+
(testing "explain path"
3378+
(let [exp (m/explain schema {:id 1})]
3379+
(is (results= {:value {:id 1}
3380+
:schema User
3381+
:errors [{:in [:id]
3382+
:path [:id 0]
3383+
:schema :string
3384+
:value 1}]}
3385+
exp))
3386+
(is (form= :string (mu/get-in schema (-> exp :errors first :path)))))
3387+
(let [explicit-ref [:ref #'UserId]
3388+
exp (m/explain explicit-ref 1)]
3389+
(is (results= {:value 1
3390+
:schema explicit-ref
3391+
:errors [{:in []
3392+
:path [0 0]
3393+
:schema :string
3394+
:value 1}]}
3395+
exp))
3396+
(is (form= :string (mu/get-in explicit-ref (-> exp :errors first :path))))))))
33633397

33643398
#?(:clj
33653399
(deftest roundrobin-var-references

test/malli/error_test.cljc

+13-1
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,8 @@
545545
(m/explain [1 2 :foo])
546546
(me/humanize)))))
547547

548+
(def VarSchema [:map [:foo :int]])
549+
548550
(deftest error-definion-lookup-test
549551
(is (= {:foo ["should be an integer"]}
550552
(-> [:map
@@ -629,7 +631,17 @@
629631
(= password password2))]]
630632
(m/explain {:password "secret"
631633
:password2 "faarao"})
632-
(me/humanize {:resolve me/-resolve-root-error}))))))
634+
(me/humanize {:resolve me/-resolve-root-error})))))
635+
636+
(testing "refs #1106"
637+
(is (= {:foo ["should be an integer"]}
638+
(me/humanize
639+
(m/explain [:ref #'VarSchema] {:foo "2"})
640+
{:resolve me/-resolve-direct-error})))
641+
(is (= {:foo ["should be an integer"]}
642+
(me/humanize
643+
(m/explain [:ref #'VarSchema] {:foo "2"})
644+
{:resolve me/-resolve-root-error})))))
633645

634646
(deftest limits
635647
(is (= {:a [["should be an int"]]

test/malli/util_test.cljc

+10-1
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,8 @@
276276
;; LensSchemas
277277
;;
278278

279+
(def Var :string)
280+
279281
(deftest basic-lens-schema-test
280282
(let [re #"kikka"
281283
int? (m/schema int?)]
@@ -333,6 +335,8 @@
333335

334336
[:ref {:registry {::a int?, ::b string?}} ::a] 0 ::a
335337
[:ref {:registry {::a int?, ::b string?}} ::a] 1 nil
338+
[:ref #'Var] 0 #'Var
339+
[:ref #'Var] 1 nil
336340

337341
[:schema int?] 0 int?
338342
[:schema int?] 1 nil)
@@ -439,7 +443,12 @@
439443
(is (form= (mu/get-in (m/schema [:ref {:registry {::a int?, ::b string?}} ::a]) [0]) ::a))
440444
(is (mu/equals (mu/get-in (m/schema [:ref {:registry {::a int?, ::b string?}} ::a]) [0 0]) int?))
441445
(is (form= (mu/get-in (m/schema [:schema {:registry {::a int?, ::b string?}} ::a]) [0]) ::a))
442-
(is (mu/equals (mu/get-in (m/schema [:schema {:registry {::a int?, ::b string?}} ::a]) [0 0]) int?)))
446+
(is (mu/equals (mu/get-in (m/schema [:schema {:registry {::a int?, ::b string?}} ::a]) [0 0]) int?))
447+
448+
(is (form= (mu/get-in (m/schema [:ref #'Var]) [0]) #'Var))
449+
(is (form= (mu/get-in (m/schema [:ref #'Var]) [0 0]) :string))
450+
(is (form= (mu/get-in (m/schema [:schema #'Var]) [0]) #'Var))
451+
(is (form= (mu/get-in (m/schema [:schema #'Var]) [0 0]) :string)))
443452

444453
(deftest dissoc-test
445454
(let [schema [:map {:title "map"}

0 commit comments

Comments
 (0)