diff --git a/bin/webpack-dev-server.js b/bin/webpack-dev-server.js index f8a5ed20dc..23a788fb5a 100755 --- a/bin/webpack-dev-server.js +++ b/bin/webpack-dev-server.js @@ -22,7 +22,10 @@ let server; const serverData = { server: null, }; - +// we must pass an object that contains the server object as a property so that +// we can update this server property later, and setupExitSignals will be able to +// recognize that the server has been instantiated, because we will set +// serverData.server to the new server object. setupExitSignals(serverData); // Prefer the local installation of webpack-dev-server diff --git a/test/server/utils/setupExitSignals.test.js b/test/server/utils/setupExitSignals.test.js new file mode 100644 index 0000000000..774b88cb9d --- /dev/null +++ b/test/server/utils/setupExitSignals.test.js @@ -0,0 +1,57 @@ +'use strict'; + +const setupExitSignals = require('../../../lib/utils/setupExitSignals'); + +describe('setupExitSignals', () => { + let server; + let exitSpy; + const signals = ['SIGINT', 'SIGTERM']; + + beforeAll(() => { + exitSpy = jest.spyOn(process, 'exit').mockImplementation(() => { }); + server = { + close: jest.fn((callback) => { + callback(); + }), + }; + }); + + afterEach(() => { + exitSpy.mockReset(); + server.close.mockClear(); + signals.forEach((signal) => { + process.removeAllListeners(signal); + }); + }); + + signals.forEach((signal) => { + it(`should exit process (${signal}, server never defined)`, (done) => { + setupExitSignals({ + server: null, + }); + process.emit(signal); + setTimeout(() => { + expect(exitSpy.mock.calls.length).toEqual(1); + done(); + }, 1000); + }); + + it(`should close server, then exit process (${signal}, server defined before signal)`, (done) => { + const serverData = { + server: null, + }; + setupExitSignals(serverData); + + setTimeout(() => { + serverData.server = server; + process.emit(signal); + }, 500); + + setTimeout(() => { + expect(server.close.mock.calls.length).toEqual(1); + expect(exitSpy.mock.calls.length).toEqual(1); + done(); + }, 1500); + }); + }); +});