Skip to content

Commit

Permalink
test: Create tool for mocking event listeners
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasEng committed Jan 14, 2025
1 parent a514966 commit 2dfefe6
Show file tree
Hide file tree
Showing 2 changed files with 221 additions and 0 deletions.
163 changes: 163 additions & 0 deletions frontend/packages/process-editor/test/EventListeners.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import { EventListeners } from './EventListeners';

describe('EventListeners', () => {
describe('add', () => {
it('Adds a listener to the given event', () => {
const eventListeners = new EventListeners();
const fun = jest.fn();
const eventName = 'event';

eventListeners.add(eventName, fun);
eventListeners.triggerEvent(eventName);

expect(fun).toHaveBeenCalledTimes(1);
});

it('Supports adding multiple listeners to the same event', () => {
const eventListeners = new EventListeners();
const fun1 = jest.fn();
const fun2 = jest.fn();
const eventName = 'event';

eventListeners.add(eventName, fun1);
eventListeners.add(eventName, fun2);
eventListeners.triggerEvent(eventName);

expect(fun1).toHaveBeenCalledTimes(1);
expect(fun2).toHaveBeenCalledTimes(1);
});

it('Supports adding listeners to multiple events', () => {
const eventListeners = new EventListeners();
const event1Fun = jest.fn();
const event2Fun = jest.fn();
const event1Name = 'event1';
const event2Name = 'event2';

eventListeners.add(event1Name, event1Fun);
eventListeners.add(event2Name, event2Fun);
eventListeners.triggerEvent(event1Name);
eventListeners.triggerEvent(event2Name);

expect(event1Fun).toHaveBeenCalledTimes(1);
expect(event2Fun).toHaveBeenCalledTimes(1);
});
});

describe('remove', () => {
it('Removes the given function from the given event listener', () => {
const eventListeners = new EventListeners();
const fun = jest.fn();
const eventName = 'event';
eventListeners.add(eventName, fun);

eventListeners.remove(eventName, fun);
eventListeners.triggerEvent(eventName);

expect(fun).not.toHaveBeenCalled();
});

it('Does not remove other functions than the given one', () => {
const eventListeners = new EventListeners();
const funToRemove = jest.fn();
const funOnSameEvent = jest.fn();
const funOnAnotherEvent = jest.fn();
const eventOfInterestName = 'event.of.interest';
const anotherEventName = 'another.event';
eventListeners.add(eventOfInterestName, funToRemove);
eventListeners.add(eventOfInterestName, funOnSameEvent);
eventListeners.add(anotherEventName, funOnAnotherEvent);

eventListeners.remove(eventOfInterestName, funToRemove);
eventListeners.triggerEvent(eventOfInterestName);
eventListeners.triggerEvent(anotherEventName);

expect(funOnSameEvent).toHaveBeenCalled();
expect(funOnAnotherEvent).toHaveBeenCalled();
expect(funToRemove).not.toHaveBeenCalled();
});
});

describe('triggerEvent', () => {
it('Calls all the functions added to the given event listener with correct parameters', () => {
const eventListeners = new EventListeners();
const fun1 = jest.fn();
const fun2 = jest.fn();
const eventName = 'event';
eventListeners.add(eventName, fun1);
eventListeners.add(eventName, fun2);
const param = 'test';

eventListeners.triggerEvent(eventName, param);

expect(fun1).toHaveBeenCalledTimes(1);
expect(fun1).toHaveBeenCalledWith(param);
expect(fun2).toHaveBeenCalledTimes(1);
expect(fun2).toHaveBeenCalledWith(param);
});

it('Supports functions with multiple parameters', () => {
const eventListeners = new EventListeners();
const fun = jest.fn();
const eventName = 'event';
eventListeners.add(eventName, fun);
const param1 = 'test';
const param2 = 1;
const param3 = true;

eventListeners.triggerEvent(eventName, param1, param2, param3);

expect(fun).toHaveBeenCalledTimes(1);
expect(fun).toHaveBeenCalledWith(param1, param2, param3);
});

it('Supports functions with no parameters', () => {
const eventListeners = new EventListeners();
const fun = jest.fn();
const eventName = 'event';
eventListeners.add(eventName, fun);

eventListeners.triggerEvent(eventName);

expect(fun).toHaveBeenCalledTimes(1);
expect(fun).toHaveBeenCalledWith();
});

it('Does not call functions on other listeners than the given one', () => {
const eventListeners = new EventListeners();
const funOfInterest = jest.fn();
const funOnAnotherEvent = jest.fn();
const eventOfInterestName = 'event.of.interest';
const anotherEventName = 'another.event';
eventListeners.add(eventOfInterestName, funOfInterest);
eventListeners.add(anotherEventName, funOnAnotherEvent);

eventListeners.triggerEvent(eventOfInterestName);

expect(funOnAnotherEvent).not.toHaveBeenCalled();
expect(funOfInterest).toHaveBeenCalled();
});
});

describe('clear', () => {
it('Removes all listeners', () => {
const eventListeners = new EventListeners();
const event1Fun1 = jest.fn();
const event1Fun2 = jest.fn();
const event2Fun = jest.fn();
const event1Name = 'event1';
const event2Name = 'event2';
eventListeners.add(event1Name, event1Fun1);
eventListeners.add(event1Name, event1Fun2);
eventListeners.add(event2Name, event2Fun);

eventListeners.clear();
eventListeners.triggerEvent(event1Name);
eventListeners.triggerEvent(event2Name);

expect(event1Fun1).not.toHaveBeenCalled();
expect(event1Fun2).not.toHaveBeenCalled();
expect(event2Fun).not.toHaveBeenCalled();
});
});
});
58 changes: 58 additions & 0 deletions frontend/packages/process-editor/test/EventListeners.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { ArrayUtils } from '@studio/pure-functions';

export class EventListeners {
private list: Map<string, Function[]>;

constructor() {
this.list = new Map<string, Function[]>();
}

triggerEvent(eventName: string, ...params: any[]): void {
if (this.has(eventName)) {
const functions = this.get(eventName);
functions.forEach((fun) => fun(...params));
}
}

add(eventName: string, callback: Function): void {
if (this.has(eventName)) this.addListenerToCurrentList(eventName, callback);
else this.createNewListenerList(eventName, [callback]);
}

private addListenerToCurrentList(eventName: string, callback: Function): void {
const currentListeners = this.get(eventName);
this.set(eventName, [...currentListeners, callback]);
}

private createNewListenerList(eventName: string, callbacks: Function[]): void {
this.set(eventName, callbacks);
}

remove(eventName: string, callback: Function): void {
if (this.has(eventName)) {
this.removeListener(eventName, callback);
}
}

private removeListener(eventName: string, callback: Function): void {
const currentList = this.get(eventName);
const newList = ArrayUtils.removeItemByValue<Function>(currentList, callback);
this.set(eventName, newList);
}

private has(eventName: string): boolean {
return this.list.has(eventName);
}

private get(eventName: string): Function[] | undefined {
return this.list.get(eventName);
}

private set(eventName: string, callbacks: Function[]): Map<string, Function[]> {
return this.list.set(eventName, callbacks);
}

clear(): void {
return this.list.clear();
}
}

0 comments on commit 2dfefe6

Please sign in to comment.