import { afterAll, describe, expect, it } from 'vitest'; import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { detectLaunchCommands } from '../src/core/launch-detect.js'; const tmp = mkdtempSync(join(tmpdir(), 'launch-detect-')); afterAll(() => rmSync(tmp, { recursive: true, force: true })); function fixture(name: string, files: Record): string { const dir = join(tmp, name); mkdirSync(dir, { recursive: true }); for (const [f, content] of Object.entries(files)) writeFileSync(join(dir, f), content); return dir; } describe('detectLaunchCommands', () => { it('extrait les scripts npm (par défaut : npm run), active les scripts de dev', () => { const dir = fixture('npm', { 'package.json': JSON.stringify({ scripts: { dev: 'vite', build: 'vite build', 'test:unit': 'vitest' } }), }); const cmds = detectLaunchCommands(dir); const dev = cmds.find((c) => c.run === 'npm run dev'); const build = cmds.find((c) => c.run === 'npm run build'); expect(dev?.enabled).toBe(true); // heuristique : dev/start/serve/watch activés expect(build?.enabled).toBe(false); expect(cmds.some((c) => c.run === 'npm run test:unit')).toBe(true); }); it('utilise pnpm/yarn selon le lockfile présent', () => { const pnpm = fixture('pnpm', { 'package.json': JSON.stringify({ scripts: { dev: 'x' } }), 'pnpm-lock.yaml': '' }); expect(detectLaunchCommands(pnpm).find((c) => c.label === 'dev')?.run).toBe('pnpm run dev'); const yarn = fixture('yarn', { 'package.json': JSON.stringify({ scripts: { dev: 'x' } }), 'yarn.lock': '' }); expect(detectLaunchCommands(yarn).find((c) => c.label === 'dev')?.run).toBe('yarn dev'); }); it('lit le Procfile (name: command), toutes activées', () => { const dir = fixture('proc', { Procfile: 'web: bundle exec puma\nworker: rake jobs:work\n# comment\n' }); const cmds = detectLaunchCommands(dir); expect(cmds.find((c) => c.label === 'web')?.run).toBe('bundle exec puma'); expect(cmds.find((c) => c.label === 'worker')?.enabled).toBe(true); expect(cmds).toHaveLength(2); // la ligne de commentaire est ignorée }); it('suggère docker compose up si un fichier compose est présent', () => { const dir = fixture('compose', { 'compose.yaml': 'services: {}' }); expect(detectLaunchCommands(dir).some((c) => c.run === 'docker compose up')).toBe(true); }); it('tolère un répertoire vide ou un package.json invalide', () => { expect(detectLaunchCommands(join(tmp, 'inexistant'))).toEqual([]); const bad = fixture('bad', { 'package.json': '{ not json' }); expect(detectLaunchCommands(bad)).toEqual([]); }); });