From 6be6248356e5c1ff43554e971878c85587e4e75e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Bisson?= Date: Fri, 21 Jun 2024 20:13:44 +0200 Subject: [PATCH] suggest instead of fix when result is stored in array --- rules/no-single-promise-in-promise-methods.js | 21 ++- test/no-single-promise-in-promise-methods.mjs | 12 +- ...o-single-promise-in-promise-methods.mjs.md | 173 +++--------------- ...single-promise-in-promise-methods.mjs.snap | Bin 2610 -> 2448 bytes 4 files changed, 39 insertions(+), 167 deletions(-) diff --git a/rules/no-single-promise-in-promise-methods.js b/rules/no-single-promise-in-promise-methods.js index 2539e15877..3f679a2400 100644 --- a/rules/no-single-promise-in-promise-methods.js +++ b/rules/no-single-promise-in-promise-methods.js @@ -33,12 +33,8 @@ const isPromiseMethodCallWithSingleElementArray = node => && node.arguments[0].elements[0] && node.arguments[0].elements[0].type !== 'SpreadElement'; -const isVariableAssignment = node => ['VariableDeclarator', 'AssignmentExpression'].includes(node.parent.type); - -const isStoredInVariable = node => isVariableAssignment(node) - || (node.parent.type === 'AwaitExpression' && isVariableAssignment(node.parent)); - -const isStoredInArray = node => isMethodCall(node, {methods: ['all']}) && isStoredInVariable(node); +const isStoredInArray = node => isMethodCall(node, {methods: ['all']}) + && ['VariableDeclarator', 'AssignmentExpression'].includes(node.parent.parent.type); const unwrapAwaitedCallExpression = (callExpression, sourceCode) => fixer => { const [promiseNode] = callExpression.arguments[0].elements; @@ -122,8 +118,7 @@ const switchToPromiseResolve = (callExpression, sourceCode) => function * (fixer /** @param {import('eslint').Rule.RuleContext} context */ const create = context => ({ CallExpression(callExpression) { - if (!isPromiseMethodCallWithSingleElementArray(callExpression) - || isStoredInArray(callExpression)) { + if (!isPromiseMethodCallWithSingleElementArray(callExpression)) { return; } @@ -141,7 +136,15 @@ const create = context => ({ callExpression.parent.type === 'AwaitExpression' && callExpression.parent.argument === callExpression ) { - problem.fix = unwrapAwaitedCallExpression(callExpression, sourceCode); + if (isStoredInArray(callExpression)) { + problem.suggest = [{ + messageId: MESSAGE_ID_SUGGESTION_UNWRAP, + fix: unwrapAwaitedCallExpression(callExpression, sourceCode), + }]; + } else { + problem.fix = unwrapAwaitedCallExpression(callExpression, sourceCode); + } + return problem; } diff --git a/test/no-single-promise-in-promise-methods.mjs b/test/no-single-promise-in-promise-methods.mjs index d6034db687..bd11df9c4f 100644 --- a/test/no-single-promise-in-promise-methods.mjs +++ b/test/no-single-promise-in-promise-methods.mjs @@ -6,8 +6,6 @@ const {test} = getTester(import.meta); // `await`ed test.snapshot({ valid: [ - 'const results = await Promise.all([promise])', - 'results = await Promise.all([promise])', ], invalid: [ 'await Promise.all([(0, promise)])', @@ -41,10 +39,10 @@ test.snapshot({ 'await Promise.race([promise])', 'await Promise.all([new Promise(() => {})])', '+await Promise.all([+1])', + 'const results = await Promise.all([promise])', + 'results = await Promise.all([promise])', 'const results = await Promise.any([promise])', - 'results = await Promise.any([promise])', 'const results = await Promise.race([promise])', - 'results = await Promise.race([promise])', // ASI, `Promise.all()` is not really `await`ed outdent` @@ -72,8 +70,6 @@ test.snapshot({ 'Promise.all([promise], extraArguments)', 'Promise.all()', 'new Promise.all([promise])', - 'const results = Promise.all([promise])', - 'results = Promise.all([promise])', // We are not checking these cases 'globalThis.Promise.all([promise])', @@ -108,9 +104,5 @@ test.snapshot({ 'Promise.all([promise])[0] ||= 1', 'Promise.all([undefined]).then()', 'Promise.all([null]).then()', - 'const results = Promise.any([promise])', - 'results = Promise.any([promise])', - 'const results = Promise.race([promise])', - 'results = Promise.race([promise])', ], }); diff --git a/test/snapshots/no-single-promise-in-promise-methods.mjs.md b/test/snapshots/no-single-promise-in-promise-methods.mjs.md index f841bc9317..c44d525b69 100644 --- a/test/snapshots/no-single-promise-in-promise-methods.mjs.md +++ b/test/snapshots/no-single-promise-in-promise-methods.mjs.md @@ -655,54 +655,50 @@ Generated by [AVA](https://avajs.dev). | ^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(32): const results = await Promise.any([promise]) +## invalid(32): const results = await Promise.all([promise]) > Input `␊ - 1 | const results = await Promise.any([promise])␊ - ` - -> Output - - `␊ - 1 | const results = await promise␊ + 1 | const results = await Promise.all([promise])␊ ` > Error 1/1 `␊ - > 1 | const results = await Promise.any([promise])␊ - | ^^^^^^^^^ Wrapping single-element array with \`Promise.any()\` is unnecessary.␊ + > 1 | const results = await Promise.all([promise])␊ + | ^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Use the value directly.␊ + 1 | const results = await promise␊ ` -## invalid(33): results = await Promise.any([promise]) +## invalid(33): results = await Promise.all([promise]) > Input `␊ - 1 | results = await Promise.any([promise])␊ - ` - -> Output - - `␊ - 1 | results = await promise␊ + 1 | results = await Promise.all([promise])␊ ` > Error 1/1 `␊ - > 1 | results = await Promise.any([promise])␊ - | ^^^^^^^^^ Wrapping single-element array with \`Promise.any()\` is unnecessary.␊ + > 1 | results = await Promise.all([promise])␊ + | ^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/1: Use the value directly.␊ + 1 | results = await promise␊ ` -## invalid(34): const results = await Promise.race([promise]) +## invalid(34): const results = await Promise.any([promise]) > Input `␊ - 1 | const results = await Promise.race([promise])␊ + 1 | const results = await Promise.any([promise])␊ ` > Output @@ -714,29 +710,29 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `␊ - > 1 | const results = await Promise.race([promise])␊ - | ^^^^^^^^^ Wrapping single-element array with \`Promise.race()\` is unnecessary.␊ + > 1 | const results = await Promise.any([promise])␊ + | ^^^^^^^^^ Wrapping single-element array with \`Promise.any()\` is unnecessary.␊ ` -## invalid(35): results = await Promise.race([promise]) +## invalid(35): const results = await Promise.race([promise]) > Input `␊ - 1 | results = await Promise.race([promise])␊ + 1 | const results = await Promise.race([promise])␊ ` > Output `␊ - 1 | results = await promise␊ + 1 | const results = await promise␊ ` > Error 1/1 `␊ - > 1 | results = await Promise.race([promise])␊ - | ^^^^^^^^^ Wrapping single-element array with \`Promise.race()\` is unnecessary.␊ + > 1 | const results = await Promise.race([promise])␊ + | ^^^^^^^^^ Wrapping single-element array with \`Promise.race()\` is unnecessary.␊ ` ## invalid(36): await Promise.all([(x,y)]) [0].toString() @@ -1210,122 +1206,3 @@ Generated by [AVA](https://avajs.dev). Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ 1 | Promise.resolve(null).then()␊ ` - -## invalid(20): const results = Promise.any([promise]) - -> Input - - `␊ - 1 | const results = Promise.any([promise])␊ - ` - -> Error 1/1 - - `␊ - > 1 | const results = Promise.any([promise])␊ - | ^^^^^^^^^ Wrapping single-element array with \`Promise.any()\` is unnecessary.␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 1/2: Use the value directly.␊ - 1 | const results = promise␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ - 1 | const results = Promise.resolve(promise)␊ - ` - -## invalid(21): results = Promise.any([promise]) - -> Input - - `␊ - 1 | results = Promise.any([promise])␊ - ` - -> Error 1/1 - - `␊ - > 1 | results = Promise.any([promise])␊ - | ^^^^^^^^^ Wrapping single-element array with \`Promise.any()\` is unnecessary.␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 1/2: Use the value directly.␊ - 1 | results = promise␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ - 1 | results = Promise.resolve(promise)␊ - ` - -## invalid(22): const results = Promise.race([promise]) - -> Input - - `␊ - 1 | const results = Promise.race([promise])␊ - ` - -> Error 1/1 - - `␊ - > 1 | const results = Promise.race([promise])␊ - | ^^^^^^^^^ Wrapping single-element array with \`Promise.race()\` is unnecessary.␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 1/2: Use the value directly.␊ - 1 | const results = promise␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ - 1 | const results = Promise.resolve(promise)␊ - ` - -## invalid(23): results = Promise.race([promise]) - -> Input - - `␊ - 1 | results = Promise.race([promise])␊ - ` - -> Error 1/1 - - `␊ - > 1 | results = Promise.race([promise])␊ - | ^^^^^^^^^ Wrapping single-element array with \`Promise.race()\` is unnecessary.␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 1/2: Use the value directly.␊ - 1 | results = promise␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ - 1 | results = Promise.resolve(promise)␊ - ` - -## invalid(32): await Promise.all([(x,y)]) [0].toString() - -> Input - - `␊ - 1 | await Promise.all([(x,y)])␊ - 2 | [0].toString()␊ - ` - -> Error 1/1 - - `␊ - > 1 | await Promise.all([(x,y)])␊ - | ^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ - 2 | [0].toString()␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 1/2: Use the value directly.␊ - 1 | await (x,y)␊ - 2 | [0].toString()␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ - 1 | await Promise.resolve((x,y))␊ - 2 | [0].toString()␊ - ` diff --git a/test/snapshots/no-single-promise-in-promise-methods.mjs.snap b/test/snapshots/no-single-promise-in-promise-methods.mjs.snap index 77733b7a1bd7770d8fff1e0879d8357924474c7c..6db0ac3cb3660ee2d262c97c546bb8f3b2416104 100644 GIT binary patch literal 2448 zcmV;B32*j6RzV*Bbv!fW>5V?*85Iw zXKIp3zmo-OVCX0YajdE z$9SBnGwtk}#{b;=|6h*p@wNTN@)66aJ?fsEIc0dJXBq3GrhQbm%q2xD%o6>WZhGXN zy7QRn8mewt%AztpLe@5aP^c74*VfnERmXFmI<>T0)13`;*^SjJuUTEp|D6d-jikcuAdAG>^a!wU~S6+L*z3j;&*k^>=xkPVXjRKbTl zSl8FqOnZg6roCbrqlRTXX4oFl>vg?Jj+x#nIUN0(!eL^%q+#1e&2U}4-cRHQaF(e=U(9G{=m`n zUxCGT0DQ@`)R!ngnCikve+H3$K_l&A_^hy5pK9+YxHF(&A_WCSE(Z63gbt*{peW$r zcJM7T9dJ+-fba_d;j6SD6f-1YOHmjPP?%)Y{UfzmZF z2zoRg!s{S}=Q$z3VaNoqmF5=%^QUq1*U7@d9BJa#PXfb++15u?Fyr?CovWeo{;|02 zuL0Yile)E}l4hed5#@4eC1CU^!j}PVMGW&h~p3P`NU} zILqx=377P`H%>D;&vjDG!0Bpgr>j{wUCou#%rFGHu9UFBE?PLHK_dMpd4$8z8_E!$;gFIg;RP__e+6lJ@0X!m8C4j?CG zo6$yccQ~cXwqS3Q2e*G{mqoj?-OQeBESDMW|5ggP?fZaTCARHxsZQ_si5`yz za2f>gGADqDKL6bU;%djn{)~>B`k#k(7Fz2i3`$OAcvQD`}?t>`Zyv}-rht#XphX;wu|K!uWqTK_z-{)xbP=GSun8n)8bebm-gA6s*5 z*CTbqZCIX5<~YlRsMSyUlfDfYHR&7Gi6&zI!-Ee1FAom-UUsC*^f#MYk9$5en(=4o zP-A7qaN9T5YGc|gx!*O2w`!21y45hql36!up4C*j&cjNcBw~UR(dxI;vTzGvAsA5? z6o4DrcT5EoWR`zlCEsc0VHKDZR{_DoFI5!~E(GxHHzkZtxRBfrT%MB3PGVu1Rd^qR@ZOgTPkP~*O?;g$M5k$fj7tv6`be`-DUikS zit0Isyt-+xC`iR+Jn6v{93rGlHe#|^>D_S|u>Idb&VvF}n!9eyqQs)3-{QJk7S-M0 zittF2Vegg>u-qEpp<||3TP2!_jp`S{y~!z$h#`oGd1Iv0&3!MmdmD~c}_ zKgnH~cW{yT;lWrv2*B*%I&ZeU%lXDHsGa$tEdHNC8f=>Aqpz)gWZ7}pkBQ<~%>k^& z{BbNhjt@0g4yEjGK-uqu5y^Q8Ngi~4Ltg0b&ETQn{E(O=fY!WdVr($!#@GY~=3+an zN@8Ci!188*JOOI?NFFhab;4Yk9adXISy9%y(VHM6tF)4U_YRM z;cB8bvoD~F%sl__MMo>da4P!P`{o7hN5~x6+>8hD6P+xy-UNd8nG1kM4P0uM5JaK; z4?y`3+<=u4WnB(NS?vc<9=pNgR{>yees~!5Gvr!5istWrMoU0Kl}zhjsyzcmjJx8ICxOz0=TrR z1T)SxW??KcRc;~ySnHO|I~=E-Dzo>Hsd9)A3fr#$wy$y6FtH2Ztm;pD8#EnZLc*4V zK6j)gHW6Yu`}Y7O`NN+(l8{0P{0$KJoeY72+y%v8FzIbVA&i`Nnw{F*Syk{YBSx<`O#@4SUI0Hf>{xvyCCaTv7&Q?kB+9=O}ZC6n6>N z57f~)=f8`fLlrg=;WglWaq8@bWpRL$xCRUqP}V*JtbKs8231&?^#fr_YpUCzNd?1< Oll4CeC@207X8-^ytD_bG literal 2610 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