2024-03-26 10:54:57 +08:00

170 lines
3.9 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from 'vitest';
import { useEvent, createHookStore, type HookStore } from '../../src/utils/hook';
describe('event', () => {
it("event's listener ops", () => {
const event = useEvent();
const fn = () => {};
event.add(fn);
expect(event.list().includes(fn)).toBeTruthy();
event.remove(fn);
expect(event.list().includes(fn)).toBeFalsy();
event.add(fn);
expect(event.list().includes(fn)).toBeTruthy();
event.clear();
expect(event.list().includes(fn)).toBeFalsy();
});
});
describe('hooks', () => {
let hookStore: HookStore;
beforeEach(() => {
hookStore = createHookStore();
});
it('should register hook successfully', () => {
const fn = () => {};
hookStore.hook('test', fn);
expect(hookStore.getHooks('test')).toContain(fn);
});
it('should ignore empty hook', () => {
hookStore.hook('', () => {});
hookStore.hook(undefined as any, () => {});
expect(hookStore.getHooks('')).toBeUndefined();
expect(hookStore.getHooks(undefined as any)).toBeUndefined();
});
it('should ignore not function hook', () => {
hookStore.hook('test', 1 as any);
hookStore.hook('test', undefined as any);
expect(hookStore.getHooks('test')).toBeUndefined();
});
it('should call registered hook', () => {
const spy = vi.fn();
hookStore.hook('test', spy);
hookStore.call('test');
expect(spy).toHaveBeenCalled();
});
it('callAsync: should sequential call registered async hook', async () => {
let count = 0;
const counts: number[] = [];
const fn = async () => {
counts.push(count++);
};
hookStore.hook('test', fn);
hookStore.hook('test', fn);
await hookStore.callAsync('test');
expect(counts).toEqual([0, 1]);
});
it('callParallel: should parallel call registered async hook', async () => {
let count = 0;
const sleep = (delay: number) => {
return new Promise((resolve) => {
setTimeout(resolve, delay);
});
};
hookStore.hook('test', () => {
count++;
});
hookStore.hook('test', async () => {
await sleep(500);
count++;
});
hookStore.hook('test', async () => {
await sleep(1000);
expect(count).toBe(2);
});
await hookStore.callParallel('test');
});
it('should throw hook error', async () => {
const error = new Error('Hook Error');
hookStore.hook('test', () => {
throw error;
});
expect(() => hookStore.call('test')).toThrow(error);
});
it('should return a self-removal function', async () => {
const spy = vi.fn();
const remove = hookStore.hook('test', spy);
hookStore.call('test');
expect(spy).toBeCalledTimes(1);
remove();
hookStore.call('test');
expect(spy).toBeCalledTimes(1);
});
it('should clear removed hooks', () => {
const result: number[] = [];
const fn1 = () => result.push(1);
const fn2 = () => result.push(2);
hookStore.hook('test', fn1);
hookStore.hook('test', fn2);
hookStore.call('test');
expect(result).toHaveLength(2);
expect(result).toEqual([1, 2]);
hookStore.remove('test', fn1);
hookStore.call('test');
expect(result).toHaveLength(3);
expect(result).toEqual([1, 2, 2]);
hookStore.remove('test');
hookStore.call('test');
expect(result).toHaveLength(3);
expect(result).toEqual([1, 2, 2]);
});
it('should clear ops works', () => {
hookStore.hook('test1', () => {});
hookStore.hook('test2', () => {});
expect(hookStore.getHooks('test1')).toHaveLength(1);
expect(hookStore.getHooks('test2')).toHaveLength(1);
hookStore.clear('test1');
expect(hookStore.getHooks('test1')).toBeUndefined();
expect(hookStore.getHooks('test2')).toHaveLength(1);
hookStore.clear();
expect(hookStore.getHooks('test1')).toBeUndefined();
expect(hookStore.getHooks('test2')).toBeUndefined();
});
});