diff --git a/packages/remix/.eslintrc.js b/packages/remix/.eslintrc.js index f1046a6136d6..0c88b5b8f12f 100644 --- a/packages/remix/.eslintrc.js +++ b/packages/remix/.eslintrc.js @@ -6,7 +6,7 @@ module.exports = { parserOptions: { jsx: true, }, - ignorePatterns: ['playwright.config.ts', 'vitest.config.ts', 'test/integration/**'], + ignorePatterns: ['playwright.config.ts', 'vitest.config.ts', 'vitest.config.unit.ts', 'test/integration/**'], extends: ['../../.eslintrc.js'], overrides: [ { diff --git a/packages/remix/jest.config.js b/packages/remix/jest.config.js deleted file mode 100644 index 7d6c8cb0990e..000000000000 --- a/packages/remix/jest.config.js +++ /dev/null @@ -1,8 +0,0 @@ -const baseConfig = require('../../jest/jest.config.js'); - -module.exports = { - ...baseConfig, - testPathIgnorePatterns: ['/build/', '/node_modules/', '/test/integration/'], - // Some tests take longer to finish, as flushing spans with OpenTelemetry takes some more time - testTimeout: 15000, -}; diff --git a/packages/remix/package.json b/packages/remix/package.json index a99c7a57eb6a..68570604bd6b 100644 --- a/packages/remix/package.json +++ b/packages/remix/package.json @@ -104,8 +104,8 @@ "test:integration:client": "yarn playwright install-deps && yarn playwright test test/integration/test/client/ --project='chromium'", "test:integration:client:ci": "yarn test:integration:client", "test:integration:server": "export NODE_OPTIONS='--stack-trace-limit=25' && vitest run", - "test:unit": "jest", - "test:watch": "jest --watch", + "test:unit": "vitest run --config vitest.config.unit.ts", + "test:watch": "vitest --watch --config vitest.config.unit.ts", "yalc:publish": "yalc publish --push --sig" }, "volta": { diff --git a/packages/remix/test/index.client.test.ts b/packages/remix/test/index.client.test.ts index 139f27f12076..cd26bc55fb55 100644 --- a/packages/remix/test/index.client.test.ts +++ b/packages/remix/test/index.client.test.ts @@ -1,19 +1,15 @@ import * as SentryReact from '@sentry/react'; +import { describe, vi, it, expect, afterEach, type Mock } from 'vitest'; import { init } from '../src/index.client'; -jest.mock('@sentry/react', () => { - return { - __esModule: true, - ...jest.requireActual('@sentry/react'), - }; -}); +vi.mock('@sentry/react', { spy: true }); -const reactInit = jest.spyOn(SentryReact, 'init'); +const reactInit = SentryReact.init as Mock; describe('Client init()', () => { afterEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); SentryReact.getGlobalScope().clear(); SentryReact.getIsolationScope().clear(); diff --git a/packages/remix/test/index.server.test.ts b/packages/remix/test/index.server.test.ts index b710e295ed1e..33dfbee862d8 100644 --- a/packages/remix/test/index.server.test.ts +++ b/packages/remix/test/index.server.test.ts @@ -1,19 +1,15 @@ import * as SentryNode from '@sentry/node'; +import { describe, vi, it, expect, afterEach, type Mock } from 'vitest'; import { init } from '../src/index.server'; -jest.mock('@sentry/node', () => { - return { - __esModule: true, - ...jest.requireActual('@sentry/node'), - }; -}); +vi.mock('@sentry/node', { spy: true }); -const nodeInit = jest.spyOn(SentryNode, 'init'); +const nodeInit = SentryNode.init as Mock; describe('Server init()', () => { afterEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); SentryNode.getGlobalScope().clear(); SentryNode.getIsolationScope().clear(); diff --git a/packages/remix/test/scripts/upload-sourcemaps.test.ts b/packages/remix/test/scripts/upload-sourcemaps.test.ts index 1a4a4acbd5c4..f03953c8dbb7 100644 --- a/packages/remix/test/scripts/upload-sourcemaps.test.ts +++ b/packages/remix/test/scripts/upload-sourcemaps.test.ts @@ -1,21 +1,40 @@ -const newMock = jest.fn(); -const uploadSourceMapsMock = jest.fn(); -const finalizeMock = jest.fn(); -const proposeVersionMock = jest.fn(() => '0.1.2.3.4'); +import { vi, describe, it, expect, beforeEach } from 'vitest'; -jest.mock('@sentry/cli', () => { - return jest.fn().mockImplementation(() => { - return { - execute: jest.fn(), - releases: { - new: newMock, - uploadSourceMaps: uploadSourceMapsMock, - finalize: finalizeMock, - proposeVersion: proposeVersionMock, - }, - }; - }); -}); +const newMock = vi.fn(); +const uploadSourceMapsMock = vi.fn(); +const finalizeMock = vi.fn(); +const proposeVersionMock = vi.fn(() => '0.1.2.3.4'); + +// The createRelease script requires the Sentry CLI, which we need to mock so we +// hook require to do this +async function mock(mockedUri: string, stub: any) { + const { Module } = await import('module'); + // @ts-expect-error test + Module._load_original = Module._load; + // @ts-expect-error test + Module._load = (uri, parent) => { + if (uri === mockedUri) return stub; + // @ts-expect-error test + return Module._load_original(uri, parent); + }; +} + +await vi.hoisted(async () => + mock( + '@sentry/cli', + vi.fn().mockImplementation(() => { + return { + execute: vi.fn(), + releases: { + new: newMock, + uploadSourceMaps: uploadSourceMapsMock, + finalize: finalizeMock, + proposeVersion: proposeVersionMock, + }, + }; + }), + ), +); // eslint-disable-next-line @typescript-eslint/no-var-requires const { createRelease } = require('../../scripts/createRelease'); diff --git a/packages/remix/tsconfig.test.json b/packages/remix/tsconfig.test.json index 3d6564a39ff5..bc444a444917 100644 --- a/packages/remix/tsconfig.test.json +++ b/packages/remix/tsconfig.test.json @@ -1,11 +1,15 @@ { "extends": "./tsconfig.json", - "include": ["test/**/*", "vitest.config.ts"], + "include": ["test/**/*", "vitest.config.ts", "vitest.config.unit.ts"], "compilerOptions": { "lib": ["DOM", "ES2018"], - "types": ["node", "jest"], + "types": ["node"], + // Required for top-level await in tests + "module": "Node16", + "target": "ES2017", + "esModuleInterop": true } } diff --git a/packages/remix/vitest.config.unit.ts b/packages/remix/vitest.config.unit.ts new file mode 100644 index 000000000000..a81b35e3fd75 --- /dev/null +++ b/packages/remix/vitest.config.unit.ts @@ -0,0 +1,14 @@ +import { defineConfig } from 'vitest/config'; + +import baseConfig from '../../vite/vite.config'; + +export default defineConfig({ + ...baseConfig, + test: { + ...baseConfig.test, + // disableConsoleIntercept: true, + // silent: false, + include: ['test/**/*.test.ts'], + exclude: ['**/integration/**/*.test.ts'], + }, +});