test: trim more unit test startup overhead

This commit is contained in:
Peter Steinberger
2026-03-22 07:52:10 +00:00
parent 3cd4978fc2
commit 574cc9de64
4 changed files with 111 additions and 113 deletions

View File

@@ -272,57 +272,57 @@ describe("installHooksFromPath", () => {
expect(fs.existsSync(path.join(result.targetDir, "HOOK.md"))).toBe(true);
});
it("rejects hook pack entries that traverse outside package directory", async () => {
const stateDir = makeTempDir();
const workDir = makeTempDir();
const pkgDir = path.join(workDir, "package");
const outsideHookDir = path.join(workDir, "outside");
fs.mkdirSync(pkgDir, { recursive: true });
fs.mkdirSync(outsideHookDir, { recursive: true });
writeHookPackManifest({
pkgDir,
hooks: ["../outside"],
});
fs.writeFileSync(path.join(outsideHookDir, "HOOK.md"), "---\nname: outside\n---\n", "utf-8");
fs.writeFileSync(path.join(outsideHookDir, "handler.ts"), "export default async () => {};\n");
it("rejects out-of-package hook entries", async () => {
const cases = [
{
hooks: ["../outside"],
setupLink: false,
expected: "openclaw.hooks entry escapes package directory",
},
{
hooks: ["./linked"],
setupLink: true,
expected: "openclaw.hooks entry resolves outside package directory",
},
] as const;
const result = await installHooksFromPath({
path: pkgDir,
hooksDir: path.join(stateDir, "hooks"),
});
for (const testCase of cases) {
const stateDir = makeTempDir();
const workDir = makeTempDir();
const pkgDir = path.join(workDir, "package");
const outsideHookDir = path.join(workDir, "outside");
const linkedDir = path.join(pkgDir, "linked");
fs.mkdirSync(pkgDir, { recursive: true });
fs.mkdirSync(outsideHookDir, { recursive: true });
fs.writeFileSync(path.join(outsideHookDir, "HOOK.md"), "---\nname: outside\n---\n", "utf-8");
fs.writeFileSync(
path.join(outsideHookDir, "handler.ts"),
"export default async () => {};\n",
"utf-8",
);
if (testCase.setupLink) {
try {
fs.symlinkSync(
outsideHookDir,
linkedDir,
process.platform === "win32" ? "junction" : "dir",
);
} catch {
continue;
}
}
writeHookPackManifest({
pkgDir,
hooks: [...testCase.hooks],
});
expectPathInstallFailureContains(result, "openclaw.hooks entry escapes package directory");
});
const result = await installHooksFromPath({
path: pkgDir,
hooksDir: path.join(stateDir, "hooks"),
});
it("rejects hook pack entries that escape via symlink", async () => {
const stateDir = makeTempDir();
const workDir = makeTempDir();
const pkgDir = path.join(workDir, "package");
const outsideHookDir = path.join(workDir, "outside");
const linkedDir = path.join(pkgDir, "linked");
fs.mkdirSync(pkgDir, { recursive: true });
fs.mkdirSync(outsideHookDir, { recursive: true });
fs.writeFileSync(path.join(outsideHookDir, "HOOK.md"), "---\nname: outside\n---\n", "utf-8");
fs.writeFileSync(path.join(outsideHookDir, "handler.ts"), "export default async () => {};\n");
try {
fs.symlinkSync(outsideHookDir, linkedDir, process.platform === "win32" ? "junction" : "dir");
} catch {
return;
expectPathInstallFailureContains(result, testCase.expected);
}
writeHookPackManifest({
pkgDir,
hooks: ["./linked"],
});
const result = await installHooksFromPath({
path: pkgDir,
hooksDir: path.join(stateDir, "hooks"),
});
expectPathInstallFailureContains(
result,
"openclaw.hooks entry resolves outside package directory",
);
});
});

View File

@@ -437,7 +437,7 @@ describe("fs-safe", () => {
});
describe("tilde expansion in file tools", () => {
it("expandHomePrefix respects process.env.HOME changes", async () => {
it("keeps tilde expansion behavior aligned", async () => {
const { expandHomePrefix } = await import("./home-dir.js");
const originalHome = process.env.HOME;
const fakeHome = path.resolve(path.sep, "tmp", "fake-home-test");
@@ -448,11 +448,8 @@ describe("tilde expansion in file tools", () => {
} finally {
process.env.HOME = originalHome;
}
});
it("reads a file via ~/path after HOME override", async () => {
const root = await tempDirs.make("openclaw-tilde-test-");
const originalHome = process.env.HOME;
process.env.HOME = root;
try {
await fs.writeFile(path.join(root, "hello.txt"), "tilde-works");
@@ -464,16 +461,7 @@ describe("tilde expansion in file tools", () => {
await result.handle.read(buf, 0, buf.length, 0);
await result.handle.close();
expect(buf.toString("utf8")).toBe("tilde-works");
} finally {
process.env.HOME = originalHome;
}
});
it("writes a file via ~/path after HOME override", async () => {
const root = await tempDirs.make("openclaw-tilde-test-");
const originalHome = process.env.HOME;
process.env.HOME = root;
try {
await writeFileWithinRoot({
rootDir: root,
relativePath: "~/output.txt",
@@ -484,14 +472,11 @@ describe("tilde expansion in file tools", () => {
} finally {
process.env.HOME = originalHome;
}
});
it("rejects ~/path that resolves outside root", async () => {
const root = await tempDirs.make("openclaw-tilde-outside-");
// HOME points to real home, ~/file goes to /home/dev/file which is outside root
const outsideRoot = await tempDirs.make("openclaw-tilde-outside-");
await expect(
openFileWithinRoot({
rootDir: root,
rootDir: outsideRoot,
relativePath: "~/escape.txt",
}),
).rejects.toMatchObject({

View File

@@ -52,7 +52,6 @@ const sourceCache = new Map<string, string>();
const representativeRuntimeSmokeSubpaths = [
"channel-runtime",
"conversation-runtime",
"discord",
"provider-auth",
"provider-setup",
"setup",
@@ -125,24 +124,28 @@ function expectSourceContract(
describe("plugin-sdk subpath exports", () => {
it("keeps the curated public list free of internal implementation subpaths", () => {
expect(pluginSdkSubpaths).not.toContain("acpx");
expect(pluginSdkSubpaths).not.toContain("compat");
expect(pluginSdkSubpaths).not.toContain("device-pair");
expect(pluginSdkSubpaths).not.toContain("google");
expect(pluginSdkSubpaths).not.toContain("lobster");
expect(pluginSdkSubpaths).not.toContain("pairing-access");
expect(pluginSdkSubpaths).not.toContain("qwen-portal-auth");
expect(pluginSdkSubpaths).not.toContain("reply-prefix");
expect(pluginSdkSubpaths).not.toContain("signal-core");
expect(pluginSdkSubpaths).not.toContain("synology-chat");
expect(pluginSdkSubpaths).not.toContain("typing");
expect(pluginSdkSubpaths).not.toContain("whatsapp");
expect(pluginSdkSubpaths).not.toContain("whatsapp-action-runtime");
expect(pluginSdkSubpaths).not.toContain("whatsapp-login-qr");
expect(pluginSdkSubpaths).not.toContain("secret-input-runtime");
expect(pluginSdkSubpaths).not.toContain("secret-input-schema");
expect(pluginSdkSubpaths).not.toContain("zai");
expect(pluginSdkSubpaths).not.toContain("provider-model-definitions");
for (const deniedSubpath of [
"acpx",
"compat",
"device-pair",
"google",
"lobster",
"pairing-access",
"provider-model-definitions",
"qwen-portal-auth",
"reply-prefix",
"secret-input-runtime",
"secret-input-schema",
"signal-core",
"synology-chat",
"typing",
"whatsapp",
"whatsapp-action-runtime",
"whatsapp-login-qr",
"zai",
]) {
expect(pluginSdkSubpaths).not.toContain(deniedSubpath);
}
});
it("keeps core focused on generic shared exports", () => {
@@ -568,13 +571,10 @@ describe("plugin-sdk subpath exports", () => {
expectSourceMentions("testing", ["removeAckReactionAfterReply", "shouldAckReaction"]);
});
it("exports shared core types used by bundled extensions", () => {
it("keeps core shared types aligned", () => {
expectTypeOf<CoreOpenClawPluginApi>().toMatchTypeOf<OpenClawPluginApi>();
expectTypeOf<CorePluginRuntime>().toMatchTypeOf<PluginRuntime>();
expectTypeOf<CoreChannelMessageActionContext>().toMatchTypeOf<ChannelMessageActionContext>();
});
it("keeps core shared types aligned with the channel prelude", () => {
expectTypeOf<CoreOpenClawPluginApi>().toMatchTypeOf<SharedOpenClawPluginApi>();
expectTypeOf<CorePluginRuntime>().toMatchTypeOf<SharedPluginRuntime>();
expectTypeOf<CoreChannelMessageActionContext>().toMatchTypeOf<SharedChannelMessageActionContext>();

View File

@@ -57,33 +57,46 @@ afterEach(() => {
});
describe("scripts/committer", () => {
it("keeps plain argv paths working", () => {
const repo = createRepo();
writeRepoFile(repo, "alpha.txt", "alpha\n");
writeRepoFile(repo, "nested/file with spaces.txt", "beta\n");
it("accepts supported path argument shapes", () => {
const cases = [
{
commitMessage: "test: plain argv",
files: [
["alpha.txt", "alpha\n"],
["nested/file with spaces.txt", "beta\n"],
] as const,
args: ["alpha.txt", "nested/file with spaces.txt"],
expected: ["alpha.txt", "nested/file with spaces.txt"],
},
{
commitMessage: "test: space blob",
files: [
["alpha.txt", "alpha\n"],
["beta.txt", "beta\n"],
] as const,
args: ["alpha.txt beta.txt"],
expected: ["alpha.txt", "beta.txt"],
},
{
commitMessage: "test: newline blob",
files: [
["alpha.txt", "alpha\n"],
["nested/file with spaces.txt", "beta\n"],
] as const,
args: ["alpha.txt\nnested/file with spaces.txt"],
expected: ["alpha.txt", "nested/file with spaces.txt"],
},
] as const;
commitWithHelper(repo, "test: plain argv", "alpha.txt", "nested/file with spaces.txt");
for (const testCase of cases) {
const repo = createRepo();
for (const [file, contents] of testCase.files) {
writeRepoFile(repo, file, contents);
}
expect(committedPaths(repo)).toEqual(["alpha.txt", "nested/file with spaces.txt"]);
});
commitWithHelper(repo, testCase.commitMessage, ...testCase.args);
it("accepts a single space-delimited path blob", () => {
const repo = createRepo();
writeRepoFile(repo, "alpha.txt", "alpha\n");
writeRepoFile(repo, "beta.txt", "beta\n");
commitWithHelper(repo, "test: space blob", "alpha.txt beta.txt");
expect(committedPaths(repo)).toEqual(["alpha.txt", "beta.txt"]);
});
it("accepts a single newline-delimited path blob", () => {
const repo = createRepo();
writeRepoFile(repo, "alpha.txt", "alpha\n");
writeRepoFile(repo, "nested/file with spaces.txt", "beta\n");
commitWithHelper(repo, "test: newline blob", "alpha.txt\nnested/file with spaces.txt");
expect(committedPaths(repo)).toEqual(["alpha.txt", "nested/file with spaces.txt"]);
expect(committedPaths(repo)).toEqual(testCase.expected);
}
});
});