requireAlignedMultilineParams: new rule #1901
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
/** | ||
* Enforces indentation of parameters in multiline functions | ||
* | ||
* Types: `Boolean`, `String`, `Number` | ||
* | ||
* Values: | ||
* - `true` to require parameters are aligned with the body of the function | ||
* - `'firstParam'` to require parameters to be aligned with the first parameter | ||
* - `Number` for the number of columns the parameters should be indented past the function body | ||
* | ||
* #### Example | ||
* | ||
* ```js | ||
* "disallowSpaceBeforeComma": true | ||
* ``` | ||
* | ||
* ##### Valid for `true` | ||
* | ||
* ```js | ||
* var test = function(one, two, | ||
* three, four, five, | ||
* six, seven, eight) { | ||
* console.log(a); | ||
* }; | ||
* ``` | ||
* | ||
* ##### Valid for `2` | ||
* | ||
* ```js | ||
* var test = function(one, two, | ||
* three, four, five, | ||
* six, seven, eight) { | ||
* console.log(a); | ||
* }; | ||
* ``` | ||
* | ||
* ##### Valid for `'firstParam'` | ||
* | ||
* ```js | ||
* var test = function(one, two, | ||
* three, four, five, | ||
* six, seven, eight) { | ||
* console.log(a); | ||
* }; | ||
* ``` | ||
* | ||
*/ | ||
|
||
var assert = require('assert'); | ||
|
||
module.exports = function() { | ||
}; | ||
|
||
module.exports.prototype = { | ||
|
||
configure: function(option) { | ||
if (typeof option === 'number') { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We want to switch to https://github.com/mafintosh/is-my-json-valid, to simplify those assertions, we can either leave this as is or you can help us out and simplify live of developers after you. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd lean towards leaving it as is, since I don't see the benefit of switching to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In your case, close to none, since you already wrote the logic and tests for it, for supporting it, there some benefit and for developers that could use this as an example for the new rules There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In that case, I'd prefer to leave it as is. The tests/logic is already done, and I don't think this is the best example to use it in. Here, we're only validating the type/value of the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Soon we will start to use it even in most simplest cases, no sweat though, as-is is fine, will try it out on the next rule :-) |
||
this._indentationLevel = option; | ||
} else if (typeof option === 'string') { | ||
assert( | ||
option === 'firstParam', | ||
this.getOptionName() + ' option requires string value to be "firstParam"' | ||
); | ||
|
||
this._alignWithFirstParam = true; | ||
} else if (option === true) { | ||
this._indentationLevel = 0; | ||
} else { | ||
assert( | ||
false, | ||
this.getOptionName() + ' option requires a valid option' | ||
); | ||
} | ||
}, | ||
|
||
getOptionName: function() { | ||
return 'requireAlignedMultilineParams'; | ||
}, | ||
|
||
check: function(file, errors) { | ||
var _this = this; | ||
file.iterateNodesByType(['FunctionDeclaration', 'FunctionExpression'], function(node) { | ||
var params = node.params; | ||
|
||
// We can pass the check if there's no params | ||
if (params.length === 0) { | ||
return; | ||
} | ||
|
||
var currentLine = params[0].loc.start.line; | ||
var referenceColumn; | ||
if (_this._alignWithFirstParam) { | ||
referenceColumn = params[0].loc.start.column; | ||
} else { | ||
referenceColumn = node.body.body[0].loc.start.column + _this._indentationLevel; | ||
} | ||
|
||
params.forEach(function(param) { | ||
if (param.loc.start.line !== currentLine) { | ||
if (param.loc.start.column !== referenceColumn) { | ||
errors.assert.indentation({ | ||
lineNumber: param.loc.start.line, | ||
actual: param.loc.start.column, | ||
expected: referenceColumn, | ||
indentChar: ' ', | ||
silent: false | ||
}); | ||
} | ||
|
||
currentLine = param.loc.start.line; | ||
} | ||
}); | ||
|
||
}); | ||
} | ||
|
||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
var Checker = require('../../../lib/checker'); | ||
var expect = require('chai').expect; | ||
|
||
describe('rules/require-aligned-multiline-params', function() { | ||
var checker; | ||
var option; | ||
function rules() { return { 'requireAlignedMultilineParams': option }; } | ||
|
||
describe('when we pass true as the config option', function() { | ||
beforeEach(function() { | ||
checker = new Checker(); | ||
checker.registerDefaultRules(); | ||
option = true; | ||
checker.configure(rules()); | ||
}); | ||
|
||
it('should validate a function with no params properly', function() { | ||
var noParamFunction = 'var noParamFunction = function() { \n' + | ||
' return;\n' + | ||
'};'; | ||
|
||
expect(checker.checkString(noParamFunction)).to.have.no.errors(); | ||
}); | ||
|
||
it('should validate a function with a single line of params properly', function() { | ||
var singleLineFunction = 'var singleLineFunction = function(a, b, c) { \n' + | ||
' console.log(a + b + c);\n' + | ||
'};'; | ||
|
||
expect(checker.checkString(singleLineFunction)).to.have.no.errors(); | ||
}); | ||
|
||
it('should validate a function with aligned params properly', function() { | ||
var unalignedFunction = 'var alignedFunction = function(a,\n' + | ||
' b, c,\n' + | ||
' d, e) {\n' + | ||
' console.log(a + b + c + d + e);\n' + | ||
'};'; | ||
|
||
expect(checker.checkString(unalignedFunction)).to.have.no.errors(); | ||
}); | ||
|
||
it('should validate a function with one unaligned param properly', function() { | ||
var unalignedFunction = 'var unalignedFunction = function(a,\n' + | ||
' b, c,\n' + | ||
' d, e) {\n' + | ||
' console.log(a + b + c + d + e);\n' + | ||
'};'; | ||
|
||
expect(checker.checkString(unalignedFunction)).to.have.one.validation.error.from( | ||
'requireAlignedMultilineParams'); | ||
}); | ||
|
||
it('should validate a function with two unaligned params properly', function() { | ||
var unalignedFunction = 'var unalignedFunction = function(a,\n' + | ||
' b, c,\n' + | ||
' d, e) {\n' + | ||
' console.log(a + b + c + d + e);\n' + | ||
'};'; | ||
|
||
expect(checker.checkString(unalignedFunction)).to.have.error.count.equal(2); | ||
}); | ||
}); | ||
|
||
describe('when we pass a number as the config option', function() { | ||
beforeEach(function() { | ||
checker = new Checker(); | ||
checker.registerDefaultRules(); | ||
option = 2; | ||
checker.configure(rules()); | ||
}); | ||
|
||
it('should validate a function with no params properly', function() { | ||
var noParamFunction = 'var noParamFunction = function() { \n' + | ||
' return;\n' + | ||
'};'; | ||
|
||
expect(checker.checkString(noParamFunction)).to.have.no.errors(); | ||
}); | ||
|
||
it('should validate a function with a single line of params properly', function() { | ||
var singleLineFunction = 'var singleLineFunction = function(a, b, c) { \n' + | ||
' console.log(a + b + c);\n' + | ||
'};'; | ||
|
||
expect(checker.checkString(singleLineFunction)).to.have.no.errors(); | ||
}); | ||
|
||
it('should validate a function with aligned params properly', function() { | ||
var unalignedFunction = 'var alignedFunction = function(a,\n' + | ||
' b, c,\n' + | ||
' d, e) {\n' + | ||
' console.log(a + b + c + d + e);\n' + | ||
'};'; | ||
|
||
expect(checker.checkString(unalignedFunction)).to.have.no.errors(); | ||
}); | ||
|
||
it('should validate a function with one unaligned param properly', function() { | ||
var unalignedFunction = 'var unalignedFunction = function(a,\n' + | ||
' b, c,\n' + | ||
' d, e) {\n' + | ||
' console.log(a + b + c + d + e);\n' + | ||
'};'; | ||
|
||
expect(checker.checkString(unalignedFunction)).to.have.one.validation.error.from( | ||
'requireAlignedMultilineParams'); | ||
}); | ||
|
||
it('should validate a function with two unaligned params properly', function() { | ||
var unalignedFunction = 'var unalignedFunction = function(a,\n' + | ||
' b, c,\n' + | ||
' d, e) {\n' + | ||
' console.log(a + b + c + d + e);\n' + | ||
'};'; | ||
|
||
expect(checker.checkString(unalignedFunction)).to.have.error.count.equal(2); | ||
}); | ||
}); | ||
|
||
describe('when we pass "firstParam" as the config option', function() { | ||
beforeEach(function() { | ||
checker = new Checker(); | ||
checker.registerDefaultRules(); | ||
option = 'firstParam'; | ||
checker.configure(rules()); | ||
}); | ||
|
||
it('should validate a function with no params properly', function() { | ||
var noParamFunction = 'var noParamFunction = function() { \n' + | ||
' return;\n' + | ||
'};'; | ||
|
||
expect(checker.checkString(noParamFunction)).to.have.no.errors(); | ||
}); | ||
|
||
it('should validate a function with a single line of params properly', function() { | ||
var singleLineFunction = 'var singleLineFunction = function(a, b, c) { \n' + | ||
' console.log(a + b + c);\n' + | ||
'};'; | ||
|
||
expect(checker.checkString(singleLineFunction)).to.have.no.errors(); | ||
}); | ||
|
||
it('should validate a function with aligned params properly', function() { | ||
var unalignedFunction = 'var alignedFunction = function(a,\n' + | ||
' b, c,\n' + | ||
' d, e) {\n' + | ||
' console.log(a + b + c + d + e);\n' + | ||
'};'; | ||
|
||
expect(checker.checkString(unalignedFunction)).to.have.no.errors(); | ||
}); | ||
|
||
it('should validate a function with one unaligned param properly', function() { | ||
var unalignedFunction = 'var unalignedFunction = function(a,\n' + | ||
' b, c,\n' + | ||
' d, e) {\n' + | ||
' console.log(a + b + c + d + e);\n' + | ||
'};'; | ||
|
||
expect(checker.checkString(unalignedFunction)).to.have.one.validation.error.from( | ||
'requireAlignedMultilineParams'); | ||
}); | ||
|
||
it('should validate a function with two unaligned params properly', function() { | ||
var unalignedFunction = 'var unalignedFunction = function(a,\n' + | ||
' b, c,\n' + | ||
' d, e) {\n' + | ||
' console.log(a + b + c + d + e);\n' + | ||
'};'; | ||
|
||
expect(checker.checkString(unalignedFunction)).to.have.error.count.equal(2); | ||
}); | ||
}); | ||
}); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you also add invalid case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added!