strip-extra-keys-transformer not working with s/or
Biserkov opened this issue · comments
Given the following specs
(ns or-spec-bug
(:require [clojure.spec.alpha :as s]
[spec-tools.core :as st]))
(s/def ::car (st/spec (s/keys :req-un [::doors])))
(s/def ::bike (st/spec (s/keys :req-un [::wheels])))
(s/def ::vehicle (st/spec (s/or :car ::car
:bike ::bike)))
(def chevy {:doors 4})
(st/conform ::vehicle chevy)
=> [:car {:doors 4}]
Since chevy
is a car
which is also a vehicle
, I would expect coerce
with strip-extra-keys
to return the same for car
and vehicle
but it doesn't:
(st/coerce ::car chevy st/strip-extra-keys-transformer)
=> {:doors 4}
(st/coerce ::vehicle chevy st/strip-extra-keys-transformer)
=> {}
That's clearly a bug, should be easy to fix.
Btw, there is CLJ-2251 that would enable sane coercion for spec. E.g. run the transformations from inside the spec, not outside (via s/form
walking) like we have to do now.
With or, there is currently no check whether the coerced value is correct, it only stops if the value has been changed, otherwise, takes the last value. For this to work as expected, it should do an extra check for the validity of the value and take the first value which is valid, like the actual s/or
works.
(s/conform (s/or :int int? :string string? :string2 string?) "1")
; => [:string "1"]
So, there should be a validity check against the results of the spec-tools.parse/parse-spec
results. It's just work, but I'm busy right now, PR would we welcome.