diff --git a/lib/rules/quotes.js b/lib/rules/quotes.js index 6dd0ed996c7..5c53c76908c 100644 --- a/lib/rules/quotes.js +++ b/lib/rules/quotes.js @@ -258,7 +258,11 @@ module.exports = { return; } - const shouldWarn = node.quasis.length === 1 && (node.quasis[0].value.cooked.indexOf("\n") === -1); + /* + * A warning should be produced if the template literal only has one TemplateElement, and has no unescaped newlines. + * An unescaped newline is a newline preceded by an even number of backslashes. + */ + const shouldWarn = node.quasis.length === 1 && !/(^|[^\\])(\\\\)*[\r\n\u2028\u2029]/.test(node.quasis[0].value.raw); if (shouldWarn) { context.report({ diff --git a/tests/lib/rules/quotes.js b/tests/lib/rules/quotes.js index d01ef76cbdc..d7430c8c19c 100644 --- a/tests/lib/rules/quotes.js +++ b/tests/lib/rules/quotes.js @@ -38,6 +38,16 @@ ruleTester.run("quotes", rule, { // Backticks are only okay if they have substitutions, contain a line break, or are tagged { code: "var foo = `back\ntick`;", options: ["single"], parserOptions: { ecmaVersion: 6 }}, + { code: "var foo = `back\rtick`;", options: ["single"], parserOptions: { ecmaVersion: 6 }}, + { code: "var foo = `back\u2028tick`;", options: ["single"], parserOptions: { ecmaVersion: 6 }}, + { code: "var foo = `back\u2029tick`;", options: ["single"], parserOptions: { ecmaVersion: 6 }}, + { + code: "var foo = `back\\\\\ntick`;", // 2 backslashes followed by a newline + options: ["single"], + parserOptions: { ecmaVersion: 6 } + }, + { code: "var foo = `back\\\\\\\\\ntick`;", options: ["single"], parserOptions: { ecmaVersion: 6 }}, + { code: "var foo = `\n`;", options: ["single"], parserOptions: { ecmaVersion: 6 }}, { code: "var foo = `back${x}tick`;", options: ["double"], parserOptions: { ecmaVersion: 6 }}, { code: "var foo = tag`backtick`;", options: ["double"], parserOptions: { ecmaVersion: 6 }}, @@ -272,6 +282,26 @@ ruleTester.run("quotes", rule, { output: "foo(); \"use strict\";", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Strings must use doublequote.", type: "TemplateLiteral" }] + }, + + // https://github.com/eslint/eslint/issues/7646 + { + code: "var foo = `foo\\nbar`;", + output: "var foo = \"foo\\nbar\";", + parserOptions: { ecmaVersion: 6 }, + errors: [{ message: "Strings must use doublequote.", type: "TemplateLiteral" }] + }, + { + code: "var foo = `foo\\\nbar`;", // 1 backslash followed by a newline + output: "var foo = \"foo\\\nbar\";", + parserOptions: { ecmaVersion: 6 }, + errors: [{ message: "Strings must use doublequote.", type: "TemplateLiteral" }] + }, + { + code: "var foo = `foo\\\\\\\nbar`;", // 3 backslashes followed by a newline + output: "var foo = \"foo\\\\\\\nbar\";", + parserOptions: { ecmaVersion: 6 }, + errors: [{ message: "Strings must use doublequote.", type: "TemplateLiteral" }] } ] });