Skip to content

Commit

Permalink
feat: add NexoEmitter class and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
drusco committed Jul 3, 2024
1 parent 21ed48a commit 4a0539f
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 7 deletions.
68 changes: 68 additions & 0 deletions src/events/NexoEmitter.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import NexoError from "../errors/NexoError.js";
import NexoEmitter from "../events/NexoEmitter.js";
import NexoEvent from "./NexoEvent.js";

describe("NexoEmitter", () => {
it("Emits the 'error' and 'nx.error' events", () => {
const emitter = new NexoEmitter();
const errorCallback = jest.fn();
const nxErrorCallback = jest.fn();
const errorMessage = "something went wrong";

emitter.on("error", errorCallback);
emitter.on("nx.error", nxErrorCallback);

emitter.on("test", () => {
throw Error(errorMessage);
});

emitter.emit("test", new NexoEvent("test"));

const [errorEvent] = errorCallback.mock.lastCall;
const [nxErrorEvent] = nxErrorCallback.mock.lastCall;

expect(errorCallback).toHaveBeenCalledTimes(1);
expect(nxErrorCallback).toHaveBeenCalledTimes(1);

expect(errorEvent).toBeInstanceOf(Error);
expect(errorEvent.message).toBe(errorMessage);
expect(nxErrorEvent).toBeInstanceOf(NexoEvent);
expect(nxErrorEvent.name).toBe("nx.error");
expect(nxErrorEvent.target).toBe(emitter);
expect(nxErrorEvent.data).toBeInstanceOf(NexoError);
expect(nxErrorEvent.data.message).toBe(errorMessage);
});

it("Emits a NexoEvent with optional arguments", () => {
const emitter = new NexoEmitter();
const callback = jest.fn();
const nexoEvent = new NexoEvent("test");

emitter.on("test", callback);
emitter.on("test", callback);

emitter.emit("test", nexoEvent, true);

const [event, arg] = callback.mock.lastCall;

expect(callback).toHaveBeenCalledTimes(2);
expect(event).toBe(nexoEvent);
expect(event.name).toBe("test");
expect(arg).toBe(true);
});

it("Adds the return value to the events 'returnValue' property", () => {
const emitter = new NexoEmitter();
const nexoEvent = new NexoEvent("test", { cancellable: true });
const returnValue = new Object();

emitter.on("test", (event: NexoEvent) => {
event.preventDefault();
return returnValue;
});

emitter.emit("test", nexoEvent);

expect(nexoEvent.returnValue).toBe(returnValue);
});
});
18 changes: 11 additions & 7 deletions src/events/NexoEmitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,17 @@ class NexoEmitter extends EventEmitter {
): boolean {
const listeners = this.listeners(eventName);

listeners.forEach((listener) => {
const returnValue = listener.call(this, event, ...args);
// ignore non defaultPrevented events
if (event.defaultPrevented === false) return;
// ignore when event.returnValue is set manually
event.returnValue = returnValue;
});
try {
listeners.forEach((listener) => {
const returnValue = listener.call(this, event, ...args);
// ignore non defaultPrevented events
if (event.defaultPrevented === false) return;
// ignore when event.returnValue is set manually
event.returnValue = returnValue;
});
} catch (error) {
this.emit("error", error);
}

return listeners.length > 0;
}
Expand Down

0 comments on commit 4a0539f

Please sign in to comment.