From 19888dc2a59e7bf818ffa6e86c6582f385a66412 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Fri, 15 Apr 2022 22:41:31 +0200 Subject: [PATCH 1/3] Validate streaming writer chunk type in testing --- test/__mocks__/node-polyfill-web-streams.js | 21 +++++++++++++++++ test/lib/mocks-require-hook.js | 24 +++++++++++++++++++ test/lib/next-test-utils.js | 26 ++++++++++++++++++--- 3 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 test/__mocks__/node-polyfill-web-streams.js create mode 100644 test/lib/mocks-require-hook.js diff --git a/test/__mocks__/node-polyfill-web-streams.js b/test/__mocks__/node-polyfill-web-streams.js new file mode 100644 index 000000000000..6f8b0246a2b2 --- /dev/null +++ b/test/__mocks__/node-polyfill-web-streams.js @@ -0,0 +1,21 @@ +// Use CJS format for represent next/dist/compiled/node-polyfill-web-streams.js + +const { + WritableStreamDefaultWriter, + ReadableStream, + TransformStream, +} = require('next/dist/compiled/web-streams-polyfill') + +const OriginWritableStreamWrite = WritableStreamDefaultWriter.prototype.write + +// Override writable stream write method to validate chunk type. +// Currently CF workers only allow to write the encoded chunk in Uint8Array format. +WritableStreamDefaultWriter.prototype.write = (chunk) => { + if (!(chunk instanceof Uint8Array)) { + throw new Error('Writing non Uint8Array chunk in streaming is not allowed') + } + OriginWritableStreamWrite(chunk) +} + +global.ReadableStream = ReadableStream +global.TransformStream = TransformStream diff --git a/test/lib/mocks-require-hook.js b/test/lib/mocks-require-hook.js new file mode 100644 index 000000000000..6bf9f8229814 --- /dev/null +++ b/test/lib/mocks-require-hook.js @@ -0,0 +1,24 @@ +const mod = require('module') + +const hookPropertyMap = new Map([ + [ + /node-polyfill-web-streams/, + require.resolve('../__mocks__/node-polyfill-web-streams.js'), + ], +]) + +function matchModule(request) { + for (const [key, value] of hookPropertyMap) { + if (key.test(request)) { + return value + } + } + return null +} + +const resolveFilename = mod._resolveFilename +mod._resolveFilename = function (request, parent, isMain, options) { + const hookResolved = matchModule(request) // hookPropertyMap.get(request) + if (hookResolved) request = hookResolved + return resolveFilename.call(mod, request, parent, isMain, options) +} diff --git a/test/lib/next-test-utils.js b/test/lib/next-test-utils.js index a33c5970a128..589dd66b6899 100644 --- a/test/lib/next-test-utils.js +++ b/test/lib/next-test-utils.js @@ -31,7 +31,13 @@ export function initNextServerScript( return new Promise((resolve, reject) => { const instance = spawn( 'node', - [...((opts && opts.nodeArgs) || []), '--no-deprecation', scriptPath], + [ + ...((opts && opts.nodeArgs) || []), + '-r', + require.resolve('./mocks-require-hook'), + '--no-deprecation', + scriptPath, + ], { env, cwd: opts && opts.cwd, @@ -147,7 +153,14 @@ export function runNextCommand(argv, options = {}) { console.log(`Running command "next ${argv.join(' ')}"`) const instance = spawn( 'node', - [...(options.nodeArgs || []), '--no-deprecation', nextBin, ...argv], + [ + ...(options.nodeArgs || []), + '-r', + require.resolve('./mocks-require-hook'), + '--no-deprecation', + nextBin, + ...argv, + ], { ...options.spawnOptions, cwd, @@ -237,7 +250,14 @@ export function runNextCommandDev(argv, stdOut, opts = {}) { return new Promise((resolve, reject) => { const instance = spawn( 'node', - [...nodeArgs, '--no-deprecation', nextBin, ...argv], + [ + ...nodeArgs, + '-r', + require.resolve('./mocks-require-hook'), + '--no-deprecation', + nextBin, + ...argv, + ], { cwd, env, From cb34a5bf3eb56fa3ef8a86fc6a840929b3e9b215 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Sun, 17 Apr 2022 23:36:31 +0200 Subject: [PATCH 2/3] call --- test/__mocks__/node-polyfill-web-streams.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/__mocks__/node-polyfill-web-streams.js b/test/__mocks__/node-polyfill-web-streams.js index 6f8b0246a2b2..74e475e50909 100644 --- a/test/__mocks__/node-polyfill-web-streams.js +++ b/test/__mocks__/node-polyfill-web-streams.js @@ -10,11 +10,11 @@ const OriginWritableStreamWrite = WritableStreamDefaultWriter.prototype.write // Override writable stream write method to validate chunk type. // Currently CF workers only allow to write the encoded chunk in Uint8Array format. -WritableStreamDefaultWriter.prototype.write = (chunk) => { +WritableStreamDefaultWriter.prototype.write = function (chunk) { if (!(chunk instanceof Uint8Array)) { throw new Error('Writing non Uint8Array chunk in streaming is not allowed') } - OriginWritableStreamWrite(chunk) + return OriginWritableStreamWrite.call(this, chunk) } global.ReadableStream = ReadableStream From b42f42aeba132d81a24d658efcde4aef5e9334a6 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Mon, 18 Apr 2022 10:56:05 +0200 Subject: [PATCH 3/3] update text --- test/__mocks__/node-polyfill-web-streams.js | 2 +- test/lib/mocks-require-hook.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/__mocks__/node-polyfill-web-streams.js b/test/__mocks__/node-polyfill-web-streams.js index 74e475e50909..c9cd1d6dfcb7 100644 --- a/test/__mocks__/node-polyfill-web-streams.js +++ b/test/__mocks__/node-polyfill-web-streams.js @@ -12,7 +12,7 @@ const OriginWritableStreamWrite = WritableStreamDefaultWriter.prototype.write // Currently CF workers only allow to write the encoded chunk in Uint8Array format. WritableStreamDefaultWriter.prototype.write = function (chunk) { if (!(chunk instanceof Uint8Array)) { - throw new Error('Writing non Uint8Array chunk in streaming is not allowed') + throw new Error('Writing non-Uint8Array chunks in a stream is not allowed.') } return OriginWritableStreamWrite.call(this, chunk) } diff --git a/test/lib/mocks-require-hook.js b/test/lib/mocks-require-hook.js index 6bf9f8229814..7c5eac856312 100644 --- a/test/lib/mocks-require-hook.js +++ b/test/lib/mocks-require-hook.js @@ -18,7 +18,7 @@ function matchModule(request) { const resolveFilename = mod._resolveFilename mod._resolveFilename = function (request, parent, isMain, options) { - const hookResolved = matchModule(request) // hookPropertyMap.get(request) + const hookResolved = matchModule(request) if (hookResolved) request = hookResolved return resolveFilename.call(mod, request, parent, isMain, options) }