import { copyFile, mkdir, mkdtemp, readFile, readdir, rm, writeFile } from 'node:fs/promises'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { afterEach, describe, expect, it } from 'vitest'; import { initializeProjectDirectory } from '@electron/opencode/project-directory-initialization'; const temporaryDirectories: string[] = []; afterEach(async () => { await Promise.all(temporaryDirectories.splice(0).map((directory) => ( rm(directory, { recursive: true, force: true }) ))); }); describe('project directory initialization', () => { it('rolls back only files and directories created by a failed in-place merge', async () => { const projectPath = await mkdtemp(join(tmpdir(), 'niancode-in-place-rollback-')); temporaryDirectories.push(projectPath); await writeFile(join(projectPath, 'keep.txt'), 'user-owned\n', 'utf8'); await mkdir(join(projectPath, 'src')); await writeFile(join(projectPath, 'src', 'existing.ts'), 'export const existing = true;\n', 'utf8'); let copyCount = 0; await expect(initializeProjectDirectory({ projectPath, templateId: 'standard-development', allowExistingDirectory: true, }, { copyFile: async (source, destination, mode) => { copyCount += 1; if (copyCount === 2) throw new Error('simulated copy failure'); await copyFile(source, destination, mode); }, })).rejects.toThrow('simulated copy failure'); expect((await readdir(projectPath)).sort()).toEqual(['keep.txt', 'src']); expect(await readFile(join(projectPath, 'keep.txt'), 'utf8')).toBe('user-owned\n'); expect(await readFile(join(projectPath, 'src', 'existing.ts'), 'utf8')).toContain('existing'); }); });