This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-05-07
Channels
- # beginners (71)
- # boot (25)
- # cider (204)
- # clara (18)
- # cljs-dev (10)
- # cljsrn (64)
- # clojure (50)
- # clojure-dev (2)
- # clojure-dusseldorf (1)
- # clojure-india (5)
- # clojure-italy (1)
- # clojure-nl (21)
- # clojure-poland (65)
- # clojure-spec (41)
- # clojure-uk (10)
- # clojurescript (4)
- # core-async (5)
- # cursive (2)
- # datomic (17)
- # duct (8)
- # emacs (8)
- # fulcro (1)
- # graphql (21)
- # hoplon (2)
- # javascript (3)
- # lumo (25)
- # mount (5)
- # off-topic (5)
- # onyx (3)
- # portkey (6)
- # re-frame (15)
- # reagent (5)
- # rum (1)
- # shadow-cljs (198)
- # spacemacs (19)
- # specter (2)
So, reached what seems to me to be a bug:
(gen/sample (s/gen (s/and (s/? string?) string?)))
-> ([""] [""] ["4"] [""] ["Ii5"] ["fye"] ["x4oa"] ["6i"] ["2LH7cR"] ["Y"])
But it seems that this should fail just as (s/and number? nil?)
. [""]
, for instance, is not a string?
.
s/? matches collections but conforms to a value and s/and flows conformed values so I think this is the expected behavior
Using s/? as a top level regex op often leads to confusing behavior - this is tricky. Usually it gets nested in s/cat or something
Thanks! Yeah I found that it works with s/exercise
so that makes sense at least
Should I expect spec validation errors to be thrown if I call a function that has a spec registered with s/fdef in CLJS?
(defn foo [a b] a)
=> #'elp.components.dialogs/foo
(s/fdef foo :args (s/cat :attributes map?
:children vector?))
=> elp.components.dialogs/foo
(foo 1 2)
=> 1
I have check-asserts on…working with specs defined with s/def and {:pre (s/valid? ….have you instrumented it?
with instrument
?
I was confused about that as well. An example I saw used s/instrument from the spec namespace….maybe it moved? Showing as undeclared var
it moved long long ago
it’s in the clojure.spec.test.alpha namespace (in clojure) and parallel in cljs
although I think you can just require that same ns in cljs and it will automatically load the right one
Thanks. Sorry…lazy this morning
I’m on cljs 1.9.946 (unfortunately). Tried googling and can’t discern whether spec.test.alpha is a separate library
Question after that would be how to instrument all functions there’s a fdef for
clojure.spec.test.alpha is a namespace and is included in clojurescript
(well the cljs equivalent)
several arities - no args = instrument all registered fdefs, or with a single symbol or with a collection of symbols
instrument is covered in the guide above and should work the same way in clojure and clojurescript
oh, one caveat is that you will likely need to include org.clojure/test.check 0.9.0 as a dep
Ah hah. Thank you 🙂
ClojureScript 1.10.238
cljs.user=> (defn foo [a b] a)
#'cljs.user/foo
cljs.user=> (require '[clojure.spec.test.alpha :as stest])
cljs.user=> (require '[clojure.spec.alpha :as s])
cljs.user=> (s/fdef foo :args (s/cat :attributes map?
:children vector?))
cljs.user/foo
cljs.user=> (stest/instrument `foo)
[cljs.user/foo]
cljs.user=> (foo 1 2)
#error {:message "Call to #'cljs.user/foo did not conform to spec:\nIn: [0] val: 1 fails at: [:args :attributes] predicate: map?\n:cljs.spec.alpha/spec #object[cljs.spec.alpha.t_cljs$spec$alpha1385]\n:cljs.spec.alpha/value (1 2)\n:cljs.spec.alpha/args (1 2)\n:cljs.spec.alpha/failure :instrument\n", :data #:cljs.spec.alpha{:problems [{:path [:args :attributes], :pred cljs.core/map?, :val 1, :via [], :in [0]}], :spec #object[cljs.spec.alpha.t_cljs$spec$alpha1385], :value (1 2), :args (1 2), :failure :instrument}}
Error: Call to #'cljs.user/foo did not conform to spec:
In: [0] val: 1 fails at: [:args :attributes] predicate: map?
:cljs.spec.alpha/spec #object[cljs.spec.alpha.t_cljs$spec$alpha1385]
:cljs.spec.alpha/value (1 2)
:cljs.spec.alpha/args (1 2)
:cljs.spec.alpha/failure :instrument
Thanks @alexmiller. Dev setup for cljs with spec is now:
(defn dev-setup []
(when config/debug?
(stest/instrument)
(s/check-asserts true)
(set! s/*explain-out* expound/printer)
(println "dev")))
Hi, guys, we'are having problems spec'ing protocols, we're implementing the protocols with records, so instead of wrap manually the protocol methods with functions, we're defining a defrecord* macro of the kind
defmacro defrecord*
[name fields pname & opts+body]
(let [[{:keys [method-parser],
:or {method-parser rest-symbol}}
body]
(parse-opts opts+body)]
`(do (defrecord ~name
~fields
~pname
[email protected])
~(-build-defns-from-protocol pname (eval method-parser)))))
Is it a good approach for now?
I think it’s a bad idea to wrap protocol functions (as you then destroy many of the benefits of protocol functions)
why? that's the advice I've always seen given (even before spec was a thing) : use protocol methods for polymorphism and a wrapping function for validation + varargs + else
I wouldn’t wrap it purely to use spec
there are some good reasons to wrap a call to a protocol but you don’t necessarily need one
rather, I would recommend just not spec’ing protocol functions
Ok @alexmiller, thanks
@alexmiller I'm curious, why not spec protocol functions?
you can’t
or rather you can’t for the purposes of instrument
I suppose you could spec them regardless for doc (and maybe check)? I haven’t tried it.
@alexmiller I thought you were suggesting it would be a bad idea even if it could be done. I wasn't missing any reason it would be a bad idea 😊