From 38306bc90c75d26e7c7ba214c8d029653499ebda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Bisson?= Date: Tue, 16 Jan 2024 14:22:02 +0100 Subject: [PATCH 01/34] Add `no-single-promise-in-promise-methods` rule --- configs/recommended.js | 1 + .../no-single-promise-in-promise-methods.md | 34 +++++++ readme.md | 1 + rules/no-single-promise-in-promise-methods.js | 95 +++++++++++++++++++ rules/utils/is-promise-method-with-array.js | 13 +++ test/no-single-promise-in-promise-methods.mjs | 72 ++++++++++++++ 6 files changed, 216 insertions(+) create mode 100644 docs/rules/no-single-promise-in-promise-methods.md create mode 100644 rules/no-single-promise-in-promise-methods.js create mode 100644 rules/utils/is-promise-method-with-array.js create mode 100644 test/no-single-promise-in-promise-methods.mjs diff --git a/configs/recommended.js b/configs/recommended.js index b4f4e8f9d6..2da3c5e960 100644 --- a/configs/recommended.js +++ b/configs/recommended.js @@ -40,6 +40,7 @@ module.exports = { 'unicorn/no-null': 'error', 'unicorn/no-object-as-default-parameter': 'error', 'unicorn/no-process-exit': 'error', + 'unicorn/no-single-promise-in-promise-methods': 'error', 'unicorn/no-static-only-class': 'error', 'unicorn/no-thenable': 'error', 'unicorn/no-this-assignment': 'error', diff --git a/docs/rules/no-single-promise-in-promise-methods.md b/docs/rules/no-single-promise-in-promise-methods.md new file mode 100644 index 0000000000..c945320c46 --- /dev/null +++ b/docs/rules/no-single-promise-in-promise-methods.md @@ -0,0 +1,34 @@ +# Disallow using `Promise` method with a single element array as parameter + +πŸ’Ό This rule is enabled in the βœ… `recommended` [config](https://github.com/sindresorhus/eslint-plugin-unicorn#preset-configs). + +πŸ”§πŸ’‘ This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) and manually fixable by [editor suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions). + + + + +Single element array parameter in a Promise.all(), Promise.any() or Promise.race() method is probably a mistake. + +## Fail + +```js +Promise.all([promise]) + +Promise.any([promise]) + +Promise.race([promise]) +``` + +## Pass + +```js +Promise.all([promise, anotherPromise]) +Promise.all(notArrayLiteral) +Promise.all([...promises]) + +Promise.any([promise, anotherPromise]) + +Promise.race([promise, anotherPromise]) + +Promise.allSettled([promise]) +``` diff --git a/readme.md b/readme.md index e8194a8097..425de4e129 100644 --- a/readme.md +++ b/readme.md @@ -148,6 +148,7 @@ If you don't use the preset, ensure you use the same `env` and `parserOptions` c | [no-null](docs/rules/no-null.md) | Disallow the use of the `null` literal. | βœ… | πŸ”§ | πŸ’‘ | | [no-object-as-default-parameter](docs/rules/no-object-as-default-parameter.md) | Disallow the use of objects as default parameters. | βœ… | | | | [no-process-exit](docs/rules/no-process-exit.md) | Disallow `process.exit()`. | βœ… | | | +| [no-single-promise-in-promise-methods](docs/rules/no-single-promise-in-promise-methods.md) | Disallow using `Promise` method with a single element array as parameter. | βœ… | πŸ”§ | πŸ’‘ | | [no-static-only-class](docs/rules/no-static-only-class.md) | Disallow classes that only have static members. | βœ… | πŸ”§ | | | [no-thenable](docs/rules/no-thenable.md) | Disallow `then` property. | βœ… | | | | [no-this-assignment](docs/rules/no-this-assignment.md) | Disallow assigning `this` to a variable. | βœ… | | | diff --git a/rules/no-single-promise-in-promise-methods.js b/rules/no-single-promise-in-promise-methods.js new file mode 100644 index 0000000000..28538e7091 --- /dev/null +++ b/rules/no-single-promise-in-promise-methods.js @@ -0,0 +1,95 @@ +'use strict'; +const isPromiseMethodWithArray = require('./utils/is-promise-method-with-array.js'); + +const MESSAGE_ID_ERROR = 'no-single-promise-in-promise-methods/error'; +const MESSAGE_ID_SUGGESTION_1 = 'no-single-promise-in-promise-methods/suggestion-1'; +const MESSAGE_ID_SUGGESTION_2 = 'no-single-promise-in-promise-methods/suggestion-2'; +const messages = { + [MESSAGE_ID_ERROR]: 'Parameter in `Promise.{{method}}` should not be a single element array.', + [MESSAGE_ID_SUGGESTION_1]: 'Use the value directly.', + [MESSAGE_ID_SUGGESTION_2]: 'Wrap the value in a `Promise.resolve`.', +}; +const METHODS = ['all', 'any', 'race']; + +const isPromiseMethodWithSinglePromise = (node, methods) => { + const types = new Set(['CallExpression', 'Identifier', 'MemberExpression']); + + if (!isPromiseMethodWithArray(node, methods) || node.arguments[0].elements.length !== 1) { + return false; + } + + const [element] = node.arguments[0].elements; + + return types.has(element.type) + || (element.type === 'AwaitExpression' && types.has(element.argument.type)); +}; + +const getMethodName = node => node.callee.property.name; + +const getAutoFixer = ({sourceCode}, node) => fixer => { + const [element] = node.arguments[0].elements; + const elementWithoutAwait = element.type === 'AwaitExpression' ? element.argument : element; + + return fixer.replaceText(node, sourceCode.getText(elementWithoutAwait)); +}; + +const getSuggestion1Fixer = ({sourceCode}, node) => fixer => + fixer.replaceText(node, sourceCode.getText(node.arguments[0].elements[0])); + +const getSuggestion2Fixer = ({sourceCode}, node) => fixer => { + const text = sourceCode.getText(node.arguments[0].elements[0]); + + return fixer.replaceText(node, `Promise.resolve(${text})`); +}; + +/** @param {import('eslint').Rule.RuleContext} context */ +const create = context => ({ + CallExpression(node) { + if (!isPromiseMethodWithSinglePromise(node, METHODS)) { + return; + } + + const descriptor = { + node, + messageId: MESSAGE_ID_ERROR, + data: { + method: getMethodName(node), + }, + }; + + if (node.parent.type === 'AwaitExpression') { + context.report({ + ...descriptor, + fix: getAutoFixer(context, node), + }); + } else { + context.report({ + ...descriptor, + suggest: [ + { + messageId: MESSAGE_ID_SUGGESTION_1, + fix: getSuggestion1Fixer(context, node), + }, + { + messageId: MESSAGE_ID_SUGGESTION_2, + fix: getSuggestion2Fixer(context, node), + }, + ], + }); + } + }, +}); + +/** @type {import('eslint').Rule.RuleModule} */ +module.exports = { + create, + meta: { + type: 'suggestion', + docs: { + description: 'Disallow using `Promise` method with a single element array as parameter.', + }, + fixable: 'code', + hasSuggestions: true, + messages, + }, +}; diff --git a/rules/utils/is-promise-method-with-array.js b/rules/utils/is-promise-method-with-array.js new file mode 100644 index 0000000000..845f5b7bd1 --- /dev/null +++ b/rules/utils/is-promise-method-with-array.js @@ -0,0 +1,13 @@ +'use strict'; +const {isMethodCall} = require('../ast/index.js'); + +const isPromiseMethodWithArray = (node, methods) => + node.callee.type === 'MemberExpression' + && node.callee.object.type === 'Identifier' + && node.callee.object.name === 'Promise' + && isMethodCall(node, methods) + && node.arguments.length === 1 + && node.arguments[0].type === 'ArrayExpression' + && node.arguments[0].elements.some(element => element !== null); + +module.exports = isPromiseMethodWithArray; diff --git a/test/no-single-promise-in-promise-methods.mjs b/test/no-single-promise-in-promise-methods.mjs new file mode 100644 index 0000000000..27137bc65d --- /dev/null +++ b/test/no-single-promise-in-promise-methods.mjs @@ -0,0 +1,72 @@ +import {getTester} from './utils/test.mjs'; + +const {test} = getTester(import.meta); + +const error = { + messageId: 'no-single-promise-in-promise-methods/error', +}; + +test({ + valid: [ + 'Promise.all([promise, anotherPromise])', + 'Promise.all(notArrayLiteral)', + 'Promise.all([...promises])', + 'Promise.all([await -1])', + 'Promise.any([promise, anotherPromise])', + 'Promise.race([promise, anotherPromise])', + 'Promise.allSettled([promise])', + 'Promise[all]([promise])', + 'Promise.all([,])', + ], + + invalid: [ + { + code: 'await Promise.all([promise])', + errors: [error], + output: 'await promise', + }, + { + code: 'await Promise.all([func()])', + errors: [error], + output: 'await func()', + }, + { + code: 'await Promise.all([promises[0]])', + errors: [error], + output: 'await promises[0]', + }, + { + code: 'await Promise.all([await promise])', + errors: [error], + output: 'await promise', + }, + { + code: 'await Promise.any([promise])', + errors: [error], + output: 'await promise', + }, + { + code: 'await Promise.race([promise])', + errors: [error], + output: 'await promise', + }, + { + code: 'Promise.all([somethingMaybeNotPromise])', + errors: [ + { + ...error, + suggestions: [ + { + messageId: 'no-single-promise-in-promise-methods/suggestion-1', + output: 'somethingMaybeNotPromise', + }, + { + messageId: 'no-single-promise-in-promise-methods/suggestion-2', + output: 'Promise.resolve(somethingMaybeNotPromise)', + }, + ], + }, + ], + }, + ], +}); From a728a1a3b848e152ee80d175b772106a62a26c58 Mon Sep 17 00:00:00 2001 From: fisker Date: Sun, 28 Jan 2024 04:33:07 +0800 Subject: [PATCH 02/34] Use snapshot test --- test/no-single-promise-in-promise-methods.mjs | 58 +------ ...o-single-promise-in-promise-methods.mjs.md | 154 ++++++++++++++++++ ...single-promise-in-promise-methods.mjs.snap | Bin 0 -> 613 bytes 3 files changed, 162 insertions(+), 50 deletions(-) create mode 100644 test/snapshots/no-single-promise-in-promise-methods.mjs.md create mode 100644 test/snapshots/no-single-promise-in-promise-methods.mjs.snap diff --git a/test/no-single-promise-in-promise-methods.mjs b/test/no-single-promise-in-promise-methods.mjs index 27137bc65d..3d189de2ec 100644 --- a/test/no-single-promise-in-promise-methods.mjs +++ b/test/no-single-promise-in-promise-methods.mjs @@ -6,7 +6,7 @@ const error = { messageId: 'no-single-promise-in-promise-methods/error', }; -test({ +test.snapshot({ valid: [ 'Promise.all([promise, anotherPromise])', 'Promise.all(notArrayLiteral)', @@ -18,55 +18,13 @@ test({ 'Promise[all]([promise])', 'Promise.all([,])', ], - invalid: [ - { - code: 'await Promise.all([promise])', - errors: [error], - output: 'await promise', - }, - { - code: 'await Promise.all([func()])', - errors: [error], - output: 'await func()', - }, - { - code: 'await Promise.all([promises[0]])', - errors: [error], - output: 'await promises[0]', - }, - { - code: 'await Promise.all([await promise])', - errors: [error], - output: 'await promise', - }, - { - code: 'await Promise.any([promise])', - errors: [error], - output: 'await promise', - }, - { - code: 'await Promise.race([promise])', - errors: [error], - output: 'await promise', - }, - { - code: 'Promise.all([somethingMaybeNotPromise])', - errors: [ - { - ...error, - suggestions: [ - { - messageId: 'no-single-promise-in-promise-methods/suggestion-1', - output: 'somethingMaybeNotPromise', - }, - { - messageId: 'no-single-promise-in-promise-methods/suggestion-2', - output: 'Promise.resolve(somethingMaybeNotPromise)', - }, - ], - }, - ], - }, + 'await Promise.all([promise])', + 'await Promise.all([func()])', + 'await Promise.all([promises[0]])', + 'await Promise.all([await promise])', + 'await Promise.any([promise])', + 'await Promise.race([promise])', + 'Promise.all([somethingMaybeNotPromise])', ], }); diff --git a/test/snapshots/no-single-promise-in-promise-methods.mjs.md b/test/snapshots/no-single-promise-in-promise-methods.mjs.md new file mode 100644 index 0000000000..5a5022f94b --- /dev/null +++ b/test/snapshots/no-single-promise-in-promise-methods.mjs.md @@ -0,0 +1,154 @@ +# Snapshot report for `test/no-single-promise-in-promise-methods.mjs` + +The actual snapshot is saved in `no-single-promise-in-promise-methods.mjs.snap`. + +Generated by [AVA](https://avajs.dev). + +## invalid(1): await Promise.all([promise]) + +> Input + + `␊ + 1 | await Promise.all([promise])␊ + ` + +> Output + + `␊ + 1 | await promise␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.all([promise])␊ + | ^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all\` should not be a single element array.␊ + ` + +## invalid(2): await Promise.all([func()]) + +> Input + + `␊ + 1 | await Promise.all([func()])␊ + ` + +> Output + + `␊ + 1 | await func()␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.all([func()])␊ + | ^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all\` should not be a single element array.␊ + ` + +## invalid(3): await Promise.all([promises[0]]) + +> Input + + `␊ + 1 | await Promise.all([promises[0]])␊ + ` + +> Output + + `␊ + 1 | await promises[0]␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.all([promises[0]])␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all\` should not be a single element array.␊ + ` + +## invalid(4): await Promise.all([await promise]) + +> Input + + `␊ + 1 | await Promise.all([await promise])␊ + ` + +> Output + + `␊ + 1 | await promise␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.all([await promise])␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all\` should not be a single element array.␊ + ` + +## invalid(5): await Promise.any([promise]) + +> Input + + `␊ + 1 | await Promise.any([promise])␊ + ` + +> Output + + `␊ + 1 | await promise␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.any([promise])␊ + | ^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.any\` should not be a single element array.␊ + ` + +## invalid(6): await Promise.race([promise]) + +> Input + + `␊ + 1 | await Promise.race([promise])␊ + ` + +> Output + + `␊ + 1 | await promise␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.race([promise])␊ + | ^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.race\` should not be a single element array.␊ + ` + +## invalid(7): Promise.all([somethingMaybeNotPromise]) + +> Input + + `␊ + 1 | Promise.all([somethingMaybeNotPromise])␊ + ` + +> Error 1/1 + + `␊ + > 1 | Promise.all([somethingMaybeNotPromise])␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all\` should not be a single element array.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Use the value directly.␊ + 1 | somethingMaybeNotPromise␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Wrap the value in a \`Promise.resolve\`.␊ + 1 | Promise.resolve(somethingMaybeNotPromise)␊ + ` diff --git a/test/snapshots/no-single-promise-in-promise-methods.mjs.snap b/test/snapshots/no-single-promise-in-promise-methods.mjs.snap new file mode 100644 index 0000000000000000000000000000000000000000..0e2e76d30e8c81ad83ecb352bec60372bd90db92 GIT binary patch literal 613 zcmV-r0-F6nRzV zzivn|O&^O000000000BM)Ip2WKoke?RuQ2$K@Z*@uCj?}YFgcug5ErMPzxd|%Sxxs zYdbidDKnF5U{4Avc=4bJUc~ha`VEwl$=XRLNwKYSOX2d{ zF&}uo%Q>`!c8Z;|2p97uE9ATtlGZtuzgWueN|aA7uSDLS@wLpjT{_I_;Krc~de1WQ zDhE2vacS>bNf%v1Juh~Wf49g#RS&jlqk6cviyvh8H{JNw+q?L0TWD8{`EyB|+$ujU z{Ldx$`6gE5-{uE6S>?BuKLAhGU*%TD|6k?y_5Z%gd9p6FpF!^}K}#~gQt7s3bj2y1 z3)v*~H;ekCn>v603Zq?sJx^L!yPaw8`yKl)sKf;InDWsBlJxPR(A{PCH|E9fSYS;9 zwql&)3p}s?wkUtq4dtqlDQelK*yz$|T;K3%JdQ^rRGJD7VYAhNCkjE25oUzN2oaSy z&@2gzbdkh%8*9xQdn(Cvp)<;XEKDdW!DiSCauZ>G_lo-Vm*({ku5XfATMGaHK^G{r literal 0 HcmV?d00001 From 7030d7fd7969f4f51033587b77b7a00f8e3c3a4e Mon Sep 17 00:00:00 2001 From: fisker Date: Sun, 28 Jan 2024 04:36:32 +0800 Subject: [PATCH 03/34] More tests --- test/no-single-promise-in-promise-methods.mjs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/no-single-promise-in-promise-methods.mjs b/test/no-single-promise-in-promise-methods.mjs index 3d189de2ec..4116af8bd8 100644 --- a/test/no-single-promise-in-promise-methods.mjs +++ b/test/no-single-promise-in-promise-methods.mjs @@ -17,6 +17,9 @@ test.snapshot({ 'Promise.allSettled([promise])', 'Promise[all]([promise])', 'Promise.all([,])', + 'NotPromise.all([promise])', + 'Promise?.all([promise])', + 'Promise.all?.([promise])', ], invalid: [ 'await Promise.all([promise])', From 1f24588cdb8e72573a3666d1c9dbeca1bb5625cc Mon Sep 17 00:00:00 2001 From: fisker Date: Sun, 28 Jan 2024 04:40:55 +0800 Subject: [PATCH 04/34] Refactor --- rules/no-single-promise-in-promise-methods.js | 39 ++++++++----------- test/no-single-promise-in-promise-methods.mjs | 2 + 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/rules/no-single-promise-in-promise-methods.js b/rules/no-single-promise-in-promise-methods.js index 28538e7091..de24f11f42 100644 --- a/rules/no-single-promise-in-promise-methods.js +++ b/rules/no-single-promise-in-promise-methods.js @@ -24,8 +24,6 @@ const isPromiseMethodWithSinglePromise = (node, methods) => { || (element.type === 'AwaitExpression' && types.has(element.argument.type)); }; -const getMethodName = node => node.callee.property.name; - const getAutoFixer = ({sourceCode}, node) => fixer => { const [element] = node.arguments[0].elements; const elementWithoutAwait = element.type === 'AwaitExpression' ? element.argument : element; @@ -49,34 +47,31 @@ const create = context => ({ return; } - const descriptor = { + const problem = { node, messageId: MESSAGE_ID_ERROR, data: { - method: getMethodName(node), + method: node.callee.property.name, }, }; if (node.parent.type === 'AwaitExpression') { - context.report({ - ...descriptor, - fix: getAutoFixer(context, node), - }); - } else { - context.report({ - ...descriptor, - suggest: [ - { - messageId: MESSAGE_ID_SUGGESTION_1, - fix: getSuggestion1Fixer(context, node), - }, - { - messageId: MESSAGE_ID_SUGGESTION_2, - fix: getSuggestion2Fixer(context, node), - }, - ], - }); + problem.fix = getAutoFixer(context, node); + return problem; } + + problem.suggest = [ + { + messageId: MESSAGE_ID_SUGGESTION_1, + fix: getSuggestion1Fixer(context, node), + }, + { + messageId: MESSAGE_ID_SUGGESTION_2, + fix: getSuggestion2Fixer(context, node), + }, + ]; + + return problem; }, }); diff --git a/test/no-single-promise-in-promise-methods.mjs b/test/no-single-promise-in-promise-methods.mjs index 4116af8bd8..70f1b87550 100644 --- a/test/no-single-promise-in-promise-methods.mjs +++ b/test/no-single-promise-in-promise-methods.mjs @@ -29,5 +29,7 @@ test.snapshot({ 'await Promise.any([promise])', 'await Promise.race([promise])', 'Promise.all([somethingMaybeNotPromise])', + 'await Promise.all([new Promise(() => {})])', + 'await Promise.all([(0, promise)])', ], }); From 92454c7694c512a2c0b90917dcdd943e2e01defb Mon Sep 17 00:00:00 2001 From: fisker Date: Sun, 28 Jan 2024 04:44:58 +0800 Subject: [PATCH 05/34] More tests --- test/no-single-promise-in-promise-methods.mjs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/test/no-single-promise-in-promise-methods.mjs b/test/no-single-promise-in-promise-methods.mjs index 70f1b87550..8b64789c6e 100644 --- a/test/no-single-promise-in-promise-methods.mjs +++ b/test/no-single-promise-in-promise-methods.mjs @@ -1,3 +1,4 @@ +import outdent from 'outdent'; import {getTester} from './utils/test.mjs'; const {test} = getTester(import.meta); @@ -30,6 +31,22 @@ test.snapshot({ 'await Promise.race([promise])', 'Promise.all([somethingMaybeNotPromise])', 'await Promise.all([new Promise(() => {})])', - 'await Promise.all([(0, promise)])', + '+await Promise.all([+1])', + outdent` + foo + await Promise.all([(0, promise)]) + `, + outdent` + foo + Promise.all([(0, promise)]) + `, + outdent` + foo + await Promise.all([[array][0]]) + `, + outdent` + foo + Promise.all([[array][0]]) + `, ], }); From a2647ae74eb60b107522955d27e5cfa4ada64261 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Bisson?= Date: Sun, 28 Jan 2024 23:44:32 +0100 Subject: [PATCH 06/34] Not limit types --- .../no-single-promise-in-promise-methods.md | 18 +-- rules/no-single-promise-in-promise-methods.js | 58 +++---- rules/utils/is-promise-method-with-array.js | 13 -- test/no-single-promise-in-promise-methods.mjs | 5 - ...o-single-promise-in-promise-methods.mjs.md | 144 ++++++++++++++++++ ...single-promise-in-promise-methods.mjs.snap | Bin 613 -> 939 bytes 6 files changed, 185 insertions(+), 53 deletions(-) delete mode 100644 rules/utils/is-promise-method-with-array.js diff --git a/docs/rules/no-single-promise-in-promise-methods.md b/docs/rules/no-single-promise-in-promise-methods.md index c945320c46..aae6753f5c 100644 --- a/docs/rules/no-single-promise-in-promise-methods.md +++ b/docs/rules/no-single-promise-in-promise-methods.md @@ -12,23 +12,23 @@ Single element array parameter in a Promise.all(), Promise.any() or Promise.race ## Fail ```js -Promise.all([promise]) +Promise.all([promise]); -Promise.any([promise]) +Promise.any([promise]); -Promise.race([promise]) +Promise.race([promise]); ``` ## Pass ```js -Promise.all([promise, anotherPromise]) -Promise.all(notArrayLiteral) -Promise.all([...promises]) +Promise.all([promise, anotherPromise]); +Promise.all(notArrayLiteral); +Promise.all([...promises]); -Promise.any([promise, anotherPromise]) +Promise.any([promise, anotherPromise]); -Promise.race([promise, anotherPromise]) +Promise.race([promise, anotherPromise]); -Promise.allSettled([promise]) +Promise.allSettled([promise]); ``` diff --git a/rules/no-single-promise-in-promise-methods.js b/rules/no-single-promise-in-promise-methods.js index de24f11f42..cfbd47ef21 100644 --- a/rules/no-single-promise-in-promise-methods.js +++ b/rules/no-single-promise-in-promise-methods.js @@ -1,5 +1,5 @@ 'use strict'; -const isPromiseMethodWithArray = require('./utils/is-promise-method-with-array.js'); +const {isMethodCall} = require('./ast/index.js'); const MESSAGE_ID_ERROR = 'no-single-promise-in-promise-methods/error'; const MESSAGE_ID_SUGGESTION_1 = 'no-single-promise-in-promise-methods/suggestion-1'; @@ -11,63 +11,69 @@ const messages = { }; const METHODS = ['all', 'any', 'race']; -const isPromiseMethodWithSinglePromise = (node, methods) => { - const types = new Set(['CallExpression', 'Identifier', 'MemberExpression']); - - if (!isPromiseMethodWithArray(node, methods) || node.arguments[0].elements.length !== 1) { - return false; - } - - const [element] = node.arguments[0].elements; - - return types.has(element.type) - || (element.type === 'AwaitExpression' && types.has(element.argument.type)); +const isPromiseMethodCallWithSingleElementArray = node => + isMethodCall(node, { + object: 'Promise', + methods: METHODS, + optionalMember: false, + optionalCall: false, + argumentsLength: 1, + }) + && node.arguments[0].type === 'ArrayExpression' + && node.arguments[0].elements.length === 1 + && node.arguments[0].elements[0] !== null + && node.arguments[0].elements[0].type !== 'SpreadElement'; + +const getText = ({sourceCode}, element) => { + const text = sourceCode.getText(element); + + return element.type === 'SequenceExpression' ? `(${text})` : text; }; -const getAutoFixer = ({sourceCode}, node) => fixer => { +const getAutoFixer = (context, node) => fixer => { const [element] = node.arguments[0].elements; const elementWithoutAwait = element.type === 'AwaitExpression' ? element.argument : element; - return fixer.replaceText(node, sourceCode.getText(elementWithoutAwait)); + return fixer.replaceText(node, getText(context, elementWithoutAwait)); }; -const getSuggestion1Fixer = ({sourceCode}, node) => fixer => - fixer.replaceText(node, sourceCode.getText(node.arguments[0].elements[0])); +const getSuggestion1Fixer = (context, node) => fixer => + fixer.replaceText(node, getText(context, node.arguments[0].elements[0])); -const getSuggestion2Fixer = ({sourceCode}, node) => fixer => { - const text = sourceCode.getText(node.arguments[0].elements[0]); +const getSuggestion2Fixer = (context, node) => fixer => { + const text = getText(context, node.arguments[0].elements[0]); return fixer.replaceText(node, `Promise.resolve(${text})`); }; /** @param {import('eslint').Rule.RuleContext} context */ const create = context => ({ - CallExpression(node) { - if (!isPromiseMethodWithSinglePromise(node, METHODS)) { + CallExpression(callExpression) { + if (!isPromiseMethodCallWithSingleElementArray(callExpression)) { return; } const problem = { - node, + node: callExpression, messageId: MESSAGE_ID_ERROR, data: { - method: node.callee.property.name, + method: callExpression.callee.property.name, }, }; - if (node.parent.type === 'AwaitExpression') { - problem.fix = getAutoFixer(context, node); + if (callExpression.parent.type === 'AwaitExpression') { + problem.fix = getAutoFixer(context, callExpression); return problem; } problem.suggest = [ { messageId: MESSAGE_ID_SUGGESTION_1, - fix: getSuggestion1Fixer(context, node), + fix: getSuggestion1Fixer(context, callExpression), }, { messageId: MESSAGE_ID_SUGGESTION_2, - fix: getSuggestion2Fixer(context, node), + fix: getSuggestion2Fixer(context, callExpression), }, ]; diff --git a/rules/utils/is-promise-method-with-array.js b/rules/utils/is-promise-method-with-array.js deleted file mode 100644 index 845f5b7bd1..0000000000 --- a/rules/utils/is-promise-method-with-array.js +++ /dev/null @@ -1,13 +0,0 @@ -'use strict'; -const {isMethodCall} = require('../ast/index.js'); - -const isPromiseMethodWithArray = (node, methods) => - node.callee.type === 'MemberExpression' - && node.callee.object.type === 'Identifier' - && node.callee.object.name === 'Promise' - && isMethodCall(node, methods) - && node.arguments.length === 1 - && node.arguments[0].type === 'ArrayExpression' - && node.arguments[0].elements.some(element => element !== null); - -module.exports = isPromiseMethodWithArray; diff --git a/test/no-single-promise-in-promise-methods.mjs b/test/no-single-promise-in-promise-methods.mjs index 8b64789c6e..cc53895028 100644 --- a/test/no-single-promise-in-promise-methods.mjs +++ b/test/no-single-promise-in-promise-methods.mjs @@ -3,16 +3,11 @@ import {getTester} from './utils/test.mjs'; const {test} = getTester(import.meta); -const error = { - messageId: 'no-single-promise-in-promise-methods/error', -}; - test.snapshot({ valid: [ 'Promise.all([promise, anotherPromise])', 'Promise.all(notArrayLiteral)', 'Promise.all([...promises])', - 'Promise.all([await -1])', 'Promise.any([promise, anotherPromise])', 'Promise.race([promise, anotherPromise])', 'Promise.allSettled([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 5a5022f94b..6867f38496 100644 --- a/test/snapshots/no-single-promise-in-promise-methods.mjs.md +++ b/test/snapshots/no-single-promise-in-promise-methods.mjs.md @@ -152,3 +152,147 @@ Generated by [AVA](https://avajs.dev). Suggestion 2/2: Wrap the value in a \`Promise.resolve\`.␊ 1 | Promise.resolve(somethingMaybeNotPromise)␊ ` + +## invalid(8): await Promise.all([new Promise(() => {})]) + +> Input + + `␊ + 1 | await Promise.all([new Promise(() => {})])␊ + ` + +> Output + + `␊ + 1 | await new Promise(() => {})␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.all([new Promise(() => {})])␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all\` should not be a single element array.␊ + ` + +## invalid(9): +await Promise.all([+1]) + +> Input + + `␊ + 1 | +await Promise.all([+1])␊ + ` + +> Output + + `␊ + 1 | +await +1␊ + ` + +> Error 1/1 + + `␊ + > 1 | +await Promise.all([+1])␊ + | ^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all\` should not be a single element array.␊ + ` + +## invalid(10): foo await Promise.all([(0, promise)]) + +> Input + + `␊ + 1 | foo␊ + 2 | await Promise.all([(0, promise)])␊ + ` + +> Output + + `␊ + 1 | foo␊ + 2 | await (0, promise)␊ + ` + +> Error 1/1 + + `␊ + 1 | foo␊ + > 2 | await Promise.all([(0, promise)])␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all\` should not be a single element array.␊ + ` + +## invalid(11): foo Promise.all([(0, promise)]) + +> Input + + `␊ + 1 | foo␊ + 2 | Promise.all([(0, promise)])␊ + ` + +> Error 1/1 + + `␊ + 1 | foo␊ + > 2 | Promise.all([(0, promise)])␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all\` should not be a single element array.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Use the value directly.␊ + 1 | foo␊ + 2 | (0, promise)␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Wrap the value in a \`Promise.resolve\`.␊ + 1 | foo␊ + 2 | Promise.resolve((0, promise))␊ + ` + +## invalid(12): foo await Promise.all([[array][0]]) + +> Input + + `␊ + 1 | foo␊ + 2 | await Promise.all([[array][0]])␊ + ` + +> Output + + `␊ + 1 | foo␊ + 2 | await [array][0]␊ + ` + +> Error 1/1 + + `␊ + 1 | foo␊ + > 2 | await Promise.all([[array][0]])␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all\` should not be a single element array.␊ + ` + +## invalid(13): foo Promise.all([[array][0]]) + +> Input + + `␊ + 1 | foo␊ + 2 | Promise.all([[array][0]])␊ + ` + +> Error 1/1 + + `␊ + 1 | foo␊ + > 2 | Promise.all([[array][0]])␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all\` should not be a single element array.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Use the value directly.␊ + 1 | foo␊ + 2 | [array][0]␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Wrap the value in a \`Promise.resolve\`.␊ + 1 | foo␊ + 2 | Promise.resolve([array][0])␊ + ` 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 0e2e76d30e8c81ad83ecb352bec60372bd90db92..8b21633e8ea13cabf781784c506b712832a2dca8 100644 GIT binary patch literal 939 zcmV;c162G$RzVp~PRcUNGX zvO~Z!6CaBR00000000B!m)~pCP!z{oMTEW$^uZ?&+hobQbxo>st8D6n4?d^^5glW) z+xE5%rb$WC&Ef=65J5yA6h#Da3O@Mg|Kg)>J_`N^N^NeN)0~?`*A9Q&w*>C@o_x+X z-;=zlmQ1^R!+o^FJ;O8kO~tS_nQ2rMO)Uc3VulARj@>X^o@1t|tTnqA>#E^etm)Qm z&%L)(sW6XS)Ay$iraCKqAT^er%m8Sx9jTGwCM$81pSPMV&sUj1Dut*<4EKX66x+EDL+G$ z??+JX9UcpLbc|;N<3gmF-L?EW1$rJaQeq9=)uCulA*CafsXLoV!G9V7f3S#T_($1*UX-5*H^6G|KFX2C-bXn; z{`aHYYVQ`bDnQSNKs&6=BS{w!qhloL0g+*%eu+>&q)`u^pTOD@*d3+a(k=+vC)FZ; z1zo$ry}Du5F0giqU$niIF!#IugD)Xqb3U+yazqDK)87%wZ)qQ8QpqmVsH7NbXk=!G zyfT+twHkLl!?r-1(~EG$<>1vhY%;UOp<+0^?3wMHPg+J|w1w%N!mc{38K}&#fCU`N zUEAE`8@T~T`1ciA-Kx~D^TMwS^c=MKmbjrPDl9F-t=r^x-x*|CT|N&bid1eyeM^!u zWQu%5)_)fqou z8}R`(;#Df3vz)NFgs;FJ{4Hsk-=swC5fk+kA~_o(`D=|?O@Bp5Kc_=T<6-{O6SPkj zx$_U3pW*(CNgAwLK0Wh2Q|j{MSo_(Mb;)o1X=F?-Np1uMsnp0L$#IEfUxmz!_sHNc z5@iM|EKy>NE-$8gttn7>K{rLD#Udh@jZTZ0cC4nqAe5hCvVws4U*tr zzivn|O&^O000000000BM)Ip2WKoke?RuQ2$K@Z*@uCj?}YFgcug5ErMPzxd|%Sxxs zYdbidDKnF5U{4Avc=4bJUc~ha`VEwl$=XRLNwKYSOX2d{ zF&}uo%Q>`!c8Z;|2p97uE9ATtlGZtuzgWueN|aA7uSDLS@wLpjT{_I_;Krc~de1WQ zDhE2vacS>bNf%v1Juh~Wf49g#RS&jlqk6cviyvh8H{JNw+q?L0TWD8{`EyB|+$ujU z{Ldx$`6gE5-{uE6S>?BuKLAhGU*%TD|6k?y_5Z%gd9p6FpF!^}K}#~gQt7s3bj2y1 z3)v*~H;ekCn>v603Zq?sJx^L!yPaw8`yKl)sKf;InDWsBlJxPR(A{PCH|E9fSYS;9 zwql&)3p}s?wkUtq4dtqlDQelK*yz$|T;K3%JdQ^rRGJD7VYAhNCkjE25oUzN2oaSy z&@2gzbdkh%8*9xQdn(Cvp)<;XEKDdW!DiSCauZ>G_lo-Vm*({ku5XfATMGaHK^G{r From 7869878e83b4af5ce0fa507922815cb416537501 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Bisson?= Date: Mon, 29 Jan 2024 10:54:11 +0100 Subject: [PATCH 07/34] Add leading semicolon --- rules/no-single-promise-in-promise-methods.js | 19 +++++++++--------- ...o-single-promise-in-promise-methods.mjs.md | 4 ++-- ...single-promise-in-promise-methods.mjs.snap | Bin 939 -> 940 bytes 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/rules/no-single-promise-in-promise-methods.js b/rules/no-single-promise-in-promise-methods.js index cfbd47ef21..5774a533d0 100644 --- a/rules/no-single-promise-in-promise-methods.js +++ b/rules/no-single-promise-in-promise-methods.js @@ -1,5 +1,6 @@ 'use strict'; const {isMethodCall} = require('./ast/index.js'); +const needsSemicolon = require('./utils/needs-semicolon.js'); const MESSAGE_ID_ERROR = 'no-single-promise-in-promise-methods/error'; const MESSAGE_ID_SUGGESTION_1 = 'no-single-promise-in-promise-methods/suggestion-1'; @@ -24,27 +25,27 @@ const isPromiseMethodCallWithSingleElementArray = node => && node.arguments[0].elements[0] !== null && node.arguments[0].elements[0].type !== 'SpreadElement'; -const getText = ({sourceCode}, element) => { +const getText = ({sourceCode}, node, element, prefix = '', suffix = '') => { + const previousToken = sourceCode.getTokenBefore(node); const text = sourceCode.getText(element); + const parenthesizedText = element.type === 'SequenceExpression' ? `(${text})` : text; + const wrappedText = `${prefix}${parenthesizedText}${suffix}`; - return element.type === 'SequenceExpression' ? `(${text})` : text; + return needsSemicolon(previousToken, sourceCode, wrappedText) ? `;${wrappedText}` : wrappedText; }; const getAutoFixer = (context, node) => fixer => { const [element] = node.arguments[0].elements; const elementWithoutAwait = element.type === 'AwaitExpression' ? element.argument : element; - return fixer.replaceText(node, getText(context, elementWithoutAwait)); + return fixer.replaceText(node, getText(context, node, elementWithoutAwait)); }; const getSuggestion1Fixer = (context, node) => fixer => - fixer.replaceText(node, getText(context, node.arguments[0].elements[0])); + fixer.replaceText(node, getText(context, node, node.arguments[0].elements[0])); -const getSuggestion2Fixer = (context, node) => fixer => { - const text = getText(context, node.arguments[0].elements[0]); - - return fixer.replaceText(node, `Promise.resolve(${text})`); -}; +const getSuggestion2Fixer = (context, node) => fixer => + fixer.replaceText(node, getText(context, node, node.arguments[0].elements[0], 'Promise.resolve(', ')')); /** @param {import('eslint').Rule.RuleContext} context */ const create = context => ({ 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 6867f38496..cbaf3f8608 100644 --- a/test/snapshots/no-single-promise-in-promise-methods.mjs.md +++ b/test/snapshots/no-single-promise-in-promise-methods.mjs.md @@ -238,7 +238,7 @@ Generated by [AVA](https://avajs.dev). --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ 1 | foo␊ - 2 | (0, promise)␊ + 2 | ;(0, promise)␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 2/2: Wrap the value in a \`Promise.resolve\`.␊ @@ -289,7 +289,7 @@ Generated by [AVA](https://avajs.dev). --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ 1 | foo␊ - 2 | [array][0]␊ + 2 | ;[array][0]␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 2/2: Wrap the value in a \`Promise.resolve\`.␊ 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 8b21633e8ea13cabf781784c506b712832a2dca8..568044172ff07f8d4dc6fe95970e14ea09501a19 100644 GIT binary patch delta 933 zcmV;W16us62doEwK~_N^Q*L2!b7*gLAa*kf0|1O?s{H%ZPglKTXJ+?mTIzpP-hqh^ zm3Xa#Ky+Za0e)L_q`*eNYq;#3}gTqkoK#zWFGB{s&5J(&jYhCegLSANMVR z`@JWh^Ue1pZ>lBJF5hq;?QmfTliySfYm=EqMbXqEuq|c?SaIxz;qn|aO=Ydwy;xTb z*J4e#ZVUI`PNl*GyQc3?9ZYpr`ao(dJ&^&>U^`MH!%bG=CO>aATf$R0hExtC6>p=r zt$L{?`um=d{}z9OJ78F_5zyHHw{Ex03Rt#)5(fsZVbx3y+~f^z31E)H+BvUQuEt<#{ZEvu}k6lV<)Iwt4rOHi1{k;ow=(%nZ=eugODkD%N;JQnik7*G3* z3z24a*YfKW=sCnli8XXrhoU`+l#WoQ?rbKJzedQP#2bIxD#Ou_=80x!#~Of^rHM^xB*ss_fd{C_CCt-@xLGCR(rRgRUhJd$()F*;6?9uOHO>X!)hLmKtq`3bBof!$HsE$xC&`;=P5ub^u;xTqUe?E-6; z_(fZ+gt>p;^&Wf)0h{%JC6psNu$umkP<~5$D3eNdp++UeP(vd#Gvt-I+^W^MD-7EL zZB{SB6_|%3a&s3ACuXDa%=jl0U@h$&`qNuR647YBR-+gD0Wp#h~Jd`L>xe@g(Ny?BZ@)248UBr}> zm6mi`j(%!R`0ZLyi;yKAA*)f%$sv&7ft2m1T5%L9jA4bWMuLBgz~Aw~OOFj=4s#wI zRK53CnOBQYwQb59N`Bg(RiyvVB0vQXP}R0G06J|qEJ;zPzjOvggF0j*KA=XtN(FS5 z6Bd7$@Drcnv|$L{zP3wBxgb-f2}dA>8}Xs=X3~ZJj{Q3g7(QSB76Q}12k*^ zf0PERmXFVT&y~77I@W&nWL@$fe;PScOA;JGK`J)#NOD{v*;gS$<2`cti$tM;3QH6j zqYI3wUTX?eV9-tR<6;33%tpsWOgmQ7Ul1M2PcdOZK>R;~B4EhBCMNndheP5AA;UKP HzZL)hI|{q% delta 931 zcmV;U16=&92df8vK~_N^Q*L2!b7*gLAa*kf0|2a1$A3r}-4HS*Tb}3CY~Ojr8|y+8 zE_YX8oU%i}G7}$*2mk;800003<(J=U(@+%0TSbJv4fMe$58GtPx^+#ebE|CXgAYEa z0}&l#vfK8y4W>y+(#_%oQ4m2y9~4CdaSA^8=>OuQZ$1it{s&5JZkyAbn?%MsQag(37nk~;)nLsLsk&3_3 z-&VcU^7{Lc{TF{8cfhbFy&bKSPx7M^Nq^9t(MNjAsPn zLZq49wfs5-dLA)SVh!EZp=eJbr6ZK7JDW-5uMzSm@y37l%ZNAkXyNAs{Npry^z;<| z1q5wcj(!G9V7f3S#T_($1*UX-5*H^6G|KFX2C-bXn;{`aHYYVQ`bDnQSN zKs&6=BS{w!qhloL0g+*%eu+>&q)`u^pTOD@*d3+a(k=+vC)FZ;1zo$ry}Du5F0giq zU$niIF!z7E{(~|%3a&s3ACuk*sM3-lbc_?Eb#C@L&1!>!xoci$OgSzUiV4<(9JZbW@ck}_n9d_>lN7cnJe zr6rw~qo10SqFsw>5wgT1WHqWeIRp}Xkh1+$D~=+CF|3f)Nbrvl_&Wl;^w=QgFz3-h z)q8)Hd9?^t+orss??r$b2NVgAz-v`-ef^ADS!;r@$B z8mwAAJ@Y+N>hk1R``MCp$#48=WK1ndZUhCX)W{>rafxJKh0Kii$lxy$Wd Date: Mon, 29 Jan 2024 22:37:47 +0100 Subject: [PATCH 08/34] Add tests --- docs/rules/no-single-promise-in-promise-methods.md | 2 +- test/no-single-promise-in-promise-methods.mjs | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/docs/rules/no-single-promise-in-promise-methods.md b/docs/rules/no-single-promise-in-promise-methods.md index aae6753f5c..ddc47debe3 100644 --- a/docs/rules/no-single-promise-in-promise-methods.md +++ b/docs/rules/no-single-promise-in-promise-methods.md @@ -23,7 +23,7 @@ Promise.race([promise]); ```js Promise.all([promise, anotherPromise]); -Promise.all(notArrayLiteral); +Promise.all(notArrayExpression); Promise.all([...promises]); Promise.any([promise, anotherPromise]); diff --git a/test/no-single-promise-in-promise-methods.mjs b/test/no-single-promise-in-promise-methods.mjs index cc53895028..589f6c68e8 100644 --- a/test/no-single-promise-in-promise-methods.mjs +++ b/test/no-single-promise-in-promise-methods.mjs @@ -6,16 +6,24 @@ const {test} = getTester(import.meta); test.snapshot({ valid: [ 'Promise.all([promise, anotherPromise])', - 'Promise.all(notArrayLiteral)', + 'Promise.all(notArrayExpression)', 'Promise.all([...promises])', 'Promise.any([promise, anotherPromise])', 'Promise.race([promise, anotherPromise])', - 'Promise.allSettled([promise])', + 'Promise.notListedMethod([promise])', 'Promise[all]([promise])', 'Promise.all([,])', 'NotPromise.all([promise])', 'Promise?.all([promise])', 'Promise.all?.([promise])', + 'Promise.all(...[promise])', + 'Promise.all([promise], extraArguments)', + 'Promise.all()', + 'new Promise.all([promise])', + + // We are not checking these cases + 'globalThis.Promise.all([promise])', + 'Promise["all"]([promise])', ], invalid: [ 'await Promise.all([promise])', From 26e557ab5fc3abef72a72abf765f4fb78a96ecb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Bisson?= Date: Wed, 31 Jan 2024 19:44:50 +0100 Subject: [PATCH 09/34] Update error message --- .../no-single-promise-in-promise-methods.md | 2 +- rules/no-single-promise-in-promise-methods.js | 2 +- ...o-single-promise-in-promise-methods.mjs.md | 26 +++++++++--------- ...single-promise-in-promise-methods.mjs.snap | Bin 940 -> 942 bytes 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/rules/no-single-promise-in-promise-methods.md b/docs/rules/no-single-promise-in-promise-methods.md index ddc47debe3..d9475dbcf1 100644 --- a/docs/rules/no-single-promise-in-promise-methods.md +++ b/docs/rules/no-single-promise-in-promise-methods.md @@ -7,7 +7,7 @@ -Single element array parameter in a Promise.all(), Promise.any() or Promise.race() method is probably a mistake. +Single element array parameter in `Promise.all()`, `Promise.any()` or `Promise.race()` is probably a mistake. ## Fail diff --git a/rules/no-single-promise-in-promise-methods.js b/rules/no-single-promise-in-promise-methods.js index 5774a533d0..eb380707e4 100644 --- a/rules/no-single-promise-in-promise-methods.js +++ b/rules/no-single-promise-in-promise-methods.js @@ -6,7 +6,7 @@ const MESSAGE_ID_ERROR = 'no-single-promise-in-promise-methods/error'; const MESSAGE_ID_SUGGESTION_1 = 'no-single-promise-in-promise-methods/suggestion-1'; const MESSAGE_ID_SUGGESTION_2 = 'no-single-promise-in-promise-methods/suggestion-2'; const messages = { - [MESSAGE_ID_ERROR]: 'Parameter in `Promise.{{method}}` should not be a single element array.', + [MESSAGE_ID_ERROR]: 'Parameter in `Promise.{{method}}()` should not be a single element array.', [MESSAGE_ID_SUGGESTION_1]: 'Use the value directly.', [MESSAGE_ID_SUGGESTION_2]: 'Wrap the value in a `Promise.resolve`.', }; 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 cbaf3f8608..fa42743cec 100644 --- a/test/snapshots/no-single-promise-in-promise-methods.mjs.md +++ b/test/snapshots/no-single-promise-in-promise-methods.mjs.md @@ -22,7 +22,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([promise])␊ - | ^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all\` should not be a single element array.␊ + | ^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all()\` should not be a single element array.␊ ` ## invalid(2): await Promise.all([func()]) @@ -43,7 +43,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([func()])␊ - | ^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all\` should not be a single element array.␊ + | ^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all()\` should not be a single element array.␊ ` ## invalid(3): await Promise.all([promises[0]]) @@ -64,7 +64,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([promises[0]])␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all\` should not be a single element array.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all()\` should not be a single element array.␊ ` ## invalid(4): await Promise.all([await promise]) @@ -85,7 +85,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([await promise])␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all\` should not be a single element array.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all()\` should not be a single element array.␊ ` ## invalid(5): await Promise.any([promise]) @@ -106,7 +106,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.any([promise])␊ - | ^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.any\` should not be a single element array.␊ + | ^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.any()\` should not be a single element array.␊ ` ## invalid(6): await Promise.race([promise]) @@ -127,7 +127,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.race([promise])␊ - | ^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.race\` should not be a single element array.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.race()\` should not be a single element array.␊ ` ## invalid(7): Promise.all([somethingMaybeNotPromise]) @@ -142,7 +142,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | Promise.all([somethingMaybeNotPromise])␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all\` should not be a single element array.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all()\` should not be a single element array.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ @@ -171,7 +171,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([new Promise(() => {})])␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all\` should not be a single element array.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all()\` should not be a single element array.␊ ` ## invalid(9): +await Promise.all([+1]) @@ -192,7 +192,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | +await Promise.all([+1])␊ - | ^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all\` should not be a single element array.␊ + | ^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all()\` should not be a single element array.␊ ` ## invalid(10): foo await Promise.all([(0, promise)]) @@ -216,7 +216,7 @@ Generated by [AVA](https://avajs.dev). `␊ 1 | foo␊ > 2 | await Promise.all([(0, promise)])␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all\` should not be a single element array.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all()\` should not be a single element array.␊ ` ## invalid(11): foo Promise.all([(0, promise)]) @@ -233,7 +233,7 @@ Generated by [AVA](https://avajs.dev). `␊ 1 | foo␊ > 2 | Promise.all([(0, promise)])␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all\` should not be a single element array.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all()\` should not be a single element array.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ @@ -267,7 +267,7 @@ Generated by [AVA](https://avajs.dev). `␊ 1 | foo␊ > 2 | await Promise.all([[array][0]])␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all\` should not be a single element array.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all()\` should not be a single element array.␊ ` ## invalid(13): foo Promise.all([[array][0]]) @@ -284,7 +284,7 @@ Generated by [AVA](https://avajs.dev). `␊ 1 | foo␊ > 2 | Promise.all([[array][0]])␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all\` should not be a single element array.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all()\` should not be a single element array.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ 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 568044172ff07f8d4dc6fe95970e14ea09501a19..bdd6e94029c3b0018f40f7fdf927e65c4415bf72 100644 GIT binary patch literal 942 zcmV;f15x}zRzV_c@FYm__Ta z>irj$79WcU00000000B!mpyOOP!xufB7~H!5)4cnwMDg?HjN!9ZK@U+7#M&`2tid9 z^(MJVEF3$sZ(1VCQWk{N0R|8VA+-`n42=93Mm9#oFF$RMmJ$@`F(h&tiFEdnoL?c% zPa`;Y50Aw>Ov=-eav{>t?pl7GLOq8lDY2&R=uo^TkQ+M?J0~4GPtQY(Z^;{qqQcTLJbFxi171O<)x+mvh$598QQwuM z44EXKk@-JFOv|v+l1|Ozn4S}|VGC*zvcyAVHL5*1gc3ZIVf(3OoI?tuSRt#C=$|9> zI}&~9v3}4&(!<26cmFf zwu{K3f7l=mT0o9ef7Rh*G~e~59v&ZShdo&j`Ln-_ys0G#55FK49eE@<79!bGA%o*1 z^7xxX!GQ`(6dS_~jj3*P3RGy&ZIO|&fEZ?@BO|6EtLbkD=9iejATa(fVc|37UlSF* Qnu9^{6WJDU57`y~02_i_@% literal 940 zcmV;d15^A#RzVVH(;fr$^5c&&p# z?248S?jMT?00000000B!m)~pCP!z{oMTEW$^uZ?&bFyUJx+c}Rb!_T`4?d^^5glW) z+xE5%rb$U|H;WTQK?D(fP!tiwDfr-{e~gd5`6&JeN^R2SH0LJKwZk9xErI*JC!h1p z_atwsCDSh7a3Ae(VF;7oR19mAnMOs?)FQAgW(Zhu?1tg;95YR2t=YX;R}I%unpaHom{ZO9M<51J78F_5zyHHw{Ex03Rt#)5(fsZVbx3y+~f^z z31E)H+BvUQuEt<#{ZEvu}k6lV<)Iwt4rOHi1{k;ow=(%nZ=eugOD zkD%N;JQnik7*G3*3z24a*YfKW=sCnli8XXrhoU`+l#WoQ?rbKJzedQP#2ecyBi`Jj zg`e}`pP=ERr>F4GBWP1{`~ynEOqI6?{?iEfgGD66KgtI5qWomI0aknWQI0hBKFaa& zzaQmRd$*ufAM{)Zw8P3gl5_zvI!=-v5E&-wmk9Mk8uj4$39K!F-BH>t?SfDHlv>2E zpldg{s2f)80&AD}MO&;Qn?ZJElJ9d zDe@6n|6RnCl$DlrT8@5dPWbIwP>YZy9wDny&B-B<;DMCwr&@6oDU4x-tVV)=jKJUV z!Ap+~Vh(d29aO#dSD9CfP_=E!8%loKpH-y)&muqt4^Y*%GXOemH!Mj}r@wRtMT0tI zBR-%;yh;UhmJ=42@Drcnv|$L{zP3wBxgb-f2}dA>8}Xs=X3~ZJj{Q3g7(QS zB76Q}12k*^f0PERmXFVT&y~77I@W&nWL@$fe;PScOA;JGK`J)#NOD{v*;gS$<2`ct zi$tM;3QH6jqYI3wUTX?eV9-tR<6;33%tpsWOgmQ7Ul7VqF=0VK{6B&sV938FCi*pp OL*fS^!#4fD761V9kid2T From 8417930e5cf69477f96be2aab44823c289cd88e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Bisson?= Date: Sat, 3 Feb 2024 22:42:35 +0100 Subject: [PATCH 10/34] Update error message --- rules/no-single-promise-in-promise-methods.js | 6 ++-- ...o-single-promise-in-promise-methods.mjs.md | 32 +++++++++--------- ...single-promise-in-promise-methods.mjs.snap | Bin 942 -> 938 bytes 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/rules/no-single-promise-in-promise-methods.js b/rules/no-single-promise-in-promise-methods.js index eb380707e4..18d586123a 100644 --- a/rules/no-single-promise-in-promise-methods.js +++ b/rules/no-single-promise-in-promise-methods.js @@ -6,9 +6,9 @@ const MESSAGE_ID_ERROR = 'no-single-promise-in-promise-methods/error'; const MESSAGE_ID_SUGGESTION_1 = 'no-single-promise-in-promise-methods/suggestion-1'; const MESSAGE_ID_SUGGESTION_2 = 'no-single-promise-in-promise-methods/suggestion-2'; const messages = { - [MESSAGE_ID_ERROR]: 'Parameter in `Promise.{{method}}()` should not be a single element array.', + [MESSAGE_ID_ERROR]: 'Wrapping a single element array with `Promise.{{method}}()` is unnecessary.', [MESSAGE_ID_SUGGESTION_1]: 'Use the value directly.', - [MESSAGE_ID_SUGGESTION_2]: 'Wrap the value in a `Promise.resolve`.', + [MESSAGE_ID_SUGGESTION_2]: 'Wrap the value with `Promise.resolve()`.', }; const METHODS = ['all', 'any', 'race']; @@ -55,7 +55,7 @@ const create = context => ({ } const problem = { - node: callExpression, + node: callExpression.arguments[0], messageId: MESSAGE_ID_ERROR, data: { method: callExpression.callee.property.name, 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 fa42743cec..c3c78d6bc2 100644 --- a/test/snapshots/no-single-promise-in-promise-methods.mjs.md +++ b/test/snapshots/no-single-promise-in-promise-methods.mjs.md @@ -22,7 +22,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([promise])␊ - | ^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all()\` should not be a single element array.␊ + | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(2): await Promise.all([func()]) @@ -43,7 +43,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([func()])␊ - | ^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all()\` should not be a single element array.␊ + | ^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(3): await Promise.all([promises[0]]) @@ -64,7 +64,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([promises[0]])␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all()\` should not be a single element array.␊ + | ^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(4): await Promise.all([await promise]) @@ -85,7 +85,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([await promise])␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all()\` should not be a single element array.␊ + | ^^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(5): await Promise.any([promise]) @@ -106,7 +106,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.any([promise])␊ - | ^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.any()\` should not be a single element array.␊ + | ^^^^^^^^^ Wrapping a single element array with \`Promise.any()\` is unnecessary.␊ ` ## invalid(6): await Promise.race([promise]) @@ -127,7 +127,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.race([promise])␊ - | ^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.race()\` should not be a single element array.␊ + | ^^^^^^^^^ Wrapping a single element array with \`Promise.race()\` is unnecessary.␊ ` ## invalid(7): Promise.all([somethingMaybeNotPromise]) @@ -142,14 +142,14 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | Promise.all([somethingMaybeNotPromise])␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all()\` should not be a single element array.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ 1 | somethingMaybeNotPromise␊ ␊ --------------------------------------------------------------------------------␊ - Suggestion 2/2: Wrap the value in a \`Promise.resolve\`.␊ + Suggestion 2/2: Wrap the value with \`Promise.resolve()\`.␊ 1 | Promise.resolve(somethingMaybeNotPromise)␊ ` @@ -171,7 +171,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([new Promise(() => {})])␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all()\` should not be a single element array.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(9): +await Promise.all([+1]) @@ -192,7 +192,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | +await Promise.all([+1])␊ - | ^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all()\` should not be a single element array.␊ + | ^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(10): foo await Promise.all([(0, promise)]) @@ -216,7 +216,7 @@ Generated by [AVA](https://avajs.dev). `␊ 1 | foo␊ > 2 | await Promise.all([(0, promise)])␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all()\` should not be a single element array.␊ + | ^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(11): foo Promise.all([(0, promise)]) @@ -233,7 +233,7 @@ Generated by [AVA](https://avajs.dev). `␊ 1 | foo␊ > 2 | Promise.all([(0, promise)])␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all()\` should not be a single element array.␊ + | ^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ @@ -241,7 +241,7 @@ Generated by [AVA](https://avajs.dev). 2 | ;(0, promise)␊ ␊ --------------------------------------------------------------------------------␊ - Suggestion 2/2: Wrap the value in a \`Promise.resolve\`.␊ + Suggestion 2/2: Wrap the value with \`Promise.resolve()\`.␊ 1 | foo␊ 2 | Promise.resolve((0, promise))␊ ` @@ -267,7 +267,7 @@ Generated by [AVA](https://avajs.dev). `␊ 1 | foo␊ > 2 | await Promise.all([[array][0]])␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all()\` should not be a single element array.␊ + | ^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(13): foo Promise.all([[array][0]]) @@ -284,7 +284,7 @@ Generated by [AVA](https://avajs.dev). `␊ 1 | foo␊ > 2 | Promise.all([[array][0]])␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^ Parameter in \`Promise.all()\` should not be a single element array.␊ + | ^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ @@ -292,7 +292,7 @@ Generated by [AVA](https://avajs.dev). 2 | ;[array][0]␊ ␊ --------------------------------------------------------------------------------␊ - Suggestion 2/2: Wrap the value in a \`Promise.resolve\`.␊ + Suggestion 2/2: Wrap the value with \`Promise.resolve()\`.␊ 1 | foo␊ 2 | Promise.resolve([array][0])␊ ` 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 bdd6e94029c3b0018f40f7fdf927e65c4415bf72..fc435f1b046e52534349cf18826248d7bf166fc8 100644 GIT binary patch literal 938 zcmV;b16BM%RzV^@LxKCg0?i2h4F;6SfVn2J1n2bsY>B z8kWUN+;y4L%=zUS*B!@pK%3SC>v6$ar&(7TR!LDQ)Ea^`Dn~6ODAFTHMjA?mNWZ9?9GE~S3P%O}MDbp-$JA`*3A&^>6!`lWCWtmffk9cdhW ztmEVR9_v=K7uKp^JriQ>uo91iT|k&Fkg&T%`bqmeqWyxV-F?0c_h0kgKcENT1p)lB zTEzFFYj1L|W?0pmthvE&+1^qZ{S*J%7Z9^)pIJgVq6y1GClSrxX`g0N$uQS7>FQ5< zWTyJOGItu)DtA4@wm_TKi*VQF;MF*6F|)y;Y&g8+na!LJTLxpWh3T!rTKoc)bs3Vo zwz<{vWUk8=;ul%vs?@YI!nCvWRJ8cE_(D-sSXhKdkI84jtH`&yd^$=Lsr-m~z9ePH zH2H@7|2bl2%1TQ(JCA0Dj){)VsYS>VSCQ4I{^Sr#@L9_CQ{6a^6o#=vRwLQJMC^A3 zd+D)}AwF2Hdi#|#uNI+V+mu6;{G^y%g&}q|QNeVpu=+iA4)FFHE z74_mnDxkBNu()J5!V$ekX`0`sL>&_IbsoW-3c>8HH_Pc?i0Y4Yh-z;Tp>6 M0gKqV*6bDl06T}#R{#J2 literal 942 zcmV;f15x}zRzV_c@FYm__Ta z>irj$79WcU00000000B!mpyOOP!xufB7~H!5)4cnwMDg?HjN!9ZK@U+7#M&`2tid9 z^(MJVEF3$sZ(1VCQWk{N0R|8VA+-`n42=93Mm9#oFF$RMmJ$@`F(h&tiFEdnoL?c% zPa`;Y50Aw>Ov=-eav{>t?pl7GLOq8lDY2&R=uo^TkQ+M?J0~4GPtQY(Z^;{qqQcTLJbFxi171O<)x+mvh$598QQwuM z44EXKk@-JFOv|v+l1|Ozn4S}|VGC*zvcyAVHL5*1gc3ZIVf(3OoI?tuSRt#C=$|9> zI}&~9v3}4&(!<26cmFf zwu{K3f7l=mT0o9ef7Rh*G~e~59v&ZShdo&j`Ln-_ys0G#55FK49eE@<79!bGA%o*1 z^7xxX!GQ`(6dS_~jj3*P3RGy&ZIO|&fEZ?@BO|6EtLbkD=9iejATa(fVc|37UlSF* Qnu9^{6WJDU57`y~02_i_@% From 345b637853c6e6512a34f4456342a68356c9a3ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Bisson?= Date: Sat, 3 Feb 2024 23:06:59 +0100 Subject: [PATCH 11/34] Rename functions --- rules/no-single-promise-in-promise-methods.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/rules/no-single-promise-in-promise-methods.js b/rules/no-single-promise-in-promise-methods.js index 18d586123a..ed6f018305 100644 --- a/rules/no-single-promise-in-promise-methods.js +++ b/rules/no-single-promise-in-promise-methods.js @@ -1,6 +1,6 @@ 'use strict'; const {isMethodCall} = require('./ast/index.js'); -const needsSemicolon = require('./utils/needs-semicolon.js'); +const {getParenthesizedText, needsSemicolon} = require('./utils/index.js'); const MESSAGE_ID_ERROR = 'no-single-promise-in-promise-methods/error'; const MESSAGE_ID_SUGGESTION_1 = 'no-single-promise-in-promise-methods/suggestion-1'; @@ -27,24 +27,23 @@ const isPromiseMethodCallWithSingleElementArray = node => const getText = ({sourceCode}, node, element, prefix = '', suffix = '') => { const previousToken = sourceCode.getTokenBefore(node); - const text = sourceCode.getText(element); - const parenthesizedText = element.type === 'SequenceExpression' ? `(${text})` : text; + const parenthesizedText = getParenthesizedText(element, sourceCode); const wrappedText = `${prefix}${parenthesizedText}${suffix}`; return needsSemicolon(previousToken, sourceCode, wrappedText) ? `;${wrappedText}` : wrappedText; }; -const getAutoFixer = (context, node) => fixer => { +const unwrapValue = (context, node) => fixer => { const [element] = node.arguments[0].elements; const elementWithoutAwait = element.type === 'AwaitExpression' ? element.argument : element; return fixer.replaceText(node, getText(context, node, elementWithoutAwait)); }; -const getSuggestion1Fixer = (context, node) => fixer => +const useValueDirectly = (context, node) => fixer => fixer.replaceText(node, getText(context, node, node.arguments[0].elements[0])); -const getSuggestion2Fixer = (context, node) => fixer => +const wrapWithPromiseResolve = (context, node) => fixer => fixer.replaceText(node, getText(context, node, node.arguments[0].elements[0], 'Promise.resolve(', ')')); /** @param {import('eslint').Rule.RuleContext} context */ @@ -63,18 +62,18 @@ const create = context => ({ }; if (callExpression.parent.type === 'AwaitExpression') { - problem.fix = getAutoFixer(context, callExpression); + problem.fix = unwrapValue(context, callExpression); return problem; } problem.suggest = [ { messageId: MESSAGE_ID_SUGGESTION_1, - fix: getSuggestion1Fixer(context, callExpression), + fix: useValueDirectly(context, callExpression), }, { messageId: MESSAGE_ID_SUGGESTION_2, - fix: getSuggestion2Fixer(context, callExpression), + fix: wrapWithPromiseResolve(context, callExpression), }, ]; From a32688f29df367d948f76e25dec9f929f1b6d70d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Bisson?= Date: Sun, 4 Feb 2024 00:48:56 +0100 Subject: [PATCH 12/34] Fix .then() error --- rules/no-single-promise-in-promise-methods.js | 23 +++++- test/no-single-promise-in-promise-methods.mjs | 3 + ...o-single-promise-in-promise-methods.mjs.md | 69 ++++++++++++++++++ ...single-promise-in-promise-methods.mjs.snap | Bin 938 -> 1077 bytes 4 files changed, 93 insertions(+), 2 deletions(-) diff --git a/rules/no-single-promise-in-promise-methods.js b/rules/no-single-promise-in-promise-methods.js index ed6f018305..1a9d58e599 100644 --- a/rules/no-single-promise-in-promise-methods.js +++ b/rules/no-single-promise-in-promise-methods.js @@ -1,6 +1,11 @@ 'use strict'; const {isMethodCall} = require('./ast/index.js'); -const {getParenthesizedText, needsSemicolon} = require('./utils/index.js'); +const { + getParenthesizedText, + isParenthesized, + needsSemicolon, + shouldAddParenthesesToMemberExpressionObject, +} = require('./utils/index.js'); const MESSAGE_ID_ERROR = 'no-single-promise-in-promise-methods/error'; const MESSAGE_ID_SUGGESTION_1 = 'no-single-promise-in-promise-methods/suggestion-1'; @@ -25,10 +30,24 @@ const isPromiseMethodCallWithSingleElementArray = node => && node.arguments[0].elements[0] !== null && node.arguments[0].elements[0].type !== 'SpreadElement'; +const wrapText = (sourceCode, node, element, text, prefix, suffix) => { + if (prefix || suffix) { + return `${prefix}${text}${suffix}`; + } + + if (node.parent.type === 'MemberExpression' + && !isParenthesized(element, sourceCode) + && shouldAddParenthesesToMemberExpressionObject(element, sourceCode)) { + return `(${text})`; + } + + return text; +}; + const getText = ({sourceCode}, node, element, prefix = '', suffix = '') => { const previousToken = sourceCode.getTokenBefore(node); const parenthesizedText = getParenthesizedText(element, sourceCode); - const wrappedText = `${prefix}${parenthesizedText}${suffix}`; + const wrappedText = wrapText(sourceCode, node, element, parenthesizedText, prefix, suffix); return needsSemicolon(previousToken, sourceCode, wrappedText) ? `;${wrappedText}` : wrappedText; }; diff --git a/test/no-single-promise-in-promise-methods.mjs b/test/no-single-promise-in-promise-methods.mjs index 589f6c68e8..866fbfb577 100644 --- a/test/no-single-promise-in-promise-methods.mjs +++ b/test/no-single-promise-in-promise-methods.mjs @@ -51,5 +51,8 @@ test.snapshot({ foo Promise.all([[array][0]]) `, + 'Promise.all([promise]).then()', + 'Promise.all([1]).then()', + 'Promise.all([(0, promise)]).then()', ], }); 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 c3c78d6bc2..c25bbbc2a6 100644 --- a/test/snapshots/no-single-promise-in-promise-methods.mjs.md +++ b/test/snapshots/no-single-promise-in-promise-methods.mjs.md @@ -296,3 +296,72 @@ Generated by [AVA](https://avajs.dev). 1 | foo␊ 2 | Promise.resolve([array][0])␊ ` + +## invalid(14): Promise.all([promise]).then() + +> Input + + `␊ + 1 | Promise.all([promise]).then()␊ + ` + +> Error 1/1 + + `␊ + > 1 | Promise.all([promise]).then()␊ + | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Use the value directly.␊ + 1 | promise.then()␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Wrap the value with \`Promise.resolve()\`.␊ + 1 | Promise.resolve(promise).then()␊ + ` + +## invalid(15): Promise.all([1]).then() + +> Input + + `␊ + 1 | Promise.all([1]).then()␊ + ` + +> Error 1/1 + + `␊ + > 1 | Promise.all([1]).then()␊ + | ^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Use the value directly.␊ + 1 | (1).then()␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Wrap the value with \`Promise.resolve()\`.␊ + 1 | Promise.resolve(1).then()␊ + ` + +## invalid(16): Promise.all([(0, promise)]).then() + +> Input + + `␊ + 1 | Promise.all([(0, promise)]).then()␊ + ` + +> Error 1/1 + + `␊ + > 1 | Promise.all([(0, promise)]).then()␊ + | ^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Use the value directly.␊ + 1 | (0, promise).then()␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Wrap the value with \`Promise.resolve()\`.␊ + 1 | Promise.resolve((0, promise)).then()␊ + ` 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 fc435f1b046e52534349cf18826248d7bf166fc8..513b7fdfc243688354f328d3c1237b33a7f2ec9f 100644 GIT binary patch literal 1077 zcmV-51j_qCRzV#*a+EgttFfag>5Q3^| zRX4dL7OoxHPD?~t=!B3Ef&m0Vhz=kzASPBe{sR`o$buLVJ4)+I{OotO14-2eZ*6+t zJ^$X9@7?uvc}+8lx2#7y%vNoU-Ii2+L($ZdMCAfeHWk$-3#PHIS}dh#nzU5g`(asD zEnTTuRl~NncSvntHbN9M|2eHI_`1XVlvPJyQ3V+BAQ>oQdy+RaXsd`0YglTM@={8YJQ)!S* z)vl6Nx4gVcREyMgofVm7DP|+(l&fAeO~WKKO*!jP&N_>;F4y& zr-8@`AhNd(1^o80$R1B!${~PX_}&3Y1P^)^09F zsqX;lPr~i(lo4w2-t$j!{*yR=008U2G~hNS?tn+BoAL4n@P8V>-&;ha4)nSQtyrJ( z_dsv_d#nSE{f~9Heb-}MZ*;<1=B)ER)}~Tqfv|G`(-{=DN2HsyUjo_>aoXPfMY#W( z_wEKA0MBvYXXOI?E?UMqv#Y9JxvVtS*cHQG@T0%yy!#wrmUfs$ltY@ZIB*ou{2g~_ zMwRq)T@gOrNsq)tm!HJ7dZofFTQzh-)7b*KZZTq48QD;@IwK|3WJOzRq#W2H7`-hl z+bpcf&sCYnkjyf)jix749$WBFM3u`z)8@Hpr}3$%vrYaBNs`IjJh^ihJqw-(zRilK zqd*bMkD&7s1s4FLoWrPW7zskMxapuI z1|C29ctzbhXfNJ_Uc8FAbmk)#7wwC%PxmNFojyhC5TCEJ0Oo`bW@o)wjQ;{uzsG%4 zJLB1p^Rx|j7MS$FjZ?o1_}{qe77x=*%bHnnge>iLZdq{6KL_kdqXdXs5Q~otkUTAr zY^$K*@ebJhMWpZmg++;u-Ui25t2;R?IPkvk*q8wjlfkhO(vijZPeAiqNN9v`?CZdA z+42y@MZ0QoShVdp>Af$uF10DU%5({_BYr^-6hV#n1sL%&dN=e51z4~@{O7zef8PUV zJntubGQmy^@LxKCg0?i2h4F;6SfVn2J1n2bsY>B z8kWUN+;y4L%=zUS*B!@pK%3SC>v6$ar&(7TR!LDQ)Ea^`Dn~6ODAFTHMjA?mNWZ9?9GE~S3P%O}MDbp-$JA`*3A&^>6!`lWCWtmffk9cdhW ztmEVR9_v=K7uKp^JriQ>uo91iT|k&Fkg&T%`bqmeqWyxV-F?0c_h0kgKcENT1p)lB zTEzFFYj1L|W?0pmthvE&+1^qZ{S*J%7Z9^)pIJgVq6y1GClSrxX`g0N$uQS7>FQ5< zWTyJOGItu)DtA4@wm_TKi*VQF;MF*6F|)y;Y&g8+na!LJTLxpWh3T!rTKoc)bs3Vo zwz<{vWUk8=;ul%vs?@YI!nCvWRJ8cE_(D-sSXhKdkI84jtH`&yd^$=Lsr-m~z9ePH zH2H@7|2bl2%1TQ(JCA0Dj){)VsYS>VSCQ4I{^Sr#@L9_CQ{6a^6o#=vRwLQJMC^A3 zd+D)}AwF2Hdi#|#uNI+V+mu6;{G^y%g&}q|QNeVpu=+iA4)FFHE z74_mnDxkBNu()J5!V$ekX`0`sL>&_IbsoW-3c>8HH_Pc?i0Y4Yh-z;Tp>6 M0gKqV*6bDl06T}#R{#J2 From 88934878794f44fdc26dafebd5624c7a6eb922f2 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Thu, 22 Feb 2024 15:01:28 +0700 Subject: [PATCH 13/34] Update no-single-promise-in-promise-methods.md --- docs/rules/no-single-promise-in-promise-methods.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/rules/no-single-promise-in-promise-methods.md b/docs/rules/no-single-promise-in-promise-methods.md index d9475dbcf1..229017be62 100644 --- a/docs/rules/no-single-promise-in-promise-methods.md +++ b/docs/rules/no-single-promise-in-promise-methods.md @@ -7,7 +7,7 @@ -Single element array parameter in `Promise.all()`, `Promise.any()` or `Promise.race()` is probably a mistake. +Passing a single-element array to `Promise.all()`, `Promise.any()`, or `Promise.race()` is likely a mistake. ## Fail @@ -23,7 +23,7 @@ Promise.race([promise]); ```js Promise.all([promise, anotherPromise]); -Promise.all(notArrayExpression); +Promise.all(arrayVariable); Promise.all([...promises]); Promise.any([promise, anotherPromise]); From e28b11ae83225ebdb5f208e43129263d423ec7d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Bisson?= Date: Thu, 22 Feb 2024 11:58:37 +0100 Subject: [PATCH 14/34] Update tests --- test/no-single-promise-in-promise-methods.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/no-single-promise-in-promise-methods.mjs b/test/no-single-promise-in-promise-methods.mjs index 866fbfb577..e972ca6782 100644 --- a/test/no-single-promise-in-promise-methods.mjs +++ b/test/no-single-promise-in-promise-methods.mjs @@ -6,7 +6,7 @@ const {test} = getTester(import.meta); test.snapshot({ valid: [ 'Promise.all([promise, anotherPromise])', - 'Promise.all(notArrayExpression)', + 'Promise.all(arrayVariable)', 'Promise.all([...promises])', 'Promise.any([promise, anotherPromise])', 'Promise.race([promise, anotherPromise])', From e15154ed881e8d944d40dd20f6a7a61c6fa6daec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Bisson?= Date: Thu, 22 Feb 2024 12:10:58 +0100 Subject: [PATCH 15/34] Update description message --- docs/rules/no-single-promise-in-promise-methods.md | 2 +- readme.md | 2 +- rules/no-single-promise-in-promise-methods.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/rules/no-single-promise-in-promise-methods.md b/docs/rules/no-single-promise-in-promise-methods.md index 229017be62..c781bf8613 100644 --- a/docs/rules/no-single-promise-in-promise-methods.md +++ b/docs/rules/no-single-promise-in-promise-methods.md @@ -1,4 +1,4 @@ -# Disallow using `Promise` method with a single element array as parameter +# Disallow passing single-element arrays to `Promise` methods πŸ’Ό This rule is enabled in the βœ… `recommended` [config](https://github.com/sindresorhus/eslint-plugin-unicorn#preset-configs). diff --git a/readme.md b/readme.md index 425de4e129..fac04c3d34 100644 --- a/readme.md +++ b/readme.md @@ -148,7 +148,7 @@ If you don't use the preset, ensure you use the same `env` and `parserOptions` c | [no-null](docs/rules/no-null.md) | Disallow the use of the `null` literal. | βœ… | πŸ”§ | πŸ’‘ | | [no-object-as-default-parameter](docs/rules/no-object-as-default-parameter.md) | Disallow the use of objects as default parameters. | βœ… | | | | [no-process-exit](docs/rules/no-process-exit.md) | Disallow `process.exit()`. | βœ… | | | -| [no-single-promise-in-promise-methods](docs/rules/no-single-promise-in-promise-methods.md) | Disallow using `Promise` method with a single element array as parameter. | βœ… | πŸ”§ | πŸ’‘ | +| [no-single-promise-in-promise-methods](docs/rules/no-single-promise-in-promise-methods.md) | Disallow passing single-element arrays to `Promise` methods. | βœ… | πŸ”§ | πŸ’‘ | | [no-static-only-class](docs/rules/no-static-only-class.md) | Disallow classes that only have static members. | βœ… | πŸ”§ | | | [no-thenable](docs/rules/no-thenable.md) | Disallow `then` property. | βœ… | | | | [no-this-assignment](docs/rules/no-this-assignment.md) | Disallow assigning `this` to a variable. | βœ… | | | diff --git a/rules/no-single-promise-in-promise-methods.js b/rules/no-single-promise-in-promise-methods.js index 1a9d58e599..bb91a82a63 100644 --- a/rules/no-single-promise-in-promise-methods.js +++ b/rules/no-single-promise-in-promise-methods.js @@ -106,7 +106,7 @@ module.exports = { meta: { type: 'suggestion', docs: { - description: 'Disallow using `Promise` method with a single element array as parameter.', + description: 'Disallow passing single-element arrays to `Promise` methods.', }, fixable: 'code', hasSuggestions: true, From d74d45f9d1420b50e49f58ed388f233742879fec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Bisson?= Date: Thu, 22 Feb 2024 13:53:24 +0100 Subject: [PATCH 16/34] Update no-single-promise-in-promise-methods.md and tests --- docs/rules/no-single-promise-in-promise-methods.md | 2 +- test/no-single-promise-in-promise-methods.mjs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/rules/no-single-promise-in-promise-methods.md b/docs/rules/no-single-promise-in-promise-methods.md index c781bf8613..1168bbce35 100644 --- a/docs/rules/no-single-promise-in-promise-methods.md +++ b/docs/rules/no-single-promise-in-promise-methods.md @@ -23,7 +23,7 @@ Promise.race([promise]); ```js Promise.all([promise, anotherPromise]); -Promise.all(arrayVariable); +Promise.all(notArrayLiteral); Promise.all([...promises]); Promise.any([promise, anotherPromise]); diff --git a/test/no-single-promise-in-promise-methods.mjs b/test/no-single-promise-in-promise-methods.mjs index e972ca6782..1f592e1647 100644 --- a/test/no-single-promise-in-promise-methods.mjs +++ b/test/no-single-promise-in-promise-methods.mjs @@ -6,7 +6,7 @@ const {test} = getTester(import.meta); test.snapshot({ valid: [ 'Promise.all([promise, anotherPromise])', - 'Promise.all(arrayVariable)', + 'Promise.all(notArrayLiteral)', 'Promise.all([...promises])', 'Promise.any([promise, anotherPromise])', 'Promise.race([promise, anotherPromise])', From 377da6e05821fba38a123de52c254becf9153d31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Bisson?= Date: Thu, 22 Feb 2024 18:55:40 +0100 Subject: [PATCH 17/34] Fix exponentiation operator error --- rules/no-single-promise-in-promise-methods.js | 3 +-- test/no-single-promise-in-promise-methods.mjs | 1 + ...o-single-promise-in-promise-methods.mjs.md | 23 +++++++++++++++++- ...single-promise-in-promise-methods.mjs.snap | Bin 1077 -> 1120 bytes 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/rules/no-single-promise-in-promise-methods.js b/rules/no-single-promise-in-promise-methods.js index bb91a82a63..e547ad615d 100644 --- a/rules/no-single-promise-in-promise-methods.js +++ b/rules/no-single-promise-in-promise-methods.js @@ -35,8 +35,7 @@ const wrapText = (sourceCode, node, element, text, prefix, suffix) => { return `${prefix}${text}${suffix}`; } - if (node.parent.type === 'MemberExpression' - && !isParenthesized(element, sourceCode) + if (!isParenthesized(element, sourceCode) && shouldAddParenthesesToMemberExpressionObject(element, sourceCode)) { return `(${text})`; } diff --git a/test/no-single-promise-in-promise-methods.mjs b/test/no-single-promise-in-promise-methods.mjs index 1f592e1647..29f878002e 100644 --- a/test/no-single-promise-in-promise-methods.mjs +++ b/test/no-single-promise-in-promise-methods.mjs @@ -54,5 +54,6 @@ test.snapshot({ 'Promise.all([promise]).then()', 'Promise.all([1]).then()', 'Promise.all([(0, promise)]).then()', + 'await Promise.all([x ** y])', ], }); 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 c25bbbc2a6..f66738802b 100644 --- a/test/snapshots/no-single-promise-in-promise-methods.mjs.md +++ b/test/snapshots/no-single-promise-in-promise-methods.mjs.md @@ -185,7 +185,7 @@ Generated by [AVA](https://avajs.dev). > Output `␊ - 1 | +await +1␊ + 1 | +await (+1)␊ ` > Error 1/1 @@ -365,3 +365,24 @@ Generated by [AVA](https://avajs.dev). Suggestion 2/2: Wrap the value with \`Promise.resolve()\`.␊ 1 | Promise.resolve((0, promise)).then()␊ ` + +## invalid(17): await Promise.all([x ** y]) + +> Input + + `␊ + 1 | await Promise.all([x ** y])␊ + ` + +> Output + + `␊ + 1 | await (x ** y)␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.all([x ** y])␊ + | ^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ` 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 513b7fdfc243688354f328d3c1237b33a7f2ec9f..311e0f18c69ac092e2dfa6047359e79aae7bc283 100644 GIT binary patch literal 1120 zcmV-m1fTmsRzV>kMjwj^00000000B!nY(Y(P!z@!9zx27ct}hf+9K?hrnyO~n3GCKWB-+T?!s z_;)^k_ulw*dET%}H=ReT+|^x!uPC~?q#62x!qg&Y%bM=OW!qZR9iG(;Lz$_q|1qoT zj;Yn0s^vQORu>jDSG%6yo!XabUg^E5{pr380E63+8X0bA^W5O)&05{{RCxg7pc(I#07M*UgfmQm7e%)GJ3VBq-87 zNaP?ASszD&euhBbj{x18JdSgBF`pEe3z3#~W^%I>>rsSBiM92*4h8%KQaVCeyE&Mo zzKW*ST|7isOU=fKr(Cr?yVtpjs z1GBODSVtOLAM1Gfj>o#$*a&M?upSMuwzU$Egk3(jzn2;VW~cUa4@$)h!d)P`(IP9S&}l!;)syIV|WlFS$k|>%o@6=x$;8 zW?@Z!zRCiILdnl-dfbZkN`!T@m>1B~iV7O@16rEEOajbljR z09H^27)}2%qJK}&mrfiRwY7xqoMR`QYofK;q`5c@@lnNfDvSnoe^0e)+ zB!!;d`~*e)I%F^2qh7p9`E;fd7MJW%*rJmZV_u&Ubx5qRlL+Qu2;mx}f8FxsG}p3bULGMcYn_{w9Q02kd$J?};uoaiBZnk= zB$90vGCbZPo4-gD9;mP+(b3)D=x=qWKm`Zg7ZDp12;x9=Y{YbAI{g#T{1y`$F&uYv zVEAmgjpCwRwLC1^b{r0#7+c5MtXt)#LfDZ$qDP95M*M<|_?bK%hJ+$4xHJ6c-Lbge zf6jQpPsGZEI~{R&U?V}xu?VvbBC{Q(%*LW^_6gbS18FlBW3ZiJErqGu##SuWP(v+4 zjRp;cce+w<(LbxlE0H$)fo%4bv>C1Te{974_r7ghh_>EwhHSq%9;1KJT7mw4Xl&|r mrjVfa+I>jmFcMML2X6L-W^4Mm9d&nh(|-VD=O@Um9{>O%;U$Xz literal 1077 zcmV-51j_qCRzV#*a+EgttFfag>5Q3^| zRX4dL7OoxHPD?~t=!B3Ef&m0Vhz=kzASPBe{sR`o$buLVJ4)+I{OotO14-2eZ*6+t zJ^$X9@7?uvc}+8lx2#7y%vNoU-Ii2+L($ZdMCAfeHWk$-3#PHIS}dh#nzU5g`(asD zEnTTuRl~NncSvntHbN9M|2eHI_`1XVlvPJyQ3V+BAQ>oQdy+RaXsd`0YglTM@={8YJQ)!S* z)vl6Nx4gVcREyMgofVm7DP|+(l&fAeO~WKKO*!jP&N_>;F4y& zr-8@`AhNd(1^o80$R1B!${~PX_}&3Y1P^)^09F zsqX;lPr~i(lo4w2-t$j!{*yR=008U2G~hNS?tn+BoAL4n@P8V>-&;ha4)nSQtyrJ( z_dsv_d#nSE{f~9Heb-}MZ*;<1=B)ER)}~Tqfv|G`(-{=DN2HsyUjo_>aoXPfMY#W( z_wEKA0MBvYXXOI?E?UMqv#Y9JxvVtS*cHQG@T0%yy!#wrmUfs$ltY@ZIB*ou{2g~_ zMwRq)T@gOrNsq)tm!HJ7dZofFTQzh-)7b*KZZTq48QD;@IwK|3WJOzRq#W2H7`-hl z+bpcf&sCYnkjyf)jix749$WBFM3u`z)8@Hpr}3$%vrYaBNs`IjJh^ihJqw-(zRilK zqd*bMkD&7s1s4FLoWrPW7zskMxapuI z1|C29ctzbhXfNJ_Uc8FAbmk)#7wwC%PxmNFojyhC5TCEJ0Oo`bW@o)wjQ;{uzsG%4 zJLB1p^Rx|j7MS$FjZ?o1_}{qe77x=*%bHnnge>iLZdq{6KL_kdqXdXs5Q~otkUTAr zY^$K*@ebJhMWpZmg++;u-Ui25t2;R?IPkvk*q8wjlfkhO(vijZPeAiqNN9v`?CZdA z+42y@MZ0QoShVdp>Af$uF10DU%5({_BYr^-6hV#n1sL%&dN=e51z4~@{O7zef8PUV zJntubGQmy Date: Fri, 23 Feb 2024 13:20:41 +0800 Subject: [PATCH 18/34] Add `shouldAddParenthesesToAwaitExpressionArgument` --- rules/no-single-promise-in-promise-methods.js | 18 +- rules/utils/index.js | 1 + ...arentheses-to-await-expression-argument.js | 21 + test/no-single-promise-in-promise-methods.mjs | 51 +- ...o-single-promise-in-promise-methods.mjs.md | 569 ++++++++++++++++-- ...single-promise-in-promise-methods.mjs.snap | Bin 1120 -> 1612 bytes 6 files changed, 580 insertions(+), 80 deletions(-) create mode 100644 rules/utils/should-add-parentheses-to-await-expression-argument.js diff --git a/rules/no-single-promise-in-promise-methods.js b/rules/no-single-promise-in-promise-methods.js index e547ad615d..0d52dbcc02 100644 --- a/rules/no-single-promise-in-promise-methods.js +++ b/rules/no-single-promise-in-promise-methods.js @@ -4,6 +4,7 @@ const { getParenthesizedText, isParenthesized, needsSemicolon, + shouldAddParenthesesToAwaitExpressionArgument, shouldAddParenthesesToMemberExpressionObject, } = require('./utils/index.js'); @@ -51,11 +52,18 @@ const getText = ({sourceCode}, node, element, prefix = '', suffix = '') => { return needsSemicolon(previousToken, sourceCode, wrappedText) ? `;${wrappedText}` : wrappedText; }; -const unwrapValue = (context, node) => fixer => { - const [element] = node.arguments[0].elements; - const elementWithoutAwait = element.type === 'AwaitExpression' ? element.argument : element; +const unwrapAwaitedCallExpression = (callExpression, sourceCode) => fixer => { + const [promiseNode] = callExpression.arguments[0].elements; + let text = getParenthesizedText(promiseNode, sourceCode); - return fixer.replaceText(node, getText(context, node, elementWithoutAwait)); + if ( + !isParenthesized(promiseNode, sourceCode) + && shouldAddParenthesesToAwaitExpressionArgument(promiseNode) + ) { + text = `(${text})`; + } + + return fixer.replaceText(callExpression, text); }; const useValueDirectly = (context, node) => fixer => @@ -80,7 +88,7 @@ const create = context => ({ }; if (callExpression.parent.type === 'AwaitExpression') { - problem.fix = unwrapValue(context, callExpression); + problem.fix = unwrapAwaitedCallExpression(callExpression, context.sourceCode); return problem; } diff --git a/rules/utils/index.js b/rules/utils/index.js index 6239c7e5d7..54c4c55f7b 100644 --- a/rules/utils/index.js +++ b/rules/utils/index.js @@ -45,6 +45,7 @@ module.exports = { isValueNotUsable: require('./is-value-not-usable.js'), needsSemicolon: require('./needs-semicolon.js'), shouldAddParenthesesToMemberExpressionObject: require('./should-add-parentheses-to-member-expression-object.js'), + shouldAddParenthesesToAwaitExpressionArgument: require('./should-add-parentheses-to-await-expression-argument.js'), singular: require('./singular.js'), toLocation: require('./to-location.js'), getAncestor: require('./get-ancestor.js'), diff --git a/rules/utils/should-add-parentheses-to-await-expression-argument.js b/rules/utils/should-add-parentheses-to-await-expression-argument.js new file mode 100644 index 0000000000..4f958f87a8 --- /dev/null +++ b/rules/utils/should-add-parentheses-to-await-expression-argument.js @@ -0,0 +1,21 @@ +'use strict'; + +/** +Check if parentheses should be added to a `node` when it's used as `argument` of `AwaitExpression`. + +@param {Node} node - The AST node to check. +@returns {boolean} +*/ +function shouldAddParenthesesToAwaitExpressionArgument(node) { + return ( + node.type === 'SequenceExpression' + || node.type === 'YieldExpression' + || node.type === 'ArrowFunctionExpression' + || node.type === 'ConditionalExpression' + || node.type === 'AssignmentExpression' + || node.type === 'LogicalExpression' + || node.type === 'BinaryExpression' + ); +} + +module.exports = shouldAddParenthesesToAwaitExpressionArgument; diff --git a/test/no-single-promise-in-promise-methods.mjs b/test/no-single-promise-in-promise-methods.mjs index 29f878002e..c805761247 100644 --- a/test/no-single-promise-in-promise-methods.mjs +++ b/test/no-single-promise-in-promise-methods.mjs @@ -3,6 +3,47 @@ import {getTester} from './utils/test.mjs'; const {test} = getTester(import.meta); +// `await`ed +test.snapshot({ + valid: [ + ], + invalid: [ + 'await Promise.all([(0, promise)])', + 'async function * foo() {await Promise.all([yield promise])}', + 'async function * foo() {await Promise.all([yield* promise])}', + 'await Promise.all([() => promise])', + 'await Promise.all([a ? b : c])', + 'await Promise.all([x ??= y])', + 'await Promise.all([x ||= y])', + 'await Promise.all([x &&= y])', + 'await Promise.all([x |= y])', + 'await Promise.all([x ^= y])', + 'await Promise.all([x ??= y])', + 'await Promise.all([x ||= y])', + 'await Promise.all([x &&= y])', + 'await Promise.all([x | y])', + 'await Promise.all([x ^ y])', + 'await Promise.all([x & y])', + 'await Promise.all([x !== y])', + 'await Promise.all([x == y])', + 'await Promise.all([x in y])', + 'await Promise.all([x >>> y])', + 'await Promise.all([x + y])', + 'await Promise.all([x / y])', + 'await Promise.all([x ** y])', + + 'await Promise.all([promise])', + 'await Promise.all([getPromise()])', + 'await Promise.all([promises[0]])', + 'await Promise.all([await promise])', + 'await Promise.any([promise])', + 'await Promise.race([promise])', + 'await Promise.all([new Promise(() => {})])', + '+await Promise.all([+1])', + ], +}); + +// Not `await`ed test.snapshot({ valid: [ 'Promise.all([promise, anotherPromise])', @@ -26,15 +67,6 @@ test.snapshot({ 'Promise["all"]([promise])', ], invalid: [ - 'await Promise.all([promise])', - 'await Promise.all([func()])', - 'await Promise.all([promises[0]])', - 'await Promise.all([await promise])', - 'await Promise.any([promise])', - 'await Promise.race([promise])', - 'Promise.all([somethingMaybeNotPromise])', - 'await Promise.all([new Promise(() => {})])', - '+await Promise.all([+1])', outdent` foo await Promise.all([(0, promise)]) @@ -54,6 +86,5 @@ test.snapshot({ 'Promise.all([promise]).then()', 'Promise.all([1]).then()', 'Promise.all([(0, promise)]).then()', - 'await Promise.all([x ** y])', ], }); 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 f66738802b..8e57a588f1 100644 --- a/test/snapshots/no-single-promise-in-promise-methods.mjs.md +++ b/test/snapshots/no-single-promise-in-promise-methods.mjs.md @@ -4,7 +4,490 @@ The actual snapshot is saved in `no-single-promise-in-promise-methods.mjs.snap`. Generated by [AVA](https://avajs.dev). -## invalid(1): await Promise.all([promise]) +## invalid(1): await Promise.all([(0, promise)]) + +> Input + + `␊ + 1 | await Promise.all([(0, promise)])␊ + ` + +> Output + + `␊ + 1 | await (0, promise)␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.all([(0, promise)])␊ + | ^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ` + +## invalid(2): async function * foo() {await Promise.all([yield promise])} + +> Input + + `␊ + 1 | async function * foo() {await Promise.all([yield promise])}␊ + ` + +> Output + + `␊ + 1 | async function * foo() {await (yield promise)}␊ + ` + +> Error 1/1 + + `␊ + > 1 | async function * foo() {await Promise.all([yield promise])}␊ + | ^^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ` + +## invalid(3): async function * foo() {await Promise.all([yield* promise])} + +> Input + + `␊ + 1 | async function * foo() {await Promise.all([yield* promise])}␊ + ` + +> Output + + `␊ + 1 | async function * foo() {await (yield* promise)}␊ + ` + +> Error 1/1 + + `␊ + > 1 | async function * foo() {await Promise.all([yield* promise])}␊ + | ^^^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ` + +## invalid(4): await Promise.all([() => promise]) + +> Input + + `␊ + 1 | await Promise.all([() => promise])␊ + ` + +> Output + + `␊ + 1 | await (() => promise)␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.all([() => promise])␊ + | ^^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ` + +## invalid(5): await Promise.all([a ? b : c]) + +> Input + + `␊ + 1 | await Promise.all([a ? b : c])␊ + ` + +> Output + + `␊ + 1 | await (a ? b : c)␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.all([a ? b : c])␊ + | ^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ` + +## invalid(6): await Promise.all([x ??= y]) + +> Input + + `␊ + 1 | await Promise.all([x ??= y])␊ + ` + +> Output + + `␊ + 1 | await (x ??= y)␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.all([x ??= y])␊ + | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ` + +## invalid(7): await Promise.all([x ||= y]) + +> Input + + `␊ + 1 | await Promise.all([x ||= y])␊ + ` + +> Output + + `␊ + 1 | await (x ||= y)␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.all([x ||= y])␊ + | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ` + +## invalid(8): await Promise.all([x &&= y]) + +> Input + + `␊ + 1 | await Promise.all([x &&= y])␊ + ` + +> Output + + `␊ + 1 | await (x &&= y)␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.all([x &&= y])␊ + | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ` + +## invalid(9): await Promise.all([x |= y]) + +> Input + + `␊ + 1 | await Promise.all([x |= y])␊ + ` + +> Output + + `␊ + 1 | await (x |= y)␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.all([x |= y])␊ + | ^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ` + +## invalid(10): await Promise.all([x ^= y]) + +> Input + + `␊ + 1 | await Promise.all([x ^= y])␊ + ` + +> Output + + `␊ + 1 | await (x ^= y)␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.all([x ^= y])␊ + | ^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ` + +## invalid(11): await Promise.all([x ??= y]) + +> Input + + `␊ + 1 | await Promise.all([x ??= y])␊ + ` + +> Output + + `␊ + 1 | await (x ??= y)␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.all([x ??= y])␊ + | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ` + +## invalid(12): await Promise.all([x ||= y]) + +> Input + + `␊ + 1 | await Promise.all([x ||= y])␊ + ` + +> Output + + `␊ + 1 | await (x ||= y)␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.all([x ||= y])␊ + | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ` + +## invalid(13): await Promise.all([x &&= y]) + +> Input + + `␊ + 1 | await Promise.all([x &&= y])␊ + ` + +> Output + + `␊ + 1 | await (x &&= y)␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.all([x &&= y])␊ + | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ` + +## invalid(14): await Promise.all([x | y]) + +> Input + + `␊ + 1 | await Promise.all([x | y])␊ + ` + +> Output + + `␊ + 1 | await (x | y)␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.all([x | y])␊ + | ^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ` + +## invalid(15): await Promise.all([x ^ y]) + +> Input + + `␊ + 1 | await Promise.all([x ^ y])␊ + ` + +> Output + + `␊ + 1 | await (x ^ y)␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.all([x ^ y])␊ + | ^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ` + +## invalid(16): await Promise.all([x & y]) + +> Input + + `␊ + 1 | await Promise.all([x & y])␊ + ` + +> Output + + `␊ + 1 | await (x & y)␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.all([x & y])␊ + | ^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ` + +## invalid(17): await Promise.all([x !== y]) + +> Input + + `␊ + 1 | await Promise.all([x !== y])␊ + ` + +> Output + + `␊ + 1 | await (x !== y)␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.all([x !== y])␊ + | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ` + +## invalid(18): await Promise.all([x == y]) + +> Input + + `␊ + 1 | await Promise.all([x == y])␊ + ` + +> Output + + `␊ + 1 | await (x == y)␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.all([x == y])␊ + | ^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ` + +## invalid(19): await Promise.all([x in y]) + +> Input + + `␊ + 1 | await Promise.all([x in y])␊ + ` + +> Output + + `␊ + 1 | await (x in y)␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.all([x in y])␊ + | ^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ` + +## invalid(20): await Promise.all([x >>> y]) + +> Input + + `␊ + 1 | await Promise.all([x >>> y])␊ + ` + +> Output + + `␊ + 1 | await (x >>> y)␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.all([x >>> y])␊ + | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ` + +## invalid(21): await Promise.all([x + y]) + +> Input + + `␊ + 1 | await Promise.all([x + y])␊ + ` + +> Output + + `␊ + 1 | await (x + y)␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.all([x + y])␊ + | ^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ` + +## invalid(22): await Promise.all([x / y]) + +> Input + + `␊ + 1 | await Promise.all([x / y])␊ + ` + +> Output + + `␊ + 1 | await (x / y)␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.all([x / y])␊ + | ^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ` + +## invalid(23): await Promise.all([x ** y]) + +> Input + + `␊ + 1 | await Promise.all([x ** y])␊ + ` + +> Output + + `␊ + 1 | await (x ** y)␊ + ` + +> Error 1/1 + + `␊ + > 1 | await Promise.all([x ** y])␊ + | ^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ` + +## invalid(24): await Promise.all([promise]) > Input @@ -25,28 +508,28 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(2): await Promise.all([func()]) +## invalid(25): await Promise.all([getPromise()]) > Input `␊ - 1 | await Promise.all([func()])␊ + 1 | await Promise.all([getPromise()])␊ ` > Output `␊ - 1 | await func()␊ + 1 | await getPromise()␊ ` > Error 1/1 `␊ - > 1 | await Promise.all([func()])␊ - | ^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 1 | await Promise.all([getPromise()])␊ + | ^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(3): await Promise.all([promises[0]]) +## invalid(26): await Promise.all([promises[0]]) > Input @@ -67,7 +550,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(4): await Promise.all([await promise]) +## invalid(27): await Promise.all([await promise]) > Input @@ -78,7 +561,7 @@ Generated by [AVA](https://avajs.dev). > Output `␊ - 1 | await promise␊ + 1 | await await promise␊ ` > Error 1/1 @@ -88,7 +571,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(5): await Promise.any([promise]) +## invalid(28): await Promise.any([promise]) > Input @@ -109,7 +592,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^ Wrapping a single element array with \`Promise.any()\` is unnecessary.␊ ` -## invalid(6): await Promise.race([promise]) +## invalid(29): await Promise.race([promise]) > Input @@ -130,30 +613,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^ Wrapping a single element array with \`Promise.race()\` is unnecessary.␊ ` -## invalid(7): Promise.all([somethingMaybeNotPromise]) - -> Input - - `␊ - 1 | Promise.all([somethingMaybeNotPromise])␊ - ` - -> Error 1/1 - - `␊ - > 1 | Promise.all([somethingMaybeNotPromise])␊ - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 1/2: Use the value directly.␊ - 1 | somethingMaybeNotPromise␊ - ␊ - --------------------------------------------------------------------------------␊ - Suggestion 2/2: Wrap the value with \`Promise.resolve()\`.␊ - 1 | Promise.resolve(somethingMaybeNotPromise)␊ - ` - -## invalid(8): await Promise.all([new Promise(() => {})]) +## invalid(30): await Promise.all([new Promise(() => {})]) > Input @@ -174,7 +634,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(9): +await Promise.all([+1]) +## invalid(31): +await Promise.all([+1]) > Input @@ -185,7 +645,7 @@ Generated by [AVA](https://avajs.dev). > Output `␊ - 1 | +await (+1)␊ + 1 | +await +1␊ ` > Error 1/1 @@ -195,7 +655,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(10): foo await Promise.all([(0, promise)]) +## invalid(1): foo await Promise.all([(0, promise)]) > Input @@ -219,7 +679,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(11): foo Promise.all([(0, promise)]) +## invalid(2): foo Promise.all([(0, promise)]) > Input @@ -246,7 +706,7 @@ Generated by [AVA](https://avajs.dev). 2 | Promise.resolve((0, promise))␊ ` -## invalid(12): foo await Promise.all([[array][0]]) +## invalid(3): foo await Promise.all([[array][0]]) > Input @@ -270,7 +730,7 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(13): foo Promise.all([[array][0]]) +## invalid(4): foo Promise.all([[array][0]]) > Input @@ -297,7 +757,7 @@ Generated by [AVA](https://avajs.dev). 2 | Promise.resolve([array][0])␊ ` -## invalid(14): Promise.all([promise]).then() +## invalid(5): Promise.all([promise]).then() > Input @@ -320,7 +780,7 @@ Generated by [AVA](https://avajs.dev). 1 | Promise.resolve(promise).then()␊ ` -## invalid(15): Promise.all([1]).then() +## invalid(6): Promise.all([1]).then() > Input @@ -343,7 +803,7 @@ Generated by [AVA](https://avajs.dev). 1 | Promise.resolve(1).then()␊ ` -## invalid(16): Promise.all([(0, promise)]).then() +## invalid(7): Promise.all([(0, promise)]).then() > Input @@ -365,24 +825,3 @@ Generated by [AVA](https://avajs.dev). Suggestion 2/2: Wrap the value with \`Promise.resolve()\`.␊ 1 | Promise.resolve((0, promise)).then()␊ ` - -## invalid(17): await Promise.all([x ** y]) - -> Input - - `␊ - 1 | await Promise.all([x ** y])␊ - ` - -> Output - - `␊ - 1 | await (x ** y)␊ - ` - -> Error 1/1 - - `␊ - > 1 | await Promise.all([x ** y])␊ - | ^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ - ` 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 311e0f18c69ac092e2dfa6047359e79aae7bc283..14a3953f4ba138ee5a93f966bf82e92ac7d6565a 100644 GIT binary patch literal 1612 zcmV-S2DAA=RzVR^!5JJjr4}bun9q2Y|Cp4+u((ZQE6vVE86JJ8G zsv51EPErf69mP)DXuB8ofDjT$AYcUoM1?@&fH-mGh7fmz7IEZ)_PGB5N@_cP?Rm$J zCvno!-1;%^y#75;pP5Of-!!%itNylqyKqPy-7)C?yl(DlhQ2K+@+#5xG~FSuw5{v9 zP0N~LNE_0^)1-Cu4S7@6ZBuL6JCAi9f%$&)|c|sI&5ML-y z4Q-1W^d+;^aokc8DD@a96&&r3ZM@uZ27|v14!-Y`nS3>2BZLrgK%%c2c#${TTC1g- zO`;K7H=70})S%a?=@6~m*1BX*cXr6N;6(B@qT8fnnzT-BTWfdAZsYoucH3$brJ{Hu zyx@tT_C&C|W}P%TX5G;(lN3qAvLu<@U_44!r^dGTFq`tts64L%rq6p!(@((??lPEU zIng8%DD2mTqW%d){mmCupnXhk>{ZLs2QPX)SWMxABG(A70gW!FG(s`P30J@@D?>P; z7-NMyzzV;owL)=(UKq0(%AOgPkYtw0T6OR^QOPd=F^ZgMhLu>tmO!m1U^avC?0EhT z$oCm9o;s>+5Tz%c8CVTIX=;ehn7$IZ)*h$lM*tCjL1f{yvBJpn+K4 z8PQ(BXdfJi({^j5pxqxSPTOl>T4-OuXcr3NwA~shX!l2o)AkyeFzxdm?Te_l5!edA zG|RO%%K98A@^Hl2DC*k)^?Q6{CnKGat(66gbWNOeEiLKVNJ!VFfwb(CM$Yc1tK)cZ ztEbCjmbe#B*T)RkM+G@;-`7DXzCM)U%+*LlI|Vpg#qm-{t!{3FfRIBj?C{ zQWJ(;O9{C)3dpr-f{Y#-3&M~KDIpg|0l6@F$b)o7&x%j3iKnw$BSkv*M~bJj*T96+ zd9bNQ4~rP>AvV=G?3hh8&U%vK#cc5TE5AjK3MxXbp z$l?#f{H0)KJ;Ap|CIH5*j1;{`J|2~w8oE}}j*c%I*ED@FgIVslmM|Fn% zxHmAEDZwF-;Ny7vyKN*=V7vlUd;yS?B_JSl?;%u)C4vlUJq~Kcr%>`+58+ml{V8M? z|BO?o*%gm}P$T>JhtrQd{>^TxD<*36;MvydluLUNaGGP%4iy~$nuH1>M#K(^&{$}xq_$=3_EyViqv78P_ASS6+ZXWw+2{+miJY9) zfjgBX@ewS@3J><1YT=TDD$MBk0l55&M9~2nOA;IzZRD3&vB8$b3yq6_VTm6aF@jvp z-32iJj){yIj3+uS0nV$V#T-n*7ro?a~`=G-u!t~)Ez=yx)+^reE z5XXTh!+!1)d(S&{z6<}vTb7{GQOC^&|BV1>tZ=+G54?7kziSgIT zaF(RV$HrAkte?ukf0W>Ca#3rs-=d7K#B|xez-50iUB<5V|JZ{EpZ(aF5bU}!KmG^5 KoNHUpJpceG03Tcc literal 1120 zcmV-m1fTmsRzV>kMjwj^00000000B!nY(Y(P!z@!9zx27ct}hf+9K?hrnyO~n3GCKWB-+T?!s z_;)^k_ulw*dET%}H=ReT+|^x!uPC~?q#62x!qg&Y%bM=OW!qZR9iG(;Lz$_q|1qoT zj;Yn0s^vQORu>jDSG%6yo!XabUg^E5{pr380E63+8X0bA^W5O)&05{{RCxg7pc(I#07M*UgfmQm7e%)GJ3VBq-87 zNaP?ASszD&euhBbj{x18JdSgBF`pEe3z3#~W^%I>>rsSBiM92*4h8%KQaVCeyE&Mo zzKW*ST|7isOU=fKr(Cr?yVtpjs z1GBODSVtOLAM1Gfj>o#$*a&M?upSMuwzU$Egk3(jzn2;VW~cUa4@$)h!d)P`(IP9S&}l!;)syIV|WlFS$k|>%o@6=x$;8 zW?@Z!zRCiILdnl-dfbZkN`!T@m>1B~iV7O@16rEEOajbljR z09H^27)}2%qJK}&mrfiRwY7xqoMR`QYofK;q`5c@@lnNfDvSnoe^0e)+ zB!!;d`~*e)I%F^2qh7p9`E;fd7MJW%*rJmZV_u&Ubx5qRlL+Qu2;mx}f8FxsG}p3bULGMcYn_{w9Q02kd$J?};uoaiBZnk= zB$90vGCbZPo4-gD9;mP+(b3)D=x=qWKm`Zg7ZDp12;x9=Y{YbAI{g#T{1y`$F&uYv zVEAmgjpCwRwLC1^b{r0#7+c5MtXt)#LfDZ$qDP95M*M<|_?bK%hJ+$4xHJ6c-Lbge zf6jQpPsGZEI~{R&U?V}xu?VvbBC{Q(%*LW^_6gbS18FlBW3ZiJErqGu##SuWP(v+4 zjRp;cce+w<(LbxlE0H$)fo%4bv>C1Te{974_r7ghh_>EwhHSq%9;1KJT7mw4Xl&|r mrjVfa+I>jmFcMML2X6L-W^4Mm9d&nh(|-VD=O@Um9{>O%;U$Xz From 062002eeab7d86837edda9ce606514459a7b0e86 Mon Sep 17 00:00:00 2001 From: fisker Date: Fri, 23 Feb 2024 13:23:02 +0800 Subject: [PATCH 19/34] Add todo --- rules/no-single-promise-in-promise-methods.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rules/no-single-promise-in-promise-methods.js b/rules/no-single-promise-in-promise-methods.js index 0d52dbcc02..304f57468c 100644 --- a/rules/no-single-promise-in-promise-methods.js +++ b/rules/no-single-promise-in-promise-methods.js @@ -63,6 +63,8 @@ const unwrapAwaitedCallExpression = (callExpression, sourceCode) => fixer => { text = `(${text})`; } + // TODO: Check ASI + return fixer.replaceText(callExpression, text); }; From 8ed5eda7ffe891bee515970b2ceba4404b8b3b60 Mon Sep 17 00:00:00 2001 From: fisker Date: Fri, 23 Feb 2024 13:27:59 +0800 Subject: [PATCH 20/34] Fix --- rules/no-single-promise-in-promise-methods.js | 2 +- test/no-single-promise-in-promise-methods.mjs | 53 +++-- ...o-single-promise-in-promise-methods.mjs.md | 211 ++++++++++-------- ...single-promise-in-promise-methods.mjs.snap | Bin 1612 -> 1727 bytes 4 files changed, 149 insertions(+), 117 deletions(-) diff --git a/rules/no-single-promise-in-promise-methods.js b/rules/no-single-promise-in-promise-methods.js index 304f57468c..3bcfab1bb3 100644 --- a/rules/no-single-promise-in-promise-methods.js +++ b/rules/no-single-promise-in-promise-methods.js @@ -63,7 +63,7 @@ const unwrapAwaitedCallExpression = (callExpression, sourceCode) => fixer => { text = `(${text})`; } - // TODO: Check ASI + // The next node is already behind a `CallExpression`, there should be no ASI problem return fixer.replaceText(callExpression, text); }; diff --git a/test/no-single-promise-in-promise-methods.mjs b/test/no-single-promise-in-promise-methods.mjs index c805761247..598c43c422 100644 --- a/test/no-single-promise-in-promise-methods.mjs +++ b/test/no-single-promise-in-promise-methods.mjs @@ -11,35 +11,40 @@ test.snapshot({ 'await Promise.all([(0, promise)])', 'async function * foo() {await Promise.all([yield promise])}', 'async function * foo() {await Promise.all([yield* promise])}', - 'await Promise.all([() => promise])', - 'await Promise.all([a ? b : c])', - 'await Promise.all([x ??= y])', - 'await Promise.all([x ||= y])', - 'await Promise.all([x &&= y])', - 'await Promise.all([x |= y])', - 'await Promise.all([x ^= y])', - 'await Promise.all([x ??= y])', - 'await Promise.all([x ||= y])', - 'await Promise.all([x &&= y])', - 'await Promise.all([x | y])', - 'await Promise.all([x ^ y])', - 'await Promise.all([x & y])', - 'await Promise.all([x !== y])', - 'await Promise.all([x == y])', - 'await Promise.all([x in y])', - 'await Promise.all([x >>> y])', - 'await Promise.all([x + y])', - 'await Promise.all([x / y])', - 'await Promise.all([x ** y])', - - 'await Promise.all([promise])', - 'await Promise.all([getPromise()])', - 'await Promise.all([promises[0]])', + 'await Promise.all([() => promise,],)', + 'await Promise.all([a ? b : c,],)', + 'await Promise.all([x ??= y,],)', + 'await Promise.all([x ||= y,],)', + 'await Promise.all([x &&= y,],)', + 'await Promise.all([x |= y,],)', + 'await Promise.all([x ^= y,],)', + 'await Promise.all([x ??= y,],)', + 'await Promise.all([x ||= y,],)', + 'await Promise.all([x &&= y,],)', + 'await Promise.all([x | y,],)', + 'await Promise.all([x ^ y,],)', + 'await Promise.all([x & y,],)', + 'await Promise.all([x !== y,],)', + 'await Promise.all([x == y,],)', + 'await Promise.all([x in y,],)', + 'await Promise.all([x >>> y,],)', + 'await Promise.all([x + y,],)', + 'await Promise.all([x / y,],)', + 'await Promise.all([x ** y,],)', + 'await Promise.all([promise,],)', + 'await Promise.all([getPromise(),],)', + 'await Promise.all([promises[0],],)', 'await Promise.all([await promise])', 'await Promise.any([promise])', 'await Promise.race([promise])', 'await Promise.all([new Promise(() => {})])', '+await Promise.all([+1])', + + // ASI, `Promise.all()` is not really `await`ed + outdent` + await Promise.all([(x,y)]) + [0].toString() + `, ], }); 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 8e57a588f1..e29cb9ec7f 100644 --- a/test/snapshots/no-single-promise-in-promise-methods.mjs.md +++ b/test/snapshots/no-single-promise-in-promise-methods.mjs.md @@ -67,12 +67,12 @@ Generated by [AVA](https://avajs.dev). | ^^^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(4): await Promise.all([() => promise]) +## invalid(4): await Promise.all([() => promise,],) > Input `␊ - 1 | await Promise.all([() => promise])␊ + 1 | await Promise.all([() => promise,],)␊ ` > Output @@ -84,16 +84,16 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `␊ - > 1 | await Promise.all([() => promise])␊ - | ^^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 1 | await Promise.all([() => promise,],)␊ + | ^^^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(5): await Promise.all([a ? b : c]) +## invalid(5): await Promise.all([a ? b : c,],) > Input `␊ - 1 | await Promise.all([a ? b : c])␊ + 1 | await Promise.all([a ? b : c,],)␊ ` > Output @@ -105,16 +105,16 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `␊ - > 1 | await Promise.all([a ? b : c])␊ - | ^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 1 | await Promise.all([a ? b : c,],)␊ + | ^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(6): await Promise.all([x ??= y]) +## invalid(6): await Promise.all([x ??= y,],) > Input `␊ - 1 | await Promise.all([x ??= y])␊ + 1 | await Promise.all([x ??= y,],)␊ ` > Output @@ -126,16 +126,16 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `␊ - > 1 | await Promise.all([x ??= y])␊ - | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 1 | await Promise.all([x ??= y,],)␊ + | ^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(7): await Promise.all([x ||= y]) +## invalid(7): await Promise.all([x ||= y,],) > Input `␊ - 1 | await Promise.all([x ||= y])␊ + 1 | await Promise.all([x ||= y,],)␊ ` > Output @@ -147,16 +147,16 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `␊ - > 1 | await Promise.all([x ||= y])␊ - | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 1 | await Promise.all([x ||= y,],)␊ + | ^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(8): await Promise.all([x &&= y]) +## invalid(8): await Promise.all([x &&= y,],) > Input `␊ - 1 | await Promise.all([x &&= y])␊ + 1 | await Promise.all([x &&= y,],)␊ ` > Output @@ -168,16 +168,16 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `␊ - > 1 | await Promise.all([x &&= y])␊ - | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 1 | await Promise.all([x &&= y,],)␊ + | ^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(9): await Promise.all([x |= y]) +## invalid(9): await Promise.all([x |= y,],) > Input `␊ - 1 | await Promise.all([x |= y])␊ + 1 | await Promise.all([x |= y,],)␊ ` > Output @@ -189,16 +189,16 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `␊ - > 1 | await Promise.all([x |= y])␊ - | ^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 1 | await Promise.all([x |= y,],)␊ + | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(10): await Promise.all([x ^= y]) +## invalid(10): await Promise.all([x ^= y,],) > Input `␊ - 1 | await Promise.all([x ^= y])␊ + 1 | await Promise.all([x ^= y,],)␊ ` > Output @@ -210,16 +210,16 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `␊ - > 1 | await Promise.all([x ^= y])␊ - | ^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 1 | await Promise.all([x ^= y,],)␊ + | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(11): await Promise.all([x ??= y]) +## invalid(11): await Promise.all([x ??= y,],) > Input `␊ - 1 | await Promise.all([x ??= y])␊ + 1 | await Promise.all([x ??= y,],)␊ ` > Output @@ -231,16 +231,16 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `␊ - > 1 | await Promise.all([x ??= y])␊ - | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 1 | await Promise.all([x ??= y,],)␊ + | ^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(12): await Promise.all([x ||= y]) +## invalid(12): await Promise.all([x ||= y,],) > Input `␊ - 1 | await Promise.all([x ||= y])␊ + 1 | await Promise.all([x ||= y,],)␊ ` > Output @@ -252,16 +252,16 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `␊ - > 1 | await Promise.all([x ||= y])␊ - | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 1 | await Promise.all([x ||= y,],)␊ + | ^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(13): await Promise.all([x &&= y]) +## invalid(13): await Promise.all([x &&= y,],) > Input `␊ - 1 | await Promise.all([x &&= y])␊ + 1 | await Promise.all([x &&= y,],)␊ ` > Output @@ -273,16 +273,16 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `␊ - > 1 | await Promise.all([x &&= y])␊ - | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 1 | await Promise.all([x &&= y,],)␊ + | ^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(14): await Promise.all([x | y]) +## invalid(14): await Promise.all([x | y,],) > Input `␊ - 1 | await Promise.all([x | y])␊ + 1 | await Promise.all([x | y,],)␊ ` > Output @@ -294,16 +294,16 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `␊ - > 1 | await Promise.all([x | y])␊ - | ^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 1 | await Promise.all([x | y,],)␊ + | ^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(15): await Promise.all([x ^ y]) +## invalid(15): await Promise.all([x ^ y,],) > Input `␊ - 1 | await Promise.all([x ^ y])␊ + 1 | await Promise.all([x ^ y,],)␊ ` > Output @@ -315,16 +315,16 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `␊ - > 1 | await Promise.all([x ^ y])␊ - | ^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 1 | await Promise.all([x ^ y,],)␊ + | ^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(16): await Promise.all([x & y]) +## invalid(16): await Promise.all([x & y,],) > Input `␊ - 1 | await Promise.all([x & y])␊ + 1 | await Promise.all([x & y,],)␊ ` > Output @@ -336,16 +336,16 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `␊ - > 1 | await Promise.all([x & y])␊ - | ^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 1 | await Promise.all([x & y,],)␊ + | ^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(17): await Promise.all([x !== y]) +## invalid(17): await Promise.all([x !== y,],) > Input `␊ - 1 | await Promise.all([x !== y])␊ + 1 | await Promise.all([x !== y,],)␊ ` > Output @@ -357,16 +357,16 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `␊ - > 1 | await Promise.all([x !== y])␊ - | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 1 | await Promise.all([x !== y,],)␊ + | ^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(18): await Promise.all([x == y]) +## invalid(18): await Promise.all([x == y,],) > Input `␊ - 1 | await Promise.all([x == y])␊ + 1 | await Promise.all([x == y,],)␊ ` > Output @@ -378,16 +378,16 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `␊ - > 1 | await Promise.all([x == y])␊ - | ^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 1 | await Promise.all([x == y,],)␊ + | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(19): await Promise.all([x in y]) +## invalid(19): await Promise.all([x in y,],) > Input `␊ - 1 | await Promise.all([x in y])␊ + 1 | await Promise.all([x in y,],)␊ ` > Output @@ -399,16 +399,16 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `␊ - > 1 | await Promise.all([x in y])␊ - | ^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 1 | await Promise.all([x in y,],)␊ + | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(20): await Promise.all([x >>> y]) +## invalid(20): await Promise.all([x >>> y,],) > Input `␊ - 1 | await Promise.all([x >>> y])␊ + 1 | await Promise.all([x >>> y,],)␊ ` > Output @@ -420,16 +420,16 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `␊ - > 1 | await Promise.all([x >>> y])␊ - | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 1 | await Promise.all([x >>> y,],)␊ + | ^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(21): await Promise.all([x + y]) +## invalid(21): await Promise.all([x + y,],) > Input `␊ - 1 | await Promise.all([x + y])␊ + 1 | await Promise.all([x + y,],)␊ ` > Output @@ -441,16 +441,16 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `␊ - > 1 | await Promise.all([x + y])␊ - | ^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 1 | await Promise.all([x + y,],)␊ + | ^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(22): await Promise.all([x / y]) +## invalid(22): await Promise.all([x / y,],) > Input `␊ - 1 | await Promise.all([x / y])␊ + 1 | await Promise.all([x / y,],)␊ ` > Output @@ -462,16 +462,16 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `␊ - > 1 | await Promise.all([x / y])␊ - | ^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 1 | await Promise.all([x / y,],)␊ + | ^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(23): await Promise.all([x ** y]) +## invalid(23): await Promise.all([x ** y,],) > Input `␊ - 1 | await Promise.all([x ** y])␊ + 1 | await Promise.all([x ** y,],)␊ ` > Output @@ -483,16 +483,16 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `␊ - > 1 | await Promise.all([x ** y])␊ - | ^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 1 | await Promise.all([x ** y,],)␊ + | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(24): await Promise.all([promise]) +## invalid(24): await Promise.all([promise,],) > Input `␊ - 1 | await Promise.all([promise])␊ + 1 | await Promise.all([promise,],)␊ ` > Output @@ -504,16 +504,16 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `␊ - > 1 | await Promise.all([promise])␊ - | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 1 | await Promise.all([promise,],)␊ + | ^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(25): await Promise.all([getPromise()]) +## invalid(25): await Promise.all([getPromise(),],) > Input `␊ - 1 | await Promise.all([getPromise()])␊ + 1 | await Promise.all([getPromise(),],)␊ ` > Output @@ -525,16 +525,16 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `␊ - > 1 | await Promise.all([getPromise()])␊ - | ^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 1 | await Promise.all([getPromise(),],)␊ + | ^^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(26): await Promise.all([promises[0]]) +## invalid(26): await Promise.all([promises[0],],) > Input `␊ - 1 | await Promise.all([promises[0]])␊ + 1 | await Promise.all([promises[0],],)␊ ` > Output @@ -546,8 +546,8 @@ Generated by [AVA](https://avajs.dev). > Error 1/1 `␊ - > 1 | await Promise.all([promises[0]])␊ - | ^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 1 | await Promise.all([promises[0],],)␊ + | ^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(27): await Promise.all([await promise]) @@ -655,6 +655,33 @@ Generated by [AVA](https://avajs.dev). | ^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` +## 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 a 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: Wrap the value with \`Promise.resolve()\`.␊ + 1 | await Promise.resolve((x,y))␊ + 2 | [0].toString()␊ + ` + ## invalid(1): foo await Promise.all([(0, promise)]) > Input 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 14a3953f4ba138ee5a93f966bf82e92ac7d6565a..1b5bf393358782864ff44389488312d1dd594e21 100644 GIT binary patch literal 1727 zcmV;w20-~iRzVZBH)UByn@XxU}E0pc(T7@H8<1Wa&1oVapBh&w_cj$9B&{sENWUr+KpuN}v6 z(o)~r=zaY7^Zn-gzHe;bYiz4}{axes+557on5ulZsA&6=s_bM$VU0-#l47#gTl!VS zkPDKkX0|e=Jlp&4A3{}73{BcIc6HOZd4Fd|GNpG`A4)uu=pD(26Q`0wiZPLO{R^dJ zRoa$S`BiPNZCa%=pwv^Kly|f>w((lqbO(Ro9X$6@B2@|42xE+O+3-;V2Yb6E?d>UA zlS#}_w5BRES(UHKn#rVAOX{!##oT3AyeAT_FvVbPO_S@gVMwh`!D?K&)N1K1CKg3o zgqLj*$~_T`j#g)lwpKS4U1M3+(DjVKt|6DwQDk+;zL=_TeOR710MnOjrr}S433m~k zWF^o^GN7V|84P6#y_p%K_?OQk(^qo`h03qj4GT z0U2&_WPoi1kzlg;vo`(}9RDHP*jQ&B9R4yumZsr*s$l3BK%FNbdTT5W{xbmnLk@Uv z3;x(+g1$;Y?{=er?oF?t^#0iKp}Q?i8@gaaKTkTH zWWEGgEpUy_L4F35d3?y{B=Ng|_y>HO2L>LK$;A={ycPxUT6o~KNPyR71bEH?PHgs1 zCeVpeFQ3eyQ=qF&>9Qtwn#BlM z7eliyM!~u`6Re&1E|dGqY&L@Uwu^*_@7~bynu$5i^Nmhvu63g!iuRvcjQB`hZa15<(SHh8ESA^UTZYWc zU777mYFlPIN=vSrYQG)tCNycqA zi{4i*8oD0lwTl;li;flFJblvvQuMwi zLIlWGU%2X4sfxwN25_esBtE=Z0OlV)k>P{!SjUCOl}9Kn+^*@U5WH`!U_Y%@g@U;&YuHK|-?MXz zpg#Ns`0&T1wJzot;yCbl*w4CR`+8^2cY~kU(-KsA*m3jTmvn%}BFAfsz-y;5uZet@ z{Qz9{9qKaC$6v?8Ss76{GOiMR{Z#P2f5chjlGeh1ZTGK)y6i9Dvfojc;nn^hYjE$i V9~l#ZRX63we*tMo>MlD$0011AKAZpm literal 1612 zcmV-S2DAA=RzVR^!5JJjr4}bun9q2Y|Cp4+u((ZQE6vVE86JJ8G zsv51EPErf69mP)DXuB8ofDjT$AYcUoM1?@&fH-mGh7fmz7IEZ)_PGB5N@_cP?Rm$J zCvno!-1;%^y#75;pP5Of-!!%itNylqyKqPy-7)C?yl(DlhQ2K+@+#5xG~FSuw5{v9 zP0N~LNE_0^)1-Cu4S7@6ZBuL6JCAi9f%$&)|c|sI&5ML-y z4Q-1W^d+;^aokc8DD@a96&&r3ZM@uZ27|v14!-Y`nS3>2BZLrgK%%c2c#${TTC1g- zO`;K7H=70})S%a?=@6~m*1BX*cXr6N;6(B@qT8fnnzT-BTWfdAZsYoucH3$brJ{Hu zyx@tT_C&C|W}P%TX5G;(lN3qAvLu<@U_44!r^dGTFq`tts64L%rq6p!(@((??lPEU zIng8%DD2mTqW%d){mmCupnXhk>{ZLs2QPX)SWMxABG(A70gW!FG(s`P30J@@D?>P; z7-NMyzzV;owL)=(UKq0(%AOgPkYtw0T6OR^QOPd=F^ZgMhLu>tmO!m1U^avC?0EhT z$oCm9o;s>+5Tz%c8CVTIX=;ehn7$IZ)*h$lM*tCjL1f{yvBJpn+K4 z8PQ(BXdfJi({^j5pxqxSPTOl>T4-OuXcr3NwA~shX!l2o)AkyeFzxdm?Te_l5!edA zG|RO%%K98A@^Hl2DC*k)^?Q6{CnKGat(66gbWNOeEiLKVNJ!VFfwb(CM$Yc1tK)cZ ztEbCjmbe#B*T)RkM+G@;-`7DXzCM)U%+*LlI|Vpg#qm-{t!{3FfRIBj?C{ zQWJ(;O9{C)3dpr-f{Y#-3&M~KDIpg|0l6@F$b)o7&x%j3iKnw$BSkv*M~bJj*T96+ zd9bNQ4~rP>AvV=G?3hh8&U%vK#cc5TE5AjK3MxXbp z$l?#f{H0)KJ;Ap|CIH5*j1;{`J|2~w8oE}}j*c%I*ED@FgIVslmM|Fn% zxHmAEDZwF-;Ny7vyKN*=V7vlUd;yS?B_JSl?;%u)C4vlUJq~Kcr%>`+58+ml{V8M? z|BO?o*%gm}P$T>JhtrQd{>^TxD<*36;MvydluLUNaGGP%4iy~$nuH1>M#K(^&{$}xq_$=3_EyViqv78P_ASS6+ZXWw+2{+miJY9) zfjgBX@ewS@3J><1YT=TDD$MBk0l55&M9~2nOA;IzZRD3&vB8$b3yq6_VTm6aF@jvp z-32iJj){yIj3+uS0nV$V#T-n*7ro?a~`=G-u!t~)Ez=yx)+^reE z5XXTh!+!1)d(S&{z6<}vTb7{GQOC^&|BV1>tZ=+G54?7kziSgIT zaF(RV$HrAkte?ukf0W>Ca#3rs-=d7K#B|xez-50iUB<5V|JZ{EpZ(aF5bU}!KmG^5 KoNHUpJpceG03Tcc From 548f94fa36c7f5bb5397e692038fb47cb599edf7 Mon Sep 17 00:00:00 2001 From: fisker Date: Fri, 23 Feb 2024 13:30:17 +0800 Subject: [PATCH 21/34] Rename message id --- rules/no-single-promise-in-promise-methods.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/rules/no-single-promise-in-promise-methods.js b/rules/no-single-promise-in-promise-methods.js index 3bcfab1bb3..10d97c0b4d 100644 --- a/rules/no-single-promise-in-promise-methods.js +++ b/rules/no-single-promise-in-promise-methods.js @@ -9,12 +9,12 @@ const { } = require('./utils/index.js'); const MESSAGE_ID_ERROR = 'no-single-promise-in-promise-methods/error'; -const MESSAGE_ID_SUGGESTION_1 = 'no-single-promise-in-promise-methods/suggestion-1'; -const MESSAGE_ID_SUGGESTION_2 = 'no-single-promise-in-promise-methods/suggestion-2'; +const MESSAGE_ID_SUGGESTION_UNWRAP = 'no-single-promise-in-promise-methods/unwrap'; +const MESSAGE_ID_SUGGESTION_SWITCH_TO_PROMISE_RESOLVE = 'no-single-promise-in-promise-methods/use-promise-resolve'; const messages = { [MESSAGE_ID_ERROR]: 'Wrapping a single element array with `Promise.{{method}}()` is unnecessary.', - [MESSAGE_ID_SUGGESTION_1]: 'Use the value directly.', - [MESSAGE_ID_SUGGESTION_2]: 'Wrap the value with `Promise.resolve()`.', + [MESSAGE_ID_SUGGESTION_UNWRAP]: 'Use the value directly.', + [MESSAGE_ID_SUGGESTION_SWITCH_TO_PROMISE_RESOLVE]: 'Wrap the value with `Promise.resolve()`.', }; const METHODS = ['all', 'any', 'race']; @@ -96,11 +96,11 @@ const create = context => ({ problem.suggest = [ { - messageId: MESSAGE_ID_SUGGESTION_1, + messageId: MESSAGE_ID_SUGGESTION_UNWRAP, fix: useValueDirectly(context, callExpression), }, { - messageId: MESSAGE_ID_SUGGESTION_2, + messageId: MESSAGE_ID_SUGGESTION_SWITCH_TO_PROMISE_RESOLVE, fix: wrapWithPromiseResolve(context, callExpression), }, ]; From a32c16cf059ef1e9f4e71f1d28deb45fe53008bf Mon Sep 17 00:00:00 2001 From: fisker Date: Fri, 23 Feb 2024 13:44:50 +0800 Subject: [PATCH 22/34] Improve `switchToPromiseResolve` --- rules/no-single-promise-in-promise-methods.js | 63 +++++++++++++++--- test/no-single-promise-in-promise-methods.mjs | 8 +-- ...o-single-promise-in-promise-methods.mjs.md | 36 +++++----- ...single-promise-in-promise-methods.mjs.snap | Bin 1727 -> 1732 bytes 4 files changed, 76 insertions(+), 31 deletions(-) diff --git a/rules/no-single-promise-in-promise-methods.js b/rules/no-single-promise-in-promise-methods.js index 10d97c0b4d..e1b0f8a9b9 100644 --- a/rules/no-single-promise-in-promise-methods.js +++ b/rules/no-single-promise-in-promise-methods.js @@ -1,4 +1,9 @@ 'use strict'; +const { + isOpeningBracketToken, + isClosingBracketToken, + isCommaToken, +} = require('@eslint-community/eslint-utils'); const {isMethodCall} = require('./ast/index.js'); const { getParenthesizedText, @@ -6,6 +11,8 @@ const { needsSemicolon, shouldAddParenthesesToAwaitExpressionArgument, shouldAddParenthesesToMemberExpressionObject, + isOpeningParenToken, + isClosingParenToken, } = require('./utils/index.js'); const MESSAGE_ID_ERROR = 'no-single-promise-in-promise-methods/error'; @@ -44,7 +51,7 @@ const wrapText = (sourceCode, node, element, text, prefix, suffix) => { return text; }; -const getText = ({sourceCode}, node, element, prefix = '', suffix = '') => { +const getText = (sourceCode, node, element, prefix = '', suffix = '') => { const previousToken = sourceCode.getTokenBefore(node); const parenthesizedText = getParenthesizedText(element, sourceCode); const wrappedText = wrapText(sourceCode, node, element, parenthesizedText, prefix, suffix); @@ -68,14 +75,50 @@ const unwrapAwaitedCallExpression = (callExpression, sourceCode) => fixer => { return fixer.replaceText(callExpression, text); }; -const useValueDirectly = (context, node) => fixer => - fixer.replaceText(node, getText(context, node, node.arguments[0].elements[0])); - -const wrapWithPromiseResolve = (context, node) => fixer => - fixer.replaceText(node, getText(context, node, node.arguments[0].elements[0], 'Promise.resolve(', ')')); +const unwrapNonAwaitedCallExpression = (node, sourceCode) => fixer => + fixer.replaceText(node, getText(sourceCode, node, node.arguments[0].elements[0])); + +const switchToPromiseResolve = (callExpression, sourceCode) => function * (fixer) { + const methodNameNode = callExpression.callee.property; + /* + ``` + Promise.all([promise,]) + // ^^^ + ``` + */ + yield fixer.replaceText(methodNameNode, 'resolve'); + + const [arrayExpression] = callExpression.arguments; + /* + ``` + Promise.all([promise,]) + // ^ + ``` + */ + const openingBracketToken = sourceCode.getFirstToken(arrayExpression); + /* + ``` + Promise.all([promise,]) + // ^ + // ^ + ``` + */ + const [ + penultimateToken, + closingBracketToken, + ] = sourceCode.getLastTokens(arrayExpression, 2); + + yield fixer.remove(openingBracketToken); + yield fixer.remove(closingBracketToken); + + if (isCommaToken(penultimateToken)) { + yield fixer.remove(penultimateToken); + } +}; /** @param {import('eslint').Rule.RuleContext} context */ const create = context => ({ + CallExpression(callExpression) { if (!isPromiseMethodCallWithSingleElementArray(callExpression)) { return; @@ -89,19 +132,21 @@ const create = context => ({ }, }; + const {sourceCode} = context; + if (callExpression.parent.type === 'AwaitExpression') { - problem.fix = unwrapAwaitedCallExpression(callExpression, context.sourceCode); + problem.fix = unwrapAwaitedCallExpression(callExpression, sourceCode); return problem; } problem.suggest = [ { messageId: MESSAGE_ID_SUGGESTION_UNWRAP, - fix: useValueDirectly(context, callExpression), + fix: unwrapNonAwaitedCallExpression(callExpression, sourceCode), }, { messageId: MESSAGE_ID_SUGGESTION_SWITCH_TO_PROMISE_RESOLVE, - fix: wrapWithPromiseResolve(context, callExpression), + fix: switchToPromiseResolve(callExpression, sourceCode), }, ]; diff --git a/test/no-single-promise-in-promise-methods.mjs b/test/no-single-promise-in-promise-methods.mjs index 598c43c422..2fb8f9a2ca 100644 --- a/test/no-single-promise-in-promise-methods.mjs +++ b/test/no-single-promise-in-promise-methods.mjs @@ -74,19 +74,19 @@ test.snapshot({ invalid: [ outdent` foo - await Promise.all([(0, promise)]) + await Promise.all([(0, promise),],) `, outdent` foo - Promise.all([(0, promise)]) + Promise.all([(0, promise),],) `, outdent` foo - await Promise.all([[array][0]]) + await Promise.all([[array][0],],) `, outdent` foo - Promise.all([[array][0]]) + Promise.all([[array][0],],) `, 'Promise.all([promise]).then()', 'Promise.all([1]).then()', 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 e29cb9ec7f..2a7613e751 100644 --- a/test/snapshots/no-single-promise-in-promise-methods.mjs.md +++ b/test/snapshots/no-single-promise-in-promise-methods.mjs.md @@ -682,13 +682,13 @@ Generated by [AVA](https://avajs.dev). 2 | [0].toString()␊ ` -## invalid(1): foo await Promise.all([(0, promise)]) +## invalid(1): foo await Promise.all([(0, promise),],) > Input `␊ 1 | foo␊ - 2 | await Promise.all([(0, promise)])␊ + 2 | await Promise.all([(0, promise),],)␊ ` > Output @@ -702,25 +702,25 @@ Generated by [AVA](https://avajs.dev). `␊ 1 | foo␊ - > 2 | await Promise.all([(0, promise)])␊ - | ^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 2 | await Promise.all([(0, promise),],)␊ + | ^^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(2): foo Promise.all([(0, promise)]) +## invalid(2): foo Promise.all([(0, promise),],) > Input `␊ 1 | foo␊ - 2 | Promise.all([(0, promise)])␊ + 2 | Promise.all([(0, promise),],)␊ ` > Error 1/1 `␊ 1 | foo␊ - > 2 | Promise.all([(0, promise)])␊ - | ^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 2 | Promise.all([(0, promise),],)␊ + | ^^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ @@ -730,16 +730,16 @@ Generated by [AVA](https://avajs.dev). --------------------------------------------------------------------------------␊ Suggestion 2/2: Wrap the value with \`Promise.resolve()\`.␊ 1 | foo␊ - 2 | Promise.resolve((0, promise))␊ + 2 | Promise.resolve((0, promise),)␊ ` -## invalid(3): foo await Promise.all([[array][0]]) +## invalid(3): foo await Promise.all([[array][0],],) > Input `␊ 1 | foo␊ - 2 | await Promise.all([[array][0]])␊ + 2 | await Promise.all([[array][0],],)␊ ` > Output @@ -753,25 +753,25 @@ Generated by [AVA](https://avajs.dev). `␊ 1 | foo␊ - > 2 | await Promise.all([[array][0]])␊ - | ^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 2 | await Promise.all([[array][0],],)␊ + | ^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ` -## invalid(4): foo Promise.all([[array][0]]) +## invalid(4): foo Promise.all([[array][0],],) > Input `␊ 1 | foo␊ - 2 | Promise.all([[array][0]])␊ + 2 | Promise.all([[array][0],],)␊ ` > Error 1/1 `␊ 1 | foo␊ - > 2 | Promise.all([[array][0]])␊ - | ^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + > 2 | Promise.all([[array][0],],)␊ + | ^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ @@ -781,7 +781,7 @@ Generated by [AVA](https://avajs.dev). --------------------------------------------------------------------------------␊ Suggestion 2/2: Wrap the value with \`Promise.resolve()\`.␊ 1 | foo␊ - 2 | Promise.resolve([array][0])␊ + 2 | Promise.resolve([array][0],)␊ ` ## invalid(5): Promise.all([promise]).then() 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 1b5bf393358782864ff44389488312d1dd594e21..c9d6b818d0689e6c53f6a1ad1b45319614e335df 100644 GIT binary patch delta 1703 zcmV;Y23YyO4a5z9K~_N^Q*L2!b7*gLAa*kf0|44HW&voW=rc;NRR!YeG$LGN2r>9( z@7_)%=L*r2$VMNF2mk;800003?VC?*+f*FKlOcqZ3)%q?AhZWvvp7kUIPKc4Q&Z43 z0Vn=U2&yX4+|)@eJiCgWw$ZW+y8+@b2^d2ltpX+vNO0kQ$_*jzXo3?*IC12P5^Tr6 z`1gBu9LGtk`qoD8=bt~{Z@%xn*uLM`QuX?~#@%y=vZ6U z$h!W8QnD&wZON+qsKRbVJ=z-Ec&%*?27l!qeCp#wsuHjf#u)1|?@ zd%Gp=?kZZ7Nz72RrYbX8m2b$J$)r|G>acyq++o+kTeL4AR9tr1FAV;1P&cn4ZadV*Be{(ROK?OXbzXcNB<3+TmonR?FX-V?7 zB)`O00J1a<-&F-eKM(3W1<_k$aqwRN@E>u&yIb(b9uxEx3VOF21$3uM2 zf8#?Rv@kQ!FHq3a=_sH(RYE}Tj~yTSpoM8e7i{PkNvD&{7XhnzuF*Nj&w?^fdVEe2 z{~QqikZ<$Az+*DGSfYT}q5xhC54;u$@Y;+3&pE(}&Hl**I#KH7lNodh)E7^t(D1@QeZI>B(vFKYu^T;LwFp?(LbI+#!MZkM ztjVosIs(?|(5%x@uujhe>p^mpJI?3VqDXG1N{Hm{j~zd`2Q5rHxd)4Ja?43WA7L@h zWA3vUr;(4c7!OW7F5u*LQ_&&-ZWjpwyf<`w;7$Wm2JYlancQwxDwPOw#iq@H?lg-Lur7vXU5tWtaVA(h@m(hOm)UFt@og6g5#PO`u;4*9ty;(N4<e?=5MOZ~ z2PAf^f112+|HFC!>*g)=Dcu(Vw=$hLL`6&s5!9RmHPJGtGCu-k9&i$fYAs+A#gj<$ zj%2;omL zgsQ+cOVxs@Uo%^Z*37s_zsG+>l`NQItjxMYe`OH?HcmYbXeLf^o^NzYbFCWvp!0eGSfmU|8M;JP{- zifY-=)xBO?7x1~t`n-PyT#tCIyy$-AqM_@4FDc-Q`OCn^=dCUqx^6WSpePn2__AoY zf2{B87(amT!ePQyrxLimnOI{kxZlm_sTEKsJ8#wi(4q(Es0wW){{?LSN_yCiN_8SU zr=2hZ!k2(sXD(R0R&c__EghXFqWi58B2PB^%2mmq23`U#T?~>Yuq2ixB~bJQqUfLw znk3%=w|^NZNrqYrlp`_ydbxz92&Imle<7Cu$OV3e`0BEe{0A`o(dQN+#;wKe*<3pIccq$`Gq(hJRbhDuGqfbnKRz- zC-yW2mG(Mr&ix7x&{*VnZ2@@g4CXbF@3NnO%f3flCi?j6csMH~3P;9OqOYF{G48jM x$aOErTKI4A{*_Rd{S9392kJ7sn%|=Qn0U{1?MKFh?xsmU{s)sl-h^2}005RjHyHo` delta 1698 zcmV;T23`5Y4ZjV4K~_N^Q*L2!b7*gLAa*kf0{}QKIgB`>s)hp*q)S_o-F6HY~O2at9t!iaYXF++|n1ClanO#b9kslk2i!NUcu6YFxS0 zlU@NIf36{y(otk}$G(`VaD7;wHvrR@Y^LE)feCjJoMa`?Niv|YQx}T*D-iW3N7OOe zr{t!NTAV(3#rDBc2p?p*MtBowbTOn6vOZ3@1kSQLf)lbnR`?BA;pebc$VTXe37es0 zn_-zqW`V6&?90hl^GGR?iw1(lwJQaGb=8SViYZgFIQZ3K~EviP$${uLbm zA=}tkXB`~=GC-E5;d`oJ=odhpCm?!jEDruN0RBS`cy9~-*kgjeN;Pdc4sz64k;aE;DEeg>3ze8}e{ z@wF&>e?=5MOm3 z2PAf^f0}$?|HFC!>)LhnDcu(Uw=$hLL`6&s5!9RqHPJGtGT#Gb9&i$fYAs+A#gj-2 zj%2;oyP zgsQ-{O4Wj?Up8Bc*35WF-{3!@N)}8pR%YFSf3k=Gn{$r>nu$5i^Nmhvu63g!iuRvc zjQB`hZa15<(SHh8ESA^UTZYWcU777mYFlPIN=vSrYQG)tCNycqAi{4i*8oD0lwTl;liS#D80dm@z z;=;WEJUVkxGVB5;PCR|n0aEn7CPD8KFAZ>(THtyP7BxhrefN*Uj?bBmxp`~~>%$E39`<`?2P@OaqIx?=l!XU=znpV-q9 zRC?HP^WK+qfW{)nYm2~Zr!lXIe3$(IT=pI6GSSCh$HQ3}Q8+TL5`Fzt@V@VQ5-%*$0)&3uAaPPGr854q4H|58F0cl9;E;~U002$mZqyPW_ From b5d870c6c3ff0facc821a0110d431ee97ba93f0c Mon Sep 17 00:00:00 2001 From: fisker Date: Fri, 23 Feb 2024 14:02:38 +0800 Subject: [PATCH 23/34] Improve `unwrapNonAwaitedCallExpression` --- rules/no-single-promise-in-promise-methods.js | 58 ++++++++---------- test/no-single-promise-in-promise-methods.mjs | 1 + ...o-single-promise-in-promise-methods.mjs.md | 23 +++++++ ...single-promise-in-promise-methods.mjs.snap | Bin 1732 -> 1803 bytes 4 files changed, 51 insertions(+), 31 deletions(-) diff --git a/rules/no-single-promise-in-promise-methods.js b/rules/no-single-promise-in-promise-methods.js index e1b0f8a9b9..4a1b1958c2 100644 --- a/rules/no-single-promise-in-promise-methods.js +++ b/rules/no-single-promise-in-promise-methods.js @@ -1,7 +1,5 @@ 'use strict'; const { - isOpeningBracketToken, - isClosingBracketToken, isCommaToken, } = require('@eslint-community/eslint-utils'); const {isMethodCall} = require('./ast/index.js'); @@ -10,9 +8,6 @@ const { isParenthesized, needsSemicolon, shouldAddParenthesesToAwaitExpressionArgument, - shouldAddParenthesesToMemberExpressionObject, - isOpeningParenToken, - isClosingParenToken, } = require('./utils/index.js'); const MESSAGE_ID_ERROR = 'no-single-promise-in-promise-methods/error'; @@ -38,69 +33,70 @@ const isPromiseMethodCallWithSingleElementArray = node => && node.arguments[0].elements[0] !== null && node.arguments[0].elements[0].type !== 'SpreadElement'; -const wrapText = (sourceCode, node, element, text, prefix, suffix) => { - if (prefix || suffix) { - return `${prefix}${text}${suffix}`; - } +const unwrapAwaitedCallExpression = (callExpression, sourceCode) => fixer => { + const [promiseNode] = callExpression.arguments[0].elements; + let text = getParenthesizedText(promiseNode, sourceCode); - if (!isParenthesized(element, sourceCode) - && shouldAddParenthesesToMemberExpressionObject(element, sourceCode)) { - return `(${text})`; + if ( + !isParenthesized(promiseNode, sourceCode) + && shouldAddParenthesesToAwaitExpressionArgument(promiseNode) + ) { + text = `(${text})`; } - return text; -}; - -const getText = (sourceCode, node, element, prefix = '', suffix = '') => { - const previousToken = sourceCode.getTokenBefore(node); - const parenthesizedText = getParenthesizedText(element, sourceCode); - const wrappedText = wrapText(sourceCode, node, element, parenthesizedText, prefix, suffix); + // The next node is already behind a `CallExpression`, there should be no ASI problem - return needsSemicolon(previousToken, sourceCode, wrappedText) ? `;${wrappedText}` : wrappedText; + return fixer.replaceText(callExpression, text); }; -const unwrapAwaitedCallExpression = (callExpression, sourceCode) => fixer => { +const unwrapNonAwaitedCallExpression = (callExpression, sourceCode) => fixer => { const [promiseNode] = callExpression.arguments[0].elements; let text = getParenthesizedText(promiseNode, sourceCode); if ( !isParenthesized(promiseNode, sourceCode) - && shouldAddParenthesesToAwaitExpressionArgument(promiseNode) + // Since the original call expression can be anywhere, it's hard to tell if the promise + // need to be parenthesized, but it's safe to add parentheses + && !( + // Known cases that not need parentheses + promiseNode.type === 'Identifier' + || promiseNode.type === 'MemberExpression' + ) ) { text = `(${text})`; } - // The next node is already behind a `CallExpression`, there should be no ASI problem + const previousToken = sourceCode.getTokenBefore(callExpression); + if (needsSemicolon(previousToken, sourceCode, text)) { + text = `;${text}`; + } return fixer.replaceText(callExpression, text); }; -const unwrapNonAwaitedCallExpression = (node, sourceCode) => fixer => - fixer.replaceText(node, getText(sourceCode, node, node.arguments[0].elements[0])); - const switchToPromiseResolve = (callExpression, sourceCode) => function * (fixer) { - const methodNameNode = callExpression.callee.property; /* ``` Promise.all([promise,]) - // ^^^ + // ^^^ methodNameNode ``` */ + const methodNameNode = callExpression.callee.property; yield fixer.replaceText(methodNameNode, 'resolve'); const [arrayExpression] = callExpression.arguments; /* ``` Promise.all([promise,]) - // ^ + // ^ openingBracketToken ``` */ const openingBracketToken = sourceCode.getFirstToken(arrayExpression); /* ``` Promise.all([promise,]) - // ^ - // ^ + // ^ penultimateToken + // ^ closingBracketToken ``` */ const [ diff --git a/test/no-single-promise-in-promise-methods.mjs b/test/no-single-promise-in-promise-methods.mjs index 2fb8f9a2ca..1aedb78d95 100644 --- a/test/no-single-promise-in-promise-methods.mjs +++ b/test/no-single-promise-in-promise-methods.mjs @@ -91,5 +91,6 @@ test.snapshot({ 'Promise.all([promise]).then()', 'Promise.all([1]).then()', 'Promise.all([(0, promise)]).then()', + 'const _ = () => Promise.all([ a ?? b ,],)', ], }); 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 2a7613e751..5919a3d346 100644 --- a/test/snapshots/no-single-promise-in-promise-methods.mjs.md +++ b/test/snapshots/no-single-promise-in-promise-methods.mjs.md @@ -852,3 +852,26 @@ Generated by [AVA](https://avajs.dev). Suggestion 2/2: Wrap the value with \`Promise.resolve()\`.␊ 1 | Promise.resolve((0, promise)).then()␊ ` + +## invalid(8): const _ = () => Promise.all([ a ?? b ,],) + +> Input + + `␊ + 1 | const _ = () => Promise.all([ a ?? b ,],)␊ + ` + +> Error 1/1 + + `␊ + > 1 | const _ = () => Promise.all([ a ?? b ,],)␊ + | ^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Use the value directly.␊ + 1 | const _ = () => (a ?? b)␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Wrap the value with \`Promise.resolve()\`.␊ + 1 | const _ = () => Promise.resolve( a ?? b ,)␊ + ` 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 c9d6b818d0689e6c53f6a1ad1b45319614e335df..fd5b2b1176b39ba2a5acf71b8b91adba88c6c82c 100644 GIT binary patch literal 1803 zcmV+m2lV(sRzV#9ugr+)z^6@e@DKYsYb1 zw`y+vc>jL<`~UO2@9U3ywN1^azGL1I4irnZG-ZEA)puo0-4Y~mnaO*yYOz-v#&y+H z3bLjN8^Ua!?Hv9>EQ_kC%RA<_VVSoMwzgzTerxH0v4_SwpYaFB&Wwwbj7h8=EHtTT z@}{CGFY7x^%a#&=)RREUJK7#wd!=dh27l=tJn_-k{GST=us0j>&W@_r znaoU8uWJfZH08RYTTE^=QzfMbe3f`!w^Jv138tJs%Trz$&|&LetTX6OfNZ1qaOk@?lL&Y zVyJ@%K-krVrv3&@{n<5ji1I1BsZS-z9K7V@U@k%qvfLoN4m`RXF$md!BwPVUSsEY- z*?=hg4x;c&)F@@n$el5)098h~2_Gh4g zx9D$xg?D)^+E-4vE7+6;#v#!L!x{@;1S_#q#Z`&WSGr?|?<>6$j=Hb7GiQn1bLL{0IdhR`&RiTbXD$^pXOA_x(=5io zx)_;tF%H(nRIqm2cZu9zX0tK0Z$~6T`|b=KzJ0p|q^5lnTTAYp(9rEW;2tP1;P%iV zoA+RMJrlYGT_U!ab;YuO7DOEU1pq8ZgYTCb^a&yFc+`UXz=As*3w)&n`;dScMb`{s z4{9gJ+?XxnUYrN`vVmU$M`_SI(4OI_6JG%*J`VmexP^o>A}Jq;{V9NeJu?^Dhdw3D z2N7sJ1+;?O($~O=Pk7G)^p%o|uS9RbgKS#$mYW~Ugis3}pb_VMa2J4op8yXJANvHX zx1z0h{2SJWTvfQV!>oAvL=vBV`;SlYjtsnefB}dvxsL-9J62uUbADkzfOX?0`jqbT zfLn>~ID{hRg#$~I`ac?=02wbQKg0KM9FldY1gvOb~lHdMoz*EDgc^KV)&On8ngu=fK;NNoKlZWMgBSs5$(FIHFZH4`OODv0QW42tdjH^~d)$4+X^t=2= zR7t@}#!9T+CyN-cKJf^kIX1z0zR{KDMmHX!X#JBjF@GknHtTi8>^_An6-&$P4O3y( zw!(I0t*NjrwV_lkty_+FlbUZ4fJa(jsZ(GFuBXDjR;`$Zw%h5}1$?fu|K2?VZbtl3 zp7XwPQ8SF7mlW{D{3Vd%1-r_cVc5ll5XIUEzAWmO4SXHrd+=R281v|?hAuA^Ys?w% zyBQs~Li*(Nn-u`G=mR>aL+j)J0=9pR``8XjbtF8Gy2JDcUj%7QU1RY_!EG*H>*#(W zdEXi#`pHJuxiWca;02JDgkc$B148Mm2`m#R$4`BLdKnDq=d9u5QC!fctcX&*rJBR3fp9Q<{Ru&7^wxVO} zXnaS{6+yH3E6CzcG=&_8posDIi}bBUyqZ9-CB2fq5!;-%cXey_{&_*W!bf(3JfRQuYU$GF&Za zQGP6INoROb^70=R+LMvkemKG*j}*q1veEfZ*GYeP{|An0V2&0<006pmZae@0 literal 1732 zcmV;#20QsdRzVk1>)*7B3xt$G5BWh-cBUv z3el6uMjwj^00000000B+n@?=pR2;{XA%v6*+5r$Cv0pc(T7(*bf0wxYfaN)`gA?|2`6Gu34g`z$LqWO2L}TVrwXUjXnQalpG< z@W&n#^c4zvw;Kg?r%DLu{juXiAG9zt&@WKX)9EOnJ5@qJ?~ffH`k;krLl&3GmvC0M9wViOv4W z1Ugab<&zn73e*=*rqKAOP?6ZQ9B(vFKY zu^T;LwFp?(LbI+#!MZkMtjVosIs(?|(5%x@uujhe>p^mpJI?3VqDXG1N{Hm{j~zd` z2Q5rHxd)4Ja?43WA7L@hWA3vUr;(4c7!OW7F5u*LQ_&&-ZWjpwyf<`w;7$Wm2JYla zncQwxDwPOw#iZ|i zE{0}ZjDmG>CRjW1T_*RJ*=z*yZ5Ig<-@T#Z$G6kK%)~dbwdCFj4IJM-_dt0Dw}y@x z-lN_1jOiA1nb=}BWz+gQBjDgK0$@2B{BWsJpAd47MK{l;g$MFv)LZAf?s1fCSa1Vh0fB+9qANd5V zb;7N9yc^b*RF}E5gRFRlio`zs4xgXm9U6H51S1e%aUKUGcC4DbZ~w!30PE&0^eNpJ z0k<-pI7CHE3lY?u12xeys4_nSWgc)6h-xih62+59^NwV_?QRaajGTxGQ~)rU1(O<& z$#Di$I1MZ0L=^rV0ROfPpFA!18!=h1%MMs#Z<{&DcZ90IHcQolsb4c&iq_1yNWaH_ zM3pRvp!0eGSfmU|8M;JP{-ifY-=)xBO?7x1~t`n-PyT#tCI zyy$-AqM_@4FDc-Q`OCn^=dCUqx^6WSpePn2__AoYtncd>KY;JTVZv3X61csYSYs}@ z-_7W$6;LNTZ`J_Nq6g@x3T-6+1#JIHdf1Libs{{coiGE!mw;PmE?B%)aKgnc9i1nl z`>hcoPd59?Rmq*}t(y6TI37G6{1$6EMr@&1)im;DV~_6O=Ryqe#l a{Fr#pb?rySgzlzEKmG@kK;DE|K>z@U!$=GO From 86b3b4ba0012c841f512ee9aa8802ec732b40cac Mon Sep 17 00:00:00 2001 From: fisker Date: Fri, 23 Feb 2024 14:07:14 +0800 Subject: [PATCH 24/34] Update message --- rules/no-single-promise-in-promise-methods.js | 5 +- ...o-single-promise-in-promise-methods.mjs.md | 94 +++++++++--------- ...single-promise-in-promise-methods.mjs.snap | Bin 1803 -> 1815 bytes 3 files changed, 49 insertions(+), 50 deletions(-) diff --git a/rules/no-single-promise-in-promise-methods.js b/rules/no-single-promise-in-promise-methods.js index 4a1b1958c2..7da5cce89e 100644 --- a/rules/no-single-promise-in-promise-methods.js +++ b/rules/no-single-promise-in-promise-methods.js @@ -14,9 +14,9 @@ const MESSAGE_ID_ERROR = 'no-single-promise-in-promise-methods/error'; const MESSAGE_ID_SUGGESTION_UNWRAP = 'no-single-promise-in-promise-methods/unwrap'; const MESSAGE_ID_SUGGESTION_SWITCH_TO_PROMISE_RESOLVE = 'no-single-promise-in-promise-methods/use-promise-resolve'; const messages = { - [MESSAGE_ID_ERROR]: 'Wrapping a single element array with `Promise.{{method}}()` is unnecessary.', + [MESSAGE_ID_ERROR]: 'Wrapping a single element in array with `Promise.{{method}}()` is unnecessary.', [MESSAGE_ID_SUGGESTION_UNWRAP]: 'Use the value directly.', - [MESSAGE_ID_SUGGESTION_SWITCH_TO_PROMISE_RESOLVE]: 'Wrap the value with `Promise.resolve()`.', + [MESSAGE_ID_SUGGESTION_SWITCH_TO_PROMISE_RESOLVE]: 'Switch to `Promise.resolve(…)`.', }; const METHODS = ['all', 'any', 'race']; @@ -114,7 +114,6 @@ const switchToPromiseResolve = (callExpression, sourceCode) => function * (fixer /** @param {import('eslint').Rule.RuleContext} context */ const create = context => ({ - CallExpression(callExpression) { if (!isPromiseMethodCallWithSingleElementArray(callExpression)) { return; 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 5919a3d346..b830cdd9a1 100644 --- a/test/snapshots/no-single-promise-in-promise-methods.mjs.md +++ b/test/snapshots/no-single-promise-in-promise-methods.mjs.md @@ -22,7 +22,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([(0, promise)])␊ - | ^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(2): async function * foo() {await Promise.all([yield promise])} @@ -43,7 +43,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | async function * foo() {await Promise.all([yield promise])}␊ - | ^^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(3): async function * foo() {await Promise.all([yield* promise])} @@ -64,7 +64,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | async function * foo() {await Promise.all([yield* promise])}␊ - | ^^^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(4): await Promise.all([() => promise,],) @@ -85,7 +85,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([() => promise,],)␊ - | ^^^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(5): await Promise.all([a ? b : c,],) @@ -106,7 +106,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([a ? b : c,],)␊ - | ^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(6): await Promise.all([x ??= y,],) @@ -127,7 +127,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x ??= y,],)␊ - | ^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(7): await Promise.all([x ||= y,],) @@ -148,7 +148,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x ||= y,],)␊ - | ^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(8): await Promise.all([x &&= y,],) @@ -169,7 +169,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x &&= y,],)␊ - | ^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(9): await Promise.all([x |= y,],) @@ -190,7 +190,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x |= y,],)␊ - | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(10): await Promise.all([x ^= y,],) @@ -211,7 +211,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x ^= y,],)␊ - | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(11): await Promise.all([x ??= y,],) @@ -232,7 +232,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x ??= y,],)␊ - | ^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(12): await Promise.all([x ||= y,],) @@ -253,7 +253,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x ||= y,],)␊ - | ^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(13): await Promise.all([x &&= y,],) @@ -274,7 +274,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x &&= y,],)␊ - | ^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(14): await Promise.all([x | y,],) @@ -295,7 +295,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x | y,],)␊ - | ^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(15): await Promise.all([x ^ y,],) @@ -316,7 +316,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x ^ y,],)␊ - | ^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(16): await Promise.all([x & y,],) @@ -337,7 +337,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x & y,],)␊ - | ^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(17): await Promise.all([x !== y,],) @@ -358,7 +358,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x !== y,],)␊ - | ^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(18): await Promise.all([x == y,],) @@ -379,7 +379,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x == y,],)␊ - | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(19): await Promise.all([x in y,],) @@ -400,7 +400,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x in y,],)␊ - | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(20): await Promise.all([x >>> y,],) @@ -421,7 +421,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x >>> y,],)␊ - | ^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(21): await Promise.all([x + y,],) @@ -442,7 +442,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x + y,],)␊ - | ^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(22): await Promise.all([x / y,],) @@ -463,7 +463,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x / y,],)␊ - | ^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(23): await Promise.all([x ** y,],) @@ -484,7 +484,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x ** y,],)␊ - | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(24): await Promise.all([promise,],) @@ -505,7 +505,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([promise,],)␊ - | ^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(25): await Promise.all([getPromise(),],) @@ -526,7 +526,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([getPromise(),],)␊ - | ^^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(26): await Promise.all([promises[0],],) @@ -547,7 +547,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([promises[0],],)␊ - | ^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(27): await Promise.all([await promise]) @@ -568,7 +568,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([await promise])␊ - | ^^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(28): await Promise.any([promise]) @@ -589,7 +589,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.any([promise])␊ - | ^^^^^^^^^ Wrapping a single element array with \`Promise.any()\` is unnecessary.␊ + | ^^^^^^^^^ Wrapping a single element in array with \`Promise.any()\` is unnecessary.␊ ` ## invalid(29): await Promise.race([promise]) @@ -610,7 +610,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.race([promise])␊ - | ^^^^^^^^^ Wrapping a single element array with \`Promise.race()\` is unnecessary.␊ + | ^^^^^^^^^ Wrapping a single element in array with \`Promise.race()\` is unnecessary.␊ ` ## invalid(30): await Promise.all([new Promise(() => {})]) @@ -631,7 +631,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([new Promise(() => {})])␊ - | ^^^^^^^^^^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(31): +await Promise.all([+1]) @@ -652,7 +652,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | +await Promise.all([+1])␊ - | ^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(32): await Promise.all([(x,y)]) [0].toString() @@ -668,7 +668,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([(x,y)])␊ - | ^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ 2 | [0].toString()␊ ␊ --------------------------------------------------------------------------------␊ @@ -677,7 +677,7 @@ Generated by [AVA](https://avajs.dev). 2 | [0].toString()␊ ␊ --------------------------------------------------------------------------------␊ - Suggestion 2/2: Wrap the value with \`Promise.resolve()\`.␊ + Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ 1 | await Promise.resolve((x,y))␊ 2 | [0].toString()␊ ` @@ -703,7 +703,7 @@ Generated by [AVA](https://avajs.dev). `␊ 1 | foo␊ > 2 | await Promise.all([(0, promise),],)␊ - | ^^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(2): foo Promise.all([(0, promise),],) @@ -720,7 +720,7 @@ Generated by [AVA](https://avajs.dev). `␊ 1 | foo␊ > 2 | Promise.all([(0, promise),],)␊ - | ^^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ @@ -728,7 +728,7 @@ Generated by [AVA](https://avajs.dev). 2 | ;(0, promise)␊ ␊ --------------------------------------------------------------------------------␊ - Suggestion 2/2: Wrap the value with \`Promise.resolve()\`.␊ + Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ 1 | foo␊ 2 | Promise.resolve((0, promise),)␊ ` @@ -754,7 +754,7 @@ Generated by [AVA](https://avajs.dev). `␊ 1 | foo␊ > 2 | await Promise.all([[array][0],],)␊ - | ^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(4): foo Promise.all([[array][0],],) @@ -771,7 +771,7 @@ Generated by [AVA](https://avajs.dev). `␊ 1 | foo␊ > 2 | Promise.all([[array][0],],)␊ - | ^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ @@ -779,7 +779,7 @@ Generated by [AVA](https://avajs.dev). 2 | ;[array][0]␊ ␊ --------------------------------------------------------------------------------␊ - Suggestion 2/2: Wrap the value with \`Promise.resolve()\`.␊ + Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ 1 | foo␊ 2 | Promise.resolve([array][0],)␊ ` @@ -796,14 +796,14 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | Promise.all([promise]).then()␊ - | ^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ 1 | promise.then()␊ ␊ --------------------------------------------------------------------------------␊ - Suggestion 2/2: Wrap the value with \`Promise.resolve()\`.␊ + Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ 1 | Promise.resolve(promise).then()␊ ` @@ -819,14 +819,14 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | Promise.all([1]).then()␊ - | ^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ 1 | (1).then()␊ ␊ --------------------------------------------------------------------------------␊ - Suggestion 2/2: Wrap the value with \`Promise.resolve()\`.␊ + Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ 1 | Promise.resolve(1).then()␊ ` @@ -842,14 +842,14 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | Promise.all([(0, promise)]).then()␊ - | ^^^^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ 1 | (0, promise).then()␊ ␊ --------------------------------------------------------------------------------␊ - Suggestion 2/2: Wrap the value with \`Promise.resolve()\`.␊ + Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ 1 | Promise.resolve((0, promise)).then()␊ ` @@ -865,13 +865,13 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | const _ = () => Promise.all([ a ?? b ,],)␊ - | ^^^^^^^^^^^ Wrapping a single element array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ 1 | const _ = () => (a ?? b)␊ ␊ --------------------------------------------------------------------------------␊ - Suggestion 2/2: Wrap the value with \`Promise.resolve()\`.␊ + Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ 1 | const _ = () => Promise.resolve( a ?? b ,)␊ ` 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 fd5b2b1176b39ba2a5acf71b8b91adba88c6c82c..4b37f19d51826047da997e07da333be29c73cc22 100644 GIT binary patch literal 1815 zcmV+y2k7`gRzV00000000B+n@w!nWEjWW0YWOL9RLABdths@lQgN*udP#C&^7@lJ|+ZJ zl~6BrTMN&wV)r9jCn1oy0pc)edoCMohfsJp7}z>5v* zqHb#?)i9(LX|f1gcYYyPW!*N_Eql{)?6+^Mt*MUs+T1-O_m8xW(fdY@j>=;I3hYM< zjcJB@K{K@H&8=<6m6DLuqev<^+8w+8!nV^H{8e!9k*gzPi!loU0N97{Q9}p3+EBN) zbaMk#uyu38&_FY^i<;?xZi3oqs7=__olRH`o=aW@-G*(`)asgTtBq#KtzAFYXjlzU z%8KX1vz`x?mJfE*ti$@YS$A~HggmTUmL$U^;%b_@W~_PFQy|behSLF zv*;wVu}&f(VP6;f`Wy1~C*RjT%I6&Cj@po;@SGQgsRU8T3$yStvgvHXEaW4?a1Nbi zu7@z>BhqjirQzqKX~?G-hr#Dz(#yj%)1qZqSoE%_SS=D=dLB7a6m;osEy~{lQhOXX zYNSB->RZUgYocBqDkomM9)c@H&y^Y46&04?0?b35c4QVYlz2yw4&}yENa+#mhCiBi z;&bH06@e4Dj5sa~+=0C3z%1>+9xN>_K$GS_ji}{#{s9$={y5Tk7}Iyh((FG&>^~5& z50(&3et6vHIPUxVX>j*d5^!&i?Vo$6ge-AC$#Ku+(%|l^B;ej2+dubC2^rund)!a4 zd1tXtAzb6axC^MCKr#=7(#}Hv6hVJq9QN4EhZl8al4D*=gLy4E^I9s*YuRC5@R>8W z0`AVIg9cx@JE0y7_^G=y>VeFt3bUo%gMAKr1>rg&%sUVLI8u2qly(mJCkXkw;;hF6 zK1AHiUUd&@Dd4Up#$8JTcP)Fk*^Ox~1>CvBxN~XX&SeF6r;D@u(I*zt=;FRgf-c@3 z+kY4Dl#qcg-dUux8&aNo4~ujW_J~C~Pra8#dVJ_ZWX^6zbu$I#o=5`bt)cxh_X{|9 z=6-{zu$$4v#l;jFjIWZQ!L-Nr-(Wf=WT3(L6KRFrkrq;zNDGN4(n1;&X(1~UX$LpE z4=tyFyPOzzISt(9tl;)rd4=75=JP4Ea!({dD{l?$zm@w1WT}-i8&Bc4sIgml#P_G7 zn7c#!Y~;OtV>-NVuq(_4bVGC8pCy@Qe+n@x@a(&#dVSI;IG%LjCUW6pfeWEhqOBN? zA7$SUW{2wL$6lGN(srCg1oM#}1y8BhFR%l{Ni)7iW_%d^k?;$N=fx1MV0N#F1N8)6 zY%98yC@W;7^%&BM?oZz!Gd>bMP0&?JRz4V=B@nTtHJg5lC?8@ifsjU;bHg>n{ym00 zKK&r(W3!oT4HVwaHq^Q%1RiG%)Fm?X*|_`s9P)mcx6jc7^f~|eLS{c}YP;Sq+{d{t zT_zv?eHx*w@U4eYr0h_T=5eG+%8=%KkIcC#XhmFUFK zPjGp1<0(guA%&w@p`eibuOR;Kc>LMZ3O^SEXFKb&Wp=*OUa=`xWmuW4mK^K6)6mTg zDFFK|@sqEt;21y!_Pb;W50;NSfPnrxDtKnnmlg&%HK^nzj7_9`jGf=!*wF0u^Sw&B zG7qoV8aSI8?5M`J25Wjlt2;)!oZuF=*kl+Fw7^QM!1KGhQ{M!~3Uq4Cwu~K3`u)u> z<<$~BVY&a(E?t<9aEzyd?{chLR@B=M^wRze%J7U^<+^3L#l#S$x(K~I>Xwas&*MAv zIrw5EptBgeysRuYCxS11v% zWi~r~B^(34w*+nD+ldl<4~1zbD{afF?0te~P(r8TG!raIwUS9B`XnRT(IFejwObl(qgrd;oZ}mrkV(6kk>*^BbF2577}UA^5|a(>+OgJ5()IsH;+I{{|~JrU>M&x z7=uIXj{2{-ZZTVVA>c zJ05%u2>GiBayEf-c8toIB2L&3C}FqAgeei(Iy9-06gm5eQX;cd3clLJE_DU5qHo4W zE0GEN6D90dGGVk@)H?j|#zWK?opx)fC@{kw=?M# z-V%zW;+7U$kh~jpFG}V=UNYm0viJL_z#f{kcJq<$Ajwi>ISaji_FW7I_dj^-vw>Yi F002f7gRTGo literal 1803 zcmV+m2lV(sRzV#9ugr+)z^6@e@DKYsYb1 zw`y+vc>jL<`~UO2@9U3ywN1^azGL1I4irnZG-ZEA)puo0-4Y~mnaO*yYOz-v#&y+H z3bLjN8^Ua!?Hv9>EQ_kC%RA<_VVSoMwzgzTerxH0v4_SwpYaFB&Wwwbj7h8=EHtTT z@}{CGFY7x^%a#&=)RREUJK7#wd!=dh27l=tJn_-k{GST=us0j>&W@_r znaoU8uWJfZH08RYTTE^=QzfMbe3f`!w^Jv138tJs%Trz$&|&LetTX6OfNZ1qaOk@?lL&Y zVyJ@%K-krVrv3&@{n<5ji1I1BsZS-z9K7V@U@k%qvfLoN4m`RXF$md!BwPVUSsEY- z*?=hg4x;c&)F@@n$el5)098h~2_Gh4g zx9D$xg?D)^+E-4vE7+6;#v#!L!x{@;1S_#q#Z`&WSGr?|?<>6$j=Hb7GiQn1bLL{0IdhR`&RiTbXD$^pXOA_x(=5io zx)_;tF%H(nRIqm2cZu9zX0tK0Z$~6T`|b=KzJ0p|q^5lnTTAYp(9rEW;2tP1;P%iV zoA+RMJrlYGT_U!ab;YuO7DOEU1pq8ZgYTCb^a&yFc+`UXz=As*3w)&n`;dScMb`{s z4{9gJ+?XxnUYrN`vVmU$M`_SI(4OI_6JG%*J`VmexP^o>A}Jq;{V9NeJu?^Dhdw3D z2N7sJ1+;?O($~O=Pk7G)^p%o|uS9RbgKS#$mYW~Ugis3}pb_VMa2J4op8yXJANvHX zx1z0h{2SJWTvfQV!>oAvL=vBV`;SlYjtsnefB}dvxsL-9J62uUbADkzfOX?0`jqbT zfLn>~ID{hRg#$~I`ac?=02wbQKg0KM9FldY1gvOb~lHdMoz*EDgc^KV)&On8ngu=fK;NNoKlZWMgBSs5$(FIHFZH4`OODv0QW42tdjH^~d)$4+X^t=2= zR7t@}#!9T+CyN-cKJf^kIX1z0zR{KDMmHX!X#JBjF@GknHtTi8>^_An6-&$P4O3y( zw!(I0t*NjrwV_lkty_+FlbUZ4fJa(jsZ(GFuBXDjR;`$Zw%h5}1$?fu|K2?VZbtl3 zp7XwPQ8SF7mlW{D{3Vd%1-r_cVc5ll5XIUEzAWmO4SXHrd+=R281v|?hAuA^Ys?w% zyBQs~Li*(Nn-u`G=mR>aL+j)J0=9pR``8XjbtF8Gy2JDcUj%7QU1RY_!EG*H>*#(W zdEXi#`pHJuxiWca;02JDgkc$B148Mm2`m#R$4`BLdKnDq=d9u5QC!fctcX&*rJBR3fp9Q<{Ru&7^wxVO} zXnaS{6+yH3E6CzcG=&_8posDIi}bBUyqZ9-CB2fq5!;-%cXey_{&_*W!bf(3JfRQuYU$GF&Za zQGP6INoROb^70=R+LMvkemKG*j}*q1veEfZ*GYeP{|An0V2&0<006pmZae@0 From 5a1232c30cc2be72de6639f8cd8bed8d7cf31318 Mon Sep 17 00:00:00 2001 From: fisker Date: Fri, 23 Feb 2024 14:10:36 +0800 Subject: [PATCH 25/34] Stricter --- rules/no-single-promise-in-promise-methods.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rules/no-single-promise-in-promise-methods.js b/rules/no-single-promise-in-promise-methods.js index 7da5cce89e..3aba4a0b9a 100644 --- a/rules/no-single-promise-in-promise-methods.js +++ b/rules/no-single-promise-in-promise-methods.js @@ -129,7 +129,10 @@ const create = context => ({ const {sourceCode} = context; - if (callExpression.parent.type === 'AwaitExpression') { + if ( + callExpression.parent.type === 'AwaitExpression' + && callExpression.parent.argument === callExpression + ) { problem.fix = unwrapAwaitedCallExpression(callExpression, sourceCode); return problem; } From bd06124b256ad353b7669191fab4f232d66703a7 Mon Sep 17 00:00:00 2001 From: fisker Date: Fri, 23 Feb 2024 14:11:53 +0800 Subject: [PATCH 26/34] Tweak tests --- test/no-single-promise-in-promise-methods.mjs | 8 --- ...o-single-promise-in-promise-methods.mjs.md | 60 ++---------------- ...single-promise-in-promise-methods.mjs.snap | Bin 1815 -> 1732 bytes 3 files changed, 6 insertions(+), 62 deletions(-) diff --git a/test/no-single-promise-in-promise-methods.mjs b/test/no-single-promise-in-promise-methods.mjs index 1aedb78d95..67f37bb7a9 100644 --- a/test/no-single-promise-in-promise-methods.mjs +++ b/test/no-single-promise-in-promise-methods.mjs @@ -72,18 +72,10 @@ test.snapshot({ 'Promise["all"]([promise])', ], invalid: [ - outdent` - foo - await Promise.all([(0, promise),],) - `, outdent` foo Promise.all([(0, promise),],) `, - outdent` - foo - await Promise.all([[array][0],],) - `, outdent` foo Promise.all([[array][0],],) 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 b830cdd9a1..aa0810acf5 100644 --- a/test/snapshots/no-single-promise-in-promise-methods.mjs.md +++ b/test/snapshots/no-single-promise-in-promise-methods.mjs.md @@ -682,31 +682,7 @@ Generated by [AVA](https://avajs.dev). 2 | [0].toString()␊ ` -## invalid(1): foo await Promise.all([(0, promise),],) - -> Input - - `␊ - 1 | foo␊ - 2 | await Promise.all([(0, promise),],)␊ - ` - -> Output - - `␊ - 1 | foo␊ - 2 | await (0, promise)␊ - ` - -> Error 1/1 - - `␊ - 1 | foo␊ - > 2 | await Promise.all([(0, promise),],)␊ - | ^^^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ - ` - -## invalid(2): foo Promise.all([(0, promise),],) +## invalid(1): foo Promise.all([(0, promise),],) > Input @@ -733,31 +709,7 @@ Generated by [AVA](https://avajs.dev). 2 | Promise.resolve((0, promise),)␊ ` -## invalid(3): foo await Promise.all([[array][0],],) - -> Input - - `␊ - 1 | foo␊ - 2 | await Promise.all([[array][0],],)␊ - ` - -> Output - - `␊ - 1 | foo␊ - 2 | await [array][0]␊ - ` - -> Error 1/1 - - `␊ - 1 | foo␊ - > 2 | await Promise.all([[array][0],],)␊ - | ^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ - ` - -## invalid(4): foo Promise.all([[array][0],],) +## invalid(2): foo Promise.all([[array][0],],) > Input @@ -784,7 +736,7 @@ Generated by [AVA](https://avajs.dev). 2 | Promise.resolve([array][0],)␊ ` -## invalid(5): Promise.all([promise]).then() +## invalid(3): Promise.all([promise]).then() > Input @@ -807,7 +759,7 @@ Generated by [AVA](https://avajs.dev). 1 | Promise.resolve(promise).then()␊ ` -## invalid(6): Promise.all([1]).then() +## invalid(4): Promise.all([1]).then() > Input @@ -830,7 +782,7 @@ Generated by [AVA](https://avajs.dev). 1 | Promise.resolve(1).then()␊ ` -## invalid(7): Promise.all([(0, promise)]).then() +## invalid(5): Promise.all([(0, promise)]).then() > Input @@ -853,7 +805,7 @@ Generated by [AVA](https://avajs.dev). 1 | Promise.resolve((0, promise)).then()␊ ` -## invalid(8): const _ = () => Promise.all([ a ?? b ,],) +## invalid(6): const _ = () => Promise.all([ a ?? b ,],) > Input 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 4b37f19d51826047da997e07da333be29c73cc22..2c5f58465cc4b22f435f89a51a61cf0d9975005e 100644 GIT binary patch literal 1732 zcmV;#20QsdRzV)qR1TdJ+TzI5NzgHzqt^aE3;r{xTQ0tewj z8K$e7OlL0`J8j#Ml91HnNXoz3S=)HAZTA;{<6nI0=2WHrq=moE})SVs8 zXo3osW;AsMOlMb_VS{FX+G?pC*wgH7*zg}q-T=*lwqdY3vn;jMDLS=lS6VHz1xiVA zeR$6Gq1^Ss>KJusw2iv0nFi#bVVaT**Ena>(U`vFo=;W29(3qsg!Ne$Yy3m-yt|AJ zvKZ+g5)$@wv9G@&Uw`s^9ie>6aq3l@a1@?*qp%Po3OQjGUO_fpj+upANEoi5qbv;( zhFnM*?x8gN95)TQ1miINJj}a!I7hT-8CELp85ODpPM2OrjuZr4dQgk!Zyu>Vi5oRi z;P>jg$i-WtUL7bWTDzWrD+Sk;^L$rSScOekhC1JoMZ{2|9YH!gH=agHk6|~w)qE$u zLQdQeIDyNE;= zIN49f4ZeJ`p&kwRg_9liNOn|(7-{$6fWlrzxXudmPD7tTDh~(JP9gscA%9<-^@zYH zh?|&I_o0>m?pkczwIp!Y(ubQIOtT5#&c?=_O#*i|Ex7w#oSa9WT1ldddnz%ycyI0K zUA$jH3c7gzBApyaY3@T@q>HeJT%^;~hq*|P4t;{m$zfD85@7C%#9-cCIy!T&fTL&b zHJCCvj8-a@1R9K|5~IQN){fp_`X!{G!FU^KnVd-T32dbK*c)j+iH$U$mW{NJo18;S z3E(cp#$8GRcPTBny;fc(r_Wq2fmZH{#AxN+rK7iUuYfeQa$@ilev2Bpm4|$PDvG(Y zbi_tJ+&89^`v$vA44_SBJ3mV@pZ!I|EKjo^lp6LmWc(<3 zeh?F?lOJn+zRI`b0wS0TeJi+1!+wG7Th2A(TV%$^;cp4AkZ4{^&`wQoGu4~u1 zH~&6^(3R=dLn!j>P>|*f(&Wl;&G{agb4SpMsL~>~q=~hrSZt=()gt9O5|QYtUQ zs}=)$o58NCw;60{EmpVnUOD~|w$LFMkF~&Zx4^YM&8}~QZTdPjvrK)LNx#4SwY*W} zZ&=R1^hy`zBN$`!EJwpM>E|BsMZKHe6_nnRQ(wb0oic=SywpzrjZ*u^v`?}UK{6QO zadq9J&TAj?CG@CEdSV)kffrT3ZFD;G{wG`l>0IxbRSgWBZZtZ26 z{*F!doRfA>IX$5p{G;3Yu*<=;&G;YVLH;U&oXw$}o#Ew75hv^il(4(pgef7}IyR}2 z6gmBgQbMy-^gnz=UPB3D#sAPST#1{oKT*Pd&-)+4 zs+)#o!<(=Iho7aO41fx&-KWU-S9q%^l8RGWWI^uKd_PL&KW;Lki;|y9@B({m(mKdT aIz*DD$Wj)%|LnOK4DNr9ocJRJK>z@XuV2&v literal 1815 zcmV+y2k7`gRzV00000000B+n@w!nWEjWW0YWOL9RLABdths@lQgN*udP#C&^7@lJ|+ZJ zl~6BrTMN&wV)r9jCn1oy0pc)edoCMohfsJp7}z>5v* zqHb#?)i9(LX|f1gcYYyPW!*N_Eql{)?6+^Mt*MUs+T1-O_m8xW(fdY@j>=;I3hYM< zjcJB@K{K@H&8=<6m6DLuqev<^+8w+8!nV^H{8e!9k*gzPi!loU0N97{Q9}p3+EBN) zbaMk#uyu38&_FY^i<;?xZi3oqs7=__olRH`o=aW@-G*(`)asgTtBq#KtzAFYXjlzU z%8KX1vz`x?mJfE*ti$@YS$A~HggmTUmL$U^;%b_@W~_PFQy|behSLF zv*;wVu}&f(VP6;f`Wy1~C*RjT%I6&Cj@po;@SGQgsRU8T3$yStvgvHXEaW4?a1Nbi zu7@z>BhqjirQzqKX~?G-hr#Dz(#yj%)1qZqSoE%_SS=D=dLB7a6m;osEy~{lQhOXX zYNSB->RZUgYocBqDkomM9)c@H&y^Y46&04?0?b35c4QVYlz2yw4&}yENa+#mhCiBi z;&bH06@e4Dj5sa~+=0C3z%1>+9xN>_K$GS_ji}{#{s9$={y5Tk7}Iyh((FG&>^~5& z50(&3et6vHIPUxVX>j*d5^!&i?Vo$6ge-AC$#Ku+(%|l^B;ej2+dubC2^rund)!a4 zd1tXtAzb6axC^MCKr#=7(#}Hv6hVJq9QN4EhZl8al4D*=gLy4E^I9s*YuRC5@R>8W z0`AVIg9cx@JE0y7_^G=y>VeFt3bUo%gMAKr1>rg&%sUVLI8u2qly(mJCkXkw;;hF6 zK1AHiUUd&@Dd4Up#$8JTcP)Fk*^Ox~1>CvBxN~XX&SeF6r;D@u(I*zt=;FRgf-c@3 z+kY4Dl#qcg-dUux8&aNo4~ujW_J~C~Pra8#dVJ_ZWX^6zbu$I#o=5`bt)cxh_X{|9 z=6-{zu$$4v#l;jFjIWZQ!L-Nr-(Wf=WT3(L6KRFrkrq;zNDGN4(n1;&X(1~UX$LpE z4=tyFyPOzzISt(9tl;)rd4=75=JP4Ea!({dD{l?$zm@w1WT}-i8&Bc4sIgml#P_G7 zn7c#!Y~;OtV>-NVuq(_4bVGC8pCy@Qe+n@x@a(&#dVSI;IG%LjCUW6pfeWEhqOBN? zA7$SUW{2wL$6lGN(srCg1oM#}1y8BhFR%l{Ni)7iW_%d^k?;$N=fx1MV0N#F1N8)6 zY%98yC@W;7^%&BM?oZz!Gd>bMP0&?JRz4V=B@nTtHJg5lC?8@ifsjU;bHg>n{ym00 zKK&r(W3!oT4HVwaHq^Q%1RiG%)Fm?X*|_`s9P)mcx6jc7^f~|eLS{c}YP;Sq+{d{t zT_zv?eHx*w@U4eYr0h_T=5eG+%8=%KkIcC#XhmFUFK zPjGp1<0(guA%&w@p`eibuOR;Kc>LMZ3O^SEXFKb&Wp=*OUa=`xWmuW4mK^K6)6mTg zDFFK|@sqEt;21y!_Pb;W50;NSfPnrxDtKnnmlg&%HK^nzj7_9`jGf=!*wF0u^Sw&B zG7qoV8aSI8?5M`J25Wjlt2;)!oZuF=*kl+Fw7^QM!1KGhQ{M!~3Uq4Cwu~K3`u)u> z<<$~BVY&a(E?t<9aEzyd?{chLR@B=M^wRze%J7U^<+^3L#l#S$x(K~I>Xwas&*MAv zIrw5EptBgeysRuYCxS11v% zWi~r~B^(34w*+nD+ldl<4~1zbD{afF?0te~P(r8TG!raIwUS9B`XnRT(IFejwObl(qgrd;oZ}mrkV(6kk>*^BbF2577}UA^5|a(>+OgJ5()IsH;+I{{|~JrU>M&x z7=uIXj{2{-ZZTVVA>c zJ05%u2>GiBayEf-c8toIB2L&3C}FqAgeei(Iy9-06gm5eQX;cd3clLJE_DU5qHo4W zE0GEN6D90dGGVk@)H?j|#zWK?opx)fC@{kw=?M# z-V%zW;+7U$kh~jpFG}V=UNYm0viJL_z#f{kcJq<$Ajwi>ISaji_FW7I_dj^-vw>Yi F002f7gRTGo From 72f0a135c3226e7a4300b2ac5b5a08b97dd71f25 Mon Sep 17 00:00:00 2001 From: fisker Date: Fri, 23 Feb 2024 14:13:36 +0800 Subject: [PATCH 27/34] More tests --- test/no-single-promise-in-promise-methods.mjs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/no-single-promise-in-promise-methods.mjs b/test/no-single-promise-in-promise-methods.mjs index 67f37bb7a9..b3ad1abacd 100644 --- a/test/no-single-promise-in-promise-methods.mjs +++ b/test/no-single-promise-in-promise-methods.mjs @@ -70,8 +70,12 @@ test.snapshot({ // We are not checking these cases 'globalThis.Promise.all([promise])', 'Promise["all"]([promise])', + + // This can't be checked + 'Promise.allSettled([promise])', ], invalid: [ + 'Promise.all([promise,],)', outdent` foo Promise.all([(0, promise),],) From d42c1d7beb34e877888390f4b6148b88a1be7d7a Mon Sep 17 00:00:00 2001 From: fisker Date: Fri, 23 Feb 2024 14:17:06 +0800 Subject: [PATCH 28/34] Update docs --- .../no-single-promise-in-promise-methods.md | 38 ++++++++++++++----- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/docs/rules/no-single-promise-in-promise-methods.md b/docs/rules/no-single-promise-in-promise-methods.md index 1168bbce35..398e041c40 100644 --- a/docs/rules/no-single-promise-in-promise-methods.md +++ b/docs/rules/no-single-promise-in-promise-methods.md @@ -12,23 +12,43 @@ Passing a single-element array to `Promise.all()`, `Promise.any()`, or `Promise. ## Fail ```js -Promise.all([promise]); +const foo = await Promise.all([promise]); +``` -Promise.any([promise]); +```js +const foo = await Promise.any([promise]); +``` -Promise.race([promise]); +```js +const foo = await Promise.race([promise]); ``` ## Pass ```js -Promise.all([promise, anotherPromise]); -Promise.all(notArrayLiteral); -Promise.all([...promises]); +const foo = await Promise.all([promise, anotherPromise]); +``` -Promise.any([promise, anotherPromise]); +```js +const foo = await Promise.all(notArrayLiteral); +``` -Promise.race([promise, anotherPromise]); +```js +const foo = await Promise.all([...promises]); +``` -Promise.allSettled([promise]); +```js +const foo = await Promise.any([promise, anotherPromise]); +``` + +```js +const foo = await Promise.race([promise, anotherPromise]); +``` + +```js +const [{value: foo, reason: error}] = await Promise.allSettled([promise]); +``` + +```js +const foo = await Promise.resolve(promise); ``` From 04bf100cf858ce2bbb42e898df507d306126bb2d Mon Sep 17 00:00:00 2001 From: fisker Date: Fri, 23 Feb 2024 14:23:01 +0800 Subject: [PATCH 29/34] More tests --- test/no-single-promise-in-promise-methods.mjs | 8 + ...o-single-promise-in-promise-methods.mjs.md | 219 +++++++++++++++++- ...single-promise-in-promise-methods.mjs.snap | Bin 1732 -> 2130 bytes 3 files changed, 221 insertions(+), 6 deletions(-) diff --git a/test/no-single-promise-in-promise-methods.mjs b/test/no-single-promise-in-promise-methods.mjs index b3ad1abacd..d98b704421 100644 --- a/test/no-single-promise-in-promise-methods.mjs +++ b/test/no-single-promise-in-promise-methods.mjs @@ -88,5 +88,13 @@ test.snapshot({ 'Promise.all([1]).then()', 'Promise.all([(0, promise)]).then()', 'const _ = () => Promise.all([ a ?? b ,],)', + 'Promise.all([ {a} = 1 ,],)', + 'Promise.all([ function () {} ,],)', + 'Promise.all([ class {} ,],)', + 'Promise.all([ new Foo ,],).then()', + 'Promise.all([ new Foo ,],).toString', + 'foo(Promise.all([promise]))', + 'Promise.all([promise]).foo = 1', + 'Promise.all([promise])[0] ||= 1', ], }); 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 aa0810acf5..ca908f8a5a 100644 --- a/test/snapshots/no-single-promise-in-promise-methods.mjs.md +++ b/test/snapshots/no-single-promise-in-promise-methods.mjs.md @@ -682,7 +682,30 @@ Generated by [AVA](https://avajs.dev). 2 | [0].toString()␊ ` -## invalid(1): foo Promise.all([(0, promise),],) +## invalid(1): Promise.all([promise,],) + +> Input + + `␊ + 1 | Promise.all([promise,],)␊ + ` + +> Error 1/1 + + `␊ + > 1 | Promise.all([promise,],)␊ + | ^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Use the value directly.␊ + 1 | promise␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ + 1 | Promise.resolve(promise,)␊ + ` + +## invalid(2): foo Promise.all([(0, promise),],) > Input @@ -709,7 +732,7 @@ Generated by [AVA](https://avajs.dev). 2 | Promise.resolve((0, promise),)␊ ` -## invalid(2): foo Promise.all([[array][0],],) +## invalid(3): foo Promise.all([[array][0],],) > Input @@ -736,7 +759,7 @@ Generated by [AVA](https://avajs.dev). 2 | Promise.resolve([array][0],)␊ ` -## invalid(3): Promise.all([promise]).then() +## invalid(4): Promise.all([promise]).then() > Input @@ -759,7 +782,7 @@ Generated by [AVA](https://avajs.dev). 1 | Promise.resolve(promise).then()␊ ` -## invalid(4): Promise.all([1]).then() +## invalid(5): Promise.all([1]).then() > Input @@ -782,7 +805,7 @@ Generated by [AVA](https://avajs.dev). 1 | Promise.resolve(1).then()␊ ` -## invalid(5): Promise.all([(0, promise)]).then() +## invalid(6): Promise.all([(0, promise)]).then() > Input @@ -805,7 +828,7 @@ Generated by [AVA](https://avajs.dev). 1 | Promise.resolve((0, promise)).then()␊ ` -## invalid(6): const _ = () => Promise.all([ a ?? b ,],) +## invalid(7): const _ = () => Promise.all([ a ?? b ,],) > Input @@ -827,3 +850,187 @@ Generated by [AVA](https://avajs.dev). Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ 1 | const _ = () => Promise.resolve( a ?? b ,)␊ ` + +## invalid(8): Promise.all([ {a} = 1 ,],) + +> Input + + `␊ + 1 | Promise.all([ {a} = 1 ,],)␊ + ` + +> Error 1/1 + + `␊ + > 1 | Promise.all([ {a} = 1 ,],)␊ + | ^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Use the value directly.␊ + 1 | ({a} = 1)␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ + 1 | Promise.resolve( {a} = 1 ,)␊ + ` + +## invalid(9): Promise.all([ function () {} ,],) + +> Input + + `␊ + 1 | Promise.all([ function () {} ,],)␊ + ` + +> Error 1/1 + + `␊ + > 1 | Promise.all([ function () {} ,],)␊ + | ^^^^^^^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Use the value directly.␊ + 1 | (function () {})␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ + 1 | Promise.resolve( function () {} ,)␊ + ` + +## invalid(10): Promise.all([ class {} ,],) + +> Input + + `␊ + 1 | Promise.all([ class {} ,],)␊ + ` + +> Error 1/1 + + `␊ + > 1 | Promise.all([ class {} ,],)␊ + | ^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Use the value directly.␊ + 1 | (class {})␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ + 1 | Promise.resolve( class {} ,)␊ + ` + +## invalid(11): Promise.all([ new Foo ,],).then() + +> Input + + `␊ + 1 | Promise.all([ new Foo ,],).then()␊ + ` + +> Error 1/1 + + `␊ + > 1 | Promise.all([ new Foo ,],).then()␊ + | ^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Use the value directly.␊ + 1 | (new Foo).then()␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ + 1 | Promise.resolve( new Foo ,).then()␊ + ` + +## invalid(12): Promise.all([ new Foo ,],).toString + +> Input + + `␊ + 1 | Promise.all([ new Foo ,],).toString␊ + ` + +> Error 1/1 + + `␊ + > 1 | Promise.all([ new Foo ,],).toString␊ + | ^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Use the value directly.␊ + 1 | (new Foo).toString␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ + 1 | Promise.resolve( new Foo ,).toString␊ + ` + +## invalid(13): foo(Promise.all([promise])) + +> Input + + `␊ + 1 | foo(Promise.all([promise]))␊ + ` + +> Error 1/1 + + `␊ + > 1 | foo(Promise.all([promise]))␊ + | ^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Use the value directly.␊ + 1 | foo(promise)␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ + 1 | foo(Promise.resolve(promise))␊ + ` + +## invalid(14): Promise.all([promise]).foo = 1 + +> Input + + `␊ + 1 | Promise.all([promise]).foo = 1␊ + ` + +> Error 1/1 + + `␊ + > 1 | Promise.all([promise]).foo = 1␊ + | ^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Use the value directly.␊ + 1 | promise.foo = 1␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ + 1 | Promise.resolve(promise).foo = 1␊ + ` + +## invalid(15): Promise.all([promise])[0] ||= 1 + +> Input + + `␊ + 1 | Promise.all([promise])[0] ||= 1␊ + ` + +> Error 1/1 + + `␊ + > 1 | Promise.all([promise])[0] ||= 1␊ + | ^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Use the value directly.␊ + 1 | promise[0] ||= 1␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ + 1 | Promise.resolve(promise)[0] ||= 1␊ + ` 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 2c5f58465cc4b22f435f89a51a61cf0d9975005e..3b65455de4d622659174c60f6db7ba0a206b76f5 100644 GIT binary patch literal 2130 zcmV-Y2(9-)RzVct6;)u9$K*{{t ze&XkO?Kn>ArORzy-@jk~|Gz%3AHQ}!S~yWRYp+=63Kuk6x9i&4gl?Qt>-xN;$kR++ zRdt&^+b~b+mX=rRb!kp2j&>W-1SM_QlJyGFK; z%43WvY&~3POslIWw7T}RvAkkCQWB7Q5J>q)J7X7~S+TvrpZW)HJ2x^m6LBJpF}BWv zpDOsU7aQvGvTiIgm07y6Sl5_V*G_7N&2)pQjfUD}tGd0!j{A=#A7{G7Rt!U{X_lon znt5mL`jJM%Y%ryu@Eo4xIh0yCSWTnG7FLX!t(ykRvIWzWWOf=ko2IVS=lS_m=eEW_1eV=laFEGJ2a$lVs|$1e4dnW*n`;l#rxK?=)d8dM6h~oi3>30L7M=$& z9gfLDHUx$v;3!jFz>p20;X0t<`?xe@6U3qaJQO((`-l=Pv+@i-qw&f(Ql+OsBIAN8 z-KmA;n*(YO!$J)d@LGKdq};7easT%L*D|#KJ{8RU-9YDl z=)N-+_x?lR{o4ZX{Zj~cesI1|QNFLQC*ixR62tfQ*xr5jrjRDz4^X~mGD-OEs>JZU zJ+^n>y(y%?cbWTskmQ}TeJ`+Uw-9%M>$`x=eF54@(?0;Fza@q}vgd%<9W{YoVXQmdp+&9@uk}f>gE`~_x6gqDJ!Z%w6tq%owB_I?Aj&doi=?Z zP`NiiJ7xL%!16c5tVc9_fOZqT>KdyiV0SgP-PI)QuBOj!vN6phV0R|A-I*lp&ZNa| zuZolX=p*GMs<^8Xql&l3_Fl!kDWsr^dl%_sLrVMJ#YMWv_K=Ho+VyTO(xaO`K+nl$ zR5udvoQuTpyfw6U&)o@ZzUOX%DUr?S%*;#z1;$m0QDE9*doM8F6jD%N+=aA6cBHuk z7Sdeog*2DMLYhm@LK%yO4z4g|yi1mhuwWeP*)>lyWW-qm;LX_Fl@} z38bl%6OE^E7d3Jz57|EzVeSm=v5-AU>=My{E^4;(Z%M|zKL|X_(cX7Tb^D}| ze>|GPMUcXKf)oN%36Ekhc@*3{hz`}^$C@iv@Hh?t2eYAn3S6n%4Q$_VG>p$c81IDt zNw^b;MYep+ZhU{XYx*f1UeJ9#;5w(RXhrU2lob zS6Uly$`zT-6)Sn$JZd*|V^Q*%eMbD`D=9d}Sc$E7$RZgW+jb8y^uJNTGn1~g5a7g2 zMNeUDBH_>2(UrwT&1yg2s}xGp>;+3>_L9a5o@Gk&ox`1u7?XC4ct>5wgyLs9z& zpmt-_Cpi;AQbgWx;pdrr2)sR&9vp)hxYf@e8%<}<|E5fU&bfA2mB2j=&gLP&=7g9{ zD29^xHz4zR2$>y%AzTh4m7W8)1e3nNXd-3*yE@qNSCRAfl4f8Rk9a>T6hS%s32^we zXfgJL1pEyRd(KJoQ%(NCs06(=2d{^WwdBQ6>+f~8u%pV zq|-!OfG#(f2zO%+2Jmvf{Gj!{2O9)s_?NYW3Zbyw0I>ax!-k24-hmk|^q>W)Ca^Ot z8bk@ap9wRs)m6))8N~PZ1QIBH-vRo*!s&xDTjdUm#7{fbta;f)Xi1d7hDLiU_zBZ& zM@zOOQR*EcgcA2VAnpg8I81D-tg+6y-vYge7gJ~_QUvejio$lb=YkO8PcBA~LNWXk zV0bMGhFoszfymGN7C{l_E?RY+{SFDgryF_I6-c1){RrT@!r>Fi;N9-O83}gq?TN>F2I9YY)8t0d+CT I01Q_E0HRnd7XSbN literal 1732 zcmV;#20QsdRzV)qR1TdJ+TzI5NzgHzqt^aE3;r{xTQ0tewj z8K$e7OlL0`J8j#Ml91HnNXoz3S=)HAZTA;{<6nI0=2WHrq=moE})SVs8 zXo3osW;AsMOlMb_VS{FX+G?pC*wgH7*zg}q-T=*lwqdY3vn;jMDLS=lS6VHz1xiVA zeR$6Gq1^Ss>KJusw2iv0nFi#bVVaT**Ena>(U`vFo=;W29(3qsg!Ne$Yy3m-yt|AJ zvKZ+g5)$@wv9G@&Uw`s^9ie>6aq3l@a1@?*qp%Po3OQjGUO_fpj+upANEoi5qbv;( zhFnM*?x8gN95)TQ1miINJj}a!I7hT-8CELp85ODpPM2OrjuZr4dQgk!Zyu>Vi5oRi z;P>jg$i-WtUL7bWTDzWrD+Sk;^L$rSScOekhC1JoMZ{2|9YH!gH=agHk6|~w)qE$u zLQdQeIDyNE;= zIN49f4ZeJ`p&kwRg_9liNOn|(7-{$6fWlrzxXudmPD7tTDh~(JP9gscA%9<-^@zYH zh?|&I_o0>m?pkczwIp!Y(ubQIOtT5#&c?=_O#*i|Ex7w#oSa9WT1ldddnz%ycyI0K zUA$jH3c7gzBApyaY3@T@q>HeJT%^;~hq*|P4t;{m$zfD85@7C%#9-cCIy!T&fTL&b zHJCCvj8-a@1R9K|5~IQN){fp_`X!{G!FU^KnVd-T32dbK*c)j+iH$U$mW{NJo18;S z3E(cp#$8GRcPTBny;fc(r_Wq2fmZH{#AxN+rK7iUuYfeQa$@ilev2Bpm4|$PDvG(Y zbi_tJ+&89^`v$vA44_SBJ3mV@pZ!I|EKjo^lp6LmWc(<3 zeh?F?lOJn+zRI`b0wS0TeJi+1!+wG7Th2A(TV%$^;cp4AkZ4{^&`wQoGu4~u1 zH~&6^(3R=dLn!j>P>|*f(&Wl;&G{agb4SpMsL~>~q=~hrSZt=()gt9O5|QYtUQ zs}=)$o58NCw;60{EmpVnUOD~|w$LFMkF~&Zx4^YM&8}~QZTdPjvrK)LNx#4SwY*W} zZ&=R1^hy`zBN$`!EJwpM>E|BsMZKHe6_nnRQ(wb0oic=SywpzrjZ*u^v`?}UK{6QO zadq9J&TAj?CG@CEdSV)kffrT3ZFD;G{wG`l>0IxbRSgWBZZtZ26 z{*F!doRfA>IX$5p{G;3Yu*<=;&G;YVLH;U&oXw$}o#Ew75hv^il(4(pgef7}IyR}2 z6gmBgQbMy-^gnz=UPB3D#sAPST#1{oKT*Pd&-)+4 zs+)#o!<(=Iho7aO41fx&-KWU-S9q%^l8RGWWI^uKd_PL&KW;Lki;|y9@B({m(mKdT aIz*DD$Wj)%|LnOK4DNr9ocJRJK>z@XuV2&v From 5e82ac7c04d428231df338b3b2279b906cd746fb Mon Sep 17 00:00:00 2001 From: fisker Date: Fri, 23 Feb 2024 14:25:25 +0800 Subject: [PATCH 30/34] Update message --- rules/no-single-promise-in-promise-methods.js | 2 +- ...o-single-promise-in-promise-methods.mjs.md | 94 +++++++++--------- ...single-promise-in-promise-methods.mjs.snap | Bin 2130 -> 2121 bytes 3 files changed, 48 insertions(+), 48 deletions(-) diff --git a/rules/no-single-promise-in-promise-methods.js b/rules/no-single-promise-in-promise-methods.js index 3aba4a0b9a..cf637bc506 100644 --- a/rules/no-single-promise-in-promise-methods.js +++ b/rules/no-single-promise-in-promise-methods.js @@ -14,7 +14,7 @@ const MESSAGE_ID_ERROR = 'no-single-promise-in-promise-methods/error'; const MESSAGE_ID_SUGGESTION_UNWRAP = 'no-single-promise-in-promise-methods/unwrap'; const MESSAGE_ID_SUGGESTION_SWITCH_TO_PROMISE_RESOLVE = 'no-single-promise-in-promise-methods/use-promise-resolve'; const messages = { - [MESSAGE_ID_ERROR]: 'Wrapping a single element in array with `Promise.{{method}}()` is unnecessary.', + [MESSAGE_ID_ERROR]: 'Wrapping single-element array with `Promise.{{method}}()` is unnecessary.', [MESSAGE_ID_SUGGESTION_UNWRAP]: 'Use the value directly.', [MESSAGE_ID_SUGGESTION_SWITCH_TO_PROMISE_RESOLVE]: 'Switch to `Promise.resolve(…)`.', }; 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 ca908f8a5a..75027e8394 100644 --- a/test/snapshots/no-single-promise-in-promise-methods.mjs.md +++ b/test/snapshots/no-single-promise-in-promise-methods.mjs.md @@ -22,7 +22,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([(0, promise)])␊ - | ^^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(2): async function * foo() {await Promise.all([yield promise])} @@ -43,7 +43,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | async function * foo() {await Promise.all([yield promise])}␊ - | ^^^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(3): async function * foo() {await Promise.all([yield* promise])} @@ -64,7 +64,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | async function * foo() {await Promise.all([yield* promise])}␊ - | ^^^^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(4): await Promise.all([() => promise,],) @@ -85,7 +85,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([() => promise,],)␊ - | ^^^^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(5): await Promise.all([a ? b : c,],) @@ -106,7 +106,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([a ? b : c,],)␊ - | ^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(6): await Promise.all([x ??= y,],) @@ -127,7 +127,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x ??= y,],)␊ - | ^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(7): await Promise.all([x ||= y,],) @@ -148,7 +148,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x ||= y,],)␊ - | ^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(8): await Promise.all([x &&= y,],) @@ -169,7 +169,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x &&= y,],)␊ - | ^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(9): await Promise.all([x |= y,],) @@ -190,7 +190,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x |= y,],)␊ - | ^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(10): await Promise.all([x ^= y,],) @@ -211,7 +211,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x ^= y,],)␊ - | ^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(11): await Promise.all([x ??= y,],) @@ -232,7 +232,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x ??= y,],)␊ - | ^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(12): await Promise.all([x ||= y,],) @@ -253,7 +253,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x ||= y,],)␊ - | ^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(13): await Promise.all([x &&= y,],) @@ -274,7 +274,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x &&= y,],)␊ - | ^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(14): await Promise.all([x | y,],) @@ -295,7 +295,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x | y,],)␊ - | ^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(15): await Promise.all([x ^ y,],) @@ -316,7 +316,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x ^ y,],)␊ - | ^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(16): await Promise.all([x & y,],) @@ -337,7 +337,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x & y,],)␊ - | ^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(17): await Promise.all([x !== y,],) @@ -358,7 +358,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x !== y,],)␊ - | ^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(18): await Promise.all([x == y,],) @@ -379,7 +379,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x == y,],)␊ - | ^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(19): await Promise.all([x in y,],) @@ -400,7 +400,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x in y,],)␊ - | ^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(20): await Promise.all([x >>> y,],) @@ -421,7 +421,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x >>> y,],)␊ - | ^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(21): await Promise.all([x + y,],) @@ -442,7 +442,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x + y,],)␊ - | ^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(22): await Promise.all([x / y,],) @@ -463,7 +463,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x / y,],)␊ - | ^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(23): await Promise.all([x ** y,],) @@ -484,7 +484,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([x ** y,],)␊ - | ^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(24): await Promise.all([promise,],) @@ -505,7 +505,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([promise,],)␊ - | ^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(25): await Promise.all([getPromise(),],) @@ -526,7 +526,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([getPromise(),],)␊ - | ^^^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(26): await Promise.all([promises[0],],) @@ -547,7 +547,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([promises[0],],)␊ - | ^^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(27): await Promise.all([await promise]) @@ -568,7 +568,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([await promise])␊ - | ^^^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(28): await Promise.any([promise]) @@ -589,7 +589,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.any([promise])␊ - | ^^^^^^^^^ Wrapping a single element in array with \`Promise.any()\` is unnecessary.␊ + | ^^^^^^^^^ Wrapping single-element array with \`Promise.any()\` is unnecessary.␊ ` ## invalid(29): await Promise.race([promise]) @@ -610,7 +610,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.race([promise])␊ - | ^^^^^^^^^ Wrapping a single element in array with \`Promise.race()\` is unnecessary.␊ + | ^^^^^^^^^ Wrapping single-element array with \`Promise.race()\` is unnecessary.␊ ` ## invalid(30): await Promise.all([new Promise(() => {})]) @@ -631,7 +631,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([new Promise(() => {})])␊ - | ^^^^^^^^^^^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^^^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(31): +await Promise.all([+1]) @@ -652,7 +652,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | +await Promise.all([+1])␊ - | ^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ` ## invalid(32): await Promise.all([(x,y)]) [0].toString() @@ -668,7 +668,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | await Promise.all([(x,y)])␊ - | ^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ 2 | [0].toString()␊ ␊ --------------------------------------------------------------------------------␊ @@ -694,7 +694,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | Promise.all([promise,],)␊ - | ^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ @@ -719,7 +719,7 @@ Generated by [AVA](https://avajs.dev). `␊ 1 | foo␊ > 2 | Promise.all([(0, promise),],)␊ - | ^^^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ @@ -746,7 +746,7 @@ Generated by [AVA](https://avajs.dev). `␊ 1 | foo␊ > 2 | Promise.all([[array][0],],)␊ - | ^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ @@ -771,7 +771,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | Promise.all([promise]).then()␊ - | ^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ @@ -794,7 +794,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | Promise.all([1]).then()␊ - | ^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ @@ -817,7 +817,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | Promise.all([(0, promise)]).then()␊ - | ^^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ @@ -840,7 +840,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | const _ = () => Promise.all([ a ?? b ,],)␊ - | ^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ @@ -863,7 +863,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | Promise.all([ {a} = 1 ,],)␊ - | ^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ @@ -886,7 +886,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | Promise.all([ function () {} ,],)␊ - | ^^^^^^^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ @@ -909,7 +909,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | Promise.all([ class {} ,],)␊ - | ^^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ @@ -932,7 +932,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | Promise.all([ new Foo ,],).then()␊ - | ^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ @@ -955,7 +955,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | Promise.all([ new Foo ,],).toString␊ - | ^^^^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ @@ -978,7 +978,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | foo(Promise.all([promise]))␊ - | ^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ @@ -1001,7 +1001,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | Promise.all([promise]).foo = 1␊ - | ^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ @@ -1024,7 +1024,7 @@ Generated by [AVA](https://avajs.dev). `␊ > 1 | Promise.all([promise])[0] ||= 1␊ - | ^^^^^^^^^ Wrapping a single element in array with \`Promise.all()\` is unnecessary.␊ + | ^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ ␊ --------------------------------------------------------------------------------␊ Suggestion 1/2: Use the value directly.␊ 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 3b65455de4d622659174c60f6db7ba0a206b76f5..6365b689a33720341328279f2b962114bd49d4f0 100644 GIT binary patch literal 2121 zcmV-P2)6e@RzVf)=DrgfH+Lz-w+4HVC=$iLP!%5(j@)~X@G>ri6IUg5jT#YWPY}P z@$dKSI8N%N%WYlX*YAD5pZ?x^es(@yJXtquFI(pe7c^V9>)QH+Zk$%@`huj$(@b4c zb(=lYFi+{0mRIX_X-+DRvz41akSnro8S09)Y}(dq7Zw&&TYYirj*+`ZTA$H7M|O_N zV~iEhlf>J92t7+8O;;K=zb<<#3wrHA?%+4SKY3f>ife)o3ZwAA87C8DC zcQpPbu-J}*i%dqkhy;XPT^Q-FAkuH#NPFl$6*l#$4vvB+IR*P;P>>a3@El0!XiN;U zAsie7SDEU9gKP*0*8vFM#RVaoAPId%p~z71#w+7US)K-Aj0?(grxq4% z4yZi@D>G2Qi}NKA;CWGT4s<74eeQ1{<2;aqcpxg9WhdD*tKnfx0{bL744{Jru@5NS z4})-9;~{(mLO3S~0d^xw0R1#S%gvv}&0lA;vt`!Atv>(^%h1;QR50WB0-gJy@lIRZ z_78#WZwYMocOl&Lfml98S-!E6gypVE49nYXd$-){LP{(@L|LB6Bw@L$62tO#+ukkr zy0EpD%iQwAB;};z`+-w?g^&vj-veas4KPmn{Q>a%O)=t;?H&l=N|Ca=nuOie_;yzl zvAdcIyK}DH#K!*iwAn|`OSk9EfqTCH_QW~piBlmqsOxNla=Zkb+9RZ#_Io!_xhKFl z<@Wo)?bpSGNA!9yP7^!NbyiKl>1u4Jt4TOrO_kH+HZzle)0x;#XOeI_lLDu`icRh= zA1)_Rv0arI6}#QG_loUxVQVY4xA-Qvm$cosZ9@zc{VLQBh!qcwNjJL`OZcZC&O%r+@WtGz*GVn>a^ZJzAG3{>4cj5Px`(Pij zJ2kX5{sZS>sxzDDv$l@{*GhD)Ar!GB6ri~qXreM`E|)RQAaG>BTX*A1+- zwap=e$SGJnd0-`TtfbmwVeA45JE1~OL9IUrtbdhTPhM8|*U(Q}CtX{KeXO)T-jpjc zn=4lGwt3uc=*E)d^ZBg!K~qw2jIk2i=#WM1Ke6L3;N`!gg69-nX(6^r_=)y@Y$D;$ z*zwh+CCzF-Nvjk})9iUmWA?JfPOJ4*jVJ#7gW1J4 zGuhI))%fu>LV76c{7;?+P1A(`wU0&9q~B7(u_^{qMqH^Ib*G+sm4PEfn$1s!#+)@JE2)SEAY16B3{| z4A?p2<)cjxZ^T605pWQ+-TrrcK(vYgu?c|KE(|e64A&O`u1hFfN(ffN0F4!-P z#VGH8TZvpR35ddPD2FSdaQy+``Wb}_R|{Lr4Fz((k*A+Me{VxEJm`Oet7aOO&0b<< zcJq!Kh@Yu!w)MInzM7i_G%8NlA`7BW{s*A^heH`%l)Qz7u{sQ(c3LCdbR$i)Qt9zu zb_1lD&G=t|gXy19H(8k}1f)d(=_6Rl1PUmXR{@om(NYOj#3gbVxRadmrU|qFSZ*c} zZnYc^kmY`TK?0Y~SOsVPe~0Qgw!X3v4;OghDqQMey#cC}-!KEyy4KXki2?l)&Esf!CrC$mO;b zgM84p2!$|m(KPFvUP$ literal 2130 zcmV-Y2(9-)RzVct6;)u9$K*{{t ze&XkO?Kn>ArORzy-@jk~|Gz%3AHQ}!S~yWRYp+=63Kuk6x9i&4gl?Qt>-xN;$kR++ zRdt&^+b~b+mX=rRb!kp2j&>W-1SM_QlJyGFK; z%43WvY&~3POslIWw7T}RvAkkCQWB7Q5J>q)J7X7~S+TvrpZW)HJ2x^m6LBJpF}BWv zpDOsU7aQvGvTiIgm07y6Sl5_V*G_7N&2)pQjfUD}tGd0!j{A=#A7{G7Rt!U{X_lon znt5mL`jJM%Y%ryu@Eo4xIh0yCSWTnG7FLX!t(ykRvIWzWWOf=ko2IVS=lS_m=eEW_1eV=laFEGJ2a$lVs|$1e4dnW*n`;l#rxK?=)d8dM6h~oi3>30L7M=$& z9gfLDHUx$v;3!jFz>p20;X0t<`?xe@6U3qaJQO((`-l=Pv+@i-qw&f(Ql+OsBIAN8 z-KmA;n*(YO!$J)d@LGKdq};7easT%L*D|#KJ{8RU-9YDl z=)N-+_x?lR{o4ZX{Zj~cesI1|QNFLQC*ixR62tfQ*xr5jrjRDz4^X~mGD-OEs>JZU zJ+^n>y(y%?cbWTskmQ}TeJ`+Uw-9%M>$`x=eF54@(?0;Fza@q}vgd%<9W{YoVXQmdp+&9@uk}f>gE`~_x6gqDJ!Z%w6tq%owB_I?Aj&doi=?Z zP`NiiJ7xL%!16c5tVc9_fOZqT>KdyiV0SgP-PI)QuBOj!vN6phV0R|A-I*lp&ZNa| zuZolX=p*GMs<^8Xql&l3_Fl!kDWsr^dl%_sLrVMJ#YMWv_K=Ho+VyTO(xaO`K+nl$ zR5udvoQuTpyfw6U&)o@ZzUOX%DUr?S%*;#z1;$m0QDE9*doM8F6jD%N+=aA6cBHuk z7Sdeog*2DMLYhm@LK%yO4z4g|yi1mhuwWeP*)>lyWW-qm;LX_Fl@} z38bl%6OE^E7d3Jz57|EzVeSm=v5-AU>=My{E^4;(Z%M|zKL|X_(cX7Tb^D}| ze>|GPMUcXKf)oN%36Ekhc@*3{hz`}^$C@iv@Hh?t2eYAn3S6n%4Q$_VG>p$c81IDt zNw^b;MYep+ZhU{XYx*f1UeJ9#;5w(RXhrU2lob zS6Uly$`zT-6)Sn$JZd*|V^Q*%eMbD`D=9d}Sc$E7$RZgW+jb8y^uJNTGn1~g5a7g2 zMNeUDBH_>2(UrwT&1yg2s}xGp>;+3>_L9a5o@Gk&ox`1u7?XC4ct>5wgyLs9z& zpmt-_Cpi;AQbgWx;pdrr2)sR&9vp)hxYf@e8%<}<|E5fU&bfA2mB2j=&gLP&=7g9{ zD29^xHz4zR2$>y%AzTh4m7W8)1e3nNXd-3*yE@qNSCRAfl4f8Rk9a>T6hS%s32^we zXfgJL1pEyRd(KJoQ%(NCs06(=2d{^WwdBQ6>+f~8u%pV zq|-!OfG#(f2zO%+2Jmvf{Gj!{2O9)s_?NYW3Zbyw0I>ax!-k24-hmk|^q>W)Ca^Ot z8bk@ap9wRs)m6))8N~PZ1QIBH-vRo*!s&xDTjdUm#7{fbta;f)Xi1d7hDLiU_zBZ& zM@zOOQR*EcgcA2VAnpg8I81D-tg+6y-vYge7gJ~_QUvejio$lb=YkO8PcBA~LNWXk zV0bMGhFoszfymGN7C{l_E?RY+{SFDgryF_I6-c1){RrT@!r>Fi;N9-O83}gq?TN>F2I9YY)8t0d+CT I01Q_E0HRnd7XSbN From 5799fd3bba47aaf64a8fdac9ecb77239baf6dcc4 Mon Sep 17 00:00:00 2001 From: fisker Date: Fri, 23 Feb 2024 14:28:45 +0800 Subject: [PATCH 31/34] Update docs --- .../no-single-promise-in-promise-methods.md | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/docs/rules/no-single-promise-in-promise-methods.md b/docs/rules/no-single-promise-in-promise-methods.md index 398e041c40..c7fe1754d0 100644 --- a/docs/rules/no-single-promise-in-promise-methods.md +++ b/docs/rules/no-single-promise-in-promise-methods.md @@ -23,32 +23,28 @@ const foo = await Promise.any([promise]); const foo = await Promise.race([promise]); ``` -## Pass - ```js -const foo = await Promise.all([promise, anotherPromise]); +const promise = Promise.all([nonPromise]); ``` -```js -const foo = await Promise.all(notArrayLiteral); -``` +## Pass ```js -const foo = await Promise.all([...promises]); +const foo = await promise; ``` ```js -const foo = await Promise.any([promise, anotherPromise]); +const promise = Promise.resolve(nonPromise); ``` ```js -const foo = await Promise.race([promise, anotherPromise]); +const foo = await Promise.all(promises); ``` ```js -const [{value: foo, reason: error}] = await Promise.allSettled([promise]); +const foo = await Promise.any([promise, anotherPromise]); ``` ```js -const foo = await Promise.resolve(promise); +const [{value: foo, reason: error}] = await Promise.allSettled([promise]); ``` From ca335f698c85598bf0d4fc19401dbc5dfb427158 Mon Sep 17 00:00:00 2001 From: fisker Date: Fri, 23 Feb 2024 14:32:28 +0800 Subject: [PATCH 32/34] Loosely hole check --- rules/no-single-promise-in-promise-methods.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/no-single-promise-in-promise-methods.js b/rules/no-single-promise-in-promise-methods.js index cf637bc506..b0090f1c2a 100644 --- a/rules/no-single-promise-in-promise-methods.js +++ b/rules/no-single-promise-in-promise-methods.js @@ -30,7 +30,7 @@ const isPromiseMethodCallWithSingleElementArray = node => }) && node.arguments[0].type === 'ArrayExpression' && node.arguments[0].elements.length === 1 - && node.arguments[0].elements[0] !== null + && node.arguments[0].elements[0] && node.arguments[0].elements[0].type !== 'SpreadElement'; const unwrapAwaitedCallExpression = (callExpression, sourceCode) => fixer => { From eed65b68ef0438911ed5f2801786d9755a657f8b Mon Sep 17 00:00:00 2001 From: fisker Date: Fri, 23 Feb 2024 14:34:32 +0800 Subject: [PATCH 33/34] More tests --- test/no-single-promise-in-promise-methods.mjs | 2 + ...o-single-promise-in-promise-methods.mjs.md | 46 ++++++++++++++++++ ...single-promise-in-promise-methods.mjs.snap | Bin 2121 -> 2205 bytes 3 files changed, 48 insertions(+) diff --git a/test/no-single-promise-in-promise-methods.mjs b/test/no-single-promise-in-promise-methods.mjs index d98b704421..fe75b2e92a 100644 --- a/test/no-single-promise-in-promise-methods.mjs +++ b/test/no-single-promise-in-promise-methods.mjs @@ -96,5 +96,7 @@ test.snapshot({ 'foo(Promise.all([promise]))', 'Promise.all([promise]).foo = 1', 'Promise.all([promise])[0] ||= 1', + 'Promise.all([undefined]).then()', + 'Promise.all([null]).then()', ], }); 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 75027e8394..bdfc08a5f2 100644 --- a/test/snapshots/no-single-promise-in-promise-methods.mjs.md +++ b/test/snapshots/no-single-promise-in-promise-methods.mjs.md @@ -1034,3 +1034,49 @@ Generated by [AVA](https://avajs.dev). Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ 1 | Promise.resolve(promise)[0] ||= 1␊ ` + +## invalid(16): Promise.all([undefined]).then() + +> Input + + `␊ + 1 | Promise.all([undefined]).then()␊ + ` + +> Error 1/1 + + `␊ + > 1 | Promise.all([undefined]).then()␊ + | ^^^^^^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Use the value directly.␊ + 1 | undefined.then()␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ + 1 | Promise.resolve(undefined).then()␊ + ` + +## invalid(17): Promise.all([null]).then() + +> Input + + `␊ + 1 | Promise.all([null]).then()␊ + ` + +> Error 1/1 + + `␊ + > 1 | Promise.all([null]).then()␊ + | ^^^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Use the value directly.␊ + 1 | (null).then()␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ + 1 | Promise.resolve(null).then()␊ + ` 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 6365b689a33720341328279f2b962114bd49d4f0..0bca2d9fbddf8d216bdbcf77eacb90dd88d73560 100644 GIT binary patch literal 2205 zcmV;O2x9j^RzVDt6XJYb6*LKpZCVHN*ii7`t#|LP!%5V&YRs0|Xi;hB$CU+&F@g`RlQt z=e6Uwshcjhb@kux`~Uy?yng)Jd4K+dX4IcI&q?PMOSLp*WlYsi$(lMRNa7@umu1yr zPc)2^s;LxZO%rB?@+e!n@dL3cs-`Y4nTv*HzI1+WPPXJ{CvF+KeW?8zzIAB(usFh) z#8#t)Mifmxp=iou`cl)fr34^#50LU7Z67=Tc+>I@KJPzx+v`Ik(=i9a7-Op}{HcKt zd!`{TEvfnfGgW;-Q^picIjQItlN$}W#g@4;YrCt@o*5#_t9?cR}OrV{zNx z1-8G&vE4s}Xw&;*`2=P8>S`L6yDAAR?;P8^<=zl7V)+5e@?0(r%UzWOmUoWr-EwaT z8*91fSbmVCoOFCIaB4Rfa*pA~Aic>*#sq=DOK;&-dP3IQzYDN<@RY!d5BAE5NB;T*_&`cLJ3=LX1;x zzYW}enNN63ulwUP(Rr@0S_)3r5<6W>!|7V4oF?1MTnbL-5<8ts!|7ZGoc1a<*1Z?e6lE$`yuo9B4M#W!tuHy7XW{qB$5WNWGFDcJ3Z zB(S@EXzzBr1K3cz-HK8nTg&O`=@cr8tCFCibdK%4qIg5d$TeVv>@N!`te1tv>t!L0 z^|FwG_0n^i>?%tsI9*EYbSVv|OBrz5E!!2cm(1r=DBF%mg0kH{wD+>@4j?0Cn`k4s zJDjo0cEsK$4{rO=9*cH&yP192SgsK5?68U zU0HU1U_VTCdJTQn_CerUg|0P(B9?>%GUb=S9YA3_R47QO^=E|loT9ctio0UvWWf1w%rE2{CAl1oT4ku#WoE;(b12LrTiH= z+FV#r%+8avQmHb@o;DR`Eh_AktTh!jr#6(jrFDkmZ%9X5guUxJz)E|7N0(KrzQ`=Y zSDF>m&`v4BpD%nQ9xvjHll?25p>xp)6THj+u0(XFdWKsUy691l4PORee(ZqRMVpy! z>D*}ioNI*aP!{}8Ck>jWG5>2H^M*mcrGjHM1+XgF$>|u9 zJm?07JkQ@l;GLxGkQgSwt$F^$XfO-@H&H@h&UV78hHgtZSRMjcj`6XCVkne<0VuCU zKp7B>Kytu<^d`S4aP(zG!zlXSg~8Uls#vrZ6&<@!#G6&F2#Vkj0Kw0BtFI@-L2nSS zv*+u~Haol#3vnReFlamd@A!adB@SX^0I?kyViF&&PXSyPQMjZCtOfxnK@zhMlN5SAsnkn_zv`|SBg8;Rk5{~KI&LpLq<9GhY{ z?zn;YnapO|ulwOwb2ETO$sSs4K@`gW0F?hYP{tP}Z((7q4g#n_YlItaWQkTPJ?EF* z0BL4({#W2&`lsbJHpL_Y(lUVb0jy*K1(eDwfXYi~se~&05;+Lm3HE%m1X>6zH@y8tFesWq0lfbRV0^1(dZf0c)S2 ftU(nDvq2zCXis$$G^t>iL9+e_^@w+h@mc@??G`E7 literal 2121 zcmV-P2)6e@RzVf)=DrgfH+Lz-w+4HVC=$iLP!%5(j@)~X@G>ri6IUg5jT#YWPY}P z@$dKSI8N%N%WYlX*YAD5pZ?x^es(@yJXtquFI(pe7c^V9>)QH+Zk$%@`huj$(@b4c zb(=lYFi+{0mRIX_X-+DRvz41akSnro8S09)Y}(dq7Zw&&TYYirj*+`ZTA$H7M|O_N zV~iEhlf>J92t7+8O;;K=zb<<#3wrHA?%+4SKY3f>ife)o3ZwAA87C8DC zcQpPbu-J}*i%dqkhy;XPT^Q-FAkuH#NPFl$6*l#$4vvB+IR*P;P>>a3@El0!XiN;U zAsie7SDEU9gKP*0*8vFM#RVaoAPId%p~z71#w+7US)K-Aj0?(grxq4% z4yZi@D>G2Qi}NKA;CWGT4s<74eeQ1{<2;aqcpxg9WhdD*tKnfx0{bL744{Jru@5NS z4})-9;~{(mLO3S~0d^xw0R1#S%gvv}&0lA;vt`!Atv>(^%h1;QR50WB0-gJy@lIRZ z_78#WZwYMocOl&Lfml98S-!E6gypVE49nYXd$-){LP{(@L|LB6Bw@L$62tO#+ukkr zy0EpD%iQwAB;};z`+-w?g^&vj-veas4KPmn{Q>a%O)=t;?H&l=N|Ca=nuOie_;yzl zvAdcIyK}DH#K!*iwAn|`OSk9EfqTCH_QW~piBlmqsOxNla=Zkb+9RZ#_Io!_xhKFl z<@Wo)?bpSGNA!9yP7^!NbyiKl>1u4Jt4TOrO_kH+HZzle)0x;#XOeI_lLDu`icRh= zA1)_Rv0arI6}#QG_loUxVQVY4xA-Qvm$cosZ9@zc{VLQBh!qcwNjJL`OZcZC&O%r+@WtGz*GVn>a^ZJzAG3{>4cj5Px`(Pij zJ2kX5{sZS>sxzDDv$l@{*GhD)Ar!GB6ri~qXreM`E|)RQAaG>BTX*A1+- zwap=e$SGJnd0-`TtfbmwVeA45JE1~OL9IUrtbdhTPhM8|*U(Q}CtX{KeXO)T-jpjc zn=4lGwt3uc=*E)d^ZBg!K~qw2jIk2i=#WM1Ke6L3;N`!gg69-nX(6^r_=)y@Y$D;$ z*zwh+CCzF-Nvjk})9iUmWA?JfPOJ4*jVJ#7gW1J4 zGuhI))%fu>LV76c{7;?+P1A(`wU0&9q~B7(u_^{qMqH^Ib*G+sm4PEfn$1s!#+)@JE2)SEAY16B3{| z4A?p2<)cjxZ^T605pWQ+-TrrcK(vYgu?c|KE(|e64A&O`u1hFfN(ffN0F4!-P z#VGH8TZvpR35ddPD2FSdaQy+``Wb}_R|{Lr4Fz((k*A+Me{VxEJm`Oet7aOO&0b<< zcJq!Kh@Yu!w)MInzM7i_G%8NlA`7BW{s*A^heH`%l)Qz7u{sQ(c3LCdbR$i)Qt9zu zb_1lD&G=t|gXy19H(8k}1f)d(=_6Rl1PUmXR{@om(NYOj#3gbVxRadmrU|qFSZ*c} zZnYc^kmY`TK?0Y~SOsVPe~0Qgw!X3v4;OghDqQMey#cC}-!KEyy4KXki2?l)&Esf!CrC$mO;b zgM84p2!$|m(KPFvUP$ From c97843e5692f080252dda954153374663b2ec2cc Mon Sep 17 00:00:00 2001 From: fisker Date: Fri, 23 Feb 2024 14:35:06 +0800 Subject: [PATCH 34/34] More --- test/no-single-promise-in-promise-methods.mjs | 2 + ...o-single-promise-in-promise-methods.mjs.md | 70 +++++++++++++++--- ...single-promise-in-promise-methods.mjs.snap | Bin 2205 -> 2274 bytes 3 files changed, 60 insertions(+), 12 deletions(-) diff --git a/test/no-single-promise-in-promise-methods.mjs b/test/no-single-promise-in-promise-methods.mjs index fe75b2e92a..4e73df0926 100644 --- a/test/no-single-promise-in-promise-methods.mjs +++ b/test/no-single-promise-in-promise-methods.mjs @@ -86,6 +86,8 @@ test.snapshot({ `, 'Promise.all([promise]).then()', 'Promise.all([1]).then()', + 'Promise.all([1.]).then()', + 'Promise.all([.1]).then()', 'Promise.all([(0, promise)]).then()', 'const _ = () => Promise.all([ a ?? b ,],)', 'Promise.all([ {a} = 1 ,],)', 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 bdfc08a5f2..4433570d96 100644 --- a/test/snapshots/no-single-promise-in-promise-methods.mjs.md +++ b/test/snapshots/no-single-promise-in-promise-methods.mjs.md @@ -805,7 +805,53 @@ Generated by [AVA](https://avajs.dev). 1 | Promise.resolve(1).then()␊ ` -## invalid(6): Promise.all([(0, promise)]).then() +## invalid(6): Promise.all([1.]).then() + +> Input + + `␊ + 1 | Promise.all([1.]).then()␊ + ` + +> Error 1/1 + + `␊ + > 1 | Promise.all([1.]).then()␊ + | ^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Use the value directly.␊ + 1 | (1.).then()␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ + 1 | Promise.resolve(1.).then()␊ + ` + +## invalid(7): Promise.all([.1]).then() + +> Input + + `␊ + 1 | Promise.all([.1]).then()␊ + ` + +> Error 1/1 + + `␊ + > 1 | Promise.all([.1]).then()␊ + | ^^^^ Wrapping single-element array with \`Promise.all()\` is unnecessary.␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 1/2: Use the value directly.␊ + 1 | (.1).then()␊ + ␊ + --------------------------------------------------------------------------------␊ + Suggestion 2/2: Switch to \`Promise.resolve(…)\`.␊ + 1 | Promise.resolve(.1).then()␊ + ` + +## invalid(8): Promise.all([(0, promise)]).then() > Input @@ -828,7 +874,7 @@ Generated by [AVA](https://avajs.dev). 1 | Promise.resolve((0, promise)).then()␊ ` -## invalid(7): const _ = () => Promise.all([ a ?? b ,],) +## invalid(9): const _ = () => Promise.all([ a ?? b ,],) > Input @@ -851,7 +897,7 @@ Generated by [AVA](https://avajs.dev). 1 | const _ = () => Promise.resolve( a ?? b ,)␊ ` -## invalid(8): Promise.all([ {a} = 1 ,],) +## invalid(10): Promise.all([ {a} = 1 ,],) > Input @@ -874,7 +920,7 @@ Generated by [AVA](https://avajs.dev). 1 | Promise.resolve( {a} = 1 ,)␊ ` -## invalid(9): Promise.all([ function () {} ,],) +## invalid(11): Promise.all([ function () {} ,],) > Input @@ -897,7 +943,7 @@ Generated by [AVA](https://avajs.dev). 1 | Promise.resolve( function () {} ,)␊ ` -## invalid(10): Promise.all([ class {} ,],) +## invalid(12): Promise.all([ class {} ,],) > Input @@ -920,7 +966,7 @@ Generated by [AVA](https://avajs.dev). 1 | Promise.resolve( class {} ,)␊ ` -## invalid(11): Promise.all([ new Foo ,],).then() +## invalid(13): Promise.all([ new Foo ,],).then() > Input @@ -943,7 +989,7 @@ Generated by [AVA](https://avajs.dev). 1 | Promise.resolve( new Foo ,).then()␊ ` -## invalid(12): Promise.all([ new Foo ,],).toString +## invalid(14): Promise.all([ new Foo ,],).toString > Input @@ -966,7 +1012,7 @@ Generated by [AVA](https://avajs.dev). 1 | Promise.resolve( new Foo ,).toString␊ ` -## invalid(13): foo(Promise.all([promise])) +## invalid(15): foo(Promise.all([promise])) > Input @@ -989,7 +1035,7 @@ Generated by [AVA](https://avajs.dev). 1 | foo(Promise.resolve(promise))␊ ` -## invalid(14): Promise.all([promise]).foo = 1 +## invalid(16): Promise.all([promise]).foo = 1 > Input @@ -1012,7 +1058,7 @@ Generated by [AVA](https://avajs.dev). 1 | Promise.resolve(promise).foo = 1␊ ` -## invalid(15): Promise.all([promise])[0] ||= 1 +## invalid(17): Promise.all([promise])[0] ||= 1 > Input @@ -1035,7 +1081,7 @@ Generated by [AVA](https://avajs.dev). 1 | Promise.resolve(promise)[0] ||= 1␊ ` -## invalid(16): Promise.all([undefined]).then() +## invalid(18): Promise.all([undefined]).then() > Input @@ -1058,7 +1104,7 @@ Generated by [AVA](https://avajs.dev). 1 | Promise.resolve(undefined).then()␊ ` -## invalid(17): Promise.all([null]).then() +## invalid(19): Promise.all([null]).then() > Input 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 0bca2d9fbddf8d216bdbcf77eacb90dd88d73560..6c58d9ef78bb5ac9b9a3d7df1ff568b36610cb4e 100644 GIT binary patch literal 2274 zcmV<82p#u9RzVR}DB0$Qm2S9*O2bw1KZsJ{UnxsvY1c{c%iARN? zigu~HaS{vHj@I5Lt0oeZ3m^`acolI#6iN?pqe6%Z2~qJBQUQU=i6Rah5jT#Y-T3v{ z-;8Iy&c@kvZ%yO>&iwzseB*D&v+pjP(9Pdr7W&T!+9Jy`he?b z^0&ZZI}F}rg6mBLAnfVFNPh*9e(got!SHEe(_WSCQSh)!!B_$ca!d@K00|vVh(Ruf zgCpQwCfnd37X!jI0K&IPLCB>@!lt57bWzw(smUUlo^dBLQXWCd@)QVTgi)5mT3EDs zpmqGz&KE&|=UBx#G9148yt#plxPgr0fhc5_oFG%Aiia@)>=Wo=039rdVW4y; z48pq_58)jU!dXTLa2PxRY^M1+*Zc|G{8chLJ53t6_4|QgLv-r{Dwy&6fX*Gzc;{N& z_P2rUuP|&64k6z3u2?=vvwUqW4a+^11eUk1?c8#I2pO^b0L}8Dp)@S_R1#R;y0&x6 z{UL0v<)Ul(K`P}`$H#zE`baJfjcyOM_8mE?9; zQn9;|3A^*2-IT`u#I5o(mobLBtpmJM; zahlt20=Hje6VB;%cbuklo~xvig4316PFK=!x{@iUscq&^3Qi9tc6ulcr-w4&v|q8Q z-Q~U0X;f@aB|*h*UE6uZ_J^>w72Ci0rnZ-K%iFm5W;q^n^G!Frottldzq?~MwYAiY z6zq0I64>3mv~#t#Lz>!t5BwW}j_wqy1-S#Ud-c38CA+s*9C#&U_$PA;mp^KU`KZ9fR?%F}HROSSvNPw;v) zfD0giHy8m#h7zB`rbkimqM-Df4mH+Xv5Y5i0GOAH{R427+TB+UT#n}O9?0Rf_&)@1 zAbc@&Ck09`3M{~$f8$Oeq=cm)0IQ$t;Gf8ab!b$T6r*7knjT8Un3D2iATGSJ)$G*KBemrEd*3yj)B8yaT~>P9Wv z=LObmZS%+^@-h~W1gs>Em9*=zF!lh2-B2Mfqt>4V)<5rBPkmeFU&ChFI^o$$>0^b} zk%m|n$y~84+2&EZrWuPuz~?jU2TiGh1B8^wT1XbL|JbfufS3RFGoDlQq?y>J;U_x! zfzgy-14rwNi>lRnl2$I1rpS|)O6(<-oKp05B^aW_;E1C~2wabX^ceu@LmVV2u0Zt$O44>aJ=UmQ9`^(_~{W0K`ueGTS_ejQ5$dfJWIF8n++{<$nOme_SZ}MX4XIW32W9 zs9|e_4L7nxD=j_um%RY#%npOIi!lDv$~u`QGKJD2p!7bhW&#Bi%PRoOOK7cxD(o8B z3*ZUPe6vJage)%;j#XKXY%2I)ZPNT!lXVJV_!lt63ZbA~2cZ3kgNBL4e)QWj*umLn zn!a#QbO;4-a23W~)fLO4q+}`v!pbDGnZ#*#RHz3hss0M>jW ztg6nmw?Wh4CluRq6v26AR?f~d08#$%$DTQ) zPy&Ak1YYGK(3RU!47!uvCKSTRSw5x!$FJiV#T_r|w>jlukX$muDd^4gP*`n~`ohz1GUl)V$HV$|jX7c9ApuqhMfV;v5&X?L5#QF2hK62rh zS>x}X{AJYyS!gSn^-%G@u2xvx;>5Gm#@TrW`P%{lvBgg4aKCSn+Trvp6G wP}g+^a2%fj0|k_|F9B;GqpU#{8fLvfn9!W+HfU18FvDd14+N574vk*`00)^;*Z=?k literal 2205 zcmV;O2x9j^RzVDt6XJYb6*LKpZCVHN*ii7`t#|LP!%5V&YRs0|Xi;hB$CU+&F@g`RlQt z=e6Uwshcjhb@kux`~Uy?yng)Jd4K+dX4IcI&q?PMOSLp*WlYsi$(lMRNa7@umu1yr zPc)2^s;LxZO%rB?@+e!n@dL3cs-`Y4nTv*HzI1+WPPXJ{CvF+KeW?8zzIAB(usFh) z#8#t)Mifmxp=iou`cl)fr34^#50LU7Z67=Tc+>I@KJPzx+v`Ik(=i9a7-Op}{HcKt zd!`{TEvfnfGgW;-Q^picIjQItlN$}W#g@4;YrCt@o*5#_t9?cR}OrV{zNx z1-8G&vE4s}Xw&;*`2=P8>S`L6yDAAR?;P8^<=zl7V)+5e@?0(r%UzWOmUoWr-EwaT z8*91fSbmVCoOFCIaB4Rfa*pA~Aic>*#sq=DOK;&-dP3IQzYDN<@RY!d5BAE5NB;T*_&`cLJ3=LX1;x zzYW}enNN63ulwUP(Rr@0S_)3r5<6W>!|7V4oF?1MTnbL-5<8ts!|7ZGoc1a<*1Z?e6lE$`yuo9B4M#W!tuHy7XW{qB$5WNWGFDcJ3Z zB(S@EXzzBr1K3cz-HK8nTg&O`=@cr8tCFCibdK%4qIg5d$TeVv>@N!`te1tv>t!L0 z^|FwG_0n^i>?%tsI9*EYbSVv|OBrz5E!!2cm(1r=DBF%mg0kH{wD+>@4j?0Cn`k4s zJDjo0cEsK$4{rO=9*cH&yP192SgsK5?68U zU0HU1U_VTCdJTQn_CerUg|0P(B9?>%GUb=S9YA3_R47QO^=E|loT9ctio0UvWWf1w%rE2{CAl1oT4ku#WoE;(b12LrTiH= z+FV#r%+8avQmHb@o;DR`Eh_AktTh!jr#6(jrFDkmZ%9X5guUxJz)E|7N0(KrzQ`=Y zSDF>m&`v4BpD%nQ9xvjHll?25p>xp)6THj+u0(XFdWKsUy691l4PORee(ZqRMVpy! z>D*}ioNI*aP!{}8Ck>jWG5>2H^M*mcrGjHM1+XgF$>|u9 zJm?07JkQ@l;GLxGkQgSwt$F^$XfO-@H&H@h&UV78hHgtZSRMjcj`6XCVkne<0VuCU zKp7B>Kytu<^d`S4aP(zG!zlXSg~8Uls#vrZ6&<@!#G6&F2#Vkj0Kw0BtFI@-L2nSS zv*+u~Haol#3vnReFlamd@A!adB@SX^0I?kyViF&&PXSyPQMjZCtOfxnK@zhMlN5SAsnkn_zv`|SBg8;Rk5{~KI&LpLq<9GhY{ z?zn;YnapO|ulwOwb2ETO$sSs4K@`gW0F?hYP{tP}Z((7q4g#n_YlItaWQkTPJ?EF* z0BL4({#W2&`lsbJHpL_Y(lUVb0jy*K1(eDwfXYi~se~&05;+Lm3HE%m1X>6zH@y8tFesWq0lfbRV0^1(dZf0c)S2 ftU(nDvq2zCXis$$G^t>iL9+e_^@w+h@mc@??G`E7