metosin / spec-tools

Clojure(Script) tools for clojure.spec

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.