Fork me on GitHub
#clojure-spec
<
2023-11-08
>
cfleming03:11:04

I have a case where conform returns :clojure.spec.alpha/invalid, but explain returns “Success!“. Am I missing something?

(def test-data (rest '(defn F "s||C_)C^?" {} ([[& {:keys [], :strs [a2p*1.+lNz3+9.-fc? !2_!T2*8_.aw7.H14*7 B_-T*E5+3lKy-gE Ca++-F*_G58!7+? VM.3-E**S*R+09eW f-F?J-D_?r*xdjb.D]} :as kQ.zi] & yeok5+8+3_O_.mXJZ] "MyN-Rmu[Y" nil :Wd--IU9M*! ":*ULe,h" :p-:?6+__S- J91*) "EcO")))
=> #'cursive.extensions.specs/test-data
(s/conform :clojure.core.specs.alpha/defn-args test-data)
=> :clojure.spec.alpha/invalid
(s/explain :clojure.core.specs.alpha/defn-args test-data)
Success!

cfleming03:11:36

Yeah that looks similar.

cfleming03:11:38

I’ve also found that generating code samples using the core specs doesn’t work well - it does work sometimes but not others, and I’m not sure why:

(gen/sample (s/gen ::core/bindings))
Error printing return value (ExceptionInfo) at clojure.test.check.generators/fn (generators.cljc:435).
Couldn't satisfy such-that predicate after 100 tries.

cfleming03:11:45

I’ve commented on the ask with some cases. Looks to me like the cases should be valid, so perhaps the bug is in conform.

hiredman03:11:29

The way s/and composes for generators is unlikely to get you a working generator for more complex specs, basically it takes the generator first spec, and then uses the rest of the specs in the and as a predicate to filter out generated values that don't match the entire s/and

hiredman03:11:02

It is limited to 100 tries

cfleming03:11:48

Hmm, I see. Thanks for the explanation.

hiredman04:11:30

I think there might be something you can bind to increase such-that's limit, but in general if you hit it you usually need to write a custom generator instead of relying on s/and's composed one

cfleming04:11:05

Is there a good way to figure out which spec is problematic? And can I override generators for the built-in specs?

cfleming04:11:18

The stacktrace didn’t seem especially useful.

hiredman04:11:03

spec has a way to define specs with custom generators, which is helpful for your own specs, for existing specs I sort of recall some mechanism for overriding but I am not sure

hiredman04:11:18

as far as figuring out which spec, I don't know

cfleming04:11:56

Ok, thanks. I’m currently generating these forms with my own code, and then just checking the result against the spec.