Welcome! Please see the About page for a little more info on how this works.

0 votes
in Spec by

23:11 $ clj -Sdeps '{:deps {org.clojure/clojure {:mvn/version "1.10.0-RC3"} org.clojure/test.check {:mvn/version "0.10.0-alpha2"}}}'
Clojure 1.10.0-RC3
user=> (require '[clojure.spec.alpha :as s])
user=> (require '[clojure.spec.test.alpha :as st])
user=> (defmulti foo identity)
user=> (s/fdef foo :args (s/cat :wat string?))
user=> (defmethod foo :bar [lol])
#object[clojure.lang.MultiFn 0x57ac5227 "clojure.lang.MultiFn@57ac5227"]
user=> (st/instrument)
user=> (defmethod foo :baz [lol])
Execution error (ClassCastException) at user/eval150 (REPL:1).
clojure.spec.test.alpha$spec_checking_fn$fn__3026 cannot be cast to clojure.lang.MultiFn
user=> *e
#error {
 :cause "clojure.spec.test.alpha$spec_checking_fn$fn__3026 cannot be cast to clojure.lang.MultiFn"
 [{:type java.lang.ClassCastException
   :message "clojure.spec.test.alpha$spec_checking_fn$fn__3026 cannot be cast to clojure.lang.MultiFn"
   :at [user$eval150 invokeStatic "NO_SOURCE_FILE" 1]}]
 [[user$eval150 invokeStatic "NO_SOURCE_FILE" 1]
  [user$eval150 invoke "NO_SOURCE_FILE" 1]
  [clojure.lang.Compiler eval "Compiler.java" 7176]
  [clojure.lang.Compiler eval "Compiler.java" 7131]
  [clojure.core$eval invokeStatic "core.clj" 3214]
  [clojure.core$eval invoke "core.clj" 3210]
  [clojure.main$repl$read_eval_print__9068$fn__9071 invoke "main.clj" 414]
  [clojure.main$repl$read_eval_print__9068 invoke "main.clj" 414]
  [clojure.main$repl$fn__9077 invoke "main.clj" 435]
  [clojure.main$repl invokeStatic "main.clj" 435]
  [clojure.main$repl_opt invokeStatic "main.clj" 499]
  [clojure.main$main invokeStatic "main.clj" 598]
  [clojure.main$main doInvoke "main.clj" 561]
  [clojure.lang.RestFn invoke "RestFn.java" 397]
  [clojure.lang.AFn applyToHelper "AFn.java" 152]
  [clojure.lang.RestFn applyTo "RestFn.java" 132]
  [clojure.lang.Var applyTo "Var.java" 705]
  [clojure.main main "main.java" 37]]}

I would expect this to not throw an exception

2 Answers

0 votes
_Comment made by: urzds_

For reference and in case someone else would also like to know the call order that works (with Clojure 1.10.0 and clojure.spec.alpha 0.2.176):
(require '[clojure.spec.alpha :as s])
; => nil
(require '[clojure.spec.test.alpha :as stest])
; => nil
(defmulti testfn :type)
; => #'user/testfn
(defmethod testfn :atype [m] 1)
; => #object[clojure.lang.MultiFn 0x5d16b612 "clojure.lang.MultiFn@5d16b612"]
(s/fdef testfn :args (s/cat :m (s/keys :req-un [::type ::does-not-exist])))
; => user/testfn
(stest/instrument `testfn)
; => [user/testfn]
(testfn {:type :atype :does-not-exist nil})
; => 1
(testfn {:type :atype})
; => clojure.lang.ExceptionInfo: Call to #'user/testfn did not conform to spec.
0 votes
Reference: https://clojure.atlassian.net/browse/CLJ-2450 (reported by slipset)