Fork me on GitHub
#clojure-spec
<
2017-01-31
>
rmuslimov02:01:31

Hello, I have newbie question for spec. Let’s suppose I have map {"first-name" “name”} , can you please show the spec which check key (= ”first-name”) and if the is string. Thanks

rmuslimov02:01:48

Thing I cannot understand here, that if I had keyword instead of “first-name” everything would be trivial:

(s/def :first-name string?)
(s/valid? (s/keys :req-un [:first-name]) {:first-name “name”}) ;=> true
But if “first-name” I cannot attach spec to it

joshjones02:01:24

if you are doing this just for experimentation -- then

(s/def ::str-str-map #(string? (get % "first-name")))
(s/valid? ::str-str-map {"first-name" "josh"})
but in practice, this only makes life difficult. there's not a way i know of to do this cleanly, as spec is not trying to promote this type of behavior

luxbock09:01:15

it's quite difficult to figure out what other options stest/check accepts in the :clojure.spec.test.check/opts key

luxbock09:01:58

the doc string says: "::stc/opts opts to flow through test.check/quick-check" but it's not really clear which function this refers to

luxbock09:01:10

I can go to the source and see it calls stest/check-1, which calls a private function stest/quick-check which calls clojure.spec.gen/quick-check which calls clojure.test.check/quick-check

luxbock09:01:02

which tells me the keys are :seed and :num-tests, so as far as I can tell :seed is the only other option it accepts

luxbock09:01:34

I wish the doc-string for stest/check just told me this right away because I might not have clojure.test.check required and so I need to dig quite deep to find the information

luxbock09:01:57

the same goes for s/coll-of which tells me it accepts the same options as every, rather than just telling what those options are

thheller11:01:00

so I have a hard time composing specs due to its macro nature

thheller11:01:28

ie. anything that creates a spec must be a macro

thheller11:01:12

I can't have a function (validate-a-thing TypeOfThing) that returns a spec

thheller11:01:08

it must be a macro that generates (s/spec #(instance? TypeOfThing %))

thheller11:01:42

or am I missing something obvious? using instance? as a basic example my spec is actually a bit more complex than that

thheller11:01:53

(defn validate-a-thing [type] (s/spec #(instance? type %)) works well enough but the error suffers as it is always fails predicate: (instance? type %)

thheller11:01:53

can't find an obvious way to provide custom explain logic, don't care about the gen part in this case

nblumoe11:01:01

Shouldn’t my generator be good enough to be used to check the corresponding function against it’s spec?

(frequencies (map (partial s/valid? (s/and ::matrix
                              ::non-zero-row-sums)) (gen/sample (matrix-gen) 100)))
;; => {true 27, false 73}
I end up with ExceptionInfo Couldn't satisfy such-that predicate after 100 tries. clojure.core/ex-info (core.clj:4725) again and again.

dergutemoritz15:01:09

@thheller Yeah you are right, validate-a-thing needs to be a macro to achieve what you want

dergutemoritz15:01:28

@thheller I don't think you're missing anything

uwo19:01:07

I’d really appreciate some feedback on this: https://groups.google.com/forum/#!topic/clojure/wwJVJKtxps8

joshjones20:01:58

this exact situation has come up several times here @uwo — unfortunately, there’s not much you can do other than what you’ve already identified, at least, none that I’m aware of. The reality is that you do not have one set of billed-charges; you have two, which means you will need to spec two, whether that’s through a multi-spec or explicit naming

joshjones20:01:08

do you have more levels of nesting than what you’ve shown?

uwo21:01:05

@joshjones thanks, and yes, many many levels of nesting