import type { Minifier, MinifyLevel } from '../../_exports/index.js'; import { type EnvVar } from './deploy.js'; import type { DeployEvent, ReplSession, TestEvent } from './session.js'; export type HeapBaselineAction = 'created' | 'ok' | 'exceeded' | 'updated' | 'stale'; export interface TestFileResult { file: string; passed: number; failed: number; skipped: number; todo: number; duration: number; events: TestEvent[]; error?: string; /** True once the file's run_done (e:6) arrived. A result without this * and without an error means the file was never accounted — the * finalization pass turns that into an error so totals can't report * PASS over files that silently never ran. */ completed?: boolean; /** heapUsed delta (bytes) between run start and end, after gc on both * sides. Relative to the (post-beforeAll) baseline; drives heap-baseline * regression tracking. Surfaced as the "retained" figure (the only memory * signal on the host sim, which has no system heap). */ heapDelta?: number; /** Memory the suite used (bytes): how far free system heap fell from the * baseline to its sampled low-water. Device-only. */ sysUsed?: number; /** Lowest free system heap (bytes) sampled during the run: the suite's * closest sampled approach to OOM. `sysUsed + sysMinFree ≈ baseline free`. * Per-file (the device runs each file in a fresh runtime). Device-only * (absent on the host sim). */ sysMinFree?: number; /** Net timer count change between run start and end (should be 0) */ timerDelta?: number; /** Net in-flight HTTP request count change (should be 0). Detects fetches * that were initiated but not cancelled or awaited before teardown. */ pendingDelta?: number; /** Chip reported by the device (e.g. "esp32c6", "host"). Used as baseline key. */ chip?: string; /** Stored baseline value for this chip (if a baseline file existed) */ heapBaselineStored?: number; /** What happened to the heap-baseline file this run */ heapBaselineAction?: HeapBaselineAction; } export interface TestRunOptions { minify: boolean; bytecode: boolean; minifier?: Minifier; minifyLevel?: MinifyLevel; envVars: EnvVar[]; timeout: number; buildDir: string; /** Value of MIKRO_ENV to set during the test run (e.g. 'test', 'simulator'). */ mikroEnv: string; /** If true, write the current heapDelta as the new baseline for the current chip. */ updateHeapBaselines?: boolean; } /** * Resolve test files from a list of patterns. Each pattern may be: * - an explicit path to an existing file (included directly) * - a glob pattern (expanded against cwd, excluding node_modules/build) * * With no patterns, falls back to the default `**\/*.test.ts` glob. Patterns * that match nothing throw — a typo in a path shouldn't silently run zero * tests. */ export declare function discoverTestFiles(cwd: string, patterns?: readonly string[]): Promise; export interface TestManifestCallbacks { /** Called with the test file about to start (based on deploy manifest order). */ onFileStart?: (file: string, index: number, total: number) => void; /** Called when a file's run_done event arrives, closing out its result. */ onFileDone?: (result: TestFileResult, index: number, total: number) => void; /** Per-event hook (suite/test events). */ onEvent?: (event: TestEvent, file: string) => void; /** Console output forwarding. */ onLog?: (level: string, text: string, file: string) => void; /** Deploy-phase progress. Fired for each DeployEvent before tests start. */ onDeployEvent?: (event: DeployEvent) => void; /** Generic progress messages. */ log?: (msg: string) => void; } /** * Build the test manifest, deploy once, and observe the device supervisor * stream as each test file runs in its own fresh runtime. Returns one * TestFileResult per input, with heap-baseline bookkeeping applied. */ export declare function runTestManifest(session: ReplSession, testFiles: string[], options: TestRunOptions, cb?: TestManifestCallbacks): Promise; /** Format a byte count for human-readable test output. */ export declare function formatBytes(n: number): string; /** * Memory portion of a file-summary line. Two distinct signals, labelled so the * number's meaning is on the label: * * peak: device only (system heap). How far free system heap dipped below * the baseline at its sampled low (sysUsed), paired with that * low-water (min free). A high-water mark: "the most this suite * needed at once," including transient TLS/wifi buffers. Always >= 0. * retained: both (JS heap). End-of-run heap minus baseline (heapDelta): bytes * the suite still holds above baseline, i.e. what it didn't release. * ~0 is good. Can be slightly negative when the run ends lighter than * baseline (a reference cycle collected since baseline); read that as * "clean," not "negative usage." */ export declare function formatMemorySummary(result: TestFileResult): string[]; /** * Demultiplex the device event stream per file. Each run_done (e:6) closes * the current file and advances the index; manifest_done ends the run. * * Readiness handling: the initial deploy restarts the device once, so a * single ready event is expected before test 1. Any subsequent ready event * (after test 1's first event) indicates an unexpected reboot — treat as a * crash and bail, returning partial results. */ /** * Observe the device event stream and produce one TestFileResult per test * file. Exported so the reducer's contract with the firmware supervisor * can be unit-tested without going through the real build+deploy path. */ export declare function collectManifestEvents(session: ReplSession, testFiles: string[], timeoutMs: number, cb: TestManifestCallbacks): Promise; //# sourceMappingURL=testRunner.d.ts.map