Tuesday, April 26, 2016

Improving test failures feedback by extending IPrintWithWriter protocol in ClojureScript

When Francesc and I decided to directly store ClojureScript +, -, * and / functions in our Operation record instead of keywords representing them our code got simpler.

However the feedback we received when a test failed got much worse because the whole function got printed in the test failure output:

The same happened when we were working on the REPL.

So we decided to extend the IPrintWithWriter protocol to improve the test failures feedback.

First, we tried to do it in the record declaration as we were doing for the Object protocol:

Surprisingly, it didn't work. We were still getting the ugly output shown before.

We were also getting this warning:

So we tried with extend-protocol:

This worked as we expected and we got a more useful failure feedback:

It also worked using extend-type:

Yet, we didn't understand why it was working as we expected with extend-type and extend-protocol but not in the declaration of the Operation record.

So we decided to ask it on the Clojurians slack.

There thanks to Alejandro Gómez and Nicolás Berger we understood what was happening. As Nicolás said:


That's the reason why it wasn't working and why we were getting that warning.

Check the code Nicolas is talking about in ClojureScript repository.

In the end, it was a nice problem to have, because we not only got a nicer and more useful failure feedback which was our initial goal, but also, learned more about extending core protocols in ClojureScript.

PS: Thank you very much to Alejandro Gómez and Nicolás Berger for their help.

2 comments:

  1. Manuel, if you take a look at the transpiled js code for `defrecord`, you'll discover that `defecord` implements cljs.core.IPrintWithWriter. See it here: http://tinyurl.com/defrecord-IPrintWithWriter

    ReplyDelete
  2. Hello Yeonathan
    Thanks for your comment Yeonathan.
    Yes, it does implement it. We just wanted to override that implementation providing our own, so that the operator function didn't get printed.
    Thanks again Yeonathan, Klipse is really great to see the transpiled JS code.

    ReplyDelete