(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 surprisinggiven that the :corp/employee
spec doesn't say anything about ice cream
That is by design in Spec — and the reference docs on http://clojure.org talk about that. I think the rationale may do too.
thanks Sean - i'll take a look
https://clojure.org/guides/spec#_entity_maps 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.”
yeah, there it is. checks that every registered key has a conforming value. good to know