mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-19 12:38:38 +00:00
test: share workspace skill test helpers
This commit is contained in:
@@ -25,6 +25,33 @@ async function createCaseDir(prefix: string): Promise<string> {
|
|||||||
return dir;
|
return dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function syncSourceSkillsToTarget(sourceWorkspace: string, targetWorkspace: string) {
|
||||||
|
await withEnv({ HOME: sourceWorkspace, PATH: "" }, () =>
|
||||||
|
syncSkillsToWorkspace({
|
||||||
|
sourceWorkspaceDir: sourceWorkspace,
|
||||||
|
targetWorkspaceDir: targetWorkspace,
|
||||||
|
bundledSkillsDir: path.join(sourceWorkspace, ".bundled"),
|
||||||
|
managedSkillsDir: path.join(sourceWorkspace, ".managed"),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function expectSyncedSkillConfinement(params: {
|
||||||
|
sourceWorkspace: string;
|
||||||
|
targetWorkspace: string;
|
||||||
|
safeSkillDirName: string;
|
||||||
|
escapedDest: string;
|
||||||
|
}) {
|
||||||
|
expect(await pathExists(params.escapedDest)).toBe(false);
|
||||||
|
await syncSourceSkillsToTarget(params.sourceWorkspace, params.targetWorkspace);
|
||||||
|
expect(
|
||||||
|
await pathExists(
|
||||||
|
path.join(params.targetWorkspace, "skills", params.safeSkillDirName, "SKILL.md"),
|
||||||
|
),
|
||||||
|
).toBe(true);
|
||||||
|
expect(await pathExists(params.escapedDest)).toBe(false);
|
||||||
|
}
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
fixtureRoot = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-skills-sync-suite-"));
|
fixtureRoot = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-skills-sync-suite-"));
|
||||||
syncSourceTemplateDir = await createCaseDir("source-template");
|
syncSourceTemplateDir = await createCaseDir("source-template");
|
||||||
@@ -115,14 +142,7 @@ describe("buildWorkspaceSkillsPrompt", () => {
|
|||||||
"dir",
|
"dir",
|
||||||
);
|
);
|
||||||
|
|
||||||
await withEnv({ HOME: sourceWorkspace, PATH: "" }, () =>
|
await syncSourceSkillsToTarget(sourceWorkspace, targetWorkspace);
|
||||||
syncSkillsToWorkspace({
|
|
||||||
sourceWorkspaceDir: sourceWorkspace,
|
|
||||||
targetWorkspaceDir: targetWorkspace,
|
|
||||||
bundledSkillsDir: path.join(sourceWorkspace, ".bundled"),
|
|
||||||
managedSkillsDir: path.join(sourceWorkspace, ".managed"),
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
const prompt = buildPrompt(targetWorkspace, {
|
const prompt = buildPrompt(targetWorkspace, {
|
||||||
bundledSkillsDir: path.join(targetWorkspace, ".bundled"),
|
bundledSkillsDir: path.join(targetWorkspace, ".bundled"),
|
||||||
@@ -151,21 +171,12 @@ describe("buildWorkspaceSkillsPrompt", () => {
|
|||||||
expect(path.relative(path.join(targetWorkspace, "skills"), escapedDest).startsWith("..")).toBe(
|
expect(path.relative(path.join(targetWorkspace, "skills"), escapedDest).startsWith("..")).toBe(
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
expect(await pathExists(escapedDest)).toBe(false);
|
await expectSyncedSkillConfinement({
|
||||||
|
sourceWorkspace,
|
||||||
await withEnv({ HOME: sourceWorkspace, PATH: "" }, () =>
|
targetWorkspace,
|
||||||
syncSkillsToWorkspace({
|
safeSkillDirName: "safe-traversal-skill",
|
||||||
sourceWorkspaceDir: sourceWorkspace,
|
escapedDest,
|
||||||
targetWorkspaceDir: targetWorkspace,
|
});
|
||||||
bundledSkillsDir: path.join(sourceWorkspace, ".bundled"),
|
|
||||||
managedSkillsDir: path.join(sourceWorkspace, ".managed"),
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
await pathExists(path.join(targetWorkspace, "skills", "safe-traversal-skill", "SKILL.md")),
|
|
||||||
).toBe(true);
|
|
||||||
expect(await pathExists(escapedDest)).toBe(false);
|
|
||||||
});
|
});
|
||||||
it("keeps synced skills confined under target workspace when frontmatter name is absolute", async () => {
|
it("keeps synced skills confined under target workspace when frontmatter name is absolute", async () => {
|
||||||
const sourceWorkspace = await createCaseDir("source");
|
const sourceWorkspace = await createCaseDir("source");
|
||||||
@@ -180,21 +191,12 @@ describe("buildWorkspaceSkillsPrompt", () => {
|
|||||||
description: "Absolute skill",
|
description: "Absolute skill",
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(await pathExists(absoluteDest)).toBe(false);
|
await expectSyncedSkillConfinement({
|
||||||
|
sourceWorkspace,
|
||||||
await withEnv({ HOME: sourceWorkspace, PATH: "" }, () =>
|
targetWorkspace,
|
||||||
syncSkillsToWorkspace({
|
safeSkillDirName: "safe-absolute-skill",
|
||||||
sourceWorkspaceDir: sourceWorkspace,
|
escapedDest: absoluteDest,
|
||||||
targetWorkspaceDir: targetWorkspace,
|
});
|
||||||
bundledSkillsDir: path.join(sourceWorkspace, ".bundled"),
|
|
||||||
managedSkillsDir: path.join(sourceWorkspace, ".managed"),
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
await pathExists(path.join(targetWorkspace, "skills", "safe-absolute-skill", "SKILL.md")),
|
|
||||||
).toBe(true);
|
|
||||||
expect(await pathExists(absoluteDest)).toBe(false);
|
|
||||||
});
|
});
|
||||||
it("filters skills based on env/config gates", async () => {
|
it("filters skills based on env/config gates", async () => {
|
||||||
const workspaceDir = await createCaseDir("workspace");
|
const workspaceDir = await createCaseDir("workspace");
|
||||||
|
|||||||
@@ -49,6 +49,16 @@ const withClearedEnv = <T>(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
async function writeEnvSkill(workspaceDir: string) {
|
||||||
|
const skillDir = path.join(workspaceDir, "skills", "env-skill");
|
||||||
|
await writeSkill({
|
||||||
|
dir: skillDir,
|
||||||
|
name: "env-skill",
|
||||||
|
description: "Needs env",
|
||||||
|
metadata: '{"openclaw":{"requires":{"env":["ENV_KEY"]},"primaryEnv":"ENV_KEY"}}',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
await fixtureSuite.setup();
|
await fixtureSuite.setup();
|
||||||
tempHome = await createTempHomeEnv("openclaw-skills-home-");
|
tempHome = await createTempHomeEnv("openclaw-skills-home-");
|
||||||
@@ -240,13 +250,7 @@ describe("buildWorkspaceSkillsPrompt", () => {
|
|||||||
describe("applySkillEnvOverrides", () => {
|
describe("applySkillEnvOverrides", () => {
|
||||||
it("sets and restores env vars", async () => {
|
it("sets and restores env vars", async () => {
|
||||||
const workspaceDir = await makeWorkspace();
|
const workspaceDir = await makeWorkspace();
|
||||||
const skillDir = path.join(workspaceDir, "skills", "env-skill");
|
await writeEnvSkill(workspaceDir);
|
||||||
await writeSkill({
|
|
||||||
dir: skillDir,
|
|
||||||
name: "env-skill",
|
|
||||||
description: "Needs env",
|
|
||||||
metadata: '{"openclaw":{"requires":{"env":["ENV_KEY"]},"primaryEnv":"ENV_KEY"}}',
|
|
||||||
});
|
|
||||||
|
|
||||||
const entries = loadWorkspaceSkillEntries(workspaceDir, resolveTestSkillDirs(workspaceDir));
|
const entries = loadWorkspaceSkillEntries(workspaceDir, resolveTestSkillDirs(workspaceDir));
|
||||||
|
|
||||||
@@ -269,13 +273,7 @@ describe("applySkillEnvOverrides", () => {
|
|||||||
|
|
||||||
it("keeps env keys tracked until all overlapping overrides restore", async () => {
|
it("keeps env keys tracked until all overlapping overrides restore", async () => {
|
||||||
const workspaceDir = await makeWorkspace();
|
const workspaceDir = await makeWorkspace();
|
||||||
const skillDir = path.join(workspaceDir, "skills", "env-skill");
|
await writeEnvSkill(workspaceDir);
|
||||||
await writeSkill({
|
|
||||||
dir: skillDir,
|
|
||||||
name: "env-skill",
|
|
||||||
description: "Needs env",
|
|
||||||
metadata: '{"openclaw":{"requires":{"env":["ENV_KEY"]},"primaryEnv":"ENV_KEY"}}',
|
|
||||||
});
|
|
||||||
|
|
||||||
const entries = loadWorkspaceSkillEntries(workspaceDir, resolveTestSkillDirs(workspaceDir));
|
const entries = loadWorkspaceSkillEntries(workspaceDir, resolveTestSkillDirs(workspaceDir));
|
||||||
|
|
||||||
@@ -301,13 +299,7 @@ describe("applySkillEnvOverrides", () => {
|
|||||||
|
|
||||||
it("applies env overrides from snapshots", async () => {
|
it("applies env overrides from snapshots", async () => {
|
||||||
const workspaceDir = await makeWorkspace();
|
const workspaceDir = await makeWorkspace();
|
||||||
const skillDir = path.join(workspaceDir, "skills", "env-skill");
|
await writeEnvSkill(workspaceDir);
|
||||||
await writeSkill({
|
|
||||||
dir: skillDir,
|
|
||||||
name: "env-skill",
|
|
||||||
description: "Needs env",
|
|
||||||
metadata: '{"openclaw":{"requires":{"env":["ENV_KEY"]},"primaryEnv":"ENV_KEY"}}',
|
|
||||||
});
|
|
||||||
|
|
||||||
const snapshot = buildWorkspaceSkillSnapshot(workspaceDir, {
|
const snapshot = buildWorkspaceSkillSnapshot(workspaceDir, {
|
||||||
...resolveTestSkillDirs(workspaceDir),
|
...resolveTestSkillDirs(workspaceDir),
|
||||||
|
|||||||
Reference in New Issue
Block a user