diff --git a/__tests__/param-names.js b/__tests__/param-names.js index 4d7b276e..f4a80599 100644 --- a/__tests__/param-names.js +++ b/__tests__/param-names.js @@ -8,7 +8,10 @@ const ruleTester = new RuleTester({ }, }) -const message = 'Promise constructor parameters must be named resolve, reject' +const messageForResolve = + 'Promise constructor parameters must be named to match "^_?resolve$"' +const messageForReject = + 'Promise constructor parameters must be named to match "^_?reject$"' ruleTester.run('param-names', rule, { valid: [ @@ -22,24 +25,42 @@ ruleTester.run('param-names', rule, { 'new Promise((resolve, reject) => {})', 'new Promise(() => {})', 'new NonPromise()', + { + code: 'new Promise((yes, no) => {})', + options: [{ resolvePattern: '^yes$', rejectPattern: '^no$' }], + }, ], invalid: [ { code: 'new Promise(function(reject, resolve) {})', - errors: [{ message }], + errors: [{ message: messageForResolve }, { message: messageForReject }], }, { code: 'new Promise(function(resolve, rej) {})', - errors: [{ message }], + errors: [{ message: messageForReject }], }, { code: 'new Promise(yes => {})', - errors: [{ message }], + errors: [{ message: messageForResolve }], }, { code: 'new Promise((yes, no) => {})', - errors: [{ message }], + errors: [{ message: messageForResolve }, { message: messageForReject }], + }, + { + code: 'new Promise(function(resolve, reject) {})', + options: [{ resolvePattern: '^yes$', rejectPattern: '^no$' }], + errors: [ + { + message: + 'Promise constructor parameters must be named to match "^yes$"', + }, + { + message: + 'Promise constructor parameters must be named to match "^no$"', + }, + ], }, ], }) diff --git a/docs/rules/param-names.md b/docs/rules/param-names.md index 0135d374..ca3ac05e 100644 --- a/docs/rules/param-names.md +++ b/docs/rules/param-names.md @@ -24,3 +24,17 @@ Promise constructor uses the [RevealingConstructor pattern](https://blog.domenic.me/the-revealing-constructor-pattern/). Using the same parameter names as the language specification makes code more uniform and easier to understand. + +#### Options + +##### `resolvePattern` + +You can pass a `{ resolvePattern: "^_?resolve$" }` as an option to this rule to +the first argument name pattern that the rule allows. Default is +`"^_?resolve$"`. + +##### `rejectPattern` + +You can pass a `{ rejectPattern: "^_?reject$" }` as an option to this rule to +the second argument name pattern that the rule allows. Default is +`"^_?reject$"`. diff --git a/rules/param-names.js b/rules/param-names.js index ab53a52e..ac01f9b1 100644 --- a/rules/param-names.js +++ b/rules/param-names.js @@ -8,9 +8,25 @@ module.exports = { docs: { url: getDocsUrl('param-names'), }, - schema: [], + schema: [ + { + type: 'object', + properties: { + resolvePattern: { type: 'string' }, + rejectPattern: { type: 'string' }, + }, + additionalProperties: false, + }, + ], }, create(context) { + const options = context.options[0] || {} + const resolvePattern = new RegExp( + options.resolvePattern || '^_?resolve$', + 'u' + ) + const rejectPattern = new RegExp(options.rejectPattern || '^_?reject$', 'u') + return { NewExpression(node) { if (node.callee.name === 'Promise' && node.arguments.length === 1) { @@ -20,16 +36,26 @@ module.exports = { return } - if ( - (params[0].name !== 'resolve' && params[0].name !== '_resolve') || - (params[1] && - params[1].name !== 'reject' && - params[1].name !== '_reject') - ) { + const resolveParamName = params[0] && params[0].name + if (resolveParamName && !resolvePattern.test(resolveParamName)) { + context.report({ + node: params[0], + message: + 'Promise constructor parameters must be named to match "{{ resolvePattern }}"', + data: { + resolvePattern: resolvePattern.source, + }, + }) + } + const rejectParamName = params[1] && params[1].name + if (rejectParamName && !rejectPattern.test(rejectParamName)) { context.report({ - node, + node: params[1], message: - 'Promise constructor parameters must be named resolve, reject', + 'Promise constructor parameters must be named to match "{{ rejectPattern }}"', + data: { + rejectPattern: rejectPattern.source, + }, }) } }