From 39dfe0880fa934e287e8ea1f7b56d5cba8d43765 Mon Sep 17 00:00:00 2001 From: Scott O'Hara Date: Sat, 26 Oct 2019 05:20:27 +1100 Subject: [PATCH] Update: false positives in function-call-argument-newline (fixes #12123) (#12280) * Fix: false positives on newlines in object/array args (fixes #12123) * Update: Additional tests for multi-line template string --- lib/rules/function-call-argument-newline.js | 10 +- .../rules/function-call-argument-newline.js | 126 +++++++++++++++++- 2 files changed, 130 insertions(+), 6 deletions(-) diff --git a/lib/rules/function-call-argument-newline.js b/lib/rules/function-call-argument-newline.js index 8bf31f7c713..31ebc097c46 100644 --- a/lib/rules/function-call-argument-newline.js +++ b/lib/rules/function-call-argument-newline.js @@ -40,13 +40,13 @@ module.exports = { const checkers = { unexpected: { messageId: "unexpectedLineBreak", - check: (prevToken, currentToken) => prevToken.loc.start.line !== currentToken.loc.start.line, + check: (prevToken, currentToken) => prevToken.loc.end.line !== currentToken.loc.start.line, createFix: (token, tokenBefore) => fixer => fixer.replaceTextRange([tokenBefore.range[1], token.range[0]], " ") }, missing: { messageId: "missingLineBreak", - check: (prevToken, currentToken) => prevToken.loc.start.line === currentToken.loc.start.line, + check: (prevToken, currentToken) => prevToken.loc.end.line === currentToken.loc.start.line, createFix: (token, tokenBefore) => fixer => fixer.replaceTextRange([tokenBefore.range[1], token.range[0]], "\n") } @@ -61,7 +61,7 @@ module.exports = { */ function checkArguments(node, checker) { for (let i = 1; i < node.arguments.length; i++) { - const prevArgToken = sourceCode.getFirstToken(node.arguments[i - 1]); + const prevArgToken = sourceCode.getLastToken(node.arguments[i - 1]); const currentArgToken = sourceCode.getFirstToken(node.arguments[i]); if (checker.check(prevArgToken, currentArgToken)) { @@ -101,10 +101,10 @@ module.exports = { } else if (option === "always") { checkArguments(node, checkers.missing); } else if (option === "consistent") { - const firstArgToken = sourceCode.getFirstToken(node.arguments[0]); + const firstArgToken = sourceCode.getLastToken(node.arguments[0]); const secondArgToken = sourceCode.getFirstToken(node.arguments[1]); - if (firstArgToken.loc.start.line === secondArgToken.loc.start.line) { + if (firstArgToken.loc.end.line === secondArgToken.loc.start.line) { checkArguments(node, checkers.unexpected); } else { checkArguments(node, checkers.missing); diff --git a/tests/lib/rules/function-call-argument-newline.js b/tests/lib/rules/function-call-argument-newline.js index 2871534e79d..6a5b739afbf 100644 --- a/tests/lib/rules/function-call-argument-newline.js +++ b/tests/lib/rules/function-call-argument-newline.js @@ -46,6 +46,8 @@ ruleTester.run("function-call-argument-newline", rule, { options: ["always"], parserOptions: { ecmaVersion: 6 } }, + { code: "fn({\n\ta: 1\n},\n\tb,\n\tc)", options: ["always"] }, + { code: "fn(`\n`,\n\ta)", options: ["always"], parserOptions: { ecmaVersion: 6 } }, /* "never" */ { code: "fn(a, b)", options: ["never"] }, @@ -59,10 +61,16 @@ ruleTester.run("function-call-argument-newline", rule, { options: ["never"], parserOptions: { ecmaVersion: 6 } }, + { code: "fn({\n\ta: 1\n}, b)", options: ["never"] }, + { code: "fn(`\n`, a)", options: ["never"], parserOptions: { ecmaVersion: 6 } }, /* "consistent" */ { code: "fn(a, b, c)", options: ["consistent"] }, - { code: "fn(a,\n\tb,\n\tc)", options: ["consistent"] } + { code: "fn(a,\n\tb,\n\tc)", options: ["consistent"] }, + { code: "fn({\n\ta: 1\n}, b, c)", options: ["consistent"] }, + { code: "fn({\n\ta: 1\n},\n\tb,\n\tc)", options: ["consistent"] }, + { code: "fn(`\n`, b, c)", options: ["consistent"], parserOptions: { ecmaVersion: 6 } }, + { code: "fn(`\n`,\n\tb,\n\tc)", options: ["consistent"], parserOptions: { ecmaVersion: 6 } } ], invalid: [ @@ -202,6 +210,35 @@ ruleTester.run("function-call-argument-newline", rule, { } ] }, + { + code: "fn({\n\ta: 1\n}, b)", + output: "fn({\n\ta: 1\n},\nb)", + options: ["always"], + errors: [ + { + messageId: "missingLineBreak", + line: 3, + column: 3, + endLine: 3, + endColumn: 4 + } + ] + }, + { + code: "fn(`\n`, b)", + output: "fn(`\n`,\nb)", + options: ["always"], + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: "missingLineBreak", + line: 2, + column: 3, + endLine: 2, + endColumn: 4 + } + ] + }, /* "never" */ { @@ -324,6 +361,35 @@ ruleTester.run("function-call-argument-newline", rule, { } ] }, + { + code: "fn({\n\ta: 1\n},\nb)", + output: "fn({\n\ta: 1\n}, b)", + options: ["never"], + errors: [ + { + messageId: "unexpectedLineBreak", + line: 3, + column: 3, + endLine: 4, + endColumn: 1 + } + ] + }, + { + code: "fn(`\n`,\nb)", + output: "fn(`\n`, b)", + options: ["never"], + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: "unexpectedLineBreak", + line: 2, + column: 3, + endLine: 3, + endColumn: 1 + } + ] + }, /* "consistent" */ { @@ -381,6 +447,64 @@ ruleTester.run("function-call-argument-newline", rule, { endColumn: 19 } ] + }, + { + code: "fn({\n\ta: 1\n},\nb, c)", + output: "fn({\n\ta: 1\n},\nb,\nc)", + options: ["consistent"], + errors: [ + { + messageId: "missingLineBreak", + line: 4, + column: 3, + endLine: 4, + endColumn: 4 + } + ] + }, + { + code: "fn({\n\ta: 1\n}, b,\nc)", + output: "fn({\n\ta: 1\n}, b, c)", + options: ["consistent"], + errors: [ + { + messageId: "unexpectedLineBreak", + line: 3, + column: 6, + endLine: 4, + endColumn: 1 + } + ] + }, + { + code: "fn(`\n`,\nb, c)", + output: "fn(`\n`,\nb,\nc)", + options: ["consistent"], + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: "missingLineBreak", + line: 3, + column: 3, + endLine: 3, + endColumn: 4 + } + ] + }, + { + code: "fn(`\n`, b,\nc)", + output: "fn(`\n`, b, c)", + options: ["consistent"], + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: "unexpectedLineBreak", + line: 2, + column: 6, + endLine: 3, + endColumn: 1 + } + ] } ] });