Our of curiosity, I tried to implement a Mocha like DSL. Seems like, the core of the DSL, could be written quite succinctly. First we will describe the core DSL.
Minimal Mocha DSL details
The 4 functions below, seem to be the relevant ones.
it are used inside a
The important part is,
describe could be nested within
to arbitrary depth. ex:
So each describe could have
it and well
At any level, all functions registered in
setup should be run
first. Then all the tests registered with
it, and then all the
describe have to be executed. After all that, function
teardown should be executed. Ex:
- Call setup functions
- Execute all the test in the level
- Execute all nested levels
- Call teardown functions
So, how do we solve it.
Lets first think just one level (ex: ignore nested describes). We
would have to collect all the DSL commands at that level, and then
execute them in a specific order. Note that we can’t just execute the
commands in the order we come across. Example, a
setup might come
after tests (
it). But all the
setup in a level have to be run
before the tests. The way I achieve this is to define all the DSL
commands as functions which save the command, and its arguments, to be
executed later. ex:
setup(fn) would save a pair
["setup", fn]. ex:
We will come to the
stack part later. Now, once all the commands in
a describe level are collected, they are to be executed one by one.
teardown commands is simple. Just execute
the function registered with them, in the context (there is a single
context, on which all setup and teardown work). Test (functions
it) are executed by running the registered function,
and showing success or failure based on output. For now, it just
checks for the exception thrown by the function. Ex:
Describe is the special case. Executing it, essentially means doing
the above, at the nested level (ex: the function registered with the
describe). Note that
teardown should run at the end. So, some
information about the current level has to be saved, till all the
nested levels are done. This is the reason to have stack, to keep the
describe is kind of the main function of the DSL.
Well, thats mostly it. There are some small details. Like directly
describe the first time we come across it (the process
has to start somewhere). Or printing the titles etc.
For more details look at the code. Its nice to find out that an expressive DSL could be implemented (to at least experiment) in less than 100 lines of code.
PS: ActiveSphere is hiring. If you would like to join, try your hands at making this code handle asynchronous tests. You can find the problem description here. Visit our careers page. Send us a mail at firstname.lastname@example.org.