38 lines
1.7 KiB
JavaScript
38 lines
1.7 KiB
JavaScript
import { test } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { readFileSync, existsSync } from "node:fs";
|
|
import { join, dirname } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const root = join(dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
const skill = readFileSync(join(root, "mentor", "SKILL.md"), "utf8");
|
|
const catalog = JSON.parse(readFileSync(join(root, "course", "catalog.json"), "utf8"));
|
|
const entries = Array.isArray(catalog) ? catalog : catalog.entries ?? Object.values(catalog);
|
|
|
|
test("mentor_skill_frontmatter_has_name_and_description", () => {
|
|
const m = /^---\n([\s\S]*?)\n---\n/.exec(skill);
|
|
assert.ok(m, "frontmatter present");
|
|
assert.match(m[1], /^name: systemic-design-mentor$/m);
|
|
assert.match(m[1], /^description: \S.{40,}/m);
|
|
});
|
|
|
|
test("mentor_skill_names_no_module_specific_cards", () => {
|
|
const META = new Set(["TEXT", "ALL", "EMPTY"]);
|
|
const names = entries
|
|
.filter((e) => e.kind === "card" || (e.kind === "word" && e.role === "noun" && !META.has(e.name)))
|
|
.map((e) => ({ name: e.name, flags: e.kind === "card" ? "i" : "" })) // noun words are ALL CAPS; "Baba Is You" the title is fine
|
|
.filter((n) => n.name.length >= 2);
|
|
assert.ok(names.length > 10, "catalog has names to check");
|
|
const esc = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
const hits = names
|
|
.filter((n) => new RegExp(`(?<![A-Za-z0-9_])${esc(n.name)}(?![A-Za-z0-9_])`, n.flags).test(skill))
|
|
.map((n) => n.name);
|
|
assert.deepEqual(hits, []);
|
|
});
|
|
|
|
test("mentor_skill_tool_paths_exist", () => {
|
|
const paths = [...skill.matchAll(/tools\/([\w-]+\.mjs)/g)].map((m) => m[1]);
|
|
assert.ok(paths.length >= 3);
|
|
for (const p of paths) assert.ok(existsSync(join(root, "tools", p)), p);
|
|
});
|