Custom test assertions in ClojureScript

220 views
Skip to first unread message

John Shahid

unread,
Sep 26, 2019, 3:43:19 PM9/26/19
to Clojure
Hi all,

I am trying to implement custom assertions in ClojureScript. I tried to
use defmethod but got the following error:

> clojure -Sdeps '{:deps {org.clojure/clojurescript {:mvn/version "1.10.520"}}}' -m cljs.main --repl --repl-env node
> cljs.user=> (require '[cljs.test])
> nil
> cljs.user=> (defmethod cljs.test/assert-expr 'foo [& arg])
> WARNING: Use of undeclared Var cljs.test/assert-expr at line 1 <cljs repl>
> Execution error (Error) at (<cljs repl>:1).
> No protocol method IMultiFn.-add-method defined for type undefined:
>
> cljs.user=> cljs.test/assert-expr
> WARNING: Use of undeclared Var cljs.test/assert-expr at line 1 <cljs repl>
> nil

What am I doing wrong?

Thanks,

JS

Thomas Heller

unread,
Sep 28, 2019, 4:57:15 AM9/28/19
to Clojure
Hey,

cljs.test/assert-expr is part of the CLJ macro side so it can't be extended from a CLJS REPL. You can write it in a .clj file and use (require-macros 'that.ns) from the CLJS REPL or use :require-macros in the ns form that uses the new assert-expr.

HTH,
Thomas

John Shahid

unread,
Sep 28, 2019, 5:15:36 PM9/28/19
to clo...@googlegroups.com

Thanks Thomas,

That was very helpful. I tried your suggestion and it works in JVM
ClojureScript. That method does not work on bootstrapped ClojureScript
though.

As far as I understand this is a result of bootstrapped ClojureScript
evaluating the .clj(c) file in the same JavaScript environment.
Bootstrapped ClojureScript tries to emulate the separate compilation
phase by putting all vars defined in the .clj file in a new namespace
ending with `$macros` suffix.

In other words, I had to do something like the following in order for my
assertion to work on both JVM and bootstrapped ClojureScript:

> (defmethod #?(:cljs cljs.test$macros/assert-expr
> :clj cljs.test/assert-expr)
> ...

Is this the best way to achieve this?

Thanks,

JS

Thomas Heller

unread,
Sep 29, 2019, 4:02:37 AM9/29/19
to Clojure
Self-hosted should work the same way but it does require compiling the macro namespace in an extra step (ie. the $macros ns is created separately). I don't know how this is done for regular self-hosted. shadow-cljs has an extra build step for this that should take care of creating everything.
Reply all
Reply to author
Forward
0 new messages