mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2026-05-25 18:03:38 +00:00
152 lines
4.6 KiB
TypeScript
152 lines
4.6 KiB
TypeScript
/*
|
|
* Tencent is pleased to support the open source community by making TMagicEditor available.
|
|
*
|
|
* Copyright (C) 2025 Tencent.
|
|
*/
|
|
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
|
|
|
|
import { DepTargetType, Target } from '@tmagic/core';
|
|
|
|
import depService from '@editor/services/dep';
|
|
|
|
vi.mock('@editor/utils/dep/worker.ts?worker&inline', () => ({
|
|
default: class FakeWorker {
|
|
public onmessage: ((e: any) => void) | null = null;
|
|
public onerror: (() => void) | null = null;
|
|
public postMessage() {
|
|
setTimeout(() => {
|
|
this.onmessage?.({ data: {} });
|
|
}, 0);
|
|
}
|
|
},
|
|
}));
|
|
|
|
const makeTarget = (id = 't1', type: string = DepTargetType.DEFAULT) =>
|
|
new Target({
|
|
id,
|
|
type,
|
|
isTarget: () => false,
|
|
});
|
|
|
|
beforeEach(() => {
|
|
depService.reset();
|
|
});
|
|
|
|
afterEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
// Promise.withResolvers polyfill for older Node
|
|
if (typeof (Promise as any).withResolvers !== 'function') {
|
|
(Promise as any).withResolvers = function withResolvers<T>() {
|
|
let resolve!: (value: T | PromiseLike<T>) => void;
|
|
let reject!: (reason?: unknown) => void;
|
|
const promise = new Promise<T>((res, rej) => {
|
|
resolve = res;
|
|
reject = rej;
|
|
});
|
|
return { promise, resolve, reject };
|
|
};
|
|
}
|
|
|
|
describe('Dep service', () => {
|
|
test('addTarget / getTarget / removeTarget', () => {
|
|
const t = makeTarget('t1');
|
|
depService.addTarget(t);
|
|
expect(depService.getTarget('t1')).toBeDefined();
|
|
expect(depService.hasTarget('t1')).toBe(true);
|
|
depService.removeTarget('t1');
|
|
expect(depService.getTarget('t1')).toBeUndefined();
|
|
});
|
|
|
|
test('addTarget 触发 add-target 事件', () => {
|
|
const fn = vi.fn();
|
|
depService.on('add-target', fn);
|
|
const t = makeTarget('t2');
|
|
depService.addTarget(t);
|
|
expect(fn).toHaveBeenCalledWith(t);
|
|
depService.off('add-target', fn);
|
|
});
|
|
|
|
test('removeTarget 触发 remove-target 事件', () => {
|
|
const fn = vi.fn();
|
|
const t = makeTarget('t3');
|
|
depService.addTarget(t);
|
|
depService.on('remove-target', fn);
|
|
depService.removeTarget('t3');
|
|
expect(fn).toHaveBeenCalledWith('t3', DepTargetType.DEFAULT);
|
|
depService.off('remove-target', fn);
|
|
});
|
|
|
|
test('removeTargets 不抛错并清空目标', () => {
|
|
depService.addTarget(makeTarget('a'));
|
|
depService.addTarget(makeTarget('b'));
|
|
expect(() => depService.removeTargets()).not.toThrow();
|
|
expect(depService.getTarget('a')).toBeUndefined();
|
|
});
|
|
|
|
test('removeTargets - 不存在的 type 直接返回', () => {
|
|
expect(() => depService.removeTargets('not-existing')).not.toThrow();
|
|
});
|
|
|
|
test('hasSpecifiedTypeTarget / clearTargets', () => {
|
|
depService.addTarget(makeTarget('x'));
|
|
expect(depService.hasSpecifiedTypeTarget()).toBe(true);
|
|
depService.clearTargets();
|
|
expect(depService.hasSpecifiedTypeTarget()).toBe(false);
|
|
});
|
|
|
|
test('set / get state', () => {
|
|
depService.set('collecting', true);
|
|
expect(depService.get('collecting')).toBe(true);
|
|
depService.set('taskLength', 5);
|
|
expect(depService.get('taskLength')).toBe(5);
|
|
});
|
|
|
|
test('collect 调用后触发 collected 事件', () => {
|
|
const fn = vi.fn();
|
|
depService.on('collected', fn);
|
|
depService.collect([{ id: 'n1', type: 'text' }] as any);
|
|
expect(fn).toHaveBeenCalled();
|
|
expect(depService.get('collecting')).toBe(false);
|
|
depService.off('collected', fn);
|
|
});
|
|
|
|
test('collectIdle - 没有命中时立即 resolve 并 emit collected', async () => {
|
|
const fn = vi.fn();
|
|
depService.on('collected', fn);
|
|
await depService.collectIdle([{ id: 'n1', type: 'text' }] as any);
|
|
expect(fn).toHaveBeenCalled();
|
|
depService.off('collected', fn);
|
|
});
|
|
|
|
test('collectByWorker 完成后触发 collected 与 ds-collected', async () => {
|
|
const fn = vi.fn();
|
|
const dsFn = vi.fn();
|
|
depService.on('collected', fn);
|
|
depService.on('ds-collected', dsFn);
|
|
await depService.collectByWorker({ items: [], id: 'app', type: 'app' } as any);
|
|
expect(fn).toHaveBeenCalled();
|
|
expect(dsFn).toHaveBeenCalled();
|
|
depService.off('collected', fn);
|
|
depService.off('ds-collected', dsFn);
|
|
});
|
|
|
|
test('clear 与 clearByType', () => {
|
|
expect(() => depService.clear()).not.toThrow();
|
|
expect(() => depService.clearByType(DepTargetType.DEFAULT)).not.toThrow();
|
|
});
|
|
|
|
test('clearIdleTasks 安全调用', () => {
|
|
expect(() => depService.clearIdleTasks()).not.toThrow();
|
|
});
|
|
|
|
test('reset 后 collecting=false 且 targets 清空', () => {
|
|
depService.addTarget(makeTarget('rs'));
|
|
depService.set('collecting', true);
|
|
depService.reset();
|
|
expect(depService.get('collecting')).toBe(false);
|
|
expect(depService.hasTarget('rs')).toBe(false);
|
|
});
|
|
});
|