diff --git a/packages/vue/jest.config.js b/packages/vue/jest.config.js deleted file mode 100644 index cd02790794a7..000000000000 --- a/packages/vue/jest.config.js +++ /dev/null @@ -1,6 +0,0 @@ -const baseConfig = require('../../jest/jest.config.js'); - -module.exports = { - ...baseConfig, - testEnvironment: 'jsdom', -}; diff --git a/packages/vue/package.json b/packages/vue/package.json index 0dc72164cdc9..76ae5cf9a90a 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -66,8 +66,8 @@ "clean": "rimraf build coverage sentry-vue-*.tgz", "fix": "eslint . --format stylish --fix", "lint": "eslint . --format stylish", - "test": "jest", - "test:watch": "jest --watch", + "test": "vitest run", + "test:watch": "vitest --watch", "yalc:publish": "yalc publish --push --sig" }, "volta": { diff --git a/packages/vue/test/errorHandler.test.ts b/packages/vue/test/errorHandler.test.ts index e6ac911c533c..273d1dfecd0e 100644 --- a/packages/vue/test/errorHandler.test.ts +++ b/packages/vue/test/errorHandler.test.ts @@ -1,3 +1,5 @@ +import { afterEach, describe, expect, test, vi } from 'vitest'; + import { setCurrentClient } from '@sentry/browser'; import { attachErrorHandler } from '../src/errorhandler'; @@ -7,7 +9,7 @@ import { generateComponentTrace } from '../src/vendor/components'; describe('attachErrorHandler', () => { describe('attachProps', () => { afterEach(() => { - jest.resetAllMocks(); + vi.resetAllMocks(); }); describe("given I don't want to `attachProps`", () => { @@ -325,13 +327,13 @@ const testHarness = ({ enableConsole, vm, }: TestHarnessOpts) => { - jest.useFakeTimers(); - const providedErrorHandlerSpy = jest.fn(); - const warnHandlerSpy = jest.fn(); - const consoleErrorSpy = jest.fn(); + vi.useFakeTimers(); + const providedErrorHandlerSpy = vi.fn(); + const warnHandlerSpy = vi.fn(); + const consoleErrorSpy = vi.fn(); const client: any = { - captureException: jest.fn(async () => Promise.resolve()), + captureException: vi.fn(async () => Promise.resolve()), }; setCurrentClient(client); @@ -339,7 +341,7 @@ const testHarness = ({ config: { silent: !!silent, }, - mixin: jest.fn(), + mixin: vi.fn(), }; if (enableErrorHandler) { @@ -380,7 +382,7 @@ const testHarness = ({ app.config.errorHandler(new DummyError(), vm, 'stub-lifecycle-hook'); // and waits for internal timers - jest.runAllTimers(); + vi.runAllTimers(); }, expect: { errorHandlerSpy: expect(providedErrorHandlerSpy), diff --git a/packages/vue/test/integration/VueIntegration.test.ts b/packages/vue/test/integration/VueIntegration.test.ts index 81e3b863a16e..9f0aeecaa722 100644 --- a/packages/vue/test/integration/VueIntegration.test.ts +++ b/packages/vue/test/integration/VueIntegration.test.ts @@ -1,3 +1,9 @@ +/** + * @vitest-environment jsdom + */ + +import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'; + import type { Client } from '@sentry/types'; import { logger } from '@sentry/utils'; import { createApp } from 'vue'; @@ -15,10 +21,10 @@ describe('Sentry.VueIntegration', () => { const globalRequest = globalThis.Request; beforeAll(() => { - globalThis.fetch = jest.fn(); + globalThis.fetch = vi.fn(); // @ts-expect-error This is a mock - globalThis.Response = jest.fn(); - globalThis.Request = jest.fn(); + globalThis.Response = vi.fn(); + globalThis.Request = vi.fn(); }); afterAll(() => { @@ -31,17 +37,17 @@ describe('Sentry.VueIntegration', () => { warnings = []; loggerWarnings = []; - jest.spyOn(logger, 'warn').mockImplementation((message: unknown) => { + vi.spyOn(logger, 'warn').mockImplementation((message: unknown) => { loggerWarnings.push(message); }); - jest.spyOn(console, 'warn').mockImplementation((message: unknown) => { + vi.spyOn(console, 'warn').mockImplementation((message: unknown) => { warnings.push(message); }); }); afterEach(() => { - jest.resetAllMocks(); + vi.resetAllMocks(); }); it('allows to initialize integration later', () => { diff --git a/packages/vue/test/integration/init.test.ts b/packages/vue/test/integration/init.test.ts index c611900ed3b0..fd9d7c56fc93 100644 --- a/packages/vue/test/integration/init.test.ts +++ b/packages/vue/test/integration/init.test.ts @@ -1,3 +1,9 @@ +/** + * @vitest-environment jsdom + */ + +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; + import { createApp } from 'vue'; import type { Client } from '@sentry/types'; @@ -11,13 +17,13 @@ describe('Sentry.init', () => { beforeEach(() => { warnings = []; - jest.spyOn(console, 'warn').mockImplementation((message: unknown) => { + vi.spyOn(console, 'warn').mockImplementation((message: unknown) => { warnings.push(message); }); }); afterEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); it('does not warn when correctly setup (Vue 3)', () => { diff --git a/packages/vue/test/router.test.ts b/packages/vue/test/router.test.ts index 8c7ca7c73e93..dc69d7ae0fd9 100644 --- a/packages/vue/test/router.test.ts +++ b/packages/vue/test/router.test.ts @@ -1,3 +1,5 @@ +import { afterEach, describe, expect, it, vi } from 'vitest'; + import * as SentryBrowser from '@sentry/browser'; import * as SentryCore from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core'; @@ -6,21 +8,21 @@ import type { Span, SpanAttributes } from '@sentry/types'; import type { Route } from '../src/router'; import { instrumentVueRouter } from '../src/router'; -const captureExceptionSpy = jest.spyOn(SentryBrowser, 'captureException'); -jest.mock('@sentry/core', () => { - const actual = jest.requireActual('@sentry/core'); +const captureExceptionSpy = vi.spyOn(SentryBrowser, 'captureException'); +vi.mock('@sentry/core', async () => { + const actual = await vi.importActual('@sentry/core'); return { ...actual, - getActiveSpan: jest.fn().mockReturnValue({}), + getActiveSpan: vi.fn().mockReturnValue({}), }; }); const mockVueRouter = { - onError: jest.fn void]>(), - beforeEach: jest.fn void) => void]>(), + onError: vi.fn<[(error: Error) => void]>(), + beforeEach: vi.fn<[(from: Route, to: Route, next?: () => void) => void]>(), }; -const mockNext = jest.fn(); +const mockNext = vi.fn(); const testRoutes: Record = { initialPageloadRoute: { matched: [], params: {}, path: '', query: {} }, @@ -68,11 +70,11 @@ const testRoutes: Record = { describe('instrumentVueRouter()', () => { afterEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); it('should return instrumentation that instruments VueRouter.onError', () => { - const mockStartSpan = jest.fn(); + const mockStartSpan = vi.fn(); instrumentVueRouter( mockVueRouter, { routeLabel: 'name', instrumentPageLoad: true, instrumentNavigation: true }, @@ -99,7 +101,7 @@ describe('instrumentVueRouter()', () => { ])( 'should return instrumentation that instruments VueRouter.beforeEach(%s, %s) for navigations', (fromKey, toKey, transactionName, transactionSource) => { - const mockStartSpan = jest.fn(); + const mockStartSpan = vi.fn(); instrumentVueRouter( mockVueRouter, { routeLabel: 'name', instrumentPageLoad: true, instrumentNavigation: true }, @@ -138,15 +140,15 @@ describe('instrumentVueRouter()', () => { 'should return instrumentation that instruments VueRouter.beforeEach(%s, %s) for pageloads', (fromKey, toKey, transactionName, transactionSource) => { const mockRootSpan = { - getSpanJSON: jest.fn().mockReturnValue({ op: 'pageload' }), - updateName: jest.fn(), - setAttribute: jest.fn(), - setAttributes: jest.fn(), + getSpanJSON: vi.fn().mockReturnValue({ op: 'pageload' }), + updateName: vi.fn(), + setAttribute: vi.fn(), + setAttributes: vi.fn(), }; - jest.spyOn(SentryCore, 'getRootSpan').mockImplementation(() => mockRootSpan as unknown as Span); + vi.spyOn(SentryCore, 'getRootSpan').mockImplementation(() => mockRootSpan as unknown as Span); - const mockStartSpan = jest.fn().mockImplementation(_ => { + const mockStartSpan = vi.fn().mockImplementation(_ => { return mockRootSpan; }); instrumentVueRouter( @@ -178,7 +180,7 @@ describe('instrumentVueRouter()', () => { ); it('allows to configure routeLabel=path', () => { - const mockStartSpan = jest.fn(); + const mockStartSpan = vi.fn(); instrumentVueRouter( mockVueRouter, { routeLabel: 'path', instrumentPageLoad: true, instrumentNavigation: true }, @@ -205,7 +207,7 @@ describe('instrumentVueRouter()', () => { }); it('allows to configure routeLabel=name', () => { - const mockStartSpan = jest.fn(); + const mockStartSpan = vi.fn(); instrumentVueRouter( mockVueRouter, { routeLabel: 'name', instrumentPageLoad: true, instrumentNavigation: true }, @@ -233,9 +235,9 @@ describe('instrumentVueRouter()', () => { it("doesn't overwrite a pageload transaction name it was set to custom before the router resolved the route", () => { const mockRootSpan = { - updateName: jest.fn(), - setAttribute: jest.fn(), - setAttributes: jest.fn(), + updateName: vi.fn(), + setAttribute: vi.fn(), + setAttributes: vi.fn(), name: '', getSpanJSON: () => ({ op: 'pageload', @@ -244,10 +246,10 @@ describe('instrumentVueRouter()', () => { }, }), }; - const mockStartSpan = jest.fn().mockImplementation(_ => { + const mockStartSpan = vi.fn().mockImplementation(_ => { return mockRootSpan; }); - jest.spyOn(SentryCore, 'getRootSpan').mockImplementation(() => mockRootSpan as unknown as Span); + vi.spyOn(SentryCore, 'getRootSpan').mockImplementation(() => mockRootSpan as unknown as Span); instrumentVueRouter( mockVueRouter, @@ -287,14 +289,14 @@ describe('instrumentVueRouter()', () => { }); it("updates the scope's `transactionName` when a route is resolved", () => { - const mockStartSpan = jest.fn().mockImplementation(_ => { + const mockStartSpan = vi.fn().mockImplementation(_ => { return {}; }); - const scopeSetTransactionNameSpy = jest.fn(); + const scopeSetTransactionNameSpy = vi.fn(); // @ts-expect-error - only creating a partial scope but that's fine - jest.spyOn(SentryCore, 'getCurrentScope').mockImplementation(() => ({ + vi.spyOn(SentryCore, 'getCurrentScope').mockImplementation(() => ({ setTransactionName: scopeSetTransactionNameSpy, })); @@ -315,17 +317,17 @@ describe('instrumentVueRouter()', () => { expect(scopeSetTransactionNameSpy).toHaveBeenCalledWith('/books/:bookId/chapter/:chapterId'); }); - test.each([ + it.each([ [false, 0], [true, 1], ])( 'should return instrumentation that considers the instrumentPageLoad = %p', (instrumentPageLoad, expectedCallsAmount) => { const mockRootSpan = { - updateName: jest.fn(), - setData: jest.fn(), - setAttribute: jest.fn(), - setAttributes: jest.fn(), + updateName: vi.fn(), + setData: vi.fn(), + setAttribute: vi.fn(), + setAttributes: vi.fn(), name: '', getSpanJSON: () => ({ op: 'pageload', @@ -334,9 +336,9 @@ describe('instrumentVueRouter()', () => { }, }), }; - jest.spyOn(SentryCore, 'getRootSpan').mockImplementation(() => mockRootSpan as unknown as Span); + vi.spyOn(SentryCore, 'getRootSpan').mockImplementation(() => mockRootSpan as unknown as Span); - const mockStartSpan = jest.fn(); + const mockStartSpan = vi.fn(); instrumentVueRouter( mockVueRouter, { routeLabel: 'name', instrumentPageLoad, instrumentNavigation: true }, @@ -354,13 +356,13 @@ describe('instrumentVueRouter()', () => { }, ); - test.each([ + it.each([ [false, 0], [true, 1], ])( 'should return instrumentation that considers the instrumentNavigation = %p', (instrumentNavigation, expectedCallsAmount) => { - const mockStartSpan = jest.fn(); + const mockStartSpan = vi.fn(); instrumentVueRouter( mockVueRouter, { routeLabel: 'name', instrumentPageLoad: true, instrumentNavigation }, @@ -378,7 +380,7 @@ describe('instrumentVueRouter()', () => { ); it("doesn't throw when `next` is not available in the beforeEach callback (Vue Router 4)", () => { - const mockStartSpan = jest.fn(); + const mockStartSpan = vi.fn(); instrumentVueRouter( mockVueRouter, { routeLabel: 'path', instrumentPageLoad: true, instrumentNavigation: true }, diff --git a/packages/vue/test/vendor/components.test.ts b/packages/vue/test/vendor/components.test.ts index 77b54889326a..49d184325ee0 100644 --- a/packages/vue/test/vendor/components.test.ts +++ b/packages/vue/test/vendor/components.test.ts @@ -1,3 +1,5 @@ +import { beforeEach, describe, expect, it } from 'vitest'; + import { formatComponentName } from '../../src/vendor/components'; describe('formatComponentName', () => { diff --git a/packages/vue/tsconfig.test.json b/packages/vue/tsconfig.test.json index af7e36ec0eda..4a990e19513a 100644 --- a/packages/vue/tsconfig.test.json +++ b/packages/vue/tsconfig.test.json @@ -1,11 +1,11 @@ { "extends": "./tsconfig.json", - "include": ["test/**/*"], + "include": ["test/**/*", "vite.config.ts"], "compilerOptions": { // should include all types from `./tsconfig.json` plus types for all test frameworks used - "types": ["jest"] + "types": [] // other package-specific, test-specific options } diff --git a/packages/vue/vite.config.ts b/packages/vue/vite.config.ts new file mode 100644 index 000000000000..0582a58f479a --- /dev/null +++ b/packages/vue/vite.config.ts @@ -0,0 +1,5 @@ +import baseConfig from '../../vite/vite.config'; + +export default { + ...baseConfig, +};