Yet another RhinoJS post, despite my constant complaints, RhinoJS presents a challenge, it has no community, no fanbase, barely any love and worst of all, there is no way to run a unit test framework inside RhinoJS, so you can't test code.
A quick Google "how to write a JavaScript unit test framework" was not the first thing I tried, I attempted to shoehorn both Jest and Mocha into Rhino over two separate attempts, even using a special browser build to see if that works... No dice, so yeah back to Google.
As it turns out, Rhino is a lot easier to work with if you start it from node.js but you still have to solve a bunch of issues
- finding tests
- pretty test output
- test syntax
I used glob to find all the tests then serialised the paths, passing them as spawn arguments to Rhino... Well kind of rhino, I opted for ringo instead as it's more node.js like with a stdlib I can understand easily.
Now that we add a rhino.js entry file, this is the handshake as the rest of the work is done in rhino.js (I did want to do IPC with node so I could use the superior logging libraries in node.js but it's not easy).
We have our globs to .test.js
files, now let's do a bad thing, let's require all the tests in a loop. It is also possible to read the test files using "fs" then eval()
the string of test file but that's probably just for injecting variables at the head of the file, I instead opted for each test to export a function and then inject the test framework into the loop of calls to require.
Now then we have tests that are being injected with methods such as describe
and it
these just work via a try catch, where each error is actually the result of a throw from Chai, did I mention Chai yet, yes I was able to make Chai run in Rhino so I get lots of assertion goodness!
Lastly we need a way to evaluate and manipulate files with no module system 😭 yes that's right it's globals and no exports like the bad old days, well the workaround is to wrap the eval() file to test in a function inside the string, pass in dependencies to allow the test to run a d then make the test return the results of variables that we need to capture the result of.
It's all a little complex so I should showdev this effort soon.
I hope you enjoyed my notes on something you will probably never have to do 😬