Skip to content

Commit 6329d4d

Browse files
committed
chore: add tests for the EventClient
1 parent b6cf44d commit 6329d4d

File tree

4 files changed

+240
-12
lines changed

4 files changed

+240
-12
lines changed

packages/event-bus-client/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,8 @@
5151
"test:types": "tsc",
5252
"test:build": "publint --strict",
5353
"build": "vite build"
54+
},
55+
"devDependencies": {
56+
"@tanstack/devtools-event-bus": "workspace:*"
5457
}
55-
}
58+
}

packages/event-bus-client/src/plugin.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ export class EventClient<
2222
> {
2323
#pluginId: TPluginId
2424
#eventTarget: () => EventTarget
25-
2625
#debug: boolean
26+
2727
constructor({
2828
pluginId,
2929
debug = false,
@@ -43,11 +43,6 @@ export class EventClient<
4343
}
4444
}
4545
private getGlobalTarget() {
46-
// CLient event target is the window object
47-
if (typeof window !== 'undefined') {
48-
this.debugLog('Using window as event target')
49-
return window
50-
}
5146
// server one is the global event target
5247
if (
5348
typeof globalThis !== 'undefined' &&
@@ -56,6 +51,12 @@ export class EventClient<
5651
this.debugLog('Using global event target')
5752
return globalThis.__TANSTACK_EVENT_TARGET__
5853
}
54+
// CLient event target is the window object
55+
if (typeof window !== 'undefined') {
56+
this.debugLog('Using window as event target')
57+
58+
return window
59+
}
5960

6061
this.debugLog('Using new EventTarget as fallback')
6162
return new EventTarget()
@@ -86,6 +87,7 @@ export class EventClient<
8687
this.emitEventToBus({
8788
type: `${this.#pluginId}:${eventSuffix}`,
8889
payload,
90+
pluginId: this.#pluginId,
8991
})
9092
}
9193

Lines changed: 223 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,226 @@
1-
import { describe, expect, it } from 'vitest'
1+
import { describe, expect, it, vi } from 'vitest'
2+
import { EventClient } from '../src'
3+
import { ClientEventBus } from '@tanstack/devtools-event-bus/client'
24

3-
describe('devtools', () => {
4-
it('should pass', () => {
5-
expect(true).toBe(true)
5+
// start the client bus for testing
6+
new ClientEventBus().start()
7+
// client bus uses window to dispatch events
8+
const clientBusEmitTarget = window
9+
10+
describe('EventClient', () => {
11+
describe('debug config', () => {
12+
it('should emit logs when debug set to true and have the correct plugin name', () => {
13+
const consoleSpy = vi.spyOn(console, 'log')
14+
new EventClient({
15+
debug: true,
16+
pluginId: 'test',
17+
})
18+
expect(consoleSpy).toHaveBeenCalledWith(
19+
'🌴 [tanstack-devtools:test-plugin]',
20+
' Initializing event subscription for plugin',
21+
'test',
22+
)
23+
})
24+
25+
it("shouldn't emit logs when debug set to false", () => {
26+
const consoleSpy = vi.spyOn(console, 'log')
27+
new EventClient({
28+
debug: false,
29+
pluginId: 'test',
30+
})
31+
expect(consoleSpy).not.toHaveBeenCalled()
32+
})
33+
})
34+
35+
describe('getGlobalTarget', () => {
36+
it('if the global target is set it should re-use it for emitting/listening/removing of events', () => {
37+
const target = new EventTarget()
38+
globalThis.__TANSTACK_EVENT_TARGET__ = target
39+
const client = new EventClient({
40+
debug: false,
41+
pluginId: 'test',
42+
})
43+
const targetEmitSpy = vi.spyOn(target, 'dispatchEvent')
44+
const targetListenSpy = vi.spyOn(target, 'addEventListener')
45+
const targetRemoveSpy = vi.spyOn(target, 'removeEventListener')
46+
const cleanup = client.on('test:event', () => {})
47+
cleanup()
48+
client.emit('test:event', { foo: 'bar' })
49+
expect(targetEmitSpy).toHaveBeenCalledWith(expect.any(Event))
50+
expect(targetListenSpy).toHaveBeenCalledWith(
51+
expect.any(String),
52+
expect.any(Function),
53+
)
54+
expect(targetRemoveSpy).toHaveBeenCalledWith(
55+
expect.any(String),
56+
expect.any(Function),
57+
)
58+
globalThis.__TANSTACK_EVENT_TARGET__ = null
59+
})
60+
61+
it('should use the window object if the globalTarget is not set for emitting/listening/removing of events', () => {
62+
const target = window
63+
const client = new EventClient({
64+
debug: false,
65+
pluginId: 'test',
66+
})
67+
const targetEmitSpy = vi.spyOn(target, 'dispatchEvent')
68+
const targetListenSpy = vi.spyOn(target, 'addEventListener')
69+
const targetRemoveSpy = vi.spyOn(target, 'removeEventListener')
70+
const cleanup = client.on('test:event', () => {})
71+
cleanup()
72+
client.emit('test:event', { foo: 'bar' })
73+
expect(targetEmitSpy).toHaveBeenCalledWith(expect.any(Event))
74+
expect(targetListenSpy).toHaveBeenCalledWith(
75+
expect.any(String),
76+
expect.any(Function),
77+
)
78+
expect(targetRemoveSpy).toHaveBeenCalledWith(
79+
expect.any(String),
80+
expect.any(Function),
81+
)
82+
})
83+
})
84+
85+
describe('on', () => {
86+
it('should register an event with the pluginId (event => test:event)', () => {
87+
const client = new EventClient({
88+
debug: false,
89+
pluginId: 'test',
90+
})
91+
92+
const eventBusSpy = vi.spyOn(clientBusEmitTarget, 'addEventListener')
93+
client.on('event', () => {})
94+
expect(eventBusSpy).toHaveBeenCalledWith(
95+
'test:event',
96+
expect.any(Function),
97+
)
98+
})
99+
it('should register an event listener for the specified event and get events when they are emitted', () => {
100+
const client = new EventClient({
101+
debug: false,
102+
pluginId: 'test',
103+
})
104+
const eventHandler = vi.fn()
105+
const cleanup = client.on('event', eventHandler)
106+
client.emit('event', { foo: 'bar' })
107+
expect(eventHandler).toHaveBeenCalledWith({
108+
type: 'test:event',
109+
payload: { foo: 'bar' },
110+
pluginId: 'test',
111+
})
112+
cleanup()
113+
})
114+
115+
it("shouldn't get an event if unregistered before it comes", () => {
116+
const client = new EventClient({
117+
debug: false,
118+
pluginId: 'test',
119+
})
120+
const eventHandler = vi.fn()
121+
const cleanup = client.on('event', eventHandler)
122+
cleanup()
123+
client.emit('event', { foo: 'bar' })
124+
expect(eventHandler).not.toHaveBeenCalled()
125+
})
126+
127+
it("shouldn't get an event if it's not registered to it", () => {
128+
const client = new EventClient({
129+
debug: false,
130+
pluginId: 'test',
131+
})
132+
const eventHandler = vi.fn()
133+
client.on('event', eventHandler)
134+
client.emit('other_event', { foo: 'bar' })
135+
expect(eventHandler).not.toHaveBeenCalled()
136+
})
137+
})
138+
139+
describe('emit', () => {
140+
it('should emit an event with the correct type and payload to the event bus', () => {
141+
const client = new EventClient({
142+
debug: false,
143+
pluginId: 'test',
144+
})
145+
const eventHandler = vi.fn()
146+
client.on('event', eventHandler)
147+
client.emit('event', { foo: 'bar' })
148+
expect(eventHandler).toHaveBeenCalledWith({
149+
type: 'test:event',
150+
payload: { foo: 'bar' },
151+
pluginId: 'test',
152+
})
153+
})
154+
})
155+
156+
describe('onAll', () => {
157+
it('should listen to all events even if they do not come from the registered client', () => {
158+
const client = new EventClient({
159+
debug: false,
160+
pluginId: 'test',
161+
})
162+
const eventHandler = vi.fn()
163+
client.onAll(eventHandler)
164+
client.emit('event', { foo: 'bar' })
165+
expect(eventHandler).toHaveBeenCalledWith({
166+
type: 'test:event',
167+
payload: { foo: 'bar' },
168+
pluginId: 'test',
169+
})
170+
clientBusEmitTarget.dispatchEvent(
171+
new CustomEvent('tanstack-dispatch-event', {
172+
detail: {
173+
type: 'other-plugin',
174+
payload: { foo: 'bar' },
175+
},
176+
}),
177+
)
178+
179+
expect(eventHandler).lastCalledWith({
180+
type: 'other-plugin',
181+
payload: { foo: 'bar' },
182+
})
183+
})
184+
})
185+
186+
describe('onAllPluginEvents', () => {
187+
it('should listen to all events that come from the plugin', () => {
188+
const client = new EventClient({
189+
debug: false,
190+
pluginId: 'test',
191+
})
192+
const eventHandler = vi.fn()
193+
client.onAllPluginEvents(eventHandler)
194+
client.emit('event', { foo: 'bar' })
195+
client.emit('event2', { foo: 'bar' })
196+
expect(eventHandler).nthCalledWith(1, {
197+
type: 'test:event',
198+
payload: { foo: 'bar' },
199+
pluginId: 'test',
200+
})
201+
expect(eventHandler).nthCalledWith(2, {
202+
type: 'test:event2',
203+
payload: { foo: 'bar' },
204+
pluginId: 'test',
205+
})
206+
})
207+
208+
it('should ignore events that do not come from the plugin', () => {
209+
const client = new EventClient({
210+
debug: false,
211+
pluginId: 'test',
212+
})
213+
const eventHandler = vi.fn()
214+
client.onAllPluginEvents(eventHandler)
215+
clientBusEmitTarget.dispatchEvent(
216+
new CustomEvent('tanstack-dispatch-event', {
217+
detail: {
218+
type: 'other-plugin',
219+
payload: { foo: 'bar' },
220+
},
221+
}),
222+
)
223+
expect(eventHandler).not.toHaveBeenCalled()
224+
})
6225
})
7226
})

pnpm-lock.yaml

Lines changed: 5 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)