Fork me on GitHub
#clojure-spec
<
2019-03-02
>
ag00:03:45

has anyone had this problem? It seems instrument doesn’t see my fdefs and they simply are ignored. fdef and the function and instrument - all in Clojurescript

ag00:03:34

I’m trying to use orchestra’s instrument - doesn’t work

seancorfield00:03:12

@ag You've required the namespace containing the functions and the fdefs before running instrument?

ag00:03:31

hmm… when I eval instrument it returns vector with speced symbols, but it doesn’t fail the spec

ag00:03:03

I’m trying to check if wrong data would cause it to throw, but it doesn’t

seancorfield00:03:10

(I'm not sure how instrument works in cljs so you may want to ask for help in #clojurescript if this seems to be a cljs-specific problem?)

seancorfield00:03:29

Hard to offer more advice without seeing your code...

seancorfield00:03:14

Also, have you tried spec's instrument directly, to eliminate an issue with Orchestra?

ag00:03:47

yeah, neither working ;(

seancorfield00:03:34

I would try it in a Clojure REPL to see if you can confirm the basics work as you expect. If they do, try that exact same example in cljs if you can.

ag00:03:17

the basics… work… if I simply create a function and call it in the repl, but when it’s within the app - it doesn’t work

ag00:03:31

probably has something to do with re-frame

ag00:03:21

yeah, seems I’m right… if I call fdefed function directly - it works. But doesn’t automatically validate when used in the app

ag00:03:47

and the fn is definitely being called

seancorfield04:03:38

@ag Ah, I suspect the code holds onto the original function value and doesn't see the instrumented version...?

metametadata11:03:09

Hi. Is there any library which allows enriching the error message of the function-based spec? Default:

(defn alright? [x] false)
(s/def ::alright alright?)
(s/explain ::alright 123)
; Output: 123 - failed: alright? spec: :user/alright
With lib:
(s/def ::alright (lib/with-explanation alright? (fn [x] (str x " is not alright!")))
(s/explain ::alright 123)
; Output: 123 - failed: alright? (123 is not alright!) spec: :user/alright

borkdude12:03:25

maybe using the explain-printer stuff? expound would be a library to look at for an example of this

5
metametadata12:03:04

setting custom :reason does the trick for me:

(defn with-reason-fn
  "Will use (reason-fn [x]) to set :reason in explain data for the specified spec."
  [spec reason-fn]
  {:pre [(s/spec? spec) (ifn? reason-fn)]}
  (reify s/Spec
    (explain*
      [_ path via in x]
      (let [data (s/explain* spec path via in x)]
        (map #(assoc % :reason (reason-fn x)) data)))

    ; Do not modify the rest of methods
    (conform* [_ x] (s/conform* spec x))
    (unform* [_ y] (s/unform* spec y))
    (gen* [_ overrides path rmap] (s/gen* spec overrides path rmap))
    (with-gen* [_ gfn] (s/with-gen* spec gfn))
    (describe* [_] (s/describe* spec))))

(s/def ::alright (with-reason-fn (s/spec alright?) (fn [x] (str x " is not alright"))))

(s/explain ::alright 123)
; Output: 123 - failed: 123 is not alright spec: :user/alright

Josip Gracin14:03:57

I'm trying to figure out why the following code is not working (using Clojure 1.10.0). The test fails. However, if I move the s/def definition of :n/repository after the extend-type line, it passes.

borkdude14:03:01

what happens if you don’t use partial but #(satisfies? % Repository)? I’m not sure if that solved it, just curious

Josip Gracin14:03:59

then it works. 🙂 you remembered my original question.

Josip Gracin14:03:22

#(satisfies? Repository %)

Josip Gracin14:03:00

strange, isn't it?

borkdude14:03:16

there was a discussion about this in the #beginners channel I believe

borkdude14:03:14

partial just binds the value of the var too early to see re-definitions, I think it’s related to that, although I’m not sure how it works with protocols

Josip Gracin14:03:45

yeah, I'm suspecting some interplay between protocol var, auto-generated interface and closures.

Josip Gracin14:03:07

is extend-type redefining something?

borkdude14:03:57

I think a protocol is a var that gets redefined everytime you extend a type:

(-reset-methods (alter-var-root (:var proto) assoc-in [:impls atype] mmap))
so that explains it

Josip Gracin14:03:41

I see. Thanks!