eslint-vitest-rule-tester
1
总安装量
1
周安装量
#49409
全站排名
安装命令
npx skills add https://github.com/antfu-collective/eslint-vitest-rule-tester --skill eslint-vitest-rule-tester
Agent 安装分布
windsurf
1
amp
1
opencode
1
kimi-cli
1
codex
1
Skill 文档
Instructions
You are helping users work with eslint-vitest-rule-tester, a library that provides ESLint rule testing with Vitest integration.
Core APIs
Two testing approaches:
run({ name, rule, valid, invalid, ...config })– All-in-one object style (config directly in object)createRuleTester({ name, rule, configs })– Returns{ valid, invalid }for explicit Vitestdescribe/itblocks (note:configskey, notlanguageOptions)
Key extensions:
outputanderrorsfields can be functions for custom assertions and snapshotsonResulthook for full result object validation- No
globals: truerequired in Vitest config
When Helping Users
Identify testing style first:
- Check if they have existing tests to match their pattern
- Default to
run()for simplicity (see Pattern 1 below) - Use
createRuleTester()for explicit Vitest test blocks with individualit()tests (Pattern 3)
Configuration:
- Use
languageOptions.parser: tsParserfor TypeScript (import from@typescript-eslint/parser) - Use
languageOptions.parserOptionsfor JS options (ecmaVersion, sourceType) - Put shared config in tester initialization, not in every test case
- Note: In
createRuleTester, config goes underconfigskey, not at top level
Type safety:
- Use
satisfies TestCasesOptions['valid']for valid test arrays - Use
satisfies TestCasesOptions['invalid']for invalid test arrays - Extract test cases as constants before passing to
run()(see Pattern 1)
Snapshots:
- Use
onResulthook withtoMatchSnapshot()for all invalid cases (Pattern 1) - Use function-based
output/errorswithtoMatchInlineSnapshot()for inline snapshots (Pattern 2) - Recommend
toMatchInlineSnapshot()overtoMatchSnapshot()when possible for better visibility
Common patterns:
// Pattern 1: run() with extracted test cases (from top-level-function.test.ts)
import type { TestCasesOptions } from 'eslint-vitest-rule-tester'
import { run } from 'eslint-vitest-rule-tester'
import { expect } from 'vitest'
import * as tsParser from '@typescript-eslint/parser'
const valids = [
'function foo() {}',
// allow arrow function inside function
'function foo() { const bar = () => {} }',
] satisfies TestCasesOptions['valid']
const invalids = [
{
code: 'const foo = () => {}',
output: 'function foo () {}',
errors: [{ messageId: 'topLevelFunctionDeclaration' }],
},
] satisfies TestCasesOptions['invalid']
run({
name: 'top-level-function',
rule,
languageOptions: { parser: tsParser },
valid: valids,
invalid: invalids,
onResult(_case, result) {
if (_case.type === 'invalid')
expect(result.output).toMatchSnapshot()
},
})
// Pattern 2: Function-based output/errors (from README)
run({
name: 'rule-name',
rule,
invalid: [
{
code: 'let foo = 1',
output(output) {
expect(output.slice(0, 3)).toBe('let')
expect(output).toMatchInlineSnapshot(`"const foo = 1;"`)
},
errors(errors) {
expect(errors).toHaveLength(1)
expect(errors.map(e => e.messageId))
.toMatchInlineSnapshot(`["preferConst"]`)
},
},
],
})
// Pattern 3: Explicit test suites (from README)
import { createRuleTester } from 'eslint-vitest-rule-tester'
import { describe, it } from 'vitest'
describe('rule-name', () => {
const { valid, invalid } = createRuleTester({
name: 'rule-name',
rule,
configs: {
languageOptions: {
parserOptions: { ecmaVersion: 2020, sourceType: 'module' },
},
},
})
it('valid case 1', () => {
valid('const foo = 1')
})
it('invalid case 1 with snapshot', async () => {
const { result } = await invalid({
code: 'const foo = 1',
errors: ['error-message-id'],
})
expect(result.output).toMatchSnapshot()
})
})
Troubleshooting
- Version errors: Requires ESLint v9.10+, check
package.json - Snapshot failures: Run
vitest -uto update snapshots - Parser issues: Add
languageOptions.parserfor TypeScript/JSX - Type errors: Import from
eslint-vitest-rule-tester, noteslint
Best Practices
- Match existing patterns – Check existing test files in the project first
- Extract test cases – Define
validsandinvalidsas constants withsatisfiesfor type safety - Add comments – Use inline comments to explain what each test case validates (e.g.,
// allow arrow function inside function) - Use snapshots – Prefer
onResulthook for bulk snapshot testing of all invalid cases - Consolidate config – Put shared parser/language options at tester level, not per test case
- TypeScript support – Import
@typescript-eslint/parserastsParserand use inlanguageOptions.parser - Error format – Use
errors: [{ messageId: 'errorId' }]for structured errors, orerrors: ['errorId']for simple cases