diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json index 61b7ab778f..7dc638986b 100644 --- a/node_modules/.package-lock.json +++ b/node_modules/.package-lock.json @@ -823,9 +823,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.31.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.31.0.tgz", - "integrity": "sha512-LOm5OVt7D4qiKCqoiPbA7LWmI+tbw1VbTUowBcUMgQSuM6poJufkFkYDcQpo5KfgD39TnNySV26QjOh7VFpSyw==", + "version": "9.32.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.32.0.tgz", + "integrity": "sha512-BBpRFZK3eX6uMLKz8WxFOBIFFcGFJ/g8XuwjTHCqHROSIsopI+ddn/d5Cfh36+7+e5edVS8dbSHnBNhrLEX0zg==", "dev": true, "license": "MIT", "engines": { @@ -6511,9 +6511,9 @@ "license": "MIT" }, "node_modules/nock": { - "version": "14.0.6", - "resolved": "https://registry.npmjs.org/nock/-/nock-14.0.6.tgz", - "integrity": "sha512-67n1OfusL/ON57fwFJ6ZurSJa/msYVQmqlz9rCel2HJYj4Zeb8v9TcmRdEW+PV2i9Fm2358umSvzZukhw/E8DA==", + "version": "14.0.7", + "resolved": "https://registry.npmjs.org/nock/-/nock-14.0.7.tgz", + "integrity": "sha512-ubwvvhSzNPqc7Nm3a/iYolwqb7lo1zfllDKO1ODsYu3KnarmQEya5yV70ZUwhVxYIl1ePuX3W+lHw2un+pUfpQ==", "dev": true, "license": "MIT", "dependencies": { diff --git a/node_modules/@eslint/js/package.json b/node_modules/@eslint/js/package.json index 7d7394b3f9..0c2e8bae38 100644 --- a/node_modules/@eslint/js/package.json +++ b/node_modules/@eslint/js/package.json @@ -1,6 +1,6 @@ { "name": "@eslint/js", - "version": "9.31.0", + "version": "9.32.0", "description": "ESLint JavaScript language implementation", "funding": "https://eslint.org/donate", "main": "./src/index.js", diff --git a/node_modules/nock/README.md b/node_modules/nock/README.md index 01d5f4a5a1..54bdc58d65 100644 --- a/node_modules/nock/README.md +++ b/node_modules/nock/README.md @@ -91,6 +91,7 @@ For instance, if a module performs HTTP requests to a CouchDB server or makes HT - [Requests made by ES Modules are not intercepted](#requests-made-by-es-modules-are-not-intercepted) - [Axios](#axios) - [Memory issues with Jest](#memory-issues-with-jest) + - [Fake timers](#fake-timers) - [Debugging](#debugging) - [Contributing](#contributing) - [Contributors](#contributors) @@ -1613,6 +1614,86 @@ One of the core principles of [Jest](https://jestjs.io/) is that it runs tests i It does this by manipulating the modules cache of Node in a way that conflicts with how Nock monkey patches the builtin `http` and `https` modules. [Related issue with more details](https://github.com/nock/nock/issues/1817). +### Fake timers + +### Jest + +To use `nock` in conjunction with `jest` fake timers, make sure you're using the "async" functions when advancing the +timers, such as `jest.advanceTimersByTimeAsync()` or `jest.runAllTimersAsync()`. Otherwise, the timers will not be +advanced correctly and you'll experience a timeout in your tests. + +```js +test('should mock a request with fake timers', async () => { + jest.useFakeTimers() + + const scope = nock('https://example.com') + .get('/path') + .delay(1000) + .reply(200, 'response') + + // Simulate a request + const request = got('https://example.com/path') + + // Fast-forward time + await jest.advanceTimersByTimeAsync(1000) + + // Or advance all timers + await jest.runAllTimersAsync() + + // Wait for the request to complete + const response = await request + + expect(response.body).toBe('response') + jest.useRealTimers() // Restore real timers after the test + scope.done() +}) +``` + +In case you don't need testing delays, you can instruct `jest` to advance the timers automatically using the +`advanceTimers` option + +```js +jest.useFakeTimers({ advanceTimers: true }) +``` + +### Sinon + +In a similar way to `jest`, if you are using `sinon` fake timers, you should use the `clock.tickAsync()` or +`clock.runAllAsync()` methods to advance the timers correctly. + +```js +it('should us sinon timers', async () => { + clock = sinon.useFakeTimers() + const scope = nock('https://example.com') + .get('/path') + .delay(1000) + .reply(200, 'response') + + // Simulate a request + const request = got('https://example.com/path') + + // Fast-forward time + await clock.tickAsync(1000) + + // Or run all timers + await clock.runAllAsync() + + // Wait for the request to complete + const response = await request + + expect(response.body).toBe('response') + clock.restore() + scope.done() +}) +``` + +Same applies for `sinon`, if you don't need testing delays, you can instruct `sinon` to advance the timers automatically +using the `shouldAdvanceTime` option + +```js +clock = sinon.useFakeTimers({ shouldAdvanceTime: true }) +``` + ## Debugging Nock uses node internals [`debuglog`](https://nodejs.org/api/util.html#utildebuglogsection-callbackg), so just run with environmental variable `NODE_DEBUG` set to `nock:*`. diff --git a/node_modules/nock/lib/common.js b/node_modules/nock/lib/common.js index 312bf1c260..0d8035ffcd 100644 --- a/node_modules/nock/lib/common.js +++ b/node_modules/nock/lib/common.js @@ -1,7 +1,6 @@ 'use strict' const { common: debug } = require('./debug') -const timers = require('timers') const url = require('url') const util = require('util') const http = require('http') @@ -521,24 +520,36 @@ function deepEqual(expected, actual) { const timeouts = new Set() const immediates = new Set() -const wrapTimer = - (timer, ids) => - (callback, ...timerArgs) => { - const cb = (...callbackArgs) => { - try { - // eslint-disable-next-line n/no-callback-literal - callback(...callbackArgs) - } finally { - ids.delete(id) - } +const _setImmediate = (callback, ...timerArgs) => { + const cb = (...callbackArgs) => { + try { + // eslint-disable-next-line n/no-callback-literal + callback(...callbackArgs) + } finally { + immediates.delete(id) + } + } + + const id = setImmediate(cb, 0, ...timerArgs) + + immediates.add(id) + return id +} + +const _setTimeout = (callback, ...timerArgs) => { + const cb = (...callbackArgs) => { + try { + // eslint-disable-next-line n/no-callback-literal + callback(...callbackArgs) + } finally { + timeouts.delete(id) } - const id = timer(cb, ...timerArgs) - ids.add(id) - return id } -const setTimeout = wrapTimer(timers.setTimeout, timeouts) -const setImmediate = wrapTimer(timers.setImmediate, immediates) + const id = setTimeout(cb, ...timerArgs) + timeouts.add(id) + return id +} function clearTimer(clear, ids) { ids.forEach(clear) @@ -714,8 +725,8 @@ module.exports = { percentDecode, percentEncode, removeAllTimers, - setImmediate, - setTimeout, + setImmediate: _setImmediate, + setTimeout: _setTimeout, stringifyRequest, convertFetchRequestToClientRequest, } diff --git a/node_modules/nock/package.json b/node_modules/nock/package.json index eab5d44d7b..7166a8ccaf 100644 --- a/node_modules/nock/package.json +++ b/node_modules/nock/package.json @@ -7,7 +7,7 @@ "testing", "isolation" ], - "version": "14.0.6", + "version": "14.0.7", "author": "Pedro Teixeira ", "repository": { "type": "git", diff --git a/package-lock.json b/package-lock.json index afde35d936..4d100f13f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -47,7 +47,7 @@ "@ava/typescript": "6.0.0", "@eslint/compat": "^1.3.1", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.31.0", + "@eslint/js": "^9.32.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", @@ -66,7 +66,7 @@ "eslint-plugin-github": "^5.1.8", "eslint-plugin-import": "2.29.1", "eslint-plugin-no-async-foreach": "^0.1.1", - "nock": "^14.0.6", + "nock": "^14.0.7", "removeNPMAbsolutePaths": "3.0.1", "sinon": "^21.0.0", "typescript": "^5.8.3" @@ -891,9 +891,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.31.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.31.0.tgz", - "integrity": "sha512-LOm5OVt7D4qiKCqoiPbA7LWmI+tbw1VbTUowBcUMgQSuM6poJufkFkYDcQpo5KfgD39TnNySV26QjOh7VFpSyw==", + "version": "9.32.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.32.0.tgz", + "integrity": "sha512-BBpRFZK3eX6uMLKz8WxFOBIFFcGFJ/g8XuwjTHCqHROSIsopI+ddn/d5Cfh36+7+e5edVS8dbSHnBNhrLEX0zg==", "dev": true, "license": "MIT", "engines": { @@ -6579,9 +6579,9 @@ "license": "MIT" }, "node_modules/nock": { - "version": "14.0.6", - "resolved": "https://registry.npmjs.org/nock/-/nock-14.0.6.tgz", - "integrity": "sha512-67n1OfusL/ON57fwFJ6ZurSJa/msYVQmqlz9rCel2HJYj4Zeb8v9TcmRdEW+PV2i9Fm2358umSvzZukhw/E8DA==", + "version": "14.0.7", + "resolved": "https://registry.npmjs.org/nock/-/nock-14.0.7.tgz", + "integrity": "sha512-ubwvvhSzNPqc7Nm3a/iYolwqb7lo1zfllDKO1ODsYu3KnarmQEya5yV70ZUwhVxYIl1ePuX3W+lHw2un+pUfpQ==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 7b52ce0912..028d7b43e4 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "@ava/typescript": "6.0.0", "@eslint/compat": "^1.3.1", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "^9.31.0", + "@eslint/js": "^9.32.0", "@microsoft/eslint-formatter-sarif": "^3.1.0", "@types/archiver": "^6.0.3", "@types/console-log-level": "^1.4.5", @@ -79,7 +79,7 @@ "eslint-plugin-github": "^5.1.8", "eslint-plugin-import": "2.29.1", "eslint-plugin-no-async-foreach": "^0.1.1", - "nock": "^14.0.6", + "nock": "^14.0.7", "removeNPMAbsolutePaths": "3.0.1", "sinon": "^21.0.0", "typescript": "^5.8.3"