Fork me on GitHub
Michael Stokley22:04:26

(s/def :corp/employee
  (s/keys :req [:employee/first-name]))

(s/def :employee/first-name string?)

(s/def :favorite/ice-cream #{:chocolate :vanilla})

(e/expound :corp/employee {:employee/first-name "michael"
                           :favorite/ice-cream :strawberry})

;; -- Spec failed --------------------

;; {:employee/first-name ...,
;;  :favorite/ice-cream :strawberry}
;; ^^^^^^^^^^^

;; should be one of: :chocolate, :vanilla

;; -- Relevant specs -------

;; :favorite/ice-cream:
;; #{:chocolate :vanilla}
;; :corp/employee:
;; (clojure.spec.alpha/keys :req [:employee/first-name])

;; -------------------------
;; Detected 1 error
I find this pretty surprising

Michael Stokley22:04:57

given that the :corp/employee spec doesn't say anything about ice cream


That is by design in Spec — and the reference docs on talk about that. I think the rationale may do too.

Michael Stokley22:04:28

thanks Sean - i'll take a look

seancorfield22:04:24 says “When conformance is checked on a map, it does two things - checking that the required attributes are included, and checking that every registered key has a conforming value. We’ll see later where optional attributes can be useful. Also note that ALL attributes are checked via keys, not just those listed in the :req and :opt keys. Thus a bare (s/keys) is valid and will check all attributes of a map without checking which keys are required or optional.”

Michael Stokley22:04:57

yeah, there it is. checks that every registered key has a conforming value. good to know