1
0
mirror of synced 2026-10-27 05:26:11 +08:00
Files
tmagic-editor/packages/editor/tests/unit/services/BaseService.spec.ts
roymondchen 94fae10ae0 feat(editor): 新增 SDK 层并将核心服务迁移至 sdk 目录
- 新增 packages/editor/src/sdk,通过 sdk.ts 对外导出
- 将 services 下的核心服务迁移至 sdk/services
- 工具函数拆分至 sdk/utils,校验逻辑迁移至 sdk/validate,新增 sdk/wiring
- services/sdk-instance.ts 负责在编辑器中实例化 SDK
- 补充 SDK 相关单元测试,新增 docs/api/editor/sdk.md 文档
2026-10-08 19:58:03 +08:00

103 lines
3.0 KiB
TypeScript

/*
* Tencent is pleased to support the open source community by making TMagicEditor available.
*
* Copyright (C) 2025 Tencent.
*/
import { describe, expect, test, vi } from 'vitest';
import BaseService from '@editor/sdk/services/BaseService';
class SyncService extends BaseService {
public count = 0;
constructor() {
super([{ name: 'add', isAsync: false }]);
}
public add(value: number): number {
this.count += value;
return this.count;
}
}
class AsyncService extends BaseService {
public count = 0;
constructor(serial = false) {
super([{ name: 'add', isAsync: true }], serial ? ['add'] : []);
}
public async add(value: number): Promise<number> {
await Promise.resolve();
this.count += value;
return this.count;
}
}
describe('BaseService 同步方法 + plugin', () => {
test('beforeAdd / afterAdd 正常被链式调用', () => {
const svc = new SyncService();
const before = vi.fn((v: number) => [v + 1]);
const after = vi.fn((result: number) => result * 10);
svc.usePlugin({ beforeAdd: before, afterAdd: after });
const result = svc.add(2);
expect(before).toHaveBeenCalledWith(2);
expect(after).toHaveBeenCalled();
expect(result).toBe(30);
});
test('removePlugin 解除指定钩子', () => {
const svc = new SyncService();
const before = vi.fn((v: number) => [v]);
svc.usePlugin({ beforeAdd: before });
svc.removePlugin({ beforeAdd: before });
svc.add(1);
expect(before).not.toHaveBeenCalled();
});
test('removeAllPlugins 清空所有 plugin', () => {
const svc = new SyncService();
const before = vi.fn((v: number) => [v]);
svc.usePlugin({ beforeAdd: before });
svc.removeAllPlugins();
svc.add(1);
expect(before).not.toHaveBeenCalled();
});
test('before 返回 Error 抛错终止', () => {
const svc = new SyncService();
svc.usePlugin({
beforeAdd: () => new Error('stop'),
});
expect(() => svc.add(1)).toThrow('stop');
});
});
describe('BaseService 异步方法', () => {
test('beforeAdd / afterAdd 异步链路', async () => {
const svc = new AsyncService();
svc.usePlugin({
beforeAdd: async (v: number) => [v + 1],
afterAdd: async (r: number) => r + 100,
});
const result = await svc.add(1);
expect(result).toBe(102);
});
test('serial 模式按顺序执行', async () => {
const svc = new AsyncService(true);
const results = await Promise.all([svc.add(1), svc.add(2), svc.add(3)]);
expect(results).toEqual([1, 3, 6]);
});
test('before 返回非数组时被包装为数组', async () => {
const svc = new AsyncService();
svc.usePlugin({ beforeAdd: async (v: number) => v + 5 });
const result = await svc.add(1);
expect(result).toBe(6);
});
test('after 返回 Error 抛错', async () => {
const svc = new AsyncService();
svc.usePlugin({ afterAdd: async () => new Error('after-bad') });
await expect(svc.add(1)).rejects.toThrow('after-bad');
});
});