From 2afb223fb5384da2416ecf4b39ac45963d9ee2d5 Mon Sep 17 00:00:00 2001 From: Anshuman Verma Date: Mon, 31 May 2021 19:17:14 +0530 Subject: [PATCH] fix: polling usage in watchFiles option (#3366) --- lib/Server.js | 10 +- .../watchFiles-option.test.js.snap.webpack4 | 85 +++++++++++++++++ .../watchFiles-option.test.js.snap.webpack5 | 85 +++++++++++++++++ test/server/watchFiles-option.test.js | 94 +++++++++++++------ 4 files changed, 242 insertions(+), 32 deletions(-) create mode 100644 test/server/__snapshots__/watchFiles-option.test.js.snap.webpack4 create mode 100644 test/server/__snapshots__/watchFiles-option.test.js.snap.webpack5 diff --git a/lib/Server.js b/lib/Server.js index b1c6d5c41f..9ae798d97e 100644 --- a/lib/Server.js +++ b/lib/Server.js @@ -973,9 +973,15 @@ class Server { // /~https://github.com/webpack/watchpack/blob/master/lib/DirectoryWatcher.js#L49 // this isn't an elegant solution, but we'll improve it in the future // eslint-disable-next-line no-undefined - const usePolling = watchOptions.poll ? true : undefined; + const usePolling = + typeof watchOptions.usePolling !== 'undefined' + ? watchOptions.usePolling + : Boolean(watchOptions.poll); const interval = - typeof watchOptions.poll === 'number' + // eslint-disable-next-line no-nested-ternary + typeof watchOptions.interval !== 'undefined' + ? watchOptions.interval + : typeof watchOptions.poll === 'number' ? watchOptions.poll : // eslint-disable-next-line no-undefined undefined; diff --git a/test/server/__snapshots__/watchFiles-option.test.js.snap.webpack4 b/test/server/__snapshots__/watchFiles-option.test.js.snap.webpack4 new file mode 100644 index 0000000000..783029c365 --- /dev/null +++ b/test/server/__snapshots__/watchFiles-option.test.js.snap.webpack4 @@ -0,0 +1,85 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`'watchFiles' option should work with options {"poll":200} should pass correct options to chokidar config 1`] = ` +Object { + "alwaysStat": true, + "atomic": false, + "followSymlinks": false, + "ignoreInitial": true, + "ignorePermissionErrors": true, + "ignored": undefined, + "interval": 200, + "persistent": true, + "usePolling": true, +} +`; + +exports[`'watchFiles' option should work with options {"poll":true} should pass correct options to chokidar config 1`] = ` +Object { + "alwaysStat": true, + "atomic": false, + "followSymlinks": false, + "ignoreInitial": true, + "ignorePermissionErrors": true, + "ignored": undefined, + "interval": undefined, + "persistent": true, + "usePolling": true, +} +`; + +exports[`'watchFiles' option should work with options {"usePolling":false,"poll":true} should pass correct options to chokidar config 1`] = ` +Object { + "alwaysStat": true, + "atomic": false, + "followSymlinks": false, + "ignoreInitial": true, + "ignorePermissionErrors": true, + "ignored": undefined, + "interval": undefined, + "persistent": true, + "usePolling": false, +} +`; + +exports[`'watchFiles' option should work with options {"usePolling":false} should pass correct options to chokidar config 1`] = ` +Object { + "alwaysStat": true, + "atomic": false, + "followSymlinks": false, + "ignoreInitial": true, + "ignorePermissionErrors": true, + "ignored": undefined, + "interval": undefined, + "persistent": true, + "usePolling": false, +} +`; + +exports[`'watchFiles' option should work with options {"usePolling":true,"interval":200,"poll":400} should pass correct options to chokidar config 1`] = ` +Object { + "alwaysStat": true, + "atomic": false, + "followSymlinks": false, + "ignoreInitial": true, + "ignorePermissionErrors": true, + "ignored": undefined, + "interval": 200, + "persistent": true, + "usePolling": true, +} +`; + +exports[`'watchFiles' option should work with options {"usePolling":true} should pass correct options to chokidar config 1`] = ` +Object { + "alwaysStat": true, + "atomic": false, + "followSymlinks": false, + "ignoreInitial": true, + "ignorePermissionErrors": true, + "ignored": undefined, + "interval": undefined, + "persistent": true, + "usePolling": true, +} +`; diff --git a/test/server/__snapshots__/watchFiles-option.test.js.snap.webpack5 b/test/server/__snapshots__/watchFiles-option.test.js.snap.webpack5 new file mode 100644 index 0000000000..783029c365 --- /dev/null +++ b/test/server/__snapshots__/watchFiles-option.test.js.snap.webpack5 @@ -0,0 +1,85 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`'watchFiles' option should work with options {"poll":200} should pass correct options to chokidar config 1`] = ` +Object { + "alwaysStat": true, + "atomic": false, + "followSymlinks": false, + "ignoreInitial": true, + "ignorePermissionErrors": true, + "ignored": undefined, + "interval": 200, + "persistent": true, + "usePolling": true, +} +`; + +exports[`'watchFiles' option should work with options {"poll":true} should pass correct options to chokidar config 1`] = ` +Object { + "alwaysStat": true, + "atomic": false, + "followSymlinks": false, + "ignoreInitial": true, + "ignorePermissionErrors": true, + "ignored": undefined, + "interval": undefined, + "persistent": true, + "usePolling": true, +} +`; + +exports[`'watchFiles' option should work with options {"usePolling":false,"poll":true} should pass correct options to chokidar config 1`] = ` +Object { + "alwaysStat": true, + "atomic": false, + "followSymlinks": false, + "ignoreInitial": true, + "ignorePermissionErrors": true, + "ignored": undefined, + "interval": undefined, + "persistent": true, + "usePolling": false, +} +`; + +exports[`'watchFiles' option should work with options {"usePolling":false} should pass correct options to chokidar config 1`] = ` +Object { + "alwaysStat": true, + "atomic": false, + "followSymlinks": false, + "ignoreInitial": true, + "ignorePermissionErrors": true, + "ignored": undefined, + "interval": undefined, + "persistent": true, + "usePolling": false, +} +`; + +exports[`'watchFiles' option should work with options {"usePolling":true,"interval":200,"poll":400} should pass correct options to chokidar config 1`] = ` +Object { + "alwaysStat": true, + "atomic": false, + "followSymlinks": false, + "ignoreInitial": true, + "ignorePermissionErrors": true, + "ignored": undefined, + "interval": 200, + "persistent": true, + "usePolling": true, +} +`; + +exports[`'watchFiles' option should work with options {"usePolling":true} should pass correct options to chokidar config 1`] = ` +Object { + "alwaysStat": true, + "atomic": false, + "followSymlinks": false, + "ignoreInitial": true, + "ignorePermissionErrors": true, + "ignored": undefined, + "interval": undefined, + "persistent": true, + "usePolling": true, +} +`; diff --git a/test/server/watchFiles-option.test.js b/test/server/watchFiles-option.test.js index b14a79cdd4..87ce8236de 100644 --- a/test/server/watchFiles-option.test.js +++ b/test/server/watchFiles-option.test.js @@ -2,6 +2,7 @@ const path = require('path'); const fs = require('graceful-fs'); +const chokidar = require('chokidar'); const testServer = require('../helpers/test-server'); const config = require('../fixtures/contentbase-config/webpack.config'); const port = require('../ports-map')['watchFiles-option']; @@ -277,38 +278,71 @@ describe("'watchFiles' option", () => { describe('should work with options', () => { const file = path.join(watchDir, 'assets/example.txt'); - beforeAll((done) => { - server = testServer.start( - config, - { - watchFiles: { - paths: file, - options: { - usePolling: true, + const chokidarMock = jest.spyOn(chokidar, 'watch'); + + const optionCases = [ + { + poll: true, + }, + { + poll: 200, + }, + { + usePolling: true, + }, + { + usePolling: false, + }, + { + usePolling: false, + poll: true, + }, + { + usePolling: true, + interval: 200, + poll: 400, + }, + ]; + + optionCases.forEach((optionCase) => { + describe(JSON.stringify(optionCase), () => { + beforeAll((done) => { + chokidarMock.mockClear(); + server = testServer.start( + config, + { + watchFiles: { + paths: file, + options: optionCase, + }, + port, }, - }, - port, - }, - done - ); - }); - - afterAll((done) => { - testServer.close(done); - fs.truncateSync(file); - }); - - it('should reload on file content changed', (done) => { - server.staticWatchers[0].on('change', (changedPath) => { - expect(changedPath).toBe(file); - - done(); + done + ); + }); + + afterAll((done) => { + testServer.close(done); + fs.truncateSync(file); + }); + + it('should pass correct options to chokidar config', () => { + expect(chokidarMock.mock.calls[0][1]).toMatchSnapshot(); + }); + + it('should reload on file content changed', (done) => { + server.staticWatchers[0].on('change', (changedPath) => { + expect(changedPath).toBe(file); + + done(); + }); + + // change file content + setTimeout(() => { + fs.writeFileSync(file, 'Kurosaki Ichigo', 'utf8'); + }, 1000); + }); }); - - // change file content - setTimeout(() => { - fs.writeFileSync(file, 'Kurosaki Ichigo', 'utf8'); - }, 1000); }); }); });