Skip to content

Instantly share code, notes, and snippets.

@lunjon
Created November 17, 2020 06:46
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lunjon/f7fbfc693b6266c4d3a4b06a1b96b5b6 to your computer and use it in GitHub Desktop.
Save lunjon/f7fbfc693b6266c4d3a4b06a1b96b5b6 to your computer and use it in GitHub Desktop.
Lua module for testing code

Testing

testing is a module I wrote for learning some Lua, and I find it quite useful for testing my modules written for neovim.

How to use it

Since I come from the perspective of neovim, I simply has the module among my regular configuration, i.e. ~/.config/nvim/lua/testing.lua. Below shows a lua script that use the testing module.

local testing = require("testing")
local assert = testing.assert

local function square(n)
    return n*n
end

-- Register test cases
testing.register("square 3", function()
    assert.equal(9, square(3))
end)

testing.register("square 5", function()
    assert.equal(24, square(5)) -- Oops!
end)


-- Run tests, and exit with status 1 if any test fails
testing.run(1)

Now run the script:

$ lua mymod_test.lua
OK:     square 3
FAIL:   square 5
        Error: expected values to be equal: 24 != 25

Because how Lua works, you can utilize monkey patching for mocking nvim functions, e.g. the global vim variable:

local testing = require("testing")
local assert = testing.assert

_G.vim = {
  api = {
    nvim_set_option(...)
        print("Do something useful instead of just printing")
    end
  }
}

local momod = require("momod")
...
local function fmtprint(fmt, ...)
local s = string.format(fmt, ...)
print(s)
end
-- Assertion helper.
local assert = {}
assert.is_nil = function(a)
if a then
error(string.format("expected %s to be nil", tostring(a)))
end
end
assert.not_nil = function(a)
if a == nil then
error(string.format("expected %s to not be nil", tostring(a)))
end
end
assert.truthy = function(a)
if not a then
error(string.format("expected value to be truthy: %s", tostring(a)))
end
end
assert.equal = function(a, b)
if a ~= b then
error(string.format("expected values to be equal: %s != %s", tostring(a), tostring(b)))
end
end
local function get_message(err)
local msg = string.match(err, "^.*:%d+:%s(.*)$")
if not msg then
return err
end
return msg
end
-- Table containing the registered tests.
local tests = {}
-- Register a function callback as a test.
-- @param name Name of the test. If it already exists, it will be replaced.
-- @param func A parameterless function to run.
local function register(name, func)
tests[name] = func
end
-- Run all registeried tests and print the results.
-- @param code Call os.exit with the given code if any test failed (default nil).
local function run(code)
local exit = code or nil
local status = true
for name, func in pairs(tests) do
local success, err = pcall(func)
if success then
fmtprint("OK:\t%s", name)
else
status = false
local msg = get_message(err)
fmtprint("FAIL:\t%s\n\tError: %s", name, msg)
end
end
if code and not status then
os.exit(exit)
end
end
return {
register = register,
assert = assert,
run = run,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment