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 77733b7a1b..6db0ac3cb3 100644 Binary files a/test/snapshots/no-single-promise-in-promise-methods.mjs.snap and b/test/snapshots/no-single-promise-in-promise-methods.mjs.snap differ