diff --git a/fixtures/nodejs-hybrid-app/src/index.ts b/fixtures/nodejs-hybrid-app/src/index.ts index a7acfc1005eb..de35f8f3afe7 100644 --- a/fixtures/nodejs-hybrid-app/src/index.ts +++ b/fixtures/nodejs-hybrid-app/src/index.ts @@ -6,7 +6,6 @@ import { Stream } from "node:stream"; import { Context } from "vm"; import { Client } from "pg"; import { s } from "./dep.cjs"; -import { testUnenvPreset } from "./unenv-preset"; testBasicNodejsProperties(); @@ -29,8 +28,6 @@ export default { return testX509Certificate(); case "/test-require-alias": return testRequireUenvAliasedPackages(); - case "/test-unenv-preset": - return await testUnenvPreset(); } return new Response( @@ -39,7 +36,6 @@ export default { Test getRandomValues() Test X509Certificate Test require unenv aliased packages -Test unenv preset `, { headers: { "Content-Type": "text/html; charset=utf-8" } } ); diff --git a/fixtures/nodejs-hybrid-app/tests/index.test.ts b/fixtures/nodejs-hybrid-app/tests/index.test.ts index 4b379b4821ca..d5510c5a5bc3 100644 --- a/fixtures/nodejs-hybrid-app/tests/index.test.ts +++ b/fixtures/nodejs-hybrid-app/tests/index.test.ts @@ -58,10 +58,4 @@ describe("nodejs compat", () => { const response = await fetch(`http://${ip}:${port}/test-require-alias`); await expect(response.text()).resolves.toBe(`"OK!"`); }); - - test("unenv preset", async ({ expect }) => { - const { ip, port } = wrangler; - const response = await fetch(`http://${ip}:${port}/test-unenv-preset`); - await expect(response.text()).resolves.toBe("OK!"); - }); }); diff --git a/packages/unenv-preset/package.json b/packages/unenv-preset/package.json index 5926da2530d6..f24e69ce7f5a 100644 --- a/packages/unenv-preset/package.json +++ b/packages/unenv-preset/package.json @@ -40,16 +40,21 @@ "scripts": { "build": "unbuild", "check:lint": "eslint", - "check:type": "tsc --noEmit" + "check:type": "tsc --noEmit", + "test:ci": "vitest run", + "test:watch": "vitest" }, "devDependencies": { "@types/node": "*", "typescript": "catalog:default", - "unbuild": "^2.0.0" + "unbuild": "^2.0.0", + "undici": "catalog:default", + "vitest": "catalog:default", + "wrangler": "workspace:*" }, "peerDependencies": { "unenv": "npm:unenv-nightly@*", - "workerd": "^1.20241216.0" + "workerd": "^1.20241230.0" }, "peerDependenciesMeta": { "workerd": { diff --git a/packages/unenv-preset/tests/index.test.ts b/packages/unenv-preset/tests/index.test.ts new file mode 100644 index 000000000000..cc0b521ef444 --- /dev/null +++ b/packages/unenv-preset/tests/index.test.ts @@ -0,0 +1,66 @@ +import fs from "node:fs"; +import path from "node:path"; +import { platform } from "node:process"; +import { fileURLToPath } from "node:url"; +import { fetch } from "undici"; +import { afterAll, beforeAll, describe, expect, test } from "vitest"; +import { runWranglerDev } from "../../../fixtures/shared/src/run-wrangler-long-lived"; +import { TESTS } from "./worker/index"; + +// Root of the current package +const pkgDir = path.resolve(fileURLToPath(import.meta.url), "../.."); +// workerd binary +const localWorkerdPath = path.join(pkgDir, "node_modules/.bin/", "workerd"); +// Base path for resolving `@cloudflare/unenv-preset` files +const localPresetResolveBaseDir = path.join(pkgDir, "package.json"); +// Base path for resolving `unjs/unenv` files +const localUnenvResolveBaseDir = path.join( + pkgDir, + "node_modules/unenv/package.json" +); + +// `runWranglerDev` + `MINIFLARE_WORKERD_PATH` is not supported on Windows +// See https://github.com/nodejs/node/issues/52554 +describe.skipIf(platform === "win32")( + `@cloudflare/unenv-preset ${platform} ${localWorkerdPath} ${fs.existsSync(localWorkerdPath)}`, + () => { + let wrangler: Awaited> | undefined; + + beforeAll(async () => { + // Use workerd binary install in `@cloudflare/unenv-preset` + // rather than the one bundled with wrangler. + const MINIFLARE_WORKERD_PATH = localWorkerdPath; + + // Use the preset from the local `@cloudflare/unenv-preset` and `unjs/unenv` + // rather than the one bundled with wrangler. + const WRANGLER_UNENV_RESOLVE_PATHS = [ + localPresetResolveBaseDir, + localUnenvResolveBaseDir, + ].join(","); + + console.log({ MINIFLARE_WORKERD_PATH, WRANGLER_UNENV_RESOLVE_PATHS }); + + wrangler = await runWranglerDev( + path.join(__dirname, "worker"), + ["--port=0", "--inspector-port=0"], + { + MINIFLARE_WORKERD_PATH, + WRANGLER_UNENV_RESOLVE_PATHS, + } + ); + }, 30000); + + afterAll(async () => { + await wrangler?.stop(); + wrangler = undefined; + }); + + test.for(Object.keys(TESTS))("%s", async (testName) => { + expect(wrangler).toBeDefined(); + const { ip, port } = wrangler!; + const response = await fetch(`http://${ip}:${port}/${testName}`); + const body = await response.text(); + expect(body).toMatch("OK!"); + }); + } +); diff --git a/fixtures/nodejs-hybrid-app/src/unenv-preset.ts b/packages/unenv-preset/tests/worker/index.ts similarity index 74% rename from fixtures/nodejs-hybrid-app/src/unenv-preset.ts rename to packages/unenv-preset/tests/worker/index.ts index 6b5bed213d0d..62cf9085a80c 100644 --- a/fixtures/nodejs-hybrid-app/src/unenv-preset.ts +++ b/packages/unenv-preset/tests/worker/index.ts @@ -1,21 +1,41 @@ import assert from "node:assert"; -// TODO: move to `@cloudflare/unenv-preset` -// See: https://github.com/cloudflare/workers-sdk/issues/7579 -export async function testUnenvPreset() { - try { - await testCryptoGetRandomValues(); - await testWorkerdImplementsBuffer(); - await testWorkerdModules(); - await testUtilImplements(); - await testWorkerdPath(); - await testWorkerdDns(); - } catch (e) { - return new Response(String(e)); - } +// List all the test functions. +// The test can be executing by fetching the `/${testName}` url. +export const TESTS = { + testCryptoGetRandomValues, + testImplementsBuffer, + testModules, + testUtilImplements, + testPath, + testDns, +}; - return new Response("OK!"); -} +export default { + async fetch(request: Request): Promise { + const url = new URL(request.url); + const testName = url.pathname.slice(1); + const test = TESTS[testName]; + if (!test) { + return new Response( + `

${testName ? `${testName} not found!` : `Pick a test to run`}

+ `, + { headers: { "Content-Type": "text/html; charset=utf-8" } } + ); + } + try { + await test(); + } catch (e) { + return new Response(String(e)); + } + + return new Response("OK!"); + }, +}; async function testCryptoGetRandomValues() { const crypto = await import("node:crypto"); @@ -26,7 +46,7 @@ async function testCryptoGetRandomValues() { assert(array.every((v) => v >= 0 && v <= 0xff_ff_ff_ff)); } -async function testWorkerdImplementsBuffer() { +async function testImplementsBuffer() { const encoder = new TextEncoder(); const buffer = await import("node:buffer"); const Buffer = buffer.Buffer; @@ -53,7 +73,7 @@ async function testWorkerdImplementsBuffer() { assert.strictEqual(typeof buffer.resolveObjectURL, "function"); } -async function testWorkerdModules() { +async function testModules() { const module = await import("node:module"); // @ts-expect-error exposed by workerd const require = module.createRequire("/"); @@ -89,7 +109,7 @@ async function testUtilImplements() { assert.strictEqual(types.isAnyArrayBuffer(new ArrayBuffer(0)), true); } -async function testWorkerdPath() { +async function testPath() { const pathWin32 = await import("node:path/win32"); assert.strictEqual(pathWin32.sep, "\\"); assert.strictEqual(pathWin32.delimiter, ";"); @@ -98,7 +118,7 @@ async function testWorkerdPath() { assert.strictEqual(pathPosix.delimiter, ":"); } -async function testWorkerdDns() { +async function testDns() { const dns = await import("node:dns"); await new Promise((resolve, reject) => { dns.resolveTxt("nodejs.org", (error, results) => { diff --git a/packages/unenv-preset/tests/worker/wrangler.json b/packages/unenv-preset/tests/worker/wrangler.json new file mode 100644 index 000000000000..be599a2d4c4f --- /dev/null +++ b/packages/unenv-preset/tests/worker/wrangler.json @@ -0,0 +1,6 @@ +{ + "name": "cloudflare-unenv-preset-test", + "main": "./index.ts", + "compatibility_date": "2024-12-16", + "compatibility_flags": ["nodejs_compat"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4a7795ba2bb7..d17586688b09 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1651,8 +1651,8 @@ importers: specifier: npm:unenv-nightly@* version: unenv-nightly@2.0.0-20241216-144314-7e05819 workerd: - specifier: ^1.20241216.0 - version: 1.20241216.0 + specifier: ^1.20241230.0 + version: 1.20241230.0 devDependencies: '@types/node': specifier: ^22.10.2 @@ -1663,6 +1663,15 @@ importers: unbuild: specifier: ^2.0.0 version: 2.0.0(typescript@5.6.3)(vue-tsc@2.0.29(typescript@5.6.3)) + undici: + specifier: catalog:default + version: 5.28.4 + vitest: + specifier: catalog:default + version: 2.1.8(@types/node@22.10.2)(@vitest/ui@2.1.8) + wrangler: + specifier: workspace:* + version: link:../wrangler packages/vitest-pool-workers: dependencies: @@ -2836,12 +2845,6 @@ packages: cpu: [x64] os: [darwin] - '@cloudflare/workerd-darwin-64@1.20241216.0': - resolution: {integrity: sha512-GreuUuvd1tp34i/I8rv9I6tJTGkLIdUZfPd4Gq7glRntWhZSfeJOlhFHOa/tIil1SrWi1UzXmWeW22DCcUIprA==} - engines: {node: '>=16'} - cpu: [x64] - os: [darwin] - '@cloudflare/workerd-darwin-64@1.20241230.0': resolution: {integrity: sha512-BZHLg4bbhNQoaY1Uan81O3FV/zcmWueC55juhnaI7NAobiQth9RppadPNpxNAmS9fK2mR5z8xrwMQSQrHmztyQ==} engines: {node: '>=16'} @@ -2854,12 +2857,6 @@ packages: cpu: [arm64] os: [darwin] - '@cloudflare/workerd-darwin-arm64@1.20241216.0': - resolution: {integrity: sha512-wGtzIWx4a8uu4y601Zq/x+5fPoSfJoXEEPkqxhcTs2g22Py60wnG91vAeVa8pZe9SipBozYczXh2OwoeCO1QVg==} - engines: {node: '>=16'} - cpu: [arm64] - os: [darwin] - '@cloudflare/workerd-darwin-arm64@1.20241230.0': resolution: {integrity: sha512-lllxycj7EzYoJ0VOJh8M3palUgoonVrILnzGrgsworgWlIpgjfXGS7b41tEGCw6AxSxL9prmTIGtfSPUvn/rjg==} engines: {node: '>=16'} @@ -2872,12 +2869,6 @@ packages: cpu: [x64] os: [linux] - '@cloudflare/workerd-linux-64@1.20241216.0': - resolution: {integrity: sha512-HRkePwhnb/4r2Bd6SS3n8VWLPnczh2ApKo3j5N0YSVOz/bEJlqEbEnKAUivCb79C3zptTsbsb0tJ4b5uZsaHtw==} - engines: {node: '>=16'} - cpu: [x64] - os: [linux] - '@cloudflare/workerd-linux-64@1.20241230.0': resolution: {integrity: sha512-Y3mHcW0KghOmWdNZyHYpEOG4Ba/ga8tht5vj1a+WXfagEjMO8Y98XhZUlCaYa9yB7Wh5jVcK5LM2jlO/BLgqpA==} engines: {node: '>=16'} @@ -2890,12 +2881,6 @@ packages: cpu: [arm64] os: [linux] - '@cloudflare/workerd-linux-arm64@1.20241216.0': - resolution: {integrity: sha512-5U99Iaj18BEJAEpKr+n2kdOyzCITbmzV0Ld4zMpIw5ZW0R2MHCo1swra84Q+bvElVOK6+7KGhjKQSqyZUF1WWA==} - engines: {node: '>=16'} - cpu: [arm64] - os: [linux] - '@cloudflare/workerd-linux-arm64@1.20241230.0': resolution: {integrity: sha512-IAjhsWPlHzhhkJ6I49sDG6XfMnhPvv0szKGXxTWQK/IWMrbGdHm4RSfNKBSoLQm67jGMIzbmcrX9UIkms27Y1g==} engines: {node: '>=16'} @@ -2908,12 +2893,6 @@ packages: cpu: [x64] os: [win32] - '@cloudflare/workerd-windows-64@1.20241216.0': - resolution: {integrity: sha512-6UtbWgZNFuVyq6d3nKsp3Eb53Ghm2EYObCKTs9TSzV2ZHbovgOIU8BKIlbfJvmkEbG4Q8bbfZkb3QJpG/IwchQ==} - engines: {node: '>=16'} - cpu: [x64] - os: [win32] - '@cloudflare/workerd-windows-64@1.20241230.0': resolution: {integrity: sha512-y5SPIk9iOb2gz+yWtHxoeMnjPnkYQswiCJ480oHC6zexnJLlKTpcmBCjDH1nWCT4pQi8F25gaH8thgElf4NvXQ==} engines: {node: '>=16'} @@ -10090,11 +10069,6 @@ packages: engines: {node: '>=16'} hasBin: true - workerd@1.20241216.0: - resolution: {integrity: sha512-q92hkfZ0ZmH6DrcQ426AqJR0KyG6NRAUNUT3Kvpzk76rLHzw6pvVeU9exATkqnwk5K3LQK6l1asuSsBDdXsPpw==} - engines: {node: '>=16'} - hasBin: true - workerd@1.20241230.0: resolution: {integrity: sha512-EgixXP0JGXGq6J9lz17TKIZtfNDUvJNG+cl9paPMfZuYWT920fFpBx+K04YmnbQRLnglsivF1GT9pxh1yrlWhg==} engines: {node: '>=16'} @@ -11151,45 +11125,30 @@ snapshots: '@cloudflare/workerd-darwin-64@1.20241106.1': optional: true - '@cloudflare/workerd-darwin-64@1.20241216.0': - optional: true - '@cloudflare/workerd-darwin-64@1.20241230.0': optional: true '@cloudflare/workerd-darwin-arm64@1.20241106.1': optional: true - '@cloudflare/workerd-darwin-arm64@1.20241216.0': - optional: true - '@cloudflare/workerd-darwin-arm64@1.20241230.0': optional: true '@cloudflare/workerd-linux-64@1.20241106.1': optional: true - '@cloudflare/workerd-linux-64@1.20241216.0': - optional: true - '@cloudflare/workerd-linux-64@1.20241230.0': optional: true '@cloudflare/workerd-linux-arm64@1.20241106.1': optional: true - '@cloudflare/workerd-linux-arm64@1.20241216.0': - optional: true - '@cloudflare/workerd-linux-arm64@1.20241230.0': optional: true '@cloudflare/workerd-windows-64@1.20241106.1': optional: true - '@cloudflare/workerd-windows-64@1.20241216.0': - optional: true - '@cloudflare/workerd-windows-64@1.20241230.0': optional: true @@ -18749,6 +18708,23 @@ snapshots: - supports-color - terser + vite-node@2.1.8(@types/node@22.10.2): + dependencies: + cac: 6.7.14 + debug: 4.3.7(supports-color@9.2.2) + es-module-lexer: 1.5.4 + pathe: 1.1.2 + vite: 5.0.12(@types/node@22.10.2) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + vite-plugin-dts@4.0.1(@types/node@18.19.59)(rollup@4.9.6)(typescript@5.6.3)(vite@5.0.12(@types/node@18.19.59)): dependencies: '@microsoft/api-extractor': 7.47.4(@types/node@18.19.59) @@ -18789,6 +18765,15 @@ snapshots: '@types/node': 18.19.59 fsevents: 2.3.3 + vite@5.0.12(@types/node@22.10.2): + dependencies: + esbuild: 0.19.12 + postcss: 8.4.33 + rollup: 4.9.6 + optionalDependencies: + '@types/node': 22.10.2 + fsevents: 2.3.3 + vitest-websocket-mock@0.4.0(vitest@2.1.8): dependencies: '@vitest/utils': 2.1.3 @@ -18830,6 +18815,41 @@ snapshots: - supports-color - terser + vitest@2.1.8(@types/node@22.10.2)(@vitest/ui@2.1.8): + dependencies: + '@vitest/expect': 2.1.8 + '@vitest/mocker': 2.1.8(msw@2.4.3(typescript@5.6.3))(vite@5.0.12(@types/node@18.19.59)) + '@vitest/pretty-format': 2.1.8 + '@vitest/runner': 2.1.8 + '@vitest/snapshot': 2.1.8 + '@vitest/spy': 2.1.8 + '@vitest/utils': 2.1.8 + chai: 5.1.2 + debug: 4.3.7(supports-color@9.2.2) + expect-type: 1.1.0 + magic-string: 0.30.14 + pathe: 1.1.2 + std-env: 3.8.0 + tinybench: 2.9.0 + tinyexec: 0.3.1 + tinypool: 1.0.1 + tinyrainbow: 1.2.0 + vite: 5.0.12(@types/node@22.10.2) + vite-node: 2.1.8(@types/node@22.10.2) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 22.10.2 + '@vitest/ui': 2.1.8(vitest@2.1.8) + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - stylus + - sugarss + - supports-color + - terser + vsce@2.15.0: dependencies: azure-devops-node-api: 11.2.0 @@ -18996,14 +19016,6 @@ snapshots: '@cloudflare/workerd-linux-arm64': 1.20241106.1 '@cloudflare/workerd-windows-64': 1.20241106.1 - workerd@1.20241216.0: - optionalDependencies: - '@cloudflare/workerd-darwin-64': 1.20241216.0 - '@cloudflare/workerd-darwin-arm64': 1.20241216.0 - '@cloudflare/workerd-linux-64': 1.20241216.0 - '@cloudflare/workerd-linux-arm64': 1.20241216.0 - '@cloudflare/workerd-windows-64': 1.20241216.0 - workerd@1.20241230.0: optionalDependencies: '@cloudflare/workerd-darwin-64': 1.20241230.0