Skip to content

Commit 3a5c501

Browse files
natemoo-regithub-actions[bot]
authored andcommitted
[ci] format
1 parent ae8958e commit 3a5c501

File tree

1 file changed

+154
-154
lines changed

1 file changed

+154
-154
lines changed

src/test-utils.ts

Lines changed: 154 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import type { HfsImpl } from "@humanfs/types";
77
import { expect, onTestFinished } from "vitest";
88

99
interface ScopedHfsImpl extends HfsImpl {
10-
text(file: string | URL): Promise<string | undefined>;
11-
json(file: string | URL): Promise<unknown | undefined>;
10+
text(file: string | URL): Promise<string | undefined>;
11+
json(file: string | URL): Promise<unknown | undefined>;
1212
}
1313

1414
/**
@@ -17,49 +17,49 @@ interface ScopedHfsImpl extends HfsImpl {
1717
* Includes all `hfs` methods — paths are resolved relative to the fixture root.
1818
*/
1919
export interface Fixture extends ScopedHfsImpl {
20-
/** The fixture root as a `file://` URL. */
21-
root: URL;
22-
/** Resolve a relative path within the fixture root. */
23-
resolve: (...segments: string[]) => URL;
24-
/** Delete the fixture directory. Also runs automatically via `onTestFinished`. */
25-
cleanup: () => Promise<void>;
20+
/** The fixture root as a `file://` URL. */
21+
root: URL;
22+
/** Resolve a relative path within the fixture root. */
23+
resolve: (...segments: string[]) => URL;
24+
/** Delete the fixture directory. Also runs automatically via `onTestFinished`. */
25+
cleanup: () => Promise<void>;
2626
}
2727

2828
/** Context passed to dynamic file content functions. */
2929
export interface FileContext {
30-
/**
31-
* Metadata about the fixture root, analogous to `import.meta`.
32-
*
33-
* - `url` — the fixture root as a `file://` URL string
34-
* - `filename` — absolute filesystem path to the fixture root
35-
* - `dirname` — same as `filename` (root is a directory)
36-
* - `resolve(path)` — resolve a relative path against the fixture root
37-
*/
38-
importMeta: {
39-
url: string;
40-
filename: string;
41-
dirname: string;
42-
resolve: (path: string) => string;
43-
};
44-
/**
45-
* Create a symbolic link to `target`.
46-
*
47-
* Returns a `SymlinkMarker` — the fixture will create the symlink on disk.
48-
*
49-
* @example
50-
* ```ts
51-
* { 'link.txt': ({ symlink }) => symlink('./target.txt') }
52-
* ```
53-
*/
54-
symlink: (target: string) => SymlinkMarker;
30+
/**
31+
* Metadata about the fixture root, analogous to `import.meta`.
32+
*
33+
* - `url` — the fixture root as a `file://` URL string
34+
* - `filename` — absolute filesystem path to the fixture root
35+
* - `dirname` — same as `filename` (root is a directory)
36+
* - `resolve(path)` — resolve a relative path against the fixture root
37+
*/
38+
importMeta: {
39+
url: string;
40+
filename: string;
41+
dirname: string;
42+
resolve: (path: string) => string;
43+
};
44+
/**
45+
* Create a symbolic link to `target`.
46+
*
47+
* Returns a `SymlinkMarker` — the fixture will create the symlink on disk.
48+
*
49+
* @example
50+
* ```ts
51+
* { 'link.txt': ({ symlink }) => symlink('./target.txt') }
52+
* ```
53+
*/
54+
symlink: (target: string) => SymlinkMarker;
5555
}
5656

5757
const SYMLINK = Symbol("symlink");
5858

5959
/** Opaque marker returned by `ctx.symlink()`. */
6060
export interface SymlinkMarker {
61-
[SYMLINK]: true;
62-
target: string;
61+
[SYMLINK]: true;
62+
target: string;
6363
}
6464

6565
/**
@@ -74,55 +74,55 @@ export interface SymlinkMarker {
7474
* | Function | `({ importMeta, symlink }) => symlink('./target')` |
7575
*/
7676
export type FileTreeValue =
77-
| string
78-
| Buffer
79-
| Record<string, unknown>
80-
| unknown[]
81-
| FileTree
82-
| ((ctx: FileContext) => string | Buffer | SymlinkMarker);
77+
| string
78+
| Buffer
79+
| Record<string, unknown>
80+
| unknown[]
81+
| FileTree
82+
| ((ctx: FileContext) => string | Buffer | SymlinkMarker);
8383

8484
/** A recursive tree of files and directories. */
8585
export interface FileTree {
86-
[key: string]: FileTreeValue;
86+
[key: string]: FileTreeValue;
8787
}
8888

8989
function isSymlinkMarker(value: unknown): value is SymlinkMarker {
90-
return typeof value === "object" && value !== null && SYMLINK in value;
90+
return typeof value === "object" && value !== null && SYMLINK in value;
9191
}
9292

9393
function isFileTree(value: unknown): value is FileTree {
94-
return (
95-
typeof value === "object" &&
96-
value !== null &&
97-
!Buffer.isBuffer(value) &&
98-
!Array.isArray(value) &&
99-
!isSymlinkMarker(value)
100-
);
94+
return (
95+
typeof value === "object" &&
96+
value !== null &&
97+
!Buffer.isBuffer(value) &&
98+
!Array.isArray(value) &&
99+
!isSymlinkMarker(value)
100+
);
101101
}
102102

103103
function scopeHfs(inner: NodeHfs, base: URL): ScopedHfsImpl {
104-
const r = (p: string | URL) => new URL(`./${p}`, base);
105-
const r2 = (a: string | URL, b: string | URL) => [r(a), r(b)] as const;
106-
107-
return {
108-
text: (p: string | URL) => inner.text(r(p)),
109-
json: (p: string | URL) => inner.json(r(p)),
110-
bytes: (p) => inner.bytes(r(p)),
111-
write: (p, c) => inner.write(r(p), c),
112-
append: (p, c) => inner.append(r(p), c),
113-
isFile: (p) => inner.isFile(r(p)),
114-
isDirectory: (p) => inner.isDirectory(r(p)),
115-
createDirectory: (p) => inner.createDirectory(r(p)),
116-
delete: (p) => inner.delete(r(p)),
117-
deleteAll: (p) => inner.deleteAll(r(p)),
118-
list: (p) => inner.list(r(p)),
119-
size: (p) => inner.size(r(p)),
120-
lastModified: (p) => inner.lastModified(r(p)),
121-
copy: (s, d) => inner.copy(...r2(s, d)),
122-
copyAll: (s, d) => inner.copyAll(...r2(s, d)),
123-
move: (s, d) => inner.move(...r2(s, d)),
124-
moveAll: (s, d) => inner.moveAll(...r2(s, d)),
125-
};
104+
const r = (p: string | URL) => new URL(`./${p}`, base);
105+
const r2 = (a: string | URL, b: string | URL) => [r(a), r(b)] as const;
106+
107+
return {
108+
text: (p: string | URL) => inner.text(r(p)),
109+
json: (p: string | URL) => inner.json(r(p)),
110+
bytes: (p) => inner.bytes(r(p)),
111+
write: (p, c) => inner.write(r(p), c),
112+
append: (p, c) => inner.append(r(p), c),
113+
isFile: (p) => inner.isFile(r(p)),
114+
isDirectory: (p) => inner.isDirectory(r(p)),
115+
createDirectory: (p) => inner.createDirectory(r(p)),
116+
delete: (p) => inner.delete(r(p)),
117+
deleteAll: (p) => inner.deleteAll(r(p)),
118+
list: (p) => inner.list(r(p)),
119+
size: (p) => inner.size(r(p)),
120+
lastModified: (p) => inner.lastModified(r(p)),
121+
copy: (s, d) => inner.copy(...r2(s, d)),
122+
copyAll: (s, d) => inner.copyAll(...r2(s, d)),
123+
move: (s, d) => inner.move(...r2(s, d)),
124+
moveAll: (s, d) => inner.moveAll(...r2(s, d)),
125+
};
126126
}
127127

128128
/**
@@ -148,86 +148,86 @@ function scopeHfs(inner: NodeHfs, base: URL): ScopedHfsImpl {
148148
* ```
149149
*/
150150
export async function createFixture(files: FileTree): Promise<Fixture> {
151-
const raw = expect.getState().currentTestName ?? "bsh";
152-
const prefix = raw
153-
.toLowerCase()
154-
.replace(/[^a-z0-9]+/g, "-")
155-
.replace(/^-|-$/g, "");
156-
const root = new URL(`${prefix}-`, `file://${tmpdir()}/`);
157-
const path = await mkdtemp(fileURLToPath(root));
158-
const base = pathToFileURL(path + sep);
159-
160-
const inner = new NodeHfs();
161-
const scoped = scopeHfs(inner, base);
162-
const resolve = (...segments: string[]) => new URL(`./${segments.join("/")}`, base);
163-
164-
const ctx: FileContext = {
165-
importMeta: {
166-
url: base.toString(),
167-
filename: fileURLToPath(base),
168-
dirname: fileURLToPath(base),
169-
resolve: (p: string) => new URL(`./${p}`, base).toString(),
170-
},
171-
symlink: (target: string): SymlinkMarker => ({ [SYMLINK]: true, target }),
172-
};
173-
174-
async function writeTree(tree: FileTree, dir: URL): Promise<void> {
175-
for (const [name, raw] of Object.entries(tree)) {
176-
const url = new URL(name, dir);
177-
178-
// Nested directory object (not a plain value)
179-
if (
180-
typeof raw !== "function" &&
181-
!Buffer.isBuffer(raw) &&
182-
!Array.isArray(raw) &&
183-
isFileTree(raw) &&
184-
!name.includes(".")
185-
) {
186-
await inner.createDirectory(url);
187-
// Trailing slash so nested entries resolve relative to the dir
188-
await writeTree(raw, new URL(`${url}/`));
189-
continue;
190-
}
191-
192-
// Ensure parent directory exists
193-
const parent = new URL("./", url);
194-
await inner.createDirectory(parent);
195-
196-
// Resolve functions
197-
const content = typeof raw === "function" ? raw(ctx) : raw;
198-
199-
// Symlink
200-
if (isSymlinkMarker(content)) {
201-
await fsSymlink(content.target, url);
202-
continue;
203-
}
204-
205-
// Buffer
206-
if (Buffer.isBuffer(content)) {
207-
await inner.write(url, content);
208-
continue;
209-
}
210-
211-
// JSON auto-serialization for .json files with non-string content
212-
if (name.endsWith(".json") && typeof content !== "string") {
213-
await inner.write(url, JSON.stringify(content, null, 2));
214-
continue;
215-
}
216-
217-
// String content
218-
await inner.write(url, content as string);
219-
}
220-
}
221-
222-
await writeTree(files, base);
223-
224-
const cleanup = () => inner.deleteAll(path).then(() => undefined);
225-
onTestFinished(cleanup);
226-
227-
return {
228-
root: base,
229-
resolve,
230-
cleanup,
231-
...scoped,
232-
};
151+
const raw = expect.getState().currentTestName ?? "bsh";
152+
const prefix = raw
153+
.toLowerCase()
154+
.replace(/[^a-z0-9]+/g, "-")
155+
.replace(/^-|-$/g, "");
156+
const root = new URL(`${prefix}-`, `file://${tmpdir()}/`);
157+
const path = await mkdtemp(fileURLToPath(root));
158+
const base = pathToFileURL(path + sep);
159+
160+
const inner = new NodeHfs();
161+
const scoped = scopeHfs(inner, base);
162+
const resolve = (...segments: string[]) => new URL(`./${segments.join("/")}`, base);
163+
164+
const ctx: FileContext = {
165+
importMeta: {
166+
url: base.toString(),
167+
filename: fileURLToPath(base),
168+
dirname: fileURLToPath(base),
169+
resolve: (p: string) => new URL(`./${p}`, base).toString(),
170+
},
171+
symlink: (target: string): SymlinkMarker => ({ [SYMLINK]: true, target }),
172+
};
173+
174+
async function writeTree(tree: FileTree, dir: URL): Promise<void> {
175+
for (const [name, raw] of Object.entries(tree)) {
176+
const url = new URL(name, dir);
177+
178+
// Nested directory object (not a plain value)
179+
if (
180+
typeof raw !== "function" &&
181+
!Buffer.isBuffer(raw) &&
182+
!Array.isArray(raw) &&
183+
isFileTree(raw) &&
184+
!name.includes(".")
185+
) {
186+
await inner.createDirectory(url);
187+
// Trailing slash so nested entries resolve relative to the dir
188+
await writeTree(raw, new URL(`${url}/`));
189+
continue;
190+
}
191+
192+
// Ensure parent directory exists
193+
const parent = new URL("./", url);
194+
await inner.createDirectory(parent);
195+
196+
// Resolve functions
197+
const content = typeof raw === "function" ? raw(ctx) : raw;
198+
199+
// Symlink
200+
if (isSymlinkMarker(content)) {
201+
await fsSymlink(content.target, url);
202+
continue;
203+
}
204+
205+
// Buffer
206+
if (Buffer.isBuffer(content)) {
207+
await inner.write(url, content);
208+
continue;
209+
}
210+
211+
// JSON auto-serialization for .json files with non-string content
212+
if (name.endsWith(".json") && typeof content !== "string") {
213+
await inner.write(url, JSON.stringify(content, null, 2));
214+
continue;
215+
}
216+
217+
// String content
218+
await inner.write(url, content as string);
219+
}
220+
}
221+
222+
await writeTree(files, base);
223+
224+
const cleanup = () => inner.deleteAll(path).then(() => undefined);
225+
onTestFinished(cleanup);
226+
227+
return {
228+
root: base,
229+
resolve,
230+
cleanup,
231+
...scoped,
232+
};
233233
}

0 commit comments

Comments
 (0)