import { describe, expect, test } from 'bun:test'; import { readFileSync } from 'node:fs'; import { join } from 'node:path'; import { RUN_FLAGS } from './cli/command-registry'; import { KNOWN_RUN_FLAGS, filterTestFilesByPatterns, parseRunArgs, staleImagePolicy, } from './run-args'; describe('parseRunArgs', () => { test('--help is recognized as help, never discarded into run-everything', () => { const parsed = parseRunArgs(['--help']); expect(parsed.helpRequested).toBe(true); expect(parsed.unknownFlags).toEqual([]); expect(parsed.patterns).toEqual([]); }); test('every known flag is accepted and yields no patterns', () => { const parsed = parseRunArgs([...KNOWN_RUN_FLAGS, '--seed=42']); expect(parsed.unknownFlags).toEqual([]); expect(parsed.patterns).toEqual([]); expect(parsed.helpRequested).toBe(false); }); test('positional patterns survive flag parsing in order', () => { const parsed = parseRunArgs(['deploy', '--keep', 'caddy', '--verbose']); expect(parsed.patterns).toEqual(['deploy', 'caddy']); expect(parsed.unknownFlags).toEqual([]); }); test('an unrecognised --flag is reported, not silently discarded', () => { // The old runner stripped every --arg it did not know, leaving zero // patterns: run everything. `--al` must error, not launch the catalogue. const parsed = parseRunArgs(['--al', '--dry-run']); expect(parsed.unknownFlags).toEqual(['--al', '--dry-run']); expect(parsed.patterns).toEqual([]); expect(parsed.helpRequested).toBe(false); }); test('the CLI discovery aliases are unknown to the runner', () => { // `cele2e run` strips --all/--all-modules before exec. If one ever // reaches the runner directly it must error, not run everything. const parsed = parseRunArgs(['--all', '--all-modules']); expect(parsed.unknownFlags).toEqual(['--all', '--all-modules']); }); }); describe('filterTestFilesByPatterns', () => { const files = [ '/mods/knot/e2e/aspect-fanout.test.ts', '/top/tests/aspect-fanout-new-systems.test.ts', '/top/tests/caddy-internal-private.test.ts', ]; test('an exact pattern selects only its own file, not the sibling it prefixes', () => { // The old substring-OR filter dragged aspect-fanout-new-systems into // `cele2e run aspect-fanout caddy-internal-private` whenever the // top-level dir was in the collected set. const picked = filterTestFilesByPatterns(files, ['aspect-fanout', 'caddy-internal-private']); expect(picked).toEqual([ '/mods/knot/e2e/aspect-fanout.test.ts', '/top/tests/caddy-internal-private.test.ts', ]); }); test('a pattern with no exact match keeps substring semantics', () => { const picked = filterTestFilesByPatterns(files, ['fanout-new']); expect(picked).toEqual(['/top/tests/aspect-fanout-new-systems.test.ts']); }); test('several patterns union their matches', () => { const picked = filterTestFilesByPatterns(files, ['aspect-fanout-new-systems', 'aspect-fanout']); expect(picked).toEqual([ '/mods/knot/e2e/aspect-fanout.test.ts', '/top/tests/aspect-fanout-new-systems.test.ts', ]); }); test('no patterns selects everything', () => { expect(filterTestFilesByPatterns(files, [])).toEqual(files); }); }); // celilo#790: a run refuses a baked image that was not built from this tree, // unless the caller said the mismatch is intended. describe('staleImagePolicy', () => { test('a plain run refuses a stale image', () => { expect(staleImagePolicy([])).toBe('fail'); expect(staleImagePolicy(['smoke', '--keep'])).toBe('fail'); }); test('--allow-stale is the deliberate way to test the image as it is', () => { expect(staleImagePolicy(['smoke', '--allow-stale'])).toBe('warn'); }); test('--source-cli runs this tree over the mount, so the baked CLI is not what is tested', () => { expect(staleImagePolicy(['smoke', '--source-cli'])).toBe('warn'); }); test('the flag is one the runner accepts and completion offers', () => { expect(parseRunArgs(['--allow-stale']).unknownFlags).toEqual([]); expect(RUN_FLAGS).toContain('--allow-stale'); }); test("the runner's preflight is the caller: it hands the policy to diagnose", () => { // runner.ts runs main() at import, so this reads the source, as the // bake-probe tests do. Without the argument the check is a warning again. const src = readFileSync(join(import.meta.dir, 'runner.ts'), 'utf-8'); expect(src).toMatch( /diagnose\(\{\s*pkgDir: PKG_DIR,\s*skipLock: true,\s*staleImage: staleImagePolicy\(rawArgs\),?\s*\}\)/, ); }); });