返回 html-video
parse-format-reply.test.ts
根目录 / packages / cli / test / parse-format-reply.test.ts
1 import { test } from 'node:test';
2 import assert from 'node:assert/strict';
3 import { parseFormatReply } from '../dist/studio-server.js';
4
5 // Regression coverage for issue #2: a typed free-text format answer (when the
6 // model asked in prose instead of rendering the hv-form card) must parse into
7 // the same {aspect, duration, frame_count} shape a card submit produces, so the
8 // flow advances to confirm instead of re-asking.
9
10 test('the exact issue #2 reply: "16:9 横屏 / 5s / 10"', () => {
11 const r = parseFormatReply('16:9 横屏 / 5s / 10');
12 assert.equal(r?.aspect, '16:9 横屏');
13 assert.equal(r?.duration, '5');
14 assert.equal(r?.frame_count, '10');
15 });
16
17 test('chinese commas + 秒/帧 units: "9:16 竖屏,3秒,6帧"', () => {
18 const r = parseFormatReply('9:16 竖屏,3秒,6帧');
19 assert.equal(r?.aspect, '9:16 手机竖屏');
20 assert.equal(r?.duration, '3');
21 assert.equal(r?.frame_count, '6');
22 });
23
24 test('keyword-only aspect, no ratio: "方形 5s"', () => {
25 const r = parseFormatReply('方形 5s');
26 assert.equal(r?.aspect, '1:1 方形');
27 assert.equal(r?.duration, '5');
28 });
29
30 test('xiaohongshu keyword maps to 4:5', () => {
31 assert.equal(parseFormatReply('小红书 10秒 8帧')?.aspect, '4:5 小红书');
32 });
33
34 test('partial: just an aspect still counts', () => {
35 assert.deepEqual(parseFormatReply('横屏'), { aspect: '16:9 横屏' });
36 });
37
38 test('does not treat duration "s" as a frame count', () => {
39 const r = parseFormatReply('16:9 / 5s');
40 assert.equal(r?.duration, '5');
41 assert.equal(r?.frame_count, undefined);
42 });
43
44 test('long prose is content, not a format answer', () => {
45 assert.equal(
46 parseFormatReply('我想做一个介绍我们公司新产品发布的视频,重点讲三个核心卖点和定价'),
47 undefined,
48 );
49 });
50
51 test('unrelated short text yields no signal', () => {
52 assert.equal(parseFormatReply('你好'), undefined);
53 assert.equal(parseFormatReply('继续'), undefined);
54 });
55
55 lines TYPESCRIPT