testdirs
v4.0.1
Published
A utility to create isolated test directories
Readme
testdirs
A utility to create isolated test directories
[!NOTE] If you want to use this package with Vitest, we recommend using the vitest-testdirs with added support for Vitest.
📦 Installation
npm install testdirs --save-dev🚀 Usage
import type { TestdirOptions } from "testdirs";
import { testdir } from "testdirs";
const testdirOptions = {
dirname: "testdir", // default: a random directory name
} satisfies TestdirOptions;
const dir = await testdir({
"file1.txt": "Hello, World!",
"nested": {
"file2.txt": "Hello, Nested!",
"tests": {
"file3.txt": "Hello, Tests!"
}
},
// Alternatively, you can create nested directories with a flat path
"nested/tests/file4.txt": "Hello, Tests!"
}, testdirOptions);
console.log(dir.path);
// you need to handle the removal process yourself!
await dir.remove();Different Types of Files
You can create different types of files using the following methods:
import type { TestdirOptions } from "testdirs";
import { link, metadata, symlink, testdir } from "testdirs";
const dir = await testdir({
"file1.txt": "Hello, World!",
"nested": {
"file2.txt": symlink("../file1.txt"),
"file3.txt": metadata("Hello, World!", { mode: 0o444 }), // read-only file
},
"readonly": metadata({
"file4.txt": "Hello, World!",
}, { mode: 0o444 }), // read-only directory
// creating a symlink pointing to file1.txt
"symlink.txt": symlink("file1.txt"),
"symlink2.txt": symlink("nested/file2.txt"),
"link.txt": link("file1.txt"),
});Create testdir from existing directory
You can create a testdir from an existing directory using the from method:
import type { FromFileSystemOptions, TestdirOptions } from "testdirs";
import assert from "node:assert";
import { fromFileSystem, testdir } from "testdirs";
const fromFSOptions = {
ignore: [".git"], // ignore everything inside the .git directory
followLinks: false, // don't follow symlinks
extras: {}, // extra files to add to the files object
getEncodingForFile: (file) => "utf-8", // get the encoding for the file (default: utf-8)
} satisfies FromFileSystemOptions;
const dir = await testdir.from("path/to/existing/directory", {
dirname: "testdir", // default: a random directory name
fromFS: fromFSOptions,
});
// Alternatively, you can also use the `fromFileSystem` method to create the files object from the file system
const files = await fromFileSystem("path/to/existing/directory", fromFSOptions);
assert(files["file1.txt"] === "Hello, World!");
const testdirOptions = {
dirname: "testdir", // default: a random directory name
} satisfies TestdirOptions;
const dir2 = await testdir(files, testdirOptions);createCustomTestdir
Build your own testdir with custom dirname, optional hooks, and a Zod-validated options schema. One compact example:
import { randomUUID } from "node:crypto";
import fs from "node:fs/promises";
import { tmpdir } from "node:os";
import path from "node:path";
import { createFileTree, fromFileSystem } from "testdirs";
import { createCustomTestdir } from "testdirs/factory";
import { z } from "zod";
// define options
const options = z.object({ dirname: z.string().optional() });
// create factory with an extension method (from)
export const myTestdir = createCustomTestdir(async ({ fixturePath, files }) => {
await fs.mkdir(fixturePath, { recursive: true });
await createFileTree(fixturePath, files);
return {
path: fixturePath,
remove: async () => fs.rm(fixturePath, { recursive: true, force: true }),
[Symbol.asyncDispose]: async () => fs.rm(fixturePath, { recursive: true, force: true }),
};
}, {
async dirname(options) {
return options?.dirname
? path.resolve(options.dirname)
: path.join(await fs.realpath(tmpdir()), `my-testdir-${randomUUID()}`);
},
optionsSchema: options,
// The extensions is not required, but allows you to attach additional methods to the testdir function
// such as `from`, presets, or convenience wrappers.
extensions: {
async from(root: string, opts?: z.input<typeof options> & { fromFS?: Parameters<typeof fromFileSystem>[1] }) {
const files = await fromFileSystem(root, opts?.fromFS);
return myTestdir(files, opts);
},
},
});
// Usage
const dir1 = await myTestdir({ "a.txt": "hello" });
await dir1.remove();
const dir2 = await myTestdir.from("path/to/fixtures", { dirname: "./tmp" });
await dir2.remove();📄 License
Published under MIT License.
