Tooling to test ESLint rules with comprehensive TypeScript support and advanced testing capabilities
—
Core rule testing functionality providing comprehensive test execution, validation, and reporting for ESLint rules with enhanced TypeScript support.
The main class for testing ESLint rules with TypeScript integration and advanced validation features.
/**
* Rule testing engine that extends ESLint's native testing with TypeScript support
*/
class RuleTester extends TestFramework {
/**
* Creates a new RuleTester instance with optional configuration
* @param testerConfig - Configuration extending ESLint's flat config with TypeScript options
*/
constructor(testerConfig?: RuleTesterConfig);
}Usage Examples:
import { RuleTester } from "@typescript-eslint/rule-tester";
// Basic usage with default TypeScript parser
const ruleTester = new RuleTester();
// Advanced configuration with custom options
const ruleTester = new RuleTester({
defaultFilenames: {
ts: "test.ts",
tsx: "test.tsx",
},
languageOptions: {
parserOptions: {
project: "./tsconfig.json",
ecmaFeatures: {
jsx: true,
},
},
},
dependencyConstraints: {
typescript: ">=4.0.0",
},
});
// Configuration for specific test environments
const ruleTester = new RuleTester({
languageOptions: {
globals: {
window: "readonly",
document: "readonly",
},
env: {
browser: true,
es2022: true,
},
},
});Executes comprehensive tests for a rule with both valid and invalid test cases.
/**
* Runs tests for a specific rule with both valid and invalid test cases
* @param ruleName - Name of the rule being tested
* @param rule - The rule module to test
* @param test - Object containing arrays of valid and invalid test cases
*/
run<MessageIds extends string, Options extends readonly unknown[]>(
ruleName: string,
rule: RuleModule<MessageIds, Options>,
test: RunTests<MessageIds, Options>
): void;Usage Examples:
import { RuleTester } from "@typescript-eslint/rule-tester";
import { myRule } from "./my-rule";
const ruleTester = new RuleTester();
ruleTester.run("my-rule", myRule, {
valid: [
// Simple string test cases
"const x = 1;",
"function foo() { return 'hello'; }",
// Complex test cases with configuration
{
code: "interface User { name: string; }",
name: "interface declaration",
languageOptions: {
parserOptions: {
project: "./tsconfig.json",
},
},
},
// Test with specific options
{
code: "type Status = 'active' | 'inactive';",
options: [{ allowUnionTypes: true }],
},
],
invalid: [
{
code: "var x = 1;",
errors: [{ messageId: "noVar", line: 1, column: 1 }],
output: "const x = 1;",
},
// Multi-pass autofix
{
code: "var a = 1; var b = 2;",
errors: [
{ messageId: "noVar", line: 1, column: 1 },
{ messageId: "noVar", line: 1, column: 12 },
],
output: ["let a = 1; var b = 2;", "let a = 1; let b = 2;"],
},
// Test with suggestions
{
code: "function foo(x: any) { return x; }",
errors: [{
messageId: "noAny",
suggestions: [{
messageId: "useUnknown",
output: "function foo(x: unknown) { return x; }",
}],
}],
},
],
});Registers a rule for testing within the RuleTester instance.
/**
* Defines a rule for testing with the given name and rule module
* @param name - The name to register the rule under
* @param rule - The rule module (function or object with create method)
*/
defineRule(name: string, rule: AnyRuleModule): void;Usage Examples:
import { RuleTester } from "@typescript-eslint/rule-tester";
const ruleTester = new RuleTester();
// Define a custom rule
ruleTester.defineRule("no-var", {
meta: {
type: "suggestion",
docs: {
description: "disallow var declarations",
},
fixable: "code",
messages: {
noVar: "Use 'const' or 'let' instead of 'var'",
},
},
create(context) {
return {
VariableDeclaration(node) {
if (node.kind === "var") {
context.report({
node,
messageId: "noVar",
fix(fixer) {
return fixer.replaceText(node, node.source().replace("var", "const"));
},
});
}
},
};
},
});
// Use the defined rule in tests
ruleTester.run("no-var", ruleTester.rules["no-var"], {
valid: ["const x = 1;"],
invalid: [{
code: "var x = 1;",
errors: [{ messageId: "noVar" }],
output: "const x = 1;",
}],
});The RuleTester integrates with various test frameworks through inherited properties that can be customized.
/**
* Test framework integration properties (inherited from TestFramework)
*/
class RuleTester {
/** Function that runs after all tests complete */
static afterAll: AfterAll;
/** Function to create test groupings */
static describe: RuleTesterTestFrameworkFunction;
/** Function to skip test groupings */
static describeSkip: RuleTesterTestFrameworkFunctionBase;
/** Function to create individual tests */
static it: RuleTesterTestFrameworkItFunction;
/** Function to run tests exclusively */
static itOnly: RuleTesterTestFrameworkFunctionBase;
/** Function to skip individual tests */
static itSkip: RuleTesterTestFrameworkFunctionBase;
}Usage Examples:
import { RuleTester } from "@typescript-eslint/rule-tester";
// Custom test framework integration (e.g., for Mocha)
RuleTester.describe = (title, fn) => {
describe(title, fn);
};
RuleTester.it = (title, fn) => {
it(title, fn);
};
RuleTester.itOnly = (title, fn) => {
it.only(title, fn);
};
// For Jest (usually works by default)
RuleTester.describe = describe;
RuleTester.it = test;
RuleTester.itOnly = test.only;type RuleModule<MessageIds extends string, Options extends readonly unknown[]> = {
meta: RuleMeta<MessageIds>;
create: (context: RuleContext<MessageIds, Options>) => RuleListener;
};
type AnyRuleModule = RuleModule<string, readonly unknown[]>;
type AnyRuleCreateFunction = (context: any) => RuleListener;
interface RuleMeta<MessageIds extends string> {
type: "problem" | "suggestion" | "layout";
docs?: {
description: string;
category?: string;
recommended?: boolean;
url?: string;
};
fixable?: "code" | "whitespace";
hasSuggestions?: boolean;
messages: Record<MessageIds, string>;
schema?: JSONSchema.JSONSchema4 | JSONSchema.JSONSchema4[];
}
interface RuleListener {
[key: string]: ((node: any) => void) | undefined;
}Install with Tessl CLI
npx tessl i tessl/npm-typescript-eslint--rule-tester