Helper function to support fixtures for Babel's testing infrastructure
npx @tessl/cli install tessl/npm-babel--helper-fixtures@7.28.0Babel Helper Fixtures provides utilities for managing test fixtures in Babel's testing infrastructure. It enables developers to organize and process test cases with structured input/output patterns, supporting comprehensive fixture parsing that handles different test formats (directories and files), validates test outputs and source maps, manages test options and configurations, and provides filtering mechanisms for platform and Node.js version compatibility.
npm install @babel/helper-fixturesimport get, { multiple, readFile, resolveOptionPluginOrPreset } from "@babel/helper-fixtures";
import type { Test, TestFile, TaskOptions } from "@babel/helper-fixtures";For CommonJS:
const get = require("@babel/helper-fixtures").default;
const { multiple, readFile, resolveOptionPluginOrPreset } = require("@babel/helper-fixtures");import get from "@babel/helper-fixtures";
// Parse test fixtures from a directory
const suites = get("/path/to/test/fixtures");
// Process each test suite
suites.forEach(suite => {
console.log(`Suite: ${suite.title}`);
suite.tests.forEach(test => {
if (!test.disabled) {
console.log(` Test: ${test.title}`);
console.log(` Input: ${test.actual.code}`);
console.log(` Expected: ${test.expect.code}`);
}
});
});The @babel/helper-fixtures package is built around several key components that work together to provide comprehensive test fixture management:
get() function recursively scans directories to discover and parse test cases, handling both directory-based and file-based test structuresThe package follows a hierarchical structure where test suites contain multiple test cases, each with input/output files, configuration options, and validation criteria. This design enables systematic test organization and automated test discovery in large codebases like the Babel monorepo.
Parses a directory of test fixtures and returns an array of test suites with all contained tests.
/**
* Main fixture parser that processes a directory of test suites
* @param entryLoc - Path to directory containing test suites
* @returns Array of parsed test suites
*/
function get(entryLoc: string): Suite[];Usage Example:
import get from "@babel/helper-fixtures";
const fixtures = get("./test/fixtures");
fixtures.forEach(suite => {
suite.tests.forEach(test => {
// Process test case
if (test.actual.code && test.expect.code) {
// Run transformation test
} else if (test.exec.code) {
// Run execution test
}
});
});Processes multiple fixture categories from a directory, returning a record mapping category names to suite arrays.
/**
* Processes multiple fixture categories from a directory
* @param entryLoc - Path to directory containing fixture categories
* @param ignore - Optional array of category names to ignore
* @returns Record mapping category names to suite arrays
*/
function multiple(entryLoc: string, ignore?: Array<string>): Record<string, Suite[]>;Usage Example:
import { multiple } from "@babel/helper-fixtures";
const categories = multiple("./test/fixtures", ["deprecated"]);
Object.entries(categories).forEach(([categoryName, suites]) => {
console.log(`Category: ${categoryName}`);
suites.forEach(suite => {
// Process suite
});
});Safely reads file contents, returning empty string if file doesn't exist.
/**
* Utility function to safely read file contents
* @param filename - Path to file to read, can be undefined
* @returns File contents as string, empty string if file doesn't exist
*/
function readFile(filename: string | undefined): string;Usage Example:
import { readFile } from "@babel/helper-fixtures";
const inputCode = readFile("./test/input.js");
const outputCode = readFile("./test/output.js");
if (inputCode && outputCode) {
// Compare input and output
}Resolves plugins and presets defined in options.json files, handling relative paths and monorepo paths.
/**
* Resolves plugins/presets defined in options.json
* @param options - The imported options.json object
* @param optionsDir - Directory where options.json is placed
* @returns Options object with resolved plugins/presets
*/
function resolveOptionPluginOrPreset(
options: any,
optionsDir: string,
): any;Usage Example:
import { resolveOptionPluginOrPreset } from "@babel/helper-fixtures";
const rawOptions = {
plugins: ["./my-plugin", "syntax-jsx"],
presets: ["env"]
};
const resolvedOptions = resolveOptionPluginOrPreset(
rawOptions,
"/path/to/test/options"
);
// Plugins and presets now have resolved pathsinterface Test {
/** Directory containing the test */
taskDir: string;
/** Human-readable test title */
title: string;
/** Whether test is disabled and optional reason */
disabled: boolean | string;
/** Test configuration options */
options: TaskOptions;
/** Directory containing options.json */
optionsDir: string;
/** Source type configuration flag */
doNotSetSourceType: boolean;
/** External helpers configuration */
externalHelpers: boolean;
/** Whether to ignore output validation */
ignoreOutput: boolean;
/** Expected stdout content */
stdout: TestIO;
/** Expected stderr content */
stderr: TestIO;
/** Executable test file */
exec: TestFile;
/** Input/actual test file */
actual: TestFile;
/** Expected output file */
expect: TestFile;
/** Input source map */
inputSourceMap?: EncodedSourceMap;
/** Generated source map */
sourceMap: string;
/** Source map file reference */
sourceMapFile: TestFile;
/** Visual source map file */
sourceMapVisual: TestFile;
/** Whether to validate visual source maps */
validateSourceMapVisual: boolean;
/** Whether to validate stdout/stderr logs */
validateLogs: boolean;
}interface TestFile extends TestIO {
/** Name of the test file */
filename: string;
}
interface TestIO {
/** File location */
loc: string;
/** File content */
code: string;
}interface TaskOptions extends InputOptions {
/** Babel 8 compatibility flag */
BABEL_8_BREAKING?: boolean;
/** Source type setting flag */
DO_NOT_SET_SOURCE_TYPE?: boolean;
/** Skip during publishing */
SKIP_ON_PUBLISH?: boolean;
/** Use external helpers */
externalHelpers?: boolean;
/** Ignore output validation */
ignoreOutput?: boolean;
/** Minimum Node.js version required */
minNodeVersion?: string;
/** Minimum Node.js version for transforms */
minNodeVersionTransform?: string;
/** Generate source maps */
sourceMap?: boolean;
/** Target operating systems */
os?: string | string[];
/** Validate stdout/stderr logs */
validateLogs?: boolean;
/** Expected error message */
throws?: boolean | string;
/** Skip reason for Babel 7/8 compatibility */
SKIP_babel7plugins_babel8core?: string;
}Note: Suite is an internal type used by the main functions but not directly exported.
interface Suite {
/** Suite-level options */
options: TaskOptions;
/** Array of test cases */
tests: Array<Test>;
/** Suite title */
title: string;
/** Suite directory path */
filename: string;
}import type { InputOptions } from "@babel/core";
import type { EncodedSourceMap } from "@jridgewell/gen-mapping";Note: These are internal constants used by the package but not exported.
/** Supported file extensions for test files */
const EXTENSIONS: string[] = [".js", ".mjs", ".ts", ".tsx", ".cts", ".mts", ".vue"];
/** Supported extensions including JSON */
const JSON_AND_EXTENSIONS: string[] = [".json", ...EXTENSIONS];The fixture parser expects test directories to follow these conventions:
test-name/
├── input.js # Input file to transform
├── output.js # Expected output file
├── exec.js # Alternative: executable test file
├── options.json # Test configuration options
├── stdout.txt # Expected stdout output
├── stderr.txt # Expected stderr output
├── source-map.json # Expected source map
└── input-source-map.json # Input source mapIndividual test files are also supported:
test-name.js # Single executable test fileThe package includes a JSON schema for validating test options: