ThunkTest
Modular testing for JavaScript. Declare tests as thunks, then execute them with a call.
const Test = require('thunk-test')
const identity = value => value
describe('identity', () => {
it('returns whatever was passed to it',
Test(identity)
.case(+0, -0)
.case('hey', 'hey')
.case(NaN, result => {
assert(isNaN(result))
}))
})
thunk Tests are composed of a string descriptor, a function to test, and test cases denoted by .case
and .throws
. Any test cases may be asynchronous - either by returning a Promise explicitly or using the async
keyword. Both .case
and .throws
accept a variadic number of arguments - the same as those provided to the function - with the exception of the last argument:
- not a function - compare the return value directly by SameValueZero
- an asserter function - pass the return value to theh asserter function and let the asserter handle all the assertions. Note that if this value is a Promise, it is resolved before calling this function
Test(string, tester function)
.case(...args, expectedResult any)
Test('my test', myFunc)
.case(...args, asserter (result any)=>Promise|())
Test(string, tester function)
.throws(...args, expectedError Error)
Test('my test', myFunc)
.throws(...args, errorAsserter (error Error, result any)=>Promise|())
Concisely test many different cases with a declarative, idiomatic API.
Test(
'pipe: awesome username generator',
pipe([
string => string.toUpperCase(),
string => `x${string}x`,
string => `X${string}X`,
string => `x${string}x`,
string => `_${string}_`,
]))
.case('deimos', '_xXxDEIMOSxXx_')
.case('|', result => assert.equal(result, '_xXx|xXx_'))
.case('?', async result => assert.equal(result, '_xXx?xXx_'))
.throws(1, new TypeError('string.toUpperCase is not a function'))
.throws(null, (err, arg0) => {
assert.strictEqual(arg0, null)
assert.strictEqual(err.name, 'TypeError')
assert.strictEqual(err.message, 'Cannot read property \'toUpperCase\' of null')
})()
Preprocessing and postprocessing are available with callbacks supplied to .before
and .after
.
Note: since all callbacks are run with the same context, you can get and set values in the execution context (this
) of a thunk Test from any provided callback.
Test('square', function square(number) {
return number ** 2
}).before(function () {
this.hello = 'world'
})
.case(3, function (squared) {
assert(squared == 9)
assert(this.hello == 'world')
})
.after(function () {
assert(this.hello == 'world')
})()
Syntax
ThunkTest = ()=>() {
before: function=>this,
after: function=>this,
beforeEach: function=>this,
afterEach: function=>this,
case: (...args, expectedResult|function=>(disposer ()=>Promise<>|())|())=>this,
throws: (...args, expectedError|function=>(disposer ()=>Promise<>|())|())=>this,
}
Test(story string, func function) -> ThunkTest
Test(func function) -> ThunkTest
Installation
with npm
npm i thunk-test
browser script, global Test
<script src="https://unpkg.com/thunk-test"></script>
browser module
import Test from 'https://unpkg.com/thunk-test/es.js'