This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-09-02
Channels
- # beginners (61)
- # boot (84)
- # cider (43)
- # cljsrn (2)
- # clojure (99)
- # clojure-android (3)
- # clojure-austin (2)
- # clojure-italy (5)
- # clojure-russia (43)
- # clojure-spec (93)
- # clojure-uk (41)
- # clojurescript (94)
- # clojutre (1)
- # cloverage (8)
- # core-async (31)
- # cursive (3)
- # datomic (14)
- # defnpodcast (1)
- # editors-rus (7)
- # events (1)
- # hoplon (15)
- # leiningen (3)
- # luminus (6)
- # om (142)
- # onyx (86)
- # other-languages (4)
- # pedestal (1)
- # planck (1)
- # portland-or (5)
- # re-frame (96)
- # reagent (16)
- # ring-swagger (17)
- # rum (73)
- # specter (25)
- # untangled (14)
- # yada (142)
@gfredericks does the maven clojure plugin do the same monkey-patching of clojure.test that lein does? http://build.clojure.org/job/java.jdbc-test-matrix/453/CLOJURE_VERSION=1.9.0-alpha11,jdk=Sun%20JDK%201.6/console <— seems to be the same exception as I got testing locally
Not sure how to tell Maven’s plugin not to do the Leiningen naughtiness 🙂
com.theoryinpractise.clojure.testrunner
is your culprit
I don't know about maven clojure, but it smells like something similar
this seems a lot harder to work around given the constraints
It rebinds the report
function
do you get to choose an alternate version of the clojure-maven-plugin if you want?
I could override it for my project I think, yes (this is for java.jdbc
)
Is there a version that is compatible with test.check’s clojure_test stuff?
alternately, any tactic you can think of that lets you require test.check.clojure-test
prior to that line running will fix it
no I was just imagining forking it :)
Hahaha… ok...
so a user.clj
could work if you can keep it out of the release jar
Would that run with Maven?
it runs when clojure boots up
user.clj
is a pretty reliably way to slip something in before just about anything else happens
Pretty sure that doesn’t work with Boot? (more an FYI but…)
why not?
I don’t remember… but it was discussed in #boot a while back...
probably something about their magical space age classloader thing
And how do you get it to be loaded for Maven running Clojure?
@seancorfield heck for that matter adding a (:require clojure.test.check.clojure-test)
to any of your namespaces should also work
putting the user.clj
on the classpath means that clojure.core reads it at then end of its loading
e.g. src/test/resources/user.clj
or whatever
Ah, yeah, that worked...
@seancorfield you can define/give your own test runner script to clojure-maven-plugin if you need to
Dynamically require
ing that namespace when my test namespace loads seems to do the trick — and I can remove the Leiningen monkey-patch setting as well.
<configuration>
<testScript>src/test/clojure/com/jobsheet/test.clj</testScript>
</configuration>
I have this now in my test ns:
(def with-spec? (try
(require 'clojure.java.jdbc.spec)
(require 'clojure.spec.test)
;; require this to workaround rebinding of report multi-fn
(require 'clojure.test.check.clojure-test)
(let [syms ((resolve 'clojure.spec.test/enumerate-namespace) 'clojure.java.jdbc)]
((resolve 'clojure.spec.test/instrument) syms))
(println "Instrumenting clojure.java.jdbc with clojure.spec")
true
(catch Exception _
false)))
Works with Leiningen and Maven!
I have a spec that looks like this:
(s/def ::value <???>)
(s/def ::type #{"type-date", "type-weirdo", "no-value"})
(s/def ::ent (s/keys :req-un [::type] :opt-un [::value]))
(s/def ::ents (s/coll-of ::ent))
Depending on the type, the value needs to be different, e.g., for type-date
, the value should be a date. I know there are multimethods that can, and probably should, be used, but I just can't get it right. What comes at the <???>
, so I can have different predicates for value depending on the value of type?have you looked at s/multi-spec
?
there is an example in the guide http://clojure.org/guides/spec
I ran into this problem two days ago you want to make N :value
specs. (e..g.`(s/def :my/value <???>)`, (s/def :other/value <???>)
, (s/def :one.more/value <???>)
and then dispatch those :value
's with a multimethod
yeah, I'm looking at it. but it seems to be somewhat different. So, I could do:
(defmulti ent-type ::type)
(defmethod ent-type "type-date" [_]
(s/keys :req-un [::value])
(s/def ent-type (s/multi-spec ent-type ::type))
So I day value is required for "type-date". But that still doesn't solve the problem. I must be missing something...@spinningtopsofdoom Allright, and I don't need to care about the namespaces? - I mean, the map contains just 'value', no namespaces. I'll give it a few tries.
instead of using ::value, you could define many :foo1/value :foo2/value :foo3/value specs
each defmethod would use a different one in :req-un
oh, allright
@alexmiller is there any movement on having spec/keys
take a map of keywords and specs (e.g.)
(spec/def :one-map (spec/keys :req-un {:value <one spec>})
(spec/def :other-map (spec/keys :req-un {:value <other spec>})
So that you don't have to have registered specs for spec/keys
nothing yet
well, it will never take inline specs
we might possibly loosen the constraint between key name and spec name, but it’s part of the design that s/keys
doesn’t use inline specs and I don’t expect that to change
the idea is to encourage defining semantics for attributes
The constraint between key name and spec name is what I would like to loosen. So then my example would be
(spec/def :one-map (spec/keys :req-un {:value ::one-spec})
(spec/def :other-map (spec/keys :req-un {:value ::other-spec})
Correct?yeah, something like that has been mentioned, but I do not know whether we’ll end up doing it or not
Well I'll make a Jira ticket for that if it's not already there, then. Thanks for the clarification.
I do not know of a jira ticket for this
Hi everybody, very new to specs, but have already a good part implemented. Now I need a little help on something that is probably very easy, but I'm stuck. I have a def that verifies a url to be a s3 url (s/def ::s3-url #(str/starts-with? % "s3")
. Using it to check a single argument works. Now I have a function with 2 arguments (from-url and to-url) of which 1 needs to conform to that spec. Can anyone hint me for the solution.
This is what I have:
(s/def ::valid-url is-valid-url?)
(s/def ::s3-url #(str/starts-with? % "s3"))
(defn sync
"sync an s3 folder with a local folder, this works both ways"
[from-url to-url])
(s/fdef sync
:args (s/and (s/cat :from-url is-valid-url? :to-url is-valid-url?)
??? this is where I get lost ???))
(s/fdef sync
:args (s/cat :from-url is-valid-url? :to-url is-valid-url?))
I guess I’m also wondering what the difference is between is-valid-url?
, ::valid-url
and ::s3-url
given that you have specs, I would actually use the specs in the sync fdef
(s/fdef sync :args (s/cat :from-url ::s3-url :to-url ::s3-url))
something like that
right so you could have something like:
(s/def ::file-url #(str/starts-with? % “file://“))
(s/def ::s3-url #(str/starts-with? % “s3://“))
(s/def ::aws-url (s/or :file ::file-url :s3 ::s3-url))
… then use ::aws-url in the sync fdef
or whatever is appropriate
oh, you want a constraint across the args!
No, that's fine!
You can do it with s/and like you were or you can do that in the :fn spec too
fn is used for constraints between args and ret or also across args
Only the args spec is checked in instrumentation though so that might be what you want
Ah, been reading about it all day and understood the args / ret, but of course that works for across args as well.
Yeah fn gets the conformed version of both args and ret
Also read about 10 times that stest/instrument only does :args, now I know that is true 😉
I have the :fn version working. I'm still curious about a solution in the :args part, where I got stuck to begin with. That way, if people use my sync function they can simply (stest/instrument `sync) and work from there.
(s/fdef :args (s/and (s/cat :from-url ::aws-url :to-url ::aws-url)
(fn [{:keys [from-url to-url]}]
(or (s3-url? from-url) (s3-url? to-url)))))
something like that
the second function in the s/and receives the conformed version of the first part of the and
so that will be a map with :from-url and :to-url keys
is it possible to use `s/multi-spec' on different specs? Something like - but this doesn't work:
(defmulti m [::type ::op])
(defmethod m ["date-type" "do"] [_]
(s/keys ...))
...
(s/def .... (s/multi-spec m [::type ::op]))
that defmulti definition looks wrong - it takes a dispatch function not a vector
(defmulti m #(vector (::type %) (::op %)))
maybe?
or it’s a great opportunity to use juxt :)
(defmulti m (juxt ::type ::op))
oh, cool... thx!
and then the retag value is not valid either - should either be a tag or a fn of generated value and dispatch-tag