合并图标规范与图集生成优化
合入 PR 137 的图标规范生成、稳定引用与图集提示词链路 保留主分支现行音效提交、Prompt 模块与结果压缩逻辑 解决 External Worker、生成提交和客户端测试冲突
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { EDITOR_ICON_DESCRIPTION_MAX_CHARS } from '../../services/image-editor/editorProjectClient';
|
||||
import type { CanvasLayer } from './ImageCanvasEditorTypes';
|
||||
import {
|
||||
IMAGE_MODEL_GPT_IMAGE_2,
|
||||
@@ -302,7 +303,7 @@ describe('ImageCanvasGenerationSubmissionModel', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('builds spec generation plans with reference prompt semantics', () => {
|
||||
it('builds icon spec generation plans without a client prompt or backend kind', () => {
|
||||
const plan = buildImageGenerationSubmissionPlan({
|
||||
dialog: {
|
||||
mode: 'spec',
|
||||
@@ -328,23 +329,47 @@ describe('ImageCanvasGenerationSubmissionModel', () => {
|
||||
});
|
||||
|
||||
expect(plan).toMatchObject({
|
||||
kind: 'image',
|
||||
kind: 'icon-spec',
|
||||
normalizedPrompt: 'AI 生成图片',
|
||||
input: {
|
||||
size: '2048x1152',
|
||||
model: 'gpt-image-2',
|
||||
aspectRatio: '16:9',
|
||||
imageSize: '2K',
|
||||
kind: 'spec',
|
||||
referenceImageSrcs: ['data:image/png;base64,ref'],
|
||||
prompt: expect.stringContaining('参考图生成规范'),
|
||||
playSetting: '休闲消除',
|
||||
artStyle: '清爽卡通',
|
||||
referenceId: 'resource-spec-ref',
|
||||
generationInputs: {
|
||||
fields: [
|
||||
{ title: '玩法设定', value: '休闲消除' },
|
||||
{ title: '美术风格', value: '清爽卡通' },
|
||||
],
|
||||
references: [
|
||||
{
|
||||
title: '参考图',
|
||||
label: '参考.png',
|
||||
refType: 'project-resource',
|
||||
refId: 'resource-spec-ref',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
result: {
|
||||
assetKind: 'icon-spec',
|
||||
title: '图标规范 8',
|
||||
generationInputs: {
|
||||
fields: [
|
||||
{ title: '玩法设定', value: '休闲消除' },
|
||||
{ title: '美术风格', value: '清爽卡通' },
|
||||
],
|
||||
references: [
|
||||
{
|
||||
title: '参考图',
|
||||
label: '参考.png',
|
||||
refType: 'project-resource',
|
||||
refId: 'resource-spec-ref',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(plan.kind === 'image' ? plan.result.generationInputs : null).toEqual(
|
||||
expect(plan.kind === 'icon-spec' ? plan.result.generationInputs : null).toEqual(
|
||||
{
|
||||
fields: [
|
||||
{ title: '玩法设定', value: '休闲消除' },
|
||||
@@ -362,13 +387,13 @@ describe('ImageCanvasGenerationSubmissionModel', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('treats the renamed UI spec entry as an icon spec asset', () => {
|
||||
it('does not add optional reference fields to an icon spec without a reference', () => {
|
||||
const plan = buildImageGenerationSubmissionPlan({
|
||||
dialog: {
|
||||
mode: 'spec',
|
||||
prompt: '',
|
||||
status: 'idle',
|
||||
specType: 'ui',
|
||||
specType: 'icon',
|
||||
specValues: {
|
||||
playSetting: '消除类派对玩法',
|
||||
artStyle: '糖果玻璃拟物',
|
||||
@@ -382,17 +407,28 @@ describe('ImageCanvasGenerationSubmissionModel', () => {
|
||||
});
|
||||
|
||||
expect(plan).toMatchObject({
|
||||
kind: 'image',
|
||||
kind: 'icon-spec',
|
||||
input: {
|
||||
playSetting: '消除类派对玩法',
|
||||
artStyle: '糖果玻璃拟物',
|
||||
generationInputs: {
|
||||
fields: [
|
||||
{ title: '玩法设定', value: '消除类派对玩法' },
|
||||
{ title: '美术风格', value: '糖果玻璃拟物' },
|
||||
],
|
||||
references: [],
|
||||
},
|
||||
},
|
||||
result: {
|
||||
assetKind: 'icon-spec',
|
||||
title: '图标规范 2',
|
||||
},
|
||||
});
|
||||
expect(plan.kind === 'image' ? plan.input : null).not.toHaveProperty(
|
||||
expect(plan.kind === 'icon-spec' ? plan.input : null).not.toHaveProperty(
|
||||
'referenceImageSrcs',
|
||||
);
|
||||
expect(plan.kind === 'image' ? plan.input.prompt : '').not.toContain(
|
||||
'参考图生成规范',
|
||||
expect(plan.kind === 'icon-spec' ? plan.input : null).not.toHaveProperty(
|
||||
'prompt',
|
||||
);
|
||||
});
|
||||
|
||||
@@ -751,6 +787,25 @@ describe('ImageCanvasGenerationSubmissionModel', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('returns an icon spritesheet error when the spec reference is not registered', () => {
|
||||
const plan = buildIconSpritesheetGenerationSubmissionPlan({
|
||||
mode: 'icon',
|
||||
prompt: '返回按钮',
|
||||
status: 'idle',
|
||||
iconSpecReference: {
|
||||
id: 'local-icon-spec',
|
||||
label: '本地图标规范',
|
||||
src: 'data:image/png;base64,spec',
|
||||
resourceId: 'local-resource-icon-spec',
|
||||
},
|
||||
});
|
||||
|
||||
expect(plan).toEqual({
|
||||
ok: false,
|
||||
errorMessage: '参考图尚未登记为项目资源或素材,请重新选择或上传后再试',
|
||||
});
|
||||
});
|
||||
|
||||
it('returns an icon spritesheet error when descriptions are empty', () => {
|
||||
const plan = buildIconSpritesheetGenerationSubmissionPlan({
|
||||
mode: 'icon',
|
||||
@@ -771,6 +826,25 @@ describe('ImageCanvasGenerationSubmissionModel', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('returns an icon spritesheet error when the complete prompt is too long', () => {
|
||||
const plan = buildIconSpritesheetGenerationSubmissionPlan({
|
||||
mode: 'icon',
|
||||
prompt: '图'.repeat(EDITOR_ICON_DESCRIPTION_MAX_CHARS + 1),
|
||||
status: 'idle',
|
||||
iconSpecReference: {
|
||||
id: 'icon-spec',
|
||||
label: '图标规范',
|
||||
src: 'data:image/png;base64,spec',
|
||||
resourceId: 'resource-icon-spec',
|
||||
},
|
||||
});
|
||||
|
||||
expect(plan).toEqual({
|
||||
ok: false,
|
||||
errorMessage: `素材描述不能超过 ${EDITOR_ICON_DESCRIPTION_MAX_CHARS} 个字符`,
|
||||
});
|
||||
});
|
||||
|
||||
it('builds icon spritesheet plans with the complete prompt and references', () => {
|
||||
const plan = buildIconSpritesheetGenerationSubmissionPlan({
|
||||
mode: 'icon',
|
||||
@@ -802,7 +876,7 @@ describe('ImageCanvasGenerationSubmissionModel', () => {
|
||||
ok: true,
|
||||
iconDescriptions: ['返回按钮\n\n设置按钮'],
|
||||
input: {
|
||||
referenceImageSrc: 'data:image/png;base64,spec',
|
||||
referenceId: 'resource-icon-spec',
|
||||
referenceImageSrcs: ['data:image/png;base64,ref'],
|
||||
iconDescriptions: ['返回按钮\n\n设置按钮'],
|
||||
model: 'gpt-image-2',
|
||||
|
||||
Reference in New Issue
Block a user