Fork me on GitHub
#clojure-spec
<
2017-04-18
>
ikitommi05:04:22

still, I find the below bit unintuitive: without :conform-keys the first one informs of error but the second one does not:

(s/conform
  (s/map-of keyword? keyword?)
  {“key” :value})
; :clojure.spec/invalid

(s/conform
  (s/map-of (s/and (s/conformer keyword) keyword?) keyword?)
  {“key” :value})
; {“key” :value}

didibus08:04:18

@ikitommi Why would a string conform to a keyword?

ikitommi09:04:41

because of the conformer. If I set the :conform-keys it conforms ok as Alex pointed out. But without it, the conform returns invalid data, which feels odd given the s/conform docs: “Given a spec and a value, returns :clojure.spec/invalid if value does not match spec, else the (possibly destructured) value.“.

Alex Miller (Clojure team)12:04:22

Seems like you're ignoring the map-of docstring

Alex Miller (Clojure team)12:04:49

There are several good reasons not to conform the keys by default

pseud12:04:30

what's the point of clojure spec's fdef ? If I check against my specs using pre & post-conditions, I will get failures at the point of invocation, but having defined a function spec doesn't really prevent the function returning a non-compliant value (and I assume the same is true for providing wrong input)

pseud12:04:07

(aside from stubbing dependent functions for tests)

Alex Miller (Clojure team)12:04:26

For use with stest/instrument and stest/check

pseud12:04:30

That's it ? The spec guide hints at fdef providing something for development, I can't temporarily get more feedback during development ?

urbank13:04:08

@pseud Isn't instrument meant for development - you can instrument a function so that it check its input, output when called?

curlyfry13:04:01

instrument only checks input for fdef if I remember correctly

curlyfry13:04:23

But yeah, it's meant to give more feedback during development

luxbock13:04:03

there's https://github.com/jeaye/orchestra if you want to check :ret and :fn as well

mobileink16:04:17

having trouble composing a few simple specs. seems to work until I use the range spec listed in the snippet.

mobileink16:04:40

also, if I compose :oic/core with something that does not include this range spec, it works ok.

arohner16:04:39

is there a way to make check stop on first failure?

mobileink16:04:56

same thing happens with (s/def ::step (s/or :i integer? :n number?))

jfntn16:04:37

Is it possible during tests to have an fdef check its args but skip checking with exercised inputs?

mobileink16:04:18

is this a bug?

(s/def ::foo number?)
(s/def ::bar (s/or :i integer? :n number?))
(s/def ::baz (s/and (s/keys :opt [::foo]) (s/keys :opt [::bar])))
(s/explain ::baz {::foo 1 ::bar 9})
;; In: [:oic.r/bar] val: [:i 9] fails spec: :oic.r/bar at: [:oic.r/bar :i] predicate: integer?
;; In: [:oic.r/bar] val: [:i 9] fails spec: :oic.r/bar at: [:oic.r/bar :n] predicate: number?

seancorfield17:04:07

No. s/and flows the conformed value through subsequent forms.

seancorfield17:04:54

(s/conform (s/keys :opt [::foo]) {::foo 1 ::bar 9}) ;=> #:boot.user{:foo 1, :bar [:i 9]}s/keys conforms all key/values if there are specs for them, not just the keys listed in :req and :opt.

seancorfield18:04:20

You want s/merge here to combine key-specs:

boot.user=> (s/def ::baz2 (s/merge (s/keys :opt [::foo]) (s/keys :opt [::bar])))
:boot.user/baz2
boot.user=> (s/explain ::baz2 {::foo 1 ::bar 9})
Success!
nil

mobileink18:04:44

d’oh! thanks, he mumbled sheepishly.