Skip to content
This repository has been archived by the owner on Jul 13, 2021. It is now read-only.

fix: fixes #86, client port bungle #87

Merged
merged 2 commits into from
Jul 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions lib/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ module.exports = (opts = {}) => {
client: options.port,
server: options.port,
};
} else if (!options.port.server) {
} else if (isNaN(parseInt(options.port.server, 10))) {
throw new HotClientError(
'`port.server` must be defined when setting host to an Object'
);
} else if (!options.port.client) {
} else if (isNaN(parseInt(options.port.client, 10))) {
throw new HotClientError(
'`port.client` must be defined when setting host to an Object'
);
Expand All @@ -87,7 +87,8 @@ module.exports = (opts = {}) => {
if (server && server.listening) {
options.webSocket = {
host: server.address().address,
port: server.address().port,
// a port.client value of 0 will be falsy, so it should pull the server port
port: options.port.client || server.address().port,
};
} else {
options.webSocket = {
Expand Down
3 changes: 2 additions & 1 deletion lib/socket-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ function onListening(server, options) {
const { address, port } = server._server.address();
server.host = address;
server.port = port;
options.webSocket.port = port;
// a port.client value of 0 will be falsy, so it should pull the server port
options.webSocket.port = options.port.client || port;

log.info(`WebSocket Server Listening on ${host.server}:${port}`);
});
Expand Down
164 changes: 164 additions & 0 deletions test/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`api mismatched client/server options sanity check 1`] = `
Object {
"host": "0.0.0.0",
"port": 7000,
}
`;

exports[`api mismatched client/server options sanity check 2`] = `
Object {
"allEntries": false,
"autoConfigure": true,
"hmr": true,
"host": Object {
"client": "localhost",
"server": "0.0.0.0",
},
"https": undefined,
"log": LogLevel {
"currentLevel": 5,
"debug": [Function],
"error": [Function],
"info": [Function],
"log": [Function],
"methodFactory": PrefixFactory {
"options": Object {
"level": [Function],
"name": [Function],
"template": "{{level}} 「{{name}}」: ",
"time": [Function],
},
Symbol(a log instance): [Circular],
Symbol(valid log levels): Object {
"DEBUG": 1,
"ERROR": 4,
"INFO": 2,
"SILENT": 5,
"TRACE": 0,
"WARN": 3,
},
},
"name": "hot",
"options": Object {
"factory": null,
"level": "silent",
"name": "hot",
"prefix": Object {
"level": [Function],
"template": "{{level}} 「{{name}}」: ",
},
"timestamp": false,
"unique": true,
},
"trace": [Function],
"type": "LogLevel",
"warn": [Function],
},
"logLevel": "silent",
"logTime": false,
"port": Object {
"client": 6000,
"server": 7000,
},
"reload": true,
"send": Object {
"errors": true,
"warnings": true,
},
"server": null,
"stats": Object {
"context": "<PROJECT_ROOT>",
},
"test": false,
"validTargets": Array [
"web",
],
"webSocket": Object {
"host": "localhost",
"port": 6000,
},
}
`;

exports[`api options sanity check 1`] = `
Object {
"host": "127.0.0.1",
"port": Any<Number>,
}
`;

exports[`api options sanity check 2`] = `
Object {
"allEntries": false,
"autoConfigure": true,
"hmr": true,
"host": Object {
"client": "localhost",
"server": "localhost",
},
"https": undefined,
"log": LogLevel {
"currentLevel": 5,
"debug": [Function],
"error": [Function],
"info": [Function],
"log": [Function],
"methodFactory": PrefixFactory {
"options": Object {
"level": [Function],
"name": [Function],
"template": "{{level}} 「{{name}}」: ",
"time": [Function],
},
Symbol(a log instance): [Circular],
Symbol(valid log levels): Object {
"DEBUG": 1,
"ERROR": 4,
"INFO": 2,
"SILENT": 5,
"TRACE": 0,
"WARN": 3,
},
},
"name": "hot",
"options": Object {
"factory": null,
"level": "silent",
"name": "hot",
"prefix": Object {
"level": [Function],
"template": "{{level}} 「{{name}}」: ",
},
"timestamp": false,
"unique": true,
},
"trace": [Function],
"type": "LogLevel",
"warn": [Function],
},
"logLevel": "silent",
"logTime": false,
"port": Object {
"client": 0,
"server": 0,
},
"reload": true,
"send": Object {
"errors": true,
"warnings": true,
},
"server": null,
"stats": Object {
"context": "<PROJECT_ROOT>",
},
"test": false,
"validTargets": Array [
"web",
],
"webSocket": Object {
"port": Any<Number>,
},
}
`;
4 changes: 4 additions & 0 deletions test/__snapshots__/options.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -300,3 +300,7 @@ Object {
},
}
`;

exports[`options throws if port.client is missing 1`] = `"webpack-hot-client: \`port.client\` must be defined when setting host to an Object"`;

exports[`options throws if port.server is missing 1`] = `"webpack-hot-client: \`port.server\` must be defined when setting host to an Object"`;
11 changes: 11 additions & 0 deletions test/fixtures/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,14 @@ console.log('dirty');
console.log('dirty');
console.log('dirty');
console.log('dirty');

console.log('dirty');
console.log('dirty');
console.log('dirty');
console.log('dirty');
console.log('dirty');
console.log('dirty');

console.log('dirty');
console.log('dirty');
console.log('dirty');
45 changes: 45 additions & 0 deletions test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,49 @@ describe('api', () => {
});
});
});

test('options sanity check', (done) => {
const config = require('./fixtures/webpack.config-object.js');
const compiler = webpack(config);
const { options: opts, server } = client(compiler, options);

server.on('listening', () => {
const { host, port } = server;
expect({ host, port }).toMatchSnapshot({
port: expect.any(Number),
});
// this assign is necessary as Jest cannot manipulate a frozen object
expect(Object.assign({}, opts)).toMatchSnapshot({
webSocket: {
port: expect.any(Number),
},
});

setTimeout(() => server.close(done), 500);
});
});

test('mismatched client/server options sanity check', (done) => {
const config = require('./fixtures/webpack.config-object.js');
const compiler = webpack(config);
const clientOptions = Object.assign({}, options, {
host: {
client: 'localhost',
server: '0.0.0.0',
},
port: {
client: 6000,
server: 7000,
},
});
const { options: opts, server } = client(compiler, clientOptions);

server.on('listening', () => {
const { host, port } = server;
expect({ host, port }).toMatchSnapshot();
expect(opts).toMatchSnapshot();

setTimeout(() => server.close(done), 500);
});
});
});
12 changes: 11 additions & 1 deletion test/options.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ describe('options', () => {
});
});

test('throws on invalid options', () => {
test('throws on invalid host option', () => {
const t = () => getOptions({ host: true });
expect(t).toThrow();
});
Expand All @@ -101,4 +101,14 @@ describe('options', () => {
const t = () => getOptions({ host: { client: 'localhost' } });
expect(t).toThrow();
});

test('throws if port.client is missing', () => {
const t = () => getOptions({ port: { server: 0 } });
expect(t).toThrowErrorMatchingSnapshot();
});

test('throws if port.server is missing', () => {
const t = () => getOptions({ port: { client: 9000 } });
expect(t).toThrowErrorMatchingSnapshot();
});
});