Skip to content

Instantly share code, notes, and snippets.

@bhb
Created February 9, 2019 02:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bhb/93f7cfabba6fb4f094f9203a6a2f4475 to your computer and use it in GitHub Desktop.
Save bhb/93f7cfabba6fb4f094f9203a6a2f4475 to your computer and use it in GitHub Desktop.
Custom explain-out with different versions of CLJS
;; Note this uses clojure 1.9, not 1.10 like other examples
;; clj -Srepro -Sdeps '{:deps {org.clojure/test.check {:mvn/version "0.9.0"} org.clojure/clojure {:mvn/version "1.9.0"} org.clojure/clojurescript {:mvn/version "1.10.339"}}}' --main cljs.main --repl
in cljs.main --repl
(require '[cljs.spec.alpha :as s])
(require '[cljs.spec.test.alpha :as st])
(require '[clojure.core.specs.alpha])
;; instrumenting a function
(s/fdef foobar :args (s/cat :x int?))
(defn foobar [x] x)
(st/instrument)
;; set up an example spec printer
(set! s/*explain-out* (fn [e-data] (println "SPEC ERROR!")))
;; Correct: Uses custom explain-out (note the "SPEC ERROR" in the message)
(foobar "")
;; #error {:message "Call to #'cljs.user/foobar did not conform to spec:\nSPEC ERROR!\n", :data #:cljs.spec.alpha{:problems [{:path [:args :x], :pred cljs.core/int?, :val "", :via [], :in [0]}], :spec #object[cljs.spec.alpha.t_cljs$spec$alpha2535], :value (""), :args (""), :failure :instrument}}
;; cljs$core$ExceptionInfo (cljs/core.cljs:11129:11)
;; <snip>
;; Incorrect: Does not use custom explain-out
(let "")
;; clojure.lang.ExceptionInfo: Call to cljs.core/let did not conform to spec:
;; In: [0] val: "" fails spec: :cljs.core.specs.alpha/bindings at: [:args :bindings] predicate: vector?
;; at line 1 <cljs repl> {:file "<cljs repl>", :line 1, :column 1, :root-source-info {:source-type :fragment, :source-form (let "")}, :tag :cljs/analysis-error}
;; at clojure.core$ex_info.invokeStatic(core.clj:4739)
;; clj -Srepro -Sdeps '{:deps {org.clojure/test.check {:mvn/version "0.9.0"} org.clojure/clojurescript {:mvn/version "1.10.439"}}}' --main cljs.main --repl
(require '[cljs.spec.alpha :as s])
(require '[cljs.spec.test.alpha :as st])
(require '[clojure.core.specs.alpha])
;; instrumenting a function
(s/fdef foobar :args (s/cat :x int?))
(defn foobar [x] x)
(st/instrument)
;; set up an example spec printer
(set! s/*explain-out* (fn [e-data] (println "SPEC ERROR!")))
;; Incorrect: does not call explain-out at all, shows raw spec data
(foobar "")
;; #error {:message "Call to #'cljs.user/foobar did not conform to spec.", :data #:cljs.spec.alpha{:problems [{:path [:x], :pred cljs.core/int?, :val "", :via [], :in [0]}], :spec #object[cljs.spec.alpha.t_cljs$spec$alpha1379], :value (""), :fn cljs.user/foobar, :args (""), :failure :instrument}}
;; cljs$core$ExceptionInfo (cljs/core.cljs:11154:11)
;; cljs.core.ex_info.cljs$core$IFn$_invoke$arity$3 (cljs/core.cljs:11186:5)
;; cljs.core.ex_info.cljs$core$IFn$_invoke$arity$2 (cljs/core.cljs:11184:16)
;; cljs.core/ex-info (cljs/core.cljs:11181:1)
;; cljs$spec$test$alpha$spec_checking_fnconform_BANG_ (cljs/spec/test/alpha.cljs:104:34)
;; G__1767__delegate (cljs/spec/test/alpha.cljs:118:42)
;; G__1767 (cljs/spec/test/alpha.cljs:115:20)
;; Incorrect: calls default explain-out
(let "")
;; clojure.lang.ExceptionInfo: Call to cljs.core/let did not conform to spec:
;; In: [0] val: "" fails spec: :cljs.core.specs.alpha/bindings at: [:args :bindings] predicate: vector?
;; at line 1 <cljs repl> {:file "<cljs repl>", :line 1, :column 1, :root-source-info {:source-type :fragment, :source-form (let "")}, :tag :cljs/analysis-error}
;; at clojure.core$ex_info.invokeStatic(core.clj:4739)
;; <snip>
;; clj -Srepro -Sdeps '{:deps {org.clojure/test.check {:mvn/version "0.9.0"} org.clojure/clojurescript {:mvn/version "1.10.516"}}}' --main cljs.main --repl
(require '[cljs.spec.alpha :as s])
(require '[cljs.spec.test.alpha :as st])
(require '[clojure.core.specs.alpha])
;; instrumenting a function
(s/fdef foobar :args (s/cat :x int?))
(defn foobar [x] x)
(st/instrument)
;; set up an example spec printer
(set! s/*explain-out* (fn [e-data] (println "SPEC ERROR!")))
;; Correct: Uses custom explain-out
(foobar "")
;; Execution error - invalid arguments to cljs.user/foobar at (<cljs repl>:1).
;; SPEC ERROR!
;; Incorrect: Uses default explain-out
(let "")
;; Execution error - invalid arguments to cljs.analyzer/do-macroexpand-check at (analyzer.cljc:3772).
;; val: "" fails spec: :cljs.core.specs.alpha/bindings at: [:args :bindings] predicate: vector?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment