Files
writing-agent/tests/reply-contract.test.ts
chenmoranzhiandCursor d0a48f9431 把正文组成收成数据契约,程序投影与旁观维护不再靠模型临场猜。
有变量真值时固定开旁观填表,开场与游玩只填模型生成区。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-07 23:47:58 +08:00

89 lines
2.9 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { parsePresentPacket } from "../src/skills/present-packet.js";
import {
openingContractError,
parseReplyDataContract,
presentSchemaFromContract,
} from "../src/skills/reply-contract.js";
const replyFormat = JSON.stringify({
schema: "context-fragment.v1",
正文: {
数据契约: {
schema: "present.v1",
blocks: {
status_card: { 类型: "kv", 来源: "program_projection", 职责: "属性" },
body: { 类型: "markdown", 来源: "model_generated", 职责: "主读正文" },
forum_feed: { 类型: "list", 来源: "model_generated", 职责: "论坛" },
danmu_stream: { 类型: "list", 来源: "model_generated", 职责: "弹幕" },
},
},
frontend: { html: `<div id="app"></div>`, css: "body{}", js: "present.onData(function(){})" },
},
});
describe("reply data contract", () => {
it("keeps model blocks and drops program projections from the fill schema", () => {
const contract = parseReplyDataContract(replyFormat);
expect(contract?.modelBlocks.map((block) => block.id)).toEqual([
"body",
"forum_feed",
"danmu_stream",
]);
expect(contract?.programBlocks.map((block) => block.id)).toEqual(["status_card"]);
expect(contract?.frontend?.html).toContain("app");
const built = presentSchemaFromContract(contract!);
const blocks = (
built.schema.properties as { blocks: { required: string[] } }
).blocks;
expect(blocks.required).toEqual(["body", "forum_feed", "danmu_stream"]);
expect(built.loose).toBe(false);
});
it("rejects an old shell packet that only fills body", () => {
const contract = parseReplyDataContract(replyFormat)!;
const error = openingContractError(
JSON.stringify({
schema: "present.v1",
shell: "prose",
blocks: { body: "清晨,@玩家推开门。" },
}),
contract,
);
expect(error).toContain("forum_feed");
expect(error).toContain("danmu_stream");
});
it("accepts present.v1 that fills every model block", () => {
const contract = parseReplyDataContract(replyFormat)!;
expect(
openingContractError(
JSON.stringify({
schema: "present.v1",
blocks: {
body: "清晨,@玩家推开门。",
forum_feed: ["有人愿意修外墙吗?"],
danmu_stream: [],
},
}),
contract,
),
).toBeUndefined();
});
it("preserves contract blocks when normalizing a present packet", () => {
const view = parsePresentPacket(
JSON.stringify({
schema: "present.v1",
blocks: {
body: "正文",
forum_feed: ["一帖"],
danmu_stream: ["一条"],
},
}),
);
expect(view.packet.blocks.forum_feed).toEqual(["一帖"]);
expect(view.packet.blocks.danmu_stream).toEqual(["一条"]);
});
});