From 544a1142b0db55bc107f89bf81a29b437dc84090 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 21 Feb 2026 19:43:31 +0000 Subject: [PATCH] test(agents): dedupe skill helper fixtures and cover empty-body rendering --- src/agents/skills.e2e-test-helpers.test.ts | 76 ++++++++++++++-------- 1 file changed, 50 insertions(+), 26 deletions(-) diff --git a/src/agents/skills.e2e-test-helpers.test.ts b/src/agents/skills.e2e-test-helpers.test.ts index 22cd6e7496c..ffa6922cb2e 100644 --- a/src/agents/skills.e2e-test-helpers.test.ts +++ b/src/agents/skills.e2e-test-helpers.test.ts @@ -6,6 +6,16 @@ import { writeSkill } from "./skills.e2e-test-helpers.js"; const tempDirs: string[] = []; +async function withTempSkillDir( + name: string, + run: (params: { root: string; skillDir: string }) => Promise, +) { + const root = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-skill-helper-")); + tempDirs.push(root); + const skillDir = path.join(root, name); + await run({ root, skillDir }); +} + afterEach(async () => { await Promise.all( tempDirs.splice(0, tempDirs.length).map((dir) => fs.rm(dir, { recursive: true, force: true })), @@ -14,39 +24,53 @@ afterEach(async () => { describe("writeSkill", () => { it("writes SKILL.md with required fields", async () => { - const root = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-skill-helper-")); - tempDirs.push(root); - const skillDir = path.join(root, "demo-skill"); + await withTempSkillDir("demo-skill", async ({ skillDir }) => { + await writeSkill({ + dir: skillDir, + name: "demo-skill", + description: "Demo", + }); - await writeSkill({ - dir: skillDir, - name: "demo-skill", - description: "Demo", + const content = await fs.readFile(path.join(skillDir, "SKILL.md"), "utf-8"); + expect(content).toContain("name: demo-skill"); + expect(content).toContain("description: Demo"); + expect(content).toContain("# demo-skill"); }); - - const content = await fs.readFile(path.join(skillDir, "SKILL.md"), "utf-8"); - expect(content).toContain("name: demo-skill"); - expect(content).toContain("description: Demo"); - expect(content).toContain("# demo-skill"); }); it("includes optional metadata, body, and frontmatterExtra", async () => { - const root = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-skill-helper-")); - tempDirs.push(root); - const skillDir = path.join(root, "custom-skill"); + await withTempSkillDir("custom-skill", async ({ skillDir }) => { + await writeSkill({ + dir: skillDir, + name: "custom-skill", + description: "Custom", + metadata: '{"openclaw":{"always":true}}', + frontmatterExtra: "user-invocable: false", + body: "# Custom Body\n", + }); - await writeSkill({ - dir: skillDir, - name: "custom-skill", - description: "Custom", - metadata: '{"openclaw":{"always":true}}', - frontmatterExtra: "user-invocable: false", - body: "# Custom Body\n", + const content = await fs.readFile(path.join(skillDir, "SKILL.md"), "utf-8"); + expect(content).toContain('metadata: {"openclaw":{"always":true}}'); + expect(content).toContain("user-invocable: false"); + expect(content).toContain("# Custom Body"); }); + }); - const content = await fs.readFile(path.join(skillDir, "SKILL.md"), "utf-8"); - expect(content).toContain('metadata: {"openclaw":{"always":true}}'); - expect(content).toContain("user-invocable: false"); - expect(content).toContain("# Custom Body"); + it("keeps empty body and trims blank frontmatter extra entries", async () => { + await withTempSkillDir("empty-body-skill", async ({ skillDir }) => { + await writeSkill({ + dir: skillDir, + name: "empty-body-skill", + description: "Empty body", + frontmatterExtra: " ", + body: "", + }); + + const content = await fs.readFile(path.join(skillDir, "SKILL.md"), "utf-8"); + expect(content).toContain("name: empty-body-skill"); + expect(content).toContain("description: Empty body"); + expect(content).not.toContain("# empty-body-skill"); + expect(content).not.toContain("user-invocable:"); + }); }); });