Fork me on GitHub
#clojure-spec
<
2017-07-06
>
gfredericks01:07:26

let in particular is a macro, and the only macro of the test.check generators

gfredericks01:07:42

and it looks like the patch doesn't lazy-load it, it completely reimplements it, with different behavior

gfredericks01:07:35

I'm not sure if lazy-loading a macro is even possible

jimmy10:07:52

hi guys, is there any good way to test all fdef in my project instead of using clojure.spec.test.alpha/check for each one explicitly.

rickmoynihan10:07:31

@nxqd: guessing you mean fdef not fspec but if you call check with 0-args it should run all var specs that have been loaded

jimmy10:07:36

rickmoynihan: really, nice. I will give it a try. Thanks

jimmy10:07:21

nice, it works 🙂

jimmy10:07:25

btw, does stest/check run all the tests in parallel ?

rickmoynihan10:07:46

no idea - guessing not

jimmy09:07:20

@U06A9614K thanks for your info ( And sorry for my lazy ass ... )

rickmoynihan10:07:24

Hmmm… wondering if generator errors like ExceptionInfo Couldn't satisfy such-that predicate after 100 tries. clojure.core/ex-info (core.clj:4725) would be better if they told you which generator/spec failed to generate a value. The stack trace doesn’t seem to contain many useful clues.

rickmoynihan10:07:01

Would be nice if the ex-info data contained something like {:generator #function[foo.bar/bar-gen] :spec :foo.bar/valid-bar?}

gfredericks11:07:58

rickmoynihan: test.check didn't provide a mechanism for this until 0.10.0-alpha1; now that that's released, clojure.spec can be modified to make use of it

rickmoynihan11:07:47

Cool! One thing I’m not quite clear on is the precise relationship between clojure.spec and test.check. I obviously understand spec uses it, and wraps it via the lazy-load mechanism. But is spec promising to expose everything inside test.check (plus its own stuff), or is it deciding on what to expose/not-expose? If so how are those decisions being made?

gfredericks11:07:36

the exposing-vs-not distinction isn't very impactful since you can reference test.check generators directly in your spec usage; I don't think that was ever disintended

gfredericks11:07:45

I don't know about why some generators don't have proxy versions in spec (other than let)

rickmoynihan11:07:44

Yeah, I’ve been thinking I might be better just using test.check.generators rather than specs lazy loaded ones… What would the disadvantage be of doing that? Presumably I’d have to make sure the non-lazy-loaded generators were only ever included in dev envs?

rickmoynihan11:07:17

It really frustrates me that the lazy loaded ones don’t have docstrings.

gfredericks11:07:21

"have to" is strong, depends on how much you care about your production deps

gfredericks11:07:28

that sounds fixable

rickmoynihan11:07:34

> depends on how much you care about your production deps Yeah, I guess I don’t when its an app. A library should probably be more conservative though.

gfredericks11:07:45

oh definitely, yes

gfredericks11:07:58

but yeah, you could stick the generators in /test or /dev or something, and then have your own sort of lazy loading thing if you need to reference them from /src

rickmoynihan11:07:55

its a shame about let not being included. It feels much nicer than fmap and others.

rickmoynihan11:07:12

but understand the macroness of it complicates it

gfredericks11:07:44

yeah; I suppose you could have a weird thing where the macro tries to require test.check and if it fails it expands to exception-throwing code

rickmoynihan11:07:42

That seems like a nice idea

rickmoynihan11:07:36

As an aside are you involved at all in the development of clojure.spec beyond your work on test.check?

gfredericks11:07:37

not beyond the details of the integration

rickmoynihan12:07:31

Thanks for explaining, and all your work on test.check. btw, I updated the CLJ-1989 with your comments on let. Hope you don’t mind, and that they accurately reflect your opinion: https://dev.clojure.org/jira/browse/CLJ-1989?focusedCommentId=46211#comment-46211

gfredericks12:07:34

only nitpick is that the macro wouldn't expand to a require call, it would actually call require before constructing any expanded code

gfredericks12:07:35

e.g.,

(defmacro let [& args] (try (require ...) `(...) (catch Exception e `(throw ...))))

rickmoynihan12:07:06

yeah fair point, that’s what I meant… will update the ticket

rickmoynihan10:07:10

Hmm also just noticed a small problem with check which is that you can’t both run it on all fdefs and provide custom options

rickmoynihan10:07:34

ahh its ok checkable-syms is exposed so can do it by hand

rickmoynihan12:07:45

@gfredericks: Do you know if test.check 0.10.0-alpha2 is compatible with the latest clj 1.9 / spec?

peeja17:07:02

Are we not supposed to be able to add generators to predicates? Is that a closed set?

peeja17:07:30

(That is, if I define a predicate, am I not able to add a generator for it?)

wilkerlucio18:07:02

@peeja I'm not sure what you asked, but I think you might want to check (s/with-gen)

wilkerlucio18:07:17

then you can set any generator you want to your spec, no mater the predicate

peeja18:07:37

Right, I mean I want to register that as the generator to use everywhere (if it's not overridden)

hlship18:07:51

I'm missing something about combining s/and and s/or: ` (s/def ::identifier (s/and (s/or :keyword simple-keyword? :symbol simple-symbol?) graphql-identifier?))

wilkerlucio18:07:04

@peeja what you can do is define a spec, and then re-use that spec instead, eg:

wilkerlucio18:07:49

(s/def ::my-spec (s/with-gen my-pred? #(gen-fn)))

(s/def ::other-spec ::my-spec)
(s/def ::another-one (s/and ::my-spec other?))

wilkerlucio18:07:01

then it will inherit the generator

wilkerlucio18:07:54

@hlship on the and case, the next predicate will receive the conformed version from the previous one

hlship18:07:23

(s/explain ::identifier :foo) java.lang.ClassCastException: clojure.lang.MapEntry cannot be cast to clojure.lang.Named ` I'm guessing that the entire map conformed by s/or (e.g., {:keyword :foo}) is being passed to graphql-identifier? (which expects a String, Keyword, or Symbol). So, what's the correct way to deal with this situation? I'd rather not do the identifier check first. I guess I could change graphql-identifier? to expect the conformed result from the s/or?

wilkerlucio18:07:43

so, your graphql-identifier? will receive something like {:keyword :bla} or {:symbol some-sym}

peeja18:07:56

@wilkerlucio Yeah, that makes sense. I was hoping to do it straight on the predicate because it looks like a nicer API, but if that's not how it's meant to work, then that works.

hlship18:07:08

It seems like it gets the Map$Entry, e.g, [:symbol foo].

wilkerlucio18:07:54

@peeja if you look at the sources for the spec generators, it uses a map to convert from symbol -> generator, I guess we can suggest this to be replaced with a multi-method making it extensible from the outside

hlship18:07:55

ok, I'm on that track.

peeja18:07:28

Is there any way to use with-gen without blowing away generator overrides?

peeja19:07:18

It seems like it can't, since it doesn't have access to the overrides like gen* does

peeja19:07:49

Are we meant to define our own macros a la keys/`map-spec-impl` etc?