clojure-spec

About: http://clojure.org/about/spec Guide: http://clojure.org/guides/spec API: https://clojure.github.io/spec.alpha/clojure.spec.alpha-api.html
johnjelinek 2020-10-13T00:19:15.096600Z

oh, hmm:

; (#:scratch{:keys [scratch/total prices]}) - failed: Extra input at: [:fn-tail :arity-1 :params] spec: :clojure.core.specs.alpha/param-list
#:scratch{:keys [scratch/total prices]} - failed: vector? at: [:fn-tail :arity-n :params] spec: :clojure.core.specs.alpha/param-list

2020-10-13T03:05:46.096900Z

is there an fdef that works for multi-methods?

2020-10-13T14:21:55.099300Z

thank you!

johnjelinek 2020-10-13T03:13:20.097300Z

ya, dunno what was up with that destructuring, but this works:

(s/def ::m (s/and (s/keys :req [::total ::prices])
                    #(= (::total %) (reduce + (::prices %)))))

johnjelinek 2020-10-13T03:33:57.097700Z

ah-ha! I think I got it! thx @alexmiller!

johnjelinek 2020-10-13T03:35:50.098200Z

I did something like this:

(s/def ::m (s/and ::total=prices (s/schema [::prices ::total])))

alexmiller 2020-10-13T03:49:25.098300Z

no, but you can pull the dispatch function out and spec that

alexmiller 2020-10-13T03:50:18.099Z

just as a heads up, I do not consider spec 2 to be ready for use and the api may change before release

👍 1
vlaaad 2020-10-13T21:11:18.101Z

I have the following spec:

(s/def ::grid
  (-> (s/keys :opt-un [::grid])
      (s/coll-of :kind vector? :min-count 1)
      (s/coll-of :kind vector? :min-count 1)))
How do I do generative testing with this kind of spec? any attempt to generate an example of ::grid makes my OS super laggy until I kill the JVM process...

alexmiller 2020-10-13T21:37:17.101500Z

that's not a valid spec? what are you expecting -> to do there?

alexmiller 2020-10-13T21:39:03.102600Z

I guess maybe it would work in the spec 1 macrology, but I find that very confusing to parse (and it won't in spec 2 I think)

alexmiller 2020-10-13T21:39:41.103100Z

in general, setting :gen-max is useful for coll specs though to bound nested coll size

vlaaad 2020-10-14T07:04:40.107500Z

It did help, thank you!

kenny 2020-10-13T22:27:56.104600Z

We often build our own spec "types" by doing something like this.

(defmacro my-custom-map
  [kpred vpred]
  (let [form `(s/map-of ~kpred ~vpred)]
    `(s/with-gen ~form #(gen/fmap identity (s/gen ~form)))))

(s/def ::k string?)
(s/def ::v string?)

(s/def ::my-custom-map (my-custom-map ::k ::v))
This, however, does not play nice with :gen overrides.
(gen/generate (s/gen ::my-custom-map {::k #(s/gen #{"a" "b"})}))
=>
{"3" "b4tq9FeW6Gt",
 "8h" "o47F763P0v5B63sA52c4xu1FN",
...}
Is there a better way of doing this that works with :gen overrides?

kenny 2020-10-14T16:07:08.110900Z

😢

kenny 2020-10-14T16:07:09.111100Z

https://clojure.atlassian.net/browse/CLJ-2095

kenny 2020-10-13T22:35:45.104700Z

Oh, duh - I think this is a perfect case for s/conformer

kenny 2020-10-13T23:15:13.105300Z

It's like with-gen needs to take an argument with :gen overrides or implicitly use a dynamic variable.

kenny 2020-10-13T23:41:43.105500Z

Can't figure out any way around this other than to override the top level spec (in my example ::my-custom-map). That can be quite painful with complex specs.