Files
Genarrative/apps/ai-game-creator-shell/tests/uiEditorFontFaces.test.ts
T
k88936 0797410eef
Project CI / Repository checks (push) Successful in 3m18s
Project CI / Frontend tests (push) Successful in 3m32s
Project CI / Backend tests (push) Successful in 4m24s
Project CI / Native shell tests (push) Successful in 15m34s
Feat/UI自动识别和布局编辑器简化版 (#170)
* 支持从项目, 本地电脑, 主站导入/引用素材.
* 页面复杂, 需要足够空间, 作为资源打开时会占满右侧
* 编辑结果作为一种新的美术资源.
* 新增素材按钮现在是空的实现, 临时在旁边加了一个新增UI设计的按钮

临时入口:
![shotmd-1787128060.jpg](/attachments/349a4fa8-7abe-4bbb-80e0-73b1717b6488)

简化:
* 组件实现了最基本的图片和文本
* 容器式布局未接入llm编辑
* 不同阶段统一维护一个状态State, 任何阶段都可以人工调整, 不设单独的步骤
* 多图的UI合并功能暂时不要求, 隐藏入口
* 因为生成工具尚未从主站迁移, 主站地图子画布未实现, 以tab栏的形式容纳素材的子画布需求搁置
* 未实现llm绑定字体功能
* 识别会替换现有UI树, 暂时不是增量的

Reviewed-on: http://192.168.35.82/git/GenarrativeAI/Genarrative/pulls/170
Co-authored-by: 王德宇 <kvtodev@outlook.com>
Co-committed-by: 王德宇 <kvtodev@outlook.com>
2026-08-20 19:07:25 +08:00

81 lines
2.3 KiB
TypeScript

// @vitest-environment jsdom
import { renderHook, waitFor } from '@testing-library/react';
import { afterEach, describe, expect, it, vi } from 'vitest';
import type { FontAsset } from '../src/features/ui-editor/types/FontAsset';
import { useUiEditorFontFaces } from '../src/features/ui-editor/useUiEditorFontFaces';
const { invoke } = vi.hoisted(() => ({
invoke: vi.fn(async () => new Uint8Array([0, 1, 2, 3]).buffer),
}));
vi.mock('@tauri-apps/api/core', () => ({ invoke }));
const FONT: FontAsset = {
asset_id: 'font-1',
metadata: {
family_name: '测试字体',
face_name: 'Regular',
weight: 400,
italic: false,
format: 'TrueType',
source_file_name: 'test.ttf',
},
path: 'assets/fonts/test.ttf',
content_sha256: 'a'.repeat(64),
};
afterEach(() => {
vi.restoreAllMocks();
invoke.mockClear();
});
describe('useUiEditorFontFaces', () => {
it('loads registered bytes into a private FontFace and releases browser resources', async () => {
const add = vi.fn();
const remove = vi.fn();
Object.defineProperty(document, 'fonts', {
configurable: true,
value: { add, delete: remove },
});
const load = vi.fn(async function (this: FontFace) {
return this;
});
vi.stubGlobal(
'FontFace',
class {
load = load;
constructor(
readonly family: string,
readonly source: string,
readonly descriptors?: FontFaceDescriptors,
) {}
},
);
const createObjectURL = vi.fn(() => 'blob:font-preview');
const revokeObjectURL = vi.fn();
vi.stubGlobal('URL', { createObjectURL, revokeObjectURL });
const { result, unmount } = renderHook(() =>
useUiEditorFontFaces('/project', { [FONT.asset_id]: FONT }),
);
await waitFor(() => {
expect(result.current['font-1']?.status).toBe('loaded');
});
expect(invoke).toHaveBeenCalledWith('read_ui_editor_font_bytes', {
projectPath: '/project',
assetId: 'font-1',
relativePath: FONT.path,
expectedSha256: FONT.content_sha256,
});
expect(add).toHaveBeenCalledTimes(1);
expect(createObjectURL).toHaveBeenCalledTimes(1);
unmount();
expect(remove).toHaveBeenCalledTimes(1);
expect(revokeObjectURL).toHaveBeenCalledWith('blob:font-preview');
});
});