"The only assert library that truly comes in clutch"
"That's a great question, I'm glad you asked"
This project is essentially a combination of ideas from two other projects ava and power-assert.
It combines the api of ava's assertions with the power of power-assert and also
provides a handy .keys
assertion which can be useful if switching from chai.
The library can be very helpful when porting an older codebase to use ava for testing. Using clutch assert will allow you to incrementally convert all of your assertions to ava style assertions and then once you're ready to switch just replace the word assert with ava's assertion mixin variable.
Note: ava does not have the .keys
assertion
Install clutch-assert
$ npm install --save clutch-assert
Instruct your test runner to require the clutch-assert loader before running tests. You will not get enhanced assertion messages if you neglect to require the loader
Example using mocha
$(npm bin)/mocha --require clutch-assert/loader path/to/test/mocha_node.js
By default the loader will instrument all files in a directory named test
, if
your tests are located elsewhere you must provide that path to the loader as
detailed under loader configuration.
const assert = require('clutch-assert');
assert.is(1 + 1, 2);
Note: Make sure to name the variable assert, due to the way the underlying dependencies work power-assert won't work correctly if the variable is named something else.
By default the loader instruments all files under the test
directory, this can be changed
by placing a .clutchrc
in the root of your project which should be a json file with a directory
top-level key.
Example
{
"directory": "test/unit"
}
The power-assert loaders
do not have support for the .keys
assertion by default. If you wish to use
that assertion you must import the patterns from clutch assert and configure
the loader to use those patterns.
Here is an example using espower-loader
const espower = require('espower-loader');
const patterns = require('clutch-assert/lib/patterns');
espower({
cwd: process.cwd(),
pattern: 'test/**/*.js',
espowerOptions: {
patterns: pattern.ENHANCED,
},
});
Passing assertion.
Failing assertion.
Assert that value
is truthy.
Assert that value
is falsy.
Assert that value
is true
.
Assert that value
is false
.
Assert that value
is equal to expected
.
Assert that value
is not equal to expected
.
Assert that value
is deeply equal to expected
.
Assert that value
is not deeply equal to expected
.
Assert that object
contains all of and only the keys
specified
Assert that an error is thrown. fn
must be a function which should throw. The thrown value must be an error. It is returned so you can run more assertions against it.
expected
can be a constructor, in which case the thrown error must be an instance of the constructor. It can be a string, which is compared against the thrown error's message, or a regular expression which is matched against this message. You can also specify a matcher object with one or more of the following properties:
instanceOf
: a constructor, the thrown error must be an instance ofis
: the thrown error must be strictly equal toexpected.is
message
: either a string, which is compared against the thrown error's message, or a regular expression, which is matched against this messagename
: the expected.name
value of the thrown errorcode
: the expected.code
value of the thrown error
Example:
const fn = () => {
throw new TypeError('hello there');
};
test('throws', t => {
const error = t.throws(() => {
fn();
}, TypeError);
t.is(error.message, 'hello there');
});
Assert that an error is thrown. thrower
can be an async function which should throw, or a promise that should reject. This assertion must be awaited.
The thrown value must be an error. It is returned so you can run more assertions against it.
expected
can be a constructor, in which case the thrown error must be an instance of the constructor. It can be a string, which is compared against the thrown error's message, or a regular expression which is matched against this message. You can also specify a matcher object with one or more of the following properties:
instanceOf
: a constructor, the thrown error must be an instance ofis
: the thrown error must be strictly equal toexpected.is
message
: either a string, which is compared against the thrown error's message, or a regular expression, which is matched against this messagename
: the expected.name
value of the thrown errorcode
: the expected.code
value of the thrown error
Example:
test('throws', async t => {
await t.throwsAsync(async () => {
throw new TypeError('hello there');
}, {instanceOf: TypeError, message: 'hello there'});
});
const promise = Promise.reject(new TypeError('hello there'));
test('rejects', async t => {
const error = await t.throwsAsync(promise);
t.is(error.message, 'hello there');
});
Assert that no error is thrown. fn
must be a function which shouldn't throw.
Assert that no error is thrown. nonThrower
can be an async function which shouldn't throw, or a promise that should resolve.
Like the .throwsAsync()
assertion, you must wait for the assertion to complete:
test('resolves', async t => {
await t.notThrowsAsync(promise);
});
Assert that contents
matches regex
.
Assert that contents
does not match regex
.
Assert that error
is falsy.
clutch-assert
provides an API for customization through which you can
customize clutch-assert by changing some options.
const assert = require('clutch-assert').customize({
output: {
maxDepth: 2,
},
});
options
has two top-level keys. assertion
and output
.
Customization options for empower module.
See empower API documentation for details.
Note that some default values are different from empower
's
(modifyMessageOnRethrow: true
and saveContextOnRethrow: true
).
Customization options for power-assert-formatter module. See power-assert-formatter API documentation for details.
Customizable properties and their default values are as follows.
const assert = require('clutch-assert').customize({
assertion: {
destructive: false,
modifyMessageOnRethrow: true,
saveContextOnRethrow: true,
patterns: [
'assert.truthy(value, [message])',
'assert.falsy(value, [message])',
'assert.true(value, [message])',
'assert.false(value, [message])',
'assert.is(value, expected, [message])',
'assert.not(value, expected, [message])',
'assert.deepEqual(value, expected, [message])',
'assert.notDeepEqual(value, expected, [message])',
'assert.regex(contents, regex, [message])',
'assert.notRegex(contents, regex, [message])',
'assert.keys(object, keys, [message])',
],
},
output: {
lineDiffThreshold: 5,
maxDepth: 1,
anonymous: 'Object',
circular: '#@Circular#',
lineSeparator: '\n',
ambiguousEastAsianCharWidth: 2,
widthOf: "(Function to calculate width of string. Please see power-assert-formatter's documentation)"
stringify: "(Function to stringify any target value. Please see power-assert-formatter's documentation)"
diff: "(Function to create diff string between two strings. Please see power-assert-formatter's documentation)"
writerClass: "(Constructor Function for output writer class. Please see power-assert-formatter's documentation)"
renderers: [
'./built-in/file',
'./built-in/assertion',
'./built-in/diagram',
'./built-in/binary-expression'
],
},
});