import assert from 'node:assert/strict'; import { chmod, mkdir, rm, symlink, writeFile } from 'node:fs/promises'; import path from 'node:path'; import test from 'node:test'; import { runPreflight } from './preflight.mjs'; const fixtureRoot = path.join(process.cwd(), '.mosaic-test-work', `preflight-${process.pid}`); const requiredBins = ['eslint', 'husky', 'prettier', 'tsc', 'turbo', 'vitest']; async function fixture(name) { const root = path.join(fixtureRoot, name); await mkdir(path.join(root, 'apps', 'web', 'src'), { recursive: true }); await writeFile(path.join(root, 'apps', 'web', 'src', 'main.tsx'), 'export default 1;\n'); return root; } async function installRequiredBins(root) { const binDir = path.join(root, 'node_modules', '.bin'); await mkdir(binDir, { recursive: true }); await Promise.all( requiredBins.map(async (name) => { const target = path.join(binDir, name); await writeFile(target, ''); await chmod(target, 0o755); }), ); } test.after(async () => { await rm(fixtureRoot, { recursive: true, force: true }); }); test('missing dependencies have a dedicated exit code and install remediation', async () => { const root = await fixture('missing-deps'); const result = await runPreflight({ root }); assert.equal(result.code, 42); assert.match(result.message, /MOSAIC_PREFLIGHT_MISSING_DEPS/); assert.match(result.message, /run pnpm install/i); }); test('a partial dependency install keeps the dedicated missing-deps result', async () => { const root = await fixture('partial-deps'); await mkdir(path.join(root, 'node_modules', '.bin'), { recursive: true }); await writeFile(path.join(root, 'node_modules', '.bin', 'tsc'), '', { mode: 0o755 }); const result = await runPreflight({ root }); assert.equal(result.code, 42); assert.match(result.message, /turbo/); }); test('a dangling required dependency shim keeps the dedicated missing-deps result', async () => { const root = await fixture('dangling-deps'); await installRequiredBins(root); const turbo = path.join(root, 'node_modules', '.bin', 'turbo'); await rm(turbo); await symlink(path.join(root, 'node_modules', 'missing-turbo'), turbo); const result = await runPreflight({ root }); assert.equal(result.code, 42); assert.match(result.message, /turbo/); }); test('installed dependencies pass', async () => { const root = await fixture('clean'); await installRequiredBins(root); assert.deepEqual(await runPreflight({ root }), { code: 0, message: 'checkout preflight passed' }); });