Fork me on GitHub
#clojure-spec
<
2021-12-01
>
johanatan00:12:06

yea, i had a few of those too but since these are registered "globally" they're fair game to my (spec-based) fuzzer. so, i'm making the ones in my project "defensive" against this (although it should never happen from production code)

johanatan00:12:54

i.e., this is where the inputs are coming from (with the one exceptional case i've found [which crashes] excluded):

(s/cat :spec (s/with-gen qualified-keyword? #(gen/elements
                                                 (clojure.set/difference
                                                  (set (keys (s/registry)))
                                                   #{::s/kvs->map})))
        :val any?)

wontheone108:12:50

Hello! I made a function to return specs depending on arguments.

(defn- search-schema-spec-for-of-and-defaultValue [of defaultValue]
  (s/keys :req-un [:build-api.search-schema/key
                   of
                   :build-api.search-schema/valueType
                   :build-api.search-schema/cardinality]
          :opt-un [:build-api.search-schema/of
                   defaultValue
                   :build-api.search-schema/doc]))
It’s called like the following,
(search-schema-spec-for-of-and-defaultValue
 :build-api.search-schema.listing/scope :build-api.search-schema.enum.one/defaultValue)
But I get the following error
Unexpected error (AssertionError) macroexpanding s/keys at (src/sharetribe/build_api/routes.clj:136:3).
Assert failed: all keys must be namespace-qualified keywords
(every? (fn* [p1__1917#] (c/and (keyword? p1__1917#) (namespace p1__1917#))) (concat req-keys req-un-specs opt opt-un))
I just wanna factor out common parts and make different specs based on of and defaultValue as they are the differentiator, any advice on how to achieve?

vlaaad09:12:11

use macros or eval instead of defn — s/keys is a macro

wontheone110:12:42

Thanks! @U47G49KHQ I defined common spec separately and combined with s/and and this seems to work good enough for me!

(def build-api-search-schema-common-spec
  (s/keys :req-un [:build-api.search-schema/key
                   :build-api.search-schema/valueType
                   :build-api.search-schema/cardinality]
          :opt-un [:build-api.search-schema/of
                   :build-api.search-schema/doc]))

(s/and build-api-search-schema-common-spec (s/keys :req-un [:build-api.search-schema.listing/scope]
                                                     :opt-un [:build-api.search-schema.enum.one/defaultValue]))

...etc...

colinkahn16:12:39

If you’re combining map specs you might want to look at s/merge as well

👍 1