import { describe, expect, test } from 'bun:test'; import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { checkTypeScriptBuild } from './typescript-build'; describe('checkTypeScriptBuild', () => { test('skips with ok when noBuild is set', async () => { const dir = mkdtempSync(join(tmpdir(), 'celilo-tsc-')); try { const r = await checkTypeScriptBuild(dir, { noBuild: true }); expect(r.status).toBe('ok'); expect(r.message).toContain('skipped'); } finally { rmSync(dir, { recursive: true, force: true }); } }); test('skips with ok when there is no TypeScript surface', async () => { const dir = mkdtempSync(join(tmpdir(), 'celilo-tsc-')); try { // Just YAML and shell — nothing to typecheck. writeFileSync(join(dir, 'manifest.yml'), 'id: x\nversion: 1.0.0'); writeFileSync(join(dir, 'install.sh'), '#!/usr/bin/env bash\n'); const r = await checkTypeScriptBuild(dir); expect(r.status).toBe('ok'); expect(r.message).toContain('no TypeScript surface'); } finally { rmSync(dir, { recursive: true, force: true }); } }); test('warns when .ts files exist but no tsconfig', async () => { const dir = mkdtempSync(join(tmpdir(), 'celilo-tsc-')); try { mkdirSync(join(dir, 'scripts')); writeFileSync(join(dir, 'scripts', 'install.ts'), 'export const x = 1;\n'); const r = await checkTypeScriptBuild(dir); expect(r.status).toBe('warn'); expect(r.message).toContain('tsconfig.json'); } finally { rmSync(dir, { recursive: true, force: true }); } }); // A tsconfig at the module ROOT is not the one we run: it lives in scripts/, // next to the package.json and node_modules that make @celilo/capabilities // resolve. Looking at the wrong level is why this check never fired. test('ignores a tsconfig at the module root', async () => { const dir = mkdtempSync(join(tmpdir(), 'celilo-tsc-')); try { mkdirSync(join(dir, 'scripts')); writeFileSync(join(dir, 'scripts', 'install.ts'), 'export const x = 1;\n'); writeFileSync(join(dir, 'tsconfig.json'), '{}'); const r = await checkTypeScriptBuild(dir); expect(r.status).toBe('warn'); expect(r.message).toContain('scripts/tsconfig.json'); } finally { rmSync(dir, { recursive: true, force: true }); } }); test('fail with helpful message when tsconfig present but no node_modules', async () => { const dir = mkdtempSync(join(tmpdir(), 'celilo-tsc-')); try { mkdirSync(join(dir, 'scripts')); writeFileSync(join(dir, 'scripts', 'install.ts'), 'export const x = 1;\n'); writeFileSync(join(dir, 'scripts', 'tsconfig.json'), '{}'); const r = await checkTypeScriptBuild(dir); expect(r.status).toBe('fail'); expect(r.message).toContain('node_modules'); expect(r.message).toContain('bun install'); } finally { rmSync(dir, { recursive: true, force: true }); } }); });