Files
writer-work-flow/apps/web/lib/skills/skills.test.ts
2026-06-28 07:31:20 +02:00

97 lines
2.6 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type { SkillView } from "@/lib/api/types";
import { groupByScope, scopeLabel, summarizeSkills, tierLabel } from "./skills";
const skill = (over: Partial<SkillView>): SkillView => ({
name: "x",
scope: "builtin",
tier: "analyst",
...over,
});
describe("scopeLabel / tierLabel", () => {
it("maps known values, passes through unknown", () => {
expect(scopeLabel("builtin")).toBe("内置");
expect(scopeLabel("mystery")).toBe("mystery");
expect(tierLabel("writer")).toBe("写手");
expect(tierLabel("xl")).toBe("xl");
});
});
describe("groupByScope", () => {
it("groups by scope in first-seen order, preserves within-group order", () => {
const skills: SkillView[] = [
skill({ name: "a", scope: "builtin" }),
skill({ name: "b", scope: "custom" }),
skill({ name: "c", scope: "builtin" }),
];
const groups = groupByScope(skills);
expect(groups.map((g) => g.scope)).toEqual(["builtin", "custom"]);
expect(groups[0]?.skills.map((s) => s.name)).toEqual(["a", "c"]);
expect(groups[1]?.skills.map((s) => s.name)).toEqual(["b"]);
});
it("handles undefined", () => {
expect(groupByScope(undefined)).toEqual([]);
});
});
describe("summarizeSkills", () => {
it("counts scopes, tiers, readonly skills and unique tables", () => {
const summary = summarizeSkills([
skill({
name: "a",
scope: "builtin",
tier: "analyst",
reads: ["projects", "outline"],
writes: [],
}),
skill({
name: "b",
scope: "custom",
tier: "writer",
reads: ["projects"],
writes: ["chapters"],
}),
skill({
name: "c",
scope: "builtin",
tier: "analyst",
reads: ["world_entities"],
writes: ["outline", "chapters"],
}),
]);
expect(summary.total).toBe(3);
expect(summary.readonlyCount).toBe(1);
expect(summary.writableCount).toBe(2);
expect(summary.scopes).toEqual([
{ key: "builtin", count: 2 },
{ key: "custom", count: 1 },
]);
expect(summary.tiers).toEqual([
{ key: "analyst", count: 2 },
{ key: "writer", count: 1 },
]);
expect(summary.readableTables).toEqual([
"outline",
"projects",
"world_entities",
]);
expect(summary.writableTables).toEqual(["chapters", "outline"]);
});
it("handles undefined", () => {
expect(summarizeSkills(undefined)).toEqual({
total: 0,
readonlyCount: 0,
writableCount: 0,
scopes: [],
tiers: [],
readableTables: [],
writableTables: [],
});
});
});