CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-typescript-eslint--rule-tester

Tooling to test ESLint rules with comprehensive TypeScript support and advanced testing capabilities

Pending
Overview
Eval results
Files

rule-testing.mddocs/

Rule Testing Engine

Core rule testing functionality providing comprehensive test execution, validation, and reporting for ESLint rules with enhanced TypeScript support.

Capabilities

RuleTester Class

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,
    },
  },
});

Rule Execution

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; }",
        }],
      }],
    },
  ],
});

Rule Definition

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;",
  }],
});

Test Framework Integration

The RuleTester integrates with various test frameworks through inherited properties that can be customized.

Framework Properties

/**
 * 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 Definitions

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

docs

dependency-constraints.md

global-configuration.md

index.md

rule-testing.md

test-cases.md

utilities.md

tile.json