or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-eslint-plugin-no-only-tests

ESLint plugin that prevents committing focused tests by detecting .only blocks in test files

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/eslint-plugin-no-only-tests@3.3.x

To install, run

npx @tessl/cli install tessl/npm-eslint-plugin-no-only-tests@3.3.0

index.mddocs/

ESLint Plugin No Only Tests

ESLint Plugin No Only Tests is a focused ESLint plugin that prevents developers from accidentally committing focused tests (using .only methods) to version control. It supports multiple JavaScript testing frameworks including Mocha, Jest, Jasmine, and others by detecting test blocks like describe.only, it.only, test.only, and similar patterns.

Package Information

  • Package Name: eslint-plugin-no-only-tests
  • Package Type: npm
  • Language: JavaScript (with TypeScript JSDoc annotations)
  • Installation: npm install --save-dev eslint-plugin-no-only-tests
  • Node.js Version: >= 5.0.0
  • TypeScript Support: JSDoc annotations with import('eslint') and import('estree') types

Core Imports

This package is designed to be consumed as an ESLint plugin and is configured in your ESLint configuration rather than imported directly into your code.

ESLint configuration (.eslintrc.json):

{
  "plugins": ["no-only-tests"],
  "rules": {
    "no-only-tests/no-only-tests": "error"
  }
}

Basic Usage

After installing and configuring the plugin, ESLint will automatically detect and report focused test blocks:

// This will trigger an error
describe.only("Some test suite", function() {
  it("should pass", function() {
    // test code
  });
});

// This will trigger an error  
it.only("Some test", function() {
  // test code
});

// This is allowed
describe("Some test suite", function() {
  it("should pass", function() {
    // test code
  });
});

Architecture

The plugin follows the standard ESLint plugin architecture:

  • Plugin Entry Point: Main plugin object with rules configuration
  • Rule Implementation: Single ESLint rule module with AST visitor pattern
  • Configuration Schema: JSON schema validation for rule options
  • Pattern Matching: AST traversal to detect focused test patterns
  • Auto-fixing: Optional automatic removal of .only calls

Capabilities

ESLint Plugin Configuration

Main plugin export providing ESLint with available rules.

module.exports = {
  rules: {
    "no-only-tests": require("./rules/no-only-tests")
  }
};

No Only Tests Rule

The core ESLint rule that detects and optionally fixes focused test patterns.

/** @type {import('eslint').Rule.RuleModule} */
const ESLintRuleModule = {
  meta: {
    docs: {
      description: "disallow .only blocks in tests";
      category: "Possible Errors";
      recommended: true;
      url: "https://github.com/levibuzolic/eslint-plugin-no-only-tests";
    };
    fixable: "code";
    schema: [{
      type: "object";
      properties: {
        block: {
          type: "array";
          items: { type: "string" };
          uniqueItems: true;
          default: defaultOptions.block;
        };
        focus: {
          type: "array"; 
          items: { type: "string" };
          uniqueItems: true;
          default: defaultOptions.focus;
        };
        functions: {
          type: "array";
          items: { type: "string" };
          uniqueItems: true;
          default: defaultOptions.functions;
        };
        fix: {
          type: "boolean";
          default: defaultOptions.fix;
        };
      };
      additionalProperties: false;
    }];
  };
  create(context: import('eslint').Rule.RuleContext): {
    Identifier(node: import('estree').Node): void;
  };
};

Rule Options

The rule accepts comprehensive configuration options for customizing detection patterns.

/** @typedef {{block?: string[], focus?: string[], functions?: string[], fix?: boolean}} RuleOptions */
interface RuleOptions {
  /** Array of test block names to detect (supports wildcard matching with '*' suffix) */
  block?: string[];
  /** Array of focus method names to detect */
  focus?: string[];
  /** Array of forbidden function names (e.g., 'fit', 'xit') */
  functions?: string[];
  /** Enable auto-fixing to remove .only calls */
  fix?: boolean;
}

Default Options:

/** @type {RuleOptions} */
const defaultOptions = {
  block: [
    "describe", "it", "context", "test", "tape", "fixture", "serial",
    "Feature", "Scenario", "Given", "And", "When", "Then"
  ],
  focus: ["only"],
  functions: [],
  fix: false
};

Configuration Examples

Basic Configuration:

{
  "rules": {
    "no-only-tests/no-only-tests": "error"
  }
}

Custom Test Blocks and Focus Methods:

{
  "rules": {
    "no-only-tests/no-only-tests": [
      "error",
      {
        "block": ["test", "it", "assert"],
        "focus": ["only", "focus"]
      }
    ]
  }
}

Wildcard Block Matching:

{
  "rules": {
    "no-only-tests/no-only-tests": [
      "error",
      {
        "block": ["test*"]
      }
    ]
  }
}

Function Blacklisting:

{
  "rules": {
    "no-only-tests/no-only-tests": [
      "error",
      {
        "functions": ["fit", "xit"]
      }
    ]
  }
}

Auto-fixing Enabled:

{
  "rules": {
    "no-only-tests/no-only-tests": [
      "error",
      {
        "fix": true
      }
    ]
  }
}

Supported Testing Frameworks

The plugin supports detection patterns for multiple JavaScript testing frameworks:

  • Mocha: describe.only, it.only, context.only
  • Jest: describe.only, it.only, test.only
  • Jasmine: describe.only, it.only
  • Tape: tape.only
  • AVA: Configurable with custom block names
  • Mocha Cakes 2: Feature.only, Scenario.only, Given.only, And.only, When.only, Then.only
  • Custom Frameworks: Fully configurable block and focus method names

Error Messages and Behavior

Pattern-based Errors:

  • Format: "{callPath} not permitted" (e.g., "describe.only not permitted")
  • Supports complex call chains: "it.default.before.only not permitted"

Function-based Errors:

  • Format: "{functionName} not permitted" (e.g., "fit not permitted")

Auto-fixing Behavior:

  • When fix: true is enabled, automatically removes the focus method (e.g., converts describe.only(...) to describe(...))
  • Only applies to pattern-based detections, not function-based ones
  • Uses fixer.removeRange([rangeStart - 1, rangeEnd]) to remove the focus method including the preceding dot
  • Requires valid range information (node.range must be available)
  • Safe transformation that preserves all other code structure

Advanced Pattern Detection

Wildcard Matching:

  • Block names ending with * enable prefix matching using block.replace(/\*$/, "")
  • Example: "test*" matches testResource.only, testExample.only
  • Non-wildcard blocks require exact ${block}. prefix match

Call Chain Analysis:

  • Detects nested method calls: it.default.before.only
  • Handles object property access patterns
  • Preserves context through complex AST traversal using getCallPath() function

AST Node Processing:

  • Uses ESLint's Identifier visitor pattern
  • Analyzes parent object relationships with null safety checks
  • Constructs call paths for accurate pattern matching
  • Uses find() for block matching, indexOf() for focus/function matching

Internal Utilities

getCallPath Function

Recursively constructs call path strings from ESTree AST nodes for pattern matching.

/**
 * Recursively constructs call path from AST node
 * @param {import('estree').Node} node - The AST node to analyze
 * @param {string[]} path - Accumulated path array (defaults to empty array)
 * @returns {string[]} Array of path components representing the call chain
 */
function getCallPath(node, path = []);

Implementation Details:

  • Handles object, property, callee, and name node properties
  • Recursive traversal with path accumulation
  • Supports complex call chains like it.default.before.only
  • Uses type guards to safely access node properties

TypeScript Types and Dependencies

The plugin relies on external TypeScript type definitions:

// Core ESLint types
import('eslint').Rule.RuleModule;
import('eslint').Rule.RuleContext;

// ESTree AST node types
import('estree').Node;

Key ESLint Interfaces:

  • Rule.RuleModule - Complete rule definition structure
  • Rule.RuleContext - Runtime context provided by ESLint
  • RuleFixer - Auto-fix interface with removeRange() method

ESTree Node Properties:

  • node.range?.[0] and node.range?.[1] - Source location ranges
  • node.parent - Parent AST node reference
  • node.name - Identifier name for Identifier nodes
  • node.object and node.property - Member expression components