Skip to content

Commit 3f74f82

Browse files
authored
ref(browser): Migrate unit tests from Chai and Karma to Jest (#3965)
1 parent d3ca7a8 commit 3f74f82

15 files changed

+634
-744
lines changed

packages/browser/.eslintrc.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ module.exports = {
2525
'prefer-template': 'off',
2626
'no-unused-expressions': 'off',
2727
'guard-for-in': 'off',
28+
'@typescript-eslint/no-explicit-any': 'off',
29+
'@typescript-eslint/no-non-null-assertion': 'off',
2830
},
2931
},
3032
{

packages/browser/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@
7373
"fix:prettier": "prettier --write \"{src,test}/**/*.ts\"",
7474
"fix:eslint": "eslint . --format stylish --fix",
7575
"test": "run-s test:unit",
76-
"test:unit": "karma start test/unit/karma.conf.js",
77-
"test:unit:watch": "karma start test/unit/karma.conf.js --auto-watch --no-single-run",
76+
"test:unit": "jest --config test/unit/jest.config.js",
77+
"test:unit:watch": "jest --config test/unit/jest.config.js --watch",
7878
"test:integration": "test/integration/run.js",
7979
"test:integration:watch": "test/integration/run.js --watch",
8080
"test:integration:checkbrowsers": "node scripts/checkbrowsers.js",
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
import { expect } from 'chai';
2-
31
import { BrowserBackend } from '../../src/backend';
42

53
let backend: BrowserBackend;
64

75
describe('BrowserBackend', () => {
86
describe('sendEvent()', () => {
9-
it('should use NoopTransport', async () => {
7+
it('should use NoopTransport', () => {
108
backend = new BrowserBackend({});
11-
expect(backend.getTransport().constructor.name).to.equal('NoopTransport');
9+
expect(backend.getTransport().constructor.name).toBe('NoopTransport');
1210
});
1311
});
1412
});

packages/browser/test/unit/index.test.ts

Lines changed: 62 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
import { SDK_VERSION } from '@sentry/core';
2-
import { expect } from 'chai';
3-
import { SinonSpy, spy } from 'sinon';
42

53
import {
64
addBreadcrumb,
@@ -22,13 +20,13 @@ import { SimpleTransport } from './mocks/simpletransport';
2220

2321
const dsn = 'https://[email protected]/4291';
2422

25-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, no-var
23+
// eslint-disable-next-line no-var
2624
declare var global: any;
2725

2826
describe('SentryBrowser', () => {
29-
const beforeSend: SinonSpy<[Event], Event> = spy((event: Event) => event);
27+
const beforeSend = jest.fn();
3028

31-
before(() => {
29+
beforeAll(() => {
3230
init({
3331
beforeSend,
3432
dsn,
@@ -42,15 +40,15 @@ describe('SentryBrowser', () => {
4240

4341
afterEach(() => {
4442
getCurrentHub().popScope();
45-
beforeSend.resetHistory();
43+
beforeSend.mockReset();
4644
});
4745

4846
describe('getContext() / setContext()', () => {
4947
it('should store/load extra', () => {
5048
configureScope((scope: Scope) => {
5149
scope.setExtra('abc', { def: [1] });
5250
});
53-
expect(global.__SENTRY__.hub._stack[1].scope._extra).to.deep.equal({
51+
expect(global.__SENTRY__.hub._stack[1].scope._extra).toEqual({
5452
abc: { def: [1] },
5553
});
5654
});
@@ -59,7 +57,7 @@ describe('SentryBrowser', () => {
5957
configureScope((scope: Scope) => {
6058
scope.setTag('abc', 'def');
6159
});
62-
expect(global.__SENTRY__.hub._stack[1].scope._tags).to.deep.equal({
60+
expect(global.__SENTRY__.hub._stack[1].scope._tags).toEqual({
6361
abc: 'def',
6462
});
6563
});
@@ -68,7 +66,7 @@ describe('SentryBrowser', () => {
6866
configureScope((scope: Scope) => {
6967
scope.setUser({ id: 'def' });
7068
});
71-
expect(global.__SENTRY__.hub._stack[1].scope._user).to.deep.equal({
69+
expect(global.__SENTRY__.hub._stack[1].scope._user).toEqual({
7270
id: 'def',
7371
});
7472
});
@@ -78,7 +76,11 @@ describe('SentryBrowser', () => {
7876
describe('user', () => {
7977
const EX_USER = { email: '[email protected]' };
8078
const client = new BrowserClient({ dsn });
81-
spy(client, 'showReportDialog');
79+
const reportDialogSpy = jest.spyOn(client, 'showReportDialog');
80+
81+
beforeEach(() => {
82+
reportDialogSpy.mockReset();
83+
});
8284

8385
it('uses the user on the scope', () => {
8486
configureScope(scope => {
@@ -88,8 +90,8 @@ describe('SentryBrowser', () => {
8890

8991
showReportDialog();
9092

91-
expect((client.showReportDialog as SinonSpy).called).to.be.true;
92-
expect((client.showReportDialog as SinonSpy).lastCall.args[0].user.email).to.eq(EX_USER.email);
93+
expect(reportDialogSpy).toBeCalled();
94+
expect(reportDialogSpy.mock.calls[0][0]!.user!.email).toBe(EX_USER.email);
9395
});
9496

9597
it('prioritizes options user over scope user', () => {
@@ -101,8 +103,8 @@ describe('SentryBrowser', () => {
101103
const DIALOG_OPTION_USER = { email: '[email protected]' };
102104
showReportDialog({ user: DIALOG_OPTION_USER });
103105

104-
expect((client.showReportDialog as SinonSpy).called).to.be.true;
105-
expect((client.showReportDialog as SinonSpy).lastCall.args[0].user.email).to.eq(DIALOG_OPTION_USER.email);
106+
expect(reportDialogSpy).toBeCalled();
107+
expect(reportDialogSpy.mock.calls[0][0]!.user!.email).toBe(DIALOG_OPTION_USER.email);
106108
});
107109
});
108110
});
@@ -114,7 +116,7 @@ describe('SentryBrowser', () => {
114116

115117
captureMessage('event');
116118
await flush(2000);
117-
expect(beforeSend.args[0][0].breadcrumbs).to.have.lengthOf(2);
119+
expect(beforeSend.mock.calls[0][0].breadcrumbs).toHaveLength(2);
118120
});
119121
});
120122

@@ -128,22 +130,20 @@ describe('SentryBrowser', () => {
128130

129131
await flush(2000);
130132

131-
const event = beforeSend.args[0][0];
132-
expect(event.exception).to.not.be.undefined;
133-
/* eslint-disable @typescript-eslint/no-non-null-assertion */
134-
expect(event.exception!.values![0]).to.not.be.undefined;
135-
expect(event.exception!.values![0].type).to.equal('Error');
136-
expect(event.exception!.values![0].value).to.equal('test');
137-
expect(event.exception!.values![0].stacktrace).to.not.be.empty;
138-
/* eslint-enable @typescript-eslint/no-non-null-assertion */
133+
const event = beforeSend.mock.calls[0][0];
134+
expect(event.exception).toBeDefined();
135+
expect(event.exception.values[0]).toBeDefined();
136+
expect(event.exception.values[0].type).toBe('Error');
137+
expect(event.exception.values[0].value).toBe('test');
138+
expect(event.exception.values[0].stacktrace.frames).not.toHaveLength(0);
139139
});
140140

141141
it('should capture a message', done => {
142142
getCurrentHub().bindClient(
143143
new BrowserClient({
144144
beforeSend: (event: Event): Event | null => {
145-
expect(event.message).to.equal('test');
146-
expect(event.exception).to.be.undefined;
145+
expect(event.message).toBe('test');
146+
expect(event.exception).toBeUndefined();
147147
done();
148148
return event;
149149
},
@@ -157,8 +157,8 @@ describe('SentryBrowser', () => {
157157
getCurrentHub().bindClient(
158158
new BrowserClient({
159159
beforeSend: (event: Event): Event | null => {
160-
expect(event.message).to.equal('event');
161-
expect(event.exception).to.be.undefined;
160+
expect(event.message).toBe('event');
161+
expect(event.exception).toBeUndefined();
162162
done();
163163
return event;
164164
},
@@ -169,7 +169,7 @@ describe('SentryBrowser', () => {
169169
});
170170

171171
it('should not dedupe an event on bound client', async () => {
172-
const localBeforeSend = spy();
172+
const localBeforeSend = jest.fn();
173173
getCurrentHub().bindClient(
174174
new BrowserClient({
175175
beforeSend: localBeforeSend,
@@ -183,11 +183,11 @@ describe('SentryBrowser', () => {
183183

184184
await flush(10);
185185

186-
expect(localBeforeSend.calledTwice).to.be.true;
186+
expect(localBeforeSend).toHaveBeenCalledTimes(2);
187187
});
188188

189189
it('should use inboundfilter rules of bound client', async () => {
190-
const localBeforeSend = spy();
190+
const localBeforeSend = jest.fn();
191191
getCurrentHub().bindClient(
192192
new BrowserClient({
193193
beforeSend: localBeforeSend,
@@ -200,7 +200,7 @@ describe('SentryBrowser', () => {
200200

201201
await flush(2000);
202202

203-
expect(localBeforeSend.called).to.be.false;
203+
expect(localBeforeSend).not.toHaveBeenCalled();
204204
});
205205
});
206206
});
@@ -209,20 +209,20 @@ describe('SentryBrowser initialization', () => {
209209
it('should use window.SENTRY_RELEASE to set release on initialization if available', () => {
210210
global.SENTRY_RELEASE = { id: 'foobar' };
211211
init({ dsn });
212-
expect(global.__SENTRY__.hub._stack[0].client.getOptions().release).to.equal('foobar');
212+
expect(global.__SENTRY__.hub._stack[0].client.getOptions().release).toBe('foobar');
213213
delete global.SENTRY_RELEASE;
214214
});
215215

216216
it('should use initialScope', () => {
217217
init({ dsn, initialScope: { tags: { a: 'b' } } });
218-
expect(global.__SENTRY__.hub._stack[0].scope._tags).to.deep.equal({ a: 'b' });
218+
expect(global.__SENTRY__.hub._stack[0].scope._tags).toEqual({ a: 'b' });
219219
});
220220

221221
it('should use initialScope Scope', () => {
222222
const scope = new Scope();
223223
scope.setTags({ a: 'b' });
224224
init({ dsn, initialScope: scope });
225-
expect(global.__SENTRY__.hub._stack[0].scope._tags).to.deep.equal({ a: 'b' });
225+
expect(global.__SENTRY__.hub._stack[0].scope._tags).toEqual({ a: 'b' });
226226
});
227227

228228
it('should use initialScope callback', () => {
@@ -233,38 +233,36 @@ describe('SentryBrowser initialization', () => {
233233
return scope;
234234
},
235235
});
236-
expect(global.__SENTRY__.hub._stack[0].scope._tags).to.deep.equal({ a: 'b' });
236+
expect(global.__SENTRY__.hub._stack[0].scope._tags).toEqual({ a: 'b' });
237237
});
238238

239239
it('should have initialization proceed as normal if window.SENTRY_RELEASE is not set', () => {
240240
// This is mostly a happy-path test to ensure that the initialization doesn't throw an error.
241241
init({ dsn });
242-
expect(global.__SENTRY__.hub._stack[0].client.getOptions().release).to.be.undefined;
242+
expect(global.__SENTRY__.hub._stack[0].client.getOptions().release).toBeUndefined();
243243
});
244244

245245
describe('SDK metadata', () => {
246246
it('should set SDK data when Sentry.init() is called', () => {
247247
init({ dsn });
248248

249-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
250249
const sdkData = (getCurrentHub().getClient() as any)._backend._transport._api.metadata?.sdk;
251250

252-
expect(sdkData.name).to.equal('sentry.javascript.browser');
253-
expect(sdkData.packages[0].name).to.equal('npm:@sentry/browser');
254-
expect(sdkData.packages[0].version).to.equal(SDK_VERSION);
255-
expect(sdkData.version).to.equal(SDK_VERSION);
251+
expect(sdkData.name).toBe('sentry.javascript.browser');
252+
expect(sdkData.packages[0].name).toBe('npm:@sentry/browser');
253+
expect(sdkData.packages[0].version).toBe(SDK_VERSION);
254+
expect(sdkData.version).toBe(SDK_VERSION);
256255
});
257256

258257
it('should set SDK data when instantiating a client directly', () => {
259258
const client = new BrowserClient({ dsn });
260259

261-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
262260
const sdkData = (client as any)._backend._transport._api.metadata?.sdk;
263261

264-
expect(sdkData.name).to.equal('sentry.javascript.browser');
265-
expect(sdkData.packages[0].name).to.equal('npm:@sentry/browser');
266-
expect(sdkData.packages[0].version).to.equal(SDK_VERSION);
267-
expect(sdkData.version).to.equal(SDK_VERSION);
262+
expect(sdkData.name).toBe('sentry.javascript.browser');
263+
expect(sdkData.packages[0].name).toBe('npm:@sentry/browser');
264+
expect(sdkData.packages[0].version).toBe(SDK_VERSION);
265+
expect(sdkData.version).toBe(SDK_VERSION);
268266
});
269267

270268
// wrapper packages (like @sentry/angular and @sentry/react) set their SDK data in their `init` methods, which are
@@ -287,13 +285,12 @@ describe('SentryBrowser initialization', () => {
287285
},
288286
});
289287

290-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
291288
const sdkData = (getCurrentHub().getClient() as any)._backend._transport._api.metadata?.sdk;
292289

293-
expect(sdkData.name).to.equal('sentry.javascript.angular');
294-
expect(sdkData.packages[0].name).to.equal('npm:@sentry/angular');
295-
expect(sdkData.packages[0].version).to.equal(SDK_VERSION);
296-
expect(sdkData.version).to.equal(SDK_VERSION);
290+
expect(sdkData.name).toBe('sentry.javascript.angular');
291+
expect(sdkData.packages[0].name).toBe('npm:@sentry/angular');
292+
expect(sdkData.packages[0].version).toBe(SDK_VERSION);
293+
expect(sdkData.version).toBe(SDK_VERSION);
297294
});
298295
});
299296
});
@@ -303,25 +300,27 @@ describe('wrap()', () => {
303300
getCurrentHub().bindClient(
304301
new BrowserClient({
305302
beforeSend: (event: Event): Event | null => {
306-
/* eslint-disable @typescript-eslint/no-non-null-assertion */
307-
expect(event.exception!.values![0].type).to.equal('TypeError');
308-
expect(event.exception!.values![0].value).to.equal('mkey');
309-
/* eslint-enable @typescript-eslint/no-non-null-assertion */
303+
expect(event.exception!.values![0].type).toBe('TypeError');
304+
expect(event.exception!.values![0].value).toBe('mkey');
310305
done();
311306
return null;
312307
},
313308
dsn,
314309
}),
315310
);
316311

317-
wrap(() => {
318-
throw new TypeError('mkey');
319-
});
312+
try {
313+
wrap(() => {
314+
throw new TypeError('mkey');
315+
});
316+
} catch (e) {
317+
// no-empty
318+
}
320319
});
321320

322321
it('should return result of a function call', () => {
323322
const result = wrap(() => 2);
324-
expect(result).to.equal(2);
323+
expect(result).toBe(2);
325324
});
326325

327326
it('should allow for passing this and arguments through binding', () => {
@@ -331,16 +330,16 @@ describe('wrap()', () => {
331330
}.bind({ context: 'this' }, 'b', 42),
332331
);
333332

334-
expect((result as unknown[])[0]).to.deep.equal({ context: 'this' });
335-
expect((result as unknown[])[1]).to.equal('b');
336-
expect((result as unknown[])[2]).to.equal(42);
333+
expect((result as unknown[])[0]).toEqual({ context: 'this' });
334+
expect((result as unknown[])[1]).toBe('b');
335+
expect((result as unknown[])[2]).toBe(42);
337336

338337
const result2 = wrap(
339338
function(this: { x: number }): number {
340339
return this.x;
341340
}.bind({ x: 42 }),
342341
);
343342

344-
expect(result2).to.equal(42);
343+
expect(result2).toBe(42);
345344
});
346345
});

0 commit comments

Comments
 (0)