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.
npm install -D espower-typescript power-assert mocha typescript @types/node @types/mochaProgrammatic API:
const espowerTypeScript = require("espower-typescript");Zero-config mode (no import needed):
# Use via Mocha --require flag
mocha --require espower-typescript/guess "test/**/*.ts"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" falseFor 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"
}
});espower-typescript consists of three main components:
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.
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);Automatic configuration mode that intelligently detects project settings and applies appropriate defaults.
Usage: --require espower-typescript/guess
Automatic Detection:
test by default, or reads from package.json directories.test["ts", "tsx"] by default, adds ["js", "jsx"] if allowJs: true in tsconfig.jsontsconfig.json from project root{testDir}/**/*.@({extensions})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;
}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;
}Configure test directory in package.json:
{
"name": "your-module",
"directories": {
"test": "spec/"
}
}Then run:
mocha --require espower-typescript/guess "spec/**/*.ts"espower-typescript automatically loads your tsconfig.json. Common configurations:
{
"compilerOptions": {
"module": "commonjs",
"target": "ES5",
"jsx": "react",
"allowJs": true
}
}Use transpile-only mode to skip type checking:
TS_NODE_TRANSPILE_ONLY=1 mocha --require espower-typescript/guess "test/**/*.ts"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);
});
});When allowJs: true is set in tsconfig.json, espower-typescript automatically includes JavaScript files:
.ts, .tsx.js, .jsx (when allowJs enabled)espower-typescript works with any test framework that supports require hooks:
mocha --require espower-typescript/guessjest.config.js setupFiles--require flag or ava.config.jsImportant: Use CommonJS-style import for the assert module:
// Correct
import assert = require('assert');
// Incorrect - won't work with power-assert
import assert from 'assert';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.
espower-typescript)/**
* Default export: the main espowerTypeScript function
* @module espower-typescript
*/
module.exports = espowerTypeScript;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.ts, .tsx (and .js, .jsx when allowJs is enabled)espower-typescript installs a custom source-map-support configuration that:
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";
};
}