From ca1afa68f7c9266344d61639272958d5c4cff73b Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Wed, 30 Sep 2020 19:58:47 +0800 Subject: [PATCH] `no-nested-ternary`: Improve report location & message (#844) --- rules/no-nested-ternary.js | 48 ++++++++---------- test/no-nested-ternary.js | 43 +++++++++-------- test/snapshots/no-nested-ternary.js.md | 59 ++++++++++++++++++++++- test/snapshots/no-nested-ternary.js.snap | Bin 234 -> 475 bytes 4 files changed, 100 insertions(+), 50 deletions(-) diff --git a/rules/no-nested-ternary.js b/rules/no-nested-ternary.js index 6780b4cef5..b73d44c936 100644 --- a/rules/no-nested-ternary.js +++ b/rules/no-nested-ternary.js @@ -2,41 +2,33 @@ const {isParenthesized} = require('eslint-utils'); const getDocumentationUrl = require('./utils/get-documentation-url'); -const MESSAGE_ID = 'no-nested-ternary'; +const MESSAGE_ID_TOO_DEEP = 'too-deep'; +const MESSAGE_ID_SHOULD_PARENTHESIZED = 'should-parenthesized'; const messages = { - [MESSAGE_ID]: 'Do not nest ternary expressions.' + [MESSAGE_ID_TOO_DEEP]: 'Do not nest ternary expressions.', + [MESSAGE_ID_SHOULD_PARENTHESIZED]: 'Nest ternary expression should be parenthesized.' }; +const nestTernarySelector = level => `:not(ConditionalExpression)${' > ConditionalExpression'.repeat(level)}`; + const create = context => { const sourceCode = context.getSourceCode(); return { - ConditionalExpression: node => { - const nodesToCheck = [node.alternate, node.consequent]; - - for (const childNode of nodesToCheck) { - if (childNode.type !== 'ConditionalExpression') { - continue; - } - - // Nesting more than one level not allowed. - if ( - childNode.alternate.type === 'ConditionalExpression' || - childNode.consequent.type === 'ConditionalExpression' - ) { - // TODO: Improve report location - context.report({node, messageId: MESSAGE_ID}); - break; - } else if (!isParenthesized(childNode, sourceCode)) { - context.report({ - node: childNode, - messageId: MESSAGE_ID, - fix: fixer => [ - fixer.insertTextBefore(childNode, '('), - fixer.insertTextAfter(childNode, ')') - ] - }); - } + [nestTernarySelector(3)]: node => { + // Nesting more than one level not allowed. + context.report({node, messageId: MESSAGE_ID_TOO_DEEP}); + }, + [nestTernarySelector(2)]: node => { + if (!isParenthesized(node, sourceCode)) { + context.report({ + node, + messageId: MESSAGE_ID_SHOULD_PARENTHESIZED, + fix: fixer => [ + fixer.insertTextBefore(node, '('), + fixer.insertTextAfter(node, ')') + ] + }); } } }; diff --git a/test/no-nested-ternary.js b/test/no-nested-ternary.js index 6c913e1dea..47e005ac3e 100644 --- a/test/no-nested-ternary.js +++ b/test/no-nested-ternary.js @@ -14,12 +14,6 @@ const typescriptRuleTester = avaRuleTester(test, { parser: require.resolve('@typescript-eslint/parser') }); -const errors = [ - { - messageId: 'no-nested-ternary' - } -]; - ruleTester.run('no-nested-ternary', rule, { valid: [ 'const foo = i > 5 ? true : false;', @@ -33,43 +27,36 @@ ruleTester.run('no-nested-ternary', rule, { invalid: [ { code: 'const foo = i > 5 ? true : (i < 100 ? true : (i < 1000 ? true : false));', - errors + errors: 1 }, { code: 'const foo = i > 5 ? true : (i < 100 ? (i > 50 ? false : true) : false);', - errors + errors: 1 }, { code: 'const foo = i > 5 ? i < 100 ? true : false : true;', output: 'const foo = i > 5 ? (i < 100 ? true : false) : true;', - errors + errors: 1 }, { code: 'const foo = i > 5 ? i < 100 ? true : false : i < 100 ? true : false;', output: 'const foo = i > 5 ? (i < 100 ? true : false) : (i < 100 ? true : false);', - errors: [ - { - column: 21 - }, - { - column: 46 - } - ] + errors: 2 }, { code: 'const foo = i > 5 ? true : i < 100 ? true : false;', output: 'const foo = i > 5 ? true : (i < 100 ? true : false);', - errors + errors: 1 }, { code: 'foo ? bar : baz === qux ? quxx : foobar;', output: 'foo ? bar : (baz === qux ? quxx : foobar);', - errors + errors: 1 }, { code: 'foo ? baz === qux ? quxx : foobar : bar;', output: 'foo ? (baz === qux ? quxx : foobar) : bar;', - errors + errors: 1 } ] }); @@ -96,5 +83,19 @@ const visualizeTester = visualizeRuleTester(test, { } }); visualizeTester.run('no-nested-ternary', rule, [ - 'const foo = i > 5 ? true : (i < 100 ? true : (i < 1000 ? true : false));' + 'const foo = i > 5 ? i < 100 ? true : false : i < 100 ? true : false;', + 'const foo = i > 5 ? true : (i < 100 ? true : (i < 1000 ? true : false));', + outdent` + const foo = a ? + b : + ( + c ? + d : + ( + e ? + f : + (g ? h : i) + ) + ) + ` ]); diff --git a/test/snapshots/no-nested-ternary.js.md b/test/snapshots/no-nested-ternary.js.md index ab56544d29..feb015d7b6 100644 --- a/test/snapshots/no-nested-ternary.js.md +++ b/test/snapshots/no-nested-ternary.js.md @@ -6,6 +6,25 @@ Generated by [AVA](https://avajs.dev). ## no-nested-ternary - #1 +> Snapshot 1 + + `␊ + Input:␊ + 1 | const foo = i > 5 ? i < 100 ? true : false : i < 100 ? true : false;␊ + ␊ + Output:␊ + 1 | const foo = i > 5 ? (i < 100 ? true : false) : (i < 100 ? true : false);␊ + ␊ + Error 1/2:␊ + > 1 | const foo = i > 5 ? i < 100 ? true : false : i < 100 ? true : false;␊ + | ^^^^^^^^^^^^^^^^^^^^^^ Nest ternary expression should be parenthesized.␊ + Error 2/2:␊ + > 1 | const foo = i > 5 ? i < 100 ? true : false : i < 100 ? true : false;␊ + | ^^^^^^^^^^^^^^^^^^^^^^ Nest ternary expression should be parenthesized.␊ + ` + +## no-nested-ternary - #2 + > Snapshot 1 `␊ @@ -17,5 +36,43 @@ Generated by [AVA](https://avajs.dev). ␊ Error 1/1:␊ > 1 | const foo = i > 5 ? true : (i < 100 ? true : (i < 1000 ? true : false));␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not nest ternary expressions.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^ Do not nest ternary expressions.␊ + ` + +## no-nested-ternary - #3 + +> Snapshot 1 + + `␊ + Input:␊ + 1 | const foo = a ?␊ + 2 | b :␊ + 3 | (␊ + 4 | c ?␊ + 5 | d :␊ + 6 | (␊ + 7 | e ?␊ + 8 | f :␊ + 9 | (g ? h : i)␊ + 10 | )␊ + 11 | )␊ + ␊ + Output:␊ + [Same as input]␊ + ␊ + Error 1/1:␊ + 1 | const foo = a ?␊ + 2 | b :␊ + 3 | (␊ + 4 | c ?␊ + 5 | d :␊ + 6 | (␊ + > 7 | e ?␊ + | ^^^␊ + > 8 | f :␊ + | ^^^^^^^^␊ + > 9 | (g ? h : i)␊ + | ^^^^^^^^^^^^^^^^^ Do not nest ternary expressions.␊ + 10 | )␊ + 11 | )␊ ` diff --git a/test/snapshots/no-nested-ternary.js.snap b/test/snapshots/no-nested-ternary.js.snap index 438a2ecc69e722f26714e15e45c4fe3c06577213..b4d43fa14b2dc1eaf1de135a4931ad314e78df58 100644 GIT binary patch literal 475 zcmV<10VMuGRzV3QId(5S^s85mv8{&@EZWV? zz;Gx2%17?^aWj5xu07-xHcg!oESkg$GLIdspOKY8kja#Z%QLT_w8V-_LBUX=Mj<&r zued}ZEk9quRv}ZtPQg^c9!T3L7#bJ=StUiKsR~vKX^A<-AR4=bH5ZqEX$b){HL&Z| z1Tt_*0nK$SD#|ZXFw{4);_NgtKw-`#1+Wrh5L*MpG6AtTlOak>!5q#Mh$1rx53I}_!sbkcD71ibIny9Y zEn$3(bYQq-fD)c2C`Jt+;$Sw&SwI$15km`K*kSlW0m=o2H%J!UQy^(re1PO}coIb& R2@!}rcmSdL8jiLF003Yc!^Z#s literal 234 zcmVoN9%0xA0LYd00000000A1 zU|?WiWcajOU+XxtcCUxv^FyEInD#L;fPg2EVrF0mvl&?#1evTDxjgd~aY!xyU>=aBD>=jCiN>dfA6f`mwY!nO)3@}BIgwhgoic>W;t+}}T zOH07!Mh7S6rYa;BD`bM~iRI#QEh@?{QZUpvwBoX(uAK@%P@{kh;>ZUIF8K<1`6UW@ ksX)h-q!#5R7F8;wRumMa78hp%U986i0Pi`>`)L6H04-lyzW@LL