1 changed files with 85 additions and 0 deletions
@ -0,0 +1,85 @@ |
|||
import { describe, expect, it } from "vitest"; |
|||
import { |
|||
buildComposerConfigPersistPatch, |
|||
} from "@/components/composer/composerDraftHelpers"; |
|||
import { readVideoGenerationConfig } from "@/utils/generationConfig"; |
|||
import type { GenerationNodeConfig } from "@/utils/generationConfig"; |
|||
import type { GenerateVideoNodeData, NanoBananaNodeData, SelectedModel, WorkflowNode } from "@/types"; |
|||
|
|||
const selectedModel: SelectedModel = { |
|||
provider: "popiserver", |
|||
modelId: "video-1", |
|||
displayName: "Video One", |
|||
capabilities: ["text-to-video", "image-to-video"], |
|||
}; |
|||
|
|||
function config(overrides: Partial<GenerationNodeConfig> = {}): GenerationNodeConfig { |
|||
return { |
|||
prompt: "a clip", |
|||
selectedModel, |
|||
inputImages: [], |
|||
batchSize: 1, |
|||
referenceSubjectList: [], |
|||
parameters: {}, |
|||
extraTaskParams: {}, |
|||
...overrides, |
|||
}; |
|||
} |
|||
|
|||
function videoNode(): WorkflowNode { |
|||
return { |
|||
id: "vid-1", |
|||
type: "generateVideo", |
|||
selected: true, |
|||
position: { x: 0, y: 0 }, |
|||
data: { |
|||
inputPrompt: "a clip", |
|||
inputImages: [], |
|||
outputVideo: null, |
|||
selectedModel, |
|||
parameters: {}, |
|||
status: "idle", |
|||
error: null, |
|||
videoHistory: [], |
|||
selectedVideoHistoryIndex: 0, |
|||
} as GenerateVideoNodeData, |
|||
} as WorkflowNode; |
|||
} |
|||
|
|||
function imageNode(): WorkflowNode { |
|||
return { |
|||
id: "img-1", |
|||
type: "nanoBanana", |
|||
selected: true, |
|||
position: { x: 0, y: 0 }, |
|||
data: { |
|||
inputPrompt: "a picture", |
|||
inputImages: [], |
|||
outputImage: null, |
|||
selectedModel, |
|||
status: "idle", |
|||
error: null, |
|||
} as NanoBananaNodeData, |
|||
} as WorkflowNode; |
|||
} |
|||
|
|||
describe("buildComposerConfigPersistPatch", () => { |
|||
it("persists the chosen batchSize (视频数量) for video nodes", () => { |
|||
const patch = buildComposerConfigPersistPatch(videoNode(), config({ batchSize: 3 })); |
|||
expect((patch as Partial<GenerateVideoNodeData>).batchSize).toBe(3); |
|||
}); |
|||
|
|||
it("round-trips a video batchSize back through readVideoGenerationConfig", () => { |
|||
const node = videoNode(); |
|||
const patch = buildComposerConfigPersistPatch(node, config({ batchSize: 4 })); |
|||
const merged = { ...node.data, ...patch } as GenerateVideoNodeData; |
|||
|
|||
// 重新打开节点时的读取路径应保留所选数量,而不是回落到默认 1。
|
|||
expect(readVideoGenerationConfig(merged, selectedModel).batchSize).toBe(4); |
|||
}); |
|||
|
|||
it("keeps parity with image nodes, which already persist batchSize", () => { |
|||
const patch = buildComposerConfigPersistPatch(imageNode(), config({ batchSize: 2 })); |
|||
expect((patch as Partial<NanoBananaNodeData>).batchSize).toBe(2); |
|||
}); |
|||
}); |
|||
Loading…
Reference in new issue