diff --git a/docs/rules/multiline-ternary.md b/docs/rules/multiline-ternary.md index e331078f3a4..4faaad79c0f 100644 --- a/docs/rules/multiline-ternary.md +++ b/docs/rules/multiline-ternary.md @@ -26,6 +26,7 @@ Note: The location of the operators is not enforced by this rule. Please see the This rule has a string option: * `"always"` (default) enforces newlines between the operands of a ternary expression. +* `"always-multiline"` enforces newlines between the operands of a ternary expression if the expression spans multiple lines. * `"never"` disallows newlines between the operands of a ternary expression (enforcing that the entire ternary expression is on one line). ### always @@ -62,6 +63,50 @@ foo > bar ? value3; ``` +### always-multiline + +Examples of **incorrect** code for this rule with the `"always-multiline"` option: + +```js +/*eslint multiline-ternary: ["error", "always"]*/ + +foo > bar ? value1 : + value2; + +foo > bar ? + value1 : value2; + +foo > bar && + bar > baz ? value1 : value2; +``` + +Examples of **correct** code for this rule with the `"always-multiline"` option: + +```js +/*eslint multiline-ternary: ["error", "always"]*/ + +foo > bar ? value1 : value2; + +foo > bar ? + value1 : + value2; + +foo > bar ? + (baz > qux ? value1 : value2) : + value3; + +foo > bar ? + (baz > qux ? + value1 : + value2) : + value3; + +foo > bar && + bar > baz ? + value1 : + value2; +``` + ### never Examples of **incorrect** code for this rule with the `"never"` option: diff --git a/lib/rules/multiline-ternary.js b/lib/rules/multiline-ternary.js index de19bd43fd6..a74f241d86c 100644 --- a/lib/rules/multiline-ternary.js +++ b/lib/rules/multiline-ternary.js @@ -20,13 +20,15 @@ module.exports = { }, schema: [ { - enum: ["always", "never"] + enum: ["always", "always-multiline", "never"] } ] }, create(context) { - const multiline = context.options[0] !== "never"; + const option = context.options[0]; + const multiline = option !== "never"; + const allowSingleLine = option === "always-multiline"; //-------------------------------------------------------------------------- // Helpers @@ -69,6 +71,10 @@ module.exports = { reportError(node.consequent, node, false); } } else { + if (allowSingleLine && node.loc.start.line === node.loc.end.line) { + return; + } + if (areTestAndConsequentOnSameLine) { reportError(node.test, node, true); } diff --git a/tests/lib/rules/multiline-ternary.js b/tests/lib/rules/multiline-ternary.js index 74221b6c040..30750246c04 100644 --- a/tests/lib/rules/multiline-ternary.js +++ b/tests/lib/rules/multiline-ternary.js @@ -37,6 +37,17 @@ ruleTester.run("multiline-ternary", rule, { { code: "a\n? b\n? c\n: d\n: e", options: ["always"] }, { code: "a\n? (b\n? c\n: d)\n: e", options: ["always"] }, + // "always-multiline" + { code: "a\n? b\n: c", options: ["always-multiline"] }, + { code: "a ?\nb :\nc", options: ["always-multiline"] }, + { code: "a\n? b\n? c\n: d\n: e", options: ["always-multiline"] }, + { code: "a\n? (b\n? c\n: d)\n: e", options: ["always-multiline"] }, + { code: "a ? b : c", options: ["always-multiline"] }, + { code: "a ? b ? c : d : e", options: ["always-multiline"] }, + { code: "a ? (b ? c : d) : e", options: ["always-multiline"] }, + { code: "a\n? (b ? c : d)\n: e", options: ["always-multiline"] }, + { code: "a ?\n(b ? c : d) :\ne", options: ["always-multiline"] }, + // "never" { code: "a ? b : c", options: ["never"] }, { code: "a ? b ? c : d : e", options: ["never"] }, @@ -282,6 +293,137 @@ ruleTester.run("multiline-ternary", rule, { }] }, + // "always-multiline" + { + code: "a\n? b : c", + options: ["always-multiline"], + errors: [{ + message: expectedConsAltMsg, + line: 2, + column: 3 + }] + }, + { + code: "a ? b\n: c", + options: ["always-multiline"], + errors: [{ + message: expectedTestConsMsg, + line: 1, + column: 1 + }] + }, + { + code: "a &&\nb ? c : d", + options: ["always-multiline"], + errors: [{ + message: expectedTestConsMsg, + line: 1, + column: 1 + }, + { + message: expectedConsAltMsg, + line: 2, + column: 5 + }] + }, + { + code: "a ? b +\nc : d", + options: ["always-multiline"], + errors: [{ + message: expectedTestConsMsg, + line: 1, + column: 1 + }, + { + message: expectedConsAltMsg, + line: 1, + column: 5 + }] + }, + { + code: "a ? b : c +\nd", + options: ["always-multiline"], + errors: [{ + message: expectedTestConsMsg, + line: 1, + column: 1 + }, + { + message: expectedConsAltMsg, + line: 1, + column: 5 + }] + }, + { + code: "a ?\n(b ? c : d) : e", + options: ["always-multiline"], + errors: [{ + message: expectedConsAltMsg, + line: 2, + column: 2 + }] + }, + { + code: "a ? (b ? c : d) :\ne", + options: ["always-multiline"], + errors: [{ + message: expectedTestConsMsg, + line: 1, + column: 1 + }] + }, + { + code: "a ? (b\n? c\n: d) : e", + options: ["always-multiline"], + errors: [{ + message: expectedTestConsMsg, + line: 1, + column: 1 + }, + { + message: expectedConsAltMsg, + line: 1, + column: 6 + }] + }, + { + code: "a ?\n(b ? c\n: d) : e", + options: ["always-multiline"], + errors: [{ + message: expectedConsAltMsg, + line: 2, + column: 2 + }, + { + message: expectedTestConsMsg, + line: 2, + column: 2 + }] + }, + { + code: "a ?\n(b\n? c : d) : e", + options: ["always-multiline"], + errors: [{ + message: expectedConsAltMsg, + line: 2, + column: 2 + }, + { + message: expectedConsAltMsg, + line: 3, + column: 3 + }] + }, + { + code: "a ?\n(b\n? c\n : d) : e", + options: ["always-multiline"], + errors: [{ + message: expectedConsAltMsg, + line: 2, + column: 2 + }] + }, + // "never" { code: "a\n? b : c",