@taicode/common-base 1.7.2 → 1.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,6 @@
1
+ export declare class Disposer {
2
+ private cleanupFunctions;
3
+ addDisposer(cleanupFn: () => unknown): void;
4
+ dispose(): void;
5
+ }
6
+ //# sourceMappingURL=disposer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disposer.d.ts","sourceRoot":"","sources":["../../source/events/disposer.ts"],"names":[],"mappings":"AAAA,qBAAa,QAAQ;IACnB,OAAO,CAAC,gBAAgB,CAAyB;IAGjD,WAAW,CAAC,SAAS,EAAE,MAAM,OAAO,GAAG,IAAI;IAK3C,OAAO,IAAI,IAAI;CAUhB"}
@@ -0,0 +1,19 @@
1
+ export class Disposer {
2
+ cleanupFunctions = [];
3
+ // 添加清理函数
4
+ addDisposer(cleanupFn) {
5
+ this.cleanupFunctions.push(cleanupFn);
6
+ }
7
+ // 执行所有清理函数
8
+ dispose() {
9
+ for (const cleanupFn of this.cleanupFunctions) {
10
+ try {
11
+ cleanupFn();
12
+ }
13
+ catch (error) {
14
+ console.error('Error during cleanup:', error);
15
+ }
16
+ }
17
+ this.cleanupFunctions = []; // 清空清理函数列表
18
+ }
19
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=disposer.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disposer.test.d.ts","sourceRoot":"","sources":["../../source/events/disposer.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,192 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { Disposer } from './disposer';
3
+ describe('Disposer', () => {
4
+ let disposer;
5
+ beforeEach(() => {
6
+ disposer = new Disposer();
7
+ });
8
+ describe('addDisposer', () => {
9
+ it('应该能够添加清理函数', () => {
10
+ const cleanupFn = vi.fn();
11
+ expect(() => {
12
+ disposer.addDisposer(cleanupFn);
13
+ }).not.toThrow();
14
+ });
15
+ it('应该能够添加多个清理函数', () => {
16
+ const cleanupFn1 = vi.fn();
17
+ const cleanupFn2 = vi.fn();
18
+ const cleanupFn3 = vi.fn();
19
+ disposer.addDisposer(cleanupFn1);
20
+ disposer.addDisposer(cleanupFn2);
21
+ disposer.addDisposer(cleanupFn3);
22
+ disposer.dispose();
23
+ expect(cleanupFn1).toHaveBeenCalledOnce();
24
+ expect(cleanupFn2).toHaveBeenCalledOnce();
25
+ expect(cleanupFn3).toHaveBeenCalledOnce();
26
+ });
27
+ it('应该能够添加返回不同类型的清理函数', () => {
28
+ const voidFn = vi.fn(() => { });
29
+ const stringFn = vi.fn(() => 'cleanup result');
30
+ const numberFn = vi.fn(() => 42);
31
+ const promiseFn = vi.fn(() => Promise.resolve('async cleanup'));
32
+ disposer.addDisposer(voidFn);
33
+ disposer.addDisposer(stringFn);
34
+ disposer.addDisposer(numberFn);
35
+ disposer.addDisposer(promiseFn);
36
+ disposer.dispose();
37
+ expect(voidFn).toHaveBeenCalled();
38
+ expect(stringFn).toHaveBeenCalled();
39
+ expect(numberFn).toHaveBeenCalled();
40
+ expect(promiseFn).toHaveBeenCalled();
41
+ });
42
+ });
43
+ describe('dispose', () => {
44
+ it('应该执行所有清理函数', () => {
45
+ const cleanupFn1 = vi.fn();
46
+ const cleanupFn2 = vi.fn();
47
+ const cleanupFn3 = vi.fn();
48
+ disposer.addDisposer(cleanupFn1);
49
+ disposer.addDisposer(cleanupFn2);
50
+ disposer.addDisposer(cleanupFn3);
51
+ disposer.dispose();
52
+ expect(cleanupFn1).toHaveBeenCalledOnce();
53
+ expect(cleanupFn2).toHaveBeenCalledOnce();
54
+ expect(cleanupFn3).toHaveBeenCalledOnce();
55
+ });
56
+ it('应该按添加顺序执行清理函数', () => {
57
+ const executionOrder = [];
58
+ disposer.addDisposer(() => executionOrder.push(1));
59
+ disposer.addDisposer(() => executionOrder.push(2));
60
+ disposer.addDisposer(() => executionOrder.push(3));
61
+ disposer.dispose();
62
+ expect(executionOrder).toEqual([1, 2, 3]);
63
+ });
64
+ it('应该处理清理函数中的错误', () => {
65
+ const workingFn1 = vi.fn();
66
+ const errorFn = vi.fn(() => {
67
+ throw new Error('Cleanup error');
68
+ });
69
+ const workingFn2 = vi.fn();
70
+ // 模拟 console.error
71
+ const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => { });
72
+ disposer.addDisposer(workingFn1);
73
+ disposer.addDisposer(errorFn);
74
+ disposer.addDisposer(workingFn2);
75
+ // dispose 不应该抛出错误
76
+ expect(() => {
77
+ disposer.dispose();
78
+ }).not.toThrow();
79
+ // 所有函数都应该被调用
80
+ expect(workingFn1).toHaveBeenCalled();
81
+ expect(errorFn).toHaveBeenCalled();
82
+ expect(workingFn2).toHaveBeenCalled();
83
+ // 错误应该被记录
84
+ expect(consoleSpy).toHaveBeenCalledWith('Error during cleanup:', expect.any(Error));
85
+ consoleSpy.mockRestore();
86
+ });
87
+ it('应该在执行后清空清理函数列表', () => {
88
+ const cleanupFn = vi.fn();
89
+ disposer.addDisposer(cleanupFn);
90
+ disposer.dispose();
91
+ expect(cleanupFn).toHaveBeenCalledOnce();
92
+ // 再次调用 dispose 不应该执行任何函数
93
+ disposer.dispose();
94
+ expect(cleanupFn).toHaveBeenCalledOnce();
95
+ });
96
+ it('应该能够在清空后重新添加清理函数', () => {
97
+ const firstCleanup = vi.fn();
98
+ const secondCleanup = vi.fn();
99
+ disposer.addDisposer(firstCleanup);
100
+ disposer.dispose();
101
+ disposer.addDisposer(secondCleanup);
102
+ disposer.dispose();
103
+ expect(firstCleanup).toHaveBeenCalledOnce();
104
+ expect(secondCleanup).toHaveBeenCalledOnce();
105
+ });
106
+ it('应该在没有清理函数时安全执行', () => {
107
+ expect(() => {
108
+ disposer.dispose();
109
+ }).not.toThrow();
110
+ });
111
+ it('应该能够多次调用 dispose', () => {
112
+ const cleanupFn = vi.fn();
113
+ disposer.addDisposer(cleanupFn);
114
+ disposer.dispose();
115
+ disposer.dispose();
116
+ disposer.dispose();
117
+ expect(cleanupFn).toHaveBeenCalledOnce();
118
+ });
119
+ });
120
+ describe('实际使用场景', () => {
121
+ it('应该能够清理事件监听器', () => {
122
+ const removeEventListener = vi.fn();
123
+ const unsubscribe = vi.fn();
124
+ disposer.addDisposer(removeEventListener);
125
+ disposer.addDisposer(unsubscribe);
126
+ disposer.dispose();
127
+ expect(removeEventListener).toHaveBeenCalled();
128
+ expect(unsubscribe).toHaveBeenCalled();
129
+ });
130
+ it('应该能够清理定时器', () => {
131
+ const clearTimeout = vi.fn();
132
+ const clearInterval = vi.fn();
133
+ disposer.addDisposer(() => clearTimeout(123));
134
+ disposer.addDisposer(() => clearInterval(456));
135
+ disposer.dispose();
136
+ expect(clearTimeout).toHaveBeenCalledWith(123);
137
+ expect(clearInterval).toHaveBeenCalledWith(456);
138
+ });
139
+ it('应该能够清理资源连接', () => {
140
+ const closeConnection = vi.fn();
141
+ const releaseResource = vi.fn();
142
+ disposer.addDisposer(() => closeConnection());
143
+ disposer.addDisposer(() => releaseResource());
144
+ disposer.dispose();
145
+ expect(closeConnection).toHaveBeenCalled();
146
+ expect(releaseResource).toHaveBeenCalled();
147
+ });
148
+ it('应该与 EventEmitter 配合使用', () => {
149
+ // 模拟 EventEmitter 的使用
150
+ const mockEventEmitter = {
151
+ on: vi.fn().mockReturnValue(vi.fn()), // 返回 off 函数
152
+ cleanup: vi.fn()
153
+ };
154
+ const offFunction1 = mockEventEmitter.on('event1', vi.fn());
155
+ const offFunction2 = mockEventEmitter.on('event2', vi.fn());
156
+ disposer.addDisposer(offFunction1);
157
+ disposer.addDisposer(offFunction2);
158
+ disposer.addDisposer(() => mockEventEmitter.cleanup());
159
+ disposer.dispose();
160
+ expect(offFunction1).toHaveBeenCalled();
161
+ expect(offFunction2).toHaveBeenCalled();
162
+ expect(mockEventEmitter.cleanup).toHaveBeenCalled();
163
+ });
164
+ });
165
+ describe('错误处理', () => {
166
+ it('应该捕获并记录同步错误', () => {
167
+ const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => { });
168
+ const error = new Error('Sync error');
169
+ disposer.addDisposer(() => {
170
+ throw error;
171
+ });
172
+ disposer.dispose();
173
+ expect(consoleSpy).toHaveBeenCalledWith('Error during cleanup:', error);
174
+ consoleSpy.mockRestore();
175
+ });
176
+ it('应该处理不同类型的错误', () => {
177
+ const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => { });
178
+ disposer.addDisposer(() => {
179
+ throw new TypeError('Type error');
180
+ });
181
+ disposer.addDisposer(() => {
182
+ throw 'String error';
183
+ });
184
+ disposer.addDisposer(() => {
185
+ throw { message: 'Object error' };
186
+ });
187
+ disposer.dispose();
188
+ expect(consoleSpy).toHaveBeenCalledTimes(3);
189
+ consoleSpy.mockRestore();
190
+ });
191
+ });
192
+ });
@@ -0,0 +1,33 @@
1
+ type OffFn = () => void;
2
+ type Listener<T = unknown> = (data: T) => void;
3
+ export declare class EventEmitter<Events extends object = object> {
4
+ private listeners;
5
+ constructor();
6
+ /**
7
+ * 订阅事件
8
+ * @param type 事件类型
9
+ * @param listener 回调函数
10
+ */
11
+ on<K extends keyof Events>(type: K, listener: Listener<Events[K]>): OffFn;
12
+ /**
13
+ * 取消订阅
14
+ * @param type 事件类型
15
+ * @param listener 要移除的回调函数(可选)
16
+ */
17
+ off<K extends keyof Events>(type: K, listener?: Listener<Events[K]>): void;
18
+ /**
19
+ * 触发事件
20
+ * @param type 事件类型
21
+ * @param data 要传递的数据
22
+ */
23
+ emit<K extends keyof Events>(type: K, data: Events[K]): void;
24
+ /**
25
+ * 一次性订阅
26
+ * @param type 事件类型
27
+ * @param listener 回调函数
28
+ */
29
+ once<K extends keyof Events>(type: K, listener: Listener<Events[K]>): void;
30
+ cleanup(): void;
31
+ }
32
+ export {};
33
+ //# sourceMappingURL=event-emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-emitter.d.ts","sourceRoot":"","sources":["../../source/events/event-emitter.ts"],"names":[],"mappings":"AAAA,KAAK,KAAK,GAAG,MAAM,IAAI,CAAA;AACvB,KAAK,QAAQ,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAA;AAE9C,qBAAa,YAAY,CAAC,MAAM,SAAS,MAAM,GAAG,MAAM;IACtD,OAAO,CAAC,SAAS,CAAsD;;IAUvE;;;;OAIG;IACH,EAAE,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK;IASzE;;;;OAIG;IACH,GAAG,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI;IAc1E;;;;OAIG;IACH,IAAI,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI;IAQ5D;;;;OAIG;IACH,IAAI,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI;IAQ1E,OAAO;CAGR"}
@@ -0,0 +1,66 @@
1
+ export class EventEmitter {
2
+ listeners = {};
3
+ constructor() {
4
+ this.on = this.on.bind(this);
5
+ this.off = this.off.bind(this);
6
+ this.once = this.once.bind(this);
7
+ this.emit = this.emit.bind(this);
8
+ this.cleanup = this.cleanup.bind(this);
9
+ }
10
+ /**
11
+ * 订阅事件
12
+ * @param type 事件类型
13
+ * @param listener 回调函数
14
+ */
15
+ on(type, listener) {
16
+ if (!this.listeners[type]) {
17
+ this.listeners[type] = [];
18
+ }
19
+ this.listeners[type].push(listener);
20
+ return () => this.off(type, listener);
21
+ }
22
+ /**
23
+ * 取消订阅
24
+ * @param type 事件类型
25
+ * @param listener 要移除的回调函数(可选)
26
+ */
27
+ off(type, listener) {
28
+ if (!this.listeners[type])
29
+ return;
30
+ if (!listener) {
31
+ // 移除该事件的所有监听器
32
+ delete this.listeners[type];
33
+ }
34
+ else {
35
+ // 移除特定监听器
36
+ this.listeners[type] = this.listeners[type].filter((fn) => fn !== listener);
37
+ }
38
+ }
39
+ /**
40
+ * 触发事件
41
+ * @param type 事件类型
42
+ * @param data 要传递的数据
43
+ */
44
+ emit(type, data) {
45
+ const listeners = this.listeners[type];
46
+ // 复制数组避免回调中取消订阅导致的遍历问题
47
+ if (listeners) {
48
+ listeners.slice().forEach((fn) => fn(data));
49
+ }
50
+ }
51
+ /**
52
+ * 一次性订阅
53
+ * @param type 事件类型
54
+ * @param listener 回调函数
55
+ */
56
+ once(type, listener) {
57
+ const onceWrapper = (data) => {
58
+ listener(data);
59
+ this.off(type, onceWrapper);
60
+ };
61
+ this.on(type, onceWrapper);
62
+ }
63
+ cleanup() {
64
+ this.listeners = {};
65
+ }
66
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=event-emitter.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-emitter.test.d.ts","sourceRoot":"","sources":["../../source/events/event-emitter.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,213 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { EventEmitter } from './event-emitter';
3
+ describe('EventEmitter', () => {
4
+ let emitter;
5
+ beforeEach(() => {
6
+ emitter = new EventEmitter();
7
+ });
8
+ describe('on', () => {
9
+ it('应该能够订阅事件', () => {
10
+ const listener = vi.fn();
11
+ emitter.on('test', listener);
12
+ emitter.emit('test', 'hello');
13
+ expect(listener).toHaveBeenCalledOnce();
14
+ expect(listener).toHaveBeenCalledWith('hello');
15
+ });
16
+ it('应该能够订阅多个监听器', () => {
17
+ const listener1 = vi.fn();
18
+ const listener2 = vi.fn();
19
+ emitter.on('test', listener1);
20
+ emitter.on('test', listener2);
21
+ emitter.emit('test', 'hello');
22
+ expect(listener1).toHaveBeenCalledOnce();
23
+ expect(listener2).toHaveBeenCalledOnce();
24
+ expect(listener1).toHaveBeenCalledWith('hello');
25
+ expect(listener2).toHaveBeenCalledWith('hello');
26
+ });
27
+ it('应该返回取消订阅函数', () => {
28
+ const listener = vi.fn();
29
+ const off = emitter.on('test', listener);
30
+ emitter.emit('test', 'hello');
31
+ expect(listener).toHaveBeenCalledOnce();
32
+ off();
33
+ emitter.emit('test', 'world');
34
+ expect(listener).toHaveBeenCalledOnce();
35
+ });
36
+ it('应该支持不同类型的事件数据', () => {
37
+ const stringListener = vi.fn();
38
+ const numberListener = vi.fn();
39
+ const objectListener = vi.fn();
40
+ const voidListener = vi.fn();
41
+ emitter.on('test', stringListener);
42
+ emitter.on('number', numberListener);
43
+ emitter.on('object', objectListener);
44
+ emitter.on('noData', voidListener);
45
+ const testObject = { id: 1, name: 'test' };
46
+ emitter.emit('test', 'hello');
47
+ emitter.emit('number', 42);
48
+ emitter.emit('object', testObject);
49
+ emitter.emit('noData', undefined);
50
+ expect(stringListener).toHaveBeenCalledWith('hello');
51
+ expect(numberListener).toHaveBeenCalledWith(42);
52
+ expect(objectListener).toHaveBeenCalledWith(testObject);
53
+ expect(voidListener).toHaveBeenCalledWith(undefined);
54
+ });
55
+ });
56
+ describe('off', () => {
57
+ it('应该能够取消订阅特定监听器', () => {
58
+ const listener1 = vi.fn();
59
+ const listener2 = vi.fn();
60
+ emitter.on('test', listener1);
61
+ emitter.on('test', listener2);
62
+ emitter.off('test', listener1);
63
+ emitter.emit('test', 'hello');
64
+ expect(listener1).not.toHaveBeenCalled();
65
+ expect(listener2).toHaveBeenCalledOnce();
66
+ });
67
+ it('应该能够取消订阅所有监听器', () => {
68
+ const listener1 = vi.fn();
69
+ const listener2 = vi.fn();
70
+ emitter.on('test', listener1);
71
+ emitter.on('test', listener2);
72
+ emitter.off('test');
73
+ emitter.emit('test', 'hello');
74
+ expect(listener1).not.toHaveBeenCalled();
75
+ expect(listener2).not.toHaveBeenCalled();
76
+ });
77
+ it('应该忽略不存在的事件类型', () => {
78
+ expect(() => {
79
+ emitter.off('test');
80
+ }).not.toThrow();
81
+ });
82
+ it('应该忽略不存在的监听器', () => {
83
+ const listener = vi.fn();
84
+ const anotherListener = vi.fn();
85
+ emitter.on('test', listener);
86
+ expect(() => {
87
+ emitter.off('test', anotherListener);
88
+ }).not.toThrow();
89
+ emitter.emit('test', 'hello');
90
+ expect(listener).toHaveBeenCalledOnce();
91
+ });
92
+ });
93
+ describe('emit', () => {
94
+ it('应该能够触发事件', () => {
95
+ const listener = vi.fn();
96
+ emitter.on('test', listener);
97
+ emitter.emit('test', 'hello');
98
+ expect(listener).toHaveBeenCalledWith('hello');
99
+ });
100
+ it('应该不抛出错误当没有监听器时', () => {
101
+ expect(() => {
102
+ emitter.emit('test', 'hello');
103
+ }).not.toThrow();
104
+ });
105
+ it('应该按顺序调用监听器', () => {
106
+ const calls = [];
107
+ emitter.on('test', () => calls.push(1));
108
+ emitter.on('test', () => calls.push(2));
109
+ emitter.on('test', () => calls.push(3));
110
+ emitter.emit('test', 'hello');
111
+ expect(calls).toEqual([1, 2, 3]);
112
+ });
113
+ it('应该处理监听器中的错误', () => {
114
+ const workingListener = vi.fn();
115
+ const errorListener = vi.fn(() => {
116
+ throw new Error('Test error');
117
+ });
118
+ const anotherWorkingListener = vi.fn();
119
+ emitter.on('test', workingListener);
120
+ emitter.on('test', errorListener);
121
+ emitter.on('test', anotherWorkingListener);
122
+ expect(() => {
123
+ emitter.emit('test', 'hello');
124
+ }).toThrow('Test error');
125
+ expect(workingListener).toHaveBeenCalled();
126
+ expect(errorListener).toHaveBeenCalled();
127
+ // 由于错误,后续监听器可能不会被调用
128
+ });
129
+ it('应该防止监听器修改监听器列表时的遍历问题', () => {
130
+ const listener1 = vi.fn();
131
+ const listener2 = vi.fn(() => {
132
+ // 在回调中取消订阅
133
+ emitter.off('test', listener3);
134
+ });
135
+ const listener3 = vi.fn();
136
+ emitter.on('test', listener1);
137
+ emitter.on('test', listener2);
138
+ emitter.on('test', listener3);
139
+ emitter.emit('test', 'hello');
140
+ expect(listener1).toHaveBeenCalled();
141
+ expect(listener2).toHaveBeenCalled();
142
+ expect(listener3).toHaveBeenCalled(); // 应该仍然被调用,因为使用了 slice()
143
+ });
144
+ });
145
+ describe('once', () => {
146
+ it('应该只执行一次监听器', () => {
147
+ const listener = vi.fn();
148
+ emitter.once('test', listener);
149
+ emitter.emit('test', 'first');
150
+ emitter.emit('test', 'second');
151
+ expect(listener).toHaveBeenCalledOnce();
152
+ expect(listener).toHaveBeenCalledWith('first');
153
+ });
154
+ it('应该在执行后自动取消订阅', () => {
155
+ const listener = vi.fn();
156
+ emitter.once('test', listener);
157
+ emitter.emit('test', 'hello');
158
+ // 验证监听器已被移除
159
+ emitter.emit('test', 'world');
160
+ expect(listener).toHaveBeenCalledOnce();
161
+ });
162
+ it('应该与普通监听器一起工作', () => {
163
+ const onceListener = vi.fn();
164
+ const normalListener = vi.fn();
165
+ emitter.once('test', onceListener);
166
+ emitter.on('test', normalListener);
167
+ emitter.emit('test', 'first');
168
+ emitter.emit('test', 'second');
169
+ expect(onceListener).toHaveBeenCalledOnce();
170
+ expect(normalListener).toHaveBeenCalledTimes(2);
171
+ });
172
+ });
173
+ describe('cleanup', () => {
174
+ it('应该清空所有监听器', () => {
175
+ const listener1 = vi.fn();
176
+ const listener2 = vi.fn();
177
+ emitter.on('test', listener1);
178
+ emitter.on('number', listener2);
179
+ emitter.cleanup();
180
+ emitter.emit('test', 'hello');
181
+ emitter.emit('number', 42);
182
+ expect(listener1).not.toHaveBeenCalled();
183
+ expect(listener2).not.toHaveBeenCalled();
184
+ });
185
+ it('清理后应该能够重新添加监听器', () => {
186
+ const listener = vi.fn();
187
+ emitter.on('test', listener);
188
+ emitter.cleanup();
189
+ const newListener = vi.fn();
190
+ emitter.on('test', newListener);
191
+ emitter.emit('test', 'hello');
192
+ expect(listener).not.toHaveBeenCalled();
193
+ expect(newListener).toHaveBeenCalledWith('hello');
194
+ });
195
+ });
196
+ describe('方法绑定', () => {
197
+ it('方法应该绑定到实例', () => {
198
+ const { on, off, emit, once, cleanup } = emitter;
199
+ const listener = vi.fn();
200
+ on('test', listener);
201
+ emit('test', 'hello');
202
+ expect(listener).toHaveBeenCalledWith('hello');
203
+ off('test', listener);
204
+ emit('test', 'world');
205
+ expect(listener).toHaveBeenCalledOnce();
206
+ // 测试其他方法
207
+ once('test', listener);
208
+ emit('test', 'once');
209
+ expect(listener).toHaveBeenCalledTimes(2);
210
+ cleanup();
211
+ });
212
+ });
213
+ });
@@ -0,0 +1,3 @@
1
+ export * from './event-emitter';
2
+ export * from './disposer';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../source/events/index.ts"],"names":[],"mappings":"AACA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,YAAY,CAAA"}
@@ -0,0 +1,3 @@
1
+ // 事件系统相关功能
2
+ export * from './event-emitter';
3
+ export * from './disposer';