eslint-vitest-rule-tester
Version:
ESLint rule tester with Vitest
185 lines (183 loc) • 7.55 kB
text/typescript
import { Linter } from "eslint";
//#region src/types.d.ts
type Awaitable<T> = Promise<T> | T;
interface ValidTestCaseBase<RuleOptions = any, MessageId extends string = string> extends CompatConfigOptions, RuleTesterBehaviorOptions {
name?: string;
description?: string;
code: string;
options?: RuleOptions;
filename?: string;
only?: boolean;
skip?: boolean;
before?: (this: NormalizedTestCase<RuleOptions, MessageId>, configs: Linter.Config[]) => Awaitable<void>;
after?: (this: NormalizedTestCase<RuleOptions, MessageId>, result: Linter.FixReport) => Awaitable<void>;
/**
* @deprecated Use `after` instead
*/
onResult?: (result: Linter.FixReport) => void;
}
type TestCaseError<MessageId extends string = string> = Partial<Linter.LintMessage> & {
/**
* Data for interpolate the error message
*/
data?: Record<string, any>;
/**
* Alias to `nodeType`
* @deprecated `nodeType` is deprecated and will be removed in the next major version.
*/
type?: string;
messageId?: MessageId;
};
interface InvalidTestCaseBase<RuleOptions = any, MessageId extends string = string> extends ValidTestCaseBase<RuleOptions, MessageId> {
/**
* Expected errors.
* If a number is provided, it asserts that the number of errors is equal to the number provided.
* If an array of strings is provided, it asserts that the error messageIds are equal to the array provided.
* If an array of objects is provided, it asserts that the errors are partially equal to the objects provided.
*/
errors?: number | (MessageId | TestCaseError<MessageId>)[] | ((errors: Linter.LintMessage[]) => Awaitable<void>);
/**
* Assert if output is expected.
* Pass `null` to assert that the output is the same as the input.
*/
output?: string | null | ((output: string, input: string) => Awaitable<void>);
}
interface NormalizedTestCase<RuleOptions = any, MessageId extends string = string> extends InvalidTestCaseBase<RuleOptions, MessageId> {
type: 'valid' | 'invalid';
code: string;
}
type InvalidTestCase<RuleOptions = any, MessageId extends string = string> = InvalidTestCaseBase<RuleOptions, MessageId> | string;
type ValidTestCase<RuleOptions = any> = ValidTestCaseBase<RuleOptions> | string;
type TestCase<RuleOptions = any, MessageId extends string = string> = ValidTestCase<RuleOptions> | InvalidTestCase<RuleOptions, MessageId>;
interface TestExecutionResult extends Linter.FixReport {
/**
* If the rule fixes in multiple steps, each step will be present here
*/
steps: Linter.FixReport[];
}
interface CompatConfigOptions {
parserOptions?: Linter.ParserOptions;
parser?: Linter.Parser;
languageOptions?: Linter.Config['languageOptions'];
linterOptions?: Linter.Config['linterOptions'];
settings?: Linter.Config['settings'];
processor?: Linter.Config['processor'];
files?: Linter.Config['files'];
}
type RuleModule = any;
interface RuleTester<RuleOptions = any, MessageId extends string = string> {
/**
* Run a single test case
*/
each: (arg: TestCase<RuleOptions, MessageId>) => Promise<{
testcase: NormalizedTestCase<RuleOptions, MessageId>;
result: TestExecutionResult;
}>;
/**
* Run a single valid test case
*/
valid: (arg: ValidTestCase<RuleOptions>) => Promise<{
testcase: NormalizedTestCase<RuleOptions, MessageId>;
result: TestExecutionResult;
}>;
/**
* Run a single invalid test case
*/
invalid: (arg: InvalidTestCase<RuleOptions, MessageId>) => Promise<{
testcase: NormalizedTestCase<RuleOptions, MessageId>;
result: TestExecutionResult;
}>;
/**
* ESLint's RuleTester style test runner, that runs multiple test cases
*/
run: (options: TestCasesOptions<RuleOptions, MessageId>) => Promise<void>;
}
interface RuleTesterBehaviorOptions {
/**
* The number of times to recursively apply the rule
* @default 10
*/
recursive?: number | false;
/**
* Run verification after applying the fix
* @default true
*/
verifyAfterFix?: boolean;
/**
* Verify that fix allways changes the code
* @default true
*/
verifyFixChanges?: boolean;
}
interface DefaultFilenames {
js: string;
jsx: string;
ts: string;
tsx: string;
}
interface RuleTesterInitOptions extends CompatConfigOptions, RuleTesterBehaviorOptions {
/**
* The rule to test
*/
rule?: RuleModule;
/**
* The name of the rule to test
*/
name?: string;
/**
* Additional flat configs to be merged with the rule config
*/
configs?: Linter.Config | Linter.Config[];
/**
* The default filenames to use for type-aware tests.
* @default { js: 'file.js', jsx: 'file.jsx', ts: 'file.ts', tsx: 'file.tsx' }
*/
defaultFilenames?: Partial<DefaultFilenames>;
}
interface TestCasesOptions<RuleOptions = any, MessageId extends string = string> {
valid?: (ValidTestCase<RuleOptions> | string)[];
invalid?: (InvalidTestCase<RuleOptions, MessageId> | string)[];
/**
* Callback to be called after each test case
*/
onResult?: (_case: NormalizedTestCase<RuleOptions, MessageId>, result: Linter.FixReport) => void | Promise<void>;
}
//#endregion
//#region src/options.d.ts
declare function pickFlatConfigFromOptions(options: CompatConfigOptions): Linter.Config | undefined;
//#endregion
//#region src/rule-tester.d.ts
declare function createRuleTester<RuleOptions = any, MessageId extends string = string>(options: RuleTesterInitOptions): RuleTester<RuleOptions, MessageId>;
//#endregion
//#region src/run.d.ts
/**
* Shortcut to run test cases for a rule
*/
declare function run<RuleOptions = any, MessageId extends string = string>(options: TestCasesOptions<RuleOptions, MessageId> & RuleTesterInitOptions): Promise<void>;
/**
* Shortcut to run test cases for a rule in classic style
*/
declare function runClassic<RuleOptions = any, MessageId extends string = string>(ruleName: string, rule: RuleModule, cases: TestCasesOptions<RuleOptions, MessageId>, options?: RuleTesterInitOptions): Promise<void>;
//#endregion
//#region node_modules/.pnpm/@antfu+utils@9.3.0/node_modules/@antfu/utils/dist/index.d.mts
/**
* Remove common leading whitespace from a template string.
* Will also remove empty lines at the beginning and end.
* @category string
* @example
* ```ts
* const str = unindent`
* if (a) {
* b()
* }
* `
*/
declare function unindent(str: TemplateStringsArray | string): string;
//#endregion
//#region src/utils.d.ts
declare function normalizeTestCase<RuleOptions = any, MessageId extends string = string>(c: TestCase<RuleOptions, MessageId>, languageOptions: Linter.Config['languageOptions'], defaultFilenames: DefaultFilenames, type?: 'valid' | 'invalid'): NormalizedTestCase<RuleOptions, MessageId>;
declare function normalizeCaseError<MessageId extends string = string>(error: TestCaseError<MessageId> | MessageId, rule?: RuleModule): Partial<Linter.LintMessage>;
declare function isUsingTypeScriptParser(languageOptions: Linter.LanguageOptions): boolean;
declare function isUsingTypeScriptTypings(languageOptions: Linter.LanguageOptions): boolean;
//#endregion
export { unindent as $, unindent, type Awaitable, CompatConfigOptions, DefaultFilenames, InvalidTestCase, InvalidTestCaseBase, NormalizedTestCase, RuleModule, RuleTester, RuleTesterBehaviorOptions, RuleTesterInitOptions, TestCase, TestCaseError, TestCasesOptions, TestExecutionResult, ValidTestCase, ValidTestCaseBase, createRuleTester, isUsingTypeScriptParser, isUsingTypeScriptTypings, normalizeCaseError, normalizeTestCase, pickFlatConfigFromOptions, run, runClassic };