alexanderjamesking/spy

Running example from README with Shadow CLJS's `:node-test` target raises an error

Luke1298 opened this issue · 3 comments

Thank you so much for spy! It's helped me to write lots of meaningful tests in clojure and clojurescript.

I've created a repo to demonstrate the behavior that I am seeing, but to summarize it seems that the following is behaving poorly:

(Preconditions: use shadow cljs' :node-test target)

  1. redef a function to a spy
  2. Call the redefed function

This gives the following error:

actual: #object[TypeError TypeError: spy_example.core_test.send_message is not a function]

From my finding investigating the compiled js files it appears that when invoking a spy directly <ie. (let [my-spy (spy/spy)] (my-spy))> Get's converted to:

(my-spy.cljs$core$IFn$_invoke$arity$0 ? my-spy.cljs$core$IFn$_invoke$arity$0() : my-spy.call(null));
(This seems right... At least it doesn't raise and exception)

But, when the redefed function is invoked after the redef <ie. (with-redefs [send-message (spy/spy)] (send-message nil nil))> this is getting converted to:

spy_example.core_test.send_message(null, null);
(This is the line that seems to be raising the "not a function" exception.)

This could be a problem with how shadow is dealing with with-redefs; and I'm happy to help however I can, wondering if you have any insights. 😄 Again thanks for spy!

NOTE: Poking around a little, if I manually edit the compiled javascript, changing spy_example.core_test.send_message to spy_example.core_test.send_message.afn then all is well.

I should also mention... I've tested on v2.0.0 and v2.9.0 of the spy library. Version of shadow.cljs 2.16.12 -- see package.json of repo.

Here is a work around as well -- I'm not sure what is causing the behavior, seems perhaps that however shadow.cljs is compiling the javascript does not play nice with with-meta/with-redefs -- or the combination of the two...

As a work around one can do:

(let [message-spy (spy/spy)]
 (with-redefs [send-message (fn [& args] (apply message-spy args)]
 ... 
 ;assert stuff about message-spy

Thanks for using spy and for the detailed report, I'll check out your repo and test it later, but I suspect it is related to compilation in shadow-cljs, adding :compiler-options {:static-fns false} to your config may fix the issue: https://stackoverflow.com/a/63726333