@irrelon/emitter 6.0.0 → 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,14 +1,15 @@
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
  }
@@ -17,7 +18,7 @@ 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,22 +42,16 @@ 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
57
  on (eventName: string, ...rest: any[]): this {
@@ -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,153 +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;
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");
260
+ });
259
261
 
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");
262
+ it("Supports awaiting async and non-async rpc listener return data", async () => {
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");
264
293
  });
265
294
 
266
295
  it("Supports responding with a cancellation signal", async () => {
267
- interface MyTestEvents {
268
- foo: () => string | ListenerReturnFlag;
269
- }
296
+ interface MyTestEvents {
297
+ foo: () => string | ListenerReturnFlag;
298
+ }
270
299
 
271
- const emitter = new Emitter<EmitterEventsInterface<MyTestEvents>>();
272
- let listenerFiredCount = 0;
300
+ const emitter = new Emitter<EmitterEventsInterface<MyTestEvents>>();
301
+ let listenerFiredCount = 0;
273
302
 
274
- emitter.on("foo", () => {
275
- listenerFiredCount++;
276
- return "Foo1 Return Value";
277
- });
303
+ emitter.on("foo", () => {
304
+ listenerFiredCount++;
305
+ return "Foo1 Return Value";
306
+ });
278
307
 
279
- emitter.on("foo", () => {
280
- listenerFiredCount++;
308
+ emitter.on("foo", () => {
309
+ listenerFiredCount++;
281
310
 
282
- // This listener will respond with a cancellation, this should terminate further listener calls
283
- return ListenerReturnFlag.cancel;
284
- });
311
+ // This listener will respond with a cancellation, this should terminate further listener calls
312
+ return ListenerReturnFlag.cancel;
313
+ });
285
314
 
286
- emitter.on("foo", () => {
287
- listenerFiredCount++;
288
- return "Foo3 Return Value";
289
- });
315
+ emitter.on("foo", () => {
316
+ listenerFiredCount++;
317
+ return "Foo3 Return Value";
318
+ });
290
319
 
291
- emitter.on("foo", () => {
292
- listenerFiredCount++;
293
- return "Foo4 Return Value";
294
- });
320
+ emitter.on("foo", () => {
321
+ listenerFiredCount++;
322
+ return "Foo4 Return Value";
323
+ });
295
324
 
296
- const results = emitter.emit("foo");
325
+ const results = emitter.emit("foo");
297
326
 
298
- assert.ok(listenerFiredCount === 2, "listenerFiredCount was not correct, await may not have been used?");
299
- assert.strictEqual(results[0], "Foo1 Return Value", "Return data should be a cancel flag");
300
- assert.strictEqual(results[1], ListenerReturnFlag.cancel, "Return data should be a cancel flag");
301
- 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");
302
331
  });
303
332
  });
304
333
 
@@ -321,8 +350,8 @@ describe("Emitter", () => {
321
350
 
322
351
  assert.strictEqual(
323
352
  !myClass._eventListeners?.moo ||
324
- (myClass._eventListeners?.moo["*"].length === 0 &&
325
- myClass._eventListeners?.moo["testId"].length === 0),
353
+ (myClass._eventListeners?.moo["*"].length === 0 &&
354
+ myClass._eventListeners?.moo["testId"].length === 0),
326
355
  true,
327
356
  "Listeners all removed from event"
328
357
  );
@@ -417,7 +446,7 @@ describe("Emitter", () => {
417
446
  it("Static emitter will emit when a new listener is added", (resolve) => {
418
447
  class MyClass extends Emitter {}
419
448
 
420
- expect(1);
449
+ expectAssertionCount(1);
421
450
 
422
451
  const myClass = new MyClass();
423
452
  myClass.emitStatic("moo");
@@ -433,7 +462,7 @@ describe("Emitter", () => {
433
462
  it("Removes static emitter", (resolve) => {
434
463
  class MyClass extends Emitter {}
435
464
 
436
- expect(1);
465
+ expectAssertionCount(1);
437
466
 
438
467
  const myClass = new MyClass();
439
468
  myClass.emitStatic("moo");
@@ -458,7 +487,7 @@ describe("Emitter", () => {
458
487
  it("Only fires the last listener added, cancelling all other listeners before it", (resolve) => {
459
488
  class MyClass extends Emitter {}
460
489
 
461
- expect(1);
490
+ expectAssertionCount(1);
462
491
 
463
492
  const myClass = new MyClass();
464
493
  myClass.on("moo", () => {
@@ -483,7 +512,7 @@ describe("Emitter", () => {
483
512
  it("Only fires the last listener added (with id), cancelling all other listeners before it", (resolve) => {
484
513
  class MyClass extends Emitter {}
485
514
 
486
- expect(2);
515
+ expectAssertionCount(2);
487
516
 
488
517
  const myClass = new MyClass();
489
518
 
@@ -542,15 +571,15 @@ describe("Emitter", () => {
542
571
 
543
572
  assert.strictEqual(
544
573
  !myClass._eventListeners?.moo ||
545
- !myClass._eventListeners?.moo["testId"] ||
546
- myClass._eventListeners?.moo["testId"].length,
574
+ !myClass._eventListeners?.moo["testId"] ||
575
+ myClass._eventListeners?.moo["testId"].length,
547
576
  true,
548
577
  "Listeners all removed from event"
549
578
  );
550
579
  assert.strictEqual(
551
580
  myClass._eventListeners?.moo &&
552
- myClass._eventListeners?.moo["*"] &&
553
- myClass._eventListeners?.moo["*"].length === 1,
581
+ myClass._eventListeners?.moo["*"] &&
582
+ myClass._eventListeners?.moo["*"].length === 1,
554
583
  true,
555
584
  "Global listener still there"
556
585
  );
@@ -559,11 +588,63 @@ describe("Emitter", () => {
559
588
 
560
589
  assert.strictEqual(
561
590
  !myClass._eventListeners?.moo ||
562
- !myClass._eventListeners?.moo["*"] ||
563
- myClass._eventListeners?.moo["*"].length === 0,
591
+ !myClass._eventListeners?.moo["*"] ||
592
+ myClass._eventListeners?.moo["*"].length === 0,
564
593
  true,
565
594
  "Listeners all removed from event"
566
595
  );
567
596
  });
568
597
  });
569
- });
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
+ });
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