mirror of
https://github.com/openclaw/openclaw.git
synced 2026-10-25 00:17:41 +00:00
* 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
125 lines
5.4 KiB
TypeScript
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]);
|
|
});
|