* feat(canvas): 视频节点截取重生成 - 支持多段/时间线导入并调用视频模型批量重生成 * test(canvas): 视频节点时间线导入 - 修正旧数据标题回退测试 * style(canvas): 视频节点截取重生成 - 格式化新增文件并修正测试 --------- Co-authored-by: sikongyue <3155157671@qq.com>
77 lines
2.9 KiB
TypeScript
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);
|
|
});
|
|
});
|