From f0ed82d60b13066ce845caea089bdea1d835fd8f Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Tue, 25 Feb 2025 12:39:37 -0500 Subject: [PATCH] test(gatsby): Migrate to vitest --- packages/gatsby/.eslintrc.js | 2 +- packages/gatsby/package.json | 4 +- .../pretest.ts => setup/globalSetup.ts} | 6 ++- packages/gatsby/test/gatsby-node.test.ts | 54 ++++++++++++------- packages/gatsby/test/index.test.ts | 2 + packages/gatsby/test/sdk.test.ts | 17 +++--- packages/gatsby/tsconfig.test.json | 4 +- packages/gatsby/vite.config.ts | 11 ++++ 8 files changed, 69 insertions(+), 31 deletions(-) rename packages/gatsby/{scripts/pretest.ts => setup/globalSetup.ts} (73%) create mode 100644 packages/gatsby/vite.config.ts diff --git a/packages/gatsby/.eslintrc.js b/packages/gatsby/.eslintrc.js index ee0716e6ec2a..1ce19816e6bf 100644 --- a/packages/gatsby/.eslintrc.js +++ b/packages/gatsby/.eslintrc.js @@ -7,7 +7,7 @@ module.exports = { jsx: true, }, // ignore these because they're not covered by a `tsconfig`, which makes eslint throw an error - ignorePatterns: ['gatsby-node.d.ts'], + ignorePatterns: ['gatsby-node.d.ts', 'setup/globalSetup.ts'], overrides: [ { files: ['scripts/**/*.ts'], diff --git a/packages/gatsby/package.json b/packages/gatsby/package.json index 41181a78f074..e946acd039be 100644 --- a/packages/gatsby/package.json +++ b/packages/gatsby/package.json @@ -75,8 +75,8 @@ "clean": "rimraf build coverage *.d.ts sentry-gatsby-*.tgz", "fix": "eslint . --format stylish --fix", "lint": "eslint . --format stylish", - "test": "yarn ts-node scripts/pretest.ts && yarn jest", - "test:watch": "yarn ts-node scripts/pretest.ts && yarn jest --watch", + "test": "vitest run", + "test:watch": "vitest --watch", "yalc:publish": "yalc publish --push --sig" }, "volta": { diff --git a/packages/gatsby/scripts/pretest.ts b/packages/gatsby/setup/globalSetup.ts similarity index 73% rename from packages/gatsby/scripts/pretest.ts rename to packages/gatsby/setup/globalSetup.ts index bc64e0478b2f..c0c948d57110 100644 --- a/packages/gatsby/scripts/pretest.ts +++ b/packages/gatsby/setup/globalSetup.ts @@ -11,4 +11,8 @@ function ensurePluginTypes(): void { } } -ensurePluginTypes(); +import type { GlobalSetupContext } from 'vitest/node'; + +export default function setup(_: GlobalSetupContext) { + ensurePluginTypes(); +} diff --git a/packages/gatsby/test/gatsby-node.test.ts b/packages/gatsby/test/gatsby-node.test.ts index 5ff15ecf034e..e9170e3a40ad 100644 --- a/packages/gatsby/test/gatsby-node.test.ts +++ b/packages/gatsby/test/gatsby-node.test.ts @@ -1,13 +1,31 @@ -import { sentryWebpackPlugin } from '@sentry/webpack-plugin'; -import { onCreateWebpackConfig } from '../gatsby-node'; +import { describe, afterAll, afterEach, beforeEach, beforeAll, vi, it, expect } from 'vitest'; + +vi.hoisted( + () => + void mock('@sentry/webpack-plugin', { + sentryWebpackPlugin: vi.fn().mockReturnValue({}), + }), +); + +// Need to override mock because `gatsby-node.js` loads `@sentry/webpack-plugin` as a CJS file. +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); + }; +} -jest.mock('@sentry/webpack-plugin', () => ({ - sentryWebpackPlugin: jest.fn().mockReturnValue({ - apply: jest.fn(), - }), -})); +import { onCreateWebpackConfig } from '../gatsby-node'; describe('onCreateWebpackConfig', () => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + const { sentryWebpackPlugin } = require('@sentry/webpack-plugin'); let originalNodeEnv: string | undefined; beforeAll(() => { @@ -20,15 +38,15 @@ describe('onCreateWebpackConfig', () => { }); afterEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); it('sets a webpack config', () => { const actions = { - setWebpackConfig: jest.fn(), + setWebpackConfig: vi.fn(), }; - const getConfig = jest.fn().mockReturnValue({ devtool: 'source-map' }); + const getConfig = vi.fn().mockReturnValue({ devtool: 'source-map' }); onCreateWebpackConfig({ actions, getConfig }, {}); @@ -38,10 +56,10 @@ describe('onCreateWebpackConfig', () => { it('does not set a webpack config if enableClientWebpackPlugin is false', () => { const actions = { - setWebpackConfig: jest.fn(), + setWebpackConfig: vi.fn(), }; - const getConfig = jest.fn().mockReturnValue({ devtool: 'source-map' }); + const getConfig = vi.fn().mockReturnValue({ devtool: 'source-map' }); onCreateWebpackConfig({ actions, getConfig }, { enableClientWebpackPlugin: false }); @@ -50,21 +68,21 @@ describe('onCreateWebpackConfig', () => { describe('delete source maps after upload', () => { beforeEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); const actions = { - setWebpackConfig: jest.fn(), + setWebpackConfig: vi.fn(), }; - const getConfig = jest.fn(); + const getConfig = vi.fn(); it('sets sourceMapFilesToDeleteAfterUpload when provided in options', () => { const actions = { - setWebpackConfig: jest.fn(), + setWebpackConfig: vi.fn(), }; - const getConfig = jest.fn().mockReturnValue({ devtool: 'source-map' }); + const getConfig = vi.fn().mockReturnValue({ devtool: 'source-map' }); onCreateWebpackConfig({ actions, getConfig }, { deleteSourcemapsAfterUpload: true }); @@ -79,7 +97,7 @@ describe('onCreateWebpackConfig', () => { ); }); - test.each([ + it.each([ { name: 'without provided options: sets hidden source maps and deletes source maps', initialConfig: undefined, diff --git a/packages/gatsby/test/index.test.ts b/packages/gatsby/test/index.test.ts index 2ebc76e04a7f..c82f31c7f41d 100644 --- a/packages/gatsby/test/index.test.ts +++ b/packages/gatsby/test/index.test.ts @@ -1,3 +1,5 @@ +import { describe, it, expect } from 'vitest'; + import * as GatsbyIntegration from '../src/index'; describe('package', () => { diff --git a/packages/gatsby/test/sdk.test.ts b/packages/gatsby/test/sdk.test.ts index dd267ad5c2e1..465a06a05c0b 100644 --- a/packages/gatsby/test/sdk.test.ts +++ b/packages/gatsby/test/sdk.test.ts @@ -1,23 +1,26 @@ +import type { Mock } from 'vitest'; +import { describe, afterEach, expect, vi, test } from 'vitest'; + import { SDK_VERSION, init } from '@sentry/react'; import { init as gatsbyInit } from '../src/sdk'; -jest.mock('@sentry/react', () => { - const actual = jest.requireActual('@sentry/react'); +vi.mock('@sentry/react', async requiredActual => { + const actual = (await requiredActual()) as any; return { ...actual, - init: jest.fn().mockImplementation(actual.init), + init: vi.fn().mockImplementation(actual.init), }; }); -const reactInit = init as jest.Mock; +const reactInit = init as Mock; describe('Initialize React SDK', () => { afterEach(() => reactInit.mockReset()); test('Has correct SDK metadata', () => { gatsbyInit({}); - const calledWith = reactInit.mock.calls[0][0]; + const calledWith = reactInit.mock.calls[0]?.[0]; const sdkMetadata = calledWith._metadata.sdk; expect(sdkMetadata.name).toStrictEqual('sentry.javascript.gatsby'); expect(sdkMetadata.version).toBe(SDK_VERSION); @@ -31,7 +34,7 @@ describe('Initialize React SDK', () => { test('not defined by default', () => { gatsbyInit({}); expect(reactInit).toHaveBeenCalledTimes(1); - const callingObject = reactInit.mock.calls[0][0]; + const callingObject = reactInit.mock.calls[0]?.[0]; expect(callingObject.environment).not.toBeDefined(); }); @@ -40,7 +43,7 @@ describe('Initialize React SDK', () => { environment: 'custom env!', }); expect(reactInit).toHaveBeenCalledTimes(1); - const callingObject = reactInit.mock.calls[0][0]; + const callingObject = reactInit.mock.calls[0]?.[0]; expect(callingObject.environment).toStrictEqual('custom env!'); }); }); diff --git a/packages/gatsby/tsconfig.test.json b/packages/gatsby/tsconfig.test.json index 9d57a32062ed..cd46cfe5ccab 100644 --- a/packages/gatsby/tsconfig.test.json +++ b/packages/gatsby/tsconfig.test.json @@ -1,11 +1,11 @@ { "extends": "./tsconfig.json", - "include": ["test/**/*"], + "include": ["test/**/*", "vite.config.ts", "setup/**/*"], "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/gatsby/vite.config.ts b/packages/gatsby/vite.config.ts new file mode 100644 index 000000000000..43826c13a3bb --- /dev/null +++ b/packages/gatsby/vite.config.ts @@ -0,0 +1,11 @@ +import { defineConfig } from 'vitest/config'; + +import baseConfig from '../../vite/vite.config'; + +export default defineConfig({ + ...baseConfig, + test: { + ...baseConfig.test, + globalSetup: 'setup/globalSetup.ts', + }, +});