mirror of
https://github.com/JimLiu/baoyu-skills.git
synced 2026-07-13 06:19:46 +08:00
test: migrate tests from centralized mjs to colocated TypeScript
Move test files from tests/ directory to colocate with source code, convert from .mjs to .ts using tsx runner, add workspaces and npm cache to CI workflow.
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
import assert from "node:assert/strict";
|
||||
import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import test from "node:test";
|
||||
|
||||
import {
|
||||
listReleaseFiles,
|
||||
validateSelfContainedRelease,
|
||||
} from "./release-files.mjs";
|
||||
|
||||
async function makeTempDir(prefix: string): Promise<string> {
|
||||
return fs.mkdtemp(path.join(os.tmpdir(), prefix));
|
||||
}
|
||||
|
||||
async function writeFile(filePath: string, contents = ""): Promise<void> {
|
||||
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
||||
await fs.writeFile(filePath, contents);
|
||||
}
|
||||
|
||||
async function writeJson(filePath: string, value: unknown): Promise<void> {
|
||||
await writeFile(filePath, `${JSON.stringify(value, null, 2)}\n`);
|
||||
}
|
||||
|
||||
test("listReleaseFiles skips generated paths and returns sorted relative paths", async (t) => {
|
||||
const root = await makeTempDir("baoyu-release-files-");
|
||||
t.after(() => fs.rm(root, { recursive: true, force: true }));
|
||||
|
||||
await writeFile(path.join(root, "b.txt"), "b");
|
||||
await writeFile(path.join(root, "a.txt"), "a");
|
||||
await writeFile(path.join(root, "nested", "keep.txt"), "keep");
|
||||
await writeFile(path.join(root, "node_modules", "skip.js"), "skip");
|
||||
await writeFile(path.join(root, ".git", "config"), "skip");
|
||||
await writeFile(path.join(root, "dist", "artifact.txt"), "skip");
|
||||
await writeFile(path.join(root, "out", "artifact.txt"), "skip");
|
||||
await writeFile(path.join(root, "build", "artifact.txt"), "skip");
|
||||
await writeFile(path.join(root, ".DS_Store"), "skip");
|
||||
await writeFile(path.join(root, "bun.lockb"), "skip");
|
||||
|
||||
const files = await listReleaseFiles(root);
|
||||
|
||||
assert.deepEqual(
|
||||
files.map((file) => file.relPath),
|
||||
["a.txt", "b.txt", "nested/keep.txt"],
|
||||
);
|
||||
});
|
||||
|
||||
test("validateSelfContainedRelease accepts file dependencies that stay within the release root", async (t) => {
|
||||
const root = await makeTempDir("baoyu-release-ok-");
|
||||
t.after(() => fs.rm(root, { recursive: true, force: true }));
|
||||
|
||||
await writeJson(path.join(root, "shared", "package.json"), {
|
||||
name: "shared-package",
|
||||
version: "1.0.0",
|
||||
});
|
||||
await writeFile(path.join(root, "shared", "index.js"), "export const shared = true;\n");
|
||||
await writeJson(path.join(root, "skill", "package.json"), {
|
||||
name: "test-skill",
|
||||
version: "1.0.0",
|
||||
dependencies: {
|
||||
"shared-package": "file:../shared",
|
||||
},
|
||||
});
|
||||
|
||||
await assert.doesNotReject(() => validateSelfContainedRelease(root));
|
||||
});
|
||||
|
||||
test("validateSelfContainedRelease rejects missing local file dependencies", async (t) => {
|
||||
const root = await makeTempDir("baoyu-release-missing-");
|
||||
t.after(() => fs.rm(root, { recursive: true, force: true }));
|
||||
|
||||
await writeJson(path.join(root, "skill", "package.json"), {
|
||||
name: "test-skill",
|
||||
version: "1.0.0",
|
||||
dependencies: {
|
||||
"shared-package": "file:../shared",
|
||||
},
|
||||
});
|
||||
|
||||
await assert.rejects(
|
||||
() => validateSelfContainedRelease(root),
|
||||
/Missing local dependency for release/,
|
||||
);
|
||||
});
|
||||
|
||||
test("validateSelfContainedRelease rejects file dependencies outside the release root", async (t) => {
|
||||
const root = await makeTempDir("baoyu-release-root-");
|
||||
const outside = await makeTempDir("baoyu-release-outside-");
|
||||
t.after(() => fs.rm(root, { recursive: true, force: true }));
|
||||
t.after(() => fs.rm(outside, { recursive: true, force: true }));
|
||||
|
||||
const skillDir = path.join(root, "skill");
|
||||
const externalSpec = path
|
||||
.relative(skillDir, outside)
|
||||
.split(path.sep)
|
||||
.join("/");
|
||||
|
||||
await writeJson(path.join(skillDir, "package.json"), {
|
||||
name: "test-skill",
|
||||
version: "1.0.0",
|
||||
dependencies: {
|
||||
"outside-package": `file:${externalSpec}`,
|
||||
},
|
||||
});
|
||||
|
||||
await assert.rejects(
|
||||
() => validateSelfContainedRelease(root),
|
||||
/Release target is not self-contained/,
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,70 @@
|
||||
import assert from "node:assert/strict";
|
||||
import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import test from "node:test";
|
||||
|
||||
import { syncSharedSkillPackages } from "./shared-skill-packages.mjs";
|
||||
|
||||
async function makeTempDir(prefix: string): Promise<string> {
|
||||
return fs.mkdtemp(path.join(os.tmpdir(), prefix));
|
||||
}
|
||||
|
||||
async function writeFile(filePath: string, contents = ""): Promise<void> {
|
||||
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
||||
await fs.writeFile(filePath, contents);
|
||||
}
|
||||
|
||||
async function writeJson(filePath: string, value: unknown): Promise<void> {
|
||||
await writeFile(filePath, `${JSON.stringify(value, null, 2)}\n`);
|
||||
}
|
||||
|
||||
test("syncSharedSkillPackages vendors workspace packages into skill scripts", async (t) => {
|
||||
const root = await makeTempDir("baoyu-sync-shared-");
|
||||
t.after(() => fs.rm(root, { recursive: true, force: true }));
|
||||
|
||||
await writeJson(path.join(root, "packages", "baoyu-md", "package.json"), {
|
||||
name: "baoyu-md",
|
||||
version: "1.0.0",
|
||||
});
|
||||
await writeFile(
|
||||
path.join(root, "packages", "baoyu-md", "src", "index.ts"),
|
||||
"export const markdown = true;\n",
|
||||
);
|
||||
|
||||
const consumerDir = path.join(root, "skills", "demo-skill", "scripts");
|
||||
await writeJson(path.join(consumerDir, "package.json"), {
|
||||
name: "demo-skill-scripts",
|
||||
version: "1.0.0",
|
||||
dependencies: {
|
||||
"baoyu-md": "^1.0.0",
|
||||
kleur: "^4.1.5",
|
||||
},
|
||||
});
|
||||
|
||||
const result = await syncSharedSkillPackages(root, { install: false });
|
||||
|
||||
assert.deepEqual(result.packageDirs, [consumerDir]);
|
||||
assert.deepEqual(result.managedPaths, [
|
||||
"skills/demo-skill/scripts/bun.lock",
|
||||
"skills/demo-skill/scripts/package.json",
|
||||
"skills/demo-skill/scripts/vendor",
|
||||
]);
|
||||
|
||||
const updatedPackageJson = JSON.parse(
|
||||
await fs.readFile(path.join(consumerDir, "package.json"), "utf8"),
|
||||
) as { dependencies: Record<string, string> };
|
||||
assert.equal(updatedPackageJson.dependencies["baoyu-md"], "file:./vendor/baoyu-md");
|
||||
assert.equal(updatedPackageJson.dependencies.kleur, "^4.1.5");
|
||||
|
||||
const vendoredPackageJson = JSON.parse(
|
||||
await fs.readFile(path.join(consumerDir, "vendor", "baoyu-md", "package.json"), "utf8"),
|
||||
) as { name: string };
|
||||
assert.equal(vendoredPackageJson.name, "baoyu-md");
|
||||
|
||||
const vendoredFile = await fs.readFile(
|
||||
path.join(consumerDir, "vendor", "baoyu-md", "src", "index.ts"),
|
||||
"utf8",
|
||||
);
|
||||
assert.match(vendoredFile, /markdown = true/);
|
||||
});
|
||||
Reference in New Issue
Block a user