- Implemented async utilities including delay, retryWithBackoff, withTimeout, parallelLimit, debounceAsync, AsyncMutex, and CircuitBreaker. - Created tests for async utilities to ensure functionality and reliability. - Developed AsyncFileSystem class with methods for file and directory operations, including ensureDir, readFile, writeFile, remove, and more. - Added tests for filesystem utilities to validate file operations and error handling.
185 lines
5.3 KiB
TypeScript
185 lines
5.3 KiB
TypeScript
import { tap, expect } from '@git.zone/tstest/tapbundle';
|
|
import * as path from 'path';
|
|
import { AsyncFileSystem } from '../../../ts/core/utils/fs-utils.js';
|
|
|
|
// Use a temporary directory for tests
|
|
const testDir = path.join(process.cwd(), '.nogit', 'test-fs-utils');
|
|
const testFile = path.join(testDir, 'test.txt');
|
|
const testJsonFile = path.join(testDir, 'test.json');
|
|
|
|
tap.test('should create and check directory existence', async () => {
|
|
// Ensure directory
|
|
await AsyncFileSystem.ensureDir(testDir);
|
|
|
|
// Check it exists
|
|
const exists = await AsyncFileSystem.exists(testDir);
|
|
expect(exists).toBeTrue();
|
|
|
|
// Check it's a directory
|
|
const isDir = await AsyncFileSystem.isDirectory(testDir);
|
|
expect(isDir).toBeTrue();
|
|
});
|
|
|
|
tap.test('should write and read text files', async () => {
|
|
const testContent = 'Hello, async filesystem!';
|
|
|
|
// Write file
|
|
await AsyncFileSystem.writeFile(testFile, testContent);
|
|
|
|
// Check file exists
|
|
const exists = await AsyncFileSystem.exists(testFile);
|
|
expect(exists).toBeTrue();
|
|
|
|
// Read file
|
|
const content = await AsyncFileSystem.readFile(testFile);
|
|
expect(content).toEqual(testContent);
|
|
|
|
// Check it's a file
|
|
const isFile = await AsyncFileSystem.isFile(testFile);
|
|
expect(isFile).toBeTrue();
|
|
});
|
|
|
|
tap.test('should write and read JSON files', async () => {
|
|
const testData = {
|
|
name: 'Test',
|
|
value: 42,
|
|
nested: {
|
|
array: [1, 2, 3]
|
|
}
|
|
};
|
|
|
|
// Write JSON
|
|
await AsyncFileSystem.writeJSON(testJsonFile, testData);
|
|
|
|
// Read JSON
|
|
const readData = await AsyncFileSystem.readJSON(testJsonFile);
|
|
expect(readData).toEqual(testData);
|
|
});
|
|
|
|
tap.test('should copy files', async () => {
|
|
const copyFile = path.join(testDir, 'copy.txt');
|
|
|
|
// Copy file
|
|
await AsyncFileSystem.copyFile(testFile, copyFile);
|
|
|
|
// Check copy exists
|
|
const exists = await AsyncFileSystem.exists(copyFile);
|
|
expect(exists).toBeTrue();
|
|
|
|
// Check content matches
|
|
const content = await AsyncFileSystem.readFile(copyFile);
|
|
const originalContent = await AsyncFileSystem.readFile(testFile);
|
|
expect(content).toEqual(originalContent);
|
|
});
|
|
|
|
tap.test('should move files', async () => {
|
|
const moveFile = path.join(testDir, 'moved.txt');
|
|
const copyFile = path.join(testDir, 'copy.txt');
|
|
|
|
// Move file
|
|
await AsyncFileSystem.moveFile(copyFile, moveFile);
|
|
|
|
// Check moved file exists
|
|
const movedExists = await AsyncFileSystem.exists(moveFile);
|
|
expect(movedExists).toBeTrue();
|
|
|
|
// Check original doesn't exist
|
|
const originalExists = await AsyncFileSystem.exists(copyFile);
|
|
expect(originalExists).toBeFalse();
|
|
});
|
|
|
|
tap.test('should list files in directory', async () => {
|
|
const files = await AsyncFileSystem.listFiles(testDir);
|
|
|
|
expect(files).toContain('test.txt');
|
|
expect(files).toContain('test.json');
|
|
expect(files).toContain('moved.txt');
|
|
});
|
|
|
|
tap.test('should list files with full paths', async () => {
|
|
const files = await AsyncFileSystem.listFilesFullPath(testDir);
|
|
|
|
const fileNames = files.map(f => path.basename(f));
|
|
expect(fileNames).toContain('test.txt');
|
|
expect(fileNames).toContain('test.json');
|
|
|
|
// All paths should be absolute
|
|
files.forEach(file => {
|
|
expect(path.isAbsolute(file)).toBeTrue();
|
|
});
|
|
});
|
|
|
|
tap.test('should get file stats', async () => {
|
|
const stats = await AsyncFileSystem.getStats(testFile);
|
|
|
|
expect(stats).not.toBeNull();
|
|
expect(stats?.isFile()).toBeTrue();
|
|
expect(stats?.size).toBeGreaterThan(0);
|
|
});
|
|
|
|
tap.test('should handle non-existent files gracefully', async () => {
|
|
const nonExistent = path.join(testDir, 'does-not-exist.txt');
|
|
|
|
// Check existence
|
|
const exists = await AsyncFileSystem.exists(nonExistent);
|
|
expect(exists).toBeFalse();
|
|
|
|
// Get stats should return null
|
|
const stats = await AsyncFileSystem.getStats(nonExistent);
|
|
expect(stats).toBeNull();
|
|
|
|
// Remove should not throw
|
|
await AsyncFileSystem.remove(nonExistent);
|
|
});
|
|
|
|
tap.test('should remove files', async () => {
|
|
// Remove a file
|
|
await AsyncFileSystem.remove(testFile);
|
|
|
|
// Check it's gone
|
|
const exists = await AsyncFileSystem.exists(testFile);
|
|
expect(exists).toBeFalse();
|
|
});
|
|
|
|
tap.test('should ensure file exists', async () => {
|
|
const ensureFile = path.join(testDir, 'ensure.txt');
|
|
|
|
// Ensure file
|
|
await AsyncFileSystem.ensureFile(ensureFile);
|
|
|
|
// Check it exists
|
|
const exists = await AsyncFileSystem.exists(ensureFile);
|
|
expect(exists).toBeTrue();
|
|
|
|
// Check it's empty
|
|
const content = await AsyncFileSystem.readFile(ensureFile);
|
|
expect(content).toEqual('');
|
|
});
|
|
|
|
tap.test('should recursively list files', async () => {
|
|
// Create subdirectory with file
|
|
const subDir = path.join(testDir, 'subdir');
|
|
const subFile = path.join(subDir, 'nested.txt');
|
|
|
|
await AsyncFileSystem.ensureDir(subDir);
|
|
await AsyncFileSystem.writeFile(subFile, 'nested content');
|
|
|
|
// List recursively
|
|
const files = await AsyncFileSystem.listFilesRecursive(testDir);
|
|
|
|
// Should include files from subdirectory
|
|
const fileNames = files.map(f => path.relative(testDir, f));
|
|
expect(fileNames).toContain('test.json');
|
|
expect(fileNames).toContain(path.join('subdir', 'nested.txt'));
|
|
});
|
|
|
|
tap.test('should clean up test directory', async () => {
|
|
// Remove entire test directory
|
|
await AsyncFileSystem.removeDir(testDir);
|
|
|
|
// Check it's gone
|
|
const exists = await AsyncFileSystem.exists(testDir);
|
|
expect(exists).toBeFalse();
|
|
});
|
|
|
|
tap.start(); |