openclaw/test/scripts/tsdown-runtime-cache.test.ts
Peter Steinberger a3267d4b57
test(agents,chat,ci): remove low-value tests (batch d309) (#178243)
* test(anthropic): deslop z0062 tests

* test(anthropic): deslop z0062 tests

* test(auto-reply): deslop z0065 tests

* test(auto-reply): deslop z0065 tests

* test(codex): deslop z0066 tests

* test(codex): deslop z0066 tests

* test(codex): deslop z0066 tests

* test(auto-reply): deslop z0067 tests

* test(auto-reply): deslop z0067 tests

* test(auto-reply): deslop z0067 tests

* test(scripts): deslop z0068 tests

* test(scripts): deslop z0068 tests

* test(scripts): deslop z0068 tests

* test(agents): deslop z0069 tests

* test(agents): deslop z0069 tests

* test(agents): deslop z0069 tests

* test(chat): deslop z0070 tests

* test(chat): deslop z0070 tests

* test(chat): deslop z0070 tests

* test(scripts): deslop z0071 tests

* test(scripts): deslop z0071 tests

* test(scripts): deslop z0071 tests

* test(agents): deslop z0064 tests

* test(agents): deslop z0064 tests

* test(agents): deslop z0064 tests

* test(agents): deslop z0072 tests

* test(agents): deslop z0072 tests

* test(agents): deslop z0072 tests

* test(ci): deslop z0073 tests

* test(ci): deslop z0073 tests

* test(auto-reply): reuse shared execution fixture after replay

* test: preserve boundary controls and repair batch fixture types

* test(scripts): allow new literal credential guard fixtures

* test: shrink timeout baseline and document mock isolation

* test: prune retired mock export baseline entries
2026-10-20 02:38:51 -07:00

125 lines
5.4 KiB
TypeScript

import fs from "node:fs";
import path from "node:path";
import type { UserConfig } from "tsdown";
import { afterEach, expect, it, vi } from "vitest";
import {
cacheTsdownRuntimeConfigs,
finalizeTsdownRuntimeCaches,
TSDOWN_CACHE_PENDING_ENV,
} from "../../scripts/lib/tsdown-runtime-cache.mts";
import { createScriptTestHarness } from "./test-helpers.js";
const { createTempDir } = createScriptTestHarness();
afterEach(() => {
vi.unstubAllEnvs();
vi.restoreAllMocks();
});
it("restores unchanged package artifacts and invalidates changed compiler inputs or corrupt output", async () => {
let root = createTempDir("tsdown-runtime-cache-");
fs.writeFileSync(path.join(root, "package.json"), '{"type":"module"}');
vi.spyOn(process, "cwd").mockImplementation(() => root);
vi.stubEnv("OPENCLAW_RUN_NODE_SKIP_DTS_BUILD", "1");
const cache = createTempDir("tsdown-runtime-cache-store-");
vi.stubEnv("BUILD_ALL_CACHE_ROOT", cache);
const configurations = (): UserConfig[] =>
["a", "b"].map((name) => ({
dts: false,
name: "packages",
entry: { index: path.join(root, `packages/${name}/src/index.ts`) },
outDir: `packages/${name}/dist`,
}));
const source = (name: string) => path.join(root, `packages/${name}/src/index.ts`);
const output = (name: string) => path.join(root, `packages/${name}/dist/index.js`);
const dependency = () => path.join(root, "shared.ts");
fs.writeFileSync(dependency(), "original shared input");
for (const name of ["a", "b"]) {
fs.mkdirSync(path.dirname(source(name)), { recursive: true });
fs.writeFileSync(source(name), `export const value = "${name}-original";`);
}
const select = () => {
fs.mkdirSync(path.join(root, ".artifacts"), { recursive: true });
const pending = fs.mkdtempSync(path.join(root, ".artifacts/pending-"));
vi.stubEnv(TSDOWN_CACHE_PENDING_ENV, pending);
return { pending, configs: cacheTsdownRuntimeConfigs(configurations()) };
};
// A small compiler-host fixture supplies watch membership, writes the output,
// and signals success through the same plugin/hooks contract as tsdown.
const complete = async (configs: UserConfig[]) => {
for (const config of configs) {
const name = path.basename(path.dirname(config.outDir!));
const watched = [source(name), ...(name === "a" ? [dependency()] : [])];
type DoneContext = {
chunks: { outDir: string; fileName: string }[];
options: { configDeps: Set<string> };
};
const done: ((context: DoneContext) => void)[] = [];
if (typeof config.hooks === "function") {
await Reflect.apply(config.hooks, undefined, [
{
hook(event: string, callback: (context: DoneContext) => void) {
if (event === "build:done") {
done.push(callback);
}
},
},
]);
}
const plugins = Array.isArray(config.plugins) ? config.plugins.flat() : [config.plugins];
for (const plugin of plugins) {
if (
plugin &&
typeof plugin === "object" &&
"buildEnd" in plugin &&
typeof plugin.buildEnd === "function"
) {
Reflect.apply(plugin.buildEnd, { getModuleIds: () => watched.values() }, [undefined]);
}
}
fs.mkdirSync(path.dirname(output(name)), { recursive: true });
fs.writeFileSync(
output(name),
watched.map((file) => fs.readFileSync(file, "utf8")).join("\n"),
);
done.forEach((callback) =>
callback({
chunks: [{ outDir: path.dirname(output(name)), fileName: "index.js" }],
options: { configDeps: new Set([path.join(root, "package.json")]) },
}),
);
}
};
const first = select();
fs.mkdirSync(path.join(root, "dist"));
await complete(first.configs);
finalizeTsdownRuntimeCaches(first.pending, root);
const originalB = fs.readFileSync(output("b"), "utf8");
fs.rmSync(path.join(root, "packages/a/dist"), { recursive: true });
fs.rmSync(path.join(root, "packages/b/dist"), { recursive: true });
fs.rmSync(path.join(root, "dist"), { recursive: true });
const previousRoot = root;
root = createTempDir("tsdown-runtime-cache-next-release-");
fs.cpSync(previousRoot, root, { recursive: true });
fs.writeFileSync(path.join(root, "shared.ts"), "changed shared input");
const second = select();
expect(second.configs.map((config) => config.outDir)).toEqual(["packages/a/dist"]);
expect(fs.readFileSync(output("b"), "utf8")).toBe(originalB);
await complete(second.configs);
finalizeTsdownRuntimeCaches(second.pending, root);
expect(fs.readFileSync(output("a"), "utf8")).toContain("changed shared input");
const cachedB = path.join(cache, "tsdown-runtime-b/outputs/packages/b/dist/index.js");
fs.writeFileSync(cachedB, "corrupt");
fs.rmSync(path.join(root, "packages/b/dist"), { recursive: true });
const third = select();
expect(third.configs.map((config) => config.outDir)).toEqual(["packages/b/dist"]);
expect(fs.existsSync(output("b"))).toBe(false);
});
it("leaves direct builds and declaration configurations with the compiler", () => {
const config: UserConfig = { entry: { index: "index.ts" }, dts: false };
expect(cacheTsdownRuntimeConfigs([config])).toEqual([config]);
vi.stubEnv(TSDOWN_CACHE_PENDING_ENV, "unused");
vi.stubEnv("OPENCLAW_RUN_NODE_SKIP_DTS_BUILD", "1");
const declaration = { ...config, dts: true };
expect(cacheTsdownRuntimeConfigs([declaration])).toEqual([declaration]);
});