import { afterEach, describe, expect, test } from 'bun:test'; import { existsSync } from 'node:fs'; import { readFile, writeFile } from 'node:fs/promises'; import { join } from 'node:path'; import { copyFixture, createMultipleTempDirectories, createTempDirectory, createTempDirectoryWithCleanup, removeMultipleTempDirectories, removeTempDirectory, } from './filesystem'; describe('Filesystem Test Utilities', () => { const createdDirs: string[] = []; afterEach(async () => { // Cleanup any directories that weren't cleaned up in test for (const dir of createdDirs) { try { if (existsSync(dir)) { await removeTempDirectory(dir); } } catch { // Ignore cleanup errors } } createdDirs.length = 0; }); describe('createTempDirectory', () => { test('creates unique temporary directory', async () => { const dir = await createTempDirectory(); createdDirs.push(dir); expect(existsSync(dir)).toBe(true); expect(dir).toMatch(/celilo-test-/); }); test('creates different directories on multiple calls', async () => { const dir1 = await createTempDirectory(); const dir2 = await createTempDirectory(); createdDirs.push(dir1, dir2); expect(dir1).not.toBe(dir2); expect(existsSync(dir1)).toBe(true); expect(existsSync(dir2)).toBe(true); }); test('directory is writable', async () => { const dir = await createTempDirectory(); createdDirs.push(dir); const testFile = join(dir, 'test.txt'); await writeFile(testFile, 'test content'); expect(existsSync(testFile)).toBe(true); const content = await readFile(testFile, 'utf-8'); expect(content).toBe('test content'); }); }); describe('removeTempDirectory', () => { test('removes empty directory', async () => { const dir = await createTempDirectory(); expect(existsSync(dir)).toBe(true); await removeTempDirectory(dir); expect(existsSync(dir)).toBe(false); }); test('removes directory with files', async () => { const dir = await createTempDirectory(); await writeFile(join(dir, 'test.txt'), 'content'); expect(existsSync(dir)).toBe(true); await removeTempDirectory(dir); expect(existsSync(dir)).toBe(false); }); test('removes directory with subdirectories', async () => { const dir = await createTempDirectory(); const subdir = join(dir, 'subdir'); await writeFile(join(dir, 'test.txt'), 'content'); // Create subdirectory with file const { mkdir } = await import('node:fs/promises'); await mkdir(subdir); await writeFile(join(subdir, 'nested.txt'), 'nested'); expect(existsSync(dir)).toBe(true); expect(existsSync(subdir)).toBe(true); await removeTempDirectory(dir); expect(existsSync(dir)).toBe(false); }); test('handles non-existent directory gracefully', async () => { // Should not throw await expect(removeTempDirectory('/tmp/does-not-exist-12345')).resolves.toBeUndefined(); }); }); describe('copyFixture', () => { test('copies fixture to destination', async () => { const tempDir = await createTempDirectory(); createdDirs.push(tempDir); const destPath = join(tempDir, 'artifact-test'); await copyFixture('./test-fixtures/modules/artifact-test', destPath); expect(existsSync(destPath)).toBe(true); expect(existsSync(join(destPath, 'manifest.yml'))).toBe(true); expect(existsSync(join(destPath, 'terraform'))).toBe(true); }); test('preserves directory structure', async () => { const tempDir = await createTempDirectory(); createdDirs.push(tempDir); const destPath = join(tempDir, 'artifact-test'); await copyFixture('./test-fixtures/modules/artifact-test', destPath); expect(existsSync(join(destPath, 'terraform', 'main.tf'))).toBe(true); expect(existsSync(join(destPath, 'build', 'build.sh'))).toBe(true); }); test('preserves file contents', async () => { const tempDir = await createTempDirectory(); createdDirs.push(tempDir); const destPath = join(tempDir, 'artifact-test'); await copyFixture('./test-fixtures/modules/artifact-test', destPath); const manifest = await readFile(join(destPath, 'manifest.yml'), 'utf-8'); expect(manifest).toContain('id: artifact-test'); }); }); describe('createMultipleTempDirectories', () => { test('creates multiple directories', async () => { const dirs = await createMultipleTempDirectories(3); createdDirs.push(...dirs); expect(dirs).toHaveLength(3); expect(existsSync(dirs[0])).toBe(true); expect(existsSync(dirs[1])).toBe(true); expect(existsSync(dirs[2])).toBe(true); }); test('directories are unique', async () => { const dirs = await createMultipleTempDirectories(3); createdDirs.push(...dirs); expect(dirs[0]).not.toBe(dirs[1]); expect(dirs[1]).not.toBe(dirs[2]); expect(dirs[0]).not.toBe(dirs[2]); }); test('creates zero directories', async () => { const dirs = await createMultipleTempDirectories(0); expect(dirs).toHaveLength(0); }); }); describe('removeMultipleTempDirectories', () => { test('removes multiple directories', async () => { const dirs = await createMultipleTempDirectories(3); expect(existsSync(dirs[0])).toBe(true); expect(existsSync(dirs[1])).toBe(true); expect(existsSync(dirs[2])).toBe(true); await removeMultipleTempDirectories(dirs); expect(existsSync(dirs[0])).toBe(false); expect(existsSync(dirs[1])).toBe(false); expect(existsSync(dirs[2])).toBe(false); }); test('handles empty array', async () => { await expect(removeMultipleTempDirectories([])).resolves.toBeUndefined(); }); }); describe('createTempDirectoryWithCleanup', () => { test('creates directory and cleanup function', async () => { const { path: dir, cleanup } = await createTempDirectoryWithCleanup(); expect(existsSync(dir)).toBe(true); expect(typeof cleanup).toBe('function'); await cleanup(); expect(existsSync(dir)).toBe(false); }); test('cleanup removes directory', async () => { const { path: dir, cleanup } = await createTempDirectoryWithCleanup(); await writeFile(join(dir, 'test.txt'), 'content'); expect(existsSync(dir)).toBe(true); await cleanup(); expect(existsSync(dir)).toBe(false); }); }); });