Compare commits

..

1 Commits

Author SHA1 Message Date
Oleks 6b7b962676 fix(review): format with prettier/oxfmt and address review feedback
- Run `bun check` to fix formatting (single quotes, 2-space indent),
  matching the rest of the repo's style
- Shorten the ENOENT-handling comment per review suggestion, pointing
  to the issue writeup instead of a large inline explanation
- Drop the private oleks/mcp-chrome#61 reference and rename the
  cspell-flagged `raceyFile` variable
2026-08-01 03:06:46 +03:00
2 changed files with 564 additions and 567 deletions
@@ -1,72 +1,71 @@
import { mkdir, mkdtemp, rm, stat, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
import { removeEmptyDirs } from "../index";
import { mkdir, mkdtemp, rm, stat, writeFile } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest';
import { removeEmptyDirs } from '../index';
// `stat` is mocked (defaulting to the real implementation) so individual
// tests can override it to simulate a file disappearing mid-walk - the race
// this suite exists to cover (oleks/mcp-chrome#61).
vi.mock("node:fs/promises", async (importOriginal) => {
const actual = await importOriginal<typeof import("node:fs/promises")>();
return { ...actual, stat: vi.fn(actual.stat) };
// tests can override it to simulate a file disappearing mid-walk.
vi.mock('node:fs/promises', async (importOriginal) => {
const actual = await importOriginal<typeof import('node:fs/promises')>();
return { ...actual, stat: vi.fn(actual.stat) };
});
const mockedStat = vi.mocked(stat);
let realStat: typeof import("node:fs/promises").stat;
let realStat: typeof import('node:fs/promises').stat;
describe("removeEmptyDirs", () => {
beforeAll(async () => {
realStat = (
await vi.importActual<typeof import("node:fs/promises")>(
"node:fs/promises",
)
).stat;
});
describe('removeEmptyDirs', () => {
beforeAll(async () => {
realStat = (
await vi.importActual<typeof import('node:fs/promises')>(
'node:fs/promises',
)
).stat;
});
afterEach(() => {
mockedStat.mockImplementation(realStat);
});
afterEach(() => {
mockedStat.mockImplementation(realStat);
});
it("removes nested empty directories", async () => {
const dir = await mkdtemp(join(tmpdir(), "wxt-remove-empty-dirs-"));
try {
await mkdir(join(dir, "a", "b"), { recursive: true });
await writeFile(join(dir, "a", "keep.txt"), "x");
it('removes nested empty directories', async () => {
const dir = await mkdtemp(join(tmpdir(), 'wxt-remove-empty-dirs-'));
try {
await mkdir(join(dir, 'a', 'b'), { recursive: true });
await writeFile(join(dir, 'a', 'keep.txt'), 'x');
await removeEmptyDirs(dir);
await removeEmptyDirs(dir);
await expect(realStat(join(dir, "a", "b"))).rejects.toThrow();
await expect(realStat(join(dir, "a", "keep.txt"))).resolves.toBeDefined();
} finally {
await rm(dir, { recursive: true, force: true });
}
});
await expect(realStat(join(dir, 'a', 'b'))).rejects.toThrow();
await expect(realStat(join(dir, 'a', 'keep.txt'))).resolves.toBeDefined();
} finally {
await rm(dir, { recursive: true, force: true });
}
});
it("does not throw when a file disappears between readdir and stat (a concurrent plugin write, oleks/mcp-chrome#61)", async () => {
const dir = await mkdtemp(join(tmpdir(), "wxt-remove-empty-dirs-"));
try {
await mkdir(join(dir, "inject-scripts"), { recursive: true });
const raceyFile = join(dir, "inject-scripts", "recorder.js");
await writeFile(raceyFile, "x");
it('does not throw when a file disappears between readdir and stat (a concurrent plugin write)', async () => {
const dir = await mkdtemp(join(tmpdir(), 'wxt-remove-empty-dirs-'));
try {
await mkdir(join(dir, 'inject-scripts'), { recursive: true });
const disappearingFile = join(dir, 'inject-scripts', 'recorder.js');
await writeFile(disappearingFile, 'x');
mockedStat.mockImplementation((async (
path: Parameters<typeof stat>[0],
...args: unknown[]
) => {
if (path === raceyFile) {
const err: NodeJS.ErrnoException = new Error(
"ENOENT: no such file or directory",
);
err.code = "ENOENT";
throw err;
}
return (realStat as (...a: unknown[]) => unknown)(path, ...args);
}) as typeof stat);
mockedStat.mockImplementation((async (
path: Parameters<typeof stat>[0],
...args: unknown[]
) => {
if (path === disappearingFile) {
const err: NodeJS.ErrnoException = new Error(
'ENOENT: no such file or directory',
);
err.code = 'ENOENT';
throw err;
}
return (realStat as (...a: unknown[]) => unknown)(path, ...args);
}) as typeof stat);
await expect(removeEmptyDirs(dir)).resolves.not.toThrow();
} finally {
await rm(dir, { recursive: true, force: true });
}
});
await expect(removeEmptyDirs(dir)).resolves.not.toThrow();
} finally {
await rm(dir, { recursive: true, force: true });
}
});
});
File diff suppressed because it is too large Load Diff