Skip to content

Commit f5b01fd

Browse files
authored
fix: makeEventFunctions take an array of parameters (#2186)
- Previously every emit required exactly one parameter, which is not the case - Allow zero or more parameters
1 parent d409e96 commit f5b01fd

3 files changed

Lines changed: 113 additions & 45 deletions

File tree

packages/dashboard/src/PanelEvent.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export const {
7676
listen: listenForPanelOpen,
7777
emit: emitPanelOpen,
7878
useListener: usePanelOpenListener,
79-
} = makeEventFunctions<PanelOpenEventDetail>(PanelEvent.OPEN);
79+
} = makeEventFunctions<[detail: PanelOpenEventDetail]>(PanelEvent.OPEN);
8080

8181
// TODO (#2147): Add the rest of the event functions here. Need to create the correct types for all of them.
8282

packages/golden-layout/src/utils/EventUtils.test.ts

Lines changed: 83 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ describe('EventUtils', () => {
4545

4646
it('makeEmitFunction', () => {
4747
const event = 'test';
48-
const emit = makeEmitFunction(event);
48+
const emit = makeEmitFunction<unknown>(event);
4949
const payload = { test: 'test' };
5050
emit(eventEmitter, payload);
5151
expect(eventEmitter.emit).toHaveBeenCalledWith(event, payload);
@@ -109,30 +109,93 @@ describe('EventUtils', () => {
109109
});
110110

111111
describe('makeEventFunctions', () => {
112-
const event = 'test';
113-
const { listen, emit, useListener } = makeEventFunctions(event);
114-
const handler = jest.fn();
112+
describe('makeEventFunctions without payload', () => {
113+
const event = 'test';
114+
const { listen, emit, useListener } = makeEventFunctions(event);
115+
const handler = jest.fn();
115116

116-
it('listen', () => {
117-
listen(eventEmitter, handler);
118-
expect(eventEmitter.on).toHaveBeenCalledWith(event, handler);
119-
expect(eventEmitter.off).not.toHaveBeenCalled();
117+
it('listen', () => {
118+
listen(eventEmitter, handler);
119+
expect(eventEmitter.on).toHaveBeenCalledWith(event, handler);
120+
expect(eventEmitter.off).not.toHaveBeenCalled();
121+
});
122+
123+
it('emit', () => {
124+
emit(eventEmitter);
125+
expect(eventEmitter.emit).toHaveBeenCalledWith(event);
126+
});
127+
128+
it('useListener', () => {
129+
const { unmount } = renderHook(() =>
130+
useListener(eventEmitter, handler)
131+
);
132+
expect(eventEmitter.on).toHaveBeenCalledWith(event, handler);
133+
expect(eventEmitter.off).not.toHaveBeenCalled();
134+
jest.clearAllMocks();
135+
unmount();
136+
expect(eventEmitter.on).not.toHaveBeenCalledWith(event, handler);
137+
expect(eventEmitter.off).toHaveBeenCalledWith(event, handler);
138+
});
120139
});
140+
describe('makeEventFunctions with payload', () => {
141+
type Payload = { test: string };
142+
const event = 'test';
143+
const { listen, emit, useListener } = makeEventFunctions<Payload>(event);
144+
const handler = jest.fn();
145+
146+
it('listen', () => {
147+
listen(eventEmitter, handler);
148+
expect(eventEmitter.on).toHaveBeenCalledWith(event, handler);
149+
expect(eventEmitter.off).not.toHaveBeenCalled();
150+
});
151+
152+
it('emit', () => {
153+
const payload: Payload = { test: 'test' };
154+
emit(eventEmitter, payload);
155+
expect(eventEmitter.emit).toHaveBeenCalledWith(event, payload);
156+
});
121157

122-
it('emit', () => {
123-
const payload = { test: 'test' };
124-
emit(eventEmitter, payload);
125-
expect(eventEmitter.emit).toHaveBeenCalledWith(event, payload);
158+
it('useListener', () => {
159+
const { unmount } = renderHook(() =>
160+
useListener(eventEmitter, handler)
161+
);
162+
expect(eventEmitter.on).toHaveBeenCalledWith(event, handler);
163+
expect(eventEmitter.off).not.toHaveBeenCalled();
164+
jest.clearAllMocks();
165+
unmount();
166+
expect(eventEmitter.on).not.toHaveBeenCalledWith(event, handler);
167+
expect(eventEmitter.off).toHaveBeenCalledWith(event, handler);
168+
});
126169
});
170+
describe('makeEventFunctions with multiple parameters', () => {
171+
type Payload = [number, string];
172+
const event = 'test';
173+
const { listen, emit, useListener } = makeEventFunctions<Payload>(event);
174+
const handler = jest.fn();
127175

128-
it('useListener', () => {
129-
const { unmount } = renderHook(() => useListener(eventEmitter, handler));
130-
expect(eventEmitter.on).toHaveBeenCalledWith(event, handler);
131-
expect(eventEmitter.off).not.toHaveBeenCalled();
132-
jest.clearAllMocks();
133-
unmount();
134-
expect(eventEmitter.on).not.toHaveBeenCalledWith(event, handler);
135-
expect(eventEmitter.off).toHaveBeenCalledWith(event, handler);
176+
it('listen', () => {
177+
listen(eventEmitter, handler);
178+
expect(eventEmitter.on).toHaveBeenCalledWith(event, handler);
179+
expect(eventEmitter.off).not.toHaveBeenCalled();
180+
});
181+
182+
it('emit', () => {
183+
const payload: Payload = [1, 'test'];
184+
emit(eventEmitter, ...payload);
185+
expect(eventEmitter.emit).toHaveBeenCalledWith(event, ...payload);
186+
});
187+
188+
it('useListener', () => {
189+
const { unmount } = renderHook(() =>
190+
useListener(eventEmitter, handler)
191+
);
192+
expect(eventEmitter.on).toHaveBeenCalledWith(event, handler);
193+
expect(eventEmitter.off).not.toHaveBeenCalled();
194+
jest.clearAllMocks();
195+
unmount();
196+
expect(eventEmitter.on).not.toHaveBeenCalledWith(event, handler);
197+
expect(eventEmitter.off).toHaveBeenCalledWith(event, handler);
198+
});
136199
});
137200
});
138201
});
Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
1-
import EventEmitter from './EventEmitter';
21
import { useEffect } from 'react';
2+
import EventEmitter from './EventEmitter';
33

4+
type AsArray<P> = P extends unknown[] ? P : [P];
5+
6+
export type EventHandlerFunction<P = []> = (...parameters: AsArray<P>) => void;
47
export type EventListenerRemover = () => void;
5-
export type EventListenFunction<TPayload = unknown> = (
8+
export type EventListenFunction<TParameters = []> = (
69
eventEmitter: EventEmitter,
7-
handler: (p: TPayload) => void
10+
handler: EventHandlerFunction<TParameters>
811
) => EventListenerRemover;
912

10-
export type EventEmitFunction<TPayload = unknown> = (
13+
export type EventEmitFunction<TParameters = []> = (
1114
eventEmitter: EventEmitter,
12-
payload: TPayload
15+
...parameters: AsArray<TParameters>
1316
) => void;
1417

15-
export type EventListenerHook<TPayload = unknown> = (
18+
export type EventListenerHook<TParameters = []> = (
1619
eventEmitter: EventEmitter,
17-
handler: (p: TPayload) => void
20+
handler: EventHandlerFunction<TParameters>
1821
) => void;
1922

2023
/**
@@ -24,35 +27,35 @@ export type EventListenerHook<TPayload = unknown> = (
2427
* @param handler The handler to call when the event is emitted
2528
* @returns A function to stop listening for the event
2629
*/
27-
export function listenForEvent<TPayload>(
30+
export function listenForEvent<TParameters = []>(
2831
eventEmitter: EventEmitter,
2932
event: string,
30-
handler: (p: TPayload) => void
33+
handler: EventHandlerFunction<TParameters>
3134
): EventListenerRemover {
3235
eventEmitter.on(event, handler);
3336
return () => {
3437
eventEmitter.off(event, handler);
3538
};
3639
}
3740

38-
export function makeListenFunction<TPayload>(
41+
export function makeListenFunction<TParameters = []>(
3942
event: string
40-
): EventListenFunction<TPayload> {
43+
): EventListenFunction<TParameters> {
4144
return (eventEmitter, handler) =>
4245
listenForEvent(eventEmitter, event, handler);
4346
}
4447

45-
export function makeEmitFunction<TPayload>(
48+
export function makeEmitFunction<TParameters = []>(
4649
event: string
47-
): EventEmitFunction<TPayload> {
48-
return (eventEmitter, payload) => {
49-
eventEmitter.emit(event, payload);
50+
): EventEmitFunction<TParameters> {
51+
return (eventEmitter, ...parameters) => {
52+
eventEmitter.emit(event, ...parameters);
5053
};
5154
}
5255

53-
export function makeUseListenerFunction<TPayload>(
56+
export function makeUseListenerFunction<TParameters = []>(
5457
event: string
55-
): EventListenerHook<TPayload> {
58+
): EventListenerHook<TParameters> {
5659
return (eventEmitter, handler) => {
5760
useEffect(
5861
() => listenForEvent(eventEmitter, event, handler),
@@ -66,14 +69,16 @@ export function makeUseListenerFunction<TPayload>(
6669
* @param event Name of the event to create functions for
6770
* @returns Listener, Emitter, and Hook functions for the event
6871
*/
69-
export function makeEventFunctions<TPayload>(event: string): {
70-
listen: EventListenFunction<TPayload>;
71-
emit: EventEmitFunction<TPayload>;
72-
useListener: EventListenerHook<TPayload>;
72+
export function makeEventFunctions<TParameters = []>(
73+
event: string
74+
): {
75+
listen: EventListenFunction<TParameters>;
76+
emit: EventEmitFunction<TParameters>;
77+
useListener: EventListenerHook<TParameters>;
7378
} {
7479
return {
75-
listen: makeListenFunction<TPayload>(event),
76-
emit: makeEmitFunction<TPayload>(event),
77-
useListener: makeUseListenerFunction<TPayload>(event),
80+
listen: makeListenFunction<TParameters>(event),
81+
emit: makeEmitFunction<TParameters>(event),
82+
useListener: makeUseListenerFunction<TParameters>(event),
7883
};
7984
}

0 commit comments

Comments
 (0)