157 lines
4.8 KiB
TypeScript
157 lines
4.8 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
||
|
||
import {
|
||
PROCEED,
|
||
foldClarifications,
|
||
needsClarifyGate,
|
||
toVM,
|
||
type ClarifyAnswer,
|
||
} from "./clarify";
|
||
|
||
describe("foldClarifications", () => {
|
||
it("原意见在前,每条澄清另起一行并保序", () => {
|
||
const answers: ClarifyAnswer[] = [
|
||
{ question: "这段谁在说话?", answer: "主角内心独白" },
|
||
{ question: "结尾要留钩子吗?", answer: "留一个悬念" },
|
||
];
|
||
|
||
const result = foldClarifications("收紧节奏", answers);
|
||
|
||
expect(result).toBe(
|
||
"收紧节奏\n已澄清:这段谁在说话? → 主角内心独白\n已澄清:结尾要留钩子吗? → 留一个悬念",
|
||
);
|
||
});
|
||
|
||
it("无回答时原样返回去空白后的 instruction", () => {
|
||
expect(foldClarifications(" 收紧节奏 ", [])).toBe("收紧节奏");
|
||
});
|
||
|
||
it("instruction 为空时只输出澄清行", () => {
|
||
const answers: ClarifyAnswer[] = [
|
||
{ question: "谁在说话?", answer: "配角旁白" },
|
||
];
|
||
expect(foldClarifications(" ", answers)).toBe("已澄清:谁在说话? → 配角旁白");
|
||
});
|
||
|
||
it("跳过空/纯空白回答的条目", () => {
|
||
const answers: ClarifyAnswer[] = [
|
||
{ question: "Q1", answer: " " },
|
||
{ question: "Q2", answer: "有效回答" },
|
||
];
|
||
expect(foldClarifications("原意见", answers)).toBe(
|
||
"原意见\n已澄清:Q2 → 有效回答",
|
||
);
|
||
});
|
||
|
||
it("问题为空(自由输入)时省略问题只留答案", () => {
|
||
const answers: ClarifyAnswer[] = [{ question: " ", answer: "就按我说的改" }];
|
||
expect(foldClarifications("原意见", answers)).toBe(
|
||
"原意见\n已澄清:就按我说的改",
|
||
);
|
||
});
|
||
|
||
it("去除问题与答案两端空白", () => {
|
||
const answers: ClarifyAnswer[] = [
|
||
{ question: " 谁在说话? ", answer: " 主角 " },
|
||
];
|
||
expect(foldClarifications("x", answers)).toBe("x\n已澄清:谁在说话? → 主角");
|
||
});
|
||
|
||
it("不可变:不修改入参数组", () => {
|
||
const answers: ClarifyAnswer[] = [{ question: "Q", answer: "A" }];
|
||
const snapshot = JSON.parse(JSON.stringify(answers));
|
||
foldClarifications("原意见", answers);
|
||
expect(answers).toEqual(snapshot);
|
||
});
|
||
|
||
it("全部为空回答且 instruction 为空时返回空串", () => {
|
||
expect(foldClarifications("", [{ question: "Q", answer: "" }])).toBe("");
|
||
});
|
||
});
|
||
|
||
describe("toVM", () => {
|
||
it("snake_case ClarifyDecision → camelCase VM,逐字段映射", () => {
|
||
const vm = toVM({
|
||
need_clarification: true,
|
||
questions: [
|
||
{
|
||
question: "想更冷峻还是更抒情?",
|
||
options: [
|
||
{ label: "冷峻", value: "改得更冷峻克制" },
|
||
{ label: "抒情", value: "改得更抒情" },
|
||
],
|
||
allow_free_text: true,
|
||
},
|
||
],
|
||
verification: "我这样理解对吗",
|
||
});
|
||
|
||
expect(vm).toEqual({
|
||
needClarification: true,
|
||
questions: [
|
||
{
|
||
question: "想更冷峻还是更抒情?",
|
||
options: [
|
||
{ label: "冷峻", value: "改得更冷峻克制" },
|
||
{ label: "抒情", value: "改得更抒情" },
|
||
],
|
||
allowFreeText: true,
|
||
},
|
||
],
|
||
verification: "我这样理解对吗",
|
||
});
|
||
});
|
||
|
||
it("字段缺省时取安全默认(空/false/undefined),不信任外部数据", () => {
|
||
const vm = toVM({});
|
||
expect(vm).toEqual({
|
||
needClarification: false,
|
||
questions: [],
|
||
verification: undefined,
|
||
});
|
||
});
|
||
|
||
it("questions/options 内字段缺省时逐项补默认", () => {
|
||
const vm = toVM({
|
||
need_clarification: true,
|
||
questions: [{ question: undefined, options: [{}], allow_free_text: undefined }],
|
||
verification: null,
|
||
});
|
||
expect(vm).toEqual({
|
||
needClarification: true,
|
||
questions: [
|
||
{ question: "", options: [{ label: "", value: "" }], allowFreeText: false },
|
||
],
|
||
verification: undefined,
|
||
});
|
||
});
|
||
});
|
||
|
||
describe("PROCEED", () => {
|
||
it("放行常量:不反问、无问题", () => {
|
||
expect(PROCEED).toEqual({ needClarification: false, questions: [] });
|
||
});
|
||
});
|
||
|
||
describe("needsClarifyGate", () => {
|
||
it("去空白后长度小于 minChars 时需要预检", () => {
|
||
expect(needsClarifyGate("改一下", 8)).toBe(true);
|
||
});
|
||
|
||
it("恰好等于 minChars 时不需预检(边界)", () => {
|
||
expect(needsClarifyGate("12345678", 8)).toBe(false);
|
||
});
|
||
|
||
it("超过 minChars 时不需预检", () => {
|
||
expect(needsClarifyGate("这是一段足够清晰具体的润色意见", 8)).toBe(false);
|
||
});
|
||
|
||
it("纯空白按空计(长度 0 < minChars)需预检", () => {
|
||
expect(needsClarifyGate(" ", 8)).toBe(true);
|
||
});
|
||
|
||
it("先去两端空白再计长度", () => {
|
||
expect(needsClarifyGate(" 改 ", 2)).toBe(true);
|
||
});
|
||
});
|