This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-08-11
Channels
- # admin-announcements (1)
- # aws (2)
- # beginners (32)
- # boot (147)
- # capetown (1)
- # cider (11)
- # cljs-dev (45)
- # cljsrn (57)
- # clojure (187)
- # clojure-russia (5)
- # clojure-spec (97)
- # clojure-uk (33)
- # clojurescript (33)
- # cloverage (17)
- # clr (4)
- # conf-proposals (93)
- # core-async (6)
- # cursive (9)
- # data-science (1)
- # datomic (24)
- # defnpodcast (1)
- # devcards (3)
- # emacs (3)
- # hoplon (95)
- # jobs (1)
- # off-topic (7)
- # om (97)
- # onyx (32)
- # overtone (1)
- # parinfer (4)
- # pedestal (1)
- # proton (1)
- # protorepl (13)
- # re-frame (4)
- # reagent (10)
- # specter (14)
- # untangled (40)
@alexmiller: super useful screencast thanks again! One thing I've not quite grokked yet is the full relationship between spec and test.check... I understand it's a dev time dependency for the generators... but should you ever be using raw clojure.test generator functions? Or should you use spec as a wrapper or use both?
I noticed that spec lazy-loaded test.check underneath too... not sure what the purpose of that is
spec.gen relies on test.check and exposes most of its generator functions
This anything that uses generators will require a dependency on test.check (we expect that to primarily be a test time dependency)
spec.gen wraps those functions to dynamically load them though, allowing you to build generators without incurring a load-time dependency on test.check
So you should always prefer using spec.gen as that lets you use specs in other ways without incurring that dependency
Maybe this itself would be a good blog topic :)
man we need some kind of canonical link for that question
t/instrument
is designed to help you ensure that you’re calling functions correctly, according to spec. Checking that functions (yours or someone else’s) are implemented correctly is a different job, handled by st/check
.
amend it with "please re-say&pin this message each morning"
@rickmoynihan: we use test.chuck for additional generators and we've taken the same approach of loading it dynamically as a test-only dependency /cc @alexmiller
@seancorfield: you just generated a bunch of lazy vars?
theres is some documentation update planned regarding this issue @alexmiller? Something the community could help you with? Sorry if the docs were already amended with this point, I didn't re-read them lately
alexmiller: thanks for the enlightening answer... And I think it would be another great blog topic 🙂
seancorfield: yeah test.chuck is awesome (thanks gfredericks btw) how do you load it as a test time dependency only? Do you mean just through a dev/test profile? Or do you mean you're reusing core.specs lazy loading things somehow.
re :ret
it in fact says it in the guide -- I think people have a false expectation of the tool to behave in a certain symmetric (for lack of a better term) way. But the real distinction is about development (`instrument` -
:ret) vs test (`check` +
:ret) time. As you know dev time vs test time is a little blurrier in a REPL.
if you think of it (and teach it to people!) in terms of that distinction, it becomes intuitive
@andrewhr sorry, what issue are you referring to? (several things in this channel)
the guide is updated with each alpha so should be in sync
@alexmiller: about :ret
in s/instrument
, @glv's answer https://clojurians.slack.com/archives/clojure-spec/p1470930899001878
guide discusses it, docstrings I think are up to date. where else should it be?
great! It's a pretty common question and we've not sure if the docs were up to date.. sorry for my laziness in not checking there before asking you
I started working on a reference page for spec which will be kind of somewhere between the docstrings and the guide, eventually I’ll get around to finishing that
@rickmoynihan: we wrap stuff we need to use in a function like this
(defn fn-string-from-regex
"Return a function that produces a generator for the given
regular expression string."
[regex]
(fn []
(require '[com.gfredericks.test.chuck.generators :as xgen])
(let [string-from-regex (resolve 'xgen/string-from-regex)]
(string-from-regex regex))))
/cc @gfredericksIn my build.boot
file I have
(deftask testing-context
"Provide main testing context."
[]
(merge-env! :dependencies '[[com.gfredericks/test.chuck "0.2.7" :scope "test"
:exclusions [*/*]]
[javax.servlet/servlet-api "2.5" :scope "test"]
[org.clojure/test.check "0.9.0" :scope "test"]])
identity)
that task is chained in ahead of any testing tasks, to make the libraries available, but scoped so they don’t end up in artifacts (in case a build test accidentally got chained in with a testing task).
sorry if I'm asking the obvious, but why are there both or
and alt
? alt
is used in sequences, but why isn't or
used there?
this is covered briefly in the guide btw
alt
describes alternatives that are in the context of a sequence
a spec with alt
can thus be reused in different regex op contexts
whereas or
represents a spec for a single value
there are situations where either would give you the same result but then there are cases where they would not
it’s better to start from the direction of what you’re spec’ing - if it is syntax in a sequential context, then use alt
, otherwise use or
(s/conform (s/* (s/alt :n number? :k keyword?)) [5 :a 10 :b 20 :c])
you are describing the structure / syntax of a sequential structure there
so use s/alt
(note that you can’t use s/or
here)
@alexmiller: thanks for explaining - I tried to find it in the guide, but couldn't understand it as clear as you explain it now
(s/conform (s/or :n number? :k keyword?) 100)
here you’re describing a single value - use s/or
Is there any reason to avoid using (s/tuple …)
for the :args
value of s/fdef
?
repl=> (s/conform (s/* (s/alt :n number? :k keyword?)) [5 :a 10 :b 20 :c])
[[:n 5] [:k :a] [:n 10] [:k :b] [:n 20] [:k :c]]
repl=> (s/conform (s/* (s/or :n number? :k keyword?)) [5 :a 10 :b 20 :c])
[[:n 5] [:k :a] [:n 10] [:k :b] [:n 20] [:k :c]]
both can work
but regex forms like cat are preferred
b/c the conformed result will tag the arguments (which tuples don’t)
again, this is syntax (the syntax of a function) so that’s a better match
hmm:
repl=> (s/conform (s/* (s/or :n (s/* number?) :s (s/* string?))) [[1 2 3]])
[[:n [1 2 3]]]
repl=> (s/conform (s/* (s/alt :n (s/* number?) :s (s/* string?))) [[1 2 3]])
StackOverflowError clojure.core/implements? (core_deftype.clj:539)
I can’t spot anything immediately that would make that result acceptable :)
looks like a bug to me
I would not expect that value to actually satisfy that spec though
you are describing sequences like [1 2 3 “a” “b” 4 5 6 “d” “e”]
whereas the first s/or spec is for sequences like [[1 2 3] [“a” “b”] [4 5 6] [“d” “e”]]
if you can file a jira, that would be useful
really, I don’t think I would use s/or to describe either of those two kinds of inputs
well, it might make sense, it really depends on semantics
(s/conform (s/* (s/spec (s/alt :n (s/* number?) :s (s/* string?)))) [[1 2 3] ["a" "b"] [4 5 6]])
or you could do (s/conform (s/* (s/or :n (s/coll-of number?) :s (s/coll-of string?))) [[1 2 3] ["a" "b"] [4 5 6]])
thx for the ticket
(s/conform (s/* (s/spec (s/alt :n (s/* number?) :s (s/* string?)))) [[1 2 3]])
;;=> [[:n [1 2 3]]]
@alexmiller: so was the bug that I missed the surrounding s/spec
?
The guide says: "If you need to spec a nested sequential collection, you must use an explicit call to spec to start a new nested regex context. "
well I mean I’d say that was your error
but it’s a bug that you got a stackoverflow :)
it should have just said invalid
it wasn't garbage though, just not accurate
is there an equivalent of declare
but for specs?
@stathissideris: you don't need to declare keywords before using them
seancorfield: Thanks... at first the require in that function makes me wince... but it's actually a nice trick being able to include the generator in the spec and use the spec in production context without the generator dependency. Nice! xgen/string-from-regex
is too nice to use! 🙂
I use runtime require
quite a bit. Very useful for conditional dependencies etc.
I seem to recall that s/atom-of
was bandied about shortly after clojure.spec was released. Is that something we should anticipate in core or has it been discarded as a bad idea?
My current use case calls for like an s/promise-of
, but I’m curious what the thinking is wrt specs for async values
it was never bandied about by anyone from core :)
I think it’s a bad idea