or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-gulp-mocha

Run Mocha tests as a Gulp plugin with configurable options and stream processing

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/gulp-mocha@10.0.x

To install, run

npx @tessl/cli install tessl/npm-gulp-mocha@10.0.0

index.mddocs/

Gulp Mocha

Gulp Mocha is a Gulp plugin that provides a thin wrapper around the Mocha testing framework to enable running Mocha tests as part of Gulp build pipelines. It processes test files through Gulp's stream system and executes them using the Mocha CLI with configurable options.

Package Information

  • Package Name: gulp-mocha
  • Package Type: npm
  • Language: JavaScript (ES Modules)
  • Installation: npm install --save-dev gulp-mocha

Core Imports

import mocha from "gulp-mocha";

For CommonJS environments:

const mocha = require("gulp-mocha");

Basic Usage

import gulp from "gulp";
import mocha from "gulp-mocha";

export default () => (
  gulp.src("test.js", { read: false })
    // gulp-mocha needs file paths so you cannot have any plugins before it
    .pipe(mocha({ reporter: "nyan" }))
);

Capabilities

Test Execution

Executes Mocha tests through Gulp's stream processing with configurable options.

/**
 * Creates a Gulp plugin stream for running Mocha tests
 * @param options - Configuration options (optional)
 * @returns Gulp plugin stream that processes test files
 */
function mocha(options?: MochaOptions): NodeJS.ReadWriteStream;

interface MochaOptions {
  // Test Interface Options
  ui?: "bdd" | "tdd" | "qunit" | "exports";
  
  // Reporter Options  
  reporter?: string;
  reporterOptions?: Record<string, any>;
  
  // Test Execution Options
  timeout?: number;
  bail?: boolean;
  grep?: string;
  exit?: boolean;
  
  // Environment Options
  globals?: string[];
  checkLeaks?: boolean;
  colors?: boolean;
  
  // Module Loading Options
  require?: string[];
  compilers?: string;
  
  // Gulp-Mocha Specific Options
  suppress?: boolean;
  
  // Any other Mocha CLI option (passed through to mocha binary)
  // Options are automatically converted from camelCase to kebab-case
  // Arrays and objects are processed according to gulp-mocha rules
  [key: string]: any;
}

Usage Examples:

import gulp from "gulp";
import mocha from "gulp-mocha";

// Basic test execution
export const test = () => (
  gulp.src("test/*.js", { read: false })
    .pipe(mocha())
);

// With custom reporter and options
export const testDetailed = () => (
  gulp.src("test/**/*.js", { read: false })
    .pipe(mocha({
      reporter: "spec",
      timeout: 5000,
      require: ["test/helper.js"],
      ui: "bdd"
    }))
);

// With error handling
export const testWithErrorHandling = () => (
  gulp.src("test.js", { read: false })
    .pipe(mocha())
    .once("error", (err) => {
      console.error(err);
      process.exit(1);
    })
    .once("end", () => {
      process.exit();
    })
);

// Suppressed output for programmatic use
export const testQuiet = () => (
  gulp.src("test/*.js", { read: false })
    .pipe(mocha({ suppress: true }))
);

// Programmatic result access with pEvent (requires p-event package)
import { pEvent } from "p-event";

export const testWithResults = async () => {
  const stream = mocha({ suppress: true });
  const resultPromise = pEvent(stream, "_result");
  
  stream.end(new Vinyl({ path: "test/my-test.js" }));
  
  const { stdout, exitCode } = await resultPromise;
  console.log(`Tests completed with exit code: ${exitCode}`);
  console.log(`Output: ${stdout}`);
};

// Multiple require files pattern
export const testWithMultipleRequires = () => (
  gulp.src("test/**/*.js", { read: false })
    .pipe(mocha({
      require: [
        "test/setup.js",
        "test/helpers.js", 
        "babel-register"
      ],
      timeout: 5000
    }))
);

// Error handling with pEvent
export const testWithAsyncErrorHandling = async () => {
  const stream = mocha({ suppress: true });
  
  try {
    const resultPromise = pEvent(stream, "_result");
    const errorPromise = pEvent(stream, "error");
    
    stream.end(new Vinyl({ path: "test/failing-test.js" }));
    
    // Race between success and error
    const result = await Promise.race([
      resultPromise.then(r => ({ type: "success", data: r })),
      errorPromise.then(e => ({ type: "error", data: e }))
    ]);
    
    if (result.type === "error") {
      console.log("Test failures detected:", result.data.message);
      console.log("isPresentable:", result.data.isPresentable);
    } else {
      console.log("Tests passed:", result.data.stdout);
    }
  } catch (error) {
    console.error("Unexpected error:", error);
  }
};

Option Processing

The plugin automatically processes options to match Mocha CLI expectations using the following rules:

  • Arrays: Most array options are converted to comma-separated strings (e.g., ['glob1', 'glob2'] becomes 'glob1,glob2')
  • Special Array Handling: The require option can be specified multiple times and remains as an array
  • Objects: Converted to key=value comma-separated format (e.g., {foo: 'bar', biz: 'baz'} becomes 'foo=bar,biz=baz')
  • Boolean values: false values are ignored, true values become CLI flags
  • String/Number values: Passed through directly
  • Excluded options: The suppress option is handled internally and not passed to Mocha CLI

Internal Processing Logic:

// Special options that can be arrays (not converted to comma-separated)
const MULTIPLE_OPTIONS = new Set(['require']);

// Options excluded from CLI arguments  
const EXCLUDED_OPTIONS = ['suppress'];

// Processing rules applied to each option:
// 1. Arrays: Convert to comma-separated unless in MULTIPLE_OPTIONS
// 2. Objects: Convert to key=value comma-separated format  
// 3. Exclude specified options from CLI arguments
// 4. Use dargs with ignoreFalse: true for boolean handling

Stream Events

The plugin emits standard Gulp stream events plus custom events:

interface MochaStream extends NodeJS.ReadWriteStream {
  // Custom Events
  on(event: "_result", listener: (result: ExecaResult) => void): this;
  on(event: "error", listener: (error: MochaTestError) => void): this;
}

interface ExecaResult {
  stdout: string;
  stderr: string;
  exitCode: number;
  command: string;
  escapedCommand: string;
  failed: boolean;
  killed: boolean;
  signal?: string;
  signalDescription?: string;
  timedOut: boolean;
}

interface MochaTestError extends Error {
  message: "There were test failures";
  isPresentable: true;
}

Configuration Options

Test Interface Options

ui

  • Type: "bdd" | "tdd" | "qunit" | "exports"
  • Default: "bdd"
  • Description: The test interface to use

Reporter Options

reporter

  • Type: string
  • Default: "spec"
  • Description: The reporter that will be used. Supports built-in Mocha reporters and third-party reporters

reporterOptions

  • Type: Record<string, any>
  • Description: Reporter-specific configuration options
  • Example: { reportFilename: "index.html" }

Test Execution Options

timeout

  • Type: number
  • Default: 2000
  • Description: Test-case timeout in milliseconds

bail

  • Type: boolean
  • Default: false
  • Description: Bail on the first test failure

grep

  • Type: string
  • Description: Only run tests matching the given pattern (compiled to RegExp internally)

exit

  • Type: boolean
  • Description: Force exit after tests complete

Environment Options

globals

  • Type: string[]
  • Description: List of accepted global variable names. Supports wildcards (["YUI"], ["gulp*"], ["*"])

checkLeaks

  • Type: boolean
  • Default: false
  • Description: Check for global variable leaks

colors

  • Type: boolean
  • Default: Boolean(supportsColor.stdout) - Automatically detected based on stdout color support
  • Description: Enable/disable colored output. When not specified, automatically detects terminal color support using the supports-color library

Module Loading Options

require

  • Type: string[]
  • Description: Require custom modules before tests are run
  • Note: This option can be specified multiple times (not converted to comma-separated)

compilers

  • Type: string
  • Description: Specify a compiler
  • Example: "js:babel-core/register"

Gulp-Mocha Specific Options

suppress

  • Type: boolean
  • Default: false
  • Description: Suppress stdout/stderr output from the Mocha process. When true, the plugin will not pipe Mocha's output to the parent process streams, allowing for programmatic access to results via the _result event. This option is excluded from CLI arguments and handled internally by gulp-mocha.

Error Handling

The plugin handles test failures and process errors with specific behavior:

  • Test Failures (exitCode > 0): Creates a new Error with message "There were test failures" and isPresentable: true
  • Process Errors (other failures): Re-throws errors from the Mocha subprocess execution as-is
  • Stream Errors: Emits standard Node.js stream error events

Error Processing Logic:

try {
  const result = await subprocess; // execa mocha execution
  stream.emit('_result', result);
} catch (error) {
  if (error.exitCode > 0) {
    // Test failures - create presentable error
    const testError = new Error('There were test failures');
    testError.isPresentable = true;
    throw testError;
  }
  // Other process errors - re-throw as-is
  throw error;
}

Error Handling Examples:

// Basic error handling
gulp.src("test/*.js", { read: false })
  .pipe(mocha())
  .on("error", (error) => {
    if (error.isPresentable) {
      console.log("Tests failed:", error.message); // "There were test failures"
    } else {
      console.log("Process error:", error);
    }
  });

// Programmatic error detection
import { pEvent } from "p-event";

const stream = mocha({ suppress: true });
try {
  const errorPromise = pEvent(stream, "error");
  stream.end(new Vinyl({ path: "test/failing-test.js" }));
  
  const error = await errorPromise;
  console.log(error.message); // "There were test failures"
  console.log(error.isPresentable); // true
} catch (processError) {
  // Handle non-test-failure errors
  console.error("Process error:", processError);
}

Integration Notes

  • File Processing: The plugin requires file paths, so no other plugins can be used before it in the pipeline
  • Stream Compatibility: Works with Gulp's vinyl file streams
  • Process Execution: Uses execa for reliable subprocess handling with local binary preference
  • Output Handling: Automatically pipes Mocha output to process stdout/stderr unless suppressed

Internal Processing Details

The plugin performs the following internal operations:

Binary Resolution:

  • Uses execa with localDir: __dirname and preferLocal: true
  • Searches for mocha binary in local node_modules first, then PATH
  • Ensures consistent binary resolution across different environments

Command Construction:

  • Collects file paths from gulp stream into an array
  • Processes options through dargs utility with ignoreFalse: true
  • Excludes internal options (suppress) from CLI arguments
  • Constructs final command: mocha [...files, ...arguments]

Stream Processing:

  • Implements gulpPlugin with supportsAnyType: true
  • Collects all files during stream processing
  • Executes Mocha subprocess only on stream finish (onFinish)
  • Emits _result event with full execa result object

Output Management:

  • Conditionally pipes subprocess stdout/stderr to process streams based on suppress option
  • When suppress: false (default): subprocess.stdout.pipe(process.stdout)
  • When suppress: true: No output piping, results accessible via _result event

Dependencies

  • Mocha: ^10.2.0 - The underlying test framework
  • Execa: ^8.0.1 - Process execution utility
  • Dargs: ^8.1.0 - Command line argument processing
  • Gulp Plugin Extras: ^0.3.0 - Gulp plugin utilities
  • Supports Color: ^9.4.0 - Terminal color support detection

Platform Requirements

  • Node.js: >=18
  • Peer Dependencies: gulp >=4 (optional)