From 139e8cdb179524f9ba21f9296452997a77f0fe0c Mon Sep 17 00:00:00 2001 From: Nathan Rajlich Date: Thu, 23 May 2024 11:20:18 -0700 Subject: [PATCH] [node] Use `vitest` for unit tests (#11631) Similar to #11302, but for the `@vercel/node` package. --- .changeset/smooth-teachers-knock.md | 2 + packages/node/package.json | 11 +- packages/node/src/index.ts | 4 +- packages/node/test/unit/dev.test.ts | 3 +- .../edge-handler-template.test.mts | 4 +- .../unit/edge-handler/edge-matcher.test.ts | 1 + .../edge-handler/edge-wasm-plugin.test.mts | 3 +- packages/node/test/unit/prepare-cache.test.ts | 1 + .../unit/serverless-functions/helpers.test.ts | 1 + packages/node/test/unit/utils.test.ts | 1 + packages/node/vitest.config.mts | 26 ++++ pnpm-lock.yaml | 111 +++++++++++++++--- utils/chunk-tests-18.js | 12 +- 13 files changed, 150 insertions(+), 30 deletions(-) create mode 100644 .changeset/smooth-teachers-knock.md create mode 100644 packages/node/vitest.config.mts diff --git a/.changeset/smooth-teachers-knock.md b/.changeset/smooth-teachers-knock.md new file mode 100644 index 00000000000..a845151cc84 --- /dev/null +++ b/.changeset/smooth-teachers-knock.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/packages/node/package.json b/packages/node/package.json index cfcbb7335fb..1c4d5b0ae10 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -12,9 +12,10 @@ "scripts": { "build": "node build.mjs", "test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --env node --verbose --bail --runInBand", - "test-unit": "pnpm test test/unit", "test-e2e": "pnpm test test/integration", - "type-check": "tsc --noEmit" + "type-check": "tsc --noEmit", + "vitest-unit-run": "vitest", + "vitest-unit": "glob --absolute 'test/unit/**/*.test.ts' 'test/unit/**/*.test.mts'" }, "files": [ "dist" @@ -51,13 +52,17 @@ "@types/etag": "1.8.0", "@types/jest": "29.5.0", "@vercel/functions": "workspace:*", + "@vitest/expect": "1.4.0", "content-type": "1.0.5", "cookie": "0.4.0", "cross-env": "7.0.3", "execa": "3.2.0", "fs-extra": "11.1.0", + "glob": "10.3.16", "jest-junit": "16.0.0", "source-map-support": "0.5.12", - "tree-kill": "1.2.2" + "tree-kill": "1.2.2", + "vite": "5.1.6", + "vitest": "1.3.1" } } diff --git a/packages/node/src/index.ts b/packages/node/src/index.ts index 4b0176004c4..3ca641d5383 100644 --- a/packages/node/src/index.ts +++ b/packages/node/src/index.ts @@ -317,7 +317,7 @@ async function compile( const babelCompileEnabled = !isEdgeFunction || process.env.VERCEL_EDGE_NO_BABEL !== '1'; if (babelCompileEnabled && esmPaths.length) { - const babelCompile = require('./babel').compile; + const babelCompile = (await import('./babel.js')).compile; for (const path of esmPaths) { const pathDir = join(workPath, dirname(path)); if (!pkgCache.has(pathDir)) { @@ -348,7 +348,7 @@ async function compile( ); } console.log(`Compiling "${filename}" from ESM to CommonJS...`); - const { code, map } = babelCompile(filename, source); + const { code, map } = babelCompile(filename, String(source)); shouldAddSourcemapSupport = true; preparedFiles[path] = new FileBlob({ data: `${code}\n//# sourceMappingURL=${filename}.map`, diff --git a/packages/node/test/unit/dev.test.ts b/packages/node/test/unit/dev.test.ts index d32398f85ff..83e2303d455 100644 --- a/packages/node/test/unit/dev.test.ts +++ b/packages/node/test/unit/dev.test.ts @@ -1,3 +1,4 @@ +import { afterAll, describe, expect, test, vi } from 'vitest'; import { forkDevServer, readMessage } from '../../src/fork-dev-server'; import { resolve, extname } from 'path'; import { createServer } from 'http'; @@ -7,7 +8,7 @@ import { fetch } from 'undici'; import { promisify } from 'util'; import { setTimeout } from 'timers/promises'; -jest.setTimeout(20 * 1000); +vi.setConfig({ testTimeout: 20 * 1000 }); const [NODE_MAJOR] = process.versions.node.split('.').map(v => Number(v)); diff --git a/packages/node/test/unit/edge-handler/edge-handler-template.test.mts b/packages/node/test/unit/edge-handler/edge-handler-template.test.mts index f0d22137d41..57a6eda96e6 100644 --- a/packages/node/test/unit/edge-handler/edge-handler-template.test.mts +++ b/packages/node/test/unit/edge-handler/edge-handler-template.test.mts @@ -1,9 +1,9 @@ +import { describe, test, expect } from 'vitest'; import { Headers, Response, Request } from 'node-fetch'; import { getUrl, respond, - // @ts-ignore - this is a special patch file to allow importing from the template -} from '../../../src/edge-functions/edge-handler-template.mjs'; +} from '../../../src/edge-functions/edge-handler-template.js'; describe('edge-handler-template', () => { describe('getUrl()', () => { diff --git a/packages/node/test/unit/edge-handler/edge-matcher.test.ts b/packages/node/test/unit/edge-handler/edge-matcher.test.ts index 7c78eea0051..07ebc770bc2 100644 --- a/packages/node/test/unit/edge-handler/edge-matcher.test.ts +++ b/packages/node/test/unit/edge-handler/edge-matcher.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { prepareFilesystem } from '../test-utils'; import { build } from '../../../src'; diff --git a/packages/node/test/unit/edge-handler/edge-wasm-plugin.test.mts b/packages/node/test/unit/edge-handler/edge-wasm-plugin.test.mts index d58c3a2db91..b27131f991a 100644 --- a/packages/node/test/unit/edge-handler/edge-wasm-plugin.test.mts +++ b/packages/node/test/unit/edge-handler/edge-wasm-plugin.test.mts @@ -1,4 +1,5 @@ -import { createEdgeWasmPlugin } from '../../../dist/edge-functions/edge-wasm-plugin.mjs'; +import { test, expect } from 'vitest'; +import { createEdgeWasmPlugin } from '../../../src/edge-functions/edge-wasm-plugin.mjs'; import { prepareFilesystem } from '../test-utils'; import { build } from 'esbuild'; import { join } from 'path'; diff --git a/packages/node/test/unit/prepare-cache.test.ts b/packages/node/test/unit/prepare-cache.test.ts index a8ba66c9abb..907855fa1f7 100644 --- a/packages/node/test/unit/prepare-cache.test.ts +++ b/packages/node/test/unit/prepare-cache.test.ts @@ -1,3 +1,4 @@ +import { describe, test, expect } from 'vitest'; import path from 'path'; import assert from 'assert'; import { prepareCache } from '../../src'; diff --git a/packages/node/test/unit/serverless-functions/helpers.test.ts b/packages/node/test/unit/serverless-functions/helpers.test.ts index a8d3eda2b2c..0fa21c87af3 100644 --- a/packages/node/test/unit/serverless-functions/helpers.test.ts +++ b/packages/node/test/unit/serverless-functions/helpers.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { getBodyParser } from '../../../src/serverless-functions/helpers'; describe('serverless-functions/helpers', () => { diff --git a/packages/node/test/unit/utils.test.ts b/packages/node/test/unit/utils.test.ts index 39bd00b97fc..e7fe048f8a0 100644 --- a/packages/node/test/unit/utils.test.ts +++ b/packages/node/test/unit/utils.test.ts @@ -1,3 +1,4 @@ +import { describe, expect, test } from 'vitest'; import { entrypointToOutputPath } from '../../src/utils'; describe('entrypointToOutputPath()', () => { diff --git a/packages/node/vitest.config.mts b/packages/node/vitest.config.mts new file mode 100644 index 00000000000..41453959017 --- /dev/null +++ b/packages/node/vitest.config.mts @@ -0,0 +1,26 @@ +/// +import { defineConfig } from 'vite'; + +export default defineConfig({ + test: { + // Use of process.chdir prohibits usage of the default "threads". https://vitest.dev/config/#forks + pool: 'forks', + env: { + // Vitest supresses color output when `process.env.CI` is true + // so override that behavior + // Issue: https://github.com/vitest-dev/vitest/issues/2732 + // Fix: https://github.com/JoshuaKGoldberg/expect-no-axe-violations/pull/3/files + FORCE_COLOR: '1', + }, + exclude: [ + // default + '**/node_modules/**', + '**/dist/**', + '**/cypress/**', + '**/.{idea,git,cache,output,temp}/**', + '**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build}.config.*', + // some artifacts in the fixtures have spec files that we're not using + '**/*.spec.js', + ], + }, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c147def6fb1..70cc8846f08 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -720,7 +720,7 @@ importers: version: 5.1.6(@types/node@14.18.33) vitest: specifier: 1.3.1 - version: 1.3.1(@types/node@14.18.33) + version: 1.3.1(@edge-runtime/vm@3.2.0)(@types/node@16.18.11) which: specifier: 3.0.0 version: 3.0.0 @@ -954,7 +954,7 @@ importers: devDependencies: vitest: specifier: 1.3.1 - version: 1.3.1(@types/node@14.18.33) + version: 1.3.1(@edge-runtime/vm@3.2.0)(@types/node@16.18.11) packages/gatsby-plugin-vercel-analytics: dependencies: @@ -1311,6 +1311,9 @@ importers: '@vercel/functions': specifier: workspace:* version: link:../functions + '@vitest/expect': + specifier: 1.4.0 + version: 1.4.0 content-type: specifier: 1.0.5 version: 1.0.5 @@ -1326,6 +1329,9 @@ importers: fs-extra: specifier: 11.1.0 version: 11.1.0 + glob: + specifier: 10.3.16 + version: 10.3.16 jest-junit: specifier: 16.0.0 version: 16.0.0 @@ -1335,6 +1341,12 @@ importers: tree-kill: specifier: 1.2.2 version: 1.2.2 + vite: + specifier: 5.1.6 + version: 5.1.6(@types/node@16.18.11) + vitest: + specifier: 1.3.1 + version: 1.3.1(@edge-runtime/vm@3.2.0)(@types/node@16.18.11) packages/python: devDependencies: @@ -2330,7 +2342,6 @@ packages: /@edge-runtime/primitives@4.1.0: resolution: {integrity: sha512-Vw0lbJ2lvRUqc7/soqygUX216Xb8T3WBZ987oywz6aJqRxcwSVWwr9e+Nqo2m9bxobA9mdbWNNoRY6S9eko1EQ==} engines: {node: '>=16'} - dev: false /@edge-runtime/vm@3.1.7: resolution: {integrity: sha512-hUMFbDQ/nZN+1TLMi6iMO1QFz9RSV8yGG8S42WFPFma1d7VSNE0eMdJUmwjmtav22/iQkzHMmu6oTSfAvRGS8g==} @@ -2344,7 +2355,6 @@ packages: engines: {node: '>=16'} dependencies: '@edge-runtime/primitives': 4.1.0 - dev: false /@emotion/hash@0.9.1: resolution: {integrity: sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==} @@ -3504,7 +3514,7 @@ packages: engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} dependencies: '@npmcli/git': 4.1.0 - glob: 10.2.3 + glob: 10.3.16 hosted-git-info: 6.1.1 json-parse-even-better-errors: 3.0.1 normalize-package-data: 5.0.0 @@ -6616,7 +6626,7 @@ packages: dependencies: '@npmcli/fs': 3.1.0 fs-minipass: 3.0.3 - glob: 10.2.3 + glob: 10.3.16 lru-cache: 7.18.3 minipass: 7.0.4 minipass-collect: 1.0.2 @@ -8264,7 +8274,7 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 5.54.1(eslint@8.24.0)(typescript@4.9.4) + '@typescript-eslint/parser': 5.54.1(eslint@8.24.0)(typescript@4.9.5) debug: 3.2.7 eslint: 8.24.0 eslint-import-resolver-node: 0.3.7 @@ -8294,7 +8304,7 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 5.54.1(eslint@8.24.0)(typescript@4.9.4) + '@typescript-eslint/parser': 5.54.1(eslint@8.24.0)(typescript@4.9.5) array-includes: 3.1.6 array.prototype.flat: 1.3.1 array.prototype.flatmap: 1.3.1 @@ -8418,7 +8428,7 @@ packages: optional: true dependencies: eslint: 8.24.0 - eslint-plugin-jest: 27.2.1(@typescript-eslint/eslint-plugin@5.54.1)(eslint@8.24.0)(jest@29.5.0)(typescript@4.9.4) + eslint-plugin-jest: 27.2.1(@typescript-eslint/eslint-plugin@5.54.1)(eslint@8.24.0)(jest@29.5.0)(typescript@4.9.5) dev: true /eslint-plugin-react-hooks@4.6.0(eslint@8.24.0): @@ -9401,6 +9411,18 @@ packages: path-scurry: 1.8.0 dev: true + /glob@10.3.16: + resolution: {integrity: sha512-JDKXl1DiuuHJ6fVS2FXjownaavciiHNUU4mOvV/B793RLh05vZL1rcPnCSaOgv1hDT6RDlY7AB7ZUvFYAtPgAw==} + engines: {node: '>=16 || 14 >=14.18'} + hasBin: true + dependencies: + foreground-child: 3.1.1 + jackspeak: 3.1.2 + minimatch: 9.0.4 + minipass: 7.0.4 + path-scurry: 1.11.1 + dev: true + /glob@7.1.2: resolution: {integrity: sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==} dependencies: @@ -10401,6 +10423,15 @@ packages: '@pkgjs/parseargs': 0.11.0 dev: true + /jackspeak@3.1.2: + resolution: {integrity: sha512-kWmLKn2tRtfYMF/BakihVVRzBKOxz4gJMiL2Rj91WnAB5TPZumSH99R/Yf1qE1u4uRimvCSJfm6hnxohXeEXjQ==} + engines: {node: '>=14'} + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + dev: true + /jaro-winkler@0.2.8: resolution: {integrity: sha512-yr+mElb6dWxA1mzFu0+26njV5DWAQRNTi5pB6fFMm79zHrfAs3d0qjhe/IpZI4AHIUJkzvu5QXQRWOw2O0GQyw==} dev: true @@ -11488,6 +11519,11 @@ packages: engines: {node: '>=8'} dev: false + /lru-cache@10.2.2: + resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==} + engines: {node: 14 || >=16.14} + dev: true + /lru-cache@4.1.5: resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} dependencies: @@ -12942,6 +12978,14 @@ packages: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} dev: true + /path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + dependencies: + lru-cache: 10.2.2 + minipass: 7.0.4 + dev: true + /path-scurry@1.8.0: resolution: {integrity: sha512-IjTrKseM404/UAWA8bBbL3Qp6O2wXkanuIE3seCxBH7ctRuvH1QRawy1N3nVDHGkdeZsjOsSe/8AQBL/VQCy2g==} engines: {node: '>=16 || 14 >=14.17'} @@ -15615,7 +15659,7 @@ packages: vfile-message: 3.1.4 dev: true - /vite-node@1.3.1(@types/node@14.18.33): + /vite-node@1.3.1(@types/node@16.18.11): resolution: {integrity: sha512-azbRrqRxlWTJEVbzInZCTchx0X69M/XPTCz4H+TLvlTcR/xH/3hkRqhOakT41fMJCMzXTu4UvegkZiEoJAWvng==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true @@ -15624,7 +15668,7 @@ packages: debug: 4.3.4 pathe: 1.1.2 picocolors: 1.0.0 - vite: 5.1.6(@types/node@14.18.33) + vite: 5.1.6(@types/node@16.18.11) transitivePeerDependencies: - '@types/node' - less @@ -15693,7 +15737,43 @@ packages: fsevents: 2.3.3 dev: true - /vitest@1.3.1(@types/node@14.18.33): + /vite@5.1.6(@types/node@16.18.11): + resolution: {integrity: sha512-yYIAZs9nVfRJ/AiOLCA91zzhjsHUgMjB+EigzFb6W2XTLO8JixBCKCjvhKZaye+NKYHCrkv3Oh50dH9EdLU2RA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 16.18.11 + esbuild: 0.19.12 + postcss: 8.4.38 + rollup: 4.13.2 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /vitest@1.3.1(@edge-runtime/vm@3.2.0)(@types/node@16.18.11): resolution: {integrity: sha512-/1QJqXs8YbCrfv/GPQ05wAZf2eakUPLPa18vkJAKE7RXOKfVHqMZZ1WlTjiwl6Gcn65M5vpNUB6EFLnEdRdEXQ==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true @@ -15718,7 +15798,8 @@ packages: jsdom: optional: true dependencies: - '@types/node': 14.18.33 + '@edge-runtime/vm': 3.2.0 + '@types/node': 16.18.11 '@vitest/expect': 1.3.1 '@vitest/runner': 1.3.1 '@vitest/snapshot': 1.3.1 @@ -15736,8 +15817,8 @@ packages: strip-literal: 2.0.0 tinybench: 2.6.0 tinypool: 0.8.3 - vite: 5.1.6(@types/node@14.18.33) - vite-node: 1.3.1(@types/node@14.18.33) + vite: 5.1.6(@types/node@16.18.11) + vite-node: 1.3.1(@types/node@16.18.11) why-is-node-running: 2.2.2 transitivePeerDependencies: - less diff --git a/utils/chunk-tests-18.js b/utils/chunk-tests-18.js index f236a51aaa6..13b3f64aec5 100644 --- a/utils/chunk-tests-18.js +++ b/utils/chunk-tests-18.js @@ -6,8 +6,8 @@ async function main() { runner: 'ubuntu-latest', packagePath: 'packages/node', packageName: '@vercel/node', - scriptName: 'test-unit', - testScript: 'test', + scriptName: 'vitest-unit', + testScript: 'vitest-unit-run', testPaths: ['test/unit/dev.test.ts'], chunkNumber: 1, allChunksLength: 1, @@ -16,8 +16,8 @@ async function main() { runner: 'macos-14', packagePath: 'packages/node', packageName: '@vercel/node', - scriptName: 'test-unit', - testScript: 'test', + scriptName: 'vitest-unit', + testScript: 'vitest-unit-run', testPaths: ['test/unit/dev.test.ts'], chunkNumber: 1, allChunksLength: 1, @@ -26,8 +26,8 @@ async function main() { runner: 'windows-latest', packagePath: 'packages/node', packageName: '@vercel/node', - scriptName: 'test-unit', - testScript: 'test', + scriptName: 'vitest-unit', + testScript: 'vitest-unit-run', testPaths: ['test/unit/dev.test.ts'], chunkNumber: 1, allChunksLength: 1,