From 028ceee1693c7566ea7ea54048ced23db5409c32 Mon Sep 17 00:00:00 2001 From: Evilebot Tnawi Date: Tue, 9 Apr 2019 18:11:33 +0300 Subject: [PATCH] fix(regression): host and port can be undefined or null (#1779) --- lib/options.json | 32 +- test/BeforeAndAfter.test.js | 24 +- test/CreateConfig.test.js | 58 ++++ test/Server.test.js | 291 +++++++++++++++++++ test/__snapshots__/CreateConfig.test.js.snap | 70 +++++ test/helper.js | 8 +- 6 files changed, 458 insertions(+), 25 deletions(-) diff --git a/lib/options.json b/lib/options.json index 703e2b5657..80ff4fc952 100644 --- a/lib/options.json +++ b/lib/options.json @@ -17,7 +17,27 @@ "type": "boolean" }, "host": { - "type": "string" + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "port": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "null" + } + ] }, "allowedHosts": { "type": "array", @@ -41,16 +61,6 @@ "publicPath": { "type": "string" }, - "port": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "string" - } - ] - }, "socket": { "type": "string" }, diff --git a/test/BeforeAndAfter.test.js b/test/BeforeAndAfter.test.js index 9340eb0ddb..498fb354d0 100644 --- a/test/BeforeAndAfter.test.js +++ b/test/BeforeAndAfter.test.js @@ -12,38 +12,38 @@ describe('Before And After options', () => { server = helper.start( config, { - before: (app, server, compiler) => { - if (!app) { + before: (appArg, serverArg, compilerArg) => { + if (!appArg) { throw new Error('app is not defined'); } - if (!server) { + if (!serverArg) { throw new Error('server is not defined'); } - if (!compiler) { + if (!compilerArg) { throw new Error('compiler is not defined'); } - app.get('/before/some/path', (req, res) => { - res.send('before'); + appArg.get('/before/some/path', (_, response) => { + response.send('before'); }); }, - after: (app, server, compiler) => { - if (!app) { + after: (appArg, serverArg, compilerArg) => { + if (!appArg) { throw new Error('app is not defined'); } - if (!server) { + if (!serverArg) { throw new Error('server is not defined'); } - if (!compiler) { + if (!compilerArg) { throw new Error('compiler is not defined'); } - app.get('/after/some/path', (req, res) => { - res.send('after'); + appArg.get('/after/some/path', (_, response) => { + response.send('after'); }); }, }, diff --git a/test/CreateConfig.test.js b/test/CreateConfig.test.js index 5cce86344f..97c5d47cba 100644 --- a/test/CreateConfig.test.js +++ b/test/CreateConfig.test.js @@ -68,6 +68,32 @@ describe('createConfig', () => { expect(config).toMatchSnapshot(); }); + it('host option (undefined)', () => { + const config = createConfig( + webpackConfig, + Object.assign({}, argv, { + // eslint-disable-next-line no-undefined + host: undefined, + }), + { port: 8080 } + ); + + expect(config).toMatchSnapshot(); + }); + + it('host option (null)', () => { + const config = createConfig( + webpackConfig, + Object.assign({}, argv, { + // eslint-disable-next-line no-undefined + host: null, + }), + { port: 8080 } + ); + + expect(config).toMatchSnapshot(); + }); + it('host option (devServer config)', () => { const config = createConfig( Object.assign({}, webpackConfig, { devServer: { host: 'example.dev' } }), @@ -893,6 +919,38 @@ describe('createConfig', () => { expect(config).toMatchSnapshot(); }); + it('port option (same) (string)', () => { + const config = createConfig( + webpackConfig, + Object.assign({}, argv, { port: '9090' }), + { port: '9090' } + ); + + expect(config).toMatchSnapshot(); + }); + + it('port option (same) (null)', () => { + const config = createConfig( + webpackConfig, + Object.assign({}, argv, { port: null }), + { port: null } + ); + + expect(config).toMatchSnapshot(); + }); + + it('port option (same) (undefined)', () => { + const config = createConfig( + webpackConfig, + // eslint-disable-next-line no-undefined + Object.assign({}, argv, { port: undefined }), + // eslint-disable-next-line no-undefined + { port: undefined } + ); + + expect(config).toMatchSnapshot(); + }); + it('port option (difference)', () => { const config = createConfig( webpackConfig, diff --git a/test/Server.test.js b/test/Server.test.js index b538ce9eac..1c4182a39f 100644 --- a/test/Server.test.js +++ b/test/Server.test.js @@ -1,8 +1,10 @@ 'use strict'; const webpack = require('webpack'); +const request = require('supertest'); const Server = require('../lib/Server'); const config = require('./fixtures/simple-config/webpack.config'); +const helper = require('./helper'); const allStats = [ {}, @@ -142,4 +144,293 @@ describe('Server', () => { })(allStats[0], 0); }); }); + + describe('host', () => { + let server = null; + let req = null; + + describe('is not be specified', () => { + beforeAll((done) => { + server = helper.start(config, {}, done); + req = request(server.app); + }); + + it('server address', () => { + const address = server.listeningApp.address(); + + expect(address.address).toBe('127.0.0.1'); + expect(address.port).toBe(8080); + }); + + it('Request to index', (done) => { + req.get('/').expect(200, done); + }); + + afterAll(helper.close); + }); + + describe('is undefined', () => { + beforeAll((done) => { + server = helper.start( + config, + { + // eslint-disable-next-line no-undefined + host: undefined, + }, + done + ); + req = request(server.app); + }); + + it('server address', () => { + const address = server.listeningApp.address(); + + expect(address.address).toBe('::'); + expect(address.port).toBe(8080); + }); + + it('Request to index', (done) => { + req.get('/').expect(200, done); + }); + + afterAll(helper.close); + }); + + describe('is null', () => { + beforeAll((done) => { + server = helper.start( + config, + { + host: null, + }, + done + ); + req = request(server.app); + }); + + it('server address', () => { + const address = server.listeningApp.address(); + + expect(address.address).toBe('::'); + expect(address.port).toBe(8080); + }); + + it('Request to index', (done) => { + req.get('/').expect(200, done); + }); + + afterAll(helper.close); + }); + + describe('is 127.0.0.1 (IPv4)', () => { + beforeAll((done) => { + server = helper.start( + config, + { + host: '127.0.0.1', + }, + done + ); + req = request(server.app); + }); + + it('server address', () => { + const address = server.listeningApp.address(); + + expect(address.address).toBe('127.0.0.1'); + expect(address.port).toBe(8080); + }); + + it('Request to index', (done) => { + req.get('/').expect(200, done); + }); + + afterAll(helper.close); + }); + + describe('is localhost', () => { + beforeAll((done) => { + server = helper.start( + config, + { + host: 'localhost', + }, + done + ); + req = request(server.app); + }); + + it('server address', () => { + const address = server.listeningApp.address(); + + expect(address.address).toBe('127.0.0.1'); + expect(address.port).toBe(8080); + }); + + it('Request to index', (done) => { + req.get('/').expect(200, done); + }); + + afterAll(helper.close); + }); + + describe('is 0.0.0.0', () => { + beforeAll((done) => { + server = helper.start( + config, + { + host: '0.0.0.0', + }, + done + ); + req = request(server.app); + }); + + it('server address', () => { + const address = server.listeningApp.address(); + + expect(address.address).toBe('0.0.0.0'); + expect(address.port).toBe(8080); + }); + + it('Request to index', (done) => { + req.get('/').expect(200, done); + }); + + afterAll(helper.close); + }); + }); + + describe('port', () => { + let server = null; + let req = null; + + describe('is not be specified', () => { + beforeAll((done) => { + server = helper.start(config, {}, done); + req = request(server.app); + }); + + it('server address', () => { + const address = server.listeningApp.address(); + + expect(address.address).toBe('127.0.0.1'); + // Random port + expect(address.port).toBeDefined(); + }); + + it('Request to index', (done) => { + req.get('/').expect(200, done); + }); + + afterAll(helper.close); + }); + + describe('is undefined', () => { + beforeAll((done) => { + server = helper.start( + config, + { + // eslint-disable-next-line no-undefined + port: undefined, + }, + done + ); + req = request(server.app); + }); + + it('server address', () => { + const address = server.listeningApp.address(); + + expect(address.address).toBe('127.0.0.1'); + // Random port + expect(address.port).toBeDefined(); + }); + + it('Request to index', (done) => { + req.get('/').expect(200, done); + }); + + afterAll(helper.close); + }); + + describe('is null', () => { + beforeAll((done) => { + server = helper.start( + config, + { + port: null, + }, + done + ); + req = request(server.app); + }); + + it('server address', () => { + const address = server.listeningApp.address(); + + expect(address.address).toBe('127.0.0.1'); + // Random port + expect(address.port).toBeDefined(); + }); + + it('Request to index', (done) => { + req.get('/').expect(200, done); + }); + + afterAll(helper.close); + }); + + describe('is "33333"', () => { + beforeAll((done) => { + server = helper.start( + config, + { + port: '33333', + }, + done + ); + req = request(server.app); + }); + + it('server address', () => { + const address = server.listeningApp.address(); + + expect(address.address).toBe('127.0.0.1'); + expect(address.port).toBe(33333); + }); + + it('Request to index', (done) => { + req.get('/').expect(200, done); + }); + + afterAll(helper.close); + }); + + describe('is 33333', () => { + beforeAll((done) => { + server = helper.start( + config, + { + port: '33333', + }, + done + ); + req = request(server.app); + }); + + it('server address', () => { + const address = server.listeningApp.address(); + + expect(address.address).toBe('127.0.0.1'); + expect(address.port).toBe(33333); + }); + + it('Request to index', (done) => { + req.get('/').expect(200, done); + }); + + afterAll(helper.close); + }); + }); }); diff --git a/test/__snapshots__/CreateConfig.test.js.snap b/test/__snapshots__/CreateConfig.test.js.snap index bd0044f1a4..a3ec18de9c 100644 --- a/test/__snapshots__/CreateConfig.test.js.snap +++ b/test/__snapshots__/CreateConfig.test.js.snap @@ -388,6 +388,20 @@ Object { } `; +exports[`createConfig host option (null) 1`] = ` +Object { + "hot": true, + "hotOnly": false, + "noInfo": true, + "port": 8080, + "publicPath": "/", + "stats": Object { + "cached": false, + "cachedAssets": false, + }, +} +`; + exports[`createConfig host option (specify for CLI and devServer config) 1`] = ` Object { "host": "other.dev", @@ -403,6 +417,20 @@ Object { } `; +exports[`createConfig host option (undefined) 1`] = ` +Object { + "hot": true, + "hotOnly": false, + "noInfo": true, + "port": 8080, + "publicPath": "/", + "stats": Object { + "cached": false, + "cachedAssets": false, + }, +} +`; + exports[`createConfig host option 1`] = ` Object { "host": "example.dev", @@ -853,6 +881,48 @@ Object { } `; +exports[`createConfig port option (same) (null) 1`] = ` +Object { + "hot": true, + "hotOnly": false, + "noInfo": true, + "port": null, + "publicPath": "/", + "stats": Object { + "cached": false, + "cachedAssets": false, + }, +} +`; + +exports[`createConfig port option (same) (string) 1`] = ` +Object { + "hot": true, + "hotOnly": false, + "noInfo": true, + "port": "9090", + "publicPath": "/", + "stats": Object { + "cached": false, + "cachedAssets": false, + }, +} +`; + +exports[`createConfig port option (same) (undefined) 1`] = ` +Object { + "hot": true, + "hotOnly": false, + "noInfo": true, + "port": undefined, + "publicPath": "/", + "stats": Object { + "cached": false, + "cachedAssets": false, + }, +} +`; + exports[`createConfig port option (same) 1`] = ` Object { "hot": true, diff --git a/test/helper.js b/test/helper.js index 85cb09b1aa..28089f111c 100644 --- a/test/helper.js +++ b/test/helper.js @@ -39,8 +39,12 @@ module.exports = { server = new Server(compiler, options); - const port = options.port || 8080; - const host = options.host || 'localhost'; + const port = Object.prototype.hasOwnProperty.call(options, 'port') + ? options.port + : 8080; + const host = Object.prototype.hasOwnProperty.call(options, 'host') + ? options.host + : 'localhost'; server.listen(port, host, (err) => { if (err) {