Files
ttstd-infinite-canvas/web/test/canvas-video-timeline-segments.test.ts
爱笑的毛毛虫 d33c6389d4 feat(canvas): 视频节点截取重生成 - 支持多段/时间线导入并调用视频模型批量重生成 (#197)
* feat(canvas): 视频节点截取重生成 - 支持多段/时间线导入并调用视频模型批量重生成

* test(canvas): 视频节点时间线导入 - 修正旧数据标题回退测试

* style(canvas): 视频节点截取重生成 - 格式化新增文件并修正测试

---------

Co-authored-by: sikongyue <3155157671@qq.com>
2026-08-10 00:13:02 +08:00

77 lines
2.9 KiB
TypeScript

import { describe, expect, test } from "bun:test";
import { buildTimelineImportSegments } from "../src/lib/canvas/canvas-video-timeline-segments";
import { CanvasNodeType, type CanvasConnection, type CanvasNodeData } from "../src/types/canvas";
import type { TimelineProject } from "../src/types/timeline";
function videoNode(id: string, title: string): CanvasNodeData {
return {
id,
type: CanvasNodeType.Video,
title,
position: { x: 0, y: 0 },
width: 100,
height: 100,
metadata: { content: `data:video/mp4;base64,${id}`, durationMs: 10_000 },
};
}
function connection(fromNodeId: string, toNodeId: string): CanvasConnection {
return { id: `conn-${fromNodeId}-${toNodeId}`, fromNodeId, toNodeId };
}
const timeline: TimelineProject = {
version: 2,
tracks: [],
clips: [
{
id: "clip-1",
kind: "video",
nodeId: "source-video",
trackId: "video",
startMs: 0,
durationMs: 3_000,
title: "源视频",
sourceStartMs: 2_000,
sourceDurationMs: 3_000,
},
],
durationMs: 3_000,
};
describe("buildTimelineImportSegments", () => {
test("下游节点能从上游视频节点导入时间线片段", () => {
const source = videoNode("source-video", "源视频");
const segment = videoNode("segment-video", "片段");
const target = videoNode("target-video", "结果");
const nodes = [target, segment, source];
const connections = [connection("source-video", "segment-video"), connection("segment-video", "target-video")];
const result = buildTimelineImportSegments(target, nodes, connections, timeline, 10_000);
expect(result.ok).toBe(true);
if (!result.ok) return;
expect(result.segments).toHaveLength(1);
expect(result.segments[0]).toMatchObject({ startMs: 2_000, endMs: 5_000, sourceNodeId: "source-video" });
});
test("旧数据 nodeId 不一致时按唯一标题回退匹配", () => {
const source = videoNode("source-video", "源视频");
const target = videoNode("target-video", "结果");
const nodes = [target, source];
const connections = [connection("source-video", "target-video")];
const oldTimeline: TimelineProject = {
...timeline,
clips: [{ ...timeline.clips[0], nodeId: "legacy-source-id" }],
};
const result = buildTimelineImportSegments(target, nodes, connections, oldTimeline, 10_000);
expect(result.ok).toBe(true);
if (!result.ok) return;
expect(result.segments[0].sourceNodeId).toBe("source-video");
});
test("没有匹配片段时返回错误", () => {
const target = videoNode("target-video", "结果");
const result = buildTimelineImportSegments(target, [target], [], timeline, 10_000);
expect(result.ok).toBe(false);
});
});