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
jacklombard 2020-06-11T09:17:11.251700Z

Do you all unit test specs?

Jivago Alves 2020-06-11T13:10:38.251800Z

Never unit tested specs. But I'm using it as part of the test. I'd test it if I was going to release it as a library.

jacklombard 2020-06-11T13:32:36.252Z

for complex specs that i use to validate data, would like to know if the spec is right

avi 2020-06-11T14:11:04.252400Z

That’s… interesting! Because I think I already think of specs as, more or less, akin to tests themselves.

avi 2020-06-11T14:12:05.252600Z

I do of course sometimes find that a spec I’ve written turns out to not quite capture what I had in mind, or a requirement, etc… but I’ve done the same with “traditional unit tests” (i.e. example tests) …

misha 2020-06-11T15:53:15.255900Z

can I express "this key is optional, but if is in map - that key has to be there too, " as s/keys out of the box? with some combination of :opt :req and or like (s/keys :req [(or :a/foo :a/bar)]) or something? Or should I s/and it?:

(s/and
      (s/keys :opt [:a/foo :a/bar])
      (fn [m]
        (let [present (partial contains? m)
              missing (complement present)
              ks [:a/foo :a/bar]]
          (or 
            (every? present ks)
            (every? missing ks)))))

alexmiller 2020-06-11T15:55:43.256400Z

s/and'ing a predicate is prob best

misha 2020-06-11T15:56:36.257100Z

is it s/and in spec2 for the same use case?

misha 2020-06-11T15:57:31.257300Z

thank you

alexmiller 2020-06-11T15:59:26.257600Z

yeah, I would do the same in spec 2

alexmiller 2020-06-11T15:59:52.258100Z

or rather I would probably make 2 different s/selects for the same s/schema

👍 1
alexmiller 2020-06-11T16:00:01.258300Z

s/keys is probably going away in spec 2

Jivago Alves 2020-06-11T16:08:18.258600Z

I use spec to help me to parse some data but I'm testing the function that does that. The fact I'm using a spec is just a implementation detail. At least, that was most of my use cases.

avi 2020-06-11T16:46:22.258800Z

Ah, I see, yeah. That makes sense.

avi 2020-06-11T16:46:33.259Z

In that case, yes, I would probably write some example tests.

dev.4openID 2020-06-11T17:58:49.259800Z

@alexmiller Over what time-frame are you anticipating spec 2 to come out?

dev.4openID 2020-06-11T17:59:29.260300Z

I am assuming it will be spec.alpha2 right?

seancorfield 2020-06-11T18:25:45.262Z

@dev.4openid I'm not Alex but my understanding is that Spec 2 will eventually become just clojure.spec when it is ready to come out of alpha -- and there's no timeframe for it yet, based on what I've seen/heard, since a lot of things are still being designed/revised.

seancorfield 2020-06-11T18:25:50.262200Z

The repo is here https://github.com/clojure/spec-alpha2

seancorfield 2020-06-11T18:28:01.264700Z

For a while, I kept a branch of our codebase current against that repo but it involved quite a few changes (and it had to keep changing as Spec 2 changed). I stopped tracking it back in ... September/October I think? Our approach going forward -- once Spec comes out of alpha -- will be to use the new Spec for new code we write and slowly, over time, migrate our Spec 1 code to "Spec 2" as needed. Spec 1 will stay available as-is "forever" so folks can stay on the old version if they don't want to migrate.

seancorfield 2020-06-11T18:28:14.264800Z

My approach to developing complex Specs is to have a (comment ,,,) form under the Specs with expressions in it that I use to test validation, conformance, and generation.

seancorfield 2020-06-11T18:28:56.265Z

I also make sure to "test" each individual part of a Spec (so I can catch generation problems early -- debugging generation problems in a large Spec is no fun!).

dev.4openID 2020-06-11T18:35:09.265300Z

Thx

alexmiller 2020-06-11T18:38:41.267Z

I’m deep in something else right now, but hoping to pop the stack back to that soon. Not sure, prob mostly gated in rework of function specs which rich has been hammocking on

1
alexmiller 2020-06-11T18:39:05.267600Z

I’m hoping it will just be clojure.spec

plins 2020-06-11T21:06:12.269500Z

how can I create a generator from an arbitrary function? here’s a silly example but It would be something like (s/def ::name (s/spec string? :gen (constantly "Margaret"))) not sure if possible but id like to combine it with a lib like https://github.com/paraseba/faker to generate test data

alexmiller 2020-06-11T21:29:13.269800Z

s/with-gen

🙏 1
plins 2020-06-12T13:14:59.290800Z

whats the difference between those two?

(s/def ::name (s/with-gen string? #(gen/return "Margaret")))
(s/def ::name (s/spec string? :gen #(gen/return "Margaret")))

alexmiller 2020-06-12T13:15:22.291Z

effectively, not much

plins 2020-06-12T13:15:43.291200Z

any one is preferred?

alexmiller 2020-06-12T13:16:28.291400Z

not really. I usually do the first one.

plins 2020-06-12T13:16:41.291600Z

thanks for the info 🙂