Skip to content

Commit 3fa9bcb

Browse files
✅ improve unit test setup (#4149)
1 parent d8dfef5 commit 3fa9bcb

28 files changed

Lines changed: 105 additions & 125 deletions

AGENTS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ yarn test:unit
2424
# Run specific test file
2525
yarn test:unit --spec packages/core/src/path/to/feature.spec.ts
2626

27+
# Run tests on a specific seed
28+
yarn test:unit --seed 123
29+
2730
# setup E2E tests (installs Playwright and builds test apps)
2831
yarn test:e2e:init
2932

packages/core/src/browser/cookie.spec.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
import { mockCookies } from '../../test'
2-
import { getCurrentSite, resetGetCurrentSite } from './cookie'
2+
import { getCurrentSite } from './cookie'
33

44
describe('cookie', () => {
55
describe('getCurrentSite', () => {
6-
beforeEach(() => {
7-
resetGetCurrentSite()
8-
})
9-
106
it('returns the eTLD+1 for example.com', () => {
117
mockCookies()
128
expect(getCurrentSite('example.com')).toBe('example.com')

packages/core/src/browser/xhrObservable.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,12 @@ function abortXhr({ target: xhr }: InstrumentedMethodCall<XMLHttpRequest, 'abort
132132
context.isAborted = true
133133
}
134134
}
135+
136+
/**
137+
* Reset the XHR observable global state. This is useful for testing to ensure clean state between tests.
138+
*
139+
* @internal
140+
*/
141+
export function resetXhrObservable() {
142+
xhrObservable = undefined
143+
}

packages/core/src/domain/session/storeStrategies/sessionInCookie.spec.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { mockClock, getSessionState, registerCleanupTask } from '../../../../test'
2-
import { setCookie, deleteCookie, getCookie, getCurrentSite } from '../../../browser/cookie'
2+
import { setCookie, deleteCookie, getCookie } from '../../../browser/cookie'
33
import type { SessionState } from '../sessionState'
44
import { validateAndBuildConfiguration } from '../../configuration'
55
import type { InitConfiguration } from '../../configuration'
@@ -93,28 +93,29 @@ describe('session in cookie strategy', () => {
9393
{
9494
initConfiguration: { clientToken: 'abc' },
9595
cookieOptions: {},
96-
cookieString: /^dd_cookie_test_[\w-]+=[^;]*;expires=[^;]+;path=\/;samesite=strict$/,
96+
cookieString: /^dd_[\w_-]+=[^;]*;expires=[^;]+;path=\/;samesite=strict$/,
9797
description: 'should set samesite to strict by default',
9898
},
9999
{
100100
initConfiguration: { clientToken: 'abc', useSecureSessionCookie: true },
101101
cookieOptions: { secure: true },
102-
cookieString: /^dd_cookie_test_[\w-]+=[^;]*;expires=[^;]+;path=\/;samesite=strict;secure$/,
102+
cookieString: /^dd_[\w_-]+=[^;]*;expires=[^;]+;path=\/;samesite=strict;secure$/,
103103
description: 'should add secure attribute when defined',
104104
},
105105
{
106106
initConfiguration: { clientToken: 'abc', trackSessionAcrossSubdomains: true },
107107
cookieOptions: { domain: 'foo.bar' },
108-
cookieString: new RegExp(
109-
`^dd_cookie_test_[\\w-]+=[^;]*;expires=[^;]+;path=\\/;samesite=strict;domain=${getCurrentSite()}$`
110-
),
108+
cookieString: new RegExp('^dd_[\\w_-]+=[^;]*;expires=[^;]+;path=\\/;samesite=strict;domain='),
111109
description: 'should set cookie domain when tracking accross subdomains',
112110
},
113111
].forEach(({ description, initConfiguration, cookieString }) => {
114112
it(description, () => {
115113
const cookieSetSpy = spyOnProperty(document, 'cookie', 'set')
116114
selectCookieStrategy(initConfiguration)
117-
expect(cookieSetSpy.calls.argsFor(0)[0]).toMatch(cookieString)
115+
expect(cookieSetSpy).toHaveBeenCalled()
116+
for (const call of cookieSetSpy.calls.all()) {
117+
expect(call.args[0]).toMatch(cookieString)
118+
}
118119
})
119120
})
120121
})

packages/core/src/domain/telemetry/telemetry.spec.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import type { StackTrace } from '../../tools/stackTrace/computeStackTrace'
2020
import { HookNames } from '../../tools/abstractHooks'
2121
import {
2222
addTelemetryError,
23-
resetTelemetry,
2423
scrubCustomerFrames,
2524
formatError,
2625
addTelemetryConfiguration,
@@ -71,10 +70,6 @@ function startAndSpyTelemetry(
7170
}
7271

7372
describe('telemetry', () => {
74-
afterEach(() => {
75-
resetTelemetry()
76-
})
77-
7873
it('collects "monitor" errors', async () => {
7974
const { getTelemetryEvents } = startAndSpyTelemetry()
8075
callMonitored(() => {

packages/core/src/domain/telemetry/telemetry.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { buildTags } from '../tags'
88
import { INTAKE_SITE_STAGING, INTAKE_SITE_US1_FED } from '../intakeSites'
99
import { BufferedObservable, Observable } from '../../tools/observable'
1010
import { clocksNow } from '../../tools/utils/timeUtils'
11-
import { displayIfDebugEnabled, startMonitorErrorCollection, resetMonitor } from '../../tools/monitor'
11+
import { displayIfDebugEnabled, startMonitorErrorCollection } from '../../tools/monitor'
1212
import { sendToExtension } from '../../tools/sendToExtension'
1313
import { performDraw } from '../../tools/utils/numberUtils'
1414
import { jsonStringify } from '../../tools/serialisation/jsonStringify'
@@ -247,7 +247,6 @@ function getRuntimeEnvInfo(): RuntimeEnvInfo {
247247

248248
export function resetTelemetry() {
249249
telemetryObservable = undefined
250-
resetMonitor()
251250
}
252251

253252
/**

packages/core/src/index.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ export {
4242
startTelemetry,
4343
addTelemetryDebug,
4444
addTelemetryError,
45-
resetTelemetry,
4645
TelemetryService,
4746
TelemetryMetrics,
4847
addTelemetryConfiguration,
@@ -106,7 +105,7 @@ export type { CookieStore, WeakRef, WeakRefConstructor } from './browser/browser
106105
export type { XhrCompleteContext, XhrStartContext } from './browser/xhrObservable'
107106
export { initXhrObservable } from './browser/xhrObservable'
108107
export type { FetchResolveContext, FetchStartContext, FetchContext } from './browser/fetchObservable'
109-
export { initFetchObservable, resetFetchObservable, ResponseBodyAction } from './browser/fetchObservable'
108+
export { initFetchObservable, ResponseBodyAction } from './browser/fetchObservable'
110109
export { fetch } from './browser/fetch'
111110
export type { PageMayExitEvent } from './browser/pageMayExitObservable'
112111
export { createPageMayExitObservable, PageExitReason, isPageExitReason } from './browser/pageMayExitObservable'
@@ -115,7 +114,7 @@ export { requestIdleCallback } from './tools/requestIdleCallback'
115114
export * from './tools/taskQueue'
116115
export * from './tools/timer'
117116
export type { ConsoleLog } from './domain/console/consoleObservable'
118-
export { initConsoleObservable, resetConsoleObservable } from './domain/console/consoleObservable'
117+
export { initConsoleObservable } from './domain/console/consoleObservable'
119118
export type { BoundedBuffer } from './tools/boundedBuffer'
120119
export { createBoundedBuffer } from './tools/boundedBuffer'
121120
export { catchUserErrors } from './tools/catchUserErrors'

packages/core/src/tools/monitor.spec.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
import { display } from './display'
2-
import { callMonitored, monitor, monitored, startMonitorErrorCollection, resetMonitor, setDebugMode } from './monitor'
2+
import { callMonitored, monitor, monitored, startMonitorErrorCollection, setDebugMode } from './monitor'
33

44
describe('monitor', () => {
55
let onMonitorErrorCollectedSpy: jasmine.Spy<(error: unknown) => void>
66

77
beforeEach(() => {
88
onMonitorErrorCollectedSpy = jasmine.createSpy()
99
})
10-
afterEach(() => {
11-
resetMonitor()
12-
})
1310

1411
describe('decorator', () => {
1512
class Candidate {

packages/core/src/tools/timer.spec.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { mockClock, mockZoneJs, registerCleanupTask } from '../../test'
1+
import { mockClock, mockZoneJs } from '../../test'
22
import type { Clock, MockZoneJs } from '../../test'
3-
import { resetMonitor, startMonitorErrorCollection } from './monitor'
3+
import { startMonitorErrorCollection } from './monitor'
44
import { setTimeout, clearTimeout, setInterval, clearInterval } from './timer'
55
import { noop } from './utils/functionUtils'
66
;[
@@ -21,9 +21,6 @@ import { noop } from './utils/functionUtils'
2121

2222
beforeEach(() => {
2323
clock = mockClock()
24-
registerCleanupTask(() => {
25-
resetMonitor()
26-
})
2724
zoneJs = mockZoneJs()
2825
})
2926

packages/core/src/tools/valueHistory.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export interface ValueHistory<Value> {
3030
stop: () => void
3131
}
3232

33-
let cleanupHistoriesInterval: TimeoutId | null = null
33+
let cleanupHistoriesInterval: TimeoutId | undefined
3434

3535
const cleanupTasks: Set<() => void> = new Set()
3636

@@ -143,9 +143,20 @@ export function createValueHistory<Value>({
143143
cleanupTasks.delete(clearExpiredValues)
144144
if (cleanupTasks.size === 0 && cleanupHistoriesInterval) {
145145
clearInterval(cleanupHistoriesInterval)
146-
cleanupHistoriesInterval = null
146+
cleanupHistoriesInterval = undefined
147147
}
148148
}
149149

150150
return { add, find, closeActive, findAll, reset, stop }
151151
}
152+
153+
/**
154+
* Reset all global state. This is useful for testing to ensure clean state between tests.
155+
*
156+
* @internal
157+
*/
158+
export function resetValueHistoryGlobals() {
159+
cleanupTasks.clear()
160+
clearInterval(cleanupHistoriesInterval)
161+
cleanupHistoriesInterval = undefined
162+
}

0 commit comments

Comments
 (0)