UNPKG

squee

Version:
433 lines (341 loc) 14.6 kB
import { EventEmitter } from "./index"; describe("EventEmitter", () => { describe("on", () => { it("triggers a listener when an event is fired after attaching the listener", () => { // Arrange const emitter = new EventEmitter(); const eventName = "event-name"; const listener = jasmine.createSpy(); emitter.on(eventName, listener); // Act emitter.emit(eventName); // Assert expect(listener).toHaveBeenCalled(); }); it("triggers a listener with args when an event is fired with args", () => { // Arrange const emitter = new EventEmitter(); const eventName = "event-name"; const listener = jasmine.createSpy(); const args = [{}, {}]; emitter.on(eventName, listener); // Act emitter.emit(eventName, ...args); // Assert expect(listener).toHaveBeenCalledWith(...args); }); it("triggers multiple listeners when an event is fired after attaching the listeners", () => { // Arrange const emitter = new EventEmitter(); const eventName = "event-name"; const firstListener = jasmine.createSpy("first"); const secondListener = jasmine.createSpy("second"); const args = [{}, {}]; emitter.on(eventName, firstListener); emitter.on(eventName, secondListener); // Act emitter.emit(eventName, ...args); // Assert expect(firstListener).toHaveBeenCalledWith(...args); expect(secondListener).toHaveBeenCalledWith(...args); }); it("triggers a listener twice when an event is fired after attaching the listener twice", () => { // Arrange const emitter = new EventEmitter(); const eventName = "event-name"; const listener = jasmine.createSpy(); emitter.on(eventName, listener); emitter.on(eventName, listener); // Act emitter.emit(eventName); // Assert expect(listener).toHaveBeenCalledTimes(2); }); it("doesn't trigger a listener when an event is fired before attaching the listener", () => { // Arrange const emitter = new EventEmitter(); const eventName = "event-name"; const listener = jasmine.createSpy(); // Act emitter.emit(eventName); // Assert expect(listener).not.toHaveBeenCalled(); }); it("doesn't trigger a listener after the event is cleared with off", () => { // Arrange const emitter = new EventEmitter(); const eventName = "event-name"; const listener = jasmine.createSpy(); emitter.on(eventName, listener); // Act emitter.off(eventName, listener); emitter.emit(eventName); // Assert expect(listener).not.toHaveBeenCalled(); }); }); describe("onAny", () => { it("adds a listener called on events with the event name and args", () => { // Arrange const emitter = new EventEmitter(); const eventName = "event-name"; const args = [{}, {}]; const listener = jasmine.createSpy(); emitter.onAny(listener); // Act emitter.emit(eventName, ...args); // Assert expect(listener).toHaveBeenCalledWith(eventName, ...args); }); }); describe("onFirst", () => { it("triggers a listener when an event is first fired after attaching the listener", () => { // Arrange const emitter = new EventEmitter(); const eventName = "event-name"; const listener = jasmine.createSpy(); emitter.onFirst(eventName, listener); // Act emitter.emit(eventName); // Assert expect(listener).toHaveBeenCalled(); }); it("triggers multiple listeners when an event is first fired after attaching the listeners", () => { // Arrange const emitter = new EventEmitter(); const eventName = "event-name"; const firstListener = jasmine.createSpy("first"); const secondListener = jasmine.createSpy("second"); const args = [{}, {}]; emitter.onFirst(eventName, firstListener); emitter.onFirst(eventName, secondListener); // Act emitter.emit(eventName, ...args); // Assert expect(firstListener).toHaveBeenCalledWith(...args); expect(secondListener).toHaveBeenCalledWith(...args); }); it("triggers a listener with the first args when an event was already fired and then fired after attaching the listener", () => { // Arrange const emitter = new EventEmitter(); const eventName = "event-name"; const listener = jasmine.createSpy(); const args = [{}, {}]; emitter.emit(eventName, ...args); emitter.onFirst(eventName, listener); // Act emitter.emit(eventName, "bad"); // Assert expect(listener).toHaveBeenCalledWith(...args); }); it("doesn't trigger a listener after the event is cleared with off", () => { // Arrange const emitter = new EventEmitter(); const eventName = "event-name"; const listener = jasmine.createSpy(); emitter.onFirst(eventName, listener); emitter.off(eventName, listener); // Act emitter.emit(eventName); // Assert expect(listener).not.toHaveBeenCalled(); }); it("uses the new first event when the event is cleared with off", () => { // Arrange const emitter = new EventEmitter(); const eventName = "event-name"; const listener = jasmine.createSpy(); const args = [{}, {}]; emitter.emit(eventName, "bad"); emitter.onFirst(eventName, listener); emitter.off(eventName); emitter.onFirst(eventName, listener); // Act emitter.emit(eventName, ...args); // Assert expect(listener).toHaveBeenCalledWith(...args); }); it("uses the original first event when the listener is cleared with off then called again", () => { // Arrange const emitter = new EventEmitter(); const eventName = "event-name"; const listener = jasmine.createSpy(); const args = [{}, {}]; emitter.emit(eventName, ...args); emitter.onFirst(eventName, listener); emitter.off(eventName, listener); emitter.onFirst(eventName, listener); // Act emitter.emit(eventName, "bad"); // Assert expect(listener).toHaveBeenCalledWith(...args); }); }); describe("off", () => { it("clears event listener when the listener is registered multiple times", () => { // Arrange const emitter = new EventEmitter(); const eventName = "event-name"; const listener = jasmine.createSpy(); emitter.on(eventName, listener); emitter.on(eventName, listener); emitter.onFirst(eventName, listener); emitter.onFirst(eventName, listener); // Act emitter.off(eventName, listener); emitter.emit(eventName); // Assert expect(listener).not.toHaveBeenCalled(); }); it("clears just the passed event listener when passed an event name and listener", () => { // Arrange const emitter = new EventEmitter(); const eventName = "event-name"; const permanentListener = jasmine.createSpy(); const temporaryListener = jasmine.createSpy(); emitter.on(eventName, permanentListener); emitter.on(eventName, temporaryListener); // Act emitter.off(eventName, temporaryListener); emitter.emit(eventName); // Assert expect(temporaryListener).not.toHaveBeenCalled(); expect(permanentListener).toHaveBeenCalled(); }); it("clears all event listeners when passed just an event name", () => { // Arrange const emitter = new EventEmitter(); const eventName = "event-name"; const secondListener = jasmine.createSpy("second"); const firstListener = jasmine.createSpy("first"); emitter.on(eventName, secondListener); emitter.on(eventName, firstListener); // Act emitter.off(eventName); emitter.emit(eventName); // Assert expect(firstListener).not.toHaveBeenCalled(); expect(secondListener).not.toHaveBeenCalled(); }); it("clears all events and event listeners when passed nothing", () => { // Arrange const emitter = new EventEmitter(); const firstEventName = "first-event"; const secondEventName = "second-event"; const secondListener = jasmine.createSpy("second"); const firstListener = jasmine.createSpy("first"); emitter.on(firstEventName, secondListener); emitter.on(secondEventName, firstListener); // Act emitter.off(); emitter.emit(firstEventName); emitter.emit(secondEventName); // Assert expect(firstListener).not.toHaveBeenCalled(); expect(secondListener).not.toHaveBeenCalled(); }); it("throws an error when an unregistered listener is passed", () => { // Arrange const emitter = new EventEmitter(); const eventName = "event-name"; // Act const action = (): void => { emitter.off(eventName, jasmine.createSpy()); }; // Assert expect(action).toThrow(`Tried to remove a non-existent listener for event name '${eventName}'.`); }); }); describe("waitFor", () => { it("resolves when the event is fired", async () => { // Arrange const emitter = new EventEmitter(); const eventName = "event-name"; // Act const action = emitter.waitFor(eventName); emitter.emit(eventName); // Assert await action; }); it("resolves with the first passed arg when the event is fired with args", async () => { // Arrange const emitter = new EventEmitter(); const eventName = "event-name"; const arg = {}; // Act const action = emitter.waitFor(eventName); emitter.emit(eventName, arg); // Assert expect(await action).toBe(arg); }); it("resolves with the next fired event if attached after the event was already fired", async () => { // Arrange const emitter = new EventEmitter(); const eventName = "event-name"; const arg = {}; emitter.emit("bad"); // Act const action = emitter.waitFor(eventName); emitter.emit(eventName, arg); // Assert expect(await action).toBe(arg); }); }); describe("waitForFirst", () => { it("resolves when an event is first fired after attaching the listener", async () => { // Arrange const emitter = new EventEmitter(); const eventName = "event-name"; // Act const action = emitter.waitForFirst(eventName); emitter.emit(eventName); // Assert await action; }); it("resolves with the first args object when an event was already fired and then fired after attaching the listener", async () => { // Arrange const emitter = new EventEmitter(); const eventName = "event-name"; const arg = {}; // Act emitter.emit("bad"); const action = emitter.waitForFirst(eventName); emitter.emit(eventName, arg); // Assert expect(await action).toBe(arg); }); it("doesn't (quickly) resolve when the event is fired before registration", async () => { // Arrange const emitter = new EventEmitter(); const eventName = "event-name"; let resolved = false; emitter.emit(eventName); // Act // tslint:disable-next-line no-floating-promises emitter.waitFor(eventName) .then(() => { resolved = true; }); // Assert await Promise.resolve(); expect(resolved).toBe(false); }); it("doesn't (quickly) resolve after the event is cleared with off", async () => { // Arrange const emitter = new EventEmitter(); const eventName = "event-name"; let resolved = false; // Act // tslint:disable-next-line no-floating-promises emitter.waitForFirst(eventName) .then(() => { resolved = true; }); emitter.off(eventName); emitter.emit(eventName); // Assert await Promise.resolve(); expect(resolved).toBe(false); }); }); });