Skip to content

Commit b2db1a6

Browse files
committed
fix: explain :path of ref schemas
The path from a [:ref ::kw] or a [:ref #'Var] to the referred schema is [0 0] due to the intermediate -pointer. See additions to get-in-test. Thus the -explainer of a -ref-schema needs to add [0 0] to the path, instead of the previous [0]. This mirrors the [0 0] already present in the -walk of -ref-schema. fixes #1106
1 parent 5941195 commit b2db1a6

File tree

4 files changed

+60
-5
lines changed

4 files changed

+60
-5
lines changed

src/malli/core.cljc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1709,7 +1709,7 @@
17091709
(let [validator (-memoize (fn [] (-validator (rf))))]
17101710
(fn [x] ((validator) x))))
17111711
(-explainer [_ path]
1712-
(let [explainer (-memoize (fn [] (-explainer (rf) (conj path 0))))]
1712+
(let [explainer (-memoize (fn [] (-explainer (rf) (into path [0 0]))))]
17131713
(fn [x in acc] ((explainer) x in acc))))
17141714
(-parser [_] (->parser -parser))
17151715
(-unparser [_] (->parser -unparser))

test/malli/core_test.cljc

+36-2
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,19 @@
624624

625625
(testing "ref schemas"
626626

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

33343347
(testing "it works"
33353348
(is (= User (m/form schema)))
3336-
(is (every? (m/validator schema) (mg/sample schema {:seed 100}))))))
3349+
(is (every? (m/validator schema) (mg/sample schema {:seed 100}))))
3350+
3351+
(testing "explain path"
3352+
(let [exp (m/explain schema {:id 1})]
3353+
(is (results= {:value {:id 1}
3354+
:schema User
3355+
:errors [{:in [:id]
3356+
:path [:id 0]
3357+
:schema :string
3358+
:value 1}]}
3359+
exp))
3360+
(is (form= :string (mu/get-in schema (-> exp :errors first :path)))))
3361+
(let [explicit-ref [:ref #'UserId]
3362+
exp (m/explain explicit-ref 1)]
3363+
(is (results= {:value 1
3364+
:schema explicit-ref
3365+
:errors [{:in []
3366+
:path [0 0]
3367+
:schema :string
3368+
:value 1}]}
3369+
exp))
3370+
(is (form= :string (mu/get-in explicit-ref (-> exp :errors first :path))))))))
33373371

33383372
#?(:clj
33393373
(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)