Files
Genarrative/src/components/image-editor/ImageCanvasGenerationLayerModel.test.ts
kdletters 3c37108ef6 拆分图片画布生成图层模型
新增生成结果图层模型和单测

主视图改为复用生成图层模型创建普通生图、快速编辑和图标图层

更新图片画布前端拆分文档和 TRACKING 回归记录
2026-06-17 07:04:20 +08:00

226 lines
5.8 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import type {
CanvasGenerationInputs,
CanvasLayer,
} from './ImageCanvasEditorTypes';
import {
createGeneratedResultLayer,
createIconSpritesheetResultLayers,
createQuickEditResultLayer,
} from './ImageCanvasGenerationLayerModel';
function createGenerated(overrides = {}) {
return {
imageSrc: 'data:image/png;base64,generated',
width: 1024,
height: 1024,
sourceType: 'generated' as const,
prompt: '生成提示词',
actualPrompt: '实际提示词',
model: 'gpt-image-2',
provider: 'VectorEngine',
taskId: 'task-generated',
objectKey: 'generated/object.png',
assetObjectId: 'asset-object-generated',
...overrides,
};
}
function createSourceLayer(overrides: Partial<CanvasLayer> = {}): CanvasLayer {
return {
id: 'layer-source',
resourceId: 'resource-source',
title: '源图',
src: 'data:image/png;base64,source',
x: 120,
y: 140,
width: 320,
height: 240,
originalWidth: 1536,
originalHeight: 1024,
zIndex: 2,
sourceType: 'generated',
groupId: 'group-a',
assetKind: 'spec',
...overrides,
};
}
function createGenerationInputs(): CanvasGenerationInputs {
return {
fields: [{ title: '生成提示词', value: '生成提示词' }],
references: [],
};
}
describe('ImageCanvasGenerationLayerModel', () => {
it('creates generated result layers centered on the active placeholder', () => {
const layer = createGeneratedResultLayer({
generated: createGenerated({ width: 2048, height: 1152 }),
generatedIndex: 7,
canvasSize: { width: 900, height: 640 },
viewport: { x: 10, y: 20, scale: 2 },
frame: {
x: 80,
y: 60,
width: 560,
height: 315,
originalWidth: 2048,
originalHeight: 1152,
},
assetKind: 'spec',
title: 'UI素材规范 7',
generationInputs: createGenerationInputs(),
});
expect(layer).toMatchObject({
id: 'layer-generated-7',
resourceId: 'local-resource-generated-7',
title: 'UI素材规范 7',
x: -664,
y: -358.5,
width: 2048,
height: 1152,
originalWidth: 2048,
originalHeight: 1152,
zIndex: 17,
sourceType: 'generated',
assetKind: 'spec',
prompt: '生成提示词',
actualPrompt: '实际提示词',
objectKey: 'generated/object.png',
assetObjectId: 'asset-object-generated',
});
expect(layer.generationInputs?.fields[0]?.value).toBe('生成提示词');
});
it('creates edit result layers beside the source image', () => {
const sourceLayer = createSourceLayer();
const layer = createGeneratedResultLayer({
generated: createGenerated({ prompt: '修改要求' }),
generatedIndex: 8,
canvasSize: { width: 900, height: 640 },
viewport: { x: 0, y: 0, scale: 1 },
sourceLayer,
generationInputs: createGenerationInputs(),
});
expect(layer).toMatchObject({
id: 'layer-edit-8',
resourceId: 'local-resource-edit-8',
title: '源图 修改结果',
x: 472,
y: 140,
width: 1024,
height: 1024,
sourceResourceId: 'resource-source',
prompt: '修改要求',
});
});
it('creates quick edit layers with source group and asset kind preserved', () => {
const sourceLayer = createSourceLayer();
const layer = createQuickEditResultLayer({
generated: createGenerated({ width: 1536, height: 1024 }),
generatedIndex: 9,
sourceLayer,
generationInputs: createGenerationInputs(),
});
expect(layer).toMatchObject({
id: 'layer-quick-edit-9',
resourceId: 'local-resource-quick-edit-9',
title: '源图 快速编辑',
x: 472,
y: 140,
width: 1536,
height: 1024,
originalWidth: 1536,
originalHeight: 1024,
sourceResourceId: 'resource-source',
groupId: 'group-a',
assetKind: 'spec',
});
});
it('creates wrapped icon layers with icon metadata', () => {
const layers = createIconSpritesheetResultLayers({
generated: {
spritesheetImageSrc: 'data:image/png;base64,sheet',
spritesheetWidth: 512,
spritesheetHeight: 512,
iconImageSrcs: [],
prompt: '图标 prompt',
actualPrompt: '图标 actual prompt',
model: 'gpt-image-2',
provider: 'VectorEngine',
taskId: 'task-icons',
},
iconResults: [
{
name: '返回按钮',
imageSrc: 'data:image/png;base64,back',
width: 256,
height: 256,
},
{
name: '设置按钮',
imageSrc: 'data:image/png;base64,settings',
width: 512,
height: 256,
},
{
name: '提示按钮',
imageSrc: 'data:image/png;base64,hint',
width: 128,
height: 128,
},
],
startIndex: 11,
canvasSize: { width: 900, height: 640 },
viewport: { x: 0, y: 0, scale: 1 },
frame: {
x: 200,
y: 100,
width: 360,
height: 360,
originalWidth: 512,
originalHeight: 512,
},
generationInputs: createGenerationInputs(),
});
expect(layers).toHaveLength(3);
expect(layers[0]).toMatchObject({
id: 'layer-icon-11',
title: '返回按钮',
x: 200,
y: 100,
width: 256,
height: 256,
assetKind: 'icon',
prompt: '图标 prompt',
actualPrompt: '图标 actual prompt',
});
expect(layers[1]).toMatchObject({
id: 'layer-icon-12',
title: '设置按钮',
x: 200,
y: 380,
width: 512,
height: 256,
assetKind: 'icon',
});
expect(layers[2]).toMatchObject({
id: 'layer-icon-13',
title: '提示按钮',
x: 200,
y: 660,
width: 128,
height: 128,
assetKind: 'icon',
});
});
});