Phase 4: add expand tests — frontmatter strip, paths, suffix.
Cover readSkillBody, formatBlock, appendSuffix, and expandSkill per SPEC §12.1. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "fs";
|
||||
import { tmpdir } from "os";
|
||||
import { join } from "path";
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import {
|
||||
appendSuffix,
|
||||
expandSkill,
|
||||
formatBlock,
|
||||
readSkillBody,
|
||||
type SkillBlockMeta,
|
||||
} from "../src/expand";
|
||||
|
||||
const tempDirs: string[] = [];
|
||||
|
||||
afterEach(() => {
|
||||
for (const dir of tempDirs.splice(0)) {
|
||||
rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
function writeSkillMd(dir: string, name: string, content: string): SkillBlockMeta {
|
||||
const baseDir = join(dir, name);
|
||||
const filePath = join(baseDir, "SKILL.md");
|
||||
mkdirSync(baseDir, { recursive: true });
|
||||
writeFileSync(filePath, content, "utf-8");
|
||||
return { name, filePath, baseDir };
|
||||
}
|
||||
|
||||
describe("readSkillBody", () => {
|
||||
it("strips YAML frontmatter and trims body", () => {
|
||||
const dir = mkdtempSync(join(tmpdir(), "pi-skill-reinject-expand-"));
|
||||
tempDirs.push(dir);
|
||||
const meta = writeSkillMd(
|
||||
dir,
|
||||
"demo-skill",
|
||||
`---
|
||||
name: demo-skill
|
||||
description: Demo
|
||||
---
|
||||
|
||||
# Instructions
|
||||
|
||||
Do the thing.
|
||||
`,
|
||||
);
|
||||
|
||||
expect(readSkillBody(meta.filePath)).toBe("# Instructions\n\nDo the thing.");
|
||||
});
|
||||
|
||||
it("returns trimmed body when frontmatter is absent", () => {
|
||||
const dir = mkdtempSync(join(tmpdir(), "pi-skill-reinject-expand-"));
|
||||
tempDirs.push(dir);
|
||||
const meta = writeSkillMd(dir, "plain", " hello world \n");
|
||||
|
||||
expect(readSkillBody(meta.filePath)).toBe("hello world");
|
||||
});
|
||||
});
|
||||
|
||||
describe("formatBlock", () => {
|
||||
it("embeds name, location, baseDir, and body", () => {
|
||||
const meta: SkillBlockMeta = {
|
||||
name: "brave-search",
|
||||
filePath: "/home/user/.pi/skills/brave-search/SKILL.md",
|
||||
baseDir: "/home/user/.pi/skills/brave-search",
|
||||
};
|
||||
|
||||
expect(formatBlock(meta, "Search the web.")).toBe(
|
||||
`<skill name="brave-search" location="/home/user/.pi/skills/brave-search/SKILL.md">
|
||||
References are relative to /home/user/.pi/skills/brave-search.
|
||||
|
||||
Search the web.
|
||||
</skill>`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("appendSuffix", () => {
|
||||
it("appends suffix after a blank line", () => {
|
||||
const block = "<skill>body</skill>";
|
||||
expect(appendSuffix(block, "[skill-reinject] note")).toBe(
|
||||
`${block}\n\n[skill-reinject] note`,
|
||||
);
|
||||
});
|
||||
|
||||
it("returns block unchanged for empty or whitespace suffix", () => {
|
||||
const block = "<skill>body</skill>";
|
||||
expect(appendSuffix(block, undefined)).toBe(block);
|
||||
expect(appendSuffix(block, " ")).toBe(block);
|
||||
});
|
||||
});
|
||||
|
||||
describe("expandSkill", () => {
|
||||
it("produces full injectable text with optional suffix", () => {
|
||||
const dir = mkdtempSync(join(tmpdir(), "pi-skill-reinject-expand-"));
|
||||
tempDirs.push(dir);
|
||||
const meta = writeSkillMd(
|
||||
dir,
|
||||
"pdf-tools",
|
||||
`---
|
||||
name: pdf-tools
|
||||
---
|
||||
|
||||
Extract pages from PDFs.
|
||||
`,
|
||||
);
|
||||
|
||||
const withoutSuffix = expandSkill(meta);
|
||||
expect(withoutSuffix).toContain('name="pdf-tools"');
|
||||
expect(withoutSuffix).toContain(`location="${meta.filePath}"`);
|
||||
expect(withoutSuffix).toContain(`References are relative to ${meta.baseDir}.`);
|
||||
expect(withoutSuffix).toContain("Extract pages from PDFs.");
|
||||
|
||||
expect(expandSkill(meta, "[skill-reinject] Re-applied.")).toBe(
|
||||
`${withoutSuffix}\n\n[skill-reinject] Re-applied.`,
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user