Tests are in the /test
directory.
A rule test file should look like this:
import {getTester} from './utils/test.mjs';
const {test} = getTester(import.meta);
test.snapshot({
valid: [
// Valid test cases goes here
],
invalid: [
// Valid test cases goes here
],
});
This runs SnapshotRuleTester
, which auto-generates the snapshot for test results, including error messages, error locations, autofix result, and suggestions. All you have to do is check the snapshot and make sure the results are expected before committing.
It's recommended to use this approach as it simplifies test writing.
import {getTester} from './utils/test.mjs';
const {test} = getTester(import.meta);
test.snapshot({
valid: [
'valid.code',
],
invalid: [
'invalid.code',
],
});
We use AVA
to run tests. To focus on a specific rule test, you can:
npx ava test/rule-name.mjs
To update snapshots, run the command above with --update-snapshots
or -u
.
npx ava test/rule-name.mjs -u
To focus on a single test case, you can:
test.snapshot({
valid: [],
invalid: [
// Tagged template with `test.only`
test.only`code`,
// Wrap code with `test.only`
test.only('code'),
// Wrap test case with `test.only`
test.only({
code: 'code',
options: [{checkFoo: true}],
}),
// Use `only: true`
{
code: 'code',
options: [{checkFoo: true}],
only: true,
},
],
})
Please remove test.only
and only: true
before committing.
This runs eslint-ava-rule-tester
:
import {getTester} from './utils/test.mjs';
const {test} = getTester(import.meta);
test({
valid: [
'valid.code',
],
invalid: [
{
code: 'invalid.code',
errors: [{ message: 'invalid.code is not allowed', column: 1, line: 1 }],
output: 'fixed.code',
}
],
});
Same as test()
, but uses @babel/eslint-parser
as parser.
Same as test()
, but uses @typescript-eslint/parser
as parser.
Same as test()
, but uses vue-eslint-parser
as parser.
test
and test.*()
accepts testerOptions
, which lets you specify common parseOptions
to all test cases.
test.snapshot({
testerOptions: {
parserOptions: {
ecmaFeatures: {
jsx: true,
},
},
},
valid: [],
invalid: [],
})
utils/test.mjs
also exposes a parsers
object, which can be used in testerOptions
or parser
for a single test case.
import {getTester, parsers} from './utils/test.mjs';
const {test} = getTester(import.meta);
test.snapshot({
testerOptions: {
parser: parsers.babel,
},
valid: [],
invalid: [],
})
import {getTester, parsers} from './utils/test.mjs';
const {test} = getTester(import.meta);
test.snapshot({
valid: [],
invalid: [
{
code: 'invalid.code.parse.by.babel',
parser: parsers.babel,
},
],
})
Why use parser: parsers.babel
instead of parser: '@babel/eslint-parser'
?
Using parsers.babel
will make the parserOptions
merge with useful default options. See parser.mjs
for details.