@irrelon/emitter 6.0.1 → 6.1.0

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.
@@ -1,23 +1,24 @@
1
+ import { jest } from "@jest/globals";
1
2
  import assert from "assert";
2
3
  import { Emitter, EmitterEventsInterface, EventListenerCallback, ListenerReturnFlag } from "../src/Emitter";
3
4
 
4
5
  let expectedAssertions = 0;
5
6
  let actualAssertions = 0;
6
7
 
7
- function expect(val: number) {
8
+ function expectAssertionCount (val: number) {
8
9
  expectedAssertions = val;
9
10
  }
10
11
 
11
- function reset() {
12
+ function resetAssertionCount () {
12
13
  expectedAssertions = 0;
13
14
  actualAssertions = 0;
14
15
  }
15
16
 
16
- function countAssertion() {
17
+ function countAssertion () {
17
18
  actualAssertions++;
18
19
  }
19
20
 
20
- function check() {
21
+ function checkAssertionCount () {
21
22
  if (expectedAssertions === undefined || expectedAssertions === actualAssertions) {
22
23
  return;
23
24
  }
@@ -25,8 +26,8 @@ function check() {
25
26
  throw new Error("expected " + expectedAssertions + " assertions, got " + actualAssertions);
26
27
  }
27
28
 
28
- beforeEach(reset);
29
- afterEach(check);
29
+ beforeEach(resetAssertionCount);
30
+ afterEach(checkAssertionCount);
30
31
 
31
32
  describe("Emitter", () => {
32
33
  describe("new Emitter()", () => {
@@ -41,25 +42,19 @@ describe("Emitter", () => {
41
42
 
42
43
  assert.strictEqual(
43
44
  !myClass._eventListeners?.moo ||
44
- !myClass._eventListeners.moo["*"] ||
45
- myClass._eventListeners.moo["*"].length,
45
+ !myClass._eventListeners.moo["*"] ||
46
+ myClass._eventListeners.moo["*"].length,
46
47
  true,
47
48
  "Listeners all removed from event"
48
49
  );
49
50
  });
50
51
 
51
52
  it("Supports extending Emitter as a base class", () => {
52
- let testFuncCount = 0;
53
-
54
53
  // Test extending Emitter and modifying base functionality
55
54
  class MyClass extends Emitter {
56
- testFunc() {
57
- testFuncCount++;
58
- }
59
-
60
55
  on(eventName: string, id: string, listener: EventListenerCallback): this;
61
56
  on(eventName: string, listener: EventListenerCallback): this;
62
- on(eventName: string, ...rest: any[]): this {
57
+ on (eventName: string, ...rest: any[]): this {
63
58
  const restTypes = rest.map((arg) => typeof arg);
64
59
 
65
60
  if (restTypes[0] === "function") {
@@ -73,14 +68,14 @@ describe("Emitter", () => {
73
68
  }
74
69
 
75
70
  // @ts-ignore
76
- emit(eventName: string, ...rest: any[]) {
71
+ emit (eventName: string, ...rest: any[]) {
77
72
  return super.emitId(eventName, "^^noId", ...rest);
78
73
  }
79
74
 
80
75
  off(eventName: string, id: string, listener?: EventListenerCallback): this;
81
76
  off(eventName: string, listener?: EventListenerCallback): this;
82
77
  off(eventName: string): this;
83
- off(eventName: string, ...rest: any[]) {
78
+ off (eventName: string, ...rest: any[]) {
84
79
  let id = rest[0];
85
80
  let func = rest[1];
86
81
 
@@ -118,22 +113,22 @@ describe("Emitter", () => {
118
113
 
119
114
  assert.strictEqual(
120
115
  !myClass._eventListeners?.moo ||
121
- !myClass._eventListeners?.moo["testId"] ||
122
- (myClass._eventListeners?.moo["testId"].length as number) === 0,
116
+ !myClass._eventListeners?.moo["testId"] ||
117
+ (myClass._eventListeners?.moo["testId"].length as number) === 0,
123
118
  true,
124
119
  "Listeners all removed from event"
125
120
  );
126
121
  assert.strictEqual(
127
122
  myClass._eventListeners?.moo &&
128
- myClass._eventListeners?.moo["^^noId"] &&
129
- myClass._eventListeners?.moo["^^noId"].length === 1,
123
+ myClass._eventListeners?.moo["^^noId"] &&
124
+ myClass._eventListeners?.moo["^^noId"].length === 1,
130
125
  true,
131
126
  "Global listener still there"
132
127
  );
133
128
  assert.strictEqual(
134
129
  !myClass._eventListeners?.moo ||
135
- !myClass._eventListeners?.moo["*"] ||
136
- myClass._eventListeners?.moo["*"].length === 0,
130
+ !myClass._eventListeners?.moo["*"] ||
131
+ myClass._eventListeners?.moo["*"].length === 0,
137
132
  true,
138
133
  "Global listener still there"
139
134
  );
@@ -142,8 +137,8 @@ describe("Emitter", () => {
142
137
 
143
138
  assert.strictEqual(
144
139
  !myClass._eventListeners?.moo ||
145
- !myClass._eventListeners?.moo["*"] ||
146
- myClass._eventListeners?.moo["*"].length === 0,
140
+ !myClass._eventListeners?.moo["*"] ||
141
+ myClass._eventListeners?.moo["*"].length === 0,
147
142
  true,
148
143
  "Listeners all removed from event"
149
144
  );
@@ -152,186 +147,187 @@ describe("Emitter", () => {
152
147
 
153
148
  describe("emit()", () => {
154
149
  it("Supports type safe usage", async () => {
155
- interface MyEventsResponses {
156
- post: () => Promise<void>;
157
- person: (name: string, age: number, enabled: boolean) => Promise<string>;
158
- house: (no: number, street: string, postcode: string, enabled: boolean) => void;
159
- }
160
-
161
- const emitter = new Emitter<MyEventsResponses>();
162
- let listenerFiredCount = 0;
163
-
164
- emitter.on("person", (name) => {
165
- return new Promise<string>((resolve) => {
166
- setTimeout(() => {
167
- listenerFiredCount++;
168
- resolve(name);
169
- }, 1000);
170
- });
171
- });
172
-
173
- emitter.on("post", () => {
174
- return new Promise<void>((resolve) => {
175
- setTimeout(() => {
176
- listenerFiredCount++;
177
- resolve();
178
- }, 1000);
179
- });
180
- });
181
-
182
- emitter.on("post", () => {
183
- return new Promise<void>((resolve) => {
184
- setTimeout(() => {
185
- listenerFiredCount++;
186
- resolve();
187
- }, 1000);
188
- });
189
- });
190
-
191
- const time = new Date().getTime();
192
- await Promise.all(emitter.emit("post"));
193
- const delta = new Date().getTime() - time;
194
-
195
- assert.ok(delta > 900, `Delta was not correct, await may not have paused? Delta was: ${delta}`);
196
- assert.ok(
197
- listenerFiredCount === 2,
198
- `listenerFiredCount was not correct, await may not have paused? listenerFiredCount was: ${listenerFiredCount}`
199
- );
150
+ interface MyEventsResponses {
151
+ post: () => Promise<void>;
152
+ person: (name: string, age: number, enabled: boolean) => Promise<string>;
153
+ house: (no: number, street: string, postcode: string, enabled: boolean) => void;
154
+ }
155
+
156
+ const emitter = new Emitter<MyEventsResponses>();
157
+ let listenerFiredCount = 0;
158
+
159
+ emitter.on("person", (name) => {
160
+ return new Promise<string>((resolve) => {
161
+ setTimeout(() => {
162
+ listenerFiredCount++;
163
+ resolve(name);
164
+ }, 1000);
165
+ });
166
+ });
167
+
168
+ emitter.on("post", () => {
169
+ return new Promise<void>((resolve) => {
170
+ setTimeout(() => {
171
+ listenerFiredCount++;
172
+ resolve();
173
+ }, 1000);
174
+ });
175
+ });
176
+
177
+ emitter.on("post", () => {
178
+ return new Promise<void>((resolve) => {
179
+ setTimeout(() => {
180
+ listenerFiredCount++;
181
+ resolve();
182
+ }, 1000);
183
+ });
184
+ });
185
+
186
+ const time = new Date().getTime();
187
+ await Promise.all(emitter.emit("post"));
188
+ const delta = new Date().getTime() - time;
189
+
190
+ assert.ok(delta > 900, `Delta was not correct, await may not have paused? Delta was: ${delta}`);
191
+ assert.ok(
192
+ listenerFiredCount === 2,
193
+ `listenerFiredCount was not correct, await may not have paused? listenerFiredCount was: ${listenerFiredCount}`
194
+ );
200
195
  });
201
196
 
202
197
  it("Supports awaiting async listeners", async () => {
203
- interface TestEvents {
204
- foo: () => Promise<void>;
205
- }
206
-
207
- const emitter = new Emitter<EmitterEventsInterface<TestEvents>>();
208
- let listenerFiredCount = 0;
209
-
210
- emitter.on("foo", async () => {
211
- return new Promise<void>((resolve) => {
212
- setTimeout(() => {
213
- listenerFiredCount++;
214
- resolve();
215
- }, 1000);
216
- });
217
- });
218
-
219
- emitter.on("foo", async () => {
220
- return new Promise<void>((resolve) => {
221
- setTimeout(() => {
222
- listenerFiredCount++;
223
- resolve();
224
- }, 1000);
225
- });
226
- });
227
-
228
- const time = new Date().getTime();
229
- await Promise.all(emitter.emit("foo"));
230
- const delta = new Date().getTime() - time;
231
-
232
- assert.ok(delta > 900, "Delta was not correct, await may not have paused?");
198
+ interface TestEvents {
199
+ foo: () => Promise<void>;
200
+ }
201
+
202
+ const emitter = new Emitter<EmitterEventsInterface<TestEvents>>();
203
+ let listenerFiredCount = 0;
204
+
205
+ emitter.on("foo", async () => {
206
+ return new Promise<void>((resolve) => {
207
+ setTimeout(() => {
208
+ listenerFiredCount++;
209
+ resolve();
210
+ }, 1000);
211
+ });
212
+ });
213
+
214
+ emitter.on("foo", async () => {
215
+ return new Promise<void>((resolve) => {
216
+ setTimeout(() => {
217
+ listenerFiredCount++;
218
+ resolve();
219
+ }, 1000);
220
+ });
221
+ });
222
+
223
+ const time = new Date().getTime();
224
+ await Promise.all(emitter.emit("foo"));
225
+ const delta = new Date().getTime() - time;
226
+
227
+ assert.ok(delta > 900, "Delta was not correct, await may not have paused?");
228
+ assert.strictEqual(listenerFiredCount, 2, "Listener fire count was incorect");
233
229
  });
234
230
 
235
231
  it("Supports awaiting async and non-async listener return data", async () => {
236
- interface MyTestEvents {
237
- foo: () => string | Promise<string>;
238
- }
239
-
240
- const emitter = new Emitter<EmitterEventsInterface<MyTestEvents>>();
241
- let listenerFiredCount = 0;
242
-
243
- emitter.on("foo", () => {
244
- return new Promise<string>((resolve) => {
245
- setTimeout(() => {
246
- listenerFiredCount++;
247
- resolve("Foo1 Return Value");
248
- }, 1000);
249
- });
250
- });
251
-
252
- emitter.on("foo", () => {
253
- return "Foo2 Return Value";
254
- });
255
-
256
- const time = new Date().getTime();
257
- const results: string[] = await Promise.all(emitter.emit("foo"));
258
- const delta = new Date().getTime() - time;
259
-
260
- assert.ok(delta > 900, "Delta was not correct, await may not have paused?");
261
- assert.ok(listenerFiredCount === 1, "listenerFiredCount was not correct, await may not have been used?");
262
- assert.strictEqual(results[0], "Foo1 Return Value", "Return data for foo1 was not correct");
263
- assert.strictEqual(results[1], "Foo2 Return Value", "Return data for foo2 was not correct");
232
+ interface MyTestEvents {
233
+ foo: () => string | Promise<string>;
234
+ }
235
+
236
+ const emitter = new Emitter<EmitterEventsInterface<MyTestEvents>>();
237
+ let listenerFiredCount = 0;
238
+
239
+ emitter.on("foo", () => {
240
+ return new Promise<string>((resolve) => {
241
+ setTimeout(() => {
242
+ listenerFiredCount++;
243
+ resolve("Foo1 Return Value");
244
+ }, 1000);
245
+ });
246
+ });
247
+
248
+ emitter.on("foo", () => {
249
+ return "Foo2 Return Value";
250
+ });
251
+
252
+ const time = new Date().getTime();
253
+ const results: string[] = await Promise.all(emitter.emit("foo"));
254
+ const delta = new Date().getTime() - time;
255
+
256
+ assert.ok(delta > 900, "Delta was not correct, await may not have paused?");
257
+ assert.ok(listenerFiredCount === 1, "listenerFiredCount was not correct, await may not have been used?");
258
+ assert.strictEqual(results[0], "Foo1 Return Value", "Return data for foo1 was not correct");
259
+ assert.strictEqual(results[1], "Foo2 Return Value", "Return data for foo2 was not correct");
264
260
  });
265
261
 
266
262
  it("Supports awaiting async and non-async rpc listener return data", async () => {
267
- interface MyTestEvents {
268
- foo1: () => string | Promise<string>;
269
- foo2: () => string;
270
- }
271
-
272
- const emitter = new Emitter<EmitterEventsInterface<MyTestEvents>>();
273
- let listenerFiredCount = 0;
274
-
275
- emitter.on("foo1", () => {
276
- return new Promise<string>((resolve) => {
277
- setTimeout(() => {
278
- listenerFiredCount++;
279
- resolve("Foo1 Return Value");
280
- }, 1000);
281
- });
282
- });
283
-
284
- emitter.on("foo2", () => {
285
- return "Foo2 Return Value";
286
- });
287
-
288
- const time = new Date().getTime();
289
- const result1 = await emitter.rpc("foo1");
290
- const result2 = emitter.rpc("foo2");
291
- const delta = new Date().getTime() - time;
292
-
293
- assert.ok(delta > 900, "Delta was not correct, await may not have paused?");
294
- assert.ok(listenerFiredCount === 1, "listenerFiredCount was not correct, await may not have been used?");
295
- assert.strictEqual(result1, "Foo1 Return Value", "Return data for foo1 was not correct");
296
- assert.strictEqual(result2, "Foo2 Return Value", "Return data for foo2 was not correct");
263
+ interface MyTestEvents {
264
+ foo1: () => string | Promise<string>;
265
+ foo2: () => string;
266
+ }
267
+
268
+ const emitter = new Emitter<EmitterEventsInterface<MyTestEvents>>();
269
+ let listenerFiredCount = 0;
270
+
271
+ emitter.on("foo1", () => {
272
+ return new Promise<string>((resolve) => {
273
+ setTimeout(() => {
274
+ listenerFiredCount++;
275
+ resolve("Foo1 Return Value");
276
+ }, 1000);
277
+ });
278
+ });
279
+
280
+ emitter.on("foo2", () => {
281
+ return "Foo2 Return Value";
282
+ });
283
+
284
+ const time = new Date().getTime();
285
+ const result1 = await emitter.rpc("foo1");
286
+ const result2 = emitter.rpc("foo2");
287
+ const delta = new Date().getTime() - time;
288
+
289
+ assert.ok(delta > 900, "Delta was not correct, await may not have paused?");
290
+ assert.ok(listenerFiredCount === 1, "listenerFiredCount was not correct, await may not have been used?");
291
+ assert.strictEqual(result1, "Foo1 Return Value", "Return data for foo1 was not correct");
292
+ assert.strictEqual(result2, "Foo2 Return Value", "Return data for foo2 was not correct");
297
293
  });
298
294
 
299
295
  it("Supports responding with a cancellation signal", async () => {
300
- interface MyTestEvents {
301
- foo: () => string | ListenerReturnFlag;
302
- }
296
+ interface MyTestEvents {
297
+ foo: () => string | ListenerReturnFlag;
298
+ }
303
299
 
304
- const emitter = new Emitter<EmitterEventsInterface<MyTestEvents>>();
305
- let listenerFiredCount = 0;
300
+ const emitter = new Emitter<EmitterEventsInterface<MyTestEvents>>();
301
+ let listenerFiredCount = 0;
306
302
 
307
- emitter.on("foo", () => {
308
- listenerFiredCount++;
309
- return "Foo1 Return Value";
310
- });
303
+ emitter.on("foo", () => {
304
+ listenerFiredCount++;
305
+ return "Foo1 Return Value";
306
+ });
311
307
 
312
- emitter.on("foo", () => {
313
- listenerFiredCount++;
308
+ emitter.on("foo", () => {
309
+ listenerFiredCount++;
314
310
 
315
- // This listener will respond with a cancellation, this should terminate further listener calls
316
- return ListenerReturnFlag.cancel;
317
- });
311
+ // This listener will respond with a cancellation, this should terminate further listener calls
312
+ return ListenerReturnFlag.cancel;
313
+ });
318
314
 
319
- emitter.on("foo", () => {
320
- listenerFiredCount++;
321
- return "Foo3 Return Value";
322
- });
315
+ emitter.on("foo", () => {
316
+ listenerFiredCount++;
317
+ return "Foo3 Return Value";
318
+ });
323
319
 
324
- emitter.on("foo", () => {
325
- listenerFiredCount++;
326
- return "Foo4 Return Value";
327
- });
320
+ emitter.on("foo", () => {
321
+ listenerFiredCount++;
322
+ return "Foo4 Return Value";
323
+ });
328
324
 
329
- const results = emitter.emit("foo");
325
+ const results = emitter.emit("foo");
330
326
 
331
- assert.ok(listenerFiredCount === 2, "listenerFiredCount was not correct, await may not have been used?");
332
- assert.strictEqual(results[0], "Foo1 Return Value", "Return data should be a cancel flag");
333
- assert.strictEqual(results[1], ListenerReturnFlag.cancel, "Return data should be a cancel flag");
334
- assert.ok(emitter.didCancel(results), "didCancel should detect a cancel flag");
327
+ assert.ok(listenerFiredCount === 2, "listenerFiredCount was not correct, await may not have been used?");
328
+ assert.strictEqual(results[0], "Foo1 Return Value", "Return data should be a cancel flag");
329
+ assert.strictEqual(results[1], ListenerReturnFlag.cancel, "Return data should be a cancel flag");
330
+ assert.ok(emitter.didCancel(results), "didCancel should detect a cancel flag");
335
331
  });
336
332
  });
337
333
 
@@ -354,8 +350,8 @@ describe("Emitter", () => {
354
350
 
355
351
  assert.strictEqual(
356
352
  !myClass._eventListeners?.moo ||
357
- (myClass._eventListeners?.moo["*"].length === 0 &&
358
- myClass._eventListeners?.moo["testId"].length === 0),
353
+ (myClass._eventListeners?.moo["*"].length === 0 &&
354
+ myClass._eventListeners?.moo["testId"].length === 0),
359
355
  true,
360
356
  "Listeners all removed from event"
361
357
  );
@@ -450,7 +446,7 @@ describe("Emitter", () => {
450
446
  it("Static emitter will emit when a new listener is added", (resolve) => {
451
447
  class MyClass extends Emitter {}
452
448
 
453
- expect(1);
449
+ expectAssertionCount(1);
454
450
 
455
451
  const myClass = new MyClass();
456
452
  myClass.emitStatic("moo");
@@ -466,7 +462,7 @@ describe("Emitter", () => {
466
462
  it("Removes static emitter", (resolve) => {
467
463
  class MyClass extends Emitter {}
468
464
 
469
- expect(1);
465
+ expectAssertionCount(1);
470
466
 
471
467
  const myClass = new MyClass();
472
468
  myClass.emitStatic("moo");
@@ -491,7 +487,7 @@ describe("Emitter", () => {
491
487
  it("Only fires the last listener added, cancelling all other listeners before it", (resolve) => {
492
488
  class MyClass extends Emitter {}
493
489
 
494
- expect(1);
490
+ expectAssertionCount(1);
495
491
 
496
492
  const myClass = new MyClass();
497
493
  myClass.on("moo", () => {
@@ -516,7 +512,7 @@ describe("Emitter", () => {
516
512
  it("Only fires the last listener added (with id), cancelling all other listeners before it", (resolve) => {
517
513
  class MyClass extends Emitter {}
518
514
 
519
- expect(2);
515
+ expectAssertionCount(2);
520
516
 
521
517
  const myClass = new MyClass();
522
518
 
@@ -575,15 +571,15 @@ describe("Emitter", () => {
575
571
 
576
572
  assert.strictEqual(
577
573
  !myClass._eventListeners?.moo ||
578
- !myClass._eventListeners?.moo["testId"] ||
579
- myClass._eventListeners?.moo["testId"].length,
574
+ !myClass._eventListeners?.moo["testId"] ||
575
+ myClass._eventListeners?.moo["testId"].length,
580
576
  true,
581
577
  "Listeners all removed from event"
582
578
  );
583
579
  assert.strictEqual(
584
580
  myClass._eventListeners?.moo &&
585
- myClass._eventListeners?.moo["*"] &&
586
- myClass._eventListeners?.moo["*"].length === 1,
581
+ myClass._eventListeners?.moo["*"] &&
582
+ myClass._eventListeners?.moo["*"].length === 1,
587
583
  true,
588
584
  "Global listener still there"
589
585
  );
@@ -592,11 +588,63 @@ describe("Emitter", () => {
592
588
 
593
589
  assert.strictEqual(
594
590
  !myClass._eventListeners?.moo ||
595
- !myClass._eventListeners?.moo["*"] ||
596
- myClass._eventListeners?.moo["*"].length === 0,
591
+ !myClass._eventListeners?.moo["*"] ||
592
+ myClass._eventListeners?.moo["*"].length === 0,
597
593
  true,
598
594
  "Listeners all removed from event"
599
595
  );
600
596
  });
601
597
  });
598
+
599
+ describe("Global listener functionality", () => {
600
+ it("Listens for any event emitted and fires the listener with the onAny() function", () => {
601
+ const emitter = new Emitter();
602
+
603
+ const spy = jest.fn();
604
+
605
+ emitter.onAny(spy);
606
+
607
+ emitter.emit("someEvent", "someArg1", true, false);
608
+
609
+ expect(spy).toHaveBeenCalledWith("someEvent", "someArg1", true, false);
610
+ });
611
+
612
+ it(`Listens for any event emitted and fires the listener with the on("*") function`, () => {
613
+ const emitter = new Emitter();
614
+
615
+ const spy = jest.fn();
616
+
617
+ emitter.on("*", spy);
618
+
619
+ emitter.emit("someEvent", "someArg1", true, false);
620
+
621
+ expect(spy).toHaveBeenCalledWith("someEvent", "someArg1", true, false);
622
+ });
623
+
624
+ it(`Cancels an event listener for any event emitted with the offAny() function`, () => {
625
+ const emitter = new Emitter();
626
+
627
+ const spy = jest.fn();
628
+
629
+ emitter.on("*", spy);
630
+ emitter.offAny(spy);
631
+
632
+ emitter.emit("someEvent", "someArg1", true, false);
633
+
634
+ expect(spy).toHaveBeenCalledTimes(0);
635
+ });
636
+
637
+ it(`Cancels an event listener for any event emitted with the off("*") function`, () => {
638
+ const emitter = new Emitter();
639
+
640
+ const spy = jest.fn();
641
+
642
+ emitter.on("*", spy);
643
+ emitter.off("*", spy);
644
+
645
+ emitter.emit("someEvent", "someArg1", true, false);
646
+
647
+ expect(spy).toHaveBeenCalledTimes(0);
648
+ });
649
+ });
602
650
  });
package/.editorconfig DELETED
@@ -1,11 +0,0 @@
1
- # EditorConfig is awesome: http://EditorConfig.org
2
-
3
- # top-most EditorConfig file
4
- root = true
5
-
6
- # Unix-style newlines with a newline ending every file
7
- [*]
8
- end_of_line = lf
9
- insert_final_newline = false
10
- indent_style = tab
11
- indent_size = 4
File without changes