-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore: dispatch all events to EventBus #445
Changes from all commits
2ff2a9a
b765501
59ad827
8975c04
a3c7c78
6bb67e8
9523320
751fc6e
22a604a
15eb2f3
ebe415e
269eb35
75a5f68
16f9cdf
a6be092
1bdd317
df7aeed
d6a9497
202a919
90fab11
aa7513f
7548383
8cda240
0c0d73c
a4132cc
a54c76c
8400db0
b17af20
bf194e7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
export type Subscriber = (message: any) => void; | ||
export enum Topic { | ||
EVENT = 'event' | ||
} | ||
|
||
/** A topic-based event bus to facilitate communication between plugins */ | ||
export default class EventBus<T = Topic> { | ||
// map<topic, subscriber> | ||
private subscribers = new Map<T, Subscriber[]>(); | ||
|
||
subscribe(topic: T, subscriber: Subscriber): void { | ||
const list = this.subscribers.get(topic) ?? []; | ||
if (list.length === 0) { | ||
this.subscribers.set(topic, list); | ||
} | ||
list.push(subscriber); | ||
} | ||
|
||
unsubscribe(topic: T, subscriber: Subscriber) { | ||
const list = this.subscribers.get(topic); | ||
if (list) { | ||
for (let i = 0; i < list.length; i++) { | ||
if (list[i] === subscriber) { | ||
list.splice(i, 1); | ||
return true; | ||
} | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
dispatch(topic: T, message: any): void { | ||
const list = this.subscribers.get(topic); | ||
if (list) { | ||
for (const subscriber of list) { | ||
subscriber(message); | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import EventBus from '../EventBus'; | ||
|
||
export enum MockTopics { | ||
FOOD = 'food', | ||
BOOKS = 'books' | ||
} | ||
describe('EventBus tests', () => { | ||
let eventBus: EventBus<MockTopics>; | ||
const l1 = jest.fn(); | ||
const l2 = jest.fn(); | ||
beforeEach(() => { | ||
eventBus = new EventBus(); | ||
jest.clearAllMocks(); | ||
}); | ||
test('when dispatch is invoked then all listeners are called', async () => { | ||
// init | ||
eventBus.subscribe(MockTopics.FOOD, l1); | ||
eventBus.subscribe(MockTopics.FOOD, l2); | ||
|
||
// run | ||
eventBus.dispatch(MockTopics.FOOD, 'burger'); | ||
|
||
// assert | ||
expect(l1).toHaveBeenCalledWith('burger'); | ||
expect(l2).toHaveBeenCalledWith('burger'); | ||
}); | ||
|
||
test('when subscriber is removed then it is not called', async () => { | ||
// init | ||
eventBus.subscribe(MockTopics.FOOD, l1); | ||
eventBus.subscribe(MockTopics.FOOD, l2); | ||
const removed = eventBus.unsubscribe(MockTopics.FOOD, l2); | ||
|
||
// run | ||
eventBus.dispatch(MockTopics.FOOD, 'burger'); | ||
|
||
// assert | ||
expect(l1).toHaveBeenCalledWith('burger'); | ||
expect(removed).toBe(true); | ||
expect(l2).not.toHaveBeenCalled(); | ||
}); | ||
|
||
test('when subscribed to topic A then does not hear topic B', async () => { | ||
eventBus.subscribe(MockTopics.FOOD, l1); | ||
eventBus.subscribe(MockTopics.BOOKS, l2); | ||
|
||
// run | ||
eventBus.dispatch(MockTopics.FOOD, 'burger'); | ||
|
||
// assert | ||
expect(l2).not.toHaveBeenCalled(); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,9 @@ import { | |
} from '../../utils/http-utils'; | ||
import { advanceTo } from 'jest-date-mock'; | ||
import { | ||
context, | ||
DEFAULT_CONFIG, | ||
getSession, | ||
record, | ||
recordPageView, | ||
xRayOffContext, | ||
|
@@ -73,6 +75,7 @@ describe('FetchPlugin tests', () => { | |
mockFetchWithErrorObject.mockClear(); | ||
mockFetchWithErrorObjectAndStack.mockClear(); | ||
record.mockClear(); | ||
getSession.mockClear(); | ||
}); | ||
|
||
test('when fetch is called then the plugin records the http request/response', async () => { | ||
|
@@ -537,17 +540,9 @@ describe('FetchPlugin tests', () => { | |
logicalServiceName: 'sample.rum.aws.amazon.com', | ||
urlsToInclude: [/aws\.amazon\.com/] | ||
}; | ||
const xRayOnContext: PluginContext = { | ||
applicationId: 'b', | ||
applicationVersion: '1.0', | ||
config: { ...DEFAULT_CONFIG, ...{ enableXRay: true } }, | ||
record, | ||
recordPageView, | ||
getSession | ||
}; | ||
|
||
const context = Object.assign({}, xRayOnContext, { getSession }); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fix unrelated breaking changes There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What was the problem here? |
||
const plugin: FetchPlugin = new FetchPlugin(config); | ||
plugin.load(xRayOnContext); | ||
plugin.load(context); | ||
|
||
// Run | ||
await fetch(URL); | ||
|
@@ -566,17 +561,10 @@ describe('FetchPlugin tests', () => { | |
logicalServiceName: 'sample.rum.aws.amazon.com', | ||
urlsToInclude: [/aws\.amazon\.com/] | ||
}; | ||
const xRayOnContext: PluginContext = { | ||
applicationId: 'b', | ||
applicationVersion: '1.0', | ||
config: { ...DEFAULT_CONFIG, ...{ enableXRay: true } }, | ||
record, | ||
recordPageView, | ||
getSession | ||
}; | ||
const context = Object.assign({}, xRayOnContext, { getSession }); | ||
|
||
const plugin: FetchPlugin = new FetchPlugin(config); | ||
plugin.load(xRayOnContext); | ||
plugin.load(context); | ||
|
||
// Run | ||
await fetch(URL); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -70,18 +70,14 @@ describe('ResourcePlugin tests', () => { | |
test('when recordResourceUrl is false then the resource name is not recorded', async () => { | ||
// Setup | ||
mockRandom(0); // Retain order in shuffle | ||
const context: PluginContext = { | ||
applicationId: 'b', | ||
applicationVersion: '1.0', | ||
config: { ...DEFAULT_CONFIG, recordResourceUrl: false }, | ||
record, | ||
recordPageView, | ||
getSession | ||
}; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fix unrelated breaking changes |
||
const plugin: ResourcePlugin = buildResourcePlugin(); | ||
const mockContext = Object.assign({}, context, { | ||
config: { ...DEFAULT_CONFIG, recordResourceUrl: false } | ||
}); | ||
|
||
// Run | ||
plugin.load(context); | ||
plugin.load(mockContext); | ||
window.dispatchEvent(new Event('load')); | ||
plugin.disable(); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ import { PartialHttpPluginConfig } from '../../utils/http-utils'; | |
import { advanceTo } from 'jest-date-mock'; | ||
import { XhrPlugin } from '../XhrPlugin'; | ||
import { | ||
context as mockContext, | ||
xRayOffContext, | ||
xRayOnContext, | ||
record, | ||
|
@@ -537,14 +538,9 @@ describe('XhrPlugin tests', () => { | |
record: false, | ||
eventCount: 0 | ||
})); | ||
const context: PluginContext = { | ||
applicationId: 'b', | ||
applicationVersion: '1.0', | ||
config: DEFAULT_CONFIG, | ||
record, | ||
recordPageView, | ||
getSession | ||
}; | ||
|
||
const context = { ...mockContext, getSession }; | ||
|
||
const config: PartialHttpPluginConfig = { | ||
logicalServiceName: 'sample.rum.aws.amazon.com', | ||
urlsToInclude: [/response\.json/] | ||
|
@@ -574,14 +570,7 @@ describe('XhrPlugin tests', () => { | |
test('when getSession returns undefined then the plugin does not record a trace', async () => { | ||
// Init | ||
const getSession: jest.MockedFunction<GetSession> = jest.fn(); | ||
const context: PluginContext = { | ||
applicationId: 'b', | ||
applicationVersion: '1.0', | ||
config: { ...DEFAULT_CONFIG, ...{ enableXRay: true } }, | ||
record, | ||
recordPageView, | ||
getSession | ||
}; | ||
const context = { ...mockContext, getSession }; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fix unrelated breaking changes |
||
const config: PartialHttpPluginConfig = { | ||
logicalServiceName: 'sample.rum.aws.amazon.com', | ||
urlsToInclude: [/response\.json/], | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: consider adding test to subscribe to different topics
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added an extra test "when subscribed to topic A then does not hear topic B"