58 lines
2.9 KiB
TypeScript
58 lines
2.9 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
|
|
|
import { parseListModeJson, parseStoryboardJson, requestedListRowCount } from "@/pages/canvas/list-mode-generator";
|
|
|
|
test("extracts the requested row count from natural language", () => {
|
|
expect(requestedListRowCount("帮我生成5个卖点")).toBe(5);
|
|
expect(requestedListRowCount("请写十条小红书标题")).toBe(10);
|
|
expect(requestedListRowCount("分析这张图")).toBeUndefined();
|
|
});
|
|
|
|
describe("list mode response parsing", () => {
|
|
test("rejects invalid rows instead of creating an empty success table", () => {
|
|
for (const rows of [[], [null, 1, "bad", []]]) {
|
|
expect(parseListModeJson(JSON.stringify({ columns: ["detail"], rows }))).toBeNull();
|
|
expect(parseStoryboardJson(JSON.stringify({ rows }))).toBeNull();
|
|
}
|
|
});
|
|
|
|
test("does not turn missing or invalid timestamps into a first-frame request", () => {
|
|
for (const time of [null, "", " ", false, -1, "invalid"]) {
|
|
const parsed = parseStoryboardJson(JSON.stringify({ rows: [{ plotDescription: "shot", keyframeTimeSeconds: time }] }));
|
|
expect(parsed?.rows[0].keyframeTimeMs).toBeUndefined();
|
|
}
|
|
expect(parseStoryboardJson('{"rows":[{"keyframeTimeSeconds":0}]}')?.rows[0].keyframeTimeMs).toBe(0);
|
|
});
|
|
test("parses plain JSON", () => {
|
|
expect(parseListModeJson('{"columns":["卖点"],"rows":[{"卖点":"轻便"}]}')).toEqual({
|
|
columns: ["卖点"],
|
|
rows: [{ 卖点: "轻便" }],
|
|
});
|
|
});
|
|
|
|
test("parses markdown JSON with surrounding explanation", () => {
|
|
expect(parseListModeJson('结果如下:\n```json\n{"columns":["标题"],"rows":[{"标题":"新品"}]}\n```\n')).toEqual({
|
|
columns: ["标题"],
|
|
rows: [{ 标题: "新品" }],
|
|
});
|
|
});
|
|
|
|
test("normalizes duplicate columns and non-string cells", () => {
|
|
expect(parseListModeJson('{"columns":["卖点","卖点","细节"],"rows":[{"卖点":["轻","薄"],"细节":123}]}')).toEqual({
|
|
columns: ["卖点", "细节"],
|
|
rows: [{ 卖点: "轻、薄", 细节: "123" }],
|
|
});
|
|
});
|
|
|
|
test("rejects malformed responses", () => {
|
|
expect(parseListModeJson("模型暂时无法分析")).toBeNull();
|
|
expect(parseListModeJson('{"columns":[],"rows":[]}')).toBeNull();
|
|
});
|
|
|
|
test("parses a storyboard response and derives generation prompts", () => {
|
|
const result = parseStoryboardJson('```json\n{"title":"拆解","rows":[{"durationSeconds":3,"plotDescription":"产品推近","motion":"缓慢推进","keyframeTimeSeconds":1.5}]}\n```');
|
|
expect(result?.title).toBe("拆解");
|
|
expect(result?.rows[0]).toMatchObject({ durationSeconds: 3, plotDescription: "产品推近", motion: "缓慢推进", videoMotionPrompt: "产品推近;缓慢推进", keyframeTimeMs: 1500 });
|
|
});
|
|
});
|