Tooling to test ESLint rules with comprehensive TypeScript support and advanced testing capabilities
—
Static configuration methods for managing default settings across all RuleTester instances and test execution control.
Static methods for setting and managing default configuration that applies to all RuleTester instances.
class RuleTester {
/**
* Sets the default configuration for all future RuleTester instances
* @param config - Configuration object that will be merged with existing defaults
*/
static setDefaultConfig(config: RuleTesterConfig): void;
/**
* Returns the current default configuration used for all tests
* @returns Read-only copy of the current default configuration
*/
static getDefaultConfig(): Readonly<RuleTesterConfig>;
/**
* Resets the configuration to the initial default state, removing any customizations
*/
static resetDefaultConfig(): void;
}Usage Examples:
import { RuleTester } from "@typescript-eslint/rule-tester";
// Set global defaults for all test suites
RuleTester.setDefaultConfig({
defaultFilenames: {
ts: "test.ts",
tsx: "test.tsx",
},
languageOptions: {
parserOptions: {
project: "./tsconfig.json",
ecmaVersion: 2022,
sourceType: "module",
},
},
dependencyConstraints: {
typescript: ">=4.0.0",
},
});
// All RuleTester instances will now use these defaults
const ruleTester1 = new RuleTester(); // Uses global config
const ruleTester2 = new RuleTester(); // Also uses global config
// Override specific settings while keeping global defaults
const ruleTester3 = new RuleTester({
languageOptions: {
parserOptions: {
// This will be merged with global config
ecmaFeatures: { jsx: true },
},
},
});
// Check current global configuration
const currentConfig = RuleTester.getDefaultConfig();
console.log(currentConfig.defaultFilenames); // { ts: "test.ts", tsx: "test.tsx" }
// Reset to original defaults
RuleTester.resetDefaultConfig();
const resetConfig = RuleTester.getDefaultConfig();
console.log(resetConfig.defaultFilenames); // { ts: "file.ts", tsx: "react.tsx" }Static methods for controlling individual test case execution with debugging and selective testing support.
class RuleTester {
/**
* Marks a valid test case to run exclusively (overloaded for string cases)
* @param item - Test case (string code) to mark as "only"
* @returns Test case object with only: true property
*/
static only<Options extends readonly unknown[]>(
item: string
): ValidTestCase<Options>;
/**
* Marks a valid test case to run exclusively (overloaded for object cases)
* @param item - Test case object to mark as "only"
* @returns Test case object with only: true property
*/
static only<Options extends readonly unknown[]>(
item: ValidTestCase<Options>
): ValidTestCase<Options>;
/**
* Marks an invalid test case to run exclusively
* @param item - Invalid test case object to mark as "only"
* @returns Test case object with only: true property
*/
static only<MessageIds extends string, Options extends readonly unknown[]>(
item: InvalidTestCase<MessageIds, Options>
): InvalidTestCase<MessageIds, Options>;
}Usage Examples:
import { RuleTester } from "@typescript-eslint/rule-tester";
const ruleTester = new RuleTester();
// Debug a specific test by running it exclusively
ruleTester.run("my-rule", myRule, {
valid: [
"const x = 1;", // Regular test
RuleTester.only("const y = 2;"), // Only this test will run
"const z = 3;", // This will be skipped
],
invalid: [
// All invalid tests will be skipped when valid tests have "only"
{
code: "var x = 1;",
errors: [{ messageId: "noVar" }],
},
],
});
// Debug a complex test case
const complexTest = RuleTester.only({
code: `
interface User {
name: string;
age: number;
}
`,
name: "complex interface test",
languageOptions: {
parserOptions: {
project: "./tsconfig.json",
},
},
});
ruleTester.run("interface-rule", interfaceRule, {
valid: [
"const x = 1;", // Skipped
complexTest, // Only this runs
],
invalid: [],
});
// Debug an invalid test case with autofix
const invalidTest = RuleTester.only({
code: "var x = 1;",
errors: [{ messageId: "noVar" }],
output: "const x = 1;",
name: "debug autofix behavior",
});
ruleTester.run("no-var-rule", noVarRule, {
valid: [], // All skipped
invalid: [
invalidTest, // Only this runs
{
code: "var y = 2;",
errors: [{ messageId: "noVar" }],
}, // Skipped
],
});Practical patterns for managing global configuration across test suites.
Project-Wide Configuration:
// setup-tests.ts - Global test setup file
import { RuleTester } from "@typescript-eslint/rule-tester";
// Set consistent defaults for entire project
RuleTester.setDefaultConfig({
defaultFilenames: {
ts: "test-file.ts",
tsx: "test-component.tsx",
},
languageOptions: {
parserOptions: {
project: "./tsconfig.test.json",
ecmaVersion: 2022,
sourceType: "module",
ecmaFeatures: {
jsx: true,
globalReturn: false,
},
},
globals: {
// Test environment globals
jest: "readonly",
describe: "readonly",
it: "readonly",
expect: "readonly",
},
},
dependencyConstraints: {
typescript: ">=4.5.0",
"@typescript-eslint/parser": ">=5.0.0",
},
});Environment-Specific Configuration:
// Configure for different environments
if (process.env.NODE_ENV === "test") {
RuleTester.setDefaultConfig({
languageOptions: {
env: {
jest: true,
node: true,
},
},
});
} else if (process.env.NODE_ENV === "browser-test") {
RuleTester.setDefaultConfig({
languageOptions: {
env: {
browser: true,
es2022: true,
},
globals: {
window: "readonly",
document: "readonly",
},
},
});
}Per-Suite Configuration:
// rule-tests/string-rules.test.ts
describe("String manipulation rules", () => {
beforeAll(() => {
RuleTester.setDefaultConfig({
// String-specific test configuration
languageOptions: {
parserOptions: {
ecmaVersion: 2020, // String methods available in ES2020
},
},
});
});
afterAll(() => {
RuleTester.resetDefaultConfig(); // Clean up for other test suites
});
const ruleTester = new RuleTester(); // Uses string-specific config
// Tests...
});Dynamic Configuration:
// Conditional configuration based on available packages
function setupRuleTester() {
const config: RuleTesterConfig = {
languageOptions: {
parserOptions: {
ecmaVersion: 2022,
sourceType: "module",
},
},
};
// Add TypeScript configuration if available
try {
require("typescript");
config.languageOptions!.parserOptions!.project = "./tsconfig.json";
config.dependencyConstraints = {
typescript: ">=4.0.0",
};
} catch {
// TypeScript not available, use JavaScript defaults
console.warn("TypeScript not found, using JavaScript-only configuration");
}
RuleTester.setDefaultConfig(config);
}
setupRuleTester();Understanding how configuration merging works with global defaults.
// Global configuration
RuleTester.setDefaultConfig({
defaultFilenames: {
ts: "global.ts",
tsx: "global.tsx",
},
languageOptions: {
parserOptions: {
ecmaVersion: 2020,
sourceType: "module",
},
globals: {
globalVar: "readonly",
},
},
});
// Instance configuration merges deeply
const ruleTester = new RuleTester({
defaultFilenames: {
ts: "instance.ts", // Overrides global setting
// tsx inherits "global.tsx" from global config
},
languageOptions: {
parserOptions: {
// ecmaVersion: 2020 inherited from global
// sourceType: "module" inherited from global
project: "./tsconfig.json", // Added to global config
},
globals: {
// globalVar: "readonly" inherited from global
instanceVar: "readonly", // Added to global config
},
},
});
// Effective configuration:
// {
// defaultFilenames: { ts: "instance.ts", tsx: "global.tsx" },
// languageOptions: {
// parserOptions: {
// ecmaVersion: 2020,
// sourceType: "module",
// project: "./tsconfig.json"
// },
// globals: {
// globalVar: "readonly",
// instanceVar: "readonly"
// }
// }
// }Install with Tessl CLI
npx tessl i tessl/npm-typescript-eslint--rule-tester