Thirst is a testing library for Lua, based on Lust, that optimizes for ease of writing.
The smoother it is to write tests, the more you'll want to do it, and the better off your codebase will be in the long run. This is especially important for weakly-typed, dynamic languages like Lua.
Download the thirst folder and require it.
thirst.section() defines a new block of tests, and thirst.it() defines a test with assertions inside. Assertions can be created with the various thirst.expect functions. You can then run your entire test suite folder at once with thirst.run_folder() (if you're using LÖVE).
Complete example:
-- spec/example_test.lua
local thirst = require("thirst")
local expect = thirst.expect
thirst.section("examples")
thirst.it("is as convenient as possible to write", {
expect.equals(1, 1),
expect.is_not_a(true, "number"),
expect.function_works(function() return math.floor(1.5) end)
})
thirst.it("error examples", {
expect.equals(true, false),
expect.is_a(function() end, "boolean"),
expect.shallow_equals({10, 20, 30}, {10, 20, 999})
})
--main.lua
local thirst = require("lib.thirst")
thirst.run_folder("spec")Output:
examples
[PASS] is as convenient as possible to write
[FAIL] error examples
spec/example_test.lua:12: Expected 'true' and 'false' to be equal.
spec/example_test.lua:13: Expected 'function: 0x01a304564480' to be a boolean, but it was a function.
spec/example_test.lua:14: Tables had mismatched values on key [3]: '30' vs '999'
==============================
PASSES: 1
FAILS: 1
Coverage: 50.0%
[++++++++++++++--------------]
==============================
If true, uses ANSI color codes for text when printing test results. If your console doesn't support color codes, switching this off will make all text print in the default color.
If true, the rundown of passes, fails and coverage printed on finish() will have a colored progress bar representing the coverage.
If true, the result of each test will be printed when it's executed.
If true, a list of all errors that occurred while testing will be printed when calling finish(), at the bottom of the results section.
Run a new test (inside the current section, if any) and prints out results if is_printing_enabled is true. Calls before-functions before and after-functions after it runs.
Add fn to be called before every it call in the current section and all sections nested inside it.
Add fn to be called before after it call in the current section and all sections inside it.
Create a group of tests that's automatically ended and cleaned up when the next one starts, or when you manually end it with pop_section().
Begin a new group of tests. it() calls after this function will be nested inside this section, with one level higher of indentation.
You can nest sections by calling this function more than once.
End the current section, clean up before and after functions, and move back to the previous section.
Pop all active sections, clean up internal state, and print some info about the entirety of the test suite so far.
This is automatically called at the end of run_folder().
Watch a function to track the number of times it was called, and the arguments it was called with. This returns a table containing one table for every time the function was called, with the arguements used inside it.
I'll be honest, I don't really understand this one. Please check the Lust docs for more info.
path- The path to the folder. This gets passed tolove.filesystem.getDirectoryItems().exclude- Optional. A Lua pattern. Filepaths that match this pattern will be skipped.
Recursively execute every Lua file inside the given folder and all nested folders, printing all results, then prints a rundown of the whole suite. This is the easiest way to run every test inside your spec folder, for instance.
Requires LÖVE.
Create a new Thirst-compatible assertion result table, to put inside tests. success should be true when the test passes, and false when it fails. error_message will be collected and displayed if it fails.
This can be used to make custom assertions; see expect.lua for examples.
These are all part of the expect table, included in thirst.expect, and all return Assertions (return values omitted in these docs for brevity). You can also make custom assertions with thirst.create_assertion().
Always succeeds. Useful when you don't have anything meaningful to test yet.
Always fails. Useful when you don't have anything meaningful to test yet.
Succeeds if value ~= nil.
Succeeds if value == nil.
Succeeds if a == b.
Succeeds if a ~= b.
Succeeds if type(value) == type_name.
Succeeds if type(value) ~= type_name.
Succeeds if func executes successfully without errors. Extra args are passed to func.
Succeeds if func errors during execution. Extra args are passed to func.
Succeeds if tab has an entry with value value.
Succeeds if tab doesn't have any entries with value value.
Succeeds if tab is completely empty.
Succeeds if tab has any non-nil entries.
Succeeds if t1 and t2 have the same exact elements, but doesn't check inside any nested tables. (Note: values are compared by equality, so {} == {} is false).
Succeeds if t1 and t2 have the same exact elements, including nested tables.
Succeeds if i > j.
Succeeds if i >= j.
Succeeds if i < j.
Succeeds if i <= j.
Succeeds if n is between low and high, inclusive. This is equivalent to (n >= low) and (n <= high).
Succeeds if n exists outside the range of low to high, inclusive. This is equivalent to (n < low) or (n > high).
This library's still in its infancy; issues regarding missing/lacking features, suggestions and improvements are always welcome.
Additionally, it'd benefit from more thorough stress-testing, so if your project is open source, easy to run, and has a decent test suite, I'd love to try forking it and converting it to Thrist. You can poke me in the LÖVE Discord server.
MIT. See LICENSE for details.