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

dependency-constraints.mddocs/

Dependency Constraints

Environment dependency validation system for conditional test execution based on package versions and availability.

Capabilities

Dependency Constraint System

Version constraint specification for conditional test execution based on environment requirements.

/**
 * Map of package names to version constraints for conditional test execution
 */
type DependencyConstraint = Readonly<Record<string, VersionConstraint>>;

/**
 * Version constraint specification - either a simple version string or complex semver range
 */
type VersionConstraint = AtLeastVersionConstraint | SemverVersionConstraint;

Usage Examples:

import { RuleTester } from "@typescript-eslint/rule-tester";

// Test suite with TypeScript version constraint
const ruleTester = new RuleTester({
  dependencyConstraints: {
    typescript: ">=4.0.0",
  },
});

// Individual test case with multiple constraints
const testCase = {
  code: "const x: bigint = 123n;",
  dependencyConstraints: {
    typescript: ">=3.2.0",
    "@typescript-eslint/parser": ">=4.0.0",
    node: ">=10.4.0",
  },
};

Simple Version Constraints

Shorthand version constraints using "at least version" format.

/**
 * Minimum version constraint shorthand (equivalent to '>=' constraint)
 */
type AtLeastVersionConstraint =
  | `${number}.${number}.${number}-${string}` // e.g., "4.1.0-beta"
  | `${number}.${number}.${number}`           // e.g., "4.1.0"
  | `${number}.${number}`                     // e.g., "4.1"
  | `${number}`;                              // e.g., "4"

Usage Examples:

const constraints = {
  // Exact version with prerelease
  typescript: "4.1.0-beta.1" as AtLeastVersionConstraint,
  
  // Exact version
  eslint: "8.0.0" as AtLeastVersionConstraint,
  
  // Major.minor version
  node: "16.0" as AtLeastVersionConstraint,
  
  // Major version only
  npm: "7" as AtLeastVersionConstraint,
};

// Test case that only runs with TypeScript 4.5 or higher
const advancedTypeTest = {
  code: "type Template<T extends string> = `Hello ${T}`;",
  dependencyConstraints: {
    typescript: "4.5.0",
  },
};

Complex Version Constraints

Advanced semver range constraints with optional configuration.

/**
 * Advanced semver version constraint with range and options
 */
interface SemverVersionConstraint {
  /** Semver range string (e.g., "^4.0.0", ">=3.0.0 <5.0.0") */
  readonly range: string;
  /** Semver parsing and matching options */
  readonly options?: boolean | RangeOptions;
}

/**
 * Options for semver range parsing and matching
 */
interface RangeOptions {
  /** Include prerelease versions in range matching */
  includePrerelease?: boolean;
  /** Use loose semver parsing (more permissive) */
  loose?: boolean;
}

Usage Examples:

const complexConstraints: Record<string, SemverVersionConstraint> = {
  // Caret range (compatible versions)
  typescript: {
    range: "^4.0.0",
    options: { includePrerelease: false },
  },
  
  // Tilde range (patch-level changes)
  eslint: {
    range: "~8.0.0",
  },
  
  // Complex range with multiple conditions
  node: {
    range: ">=14.0.0 <18.0.0",
    options: { loose: true },
  },
  
  // Range with prerelease support
  "@typescript-eslint/parser": {
    range: ">=5.0.0-0",
    options: {
      includePrerelease: true,
      loose: false,
    },
  },
};

// Test case with complex version requirements
const modernSyntaxTest = {
  code: "const obj = { ...spread, newProp: 'value' };",
  dependencyConstraints: {
    typescript: {
      range: "^4.1.0",
      options: { includePrerelease: false },
    },
    node: {
      range: ">=12.0.0",
    },
  },
};

Practical Usage Patterns

Real-world examples of dependency constraints in test scenarios.

TypeScript Feature Testing:

// Test modern TypeScript features
const templateLiteralTest = {
  code: `
    type EventName<T extends string> = \`on\${Capitalize<T>}\`;
    type Handler = EventName<'click'>;
  `,
  dependencyConstraints: {
    typescript: "4.1.0", // Template literal types introduced in 4.1
  },
};

// Test conditional types (TypeScript 2.8+)
const conditionalTypeTest = {
  code: "type NonNullable<T> = T extends null | undefined ? never : T;",
  dependencyConstraints: {
    typescript: "2.8.0",
  },
};

Environment-Specific Testing:

// Node.js specific features
const nodeFeatureTest = {
  code: "import { Worker } from 'worker_threads';",
  dependencyConstraints: {
    node: "10.5.0", // Worker threads introduced in Node 10.5
  },
};

// ES Module support
const esmTest = {
  code: "export const value = await import('./module.js');",
  dependencyConstraints: {
    node: "14.0.0", // Top-level await in modules
  },
  languageOptions: {
    parserOptions: {
      sourceType: 'module',
      ecmaVersion: 2022,
    },
  },
};

Parser Version Testing:

// Test with specific parser capabilities
const parserFeatureTest = {
  code: "class Example { #private = 42; }",
  dependencyConstraints: {
    "@typescript-eslint/parser": "4.0.0", // Private fields support
    typescript: "3.8.0",
  },
};

// Test with ESLint version requirements
const eslintFeatureTest = {
  code: "const config = { rules: { 'new-rule': 'error' } };",
  dependencyConstraints: {
    eslint: {
      range: ">=8.0.0", // Modern ESLint features
    },
  },
};

Multi-Package Constraints:

// Test requiring multiple package versions
const fullStackTest = {
  code: `
    import type { Config } from '@typescript-eslint/utils';
    const config: Config = { rules: {} };
  `,
  dependencyConstraints: {
    typescript: ">=4.0.0",
    "@typescript-eslint/utils": "^5.0.0",
    "@typescript-eslint/parser": "^5.0.0",
    eslint: {
      range: ">=7.0.0 <9.0.0",
      options: { includePrerelease: false },
    },
  },
};

Constraint Configuration Strategies:

// Global constraints for entire test suite
const ruleTester = new RuleTester({
  dependencyConstraints: {
    typescript: ">=4.0.0", // Minimum TypeScript version for all tests
    node: ">=14.0.0",      // Minimum Node.js version
  },
});

// Override constraints for specific test cases
ruleTester.run("my-rule", myRule, {
  valid: [
    // Standard test (uses global constraints)
    "const x = 1;",
    
    // Advanced test with higher requirements
    {
      code: "const obj = { ...props, key: 'value' };",
      dependencyConstraints: {
        typescript: ">=4.2.0", // Object spread requires 4.2+
      },
    },
  ],
  invalid: [
    {
      code: "var x = 1;",
      errors: [{ messageId: "noVar" }],
      // Uses global constraints by default
    },
  ],
});

Constraint Validation

The dependency constraint system automatically validates environment requirements before executing tests:

  1. Package Detection: Automatically detects installed package versions
  2. Version Comparison: Uses semver-compatible version comparison
  3. Test Skipping: Gracefully skips tests when constraints aren't met
  4. Error Reporting: Provides clear messages when dependencies are missing or incompatible

Example Constraint Validation Messages:

✓ typescript@4.5.2 satisfies constraint ">=4.0.0"
⚠ Skipping test: node@12.22.0 does not satisfy constraint ">=14.0.0"
✗ Error: Package "@typescript-eslint/parser" not found, required by constraint ">=5.0.0"

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