Fork me on GitHub
#clojure-spec
<
2018-08-31
>
misha09:08:06

sanity check: how do you share specs between libraries/modules-of-app?

Ulrich09:08:25

Help! I need my generated test data to have unique ids in various places (not uuids, though, just positive integers). I hacked a stateful generator (using an atom) for that which cannot be the right way…? How do I do stateful generators? exercise and sample seem to have no way to allow a state…

Ulrich09:08:48

@misha require the namespace - it’s magic

misha09:08:38

meaning: package it as a shared lib itself?

Ulrich09:08:33

maybe i misunderstood. If you want to use specs defined in one namespace, just require that namespace where you wish to use the spec. If it is in a lib the declaring namespace should be in the lib’s jar … Is that what you asked?

mpenet09:08:37

@ulrich.becker you can do an ugly hack with gen/fmap with a closed around atom and a (gen/return nil)

mpenet09:08:44

there's probably a better way tho

mpenet09:08:59

something like that: (gen/sample (let [a (atom 0)] (gen/fmap (fn [_] (swap! a inc)) (gen/return nil))))

Ulrich09:08:07

(gen/no-shrink (gen/fmap (fn [_] (swap! unique-id inc))
                                            (gen/return 0))

Ulrich09:08:12

like this?

codonnell09:08:21

@misha we share specs between a backend clojure repo and a frontend clojurescript repo at my work by putting the specs in a third repo that has the specs in cljc files. It works pretty well IMO.

mpenet10:08:14

but messing with (gen/return nil) is usually a smell

mpenet10:08:35

this kind of breaks the purpose of using prop testing in the first place

Ulrich10:08:18

But the need for unique ids is very real, somebody must have a better solution? (except using UUIDS)

mpenet10:08:31

why uuids are bad?

Ulrich10:08:06

not bad just ugly…

mpenet10:08:06

you can also use something like gen/vector-distinct of ints

Ulrich10:08:27

nope vector/distinct does not work

mpenet10:08:47

right, it would return a collection, not really useful

mpenet10:08:35

I guess another alternative is to let the random part untouched and keep track of values used in one way or another, I guess again you can do that with an atom or something. Still feels a bit odd

mpenet10:08:02

something like that? (let [bin (atom #{})] (gen/such-that (fn [x] (and (not (get @bin x)) (swap! bin conj x)) ) (gen/int)))

mpenet10:08:36

but that atom will grow, and that might hurt

mpenet10:08:28

it can also fail to generate valid values after a while

mpenet10:08:04

so yeah, (g/return nil) 🙂

mpenet10:08:59

just for fun another dirty trick: (gen/fmap hash (gen/uuid)), but you would get neg values, so (gen/sample (gen/fmap #(bit-and (hash %) 0x7FFFFFFF) (gen/uuid))) would work (with potential collisions tho)

😂 4
misha11:08:33

@codonnell will sending specs as an edn make any sense?

codonnell22:08:17

I'm not sure what you mean by this. Could you elaborate?

misha06:09:48

front-end sends "back-end, give me your specs" back-end responds with subset of spec registry as edn front-end reads, evals

misha06:09:43

this skips fron-end re-compilation if specs change

codonnell12:09:18

I suppose you could do this if you need to update specs at runtime. I haven't personally run into a scenario where building a static registry at compile time was insufficient.

lilactown15:08:42

spec-tools is super impressive

lilactown15:08:59

general question about spec: one of the things that keeps coming up for me, is that I’d like a language to describe a schema or shape of data that I would need to translate to some other schema language (e.g. GraphQL, dynamoDB, etc.). As a spec neophyte, my first instinct/desire is to reach for clojure.spec as the schema language, and somehow convert the spec to the other schema language. But the more I think about it, the more it feels like spec is much better setup to be the tool to do the conversion, and it’s left up to me to create my own schema language in Clojure. Which one is correct?

dadair15:08:41

I think there was some project that went from spec to various schema formats, but I can’t seem to recall it right now

dadair15:08:22

Or maybe it was datomic schema to other schema

lilactown15:08:28

I was just looking at spec-tools, which can convert specs to JSON Schema and Swagger Schemas

lilactown15:08:53

which might work for my use case, but then I need to write JSON Schema => GraphQL or DDB or datomic…