Skip to content

Commit

Permalink
report errors for cast strategy
Browse files Browse the repository at this point in the history
  • Loading branch information
Belco90 committed Mar 9, 2022
1 parent 64e056e commit bf2c26e
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 18 deletions.
50 changes: 37 additions & 13 deletions lib/rules/jsx-no-leaked-zero.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,24 +73,27 @@ module.exports = {
return node;
}

function ruleFixer(fixer, logicalExpressionNode) {
function ruleFixer(fixer, reportedNode, leftNode, rightNode) {
const sourceCode = context.getSourceCode();
const rightSideText = sourceCode.getText(rightNode);

if (fixStrategy === CAST_FIX_STRATEGY) {
let leftSideRange = logicalExpressionNode.left.range;
if (isParenthesized(context, logicalExpressionNode.left)) {
const [leftSideStart, leftSideEnd] = leftSideRange;
leftSideRange = [leftSideStart - 1, leftSideEnd + 1];
let leftSideText = sourceCode.getText(leftNode);
if (isParenthesized(context, leftNode)) {
leftSideText = `(${leftSideText})`;
}
return fixer.insertTextBeforeRange(leftSideRange, '!!');

const shouldPrefixDoubleNegation = leftNode.type !== 'UnaryExpression';

return fixer.replaceText(reportedNode, `${shouldPrefixDoubleNegation ? '!!' : ''}${leftSideText} && ${rightSideText}`);
}

if (fixStrategy === TERNARY_FIX_STRATEGY) {
const sourceCode = context.getSourceCode();
const rightSideText = sourceCode.getText(logicalExpressionNode.right);
let leftSideText = sourceCode.getText(trimLeftNode(logicalExpressionNode.left));
if (isParenthesized(context, logicalExpressionNode.left)) {
let leftSideText = sourceCode.getText(trimLeftNode(leftNode));
if (isParenthesized(context, leftNode)) {
leftSideText = `(${leftSideText})`;
}
return fixer.replaceText(logicalExpressionNode, `${leftSideText} ? ${rightSideText} : null`);
return fixer.replaceText(reportedNode, `${leftSideText} ? ${rightSideText} : null`);
}

throw new Error('Invalid value for "fixStrategy" option');
Expand All @@ -103,14 +106,35 @@ module.exports = {
return;
}

// TODO: check if can be removed
if (fixStrategy === TERNARY_FIX_STRATEGY && leftSide.type === 'ConditionalExpression') {
return;
}

if (fixStrategy === CAST_FIX_STRATEGY && ['UnaryExpression', 'BinaryExpression', 'CallExpression'].includes(leftSide.type)) {
return;
}

report(context, messages.noPotentialNumericEvaluation, 'noPotentialNumericEvaluation', {
node,
fix(fixer) {
return ruleFixer(fixer, node, leftSide, node.right);
},
});
},
'JSXExpressionContainer > ConditionalExpression'(node) {
if (areBothStrategiesValid) {
return;
}

if (fixStrategy === TERNARY_FIX_STRATEGY) {
return;
}

report(context, messages.noPotentialNumericEvaluation, 'noPotentialNumericEvaluation', {
node: leftSide,
node,
fix(fixer) {
return ruleFixer(fixer, node);
return ruleFixer(fixer, node, node.test, node.consequent);
},
});
},
Expand Down
80 changes: 75 additions & 5 deletions tests/lib/rules/jsx-no-leaked-zero.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@ ruleTester.run('jsx-no-leaked-zero', rule, {
}
`,
},
{
options: [{ validFixStrategies: ['cast'] }],
code: `
const Component = ({ elements, count }) => {
return <div>{!!count && <List elements={elements}/>}</div>
}
`,
},
{
options: [{ validFixStrategies: ['cast', 'ternary'] }],
code: `
Expand All @@ -108,6 +116,14 @@ ruleTester.run('jsx-no-leaked-zero', rule, {
}
`,
},
{
options: [{ validFixStrategies: ['cast', 'ternary'] }],
code: `
const Component = ({ elements, count }) => {
return <div>{!!count && <List elements={elements}/>}</div>
}
`,
},
]),

invalid: parsers.all([
Expand Down Expand Up @@ -206,7 +222,7 @@ ruleTester.run('jsx-no-leaked-zero', rule, {
errors: [{
message: 'Potential numeric evaluation resulting in an unintentionally rendered `0`',
line: 3,
column: 25,
column: 24,
}],
output: `
const Component = ({ numberA, numberB }) => {
Expand Down Expand Up @@ -316,7 +332,7 @@ ruleTester.run('jsx-no-leaked-zero', rule, {
errors: [{
message: 'Potential numeric evaluation resulting in an unintentionally rendered `0`',
line: 3,
column: 25,
column: 24,
}],
output: `
const Component = ({ numberA, numberB }) => {
Expand Down Expand Up @@ -435,7 +451,6 @@ ruleTester.run('jsx-no-leaked-zero', rule, {
`,
},

/*
// Invalid tests with "cast" fix strategy
{
code: `
Expand Down Expand Up @@ -537,14 +552,69 @@ ruleTester.run('jsx-no-leaked-zero', rule, {
errors: [{
message: 'Potential numeric evaluation resulting in an unintentionally rendered `0`',
line: 3,
column: 25,
column: 24,
}],
output: `
const Component = ({ numberA, numberB }) => {
return <div>{!!(numberA || numberB) && <Results>{numberA+numberB}</Results>}</div>
}
`,
},
*/

// cases: ternary isn't valid if fix strategy is only "cast"
{
code: `
const Component = ({ count, title }) => {
return <div>{count ? title : null}</div>
}
`,
options: [{ validFixStrategies: ['cast'] }],
errors: [{
message: 'Potential numeric evaluation resulting in an unintentionally rendered `0`',
line: 3,
column: 24,
}],
output: `
const Component = ({ count, title }) => {
return <div>{!!count && title}</div>
}
`,
},
{
code: `
const Component = ({ count, title }) => {
return <div>{!count ? title : null}</div>
}
`,
options: [{ validFixStrategies: ['cast'] }],
errors: [{
message: 'Potential numeric evaluation resulting in an unintentionally rendered `0`',
line: 3,
column: 24,
}],
output: `
const Component = ({ count, title }) => {
return <div>{!count && title}</div>
}
`,
},
{
code: `
const Component = ({ count, somethingElse, title }) => {
return <div>{count && somethingElse ? title : null}</div>
}
`,
options: [{ validFixStrategies: ['cast'] }],
errors: [{
message: 'Potential numeric evaluation resulting in an unintentionally rendered `0`',
line: 3,
column: 24,
}],
output: `
const Component = ({ count, somethingElse, title }) => {
return <div>{!!count && somethingElse && title}</div>
}
`,
},
]),
});

0 comments on commit bf2c26e

Please sign in to comment.