This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-01-18
Channels
- # aleph (1)
- # announcements (2)
- # aws (4)
- # beginners (73)
- # boot (2)
- # boot-dev (3)
- # cider (6)
- # cljs-dev (40)
- # clojure (64)
- # clojure-austin (2)
- # clojure-belgium (1)
- # clojure-dev (25)
- # clojure-estonia (1)
- # clojure-europe (16)
- # clojure-italy (11)
- # clojure-nl (4)
- # clojure-spec (90)
- # clojure-sweden (2)
- # clojure-uk (105)
- # clojurescript (58)
- # core-async (10)
- # cursive (23)
- # data-science (1)
- # datascript (3)
- # datomic (14)
- # duct (11)
- # fulcro (48)
- # graphql (1)
- # hyperfiddle (3)
- # kaocha (95)
- # liberator (1)
- # lumo (6)
- # nrepl (1)
- # off-topic (14)
- # onyx (2)
- # overtone (8)
- # portkey (3)
- # re-frame (31)
- # reagent (6)
- # shadow-cljs (185)
- # sql (12)
- # tools-deps (6)
- # vim (6)
- # yada (224)
Trying to spec partition-all, but I get an exception. Repro:
Clojure 1.10.0
user=> (require '[clojure.spec.alpha :as s])
nil
user=> (require '[clojure.spec.test.alpha :as stest])
nil
user=> (s/fdef clojure.core/partition-all :args (s/cat :n pos-int?))
clojure.core/partition-all
user=> (stest/instrument `partition-all)
[clojure.core/partition-all]
user=> (partition-all 1)
Execution error (ClassCastException) at user/eval142 (REPL:1).
clojure.spec.test.alpha$spec_checking_fn$fn__3026 cannot be cast to clojure.lang.IFn$LO
this is actually the first time I couldn’t instrument something on CLJ that I could on CLJS, normally it’s the other way around 😉
I guess instrument could look at the arglists and figure out if it needs to compile the wrapping fn to a primitive fn
How do people manage the seperation of concerns around app code, specs and generators? Generators are essentially a testing concern, but you also use want them at dev time so you can inspect sample values etc… Part of my issue is that writing generators eats up quite a few LOCs, so I’m tempted to put them in a different ns to the specs and app logic… I also feel like in clojure that they should be optional… which means you don’t really want them in the require tree in the production app. Are there any patterns people have for arranging these? Currently I just them all in the same ns — but at some point I worry it’ll be hard to see the wood for the trees.
Thinking also are there any lazy-loading patterns I can easily apply to my own generators?
Also you often want different generators depending on context
I know you can override them via st/check
etc — but not really sure how to organise all these bits
@rickmoynihan clojure.spec.test/check takes overridable generators. I use those, if I don’t make a generator attached to the spec itself.
Hi, I am trying to write a generator... but no luck... I am trying to follow the examples from the test.check page... but no luck (yet)
it can't find certain functions for instance.. while as far as I can work out they should be in the clojure.spec.gen.alpha
namespace
You may have to reference test check namespaces directly. Spec doesn’t expose all the stuff that’s available
ok will do. thank you. (I can't do it now, but I'll try later tonight) Thank you @borkdude
@thomas you know about lazy loading right?
you need to be aware that clojure.spec.gen.alpha
generators are subtly different to test.check ones
I always forget the details… but IIRC generators from spec are wrapped in a 0 arg function to allow lazy loading… so if you’re trying to use test.check
generators you need to wrap them one more time in a fn
call… or something like that. 🙂
@thomas here’s an example that might be helpful in addition to what @rickmoynihan said: https://github.com/borkdude/speculative/blob/master/test/speculative/core_test.cljc#L107
@borkdude: respeced looks useful… do you have any machinery to trigger st/check
in a deftest
and get a good error out from clojure.test
when things go wrong?
I’ve written a few things like this in the past — but the results have always been lackluster.
yes, I’m doing that here: https://github.com/borkdude/speculative/blob/master/test/speculative/test_utils.cljc#L31 when a spec doesn’t conform, I see the thrown exception
the crucial part is (clojure.test/is (respeced.test/successful? stc-result#))
, succesful?
realizes the stc-result (it’s lazy) and checks if there’s at least one
yeah I’ve done things like that before — but yours looks like it might give better output…
I’m guessing clojure.test
just prints the error as (is (not (successful? ,,,)))
Yeah I’m going to 🙂
@borkdude: would you say a use case for rt/check-call
is to check real sample data conforms to the spec then? i.e. as a way to check that the spec is valid, as much as the data/fdef?
@rickmoynihan check-call is made for checking fdefs on example based tests
one problem I’d like to tackle is: your function accepts arity 1 and 2, but you spec’ed only 2. there’s no way to detect this with stest/check since it only generates 2 args.
so fdefs could be insuffient. would be nice if that could be automatically detected.
agreed
it would be nice if you could generate data to detected that your fdef missed a case. I guess you can
related what I also find useful is a test of a s/conform
against some example data… so you know you spec’d the right thing.
but then you find that clojure.test/is
is effectively testing a boolean s/valid?
is insufficient as you want to see the spec failure not just (is (not (s/valid? ,,,)))
but I think there’s an equivalent need for spec checking too
as you say check
requires an fdef
I was writing things like (is (not= :clojure.spec.alpha/invalid (s/conform :spec/here {:sample :data}))
but you need to be careful using :clojure.spec.alpha/invalid
in these macros because it can cause compilation errors due to :clojure.spec.alpha/invalid
being used to check the macro syntax
but the reasoning there is that comparing (= ::s/invalid sample-result)
gives you a meaningful error in clojure.test.
hah, yeah, I had a similar issue when spec’ing assoc
, because then you cannot assoc the value :clojure.spec.alpha/invalid
which Cursive does when you use the REPL 😛
yeah IIRC there’s a ticket open on the issue somewhere
yeah. one of the proposals there is to use a singleton object to represent invalid inside spec and only to the outside use the keyword
you can use s/valid? rather than checking ::s/invalid
or s/invalid?
I don’t think a singleton object is a feasible solution
I’m not even sure I agree it’s a problem
@alexmiller It’s a problem when you instrument a function that must be able to deal with ::s/invalid as one of the arguments. This is important in tooling such as Cursive where ::s/invalid is remembered as REPL state for example
there are a very small number of such functions and some workarounds even for those cases
I consider “do nothing” to be a leading contender alternative for that ticket
how many votes are representative of “considered important enough by the community” in general for a CLJ Jira issue?
votes are about attention, not answers
if you’re not spec’ing core functions used by spec, how often is this an issue?
b/c that’s when I’ve seen people raise it
probably tooling, but then it would only be an issue for the developer of that tooling
I don’t consider this a settled result (which is why the ticket is still open)
that’s just my current thinking on it
changing topics, I just merged a giant refactor in spec-alpha2 in case anyone is interested
although since it’s a refactoring rather than new stuff, it’s not particularly exciting
I think this issue is more important than the any problem: https://dev.clojure.org/jira/browse/CLJ-2443
I haven’t had time to look at it seriously but I am aware of it
there are some subtly important differences in the api for callers
I will try to write about those in my journal today rather than spew them here
What approach do folks use to handle the namespacing of nested keys. We are trying to spec check the interface to an external service and the payload is a nested map. Namespaced keywords would seem to imply having to create a namespace for each nesting which isn’t ideal. Alternatively, we could generate the specs but this seems to have its own problems. As far as I can tell this would imply having to compose macros which seems excessive. Additionally, the caller side would have to construct the long form of these keywords in order to pull out the necessary data since there would be no namespaces to alias with this approach. Is there another approach that I’m missing? Its also possible that spec isn’t appropriate for this use case.