Phase 2(写作工作台重构):把写章指令升级为三槽——文风预设 + 新增剧情需求预设 (打脸反转/章末钩子/高潮/转折/扮猪吃虎,源自 plan §4.2 分类法,tianyayu6/oh-story MIT) + 自定义自由文本。三者经 composeDirective 合并为单条 directive→volatile(MVP 纯前端、 零契约、不动 write_craft.md 字节,金标准零回归)。DirectivePanel 拆成文风/剧情两组 chips。
39 lines
1.5 KiB
TypeScript
39 lines
1.5 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
||
|
||
import { composeDirective, PLOT_PRESETS, STYLE_PRESETS } from "./directive";
|
||
|
||
describe("composeDirective", () => {
|
||
it("returns empty string when nothing selected", () => {
|
||
expect(composeDirective("", [])).toBe("");
|
||
expect(composeDirective(" ", [])).toBe("");
|
||
});
|
||
|
||
it("uses free text only when no presets", () => {
|
||
expect(composeDirective("多写战斗", [])).toBe("多写战斗");
|
||
});
|
||
|
||
it("combines presets (in canonical order) then free text", () => {
|
||
const result = composeDirective("多写战斗", ["fast-pace", "less-ai"]);
|
||
const lessAi = STYLE_PRESETS.find((p) => p.id === "less-ai")!.text;
|
||
const fastPace = STYLE_PRESETS.find((p) => p.id === "fast-pace")!.text;
|
||
expect(result).toBe(`${lessAi};${fastPace};多写战斗`);
|
||
});
|
||
|
||
it("ignores unknown preset ids", () => {
|
||
const lessAi = STYLE_PRESETS.find((p) => p.id === "less-ai")!.text;
|
||
expect(composeDirective("", ["nope", "less-ai"])).toBe(lessAi);
|
||
});
|
||
|
||
it("resolves 剧情需求 presets alongside 文风", () => {
|
||
const plot = PLOT_PRESETS[0]!;
|
||
expect(composeDirective("", [plot.id])).toBe(plot.text);
|
||
});
|
||
|
||
it("orders 文风 presets before 剧情 presets, then free text", () => {
|
||
const style = STYLE_PRESETS[0]!;
|
||
const plot = PLOT_PRESETS[0]!;
|
||
const result = composeDirective("再收紧节奏", [plot.id, style.id]);
|
||
expect(result).toBe(`${style.text};${plot.text};再收紧节奏`);
|
||
});
|
||
});
|