or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-espower-typescript

Power-assert instrumentor for TypeScript that provides zero-config and programmatic integration

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

To install, run

npx @tessl/cli install tessl/npm-espower-typescript@10.0.0

index.mddocs/

espower-typescript

espower-typescript is a power-assert instrumentor for TypeScript that enables enhanced assertion failure messages by capturing and displaying runtime values of intermediate expressions in test assertions. It provides seamless integration with TypeScript test suites through both zero-config and programmatic approaches.

Package Information

  • Package Name: espower-typescript
  • Package Type: npm
  • Language: JavaScript/TypeScript
  • Installation: npm install -D espower-typescript power-assert mocha typescript @types/node @types/mocha

Core Imports

Programmatic API:

const espowerTypeScript = require("espower-typescript");

Zero-config mode (no import needed):

# Use via Mocha --require flag
mocha --require espower-typescript/guess "test/**/*.ts"

Basic Usage

Zero-Config Mode (Recommended)

The simplest way to use espower-typescript is through the zero-config mode that automatically detects your project configuration:

# Install dependencies
npm install -D espower-typescript power-assert mocha typescript @types/node @types/mocha

# Run tests with power-assert instrumentation
mocha --require espower-typescript/guess "test/**/*.ts"

Test file example:

// test/example.ts
import assert = require('assert');

describe('Array#join', () => {
  it('joins all elements into a string with separator', () => {
    assert(['a', 'b', 'c'].join(':') === 'a:b:c:');
  });
});

Output with enhanced assertion messages:

AssertionError [ERR_ASSERTION]:   # test.ts:6

assert(['a','b','c'].join(':') === 'a:b:c:')
       |             |         |
       ["a","b","c"] "a:b:c"   false

Programmatic Mode

For custom integration scenarios, use the programmatic API:

const espowerTypeScript = require("espower-typescript");

// Configure and register TypeScript instrumentation
espowerTypeScript({
  cwd: process.cwd(),
  pattern: "test/**/*.ts",
  extensions: ["ts", "tsx"],
  // espower-source options can be included
  destructive: false,
  sourceRoot: "./src"
}, {
  // ts-node options (optional)
  transpileOnly: true,
  compilerOptions: {
    module: "commonjs"
  }
});

Architecture

espower-typescript consists of three main components:

  • Main Module: Programmatic API for custom integration with configurable options
  • Guess Module: Zero-config mode with automatic project detection and intelligent defaults
  • TypeScript Integration: Seamless ts-node integration with source-map support for accurate debugging

The library works by registering custom require.extensions handlers that intercept TypeScript file loading, compile them via ts-node, and apply power-assert instrumentation to matching files. Instrumented source code is cached internally for source map support and performance optimization.

Capabilities

Main Instrumentor Function

Registers TypeScript compilation and power-assert instrumentation for specified file patterns.

/**
 * Register TypeScript compilation and power-assert instrumentation
 * @param {Object} options - Configuration options for espower instrumentation
 * @param {string} [options.cwd] - Current working directory, defaults to process.cwd()
 * @param {string} options.pattern - Glob pattern for files to instrument
 * @param {string[]} [options.extensions] - File extensions to process, defaults to ["ts", "tsx"]
 * @param {boolean} [options.destructive] - Enable destructive AST transformation (espower-source option)
 * @param {string} [options.sourceRoot] - Source root directory for source maps (espower-source option)
 * @param {Object} [options.sourceMap] - Source map configuration (espower-source option)
 * @param {Object} [tsNodeOptions] - Options passed to ts-node register
 * @returns {void} - Function registers require.extensions hooks and returns nothing
 */
function espowerTypeScript(options, tsNodeOptions);

Zero-Config Mode

Automatic configuration mode that intelligently detects project settings and applies appropriate defaults.

Usage: --require espower-typescript/guess

Automatic Detection:

  • Test Directory: Uses test by default, or reads from package.json directories.test
  • File Extensions: ["ts", "tsx"] by default, adds ["js", "jsx"] if allowJs: true in tsconfig.json
  • TypeScript Config: Automatically loads and parses tsconfig.json from project root
  • Glob Pattern: Constructs pattern as {testDir}/**/*.@({extensions})

Configuration Options

Options object for the programmatic API:

interface EspowerOptions {
  /** Current working directory, defaults to process.cwd() */
  cwd?: string;
  /** Glob pattern for files to instrument (required) */
  pattern: string;
  /** File extensions to process, defaults to ["ts", "tsx"] */
  extensions?: string[];
  /** Enable destructive AST transformation (passed to espower-source) */
  destructive?: boolean;
  /** Source root directory for source maps (passed to espower-source) */
  sourceRoot?: string;
  /** Source map configuration object (passed to espower-source) */
  sourceMap?: Object;
  /** Additional espower-source options - see espower-source documentation for complete list */
  [key: string]: any;
}

TypeScript Node Options

Optional configuration passed to ts-node for TypeScript compilation:

interface TsNodeOptions {
  /** Disable type checking for faster compilation */
  transpileOnly?: boolean;
  /** Custom TypeScript compiler options */
  compilerOptions?: Object;
  /** Additional file extensions to register */
  extensions?: string[];
  /** Custom TypeScript configuration file path */
  project?: string;
  /** Skip project config option loading */
  skipProject?: boolean;
  /** Skip ignore option loading */
  skipIgnore?: boolean;
  /** Custom module type to use for compilation */
  moduleTypes?: Object;
  /** Enable experimental ESM loader */
  experimentalEsmLoader?: boolean;
  /** Additional ts-node options - see ts-node documentation for complete list */
  [key: string]: any;
}

Advanced Usage

Custom Test Directory

Configure test directory in package.json:

{
  "name": "your-module",
  "directories": {
    "test": "spec/"
  }
}

Then run:

mocha --require espower-typescript/guess "spec/**/*.ts"

TypeScript Configuration

espower-typescript automatically loads your tsconfig.json. Common configurations:

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "ES5",
    "jsx": "react",
    "allowJs": true
  }
}

Performance Optimization

Use transpile-only mode to skip type checking:

TS_NODE_TRANSPILE_ONLY=1 mocha --require espower-typescript/guess "test/**/*.ts"

JSX/React Support

espower-typescript supports .tsx files and React JSX out of the box:

// test/component.test.tsx
import assert = require('assert');
import React from 'react';
import MyComponent from '../src/MyComponent';

describe('React Component', () => {
  it('renders correctly', () => {
    const element = <MyComponent />;
    assert(element.type === MyComponent);
  });
});

Multiple File Extensions

When allowJs: true is set in tsconfig.json, espower-typescript automatically includes JavaScript files:

  • TypeScript: .ts, .tsx
  • JavaScript: .js, .jsx (when allowJs enabled)

Error Handling

Configuration Errors

  • Missing tsconfig.json: Gracefully degrades to default TypeScript options
  • Invalid tsconfig.json: Throws descriptive error with TypeScript compiler message
  • Missing test directory: Pattern matching simply finds no files to instrument

Runtime Behavior

  • Non-matching files: Bypass instrumentation, use original require.extensions handler
  • Compilation errors: Delegated to ts-node's error handling system
  • Source maps: Automatically corrected for accurate line numbers in error messages

Integration Notes

Test Framework Compatibility

espower-typescript works with any test framework that supports require hooks:

  • Mocha: mocha --require espower-typescript/guess
  • Jest: Configure in jest.config.js setupFiles
  • Ava: Use --require flag or ava.config.js

Assert Library Requirements

Important: Use CommonJS-style import for the assert module:

// Correct
import assert = require('assert');

// Incorrect - won't work with power-assert
import assert from 'assert';

Source Map Support

espower-typescript includes built-in source-map-support with custom file retrieval to ensure error stack traces point to original TypeScript source files rather than compiled JavaScript.

Module Exports

Main Module (espower-typescript)

/**
 * Default export: the main espowerTypeScript function
 * @module espower-typescript
 */
module.exports = espowerTypeScript;

Guess Module (espower-typescript/guess)

/**
 * Self-executing module that automatically configures and registers espower-typescript
 * No exports - side-effects only module that calls espowerTypeScript with auto-detected options
 * @module espower-typescript/guess
 */
// No explicit exports - executes espowerTypeScript() with auto-detected configuration

Internal Implementation Details

File Processing Pipeline

  1. File Interception: Custom require.extensions handlers intercept .ts, .tsx (and .js, .jsx when allowJs is enabled)
  2. Pattern Matching: Files are matched against the provided glob pattern using minimatch
  3. TypeScript Compilation: Matching files are compiled via ts-node with provided options
  4. Power-Assert Instrumentation: Compiled JavaScript is processed by espower-source for assertion enhancement
  5. Source Caching: Instrumented source is cached for source map retrieval and performance
  6. Module Loading: Final instrumented code is executed in the Node.js module system

Source Map Handling

espower-typescript installs a custom source-map-support configuration that:

  • Retrieves cached source: Uses internal sourceCache for accurate source map resolution
  • Preserves TypeScript origins: Maps error locations back to original .ts/.tsx files
  • Integrates with debugging: Provides correct line numbers and file paths in stack traces

Dependency Integration

espower-typescript integrates with several key dependencies:

/**
 * Core dependencies and their roles in the instrumentation process
 */
interface DependencyIntegration {
  /** espower-source: Provides the actual power-assert AST instrumentation */
  espowerSource: {
    function: "Instruments JavaScript AST with power-assert enhancements";
    options: "Accepts all espower-source configuration options";
  };
  /** ts-node: Handles TypeScript to JavaScript compilation */
  tsNode: {
    function: "Compiles TypeScript files to JavaScript on-the-fly";
    registration: "Uses ts-node.register() with provided options";
  };
  /** minimatch: Provides glob pattern matching for file filtering */
  minimatch: {
    function: "Matches file paths against provided glob patterns";
    usage: "Determines which files should be instrumented";
  };
  /** source-map-support: Provides accurate stack traces */
  sourceMapSupport: {
    function: "Maps compiled JavaScript errors back to TypeScript source";
    customization: "Uses custom retrieveFile function with sourceCache";
  };
}