From ae93eb9de8bdf51f3137b53a39c9f38f9aea764a Mon Sep 17 00:00:00 2001 From: Tim Fish Date: Mon, 24 Feb 2025 18:30:50 +0100 Subject: [PATCH] test(node): Migrate to vitest --- packages/node/package.json | 6 +- packages/node/test/cron.test.ts | 175 ++++++++------- packages/node/test/helpers/conditional.ts | 3 +- .../node/test/integration/breadcrumbs.test.ts | 31 +-- .../node/test/integration/console.test.ts | 7 +- packages/node/test/integration/scope.test.ts | 27 +-- .../test/integration/transactions.test.ts | 35 +-- .../node/test/integrations/context.test.ts | 18 +- .../test/integrations/contextlines.test.ts | 30 ++- packages/node/test/integrations/http.test.ts | 1 + .../test/integrations/localvariables.test.ts | 208 +++++++++--------- .../request-session-tracking.test.ts | 35 +-- .../node/test/integrations/spotlight.test.ts | 38 ++-- .../test/integrations/tracing/graphql.test.ts | 7 +- .../test/integrations/tracing/mongo.test.ts | 7 +- .../test/integrations/tracing/redis.test.ts | 1 + packages/node/test/sdk/api.test.ts | 7 +- packages/node/test/sdk/client.test.ts | 11 +- packages/node/test/sdk/init.test.ts | 49 +++-- packages/node/test/sdk/initOtel.test.ts | 19 +- packages/node/test/sdk/preload.test.ts | 15 +- packages/node/test/transports/http.test.ts | 50 +++-- packages/node/test/transports/https.test.ts | 39 ++-- .../node/test/utils/ensureIsWrapped.test.ts | 13 +- packages/node/test/utils/entry-point.test.ts | 1 + packages/node/test/utils/envToBool.test.ts | 1 + .../node/test/utils/getRequestUrl.test.ts | 1 + packages/node/test/utils/module.test.ts | 1 + packages/node/tsconfig.test.json | 4 +- packages/node/vite.config.ts | 8 + 30 files changed, 468 insertions(+), 380 deletions(-) create mode 100644 packages/node/vite.config.ts diff --git a/packages/node/package.json b/packages/node/package.json index 9614f4351004..e5adb16c23bd 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -119,9 +119,9 @@ "clean": "rimraf build coverage sentry-node-*.tgz", "fix": "eslint . --format stylish --fix", "lint": "eslint . --format stylish", - "test": "yarn test:jest", - "test:jest": "jest", - "test:watch": "jest --watch", + "test": "yarn test:unit", + "test:unit": "vitest run", + "test:watch": "vitest --watch", "yalc:publish": "yalc publish --push --sig" }, "volta": { diff --git a/packages/node/test/cron.test.ts b/packages/node/test/cron.test.ts index d068280a41e0..5ae016b43ac9 100644 --- a/packages/node/test/cron.test.ts +++ b/packages/node/test/cron.test.ts @@ -1,18 +1,19 @@ import * as SentryCore from '@sentry/core'; +import { type MockInstance, afterEach, beforeEach, describe, expect, test, vi } from 'vitest'; import { cron } from '../src'; import type { CronJob, CronJobParams } from '../src/cron/cron'; import type { NodeCron, NodeCronOptions } from '../src/cron/node-cron'; describe('cron check-ins', () => { - let withMonitorSpy: jest.SpyInstance; + let withMonitorSpy: MockInstance; beforeEach(() => { - withMonitorSpy = jest.spyOn(SentryCore, 'withMonitor'); + withMonitorSpy = vi.spyOn(SentryCore, 'withMonitor'); }); afterEach(() => { - jest.restoreAllMocks(); + vi.restoreAllMocks(); }); describe('cron', () => { @@ -48,43 +49,45 @@ describe('cron check-ins', () => { } } - test('new CronJob()', done => { - expect.assertions(4); - - const CronJobWithCheckIn = cron.instrumentCron(CronJobMock, 'my-cron-job'); - - new CronJobWithCheckIn( - '* * * Jan,Sep Sun', - () => { - expect(withMonitorSpy).toHaveBeenCalledTimes(1); - expect(withMonitorSpy).toHaveBeenLastCalledWith('my-cron-job', expect.anything(), { - schedule: { type: 'crontab', value: '* * * 1,9 0' }, - timezone: 'America/Los_Angeles', - }); - done(); - }, - undefined, - true, - 'America/Los_Angeles', - ); - }); + test('new CronJob()', () => + new Promise(done => { + expect.assertions(4); + + const CronJobWithCheckIn = cron.instrumentCron(CronJobMock, 'my-cron-job'); + + new CronJobWithCheckIn( + '* * * Jan,Sep Sun', + () => { + expect(withMonitorSpy).toHaveBeenCalledTimes(1); + expect(withMonitorSpy).toHaveBeenLastCalledWith('my-cron-job', expect.anything(), { + schedule: { type: 'crontab', value: '* * * 1,9 0' }, + timezone: 'America/Los_Angeles', + }); + done(); + }, + undefined, + true, + 'America/Los_Angeles', + ); + })); - test('CronJob.from()', done => { - expect.assertions(4); + test('CronJob.from()', () => + new Promise(done => { + expect.assertions(4); - const CronJobWithCheckIn = cron.instrumentCron(CronJobMock, 'my-cron-job'); + const CronJobWithCheckIn = cron.instrumentCron(CronJobMock, 'my-cron-job'); - CronJobWithCheckIn.from({ - cronTime: '* * * Jan,Sep Sun', - onTick: () => { - expect(withMonitorSpy).toHaveBeenCalledTimes(1); - expect(withMonitorSpy).toHaveBeenLastCalledWith('my-cron-job', expect.anything(), { - schedule: { type: 'crontab', value: '* * * 1,9 0' }, - }); - done(); - }, - }); - }); + CronJobWithCheckIn.from({ + cronTime: '* * * Jan,Sep Sun', + onTick: () => { + expect(withMonitorSpy).toHaveBeenCalledTimes(1); + expect(withMonitorSpy).toHaveBeenLastCalledWith('my-cron-job', expect.anything(), { + schedule: { type: 'crontab', value: '* * * 1,9 0' }, + }); + done(); + }, + }); + })); test('throws with multiple jobs same name', () => { const CronJobWithCheckIn = cron.instrumentCron(CronJobMock, 'my-cron-job'); @@ -108,32 +111,33 @@ describe('cron check-ins', () => { }); describe('node-cron', () => { - test('calls withMonitor', done => { - expect.assertions(5); - - const nodeCron: NodeCron = { - schedule: (expression: string, callback: () => void, options?: NodeCronOptions): unknown => { - expect(expression).toBe('* * * Jan,Sep Sun'); - expect(callback).toBeInstanceOf(Function); - expect(options?.name).toBe('my-cron-job'); - return callback(); - }, - }; - - const cronWithCheckIn = cron.instrumentNodeCron(nodeCron); - - cronWithCheckIn.schedule( - '* * * Jan,Sep Sun', - () => { - expect(withMonitorSpy).toHaveBeenCalledTimes(1); - expect(withMonitorSpy).toHaveBeenLastCalledWith('my-cron-job', expect.anything(), { - schedule: { type: 'crontab', value: '* * * 1,9 0' }, - }); - done(); - }, - { name: 'my-cron-job' }, - ); - }); + test('calls withMonitor', () => + new Promise(done => { + expect.assertions(5); + + const nodeCron: NodeCron = { + schedule: (expression: string, callback: () => void, options?: NodeCronOptions): unknown => { + expect(expression).toBe('* * * Jan,Sep Sun'); + expect(callback).toBeInstanceOf(Function); + expect(options?.name).toBe('my-cron-job'); + return callback(); + }, + }; + + const cronWithCheckIn = cron.instrumentNodeCron(nodeCron); + + cronWithCheckIn.schedule( + '* * * Jan,Sep Sun', + () => { + expect(withMonitorSpy).toHaveBeenCalledTimes(1); + expect(withMonitorSpy).toHaveBeenLastCalledWith('my-cron-job', expect.anything(), { + schedule: { type: 'crontab', value: '* * * 1,9 0' }, + }); + done(); + }, + { name: 'my-cron-job' }, + ); + })); test('throws without supplied name', () => { const nodeCron: NodeCron = { @@ -154,32 +158,33 @@ describe('cron check-ins', () => { }); describe('node-schedule', () => { - test('calls withMonitor', done => { - expect.assertions(5); - - class NodeScheduleMock { - scheduleJob( - nameOrExpression: string | Date | object, - expressionOrCallback: string | Date | object | (() => void), - callback: () => void, - ): unknown { - expect(nameOrExpression).toBe('my-cron-job'); - expect(expressionOrCallback).toBe('* * * Jan,Sep Sun'); - expect(callback).toBeInstanceOf(Function); - return callback(); + test('calls withMonitor', () => + new Promise(done => { + expect.assertions(5); + + class NodeScheduleMock { + scheduleJob( + nameOrExpression: string | Date | object, + expressionOrCallback: string | Date | object | (() => void), + callback: () => void, + ): unknown { + expect(nameOrExpression).toBe('my-cron-job'); + expect(expressionOrCallback).toBe('* * * Jan,Sep Sun'); + expect(callback).toBeInstanceOf(Function); + return callback(); + } } - } - const scheduleWithCheckIn = cron.instrumentNodeSchedule(new NodeScheduleMock()); + const scheduleWithCheckIn = cron.instrumentNodeSchedule(new NodeScheduleMock()); - scheduleWithCheckIn.scheduleJob('my-cron-job', '* * * Jan,Sep Sun', () => { - expect(withMonitorSpy).toHaveBeenCalledTimes(1); - expect(withMonitorSpy).toHaveBeenLastCalledWith('my-cron-job', expect.anything(), { - schedule: { type: 'crontab', value: '* * * 1,9 0' }, + scheduleWithCheckIn.scheduleJob('my-cron-job', '* * * Jan,Sep Sun', () => { + expect(withMonitorSpy).toHaveBeenCalledTimes(1); + expect(withMonitorSpy).toHaveBeenLastCalledWith('my-cron-job', expect.anything(), { + schedule: { type: 'crontab', value: '* * * 1,9 0' }, + }); + done(); }); - done(); - }); - }); + })); test('throws without crontab string', () => { class NodeScheduleMock { diff --git a/packages/node/test/helpers/conditional.ts b/packages/node/test/helpers/conditional.ts index 01e64d8804df..48df7d821da8 100644 --- a/packages/node/test/helpers/conditional.ts +++ b/packages/node/test/helpers/conditional.ts @@ -1,4 +1,5 @@ import { parseSemver } from '@sentry/core'; +import { it, test } from 'vitest'; const NODE_VERSION = parseSemver(process.versions.node).major; @@ -8,7 +9,7 @@ const NODE_VERSION = parseSemver(process.versions.node).major; * @param {{ min?: number; max?: number }} allowedVersion * @return {*} {jest.Describe} */ -export const conditionalTest = (allowedVersion: { min?: number; max?: number }): jest.It => { +export const conditionalTest = (allowedVersion: { min?: number; max?: number }) => { if (!NODE_VERSION) { return it.skip; } diff --git a/packages/node/test/integration/breadcrumbs.test.ts b/packages/node/test/integration/breadcrumbs.test.ts index d32d1490be76..20e19a8a4b55 100644 --- a/packages/node/test/integration/breadcrumbs.test.ts +++ b/packages/node/test/integration/breadcrumbs.test.ts @@ -3,10 +3,11 @@ import { startSpan } from '@sentry/opentelemetry'; import { getClient } from '../../src/'; import type { NodeClient } from '../../src/sdk/client'; +import { afterEach, describe, expect, it, vi } from 'vitest'; import { cleanupOtel, mockSdkInit } from '../helpers/mockSdkInit'; describe('Integration | breadcrumbs', () => { - const beforeSendTransaction = jest.fn(() => null); + const beforeSendTransaction = vi.fn(() => null); afterEach(() => { cleanupOtel(); @@ -14,8 +15,8 @@ describe('Integration | breadcrumbs', () => { describe('without tracing', () => { it('correctly adds & retrieves breadcrumbs', async () => { - const beforeSend = jest.fn(() => null); - const beforeBreadcrumb = jest.fn(breadcrumb => breadcrumb); + const beforeSend = vi.fn(() => null); + const beforeBreadcrumb = vi.fn(breadcrumb => breadcrumb); mockSdkInit({ beforeSend, beforeBreadcrumb }); @@ -50,8 +51,8 @@ describe('Integration | breadcrumbs', () => { }); it('handles parallel scopes', async () => { - const beforeSend = jest.fn(() => null); - const beforeBreadcrumb = jest.fn(breadcrumb => breadcrumb); + const beforeSend = vi.fn(() => null); + const beforeBreadcrumb = vi.fn(breadcrumb => breadcrumb); mockSdkInit({ beforeSend, beforeBreadcrumb }); @@ -96,8 +97,8 @@ describe('Integration | breadcrumbs', () => { }); it('correctly adds & retrieves breadcrumbs', async () => { - const beforeSend = jest.fn(() => null); - const beforeBreadcrumb = jest.fn(breadcrumb => breadcrumb); + const beforeSend = vi.fn(() => null); + const beforeBreadcrumb = vi.fn(breadcrumb => breadcrumb); mockSdkInit({ beforeSend, beforeBreadcrumb, beforeSendTransaction, tracesSampleRate: 1 }); @@ -141,8 +142,8 @@ describe('Integration | breadcrumbs', () => { }); it('correctly adds & retrieves breadcrumbs for the current isolation span only', async () => { - const beforeSend = jest.fn(() => null); - const beforeBreadcrumb = jest.fn(breadcrumb => breadcrumb); + const beforeSend = vi.fn(() => null); + const beforeBreadcrumb = vi.fn(breadcrumb => breadcrumb); mockSdkInit({ beforeSend, beforeBreadcrumb, beforeSendTransaction, tracesSampleRate: 1 }); @@ -193,8 +194,8 @@ describe('Integration | breadcrumbs', () => { }); it('ignores scopes inside of root span', async () => { - const beforeSend = jest.fn(() => null); - const beforeBreadcrumb = jest.fn(breadcrumb => breadcrumb); + const beforeSend = vi.fn(() => null); + const beforeBreadcrumb = vi.fn(breadcrumb => breadcrumb); mockSdkInit({ beforeSend, beforeBreadcrumb, beforeSendTransaction, tracesSampleRate: 1 }); @@ -234,8 +235,8 @@ describe('Integration | breadcrumbs', () => { }); it('handles deep nesting of scopes', async () => { - const beforeSend = jest.fn(() => null); - const beforeBreadcrumb = jest.fn(breadcrumb => breadcrumb); + const beforeSend = vi.fn(() => null); + const beforeBreadcrumb = vi.fn(breadcrumb => breadcrumb); mockSdkInit({ beforeSend, beforeBreadcrumb, beforeSendTransaction, tracesSampleRate: 1 }); @@ -292,8 +293,8 @@ describe('Integration | breadcrumbs', () => { }); it('correctly adds & retrieves breadcrumbs in async spans', async () => { - const beforeSend = jest.fn(() => null); - const beforeBreadcrumb = jest.fn(breadcrumb => breadcrumb); + const beforeSend = vi.fn(() => null); + const beforeBreadcrumb = vi.fn(breadcrumb => breadcrumb); mockSdkInit({ beforeSend, beforeBreadcrumb, beforeSendTransaction, tracesSampleRate: 1 }); diff --git a/packages/node/test/integration/console.test.ts b/packages/node/test/integration/console.test.ts index 9d4d5a415ee5..401dffd34819 100644 --- a/packages/node/test/integration/console.test.ts +++ b/packages/node/test/integration/console.test.ts @@ -1,17 +1,18 @@ import * as SentryCore from '@sentry/core'; import { resetInstrumentationHandlers } from '@sentry/core'; +import { afterEach, describe, expect, it, vi } from 'vitest'; import { getClient } from '../../src'; import type { NodeClient } from '../../src'; import { consoleIntegration } from '../../src/integrations/console'; -const addBreadcrumbSpy = jest.spyOn(SentryCore, 'addBreadcrumb'); +const addBreadcrumbSpy = vi.spyOn(SentryCore, 'addBreadcrumb'); -jest.spyOn(console, 'log').mockImplementation(() => { +vi.spyOn(console, 'log').mockImplementation(() => { // noop so that we don't spam the logs }); afterEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); resetInstrumentationHandlers(); }); diff --git a/packages/node/test/integration/scope.test.ts b/packages/node/test/integration/scope.test.ts index 4ec51b813229..a3c8de869df5 100644 --- a/packages/node/test/integration/scope.test.ts +++ b/packages/node/test/integration/scope.test.ts @@ -2,6 +2,7 @@ import { getCapturedScopesOnSpan, getCurrentScope } from '@sentry/core'; import { getClient } from '@sentry/opentelemetry'; import { clearGlobalScope } from '../../../core/test/lib/clear-global-scope'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import * as Sentry from '../../src/'; import type { NodeClient } from '../../src/sdk/client'; import { cleanupOtel, mockSdkInit, resetGlobals } from '../helpers/mockSdkInit'; @@ -16,8 +17,8 @@ describe('Integration | Scope', () => { ['without tracing', false], ])('%s', (_name, tracingEnabled) => { it('correctly syncs OTEL context & Sentry hub/scope', async () => { - const beforeSend = jest.fn(() => null); - const beforeSendTransaction = jest.fn(() => null); + const beforeSend = vi.fn(() => null); + const beforeSendTransaction = vi.fn(() => null); mockSdkInit({ tracesSampleRate: tracingEnabled ? 1 : 0, beforeSend, beforeSendTransaction }); @@ -130,8 +131,8 @@ describe('Integration | Scope', () => { }); it('isolates parallel root scopes', async () => { - const beforeSend = jest.fn(() => null); - const beforeSendTransaction = jest.fn(() => null); + const beforeSend = vi.fn(() => null); + const beforeSendTransaction = vi.fn(() => null); mockSdkInit({ tracesSampleRate: tracingEnabled ? 1 : 0, beforeSend, beforeSendTransaction }); @@ -265,7 +266,7 @@ describe('Integration | Scope', () => { }); it('is applied to events', async () => { - const beforeSend = jest.fn(); + const beforeSend = vi.fn(); mockSdkInit({ beforeSend }); const client = Sentry.getClient(); @@ -323,7 +324,7 @@ describe('Integration | Scope', () => { }); it('is applied to events', async () => { - const beforeSend = jest.fn(); + const beforeSend = vi.fn(); mockSdkInit({ beforeSend }); const client = Sentry.getClient(); @@ -353,7 +354,7 @@ describe('Integration | Scope', () => { }); it('withIsolationScope works', async () => { - const beforeSend = jest.fn(); + const beforeSend = vi.fn(); mockSdkInit({ beforeSend }); const client = Sentry.getClient(); @@ -403,7 +404,7 @@ describe('Integration | Scope', () => { }); it('can be deeply nested', async () => { - const beforeSend = jest.fn(); + const beforeSend = vi.fn(); mockSdkInit({ beforeSend }); const client = Sentry.getClient(); @@ -475,7 +476,7 @@ describe('Integration | Scope', () => { }); it('is applied to events', async () => { - const beforeSend = jest.fn(); + const beforeSend = vi.fn(); mockSdkInit({ beforeSend }); const client = Sentry.getClient(); @@ -505,7 +506,7 @@ describe('Integration | Scope', () => { }); it('withScope works', async () => { - const beforeSend = jest.fn(); + const beforeSend = vi.fn(); mockSdkInit({ beforeSend }); const client = Sentry.getClient(); @@ -554,7 +555,7 @@ describe('Integration | Scope', () => { }); it('can be deeply nested', async () => { - const beforeSend = jest.fn(); + const beforeSend = vi.fn(); mockSdkInit({ beforeSend }); const client = Sentry.getClient(); @@ -600,7 +601,7 @@ describe('Integration | Scope', () => { }); it('automatically forks with OTEL context', async () => { - const beforeSend = jest.fn(); + const beforeSend = vi.fn(); mockSdkInit({ beforeSend }); const client = Sentry.getClient(); @@ -649,7 +650,7 @@ describe('Integration | Scope', () => { }); it('merges data from global, isolation and current scope', async () => { - const beforeSend = jest.fn(); + const beforeSend = vi.fn(); mockSdkInit({ beforeSend }); const client = Sentry.getClient(); diff --git a/packages/node/test/integration/transactions.test.ts b/packages/node/test/integration/transactions.test.ts index 1f396b11c3af..a7207d30cbac 100644 --- a/packages/node/test/integration/transactions.test.ts +++ b/packages/node/test/integration/transactions.test.ts @@ -5,18 +5,19 @@ import { logger } from '@sentry/core'; import type { TransactionEvent } from '@sentry/core'; import { SentrySpanProcessor } from '@sentry/opentelemetry'; +import { afterEach, describe, expect, it, vi } from 'vitest'; import * as Sentry from '../../src'; import { cleanupOtel, getProvider, mockSdkInit } from '../helpers/mockSdkInit'; describe('Integration | Transactions', () => { afterEach(() => { - jest.restoreAllMocks(); + vi.restoreAllMocks(); cleanupOtel(); }); it('correctly creates transaction & spans', async () => { const transactions: TransactionEvent[] = []; - const beforeSendTransaction = jest.fn(event => { + const beforeSendTransaction = vi.fn(event => { transactions.push(event); return null; }); @@ -162,7 +163,7 @@ describe('Integration | Transactions', () => { }); it('correctly creates concurrent transaction & spans', async () => { - const beforeSendTransaction = jest.fn(() => null); + const beforeSendTransaction = vi.fn(() => null); mockSdkInit({ tracesSampleRate: 1, beforeSendTransaction }); @@ -307,7 +308,7 @@ describe('Integration | Transactions', () => { }); it('correctly creates concurrent transaction & spans when using native OTEL tracer', async () => { - const beforeSendTransaction = jest.fn(() => null); + const beforeSendTransaction = vi.fn(() => null); mockSdkInit({ tracesSampleRate: 1, beforeSendTransaction }); @@ -444,7 +445,7 @@ describe('Integration | Transactions', () => { }); it('correctly creates transaction & spans with a trace header data', async () => { - const beforeSendTransaction = jest.fn(() => null); + const beforeSendTransaction = vi.fn(() => null); const traceId = 'd4cda95b652f4a1592b449d5929fda1b'; const parentSpanId = '6e0c63257de34c92'; @@ -552,14 +553,14 @@ describe('Integration | Transactions', () => { }); it('cleans up spans that are not flushed for over 5 mins', async () => { - const beforeSendTransaction = jest.fn(() => null); + const beforeSendTransaction = vi.fn(() => null); const now = Date.now(); - jest.useFakeTimers(); - jest.setSystemTime(now); + vi.useFakeTimers(); + vi.setSystemTime(now); const logs: unknown[] = []; - jest.spyOn(logger, 'log').mockImplementation(msg => logs.push(msg)); + vi.spyOn(logger, 'log').mockImplementation(msg => logs.push(msg)); mockSdkInit({ tracesSampleRate: 1, beforeSendTransaction }); @@ -585,7 +586,7 @@ describe('Integration | Transactions', () => { await new Promise(resolve => setTimeout(resolve, 10 * 60 * 1000)); }); - jest.advanceTimersByTime(1); + vi.advanceTimersByTime(1); // Child-spans have been added to the exporter, but they are pending since they are waiting for their parent const finishedSpans1 = []; @@ -598,12 +599,12 @@ describe('Integration | Transactions', () => { expect(beforeSendTransaction).toHaveBeenCalledTimes(0); // Now wait for 5 mins - jest.advanceTimersByTime(5 * 60 * 1_000 + 1); + vi.advanceTimersByTime(5 * 60 * 1_000 + 1); // Adding another span will trigger the cleanup Sentry.startSpan({ name: 'other span' }, () => {}); - jest.advanceTimersByTime(1); + vi.advanceTimersByTime(1); // Old spans have been cleared away const finishedSpans2 = []; @@ -627,17 +628,17 @@ describe('Integration | Transactions', () => { it('allows to configure `maxSpanWaitDuration` to capture long running spans', async () => { const transactions: TransactionEvent[] = []; - const beforeSendTransaction = jest.fn(event => { + const beforeSendTransaction = vi.fn(event => { transactions.push(event); return null; }); const now = Date.now(); - jest.useFakeTimers(); - jest.setSystemTime(now); + vi.useFakeTimers(); + vi.setSystemTime(now); const logs: unknown[] = []; - jest.spyOn(logger, 'log').mockImplementation(msg => logs.push(msg)); + vi.spyOn(logger, 'log').mockImplementation(msg => logs.push(msg)); mockSdkInit({ tracesSampleRate: 1, @@ -669,7 +670,7 @@ describe('Integration | Transactions', () => { }); // Now wait for 100 mins - jest.advanceTimersByTime(100 * 60 * 1_000); + vi.advanceTimersByTime(100 * 60 * 1_000); expect(beforeSendTransaction).toHaveBeenCalledTimes(1); expect(transactions).toHaveLength(1); diff --git a/packages/node/test/integrations/context.test.ts b/packages/node/test/integrations/context.test.ts index dde182c552ba..cad71c5af728 100644 --- a/packages/node/test/integrations/context.test.ts +++ b/packages/node/test/integrations/context.test.ts @@ -1,12 +1,22 @@ import * as os from 'node:os'; +import { afterAll, describe, expect, it, vi } from 'vitest'; import { getAppContext, getDeviceContext } from '../../src/integrations/context'; import { conditionalTest } from '../helpers/conditional'; +vi.mock('node:os', async () => { + // eslint-disable-next-line @typescript-eslint/consistent-type-imports + const original = (await vi.importActual('node:os')) as typeof import('node:os'); + return { + ...original, + uptime: original.uptime, + }; +}); + describe('Context', () => { describe('getAppContext', () => { afterAll(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); conditionalTest({ max: 18 })('it does not return free_memory on older node versions', () => { @@ -23,7 +33,7 @@ describe('Context', () => { ); conditionalTest({ min: 22 })('returns no free_memory if process.availableMemory ', () => { - jest.spyOn(process as any, 'availableMemory').mockReturnValue(undefined as unknown as number); + vi.spyOn(process as any, 'availableMemory').mockReturnValue(undefined as unknown as number); const appContext = getAppContext(); expect(appContext.free_memory).toBeUndefined(); }); @@ -31,7 +41,7 @@ describe('Context', () => { describe('getDeviceContext', () => { afterAll(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); it('returns boot time if os.uptime is defined and returns a valid uptime', () => { @@ -40,7 +50,7 @@ describe('Context', () => { }); it('returns no boot time if os.uptime() returns undefined', () => { - jest.spyOn(os, 'uptime').mockReturnValue(undefined as unknown as number); + vi.spyOn(os, 'uptime').mockReturnValue(undefined as unknown as number); const deviceCtx = getDeviceContext({}); expect(deviceCtx.boot_time).toBeUndefined(); }); diff --git a/packages/node/test/integrations/contextlines.test.ts b/packages/node/test/integrations/contextlines.test.ts index 47827d8cfeb2..be074030b1a0 100644 --- a/packages/node/test/integrations/contextlines.test.ts +++ b/packages/node/test/integrations/contextlines.test.ts @@ -2,6 +2,7 @@ import * as fs from 'node:fs'; import { parseStackFrames } from '@sentry/core'; import type { StackFrame } from '@sentry/core'; +import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'; import { MAX_CONTEXTLINES_COLNO, MAX_CONTEXTLINES_LINENO, @@ -11,6 +12,15 @@ import { import { defaultStackParser } from '../../src/sdk/api'; import { getError } from '../helpers/error'; +vi.mock('node:fs', async () => { + // eslint-disable-next-line @typescript-eslint/consistent-type-imports + const original = (await vi.importActual('node:fs')) as typeof import('node:fs'); + return { + ...original, + createReadStream: original.createReadStream, + }; +}); + describe('ContextLines', () => { let contextLines: ReturnType; @@ -24,7 +34,7 @@ describe('ContextLines', () => { }); afterEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); describe('limits', () => { @@ -39,7 +49,7 @@ describe('ContextLines', () => { }, ]; - const readStreamSpy = jest.spyOn(fs, 'createReadStream'); + const readStreamSpy = vi.spyOn(fs, 'createReadStream'); await addContext(frames); expect(readStreamSpy).not.toHaveBeenCalled(); }); @@ -55,7 +65,7 @@ describe('ContextLines', () => { }, ]; - const readStreamSpy = jest.spyOn(fs, 'createReadStream'); + const readStreamSpy = vi.spyOn(fs, 'createReadStream'); await addContext(frames); expect(readStreamSpy).not.toHaveBeenCalled(); }); @@ -73,7 +83,7 @@ describe('ContextLines', () => { }, ]; - const readStreamSpy = jest.spyOn(fs, 'createReadStream'); + const readStreamSpy = vi.spyOn(fs, 'createReadStream'); await addContext(frames); expect(frames[0]!.pre_context).toBeUndefined(); @@ -85,7 +95,7 @@ describe('ContextLines', () => { expect.assertions(1); const frames = parseStackFrames(defaultStackParser, new Error('test')); - const readStreamSpy = jest.spyOn(fs, 'createReadStream'); + const readStreamSpy = vi.spyOn(fs, 'createReadStream'); await addContext(frames); const numCalls = readStreamSpy.mock.calls.length; @@ -99,7 +109,7 @@ describe('ContextLines', () => { test('parseStack with ESM module names', async () => { expect.assertions(1); - const readStreamSpy = jest.spyOn(fs, 'createReadStream'); + const readStreamSpy = vi.spyOn(fs, 'createReadStream'); const framesWithFilePath: StackFrame[] = [ { colno: 1, @@ -116,7 +126,7 @@ describe('ContextLines', () => { test('parseStack with adding different file', async () => { expect.assertions(1); const frames = parseStackFrames(defaultStackParser, new Error('test')); - const readStreamSpy = jest.spyOn(fs, 'createReadStream'); + const readStreamSpy = vi.spyOn(fs, 'createReadStream'); await addContext(frames); @@ -170,7 +180,7 @@ describe('ContextLines', () => { test('parseStack with duplicate files', async () => { expect.assertions(1); - const readStreamSpy = jest.spyOn(fs, 'createReadStream'); + const readStreamSpy = vi.spyOn(fs, 'createReadStream'); const framesWithDuplicateFiles: StackFrame[] = [ { colno: 1, @@ -198,7 +208,7 @@ describe('ContextLines', () => { test('stack errors without lineno', async () => { expect.assertions(1); - const readStreamSpy = jest.spyOn(fs, 'createReadStream'); + const readStreamSpy = vi.spyOn(fs, 'createReadStream'); const framesWithDuplicateFiles: StackFrame[] = [ { colno: 1, @@ -215,7 +225,7 @@ describe('ContextLines', () => { test('parseStack with no context', async () => { expect.assertions(1); contextLines = _contextLinesIntegration({ frameContextLines: 0 }); - const readStreamSpy = jest.spyOn(fs, 'createReadStream'); + const readStreamSpy = vi.spyOn(fs, 'createReadStream'); const frames = parseStackFrames(defaultStackParser, new Error('test')); diff --git a/packages/node/test/integrations/http.test.ts b/packages/node/test/integrations/http.test.ts index a6a8e612c019..ad59c1709646 100644 --- a/packages/node/test/integrations/http.test.ts +++ b/packages/node/test/integrations/http.test.ts @@ -1,3 +1,4 @@ +import { describe, expect, it } from 'vitest'; import { _shouldInstrumentSpans } from '../../src/integrations/http'; describe('httpIntegration', () => { diff --git a/packages/node/test/integrations/localvariables.test.ts b/packages/node/test/integrations/localvariables.test.ts index ad9f6804d9a3..72096fc4fa14 100644 --- a/packages/node/test/integrations/localvariables.test.ts +++ b/packages/node/test/integrations/localvariables.test.ts @@ -1,97 +1,102 @@ +import { describe, expect, it, vi } from 'vitest'; import { createRateLimiter } from '../../src/integrations/local-variables/common'; import { createCallbackList } from '../../src/integrations/local-variables/local-variables-sync'; import { NODE_MAJOR } from '../../src/nodeVersion'; -jest.useFakeTimers(); +vi.useFakeTimers(); const describeIf = (condition: boolean) => (condition ? describe : describe.skip); describeIf(NODE_MAJOR >= 18)('LocalVariables', () => { describe('createCallbackList', () => { - it('Should call callbacks in reverse order', done => { - const log: number[] = []; - - const { add, next } = createCallbackList(n => { - expect(log).toEqual([5, 4, 3, 2, 1]); - expect(n).toBe(15); - done(); - }); - - add(n => { - log.push(1); - next(n + 1); - }); - - add(n => { - log.push(2); - next(n + 1); - }); - - add(n => { - log.push(3); - next(n + 1); - }); - - add(n => { - log.push(4); - next(n + 1); - }); - - add(n => { - log.push(5); - next(n + 11); - }); - - next(0); - }); + it('Should call callbacks in reverse order', () => + new Promise(done => { + const log: number[] = []; - it('only calls complete once even if multiple next', done => { - const { add, next } = createCallbackList(n => { - expect(n).toBe(1); - done(); - }); + const { add, next } = createCallbackList(n => { + expect(log).toEqual([5, 4, 3, 2, 1]); + expect(n).toBe(15); + done(); + }); + + add(n => { + log.push(1); + next(n + 1); + }); + + add(n => { + log.push(2); + next(n + 1); + }); + + add(n => { + log.push(3); + next(n + 1); + }); + + add(n => { + log.push(4); + next(n + 1); + }); + + add(n => { + log.push(5); + next(n + 11); + }); + + next(0); + })); + + it('only calls complete once even if multiple next', () => + new Promise(done => { + const { add, next } = createCallbackList(n => { + expect(n).toBe(1); + done(); + }); - add(n => { - next(n + 1); - // We dont actually do this in our code... - next(n + 1); - }); + add(n => { + next(n + 1); + // We dont actually do this in our code... + next(n + 1); + }); - next(0); - }); + next(0); + })); - it('calls completed if added closure throws', done => { - const { add, next } = createCallbackList(n => { - expect(n).toBe(10); - done(); - }); + it('calls completed if added closure throws', () => + new Promise(done => { + const { add, next } = createCallbackList(n => { + expect(n).toBe(10); + done(); + }); - add(n => { - throw new Error('test'); - next(n + 1); - }); + add(n => { + throw new Error('test'); + next(n + 1); + }); - next(10); - }); + next(10); + })); }); describe('rateLimiter', () => { - it('calls disable if exceeded', done => { - const increment = createRateLimiter( - 5, - () => {}, - () => { - done(); - }, - ); - - for (let i = 0; i < 7; i++) { - increment(); - jest.advanceTimersByTime(100); - } - - jest.advanceTimersByTime(1_000); - }); + it('calls disable if exceeded', () => + new Promise(done => { + const increment = createRateLimiter( + 5, + () => {}, + () => { + done(); + }, + ); + + for (let i = 0; i < 7; i++) { + increment(); + vi.advanceTimersByTime(100); + } + + vi.advanceTimersByTime(1_000); + })); it('does not call disable if not exceeded', () => { const increment = createRateLimiter( @@ -106,38 +111,39 @@ describeIf(NODE_MAJOR >= 18)('LocalVariables', () => { for (let i = 0; i < 4; i++) { increment(); - jest.advanceTimersByTime(200); + vi.advanceTimersByTime(200); } - jest.advanceTimersByTime(600); + vi.advanceTimersByTime(600); for (let i = 0; i < 4; i++) { increment(); - jest.advanceTimersByTime(200); + vi.advanceTimersByTime(200); } }); - it('re-enables after timeout', done => { - let called = false; - - const increment = createRateLimiter( - 5, - () => { - expect(called).toEqual(true); - done(); - }, - () => { - expect(called).toEqual(false); - called = true; - }, - ); - - for (let i = 0; i < 10; i++) { - increment(); - jest.advanceTimersByTime(100); - } - - jest.advanceTimersByTime(10_000); - }); + it('re-enables after timeout', () => + new Promise(done => { + let called = false; + + const increment = createRateLimiter( + 5, + () => { + expect(called).toEqual(true); + done(); + }, + () => { + expect(called).toEqual(false); + called = true; + }, + ); + + for (let i = 0; i < 10; i++) { + increment(); + vi.advanceTimersByTime(100); + } + + vi.advanceTimersByTime(10_000); + })); }); }); diff --git a/packages/node/test/integrations/request-session-tracking.test.ts b/packages/node/test/integrations/request-session-tracking.test.ts index 7d5e4154d3fc..da4a6896a8ae 100644 --- a/packages/node/test/integrations/request-session-tracking.test.ts +++ b/packages/node/test/integrations/request-session-tracking.test.ts @@ -1,20 +1,21 @@ import { EventEmitter } from 'stream'; import { Scope, ServerRuntimeClient, createTransport, withScope } from '@sentry/core'; import type { Client } from '@sentry/core'; +import { describe, expect, it, vi } from 'vitest'; import { recordRequestSession } from '../../src/integrations/http/SentryHttpInstrumentation'; -jest.useFakeTimers(); +vi.useFakeTimers(); describe('recordRequestSession()', () => { it('should send an "exited" session for an ok ended request', () => { const client = createTestClient(); - const sendSessionSpy = jest.spyOn(client, 'sendSession'); + const sendSessionSpy = vi.spyOn(client, 'sendSession'); - jest.setSystemTime(new Date('March 19, 1999 06:12:34 UTC')); + vi.setSystemTime(new Date('March 19, 1999 06:12:34 UTC')); simulateRequest(client, 'ok'); - jest.runAllTimers(); + vi.runAllTimers(); expect(sendSessionSpy).toBeCalledWith({ aggregates: [{ crashed: 0, errored: 0, exited: 1, started: '1999-03-19T06:12:00.000Z' }], @@ -23,13 +24,13 @@ describe('recordRequestSession()', () => { it('should send an "crashed" session when the session on the requestProcessingMetadata was overridden with crashed', () => { const client = createTestClient(); - const sendSessionSpy = jest.spyOn(client, 'sendSession'); + const sendSessionSpy = vi.spyOn(client, 'sendSession'); - jest.setSystemTime(new Date('March 19, 1999 06:12:34 UTC')); + vi.setSystemTime(new Date('March 19, 1999 06:12:34 UTC')); simulateRequest(client, 'crashed'); - jest.runAllTimers(); + vi.runAllTimers(); expect(sendSessionSpy).toBeCalledWith({ aggregates: [{ crashed: 1, errored: 0, exited: 0, started: expect.stringMatching(/....-..-..T..:..:00.000Z/) }], @@ -38,13 +39,13 @@ describe('recordRequestSession()', () => { it('should send an "errored" session when the session on the requestProcessingMetadata was overridden with errored', () => { const client = createTestClient(); - const sendSessionSpy = jest.spyOn(client, 'sendSession'); + const sendSessionSpy = vi.spyOn(client, 'sendSession'); - jest.setSystemTime(new Date('March 19, 1999 06:12:34 UTC')); + vi.setSystemTime(new Date('March 19, 1999 06:12:34 UTC')); simulateRequest(client, 'errored'); - jest.runAllTimers(); + vi.runAllTimers(); expect(sendSessionSpy).toBeCalledWith({ aggregates: [{ crashed: 0, errored: 1, exited: 0, started: expect.stringMatching(/....-..-..T..:..:00.000Z/) }], @@ -54,9 +55,9 @@ describe('recordRequestSession()', () => { it('should aggregate request sessions within a time frame', async () => { const client = createTestClient(); - const sendSessionSpy = jest.spyOn(client, 'sendSession'); + const sendSessionSpy = vi.spyOn(client, 'sendSession'); - jest.setSystemTime(new Date('March 19, 1999 06:00:00 UTC')); + vi.setSystemTime(new Date('March 19, 1999 06:00:00 UTC')); simulateRequest(client, 'ok'); simulateRequest(client, 'ok'); @@ -64,12 +65,12 @@ describe('recordRequestSession()', () => { simulateRequest(client, 'errored'); // "Wait" 1+ second to get into new bucket - jest.setSystemTime(new Date('March 19, 1999 06:01:01 UTC')); + vi.setSystemTime(new Date('March 19, 1999 06:01:01 UTC')); simulateRequest(client, 'ok'); simulateRequest(client, 'errored'); - jest.runAllTimers(); + vi.runAllTimers(); expect(sendSessionSpy).toBeCalledWith({ aggregates: [ @@ -87,14 +88,14 @@ describe('recordRequestSession()', () => { it('should flush pending sessions when the client emits a "flush" hook', async () => { const client = createTestClient(); - const sendSessionSpy = jest.spyOn(client, 'sendSession'); + const sendSessionSpy = vi.spyOn(client, 'sendSession'); - jest.setSystemTime(new Date('March 19, 1999 06:00:00 UTC')); + vi.setSystemTime(new Date('March 19, 1999 06:00:00 UTC')); simulateRequest(client, 'ok'); // "Wait" 1+ second to get into new bucket - jest.setSystemTime(new Date('March 19, 1999 06:01:01 UTC')); + vi.setSystemTime(new Date('March 19, 1999 06:01:01 UTC')); simulateRequest(client, 'ok'); diff --git a/packages/node/test/integrations/spotlight.test.ts b/packages/node/test/integrations/spotlight.test.ts index fef4765c9b15..a26a36aced91 100644 --- a/packages/node/test/integrations/spotlight.test.ts +++ b/packages/node/test/integrations/spotlight.test.ts @@ -1,17 +1,27 @@ -import * as http from 'http'; +import * as http from 'node:http'; import { createEnvelope, logger } from '@sentry/core'; import type { Envelope, EventEnvelope } from '@sentry/core'; +import { afterEach, describe, expect, it, vi } from 'vitest'; import { spotlightIntegration } from '../../src/integrations/spotlight'; import { NodeClient } from '../../src/sdk/client'; import { getDefaultNodeClientOptions } from '../helpers/getDefaultNodeClientOptions'; +vi.mock('node:http', async () => { + // eslint-disable-next-line @typescript-eslint/consistent-type-imports + const original = (await vi.importActual('node:http')) as typeof import('node:http'); + return { + ...original, + request: original.request, + }; +}); + describe('Spotlight', () => { - const loggerSpy = jest.spyOn(logger, 'warn'); + const loggerSpy = vi.spyOn(logger, 'warn'); afterEach(() => { loggerSpy.mockClear(); - jest.clearAllMocks(); + vi.clearAllMocks(); }); const options = getDefaultNodeClientOptions(); @@ -25,7 +35,7 @@ describe('Spotlight', () => { it('registers a callback on the `beforeEnvelope` hook', () => { const clientWithSpy = { ...client, - on: jest.fn(), + on: vi.fn(), }; const integration = spotlightIntegration(); // @ts-expect-error - this is fine in tests @@ -34,18 +44,18 @@ describe('Spotlight', () => { }); it('sends an envelope POST request to the sidecar url', () => { - const httpSpy = jest.spyOn(http, 'request').mockImplementationOnce(() => { + const httpSpy = vi.spyOn(http, 'request').mockImplementationOnce(() => { return { - on: jest.fn(), - write: jest.fn(), - end: jest.fn(), + on: vi.fn(), + write: vi.fn(), + end: vi.fn(), } as any; }); let callback: (envelope: Envelope) => void = () => {}; const clientWithSpy = { ...client, - on: jest.fn().mockImplementationOnce((_, cb) => (callback = cb)), + on: vi.fn().mockImplementationOnce((_, cb) => (callback = cb)), }; const integration = spotlightIntegration(); @@ -73,18 +83,18 @@ describe('Spotlight', () => { }); it('sends an envelope POST request to a custom sidecar url', () => { - const httpSpy = jest.spyOn(http, 'request').mockImplementationOnce(() => { + const httpSpy = vi.spyOn(http, 'request').mockImplementationOnce(() => { return { - on: jest.fn(), - write: jest.fn(), - end: jest.fn(), + on: vi.fn(), + write: vi.fn(), + end: vi.fn(), } as any; }); let callback: (envelope: Envelope) => void = () => {}; const clientWithSpy = { ...client, - on: jest.fn().mockImplementationOnce((_, cb) => (callback = cb)), + on: vi.fn().mockImplementationOnce((_, cb) => (callback = cb)), }; const integration = spotlightIntegration({ sidecarUrl: 'http://mylocalhost:8888/abcd' }); diff --git a/packages/node/test/integrations/tracing/graphql.test.ts b/packages/node/test/integrations/tracing/graphql.test.ts index 779b8dace830..10b8783c3702 100644 --- a/packages/node/test/integrations/tracing/graphql.test.ts +++ b/packages/node/test/integrations/tracing/graphql.test.ts @@ -1,15 +1,16 @@ import { GraphQLInstrumentation } from '@opentelemetry/instrumentation-graphql'; +import { type MockInstance, beforeEach, describe, expect, it, vi } from 'vitest'; import { graphqlIntegration, instrumentGraphql } from '../../../src/integrations/tracing/graphql'; import { INSTRUMENTED } from '../../../src/otel/instrument'; -jest.mock('@opentelemetry/instrumentation-graphql'); +vi.mock('@opentelemetry/instrumentation-graphql'); describe('GraphQL', () => { beforeEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); delete INSTRUMENTED.Graphql; - (GraphQLInstrumentation as unknown as jest.SpyInstance).mockImplementation(() => { + (GraphQLInstrumentation as unknown as MockInstance).mockImplementation(() => { return { setTracerProvider: () => undefined, setMeterProvider: () => undefined, diff --git a/packages/node/test/integrations/tracing/mongo.test.ts b/packages/node/test/integrations/tracing/mongo.test.ts index 29571c07babe..c4944df08e16 100644 --- a/packages/node/test/integrations/tracing/mongo.test.ts +++ b/packages/node/test/integrations/tracing/mongo.test.ts @@ -1,5 +1,6 @@ import { MongoDBInstrumentation } from '@opentelemetry/instrumentation-mongodb'; +import { type MockInstance, beforeEach, describe, expect, it, vi } from 'vitest'; import { _defaultDbStatementSerializer, instrumentMongo, @@ -7,14 +8,14 @@ import { } from '../../../src/integrations/tracing/mongo'; import { INSTRUMENTED } from '../../../src/otel/instrument'; -jest.mock('@opentelemetry/instrumentation-mongodb'); +vi.mock('@opentelemetry/instrumentation-mongodb'); describe('Mongo', () => { beforeEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); delete INSTRUMENTED.Mongo; - (MongoDBInstrumentation as unknown as jest.SpyInstance).mockImplementation(() => { + (MongoDBInstrumentation as unknown as MockInstance).mockImplementation(() => { return { setTracerProvider: () => undefined, setMeterProvider: () => undefined, diff --git a/packages/node/test/integrations/tracing/redis.test.ts b/packages/node/test/integrations/tracing/redis.test.ts index 57eb727964be..a23d648b92d1 100644 --- a/packages/node/test/integrations/tracing/redis.test.ts +++ b/packages/node/test/integrations/tracing/redis.test.ts @@ -1,3 +1,4 @@ +import { describe, expect, it } from 'vitest'; import { GET_COMMANDS, SET_COMMANDS, diff --git a/packages/node/test/sdk/api.test.ts b/packages/node/test/sdk/api.test.ts index 40510e46744e..e171d1e6ee02 100644 --- a/packages/node/test/sdk/api.test.ts +++ b/packages/node/test/sdk/api.test.ts @@ -1,9 +1,10 @@ import type { Event } from '@sentry/core'; +import { afterEach, describe, expect, it, vi } from 'vitest'; import { getActiveSpan, getClient, startInactiveSpan, startSpan, withActiveSpan } from '../../src'; import { cleanupOtel, mockSdkInit } from '../helpers/mockSdkInit'; afterEach(() => { - jest.restoreAllMocks(); + vi.restoreAllMocks(); cleanupOtel(); }); @@ -21,7 +22,7 @@ describe('withActiveSpan()', () => { }); it('should create child spans when calling startSpan within the callback', async () => { - const beforeSendTransaction = jest.fn(() => null); + const beforeSendTransaction = vi.fn(() => null); mockSdkInit({ tracesSampleRate: 1, beforeSendTransaction }); const client = getClient(); @@ -66,7 +67,7 @@ describe('withActiveSpan()', () => { it('when `null` is passed, should start a new trace for new spans', async () => { const transactions: Event[] = []; - const beforeSendTransaction = jest.fn((event: Event) => { + const beforeSendTransaction = vi.fn((event: Event) => { transactions.push(event); return null; }); diff --git a/packages/node/test/sdk/client.test.ts b/packages/node/test/sdk/client.test.ts index 8eb66b78e82e..18b6c1d3ef53 100644 --- a/packages/node/test/sdk/client.test.ts +++ b/packages/node/test/sdk/client.test.ts @@ -4,6 +4,7 @@ import * as opentelemetryInstrumentationPackage from '@opentelemetry/instrumenta import type { Event, EventHint } from '@sentry/core'; import { SDK_VERSION, Scope, getCurrentScope, getGlobalScope, getIsolationScope } from '@sentry/core'; import { setOpenTelemetryContextAsyncContextStrategy } from '@sentry/opentelemetry'; +import { afterEach, beforeEach, describe, expect, it, test, vi } from 'vitest'; import { NodeClient } from '../../src'; import { getDefaultNodeClientOptions } from '../helpers/getDefaultNodeClientOptions'; import { cleanupOtel } from '../helpers/mockSdkInit'; @@ -18,7 +19,7 @@ describe('NodeClient', () => { }); afterEach(() => { - jest.restoreAllMocks(); + vi.restoreAllMocks(); cleanupOtel(); }); @@ -162,7 +163,7 @@ describe('NodeClient', () => { }); const client = new NodeClient(options); - const sendEnvelopeSpy = jest.spyOn(client, 'sendEnvelope'); + const sendEnvelopeSpy = vi.spyOn(client, 'sendEnvelope'); const id = client.captureCheckIn( { monitorSlug: 'foo', status: 'in_progress' }, @@ -232,7 +233,7 @@ describe('NodeClient', () => { }); const client = new NodeClient(options); - const sendEnvelopeSpy = jest.spyOn(client, 'sendEnvelope'); + const sendEnvelopeSpy = vi.spyOn(client, 'sendEnvelope'); const id = client.captureCheckIn({ monitorSlug: 'heartbeat-monitor', status: 'ok' }); @@ -258,7 +259,7 @@ describe('NodeClient', () => { const options = getDefaultNodeClientOptions({ serverName: 'bar', enabled: false }); const client = new NodeClient(options); - const sendEnvelopeSpy = jest.spyOn(client, 'sendEnvelope'); + const sendEnvelopeSpy = vi.spyOn(client, 'sendEnvelope'); client.captureCheckIn({ monitorSlug: 'foo', status: 'in_progress' }); @@ -267,7 +268,7 @@ describe('NodeClient', () => { }); it('registers instrumentations provided with `openTelemetryInstrumentations`', () => { - const registerInstrumentationsSpy = jest + const registerInstrumentationsSpy = vi .spyOn(opentelemetryInstrumentationPackage, 'registerInstrumentations') .mockImplementationOnce(() => () => undefined); const instrumentationsArray = ['foobar'] as unknown as opentelemetryInstrumentationPackage.Instrumentation[]; diff --git a/packages/node/test/sdk/init.test.ts b/packages/node/test/sdk/init.test.ts index f6a02c2af4bd..a07e36a62d5a 100644 --- a/packages/node/test/sdk/init.test.ts +++ b/packages/node/test/sdk/init.test.ts @@ -2,6 +2,7 @@ import { logger } from '@sentry/core'; import type { Integration } from '@sentry/core'; import * as SentryOpentelemetry from '@sentry/opentelemetry'; +import { type Mock, type MockInstance, afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { getClient } from '../../src/'; import * as auto from '../../src/integrations/tracing'; import { init, validateOpenTelemetrySetup } from '../../src/sdk'; @@ -15,25 +16,25 @@ const PUBLIC_DSN = 'https://username@domain/123'; class MockIntegration implements Integration { public name: string; - public setupOnce: jest.Mock = jest.fn(); + public setupOnce: Mock = vi.fn(); public constructor(name: string) { this.name = name; } } describe('init()', () => { - let mockAutoPerformanceIntegrations: jest.SpyInstance = jest.fn(() => []); + let mockAutoPerformanceIntegrations: MockInstance = vi.fn(() => []); beforeEach(() => { global.__SENTRY__ = {}; - mockAutoPerformanceIntegrations = jest.spyOn(auto, 'getAutoPerformanceIntegrations').mockImplementation(() => []); + mockAutoPerformanceIntegrations = vi.spyOn(auto, 'getAutoPerformanceIntegrations').mockImplementation(() => []); }); afterEach(() => { cleanupOtel(); - jest.clearAllMocks(); + vi.clearAllMocks(); }); describe('integrations', () => { @@ -64,10 +65,10 @@ describe('init()', () => { init({ dsn: PUBLIC_DSN, integrations: mockIntegrations, defaultIntegrations: mockDefaultIntegrations }); - expect(mockDefaultIntegrations[0]?.setupOnce as jest.Mock).toHaveBeenCalledTimes(0); - expect(mockDefaultIntegrations[1]?.setupOnce as jest.Mock).toHaveBeenCalledTimes(1); - expect(mockIntegrations[0]?.setupOnce as jest.Mock).toHaveBeenCalledTimes(1); - expect(mockIntegrations[1]?.setupOnce as jest.Mock).toHaveBeenCalledTimes(1); + expect(mockDefaultIntegrations[0]?.setupOnce as Mock).toHaveBeenCalledTimes(0); + expect(mockDefaultIntegrations[1]?.setupOnce as Mock).toHaveBeenCalledTimes(1); + expect(mockIntegrations[0]?.setupOnce as Mock).toHaveBeenCalledTimes(1); + expect(mockIntegrations[1]?.setupOnce as Mock).toHaveBeenCalledTimes(1); expect(mockAutoPerformanceIntegrations).toHaveBeenCalledTimes(0); }); @@ -89,9 +90,9 @@ describe('init()', () => { }, }); - expect(mockDefaultIntegrations[0]?.setupOnce as jest.Mock).toHaveBeenCalledTimes(1); - expect(mockDefaultIntegrations[1]?.setupOnce as jest.Mock).toHaveBeenCalledTimes(0); - expect(newIntegration.setupOnce as jest.Mock).toHaveBeenCalledTimes(1); + expect(mockDefaultIntegrations[0]?.setupOnce as Mock).toHaveBeenCalledTimes(1); + expect(mockDefaultIntegrations[1]?.setupOnce as Mock).toHaveBeenCalledTimes(0); + expect(newIntegration.setupOnce as Mock).toHaveBeenCalledTimes(1); expect(mockAutoPerformanceIntegrations).toHaveBeenCalledTimes(0); }); @@ -111,9 +112,9 @@ describe('init()', () => { tracesSampleRate: 1, }); - expect(mockIntegrations[0]?.setupOnce as jest.Mock).toHaveBeenCalledTimes(1); - expect(mockIntegrations[1]?.setupOnce as jest.Mock).toHaveBeenCalledTimes(1); - expect(autoPerformanceIntegration.setupOnce as jest.Mock).toHaveBeenCalledTimes(1); + expect(mockIntegrations[0]?.setupOnce as Mock).toHaveBeenCalledTimes(1); + expect(mockIntegrations[1]?.setupOnce as Mock).toHaveBeenCalledTimes(1); + expect(autoPerformanceIntegration.setupOnce as Mock).toHaveBeenCalledTimes(1); expect(mockAutoPerformanceIntegrations).toHaveBeenCalledTimes(1); const client = getClient(); @@ -154,14 +155,14 @@ describe('validateOpenTelemetrySetup', () => { afterEach(() => { global.__SENTRY__ = {}; cleanupOtel(); - jest.clearAllMocks(); + vi.clearAllMocks(); }); it('works with correct setup', () => { - const errorSpy = jest.spyOn(logger, 'error').mockImplementation(() => {}); - const warnSpy = jest.spyOn(logger, 'warn').mockImplementation(() => {}); + const errorSpy = vi.spyOn(logger, 'error').mockImplementation(() => {}); + const warnSpy = vi.spyOn(logger, 'warn').mockImplementation(() => {}); - jest.spyOn(SentryOpentelemetry, 'openTelemetrySetupCheck').mockImplementation(() => { + vi.spyOn(SentryOpentelemetry, 'openTelemetrySetupCheck').mockImplementation(() => { return ['SentryContextManager', 'SentryPropagator', 'SentrySampler']; }); @@ -172,10 +173,10 @@ describe('validateOpenTelemetrySetup', () => { }); it('works with missing setup, without tracing', () => { - const errorSpy = jest.spyOn(logger, 'error').mockImplementation(() => {}); - const warnSpy = jest.spyOn(logger, 'warn').mockImplementation(() => {}); + const errorSpy = vi.spyOn(logger, 'error').mockImplementation(() => {}); + const warnSpy = vi.spyOn(logger, 'warn').mockImplementation(() => {}); - jest.spyOn(SentryOpentelemetry, 'openTelemetrySetupCheck').mockImplementation(() => { + vi.spyOn(SentryOpentelemetry, 'openTelemetrySetupCheck').mockImplementation(() => { return []; }); @@ -191,10 +192,10 @@ describe('validateOpenTelemetrySetup', () => { }); it('works with missing setup, with tracing', () => { - const errorSpy = jest.spyOn(logger, 'error').mockImplementation(() => {}); - const warnSpy = jest.spyOn(logger, 'warn').mockImplementation(() => {}); + const errorSpy = vi.spyOn(logger, 'error').mockImplementation(() => {}); + const warnSpy = vi.spyOn(logger, 'warn').mockImplementation(() => {}); - jest.spyOn(SentryOpentelemetry, 'openTelemetrySetupCheck').mockImplementation(() => { + vi.spyOn(SentryOpentelemetry, 'openTelemetrySetupCheck').mockImplementation(() => { return []; }); diff --git a/packages/node/test/sdk/initOtel.test.ts b/packages/node/test/sdk/initOtel.test.ts index bb3c3a29c919..69c1da3fc258 100644 --- a/packages/node/test/sdk/initOtel.test.ts +++ b/packages/node/test/sdk/initOtel.test.ts @@ -1,27 +1,28 @@ import { logger } from '@sentry/core'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; import { _clampSpanProcessorTimeout } from '../../src/sdk/initOtel'; describe('_clampSpanProcessorTimeout', () => { beforeEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); it('works with undefined', () => { - const loggerWarnSpy = jest.spyOn(logger, 'warn').mockImplementation(() => {}); + const loggerWarnSpy = vi.spyOn(logger, 'warn').mockImplementation(() => {}); const timeout = _clampSpanProcessorTimeout(undefined); expect(timeout).toBe(undefined); expect(loggerWarnSpy).not.toHaveBeenCalled(); }); it('works with positive number', () => { - const loggerWarnSpy = jest.spyOn(logger, 'warn').mockImplementation(() => {}); + const loggerWarnSpy = vi.spyOn(logger, 'warn').mockImplementation(() => {}); const timeout = _clampSpanProcessorTimeout(10); expect(timeout).toBe(10); expect(loggerWarnSpy).not.toHaveBeenCalled(); }); it('works with 0', () => { - const loggerWarnSpy = jest.spyOn(logger, 'warn').mockImplementation(() => {}); + const loggerWarnSpy = vi.spyOn(logger, 'warn').mockImplementation(() => {}); const timeout = _clampSpanProcessorTimeout(0); expect(timeout).toBe(undefined); expect(loggerWarnSpy).toHaveBeenCalledTimes(1); @@ -31,7 +32,7 @@ describe('_clampSpanProcessorTimeout', () => { }); it('works with negative number', () => { - const loggerWarnSpy = jest.spyOn(logger, 'warn').mockImplementation(() => {}); + const loggerWarnSpy = vi.spyOn(logger, 'warn').mockImplementation(() => {}); const timeout = _clampSpanProcessorTimeout(-10); expect(timeout).toBe(undefined); expect(loggerWarnSpy).toHaveBeenCalledTimes(1); @@ -41,7 +42,7 @@ describe('_clampSpanProcessorTimeout', () => { }); it('works with -Infinity', () => { - const loggerWarnSpy = jest.spyOn(logger, 'warn').mockImplementation(() => {}); + const loggerWarnSpy = vi.spyOn(logger, 'warn').mockImplementation(() => {}); const timeout = _clampSpanProcessorTimeout(-Infinity); expect(timeout).toBe(undefined); expect(loggerWarnSpy).toHaveBeenCalledTimes(1); @@ -51,7 +52,7 @@ describe('_clampSpanProcessorTimeout', () => { }); it('works with Infinity', () => { - const loggerWarnSpy = jest.spyOn(logger, 'warn').mockImplementation(() => {}); + const loggerWarnSpy = vi.spyOn(logger, 'warn').mockImplementation(() => {}); const timeout = _clampSpanProcessorTimeout(Infinity); expect(timeout).toBe(1_000_000); expect(loggerWarnSpy).toHaveBeenCalledTimes(1); @@ -59,7 +60,7 @@ describe('_clampSpanProcessorTimeout', () => { }); it('works with large number', () => { - const loggerWarnSpy = jest.spyOn(logger, 'warn').mockImplementation(() => {}); + const loggerWarnSpy = vi.spyOn(logger, 'warn').mockImplementation(() => {}); const timeout = _clampSpanProcessorTimeout(1_000_000_000); expect(timeout).toBe(1_000_000); expect(loggerWarnSpy).toHaveBeenCalledTimes(1); @@ -67,7 +68,7 @@ describe('_clampSpanProcessorTimeout', () => { }); it('works with NaN', () => { - const loggerWarnSpy = jest.spyOn(logger, 'warn').mockImplementation(() => {}); + const loggerWarnSpy = vi.spyOn(logger, 'warn').mockImplementation(() => {}); const timeout = _clampSpanProcessorTimeout(NaN); expect(timeout).toBe(undefined); expect(loggerWarnSpy).toHaveBeenCalledTimes(1); diff --git a/packages/node/test/sdk/preload.test.ts b/packages/node/test/sdk/preload.test.ts index 70dffe039a82..8daf8ada5c4b 100644 --- a/packages/node/test/sdk/preload.test.ts +++ b/packages/node/test/sdk/preload.test.ts @@ -1,18 +1,19 @@ import { logger } from '@sentry/core'; +import { afterEach, describe, expect, it, vi } from 'vitest'; describe('preload', () => { afterEach(() => { - jest.resetAllMocks(); + vi.resetAllMocks(); logger.disable(); delete process.env.SENTRY_DEBUG; delete process.env.SENTRY_PRELOAD_INTEGRATIONS; - jest.resetModules(); + vi.resetModules(); }); it('works without env vars', async () => { - const logSpy = jest.spyOn(console, 'log'); + const logSpy = vi.spyOn(console, 'log'); await import('../../src/preload'); @@ -20,9 +21,9 @@ describe('preload', () => { }); it('works with SENTRY_DEBUG set', async () => { - const logSpy = jest.spyOn(console, 'log').mockImplementation(() => {}); + const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); // We want to swallow these logs - jest.spyOn(console, 'debug').mockImplementation(() => {}); + vi.spyOn(console, 'debug').mockImplementation(() => {}); process.env.SENTRY_DEBUG = '1'; @@ -34,9 +35,9 @@ describe('preload', () => { }); it('works with SENTRY_DEBUG & SENTRY_PRELOAD_INTEGRATIONS set', async () => { - const logSpy = jest.spyOn(console, 'log').mockImplementation(() => {}); + const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); // We want to swallow these logs - jest.spyOn(console, 'debug').mockImplementation(() => {}); + vi.spyOn(console, 'debug').mockImplementation(() => {}); process.env.SENTRY_DEBUG = '1'; process.env.SENTRY_PRELOAD_INTEGRATIONS = 'Http,Express'; diff --git a/packages/node/test/transports/http.test.ts b/packages/node/test/transports/http.test.ts index 68b79f05f77d..4dcf31dd2661 100644 --- a/packages/node/test/transports/http.test.ts +++ b/packages/node/test/transports/http.test.ts @@ -4,13 +4,24 @@ import { createTransport } from '@sentry/core'; import { addItemToEnvelope, createAttachmentEnvelopeItem, createEnvelope, serializeEnvelope } from '@sentry/core'; import type { EventEnvelope, EventItem } from '@sentry/core'; +import { type Mock, afterEach, describe, expect, it, vi } from 'vitest'; import { makeNodeTransport } from '../../src/transports'; -jest.mock('@sentry/core', () => { - const actualCore = jest.requireActual('@sentry/core'); +vi.mock('@sentry/core', async () => { + // eslint-disable-next-line @typescript-eslint/consistent-type-imports + const actualCore = (await vi.importActual('@sentry/core')) as typeof import('@sentry/core'); return { ...actualCore, - createTransport: jest.fn().mockImplementation(actualCore.createTransport), + createTransport: vi.fn().mockImplementation(actualCore.createTransport), + }; +}); + +vi.mock('node:http', async () => { + // eslint-disable-next-line @typescript-eslint/consistent-type-imports + const original = (await vi.importActual('node:http')) as typeof import('node:http'); + return { + ...original, + request: original.request, }; }); @@ -78,17 +89,20 @@ const defaultOptions = { }; // empty function to keep test output clean -const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {}); +const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}); -afterEach(done => { - jest.clearAllMocks(); +afterEach( + () => + new Promise(done => { + vi.clearAllMocks(); - if (testServer?.listening) { - testServer.close(done); - } else { - done(); - } -}); + if (testServer?.listening) { + testServer.close(() => done()); + } else { + done(); + } + }), +); describe('makeNewHttpTransport()', () => { describe('.send()', () => { @@ -206,7 +220,7 @@ describe('makeNewHttpTransport()', () => { }); describe('proxy', () => { - const proxyAgentSpy = jest + const proxyAgentSpy = vi .spyOn(httpProxyAgent, 'HttpsProxyAgent') // @ts-expect-error using http agent as https proxy agent .mockImplementation(() => new http.Agent({ keepAlive: false, maxSockets: 30, timeout: 2000 })); @@ -299,7 +313,7 @@ describe('makeNewHttpTransport()', () => { }); makeNodeTransport(defaultOptions); - const registeredRequestExecutor = (createTransport as jest.Mock).mock.calls[0][1]; + const registeredRequestExecutor = (createTransport as Mock).mock.calls[0]?.[1]; const executorResult = registeredRequestExecutor({ body: serializeEnvelope(EVENT_ENVELOPE), @@ -319,7 +333,7 @@ describe('makeNewHttpTransport()', () => { }); makeNodeTransport(defaultOptions); - const registeredRequestExecutor = (createTransport as jest.Mock).mock.calls[0][1]; + const registeredRequestExecutor = (createTransport as Mock).mock.calls[0]?.[1]; const executorResult = registeredRequestExecutor({ body: serializeEnvelope(EVENT_ENVELOPE), @@ -347,7 +361,7 @@ describe('makeNewHttpTransport()', () => { }); makeNodeTransport(defaultOptions); - const registeredRequestExecutor = (createTransport as jest.Mock).mock.calls[0][1]; + const registeredRequestExecutor = (createTransport as Mock).mock.calls[0]?.[1]; const executorResult = registeredRequestExecutor({ body: serializeEnvelope(EVENT_ENVELOPE), @@ -375,7 +389,7 @@ describe('makeNewHttpTransport()', () => { }); makeNodeTransport(defaultOptions); - const registeredRequestExecutor = (createTransport as jest.Mock).mock.calls[0][1]; + const registeredRequestExecutor = (createTransport as Mock).mock.calls[0]?.[1]; const executorResult = registeredRequestExecutor({ body: serializeEnvelope(EVENT_ENVELOPE), @@ -395,7 +409,7 @@ describe('makeNewHttpTransport()', () => { }); it('should create a noop transport if an invalid url is passed', async () => { - const requestSpy = jest.spyOn(http, 'request'); + const requestSpy = vi.spyOn(http, 'request'); const transport = makeNodeTransport({ ...defaultOptions, url: 'foo' }); await transport.send(EVENT_ENVELOPE); expect(requestSpy).not.toHaveBeenCalled(); diff --git a/packages/node/test/transports/https.test.ts b/packages/node/test/transports/https.test.ts index 3c1743178e87..b8a7d605b2f3 100644 --- a/packages/node/test/transports/https.test.ts +++ b/packages/node/test/transports/https.test.ts @@ -4,15 +4,17 @@ import { createTransport } from '@sentry/core'; import { createEnvelope, serializeEnvelope } from '@sentry/core'; import type { EventEnvelope, EventItem } from '@sentry/core'; +import { type Mock, afterEach, describe, expect, it, vi } from 'vitest'; import { makeNodeTransport } from '../../src/transports'; import type { HTTPModule, HTTPModuleRequestIncomingMessage } from '../../src/transports/http-module'; import testServerCerts from './test-server-certs'; -jest.mock('@sentry/core', () => { - const actualCore = jest.requireActual('@sentry/core'); +vi.mock('@sentry/core', async () => { + // eslint-disable-next-line @typescript-eslint/consistent-type-imports + const actualCore = (await vi.importActual('@sentry/core')) as typeof import('@sentry/core'); return { ...actualCore, - createTransport: jest.fn().mockImplementation(actualCore.createTransport), + createTransport: vi.fn().mockImplementation(actualCore.createTransport), }; }); @@ -69,7 +71,7 @@ const EVENT_ENVELOPE = createEnvelope({ event_id: 'aa3ff046696b4b const SERIALIZED_EVENT_ENVELOPE = serializeEnvelope(EVENT_ENVELOPE); const unsafeHttpsModule: HTTPModule = { - request: jest + request: vi .fn() .mockImplementation((options: https.RequestOptions, callback?: (res: HTTPModuleRequestIncomingMessage) => void) => { return https.request({ ...options, rejectUnauthorized: false }, callback); @@ -82,15 +84,18 @@ const defaultOptions = { recordDroppedEvent: () => undefined, // noop }; -afterEach(done => { - jest.clearAllMocks(); +afterEach( + () => + new Promise(done => { + vi.clearAllMocks(); - if (testServer?.listening) { - testServer.close(done); - } else { - done(); - } -}); + if (testServer?.listening) { + testServer.close(() => done()); + } else { + done(); + } + }), +); describe('makeNewHttpsTransport()', () => { describe('.send()', () => { @@ -180,7 +185,7 @@ describe('makeNewHttpsTransport()', () => { }); describe('proxy', () => { - const proxyAgentSpy = jest + const proxyAgentSpy = vi .spyOn(httpProxyAgent, 'HttpsProxyAgent') // @ts-expect-error using http agent as https proxy agent .mockImplementation(() => new http.Agent({ keepAlive: false, maxSockets: 30, timeout: 2000 })); @@ -291,7 +296,7 @@ describe('makeNewHttpsTransport()', () => { }); makeNodeTransport(defaultOptions); - const registeredRequestExecutor = (createTransport as jest.Mock).mock.calls[0][1]; + const registeredRequestExecutor = (createTransport as Mock).mock.calls[0]?.[1]; const executorResult = registeredRequestExecutor({ body: serializeEnvelope(EVENT_ENVELOPE), @@ -311,7 +316,7 @@ describe('makeNewHttpsTransport()', () => { }); makeNodeTransport(defaultOptions); - const registeredRequestExecutor = (createTransport as jest.Mock).mock.calls[0][1]; + const registeredRequestExecutor = (createTransport as Mock).mock.calls[0]?.[1]; const executorResult = registeredRequestExecutor({ body: serializeEnvelope(EVENT_ENVELOPE), @@ -339,7 +344,7 @@ describe('makeNewHttpsTransport()', () => { }); makeNodeTransport(defaultOptions); - const registeredRequestExecutor = (createTransport as jest.Mock).mock.calls[0][1]; + const registeredRequestExecutor = (createTransport as Mock).mock.calls[0]?.[1]; const executorResult = registeredRequestExecutor({ body: serializeEnvelope(EVENT_ENVELOPE), @@ -367,7 +372,7 @@ describe('makeNewHttpsTransport()', () => { }); makeNodeTransport(defaultOptions); - const registeredRequestExecutor = (createTransport as jest.Mock).mock.calls[0][1]; + const registeredRequestExecutor = (createTransport as Mock).mock.calls[0]?.[1]; const executorResult = registeredRequestExecutor({ body: serializeEnvelope(EVENT_ENVELOPE), diff --git a/packages/node/test/utils/ensureIsWrapped.test.ts b/packages/node/test/utils/ensureIsWrapped.test.ts index c328545315ce..890b913a4cb2 100644 --- a/packages/node/test/utils/ensureIsWrapped.test.ts +++ b/packages/node/test/utils/ensureIsWrapped.test.ts @@ -1,3 +1,4 @@ +import { afterEach, describe, expect, it, vi } from 'vitest'; import { ensureIsWrapped } from '../../src/utils/ensureIsWrapped'; import { cleanupOtel, mockSdkInit, resetGlobals } from '../helpers/mockSdkInit'; @@ -12,13 +13,13 @@ const wrappedfunction = Object.assign(() => {}, { describe('ensureIsWrapped', () => { afterEach(() => { - jest.restoreAllMocks(); + vi.restoreAllMocks(); cleanupOtel(); resetGlobals(); }); it('warns when the method is unwrapped', () => { - const spyWarn = jest.spyOn(console, 'warn').mockImplementation(() => {}); + const spyWarn = vi.spyOn(console, 'warn').mockImplementation(() => {}); mockSdkInit({ tracesSampleRate: 1 }); @@ -31,7 +32,7 @@ describe('ensureIsWrapped', () => { }); it('does not warn when the method is wrapped', () => { - const spyWarn = jest.spyOn(console, 'warn').mockImplementation(() => {}); + const spyWarn = vi.spyOn(console, 'warn').mockImplementation(() => {}); mockSdkInit({ tracesSampleRate: 1 }); @@ -41,7 +42,7 @@ describe('ensureIsWrapped', () => { }); it('does not warn without a client', () => { - const spyWarn = jest.spyOn(console, 'warn').mockImplementation(() => {}); + const spyWarn = vi.spyOn(console, 'warn').mockImplementation(() => {}); resetGlobals(); ensureIsWrapped(wrappedfunction, 'express'); @@ -50,7 +51,7 @@ describe('ensureIsWrapped', () => { }); it('does not warn without tracing', () => { - const spyWarn = jest.spyOn(console, 'warn').mockImplementation(() => {}); + const spyWarn = vi.spyOn(console, 'warn').mockImplementation(() => {}); mockSdkInit({}); @@ -60,7 +61,7 @@ describe('ensureIsWrapped', () => { }); it('does not warn if disableInstrumentationWarnings=true', () => { - const spyWarn = jest.spyOn(console, 'warn').mockImplementation(() => {}); + const spyWarn = vi.spyOn(console, 'warn').mockImplementation(() => {}); mockSdkInit({ tracesSampleRate: 1, disableInstrumentationWarnings: true }); diff --git a/packages/node/test/utils/entry-point.test.ts b/packages/node/test/utils/entry-point.test.ts index 5013482bca46..bd65ca5506c0 100644 --- a/packages/node/test/utils/entry-point.test.ts +++ b/packages/node/test/utils/entry-point.test.ts @@ -1,3 +1,4 @@ +import { describe, expect, it } from 'vitest'; import type { ProcessArgs, ProcessInterface } from '../../src/utils/entry-point'; import { getEntryPointType, parseProcessPaths } from '../../src/utils/entry-point'; diff --git a/packages/node/test/utils/envToBool.test.ts b/packages/node/test/utils/envToBool.test.ts index cd06ef132267..aa3c73fe1e8f 100644 --- a/packages/node/test/utils/envToBool.test.ts +++ b/packages/node/test/utils/envToBool.test.ts @@ -1,3 +1,4 @@ +import { describe, expect, it } from 'vitest'; import { envToBool } from '../../src/utils/envToBool'; describe('envToBool', () => { diff --git a/packages/node/test/utils/getRequestUrl.test.ts b/packages/node/test/utils/getRequestUrl.test.ts index caa92aa10a59..621896987390 100644 --- a/packages/node/test/utils/getRequestUrl.test.ts +++ b/packages/node/test/utils/getRequestUrl.test.ts @@ -1,5 +1,6 @@ import type { RequestOptions } from 'http'; +import { describe, expect, it } from 'vitest'; import { getRequestUrl } from '../../src/utils/getRequestUrl'; describe('getRequestUrl', () => { diff --git a/packages/node/test/utils/module.test.ts b/packages/node/test/utils/module.test.ts index 1616bc7482d9..73404c37673e 100644 --- a/packages/node/test/utils/module.test.ts +++ b/packages/node/test/utils/module.test.ts @@ -1,3 +1,4 @@ +import { describe, expect, it } from 'vitest'; import { createGetModuleFromFilename } from '../../src'; describe('createGetModuleFromFilename', () => { diff --git a/packages/node/tsconfig.test.json b/packages/node/tsconfig.test.json index b0c6b000999b..3f2ffb86f0f7 100644 --- a/packages/node/tsconfig.test.json +++ b/packages/node/tsconfig.test.json @@ -1,11 +1,11 @@ { "extends": "./tsconfig.json", - "include": ["test/**/*", "./src/integrations/diagnostic_channel.d.ts"], + "include": ["test/**/*", "./src/integrations/diagnostic_channel.d.ts", "vite.config.ts"], "compilerOptions": { // should include all types from `./tsconfig.json` plus types for all test frameworks used - "types": ["node", "jest"] + "types": ["node"] // other package-specific, test-specific options } diff --git a/packages/node/vite.config.ts b/packages/node/vite.config.ts new file mode 100644 index 000000000000..f18ec92095bc --- /dev/null +++ b/packages/node/vite.config.ts @@ -0,0 +1,8 @@ +import baseConfig from '../../vite/vite.config'; + +export default { + ...baseConfig, + test: { + ...baseConfig.test, + }, +};