diff --git a/.eslintrc b/.eslintrc index af0e6ddc15670f..59f9f06e8baa0d 100644 --- a/.eslintrc +++ b/.eslintrc @@ -85,9 +85,10 @@ rules: prefer-const: 2 # Custom rules in tools/eslint-rules + align-function-arguments: 2 + align-multiline-assignment: 2 assert-fail-single-argument: 2 new-with-error: [2, "Error", "RangeError", "TypeError", "SyntaxError", "ReferenceError"] - align-multiline-assignment: 2 # Global scoped method and vars globals: diff --git a/test/internet/test-dgram-multicast-multi-process.js b/test/internet/test-dgram-multicast-multi-process.js index 040b89e0b2cd04..dfbe9a3077b94a 100644 --- a/test/internet/test-dgram-multicast-multi-process.js +++ b/test/internet/test-dgram-multicast-multi-process.js @@ -91,7 +91,7 @@ function launchChildProcess(index) { worker.pid, count); assert.strictEqual(count, messages.length, - 'A worker received an invalid multicast message'); + 'A worker received an invalid multicast message'); }); clearTimeout(timer); diff --git a/test/parallel/test-assert.js b/test/parallel/test-assert.js index 460829a16ea884..80af439e7f36ec 100644 --- a/test/parallel/test-assert.js +++ b/test/parallel/test-assert.js @@ -461,7 +461,7 @@ try { } catch (e) { assert.equal(e.toString().split('\n')[0], 'AssertionError: oh no'); assert.equal(e.generatedMessage, false, - 'Message incorrectly marked as generated'); + 'Message incorrectly marked as generated'); } // Verify that throws() and doesNotThrow() throw on non-function block diff --git a/test/parallel/test-buffer.js b/test/parallel/test-buffer.js index db2b0ae7a22b57..d0ebe64db9453a 100644 --- a/test/parallel/test-buffer.js +++ b/test/parallel/test-buffer.js @@ -571,18 +571,30 @@ assert.equal(new Buffer('KioqKioqKioqKioqKioqKioqKio', 'base64').toString(), '********************'); // handle padding graciously, multiple-of-4 or not -assert.equal(new Buffer('72INjkR5fchcxk9+VgdGPFJDxUBFR5/rMFsghgxADiw==', - 'base64').length, 32); -assert.equal(new Buffer('72INjkR5fchcxk9+VgdGPFJDxUBFR5/rMFsghgxADiw=', - 'base64').length, 32); -assert.equal(new Buffer('72INjkR5fchcxk9+VgdGPFJDxUBFR5/rMFsghgxADiw', - 'base64').length, 32); -assert.equal(new Buffer('w69jACy6BgZmaFvv96HG6MYksWytuZu3T1FvGnulPg==', - 'base64').length, 31); -assert.equal(new Buffer('w69jACy6BgZmaFvv96HG6MYksWytuZu3T1FvGnulPg=', - 'base64').length, 31); -assert.equal(new Buffer('w69jACy6BgZmaFvv96HG6MYksWytuZu3T1FvGnulPg', - 'base64').length, 31); +assert.equal( + new Buffer('72INjkR5fchcxk9+VgdGPFJDxUBFR5/rMFsghgxADiw==', 'base64').length, + 32 +); +assert.equal( + new Buffer('72INjkR5fchcxk9+VgdGPFJDxUBFR5/rMFsghgxADiw=', 'base64').length, + 32 +); +assert.equal( + new Buffer('72INjkR5fchcxk9+VgdGPFJDxUBFR5/rMFsghgxADiw', 'base64').length, + 32 +); +assert.equal( + new Buffer('w69jACy6BgZmaFvv96HG6MYksWytuZu3T1FvGnulPg==', 'base64').length, + 31 +); +assert.equal( + new Buffer('w69jACy6BgZmaFvv96HG6MYksWytuZu3T1FvGnulPg=', 'base64').length, + 31 +); +assert.equal( + new Buffer('w69jACy6BgZmaFvv96HG6MYksWytuZu3T1FvGnulPg', 'base64').length, + 31 +); // This string encodes single '.' character in UTF-16 var dot = new Buffer('//4uAA==', 'base64'); diff --git a/test/parallel/test-cluster-basic.js b/test/parallel/test-cluster-basic.js index 60bd27b24eee89..5a5efabbab821a 100644 --- a/test/parallel/test-cluster-basic.js +++ b/test/parallel/test-cluster-basic.js @@ -4,7 +4,7 @@ var assert = require('assert'); var cluster = require('cluster'); assert.equal('NODE_UNIQUE_ID' in process.env, false, - 'NODE_UNIQUE_ID should be removed on startup'); + 'NODE_UNIQUE_ID should be removed on startup'); function forEach(obj, fn) { Object.keys(obj).forEach(function(name, index) { @@ -93,7 +93,7 @@ else if (cluster.isMaster) { worker = cluster.fork(); assert.equal(worker.id, 1); assert.ok(worker instanceof cluster.Worker, - 'the worker is not a instance of the Worker constructor'); + 'the worker is not a instance of the Worker constructor'); //Check event forEach(checks.worker.events, function(bool, name, index) { diff --git a/test/parallel/test-crypto-binary-default.js b/test/parallel/test-crypto-binary-default.js index d2554ab6ec4d4d..129bbcacef151e 100644 --- a/test/parallel/test-crypto-binary-default.js +++ b/test/parallel/test-crypto-binary-default.js @@ -347,8 +347,11 @@ var a4 = crypto.createHash('sha1').update('Test123').digest('buffer'); if (!common.hasFipsCrypto) { var a0 = crypto.createHash('md5').update('Test123').digest('binary'); - assert.equal(a0, 'h\u00ea\u00cb\u0097\u00d8o\fF!\u00fa+\u000e\u0017\u00ca' + - '\u00bd\u008c', 'Test MD5 as binary'); + assert.equal( + a0, + 'h\u00ea\u00cb\u0097\u00d8o\fF!\u00fa+\u000e\u0017\u00ca\u00bd\u008c', + 'Test MD5 as binary' + ); } assert.equal(a1, '8308651804facb7b9af8ffc53a33a22d6a1c8ac2', 'Test SHA1'); diff --git a/test/parallel/test-crypto-hash.js b/test/parallel/test-crypto-hash.js index aec035afe184f4..8272aedcc51e1f 100644 --- a/test/parallel/test-crypto-hash.js +++ b/test/parallel/test-crypto-hash.js @@ -39,8 +39,11 @@ a8 = a8.read(); if (!common.hasFipsCrypto) { var a0 = crypto.createHash('md5').update('Test123').digest('binary'); - assert.equal(a0, 'h\u00ea\u00cb\u0097\u00d8o\fF!\u00fa+\u000e\u0017\u00ca' + - '\u00bd\u008c', 'Test MD5 as binary'); + assert.equal( + a0, + 'h\u00ea\u00cb\u0097\u00d8o\fF!\u00fa+\u000e\u0017\u00ca\u00bd\u008c', + 'Test MD5 as binary' + ); } assert.equal(a1, '8308651804facb7b9af8ffc53a33a22d6a1c8ac2', 'Test SHA1'); assert.equal(a2, '2bX1jws4GYKTlxhloUB09Z66PoJZW+y+hq5R8dnx9l4=', diff --git a/test/parallel/test-domain-exit-dispose-again.js b/test/parallel/test-domain-exit-dispose-again.js index 7360e79412296d..0928addd9ace55 100644 --- a/test/parallel/test-domain-exit-dispose-again.js +++ b/test/parallel/test-domain-exit-dispose-again.js @@ -38,7 +38,7 @@ setTimeout(function firstTimer() { d.dispose(); console.error(err); console.error('in domain error handler', - process.domain, process.domain === d); + process.domain, process.domain === d); }); d.run(function() { diff --git a/test/parallel/test-domain-throw-error-then-throw-from-uncaught-exception-handler.js b/test/parallel/test-domain-throw-error-then-throw-from-uncaught-exception-handler.js index 499988107dae27..ae86ef2cdf20d3 100644 --- a/test/parallel/test-domain-throw-error-then-throw-from-uncaught-exception-handler.js +++ b/test/parallel/test-domain-throw-error-then-throw-from-uncaught-exception-handler.js @@ -62,8 +62,8 @@ function runTestWithoutAbortOnUncaughtException() { 'include domain\'s error\'s message'); assert.notEqual(err.code, 0, - 'child process should have exited with a non-zero exit code, ' + - 'but did not'); + 'child process should have exited with a non-zero ' + + 'exit code, but did not'); }); } @@ -72,8 +72,8 @@ function runTestWithAbortOnUncaughtException() { withAbortOnUncaughtException: true }), function onTestDone(err, stdout, stderr) { assert.notEqual(err.code, RAN_UNCAUGHT_EXCEPTION_HANDLER_EXIT_CODE, - 'child process should not have run its uncaughtException event ' + - 'handler'); + 'child process should not have run its uncaughtException ' + + 'event handler'); assert(common.nodeProcessAborted(err.code, err.signal), 'process should have aborted, but did not'); }); diff --git a/test/parallel/test-domain-timers.js b/test/parallel/test-domain-timers.js index a97b300da02d31..58989e812bba50 100644 --- a/test/parallel/test-domain-timers.js +++ b/test/parallel/test-domain-timers.js @@ -34,7 +34,7 @@ timeout = setTimeout(function() {}, 10 * 1000); process.on('exit', function() { assert.equal(timeout_err.message, 'Timeout UNREFd', - 'Domain should catch timer error'); + 'Domain should catch timer error'); assert.equal(immediate_err.message, 'Immediate Error', - 'Domain should catch immediate error'); + 'Domain should catch immediate error'); }); diff --git a/test/parallel/test-domain-top-level-error-handler-clears-stack.js b/test/parallel/test-domain-top-level-error-handler-clears-stack.js index a5fec1f65ef029..f2095f09b7836c 100644 --- a/test/parallel/test-domain-top-level-error-handler-clears-stack.js +++ b/test/parallel/test-domain-top-level-error-handler-clears-stack.js @@ -23,7 +23,7 @@ d.on('error', common.mustCall(function() { // call to process._fatalException, and so on recursively and // indefinitely. console.error('domains stack length should be 1, but instead is:', - domain._stack.length); + domain._stack.length); process.exit(1); } }); diff --git a/test/parallel/test-file-write-stream2.js b/test/parallel/test-file-write-stream2.js index e95760bc2d9a4e..e11f7e7815f1d0 100644 --- a/test/parallel/test-file-write-stream2.js +++ b/test/parallel/test-file-write-stream2.js @@ -24,8 +24,8 @@ process.on('exit', function() { console.log(' expected: %j', cb_expected); console.log(' occurred: %j', cb_occurred); assert.strictEqual(cb_occurred, cb_expected, - 'events missing or out of order: "' + - cb_occurred + '" !== "' + cb_expected + '"'); + 'events missing or out of order: "' + + cb_occurred + '" !== "' + cb_expected + '"'); } else { console.log('ok'); } diff --git a/test/parallel/test-file-write-stream3.js b/test/parallel/test-file-write-stream3.js index caa0f106f4d91e..55806e8d22774c 100644 --- a/test/parallel/test-file-write-stream3.js +++ b/test/parallel/test-file-write-stream3.js @@ -24,8 +24,8 @@ process.on('exit', function() { console.log(' expected: %j', cb_expected); console.log(' occurred: %j', cb_occurred); assert.strictEqual(cb_occurred, cb_expected, - 'events missing or out of order: "' + - cb_occurred + '" !== "' + cb_expected + '"'); + 'events missing or out of order: "' + + cb_occurred + '" !== "' + cb_expected + '"'); } }); diff --git a/test/parallel/test-fs-realpath.js b/test/parallel/test-fs-realpath.js index bbe8c26d120f0e..d627c01487c2c2 100644 --- a/test/parallel/test-fs-realpath.js +++ b/test/parallel/test-fs-realpath.js @@ -338,14 +338,14 @@ function test_escape_cwd(cb) { console.log('test_escape_cwd'); asynctest(fs.realpath, ['..'], cb, function(er, uponeActual) { assert.equal(upone, uponeActual, - 'realpath("..") expected: ' + path.resolve(upone) + - ' actual:' + uponeActual); + 'realpath("..") expected: ' + path.resolve(upone) + + ' actual:' + uponeActual); }); } var uponeActual = fs.realpathSync('..'); assert.equal(upone, uponeActual, - 'realpathSync("..") expected: ' + path.resolve(upone) + - ' actual:' + uponeActual); + 'realpathSync("..") expected: ' + path.resolve(upone) + + ' actual:' + uponeActual); // going up with .. multiple times diff --git a/test/parallel/test-http-agent-error-on-idle.js b/test/parallel/test-http-agent-error-on-idle.js index e3388ee0dcbd96..f609efc8d59b6d 100644 --- a/test/parallel/test-http-agent-error-on-idle.js +++ b/test/parallel/test-http-agent-error-on-idle.js @@ -47,7 +47,7 @@ server.listen(common.PORT, function() { function done() { assert.equal(Object.keys(agent.freeSockets).length, 0, - 'expect the freeSockets pool to be empty'); + 'expect the freeSockets pool to be empty'); agent.destroy(); server.close(); diff --git a/test/parallel/test-http-agent-keepalive.js b/test/parallel/test-http-agent-keepalive.js index 6800e893e329da..85c0ad5dbc2b4f 100644 --- a/test/parallel/test-http-agent-keepalive.js +++ b/test/parallel/test-http-agent-keepalive.js @@ -74,7 +74,7 @@ function remoteClose() { setTimeout(function() { assert.equal(agent.sockets[name], undefined); assert.equal(agent.freeSockets[name], undefined, - 'freeSockets is not empty'); + 'freeSockets is not empty'); remoteError(); }, common.platformTimeout(200)); }); diff --git a/test/parallel/test-http-agent-maxsockets.js b/test/parallel/test-http-agent-maxsockets.js index e11aa2addad746..11f8d28a7389e2 100644 --- a/test/parallel/test-http-agent-maxsockets.js +++ b/test/parallel/test-http-agent-maxsockets.js @@ -30,7 +30,7 @@ function done() { } var freepool = agent.freeSockets[Object.keys(agent.freeSockets)[0]]; assert.equal(freepool.length, 2, - 'expect keep 2 free sockets, but got ' + freepool.length); + 'expect keep 2 free sockets, but got ' + freepool.length); agent.destroy(); server.close(); } diff --git a/test/parallel/test-http-destroyed-socket-write2.js b/test/parallel/test-http-destroyed-socket-write2.js index fd58892350bc2a..7588393840f2cc 100644 --- a/test/parallel/test-http-destroyed-socket-write2.js +++ b/test/parallel/test-http-destroyed-socket-write2.js @@ -42,8 +42,8 @@ server.listen(common.PORT, function() { default: assert.strictEqual(er.code, - 'ECONNRESET', - 'Writing to a torn down client should RESET or ABORT'); + 'ECONNRESET', + 'Write to a torn down client should RESET or ABORT'); break; } diff --git a/test/parallel/test-http-parser-bad-ref.js b/test/parallel/test-http-parser-bad-ref.js index 545a9c1fef11c4..01179641175e02 100644 --- a/test/parallel/test-http-parser-bad-ref.js +++ b/test/parallel/test-http-parser-bad-ref.js @@ -75,10 +75,12 @@ demoBug('POST /1', '/22 HTTP/1.1\r\n' + 'Content-Length: 4\r\n\r\n' + 'pong'); +/* eslint-disable align-function-arguments */ demoBug('POST /1/22 HTTP/1.1\r\n' + 'Content-Type: tex', 't/plain\r\n' + 'Content-Length: 4\r\n\r\n' + 'pong'); +/* eslint-enable align-function-arguments */ process.on('exit', function() { assert.equal(2, headersComplete); diff --git a/test/parallel/test-http-url.parse-post.js b/test/parallel/test-http-url.parse-post.js index b6a0fdeb255235..7611b0856320a6 100644 --- a/test/parallel/test-http-url.parse-post.js +++ b/test/parallel/test-http-url.parse-post.js @@ -14,7 +14,7 @@ function check(request) { assert.strictEqual(request.url, '/asdf?qwer=zxcv'); //the host header should use the url.parse.hostname assert.strictEqual(request.headers.host, - testURL.hostname + ':' + testURL.port); + testURL.hostname + ':' + testURL.port); } var server = http.createServer(function(request, response) { diff --git a/test/parallel/test-require-process.js b/test/parallel/test-require-process.js index 33634930b4e614..4e5821add13183 100644 --- a/test/parallel/test-require-process.js +++ b/test/parallel/test-require-process.js @@ -4,4 +4,4 @@ var assert = require('assert'); var nativeProcess = require('process'); assert.strictEqual(nativeProcess, process, - 'require("process") should return a reference to global process'); + 'require("process") should return global process reference'); diff --git a/test/parallel/test-timers-ordering.js b/test/parallel/test-timers-ordering.js index cef91e58e78c3d..c23af9d8307e9a 100644 --- a/test/parallel/test-timers-ordering.js +++ b/test/parallel/test-timers-ordering.js @@ -19,7 +19,7 @@ var f = function(i) { var now = Timer.now(); console.log(i, now); assert(now >= last_ts + 1, - 'current ts ' + now + ' < prev ts ' + last_ts + ' + 1'); + 'current ts ' + now + ' < prev ts ' + last_ts + ' + 1'); last_ts = now; // schedule next iteration diff --git a/test/parallel/test-timers-reset-process-domain-on-throw.js b/test/parallel/test-timers-reset-process-domain-on-throw.js index ab3ffd3596ed53..55e7ef57dcafc4 100644 --- a/test/parallel/test-timers-reset-process-domain-on-throw.js +++ b/test/parallel/test-timers-reset-process-domain-on-throw.js @@ -36,8 +36,8 @@ function secondTimer() { // secondTimer was scheduled before any domain had been created, so its // callback should not have any active domain set when it runs. if (process.domain !== null) { - console.log('process.domain should be null in this timer callback, but ' + - 'instead is:', process.domain); + console.log('process.domain should be null in this timer callback, but is:', + process.domain); // Do not use assert here, as it throws errors and if a domain with an error // handler is active, then asserting wouldn't make the test fail. process.exit(1); diff --git a/test/parallel/test-zlib-convenience-methods.js b/test/parallel/test-zlib-convenience-methods.js index 70c102efd2862c..ccb3347266a9b4 100644 --- a/test/parallel/test-zlib-convenience-methods.js +++ b/test/parallel/test-zlib-convenience-methods.js @@ -23,8 +23,8 @@ var opts = { zlib[method[0]](expect, opts, function(err, result) { zlib[method[1]](result, opts, function(err, result) { assert.equal(result, expect, - 'Should get original string after ' + - method[0] + '/' + method[1] + ' with options.'); + 'Should get original string after ' + + method[0] + '/' + method[1] + ' with options.'); hadRun++; }); }); @@ -32,8 +32,8 @@ var opts = { zlib[method[0]](expect, function(err, result) { zlib[method[1]](result, function(err, result) { assert.equal(result, expect, - 'Should get original string after ' + - method[0] + '/' + method[1] + ' without options.'); + 'Should get original string after ' + + method[0] + '/' + method[1] + ' without options.'); hadRun++; }); }); @@ -41,15 +41,15 @@ var opts = { var result = zlib[method[0] + 'Sync'](expect, opts); result = zlib[method[1] + 'Sync'](result, opts); assert.equal(result, expect, - 'Should get original string after ' + - method[0] + '/' + method[1] + ' with options.'); + 'Should get original string after ' + + method[0] + '/' + method[1] + ' with options.'); hadRun++; result = zlib[method[0] + 'Sync'](expect); result = zlib[method[1] + 'Sync'](result); assert.equal(result, expect, - 'Should get original string after ' + - method[0] + '/' + method[1] + ' without options.'); + 'Should get original string after ' + + method[0] + '/' + method[1] + ' without options.'); hadRun++; }); diff --git a/test/parallel/test-zlib-flush-drain.js b/test/parallel/test-zlib-flush-drain.js index 14a42e76cc3874..fcc17ad589d11f 100644 --- a/test/parallel/test-zlib-flush-drain.js +++ b/test/parallel/test-zlib-flush-drain.js @@ -38,11 +38,11 @@ deflater.on('drain', function() { process.once('exit', function() { assert.equal(beforeFlush, true, - 'before calling flush the writable stream should need to drain'); + 'before calling flush, writable stream should need to drain'); assert.equal(afterFlush, false, - 'after calling flush the writable stream should not need to drain'); + 'after calling flush, writable stream should not need to drain'); assert.equal(drainCount, 1, - 'the deflater should have emitted a single drain event'); + 'the deflater should have emitted a single drain event'); assert.equal(flushCount, 2, - 'flush should be called twice'); + 'flush should be called twice'); }); diff --git a/tools/doc/html.js b/tools/doc/html.js index feb99cd810415c..a232117439bbc7 100644 --- a/tools/doc/html.js +++ b/tools/doc/html.js @@ -11,11 +11,11 @@ module.exports = toHTML; // TODO(chrisdickinson): never stop vomitting / fix this. var gtocPath = path.resolve(path.join( __dirname, - '..', - '..', - 'doc', - 'api', - '_toc.markdown' + '..', + '..', + 'doc', + 'api', + '_toc.markdown' )); var gtocLoading = null; var gtocData = null; diff --git a/tools/eslint-rules/align-function-arguments.js b/tools/eslint-rules/align-function-arguments.js new file mode 100644 index 00000000000000..a8cd71660d7d60 --- /dev/null +++ b/tools/eslint-rules/align-function-arguments.js @@ -0,0 +1,70 @@ +/** + * @fileoverview Align arguments in multiline function calls + * @author Rich Trott + */ +'use strict'; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +function checkArgumentAlignment(context, node) { + + function isNodeFirstInLine(node, byEndLocation) { + const firstToken = byEndLocation === true ? context.getLastToken(node, 1) : + context.getTokenBefore(node); + const startLine = byEndLocation === true ? node.loc.end.line : + node.loc.start.line; + const endLine = firstToken ? firstToken.loc.end.line : -1; + + return startLine !== endLine; + } + + if (node.arguments.length === 0) + return; + + var msg = ''; + const first = node.arguments[0]; + var currentLine = first.loc.start.line; + const firstColumn = first.loc.start.column; + + const ignoreTypes = [ + 'ArrowFunctionExpression', + 'CallExpression', + 'FunctionExpression', + 'ObjectExpression', + 'TemplateLiteral' + ]; + + const args = node.arguments; + + // For now, don't bother trying to validate potentially complicating things + // like closures. Different people will have very different ideas and it's + // probably best to implement configuration options. + if (args.some((node) => { return ignoreTypes.indexOf(node.type) !== -1; })) { + return; + } + + if (!isNodeFirstInLine(node)) { + return; + } + + args.slice(1).forEach((argument) => { + if (argument.loc.start.line === currentLine + 1) { + if (argument.loc.start.column !== firstColumn) { + msg = 'Function called with argument in column ' + + `${argument.loc.start.column}, expected in ${firstColumn}`; + } + } + currentLine = argument.loc.start.line; + }); + + if (msg) + context.report(node, msg); +} + +module.exports = function(context) { + return { + 'CallExpression': (node) => checkArgumentAlignment(context, node) + }; +};