From 5fbecf0509aeb78ddde066971d14746b46fb4f17 Mon Sep 17 00:00:00 2001 From: Gil Tayar Date: Wed, 18 Oct 2023 20:34:28 +0300 Subject: [PATCH] add listMockedModules --- example-esm/package-lock.json | 2 +- example/package-lock.json | 2 +- lib/quibble.js | 7 +++++++ lib/quibble.mjs | 17 ++++++++++++++--- lib/thisWillRunInUserThread.js | 25 ++++++++++++++++++++++++- test/esm-lib/quibble-esm.test.mjs | 28 ++++++++++++++++++++++++++++ test/lib/quibble.test.js | 19 +++++++++++++++++++ 7 files changed, 94 insertions(+), 6 deletions(-) diff --git a/example-esm/package-lock.json b/example-esm/package-lock.json index 659aa4e..4be2a8d 100644 --- a/example-esm/package-lock.json +++ b/example-esm/package-lock.json @@ -12,7 +12,7 @@ } }, "..": { - "version": "0.7.0", + "version": "0.8.0", "dev": true, "license": "MIT", "dependencies": { diff --git a/example/package-lock.json b/example/package-lock.json index a19123f..7a38c84 100644 --- a/example/package-lock.json +++ b/example/package-lock.json @@ -12,7 +12,7 @@ } }, "..": { - "version": "0.7.0", + "version": "0.8.0", "dev": true, "license": "MIT", "dependencies": { diff --git a/lib/quibble.js b/lib/quibble.js index 44e3354..7b89f3f 100644 --- a/lib/quibble.js +++ b/lib/quibble.js @@ -119,6 +119,13 @@ quibble.esm = async function (specifier, namedExportStubs, defaultExportStub) { }) } +quibble.listMockedModules = function () { + const esmMockedModules = quibbleUserToLoaderCommunication()?.listMockedModules() ?? [] + const cjsMockedModules = Object.keys(quibbles).map((modulePath) => pathToFileURL(modulePath).href) + + return esmMockedModules.concat(cjsMockedModules) +} + quibble.isLoaderLoaded = function () { return !!quibbleUserToLoaderCommunication() } diff --git a/lib/quibble.mjs b/lib/quibble.mjs index 527433b..0b1d4f8 100644 --- a/lib/quibble.mjs +++ b/lib/quibble.mjs @@ -88,9 +88,7 @@ function getStubsInfo (moduleUrl) { if (!quibbleLoaderState.quibbledModules) return undefined if (!moduleUrl.includes('__quibble=')) return undefined - const moduleKey = moduleUrl - .replace(/\?.*/, '') - .replace(/#.*/, '') + const moduleKey = moduleUrl.replace(/\?.*/, '').replace(/#.*/, '') const moduleMockingInfo = quibbleLoaderState.quibbledModules.get(moduleKey) @@ -159,6 +157,19 @@ export const globalPreload = ({ port }) => { ++quibbleLoaderState.stubModuleGeneration Atomics.store(data.hasAddMockedHappened, 0, 1) Atomics.notify(data.hasAddMockedHappened, 0) + } else if (data.type === 'listMockedModules') { + const mockedModules = Array.from(quibbleLoaderState.quibbledModules.keys()) + const serializedMockedModules = mockedModules.join(' ') + const encodedMockedModules = new TextEncoder().encode(serializedMockedModules) + + data.mockedModulesListLength[0] = encodedMockedModules.length + if (encodedMockedModules.length <= data.mockedModulesList.length) { + for (let i = 0; i < encodedMockedModules.length; ++i) { + data.mockedModulesList[i] = encodedMockedModules[i] + } + } + Atomics.store(data.hasListMockedModulesHappened, 0, 1) + Atomics.notify(data.hasListMockedModulesHappened, 0) } }) port.unref() diff --git a/lib/thisWillRunInUserThread.js b/lib/thisWillRunInUserThread.js index 182ff6f..69d63cc 100644 --- a/lib/thisWillRunInUserThread.js +++ b/lib/thisWillRunInUserThread.js @@ -16,7 +16,7 @@ exports.thisWillRunInUserThread = (globalThis, port) => { quibbleLoaderState.stubModuleGeneration++ } }, - async addMockedModule ( + addMockedModule ( moduleUrl, { namedExportStubs, defaultExportStub } ) { @@ -45,6 +45,29 @@ exports.thisWillRunInUserThread = (globalThis, port) => { }) ++quibbleLoaderState.stubModuleGeneration } + }, + listMockedModules () { + if (!loaderAndUserRunInSameThread(globalThis)) { + const hasListMockedModulesHappened = new Int32Array(new SharedArrayBuffer(4)) + const mockedModulesListLength = new Int32Array(new SharedArrayBuffer(4)) + const mockedModulesList = new Uint8Array(new SharedArrayBuffer(20 * 1024 * 1024)) // 20MB should be sufficient + port.postMessage({ + type: 'listMockedModules', + hasListMockedModulesHappened, + mockedModulesListLength, + mockedModulesList + }) + Atomics.wait(hasListMockedModulesHappened, 0, 0) + if (mockedModulesListLength[0] > mockedModulesList.length) { + throw new Error('Not enough buffer allocated for result') + } + const serializedMockedModules = new TextDecoder().decode(mockedModulesList.slice(0, mockedModulesListLength[0])) + return serializedMockedModules ? serializedMockedModules.split(' ') : [] + } else { + const quibbleLoaderState = globalThis[Symbol.for('__quibbleLoaderState')] + + return Array.from(quibbleLoaderState.quibbledModules.keys()) + } } } diff --git a/test/esm-lib/quibble-esm.test.mjs b/test/esm-lib/quibble-esm.test.mjs index 3cad748..074adb3 100644 --- a/test/esm-lib/quibble-esm.test.mjs +++ b/test/esm-lib/quibble-esm.test.mjs @@ -2,6 +2,9 @@ // as it checks how quibble interacts with internal modules import 'fs' import quibble from 'quibble' +import { fileURLToPath, pathToFileURL } from 'url' + +const __filename = fileURLToPath(import.meta.url) export default { afterEach: function () { quibble.reset() }, @@ -170,6 +173,31 @@ export default { // Should still allow Proxy. await quibble.esm('../esm-fixtures/a-module.mjs', new Proxy({}, {})) + }, + 'list mocked modules': async function () { + await quibble.esm('../esm-fixtures/a-module-with-function.mjs', { + namedExport: 'replacement', + life: 41, + namedFunctionExport: () => 'export replacement' + }, 'default-export-replacement') + + assert.deepEqual(quibble.listMockedModules(), [ + pathToFileURL(quibble.absolutify('../esm-fixtures/a-module-with-function.mjs', __filename)).href + ]) + await quibble.esm('../esm-fixtures/a-module.mjs', { + namedExport: 'replacement', + life: 41, + namedFunctionExport: () => 'export replacement' + }, 'default-export-replacement') + + assert.deepEqual(quibble.listMockedModules(), [ + pathToFileURL(quibble.absolutify('../esm-fixtures/a-module-with-function.mjs', __filename)).href, + pathToFileURL(quibble.absolutify('../esm-fixtures/a-module.mjs', __filename)).href + ]) + + quibble.reset() + + assert.deepEqual(quibble.listMockedModules(), []) } } diff --git a/test/lib/quibble.test.js b/test/lib/quibble.test.js index 46385f0..d9cdefe 100644 --- a/test/lib/quibble.test.js +++ b/test/lib/quibble.test.js @@ -1,4 +1,5 @@ const quibble = require('../../lib/quibble') +const { pathToFileURL } = require('url') module.exports = { 'basic behavior': function () { @@ -127,6 +128,24 @@ module.exports = { assert.equal(quibbledRequiresANodeModule(), false) }, + 'list mocked modules': async function () { + quibble('../fixtures/a-function', function () { return 'kek' }) + + assert.deepEqual(quibble.listMockedModules(), [ + pathToFileURL(quibble.absolutify('../fixtures/a-function', __filename)).href + ]) + + quibble('../fixtures/b-function', function () { return 'kek' }) + + assert.deepEqual(quibble.listMockedModules(), [ + pathToFileURL(quibble.absolutify('../fixtures/a-function', __filename)).href, + pathToFileURL(quibble.absolutify('../fixtures/b-function', __filename)).href + ]) + + quibble.reset() + + assert.deepEqual(await quibble.listMockedModules(), []) + }, afterEach: function () { quibble.reset() },