repositories / pi-ext
pi-ext
bugabingas pi extensions
owned by admin
extensions/strata/__tests__/fixture.test.ts
Rawimport { execFile } from "node:child_process";
import { existsSync } from "node:fs";
import { mkdtemp, readFile, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import path from "node:path";
import { promisify } from "node:util";
import { aroundEach, expect, it, vi } from "vitest";
import {
cleanupNative,
git,
nativeOperation,
nativeTest,
openFixture,
testSignal,
withFakeGh,
} from "./fixture.js";
const exec = promisify(execFile);
aroundEach(nativeTest);
it("isolates fixture repositories from inherited hook Git variables", async () => {
const sentinel = await openFixture();
const gitDir = path.join(sentinel.root, ".git");
const files = ["config", "HEAD", "index"];
const before = await Promise.all(
files.map((file) => readFile(path.join(gitDir, file))),
);
const refs = await git(sentinel.root, "show-ref");
const bare = await mkdtemp(path.join(tmpdir(), "strata-bare-"));
cleanupNative(() => rm(bare, { recursive: true, force: true }));
try {
for (const [key, value] of Object.entries({
GIT_DIR: gitDir,
GIT_COMMON_DIR: gitDir,
GIT_WORK_TREE: sentinel.root,
GIT_INDEX_FILE: path.join(gitDir, "index"),
GIT_OBJECT_DIRECTORY: path.join(gitDir, "objects"),
GIT_PREFIX: "nested/",
GIT_CONFIG_COUNT: "1",
GIT_CONFIG_KEY_0: "core.bare",
GIT_CONFIG_VALUE_0: "true",
}))
vi.stubEnv(key, value);
await git(bare, "init", "--quiet", "--bare");
expect(existsSync(path.join(bare, "config"))).toBe(true);
const isolated = await openFixture();
expect(
path.normalize(
await git(isolated.root, "rev-parse", "--absolute-git-dir"),
),
).toBe(path.join(isolated.root, ".git"));
await git(isolated.root, "add", ".");
await git(isolated.root, "commit", "--quiet", "-m", "isolated change");
expect(await git(isolated.root, "log", "-1", "--format=%s")).toBe(
"isolated change",
);
} finally {
vi.unstubAllEnvs();
}
for (const [index, file] of files.entries())
expect(await readFile(path.join(gitDir, file))).toEqual(before[index]);
expect(await git(sentinel.root, "show-ref")).toBe(refs);
});
it.for(["failure", "abort"])(
"drains %s cleanup before the next fake command",
async (mode, context) => {
const before = {
PATH: process.env.PATH,
NODE_OPTIONS: process.env.NODE_OPTIONS,
STRATA_FAKE_GH_PRELOAD: process.env.STRATA_FAKE_GH_PRELOAD,
};
const controller = new AbortController();
const reason = new Error("controlled cleanup");
let fixture!: Awaited<ReturnType<typeof openFixture>>;
let preload = "";
let finished = 0;
let result!: Promise<unknown>;
const scope = nativeOperation(() =>
nativeTest(
async () => {
fixture = await openFixture();
const started = Promise.withResolvers<void>();
const release = Promise.withResolvers<void>();
result = withFakeGh('process.stdout.write("first");', async () => {
preload = process.env.STRATA_FAKE_GH_PRELOAD ?? "";
try {
// The preload must not intercept either Node or the required Node Git wrapper.
expect(
(
await exec(
process.execPath,
["-e", 'process.stdout.write("helper")'],
{ signal: testSignal() },
)
).stdout,
).toBe("helper");
expect(await git(fixture.root, "--version")).toMatch(
/^git version /,
);
started.resolve();
await release.promise;
testSignal().throwIfAborted();
throw reason;
} finally {
finished++;
started.resolve();
}
}).catch((error: unknown) => error);
await started.promise;
if (mode === "abort") controller.abort(reason);
release.resolve();
if (mode === "failure") throw await result;
// Like Vitest's timeout: runTest returns while its callback is still unwinding.
},
{ signal: AbortSignal.any([context.signal, controller.signal]) },
),
);
if (mode === "failure") await expect(scope).rejects.toBe(reason);
else await scope;
expect(await result).toBe(reason);
expect(finished).toBe(1);
expect(existsSync(preload)).toBe(false);
expect(existsSync(fixture.root)).toBe(false);
for (const [key, value] of Object.entries(before))
expect(process.env[key]).toBe(value);
await withFakeGh('process.stdout.write("later");', async () => {
const activePreload = process.env.STRATA_FAKE_GH_PRELOAD;
await fixture.close();
expect(
(await exec("gh", ["pr", "view"], { signal: context.signal })).stdout,
).toBe("later");
expect(process.env.STRATA_FAKE_GH_PRELOAD).toBe(activePreload);
expect(finished).toBe(1);
});
for (const [key, value] of Object.entries(before))
expect(process.env[key]).toBe(value);
},
);