From 0dac15995224a1d8cdcfd8045e8c9e77b29e278a Mon Sep 17 00:00:00 2001 From: Akul Srivastava Date: Sat, 24 Dec 2022 23:47:38 +0530 Subject: [PATCH] [Fix] `jsx-no-leaked-render`: invalid fixes in coerce mode --- CHANGELOG.md | 2 ++ lib/rules/jsx-no-leaked-render.js | 12 +++++++++ tests/lib/rules/jsx-no-leaked-render.js | 36 +++++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 996905229e..88dab9ebfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange * [`jsx-no-leaked-render`]: Don't report errors on empty strings if React >= v18 ([#3488][] @himanshu007-creator) * [`no-invalid-html-attribute`]: convert autofix to suggestion ([#3474][] @himanshu007-creator @ljharb) * [`jsx-no-leaked-render`]: fix removing parentheses for conditionals ([#3502][] @akulsr0) +* [`jsx-no-leaked-render`]: invalid fixes in coerce mode ([#3511][] @akulsr0) ### Changed * [Docs] [`jsx-no-leaked-render`]: Remove mentions of empty strings for React 18 ([#3468][] @karlhorky) @@ -28,6 +29,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange * [Docs] [`prefer-exact-props`]: fix example flow syntax ([#3510][] @smackfu) * [Perf] use `anyOf` instead of `oneOf` (@ljharb @remcohaszing) +[#3511]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3511 [#3510]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3510 [#3504]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3504 [#3499]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3499 diff --git a/lib/rules/jsx-no-leaked-render.js b/lib/rules/jsx-no-leaked-render.js index dccba5b695..9ac795d98b 100644 --- a/lib/rules/jsx-no-leaked-render.js +++ b/lib/rules/jsx-no-leaked-render.js @@ -61,9 +61,21 @@ function ruleFixer(context, fixStrategy, fixer, reportedNode, leftNode, rightNod if (isParenthesized(context, node)) { nodeText = `(${nodeText})`; } + if (node.parent && node.parent.type === 'ConditionalExpression' && node.parent.consequent.value === false) { + return `${getIsCoerceValidNestedLogicalExpression(node) ? '' : '!'}${nodeText}`; + } return `${getIsCoerceValidNestedLogicalExpression(node) ? '' : '!!'}${nodeText}`; }).join(' && '); + if (rightNode.parent.type === 'ConditionalExpression' && rightNode.parent.consequent.value === false) { + const consequentVal = rightNode.parent.consequent.raw || rightNode.parent.consequent.name; + const alternateVal = rightNode.parent.alternate.raw || rightNode.parent.alternate.name; + if (rightNode.parent.test.type === 'LogicalExpression') { + return fixer.replaceText(reportedNode, `${newText} ? ${consequentVal} : ${alternateVal}`); + } + return fixer.replaceText(reportedNode, `${newText} && ${rightNode.parent.alternate.name}`); + } + if (rightNode.type === 'ConditionalExpression') { return fixer.replaceText(reportedNode, `${newText} && (${rightSideText})`); } diff --git a/tests/lib/rules/jsx-no-leaked-render.js b/tests/lib/rules/jsx-no-leaked-render.js index cd9a1f982c..8879460d25 100644 --- a/tests/lib/rules/jsx-no-leaked-render.js +++ b/tests/lib/rules/jsx-no-leaked-render.js @@ -847,5 +847,41 @@ ruleTester.run('jsx-no-leaked-render', rule, { column: 24, }], }, + { + code: ` + const MyComponent = () => { + return + } + `, + output: ` + const MyComponent = () => { + return + } + `, + options: [{ validStrategies: ['coerce'] }], + errors: [{ + message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes', + line: 3, + column: 38, + }], + }, + { + code: ` + const MyComponent = () => { + return + } + `, + output: ` + const MyComponent = () => { + return + } + `, + options: [{ validStrategies: ['coerce'] }], + errors: [{ + message: 'Potential leaked value that might cause unintentionally rendered values or rendering crashes', + line: 3, + column: 38, + }], + }, ]), });