Skip to content

Commit

Permalink
fix(event-bus): subscribe method takes the event class as input
Browse files Browse the repository at this point in the history
  • Loading branch information
gtoselli committed Mar 9, 2024
1 parent f895930 commit b57a0dd
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 43 deletions.
5 changes: 4 additions & 1 deletion src/event-bus/event-bus.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ export type IEvent<T> = {
payload: T;
};

export type EventClass<E extends IEvent<unknown>> = { new (payload: unknown): E };

This comment has been minimized.

Copy link
@lucagiove

lucagiove Mar 11, 2024

Contributor

@gtoselli I don't understand the point of having an Interface for the class.
The class is compatible with IEvent, no?

This comment has been minimized.

Copy link
@gtoselli

gtoselli Mar 12, 2024

Author Contributor

@lucagiove this interface stays for "the class constructor" and not a "class instance"

This comment has been minimized.

Copy link
@lucagiove

lucagiove Mar 12, 2024

Contributor

Yep I understood later on.
I added a different comment.
For a change suggestion.


export interface IEventHandler<E extends IEvent<unknown>> {
handle: (event: E) => Promise<void>;
}

export interface IEventBus {
subscribe<E extends IEvent<unknown>>(handler: IEventHandler<E>, event: E): void;
subscribe<E extends IEvent<unknown>>(handler: IEventHandler<E>, event: EventClass<E>): void;

publish<E extends IEvent<unknown>>(event: E): Promise<void>;
}
86 changes: 46 additions & 40 deletions src/event-bus/local-event-bus.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,16 @@ describe('LocalEventBus', () => {
});

describe('Given one subscribed handler to foo event', () => {
let handler1Mock: jest.Mock;
const handler1Mock = jest.fn();

class FooEventHandler {
async handle(event: FooEvent) {
await handler1Mock(event);
}
}

beforeEach(() => {
handler1Mock = jest.fn();
eventBus.subscribe(
{
handle: handler1Mock,
},
FooEvent,
);
eventBus.subscribe(new FooEventHandler(), FooEvent);
});

describe('When publish a foo event', () => {
Expand All @@ -65,15 +66,16 @@ describe('LocalEventBus', () => {
});

describe('Given another subscribed handler to foo event', () => {
let handler2Mock: jest.Mock;
const handler2Mock = jest.fn();

class FooEventHandler2 {
async handle(event: FooEvent) {
await handler2Mock(event);
}
}

beforeEach(() => {
handler2Mock = jest.fn();
eventBus.subscribe(
{
handle: handler2Mock,
},
FooEvent,
);
eventBus.subscribe(new FooEventHandler2(), FooEvent);
});

describe('When publish event', () => {
Expand All @@ -88,15 +90,16 @@ describe('LocalEventBus', () => {
});

describe('Given a handler subscribed for bar event', () => {
let handler3Mock: jest.Mock;
const handler3Mock = jest.fn();

class BarEventHandler {
async handle(event: BarEvent) {
await handler3Mock(event);
}
}

beforeEach(() => {
handler3Mock = jest.fn();
eventBus.subscribe(
{
handle: handler3Mock,
},
BarEvent,
);
eventBus.subscribe(new BarEventHandler(), BarEvent);
});

describe('When publish FooEvent', () => {
Expand All @@ -122,24 +125,27 @@ describe('LocalEventBus', () => {
});

describe('Given two subscribed handlers (with one that fail) for foo event', () => {
let handlerOkMock: jest.Mock;
let handlerKoMock: jest.Mock;
const handlerOkMock = jest.fn();
const handlerKoMock = jest.fn();

class FooEventHandlerOk {
async handle(event: FooEvent) {
await handlerOkMock(event);
}
}

class FooEventHandlerKo {
async handle(event: FooEvent) {
await handlerKoMock(event);
throw new Error('ko');
}
}

beforeEach(() => {
handlerOkMock = jest.fn().mockResolvedValue('ok');
handlerKoMock = jest.fn().mockRejectedValue(new Error('ko'));
eventBus.subscribe(
{
handle: handlerOkMock,
},
FooEvent,
);
eventBus.subscribe(
{
handle: handlerKoMock,
},
FooEvent,
);
handlerOkMock.mockResolvedValue('ok');
handlerKoMock.mockRejectedValue(new Error('ko'));
eventBus.subscribe(new FooEventHandlerOk(), FooEvent);
eventBus.subscribe(new FooEventHandlerKo(), FooEvent);
});

describe('When publish event', () => {
Expand Down
5 changes: 3 additions & 2 deletions src/event-bus/local-event-bus.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { ILogger } from '../logger';
import { IEvent, IEventBus, IEventHandler } from './event-bus.interface';
import { EventClass, IEvent, IEventBus, IEventHandler } from './event-bus.interface';

export class LocalEventBus implements IEventBus {
private handlers: { [key: string]: IEventHandler<IEvent<unknown>>[] } = {};

constructor(private logger: ILogger) {}

public subscribe<T extends IEvent<unknown>>(handler: IEventHandler<T>, event: T): void {
public subscribe<T extends IEvent<unknown>>(handler: IEventHandler<T>, event: EventClass<T>): void {
if (!this.handlers[event.name]) this.handlers[event.name] = [];
this.handlers[event.name].push(handler);
}

public async publish<T extends IEvent<unknown>>(event: T): Promise<void> {
const handlers = this.handlers[event.name] as IEventHandler<T>[];
if (!handlers || !handlers.length) {
Expand Down

0 comments on commit b57a0dd

Please sign in to comment.