Skip to content

Commit

Permalink
Update: make newline-per-chained-call fixable (#9149)
Browse files Browse the repository at this point in the history
  • Loading branch information
joaogranado authored and kaicataldo committed Sep 13, 2017
1 parent 61f1093 commit 2731f94
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 4 deletions.
23 changes: 20 additions & 3 deletions lib/rules/newline-per-chained-call.js
Expand Up @@ -19,7 +19,7 @@ module.exports = {
category: "Stylistic Issues",
recommended: false
},

fixable: "whitespace",
schema: [{
type: "object",
properties: {
Expand All @@ -40,6 +40,18 @@ module.exports = {

const sourceCode = context.getSourceCode();

/**
* Get the prefix of a given MemberExpression node.
* If the MemberExpression node is a computed value it returns a
* left bracket. If not it returns a period.
*
* @param {ASTNode} node - A MemberExpression node to get
* @returns {string} The prefix of the node.
*/
function getPrefix(node) {
return node.computed ? "[" : ".";
}

/**
* Gets the property text of a given MemberExpression node.
* If the text is multiline, this returns only the first line.
Expand All @@ -48,7 +60,7 @@ module.exports = {
* @returns {string} The property text of the node.
*/
function getPropertyText(node) {
const prefix = node.computed ? "[" : ".";
const prefix = getPrefix(node);
const lines = sourceCode.getText(node.property).split(astUtils.LINEBREAK_MATCHER);
const suffix = node.computed && lines.length === 1 ? "]" : "";

Expand All @@ -70,13 +82,18 @@ module.exports = {
parent = parent.callee.object;
}

if (depth > ignoreChainWithDepth && callee.property.loc.start.line === callee.object.loc.end.line) {
if (depth > ignoreChainWithDepth && astUtils.isTokenOnSameLine(callee.object, callee.property)) {
context.report({
node: callee.property,
loc: callee.property.loc.start,
message: "Expected line break before `{{callee}}`.",
data: {
callee: getPropertyText(callee)
},
fix(fixer) {
const firstTokenAfterObject = sourceCode.getTokenAfter(callee.object, astUtils.isNotClosingParenToken);

return fixer.insertTextBefore(firstTokenAfterObject, "\n");
}
});
}
Expand Down
68 changes: 67 additions & 1 deletion tests/lib/rules/newline-per-chained-call.js
Expand Up @@ -28,45 +28,53 @@ ruleTester.run("newline-per-chained-call", rule, {
}],
invalid: [{
code: "_\n.chain({}).map(foo).filter(bar).value();",
output: "_\n.chain({}).map(foo)\n.filter(bar)\n.value();",
errors: [{
message: "Expected line break before `.filter`."
}, {
message: "Expected line break before `.value`."
}]
}, {
code: "_\n.chain({})\n.map(foo)\n.filter(bar).value();",
output: "_\n.chain({})\n.map(foo)\n.filter(bar)\n.value();",
errors: [{
message: "Expected line break before `.value`."
}]
}, {
code: "a().b().c().e.d()",
output: "a().b()\n.c().e.d()",
errors: [{
message: "Expected line break before `.c`."
}]
}, {
code: "a.b.c().e().d()",
output: "a.b.c().e()\n.d()",
errors: [{
message: "Expected line break before `.d`."
}]
}, {
code: "_.chain({}).map(a).value(); ",
output: "_.chain({}).map(a)\n.value(); ",
errors: [{
message: "Expected line break before `.value`."
}]
}, {
code: "var a = m1.m2();\n var b = m1.m2().m3().m4().m5();",
output: "var a = m1.m2();\n var b = m1.m2().m3()\n.m4()\n.m5();",
errors: [{
message: "Expected line break before `.m4`."
}, {
message: "Expected line break before `.m5`."
}]
}, {
code: "var a = m1.m2();\n var b = m1.m2().m3()\n.m4().m5();",
output: "var a = m1.m2();\n var b = m1.m2().m3()\n.m4()\n.m5();",
errors: [{
message: "Expected line break before `.m5`."
}]
}, {
code: "var a = m1().m2\n.m3().m4().m5().m6().m7();",
output: "var a = m1().m2\n.m3().m4().m5()\n.m6()\n.m7();",
options: [{
ignoreChainWithDepth: 3
}],
Expand Down Expand Up @@ -105,6 +113,37 @@ ruleTester.run("newline-per-chained-call", rule, {
" // Do something with error.",
"}).end();"
].join("\n"),
output: [
"http.request({",
" // Param",
" // Param",
" // Param",
"}).on('response', function(response) {",
" // Do something with response.",
" // Do something with response.",
" // Do something with response.",
" // Do something with response.",
" // Do something with response.",
" // Do something with response.",
" // Do something with response.",
" // Do something with response.",
" // Do something with response.",
" // Do something with response.",
"})",
".on('error', function(error) {",
" // Do something with error.",
" // Do something with error.",
" // Do something with error.",
" // Do something with error.",
" // Do something with error.",
" // Do something with error.",
" // Do something with error.",
" // Do something with error.",
" // Do something with error.",
" // Do something with error.",
"})",
".end();"
].join("\n"),
errors: [{
message: "Expected line break before `.on`."
}, {
Expand All @@ -116,15 +155,42 @@ ruleTester.run("newline-per-chained-call", rule, {
" 'method3' :",
" 'method4']()"
].join("\n"),
output: [
"anObject.method1().method2()",
"['method' + n]()",
"[aCondition ?",
" 'method3' :",
" 'method4']()"
].join("\n"),
errors: [{
message: "Expected line break before `['method' + n]`."
}, {
message: "Expected line break before `[aCondition ?`."
}]
}, {
code: "foo.bar()['foo' + \u2029 + 'bar']()",
output: "foo.bar()\n['foo' + \u2029 + 'bar']()",
options: [{ ignoreChainWithDepth: 1 }],
errors: [{ message: "Expected line break before `['foo' + `." }]
}, {
code: "foo.bar()[(biz)]()",
output: "foo.bar()\n[(biz)]()",
options: [{ ignoreChainWithDepth: 1 }],
errors: [{ message: "Expected line break before `[biz]`." }]
}, {
code: "(foo).bar().biz()",
output: "(foo).bar()\n.biz()",
options: [{ ignoreChainWithDepth: 1 }],
errors: [{ message: "Expected line break before `.biz`." }]
}, {
code: "foo.bar(). /* comment */ biz()",
output: "foo.bar()\n. /* comment */ biz()",
options: [{ ignoreChainWithDepth: 1 }],
errors: [{ message: "Expected line break before `.biz`." }]
}, {
code: "foo.bar() /* comment */ .biz()",
output: "foo.bar() /* comment */ \n.biz()",
options: [{ ignoreChainWithDepth: 1 }],
errors: [{ message: "Expected line break before `.biz`." }]
}]

});

0 comments on commit 2731f94

Please sign in to comment.