What
I called it spacesuit.lua as it wraps your functions and gives you minimal support to write tests (assertions and spies) in the wild. If you need your tests to be TAP compliant, runnable from any platform, and a well known solution, I can recommend busted, but for me, I tried to keep it minimal so I can put it in my bag and run the files I need from my console, using some silly bash/zsh script using globbing. no need for luarocks, native compilation of lfs or anything.Apart from providing some sugar for assert_equal (which I'll probably delete in favour of plain assert(foo==42)), it provides:
- assert_raise(fun): runs the function and asserts an error is thrown during its execution.
- spy(fun): returns a proxy function (it's a table with __call in its metatble) that logs all the calls (both actual parmeters and results). The usage is quite simple:
s = spy(function(x) return x+1 end) s(42) s(45) -- inspect the log s.called_with(42) -- true s.called_with(42).and_returns_with(43) -- true s.called_with(43) -- error s.called_with(42).and_returns_with(44) -- error --number of times called s.called() -- true s.called(1) -- error s.called(2) -- true
How
The how is what is interesting. When you make a spy out of a function, spacesuit creates a func table which responds to called_with. called_with returns a table with and_returns_with key which will do the matching. It's quite a nice usage of lexical scope juggling.
For the hijacking part, I wanted to wrap everything into another table which would have the 'clean' method, and use __call to call the spy table (that would cascade to its __call entry in its metatable, but lua doesn't let you chain __call's. So you have to write the outer one as a function that calls the inner one (and then the __call is run).