Welcome! Please see the About page for a little more info on how this works.

0 votes
in Spec by
Some kinds of operations on specs are currently hard to implement as there is no uniform way to find what "child" specs are being composed by a spec. Examples:

* Dependency analysis
* Deep describe (show all specs used by a top-level spec)
* Detection of missing or invalid spec names

For example, given:


(s/def ::user-id int?)
(s/def ::user (s/keys :req [::userid])) ;; note misspelling
(s/valid? ::user {::userid "Jim"}) ;; => true but expect false


And the means to determine the "child" specs of ::user, a linter could check whether all of the keys in s/keys are specs that have been defined.

*Workarounds:*

1. {{form}} can be used to get the original spec form, but that must then be further interpreted (and is missing the original lexical environment in which it was created). Example attempt: https://gist.github.com/ericnormand/6cfe6809beeeea3246679e904372cca0
2. Spec form specs (CLJ-2112) are not available yet, but could be used to get a parsed representation of specs, which would still require some processing but would at least have known forms.

*Proposed:*

Add a mechanism to get the "child" specs a spec is composed of. Each spec implementation could then choose how to implement this in the appropriate way.

3 Answers

0 votes
by

Comment made by: ericnormand

I forgot to add this proposal:

Proposal

I propose that we add a children* method to the Spec protocol. It should return a collection of specs directly referred to. The specs in the collection should be a keyword (if it is referred to by name), an instance of Spec (for nested specs), or some other value valid as a spec (such as a fn).

0 votes
by

Comment made by: alexmiller

Rewrote title and some of the description to be less dependent on implementation details (which may change) and more about the problem at hand.

0 votes
by
Reference: https://clojure.atlassian.net/browse/CLJ-2208 (reported by ericnormand)
...