clojure-spec

greg 2023-06-01T12:17:16.699839Z

Hi, I noticed this behaviour that even if the keyword is not explicitly included in s/key, it is implicitly included:

(s/def :person/name string?)
(s/def :person/surname string?)
(s/def :person/email string?)
(s/def ::profile
  (s/keys :req [:person/name
                :person/surname]))

(comment
 (s/explain ::profile {:person/name "Tom"
                       :person/surname "Wilkins"
                       :person/age 29})
 ; => Success!
 
 (s/explain ::profile {:person/name "Tom"
                       :person/surname "Wilkins"
                       :person/email nil})
 ; => nil - failed: string? in: [:person/email] at: [:person/email] spec: :person/email 
In the above example :person/email is not included in profile but the spec is complaining about it. Can it be disabled?

Alex Miller (Clojure team) 2023-06-01T13:09:19.587729Z

This is by design (see the docstring of s/keys)

greg 2023-06-01T13:20:30.730869Z

Thank you @alexmiller, I read it. Can I compose a spec to validate a map in some other way so these namespaced spaces are not implicitly included?

greg 2023-06-01T13:22:35.261599Z

The problem I'm facing is that I can't control the data I receive, and in the codebase I work with, there is lots of specs namespaced by category, here and there, often duplicated (another issue with overriding entries in registory). I'm trying to tackle these issues one by one, instead of making big changes in one go. One of these namespace specs conflicts with keys used in maps I try to validate.

Alex Miller (Clojure team) 2023-06-01T13:56:25.207179Z

In short, no, with s/keys. You can instead select-keys the data to just the keys you want to check before validating

greg 2023-06-01T14:22:10.168369Z

Yes, unfortunately this strategy would not work with instrumenting functions 😞

greg 2023-06-03T01:22:54.793309Z

Ok, I managed to find a workaround to this problem. What I did was writing a wrapper to wrap Malli schema under Spec protocol. That map validation is performed by Malli despite the instrumentation is executed via Spec api. This way I managed to avoid s/keys behaviour. The other issue I had in the same repo was that these subspecs (`:person/name`, :person/surname , etc) were defined multiple times in different parts of the project resulting in overriding global registry. Thanks to that wrapper I also managed to avoid that problem.