Complex testing – the saga

While I’m developing Chlorine, sometimes I need to test multiple specific implementations of lots of really complicated stuff like REPL state, connection, async stuff (as the project is ClojureScript on Node.JS, all I/O treatment is via callbacks) and the complicated nature of rendering multiple different object types on Atom editor. I had multiple regression errors, then I’ve created some “acceptance” tests (these open up a real Atom editor and evaluate commands on it). The problem with these tests should be obvious: they are slow, and I mean REALLY SLOW, and they need a real Atom editor, lots of setups, and because Atom is not really predictable on its actions (sometimes you connect REPL and it changes the focus on the editor) there are lots of unnecessary interactions on the editor just to have less false-negatives.

Now, as I told before, I’m developing Chlorine together with REPL-Tooling, a library that should contain all tooling for any editor capable of running Javascript to run a port or Chlorine. There’s still too much on Chlorine that relies on internal Atom APIs (for example, detection of the beginning and end of forms is one, detection of namespace’s forms is other) but time is passing and more and more is being moved to REPL-Tooling, and as soon as the detection of forms is on REPL-Tooling (and is stable) there should be possible to port most Clojure parts to REPL-Tooling, and then I can think on how to refactor the ClojureScript part, test it, and then Chlorine will be a very easy project to port. Also, as a proof-of-concept there’s Clematis for NeoVIM (it’s still on the very beginning and nothing much happened after I wrote about it here), and also an “electron fake editor” that I’m using as test.

Wait, What?
(more…)

Chlorine, Clematis, REPL Tooling

Recently I began to migrate some of the code on Chlorine to REPL Tooling, so things may become more testable. I already found multiple bugs in this approach and began an integration test methodology using Electron (I say that there are three kinds of developers in the field of automated tests – the ones that don’t test, the ones that do, and test freaks. I’m probably the later).

In the beginning, the idea would be to rewrite the renderer of results and exceptions so that I could fix lots of bugs that they have. So far, it’s progressing slowly, but I already can render datomic results in a meaningful way (the last renderer was interpreting as Java objects, which they indeed are) and fix some bugs with tags and other issues.

Now, one of the things that I wanted in the new renderer is the ability to copy/paste results in a meaningful way – as I’m using UNREPL, there are lots of tags that need to be reinterpreted, like #unrepl/browseable for datafy. These need to be “translated” to something useful for rendering on screen, with links to navigate inner details, but for copy-paste they should have a textual representation that makes sense (probably the hard part).

The results of all these experiments are quite interesting – when you evaluate something and th result is a Java object, there’s a link ... that can be used to navigate inside the object: it’ll show getters, the current class, methods that the object supports, so things like “goto definition for Java object” or “Javadocs” aren’t really necessary.

Then, one of my friends asked for a Vim option. Just for fun, I started Clematis, a port of Chlorine to NeoVim. And it seems they things are progressing faster than I thought!
(more…)

Chlorine is thriving!

When I started this project, I was experimenting with shadow-cljs to see if I would be able to make an Atom package that would auto reload, run tests on ClojureScript, and se how far could I push ClojureScript in an Atom package.

Now, some months later, I’m seeing the package being used by a bunch of people, and I even discovered some bugs in UNREPL! Now, on this post, I’ll discuss a little bit more in detail the design decisions and my vision on the future of the project.

Chlorine is a clojure and ClojureScript atom package. It connects to a socket repl (opened via lein, boot, clj, shadow-cljs, lumo, or even REBL) and then upgrades the repl to be programmatically oriented with unrepl. Unrepl only works on Clojure, so for ClojureScript we use other techniques. Also, socket repl is a stream protocol, so to emulate a “request-response”, we need to coordinate things so Atom (and other editors) can react to commands and know exactly what’s the correct response for each command sent.

Design decisions

The choice for UNREPL was mostly because there is almost no documentation about prepl so far. Also, Socket REPL is literally everywhere: on Clojure , on ClojureCLR, on Lumo and Plank. Also, I wanted a better way to use ClojureScript, and I still have nightmares trying to use it over nREPL… and with Socket REPL things work fine.

Also, when I started the project Clojure 1.10 was just alpha software, and UNREPL offers us insanely good support for lazy lists, big strings, and other things that I wanted to use out of the box. One of the problems I’m still facing is coordination of evaluate/response, but this will probably be solved after a bunch of other fixes I’ll try.
(more…)