From 6cb0f008d1ca1b657361f377d3828d6ef68656d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=B5=E1=86=B7=E1=84=89=E1=85=A1=E1=86=BC?= =?UTF-8?q?=E1=84=83=E1=85=AE?= Date: Sun, 18 Feb 2024 22:58:38 +0900 Subject: [PATCH] [Fix] `jsx-boolean-value`: make error messages clearer --- CHANGELOG.md | 2 + lib/rules/jsx-boolean-value.js | 37 ++++------------- tests/lib/rules/jsx-boolean-value.js | 61 ++++++++++++++++++++++------ 3 files changed, 60 insertions(+), 40 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0cc3999fcb..4fac357d9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange * [`forbid-elements`]: prevent a crash on `createElement()` ([#3632][] @ljharb) ### Changed +* [`jsx-boolean-value`]: make error messages clearer ([#3691][] @developer-bandi) * [Refactor] `propTypes`: extract type params to var ([#3634][] @HenryBrown0) * [Refactor] [`boolean-prop-naming`]: invert if statement ([#3634][] @HenryBrown0) * [Refactor] [`function-component-definition`]: exit early if no type params ([#3634][] @HenryBrown0) @@ -40,6 +41,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange * [Docs] [`hook-use-state`]: fix an undefined variable ([#3626][] @chentsulin) [#3697]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3697 +[#3691]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3691 [#3690]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3690 [#3680]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3680 [#3679]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3679 diff --git a/lib/rules/jsx-boolean-value.js b/lib/rules/jsx-boolean-value.js index ae6dda0da7..0090c0a174 100644 --- a/lib/rules/jsx-boolean-value.js +++ b/lib/rules/jsx-boolean-value.js @@ -21,19 +21,6 @@ const exceptionsSchema = { const ALWAYS = 'always'; const NEVER = 'never'; -const errorData = new WeakMap(); -/** - * @param {object} exceptions - * @returns {object} - */ -function getErrorData(exceptions) { - if (!errorData.has(exceptions)) { - const exceptionProps = Array.from(exceptions, (name) => `\`${name}\``).join(', '); - const exceptionsMessage = exceptions.size > 0 ? ` for the following props: ${exceptionProps}` : ''; - errorData.set(exceptions, { exceptionsMessage }); - } - return errorData.get(exceptions); -} /** * @param {string} configuration * @param {Set} exceptions @@ -62,12 +49,9 @@ function isNever(configuration, exceptions, propName) { } const messages = { - omitBoolean: 'Value must be omitted for boolean attributes{{exceptionsMessage}}', - omitBoolean_noMessage: 'Value must be omitted for boolean attributes', - setBoolean: 'Value must be set for boolean attributes{{exceptionsMessage}}', - setBoolean_noMessage: 'Value must be set for boolean attributes', - omitPropAndBoolean: 'Value and Prop must be omitted for false attributes{{exceptionsMessage}}', - omitPropAndBoolean_noMessage: 'Value and Prop must be omitted for false attributes', + omitBoolean: 'Value must be omitted for boolean attribute `{{propName}}`', + setBoolean: 'Value must be set for boolean attribute `{{propName}}`', + omitPropAndBoolean: 'Value must be omitted for `false` attribute: `{{propName}}`', }; module.exports = { @@ -135,8 +119,8 @@ module.exports = { isAlways(configuration, exceptions, propName) && value === null ) { - const data = getErrorData(exceptions); - const messageId = data.exceptionsMessage ? 'setBoolean' : 'setBoolean_noMessage'; + const messageId = 'setBoolean'; + const data = { propName }; report(context, messages[messageId], messageId, { node, data, @@ -152,8 +136,8 @@ module.exports = { && value.type === 'JSXExpressionContainer' && value.expression.value === true ) { - const data = getErrorData(exceptions); - const messageId = data.exceptionsMessage ? 'omitBoolean' : 'omitBoolean_noMessage'; + const messageId = 'omitBoolean'; + const data = { propName }; report(context, messages[messageId], messageId, { node, data, @@ -169,11 +153,8 @@ module.exports = { && value.type === 'JSXExpressionContainer' && value.expression.value === false ) { - const data = getErrorData(exceptions); - const messageId = data.exceptionsMessage - ? 'omitPropAndBoolean' - : 'omitPropAndBoolean_noMessage'; - + const messageId = 'omitPropAndBoolean'; + const data = { propName }; report(context, messages[messageId], messageId, { node, data, diff --git a/tests/lib/rules/jsx-boolean-value.js b/tests/lib/rules/jsx-boolean-value.js index 678b492740..e8cbbb3e7f 100644 --- a/tests/lib/rules/jsx-boolean-value.js +++ b/tests/lib/rules/jsx-boolean-value.js @@ -63,7 +63,10 @@ ruleTester.run('jsx-boolean-value', rule, { output: ';', options: ['never'], errors: [ - { messageId: 'omitBoolean_noMessage' }, + { + messageId: 'omitBoolean', + data: { propName: 'foo' }, + }, ], }, { @@ -73,11 +76,11 @@ ruleTester.run('jsx-boolean-value', rule, { errors: [ { messageId: 'omitBoolean', - data: { exceptionsMessage: ' for the following props: `foo`, `bar`' }, + data: { propName: 'foo' }, }, { messageId: 'omitBoolean', - data: { exceptionsMessage: ' for the following props: `foo`, `bar`' }, + data: { propName: 'bar' }, }, ], }, @@ -85,14 +88,20 @@ ruleTester.run('jsx-boolean-value', rule, { code: ';', output: ';', errors: [ - { messageId: 'omitBoolean_noMessage' }, + { + messageId: 'omitBoolean', + data: { propName: 'foo' }, + }, ], }, { code: ';', output: ';', errors: [ - { messageId: 'omitBoolean_noMessage' }, + { + messageId: 'omitBoolean', + data: { propName: 'foo' }, + }, ], }, { @@ -100,7 +109,10 @@ ruleTester.run('jsx-boolean-value', rule, { output: ';', options: ['always'], errors: [ - { messageId: 'setBoolean_noMessage' }, + { + messageId: 'setBoolean', + data: { propName: 'foo' }, + }, ], }, { @@ -110,11 +122,11 @@ ruleTester.run('jsx-boolean-value', rule, { errors: [ { messageId: 'setBoolean', - data: { exceptionsMessage: ' for the following props: `foo`, `bar`' }, + data: { propName: 'foo' }, }, { messageId: 'setBoolean', - data: { exceptionsMessage: ' for the following props: `foo`, `bar`' }, + data: { propName: 'bar' }, }, ], }, @@ -123,8 +135,14 @@ ruleTester.run('jsx-boolean-value', rule, { output: ';', options: ['never', { assumeUndefinedIsFalse: true }], errors: [ - { messageId: 'omitPropAndBoolean_noMessage' }, - { messageId: 'omitPropAndBoolean_noMessage' }, + { + messageId: 'omitPropAndBoolean', + data: { propName: 'foo' }, + }, + { + messageId: 'omitPropAndBoolean', + data: { propName: 'bak' }, + }, ], }, { @@ -137,11 +155,30 @@ ruleTester.run('jsx-boolean-value', rule, { errors: [ { messageId: 'omitPropAndBoolean', - data: { exceptionsMessage: ' for the following props: `baz`, `bak`' }, + data: { propName: 'baz' }, }, { messageId: 'omitPropAndBoolean', - data: { exceptionsMessage: ' for the following props: `baz`, `bak`' }, + data: { propName: 'bak' }, + }, + ], + }, + { + code: ';', + output: ';', + options: ['always', { never: ['foo', 'bar'] }], + errors: [ + { + messageId: 'omitBoolean', + data: { propName: 'foo' }, + }, + { + messageId: 'omitBoolean', + data: { propName: 'bar' }, + }, + { + messageId: 'setBoolean', + data: { propName: 'baz' }, }, ], },