Skip to content

Commit e755296

Browse files
authored
feat: add rule options generic type support (#12)
1 parent 6f1885a commit e755296

File tree

4 files changed

+26
-27
lines changed

4 files changed

+26
-27
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ run({
125125
`onResult` field can be a function to do custom assertions with the entire result object.
126126

127127
```ts
128-
import { runClassic } from 'eslint-vitest-rule-tester'
128+
import { run } from 'eslint-vitest-rule-tester'
129129
import { expect } from 'vitest'
130130

131131
run({

src/rule-tester.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { isUsingTypeScriptParser, normalizeCaseError, normalizeTestCase } from '
1515
import { getAjvInstance, getRuleOptionsSchema } from './vendor/ajv'
1616
import { applyFixes } from './vendor/fixer'
1717

18-
export function createRuleTester(options: RuleTesterInitOptions): RuleTester {
18+
export function createRuleTester<RuleOptions = any>(options: RuleTesterInitOptions): RuleTester<RuleOptions> {
1919
const languageOptions = deepMerge(
2020
options.languageOptions ?? {
2121
parser: options.parser,
@@ -48,7 +48,7 @@ export function createRuleTester(options: RuleTesterInitOptions): RuleTester {
4848
...options.defaultFilenames,
4949
}
5050

51-
async function each(c: TestCase) {
51+
async function each(c: TestCase<RuleOptions>) {
5252
const testcase = normalizeTestCase(c, languageOptions, defaultFilenames)
5353

5454
const {
@@ -200,20 +200,20 @@ export function createRuleTester(options: RuleTesterInitOptions): RuleTester {
200200
}
201201
}
202202

203-
async function valid(arg: ValidTestCase | string) {
203+
async function valid(arg: ValidTestCase<RuleOptions> | string) {
204204
const result = await each(arg)
205205
expect.soft(result.result.messages, 'no errors on valid cases').toEqual([])
206206
expect.soft(result.result.fixed, 'no need to fix for valid cases').toBeFalsy()
207207
return result
208208
}
209209

210-
async function invalid(arg: InvalidTestCase | string) {
210+
async function invalid(arg: InvalidTestCase<RuleOptions> | string) {
211211
const result = await each(arg)
212212
expect.soft(result.result.messages, 'expect errors').not.toEqual([])
213213
return result
214214
}
215215

216-
async function run(cases: TestCasesOptions) {
216+
async function run(cases: TestCasesOptions<RuleOptions>) {
217217
describe(options.name || 'rule-to-test', () => {
218218
if (cases.valid?.length) {
219219
describe('valid', () => {

src/run.ts

+6-7
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,21 @@ import { createRuleTester } from './rule-tester'
44
/**
55
* Shortcut to run test cases for a rule
66
*/
7-
8-
export function run(options: TestCasesOptions & RuleTesterInitOptions) {
9-
const tester = createRuleTester(options)
7+
export function run<RuleOptions = any>(options: TestCasesOptions<RuleOptions> & RuleTesterInitOptions) {
8+
const tester = createRuleTester<RuleOptions>(options)
109
return tester.run(options)
1110
}
11+
1212
/**
1313
* Shortcut to run test cases for a rule in classic style
1414
*/
15-
16-
export function runClassic(
15+
export function runClassic<RuleOptions = any>(
1716
ruleName: string,
1817
rule: RuleModule,
19-
cases: TestCasesOptions,
18+
cases: TestCasesOptions<RuleOptions>,
2019
options?: RuleTesterInitOptions,
2120
) {
22-
const tester = createRuleTester({
21+
const tester = createRuleTester<RuleOptions>({
2322
rule,
2423
name: ruleName,
2524
...options,

src/types.ts

+14-14
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import type { Linter } from 'eslint'
22

33
export type Awaitable<T> = Promise<T> | T
4-
export interface ValidTestCaseBase extends CompatConfigOptions, RuleTesterBehaviorOptions {
4+
export interface ValidTestCaseBase<RuleOptions = any> extends CompatConfigOptions, RuleTesterBehaviorOptions {
55
name?: string
66
description?: string
77
code: string
8-
options?: any
8+
options?: RuleOptions
99
filename?: string
1010
only?: boolean
1111
skip?: boolean
@@ -29,7 +29,7 @@ export interface TestCaseError extends Partial<Linter.LintMessage> {
2929
type?: string
3030
}
3131

32-
export interface InvalidTestCaseBase extends ValidTestCaseBase {
32+
export interface InvalidTestCaseBase<RuleOptions = any> extends ValidTestCaseBase<RuleOptions> {
3333
/**
3434
* Expected errors.
3535
* If a number is provided, it asserts that the number of errors is equal to the number provided.
@@ -49,10 +49,10 @@ export interface NormalizedTestCase extends InvalidTestCaseBase {
4949
code: string
5050
}
5151

52-
export type InvalidTestCase = InvalidTestCaseBase | string
53-
export type ValidTestCase = ValidTestCaseBase | string
52+
export type InvalidTestCase<RuleOptions = any> = InvalidTestCaseBase<RuleOptions> | string
53+
export type ValidTestCase<RuleOptions = any> = ValidTestCaseBase<RuleOptions> | string
5454

55-
export type TestCase = ValidTestCase | InvalidTestCase
55+
export type TestCase<RuleOptions = any> = ValidTestCase<RuleOptions> | InvalidTestCase<RuleOptions>
5656

5757
export interface TestExecutionResult extends Linter.FixReport {
5858
/**
@@ -73,23 +73,23 @@ export interface CompatConfigOptions {
7373

7474
export type RuleModule = any // to allow any rule module
7575

76-
export interface RuleTester {
76+
export interface RuleTester<RuleOptions = any> {
7777
/**
7878
* Run a single test case
7979
*/
80-
each: (arg: TestCase) => Promise<{ testcase: NormalizedTestCase, result: TestExecutionResult }>
80+
each: (arg: TestCase<RuleOptions>) => Promise<{ testcase: NormalizedTestCase, result: TestExecutionResult }>
8181
/**
8282
* Run a single valid test case
8383
*/
84-
valid: (arg: ValidTestCase) => Promise<{ testcase: NormalizedTestCase, result: TestExecutionResult }>
84+
valid: (arg: ValidTestCase<RuleOptions>) => Promise<{ testcase: NormalizedTestCase, result: TestExecutionResult }>
8585
/**
8686
* Run a single invalid test case
8787
*/
88-
invalid: (arg: InvalidTestCase) => Promise<{ testcase: NormalizedTestCase, result: TestExecutionResult }>
88+
invalid: (arg: InvalidTestCase<RuleOptions>) => Promise<{ testcase: NormalizedTestCase, result: TestExecutionResult }>
8989
/**
9090
* ESLint's RuleTester style test runner, that runs multiple test cases
9191
*/
92-
run: (options: TestCasesOptions) => Promise<void>
92+
run: (options: TestCasesOptions<RuleOptions>) => Promise<void>
9393
}
9494

9595
export interface RuleTesterBehaviorOptions {
@@ -137,9 +137,9 @@ export interface RuleTesterInitOptions extends CompatConfigOptions, RuleTesterBe
137137
defaultFilenames?: Partial<DefaultFilenames>
138138
}
139139

140-
export interface TestCasesOptions {
141-
valid?: (ValidTestCase | string)[]
142-
invalid?: (InvalidTestCase | string)[]
140+
export interface TestCasesOptions<RuleOptions = any> {
141+
valid?: (ValidTestCase<RuleOptions> | string)[]
142+
invalid?: (InvalidTestCase<RuleOptions> | string)[]
143143
/**
144144
* Callback to be called after each test case
145145
*/

0 commit comments

Comments
 (0)