246 lines
5.1 KiB
TypeScript
246 lines
5.1 KiB
TypeScript
import * as plugins from './tstest.plugins.js';
|
|
import type { Runtime } from './tstest.classes.runtime.parser.js';
|
|
import { TapParser } from './tstest.classes.tap.parser.js';
|
|
|
|
/**
|
|
* Runtime-specific configuration options
|
|
*/
|
|
export interface RuntimeOptions {
|
|
/**
|
|
* Environment variables to pass to the runtime
|
|
*/
|
|
env?: Record<string, string>;
|
|
|
|
/**
|
|
* Additional command-line arguments
|
|
*/
|
|
extraArgs?: string[];
|
|
|
|
/**
|
|
* Working directory for test execution
|
|
*/
|
|
cwd?: string;
|
|
|
|
/**
|
|
* Timeout in milliseconds (0 = no timeout)
|
|
*/
|
|
timeout?: number;
|
|
}
|
|
|
|
/**
|
|
* Deno-specific configuration options
|
|
*/
|
|
export interface DenoOptions extends RuntimeOptions {
|
|
/**
|
|
* Permissions to grant to Deno
|
|
* Default: ['--allow-read', '--allow-env']
|
|
*/
|
|
permissions?: string[];
|
|
|
|
/**
|
|
* Path to deno.json config file
|
|
*/
|
|
configPath?: string;
|
|
|
|
/**
|
|
* Path to import map file
|
|
*/
|
|
importMap?: string;
|
|
}
|
|
|
|
/**
|
|
* Chromium-specific configuration options
|
|
*/
|
|
export interface ChromiumOptions extends RuntimeOptions {
|
|
/**
|
|
* Chromium launch arguments
|
|
*/
|
|
launchArgs?: string[];
|
|
|
|
/**
|
|
* Headless mode (default: true)
|
|
*/
|
|
headless?: boolean;
|
|
|
|
/**
|
|
* Port range for HTTP server
|
|
*/
|
|
portRange?: { min: number; max: number };
|
|
}
|
|
|
|
/**
|
|
* Command configuration returned by createCommand()
|
|
*/
|
|
export interface RuntimeCommand {
|
|
/**
|
|
* The main command executable (e.g., 'node', 'deno', 'bun')
|
|
*/
|
|
command: string;
|
|
|
|
/**
|
|
* Command-line arguments
|
|
*/
|
|
args: string[];
|
|
|
|
/**
|
|
* Environment variables
|
|
*/
|
|
env?: Record<string, string>;
|
|
|
|
/**
|
|
* Working directory
|
|
*/
|
|
cwd?: string;
|
|
}
|
|
|
|
/**
|
|
* Runtime availability check result
|
|
*/
|
|
export interface RuntimeAvailability {
|
|
/**
|
|
* Whether the runtime is available
|
|
*/
|
|
available: boolean;
|
|
|
|
/**
|
|
* Version string if available
|
|
*/
|
|
version?: string;
|
|
|
|
/**
|
|
* Error message if not available
|
|
*/
|
|
error?: string;
|
|
}
|
|
|
|
/**
|
|
* Abstract base class for runtime adapters
|
|
* Each runtime (Node, Chromium, Deno, Bun) implements this interface
|
|
*/
|
|
export abstract class RuntimeAdapter {
|
|
/**
|
|
* Runtime identifier
|
|
*/
|
|
abstract readonly id: Runtime;
|
|
|
|
/**
|
|
* Human-readable display name
|
|
*/
|
|
abstract readonly displayName: string;
|
|
|
|
/**
|
|
* Check if this runtime is available on the system
|
|
* @returns Availability information including version
|
|
*/
|
|
abstract checkAvailable(): Promise<RuntimeAvailability>;
|
|
|
|
/**
|
|
* Create the command configuration for executing a test
|
|
* @param testFile - Absolute path to the test file
|
|
* @param options - Runtime-specific options
|
|
* @returns Command configuration
|
|
*/
|
|
abstract createCommand(testFile: string, options?: RuntimeOptions): RuntimeCommand;
|
|
|
|
/**
|
|
* Execute a test file and return a TAP parser
|
|
* @param testFile - Absolute path to the test file
|
|
* @param index - Test index (for display)
|
|
* @param total - Total number of tests (for display)
|
|
* @param options - Runtime-specific options
|
|
* @returns TAP parser with test results
|
|
*/
|
|
abstract run(
|
|
testFile: string,
|
|
index: number,
|
|
total: number,
|
|
options?: RuntimeOptions
|
|
): Promise<TapParser>;
|
|
|
|
/**
|
|
* Get the default options for this runtime
|
|
* Can be overridden by subclasses
|
|
*/
|
|
protected getDefaultOptions(): RuntimeOptions {
|
|
return {
|
|
timeout: 0,
|
|
extraArgs: [],
|
|
env: {},
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Merge user options with defaults
|
|
*/
|
|
protected mergeOptions<T extends RuntimeOptions>(userOptions?: T): T {
|
|
const defaults = this.getDefaultOptions();
|
|
return {
|
|
...defaults,
|
|
...userOptions,
|
|
env: { ...defaults.env, ...userOptions?.env },
|
|
extraArgs: [...(defaults.extraArgs || []), ...(userOptions?.extraArgs || [])],
|
|
} as T;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Registry for runtime adapters
|
|
* Manages all available runtime implementations
|
|
*/
|
|
export class RuntimeAdapterRegistry {
|
|
private adapters: Map<Runtime, RuntimeAdapter> = new Map();
|
|
|
|
/**
|
|
* Register a runtime adapter
|
|
*/
|
|
register(adapter: RuntimeAdapter): void {
|
|
this.adapters.set(adapter.id, adapter);
|
|
}
|
|
|
|
/**
|
|
* Get an adapter by runtime ID
|
|
*/
|
|
get(runtime: Runtime): RuntimeAdapter | undefined {
|
|
return this.adapters.get(runtime);
|
|
}
|
|
|
|
/**
|
|
* Get all registered adapters
|
|
*/
|
|
getAll(): RuntimeAdapter[] {
|
|
return Array.from(this.adapters.values());
|
|
}
|
|
|
|
/**
|
|
* Check which runtimes are available on the system
|
|
*/
|
|
async checkAvailability(): Promise<Map<Runtime, RuntimeAvailability>> {
|
|
const results = new Map<Runtime, RuntimeAvailability>();
|
|
|
|
for (const [runtime, adapter] of this.adapters) {
|
|
const availability = await adapter.checkAvailable();
|
|
results.set(runtime, availability);
|
|
}
|
|
|
|
return results;
|
|
}
|
|
|
|
/**
|
|
* Get adapters for a list of runtimes, in order
|
|
* @param runtimes - Ordered list of runtimes
|
|
* @returns Adapters in the same order, skipping any that aren't registered
|
|
*/
|
|
getAdaptersForRuntimes(runtimes: Runtime[]): RuntimeAdapter[] {
|
|
const adapters: RuntimeAdapter[] = [];
|
|
|
|
for (const runtime of runtimes) {
|
|
const adapter = this.get(runtime);
|
|
if (adapter) {
|
|
adapters.push(adapter);
|
|
}
|
|
}
|
|
|
|
return adapters;
|
|
}
|
|
}
|