Files
smartfile/test/helpers/mock-smartfs.ts

182 lines
4.8 KiB
TypeScript

/**
* Mock SmartFs implementation for testing
* Provides fluent API matching @push.rocks/smartfs using native Node.js fs
*/
import { promises as fsPromises, createReadStream, createWriteStream } from 'fs';
import * as path from 'path';
import { Readable, Writable } from 'stream';
/**
* Mock SmartFsFile - Fluent file operations builder
*/
class MockSmartFsFile {
private filePath: string;
private options: {
encoding?: BufferEncoding;
recursive?: boolean;
} = {};
constructor(filePath: string) {
this.filePath = filePath;
}
// Configuration methods (return this for chaining)
public encoding(encoding: BufferEncoding): this {
this.options.encoding = encoding;
return this;
}
public recursive(): this {
this.options.recursive = true;
return this;
}
// Action methods (return Promises)
public async read(): Promise<string | Buffer> {
if (this.options.encoding) {
return await fsPromises.readFile(this.filePath, this.options.encoding);
}
return await fsPromises.readFile(this.filePath);
}
public async write(content: string | Buffer): Promise<void> {
// Ensure directory exists
const dirPath = path.dirname(this.filePath);
await fsPromises.mkdir(dirPath, { recursive: true });
if (this.options.encoding && typeof content === 'string') {
await fsPromises.writeFile(this.filePath, content, this.options.encoding);
} else {
await fsPromises.writeFile(this.filePath, content);
}
}
public async exists(): Promise<boolean> {
try {
await fsPromises.access(this.filePath);
return true;
} catch {
return false;
}
}
public async delete(): Promise<void> {
await fsPromises.unlink(this.filePath);
}
public async stat(): Promise<any> {
return await fsPromises.stat(this.filePath);
}
public async readStream(): Promise<Readable> {
return createReadStream(this.filePath);
}
public async writeStream(): Promise<Writable> {
// Ensure directory exists
const dirPath = path.dirname(this.filePath);
await fsPromises.mkdir(dirPath, { recursive: true });
return createWriteStream(this.filePath);
}
public async copy(dest: string): Promise<void> {
await fsPromises.copyFile(this.filePath, dest);
}
}
/**
* Mock SmartFsDirectory - Fluent directory operations builder
*/
class MockSmartFsDirectory {
private dirPath: string;
private options: {
recursive?: boolean;
} = {};
constructor(dirPath: string) {
this.dirPath = dirPath;
}
// Configuration methods (return this for chaining)
public recursive(): this {
this.options.recursive = true;
return this;
}
// Action methods (return Promises)
public async list(): Promise<Array<{ path: string; isFile: boolean; isDirectory: boolean }>> {
const entries: Array<{ path: string; isFile: boolean; isDirectory: boolean }> = [];
if (this.options.recursive) {
// Recursive listing
const walk = async (dir: string) => {
const items = await fsPromises.readdir(dir);
for (const item of items) {
const fullPath = path.join(dir, item);
const stats = await fsPromises.stat(fullPath);
if (stats.isFile()) {
entries.push({ path: fullPath, isFile: true, isDirectory: false });
} else if (stats.isDirectory()) {
entries.push({ path: fullPath, isFile: false, isDirectory: true });
await walk(fullPath);
}
}
};
await walk(this.dirPath);
} else {
// Non-recursive listing
const items = await fsPromises.readdir(this.dirPath);
for (const item of items) {
const fullPath = path.join(this.dirPath, item);
const stats = await fsPromises.stat(fullPath);
entries.push({
path: fullPath,
isFile: stats.isFile(),
isDirectory: stats.isDirectory(),
});
}
}
return entries;
}
public async create(): Promise<void> {
if (this.options.recursive) {
await fsPromises.mkdir(this.dirPath, { recursive: true });
} else {
await fsPromises.mkdir(this.dirPath);
}
}
public async exists(): Promise<boolean> {
try {
const stats = await fsPromises.stat(this.dirPath);
return stats.isDirectory();
} catch {
return false;
}
}
public async delete(): Promise<void> {
if (this.options.recursive) {
await fsPromises.rm(this.dirPath, { recursive: true, force: true });
} else {
await fsPromises.rmdir(this.dirPath);
}
}
}
/**
* Mock SmartFs - Main class matching @push.rocks/smartfs API
*/
export class MockSmartFs {
public file(filePath: string): MockSmartFsFile {
return new MockSmartFsFile(filePath);
}
public directory(dirPath: string): MockSmartFsDirectory {
return new MockSmartFsDirectory(dirPath);
}
}