Skip to content

Commit

Permalink
fix: incorrect behaviour for checkKeyMustBeforeSpread with map callbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
akulsr0 committed Jun 18, 2024
1 parent 393bfa2 commit 483ae9e
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 18 deletions.
46 changes: 28 additions & 18 deletions lib/rules/jsx-key.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,35 @@ module.exports = {
const reactPragma = pragmaUtil.getFromContext(context);
const fragmentPragma = pragmaUtil.getFragmentFromContext(context);

function isKeyAfterSpread(attributes) {
let hasFoundSpread = false;
return attributes.some((attribute) => {
if (attribute.type === 'JSXSpreadAttribute') {
hasFoundSpread = true;
return false;
}
if (attribute.type !== 'JSXAttribute') {
return false;

Check warning on line 84 in lib/rules/jsx-key.js

View check run for this annotation

Codecov / codecov/patch

lib/rules/jsx-key.js#L84

Added line #L84 was not covered by tests
}
return hasFoundSpread && propName(attribute) === 'key';
});
}

function checkIteratorElement(node) {
if (node.type === 'JSXElement' && !hasProp(node.openingElement.attributes, 'key')) {
report(context, messages.missingIterKey, 'missingIterKey', {
node,
});
if (node.type === 'JSXElement') {
if (!hasProp(node.openingElement.attributes, 'key')) {
report(context, messages.missingIterKey, 'missingIterKey', {
node,
});
} else {
const attrs = node.openingElement.attributes;

if (checkKeyMustBeforeSpread && isKeyAfterSpread(attrs)) {
report(context, messages.keyBeforeSpread, 'keyBeforeSpread', {
node: node.type === 'ArrayExpression' ? node : node.parent,
});
}
}
} else if (checkFragmentShorthand && node.type === 'JSXFragment') {
report(context, messages.missingIterKeyUsePrag, 'missingIterKeyUsePrag', {
node,
Expand Down Expand Up @@ -115,20 +139,6 @@ module.exports = {
return returnStatements;
}

function isKeyAfterSpread(attributes) {
let hasFoundSpread = false;
return attributes.some((attribute) => {
if (attribute.type === 'JSXSpreadAttribute') {
hasFoundSpread = true;
return false;
}
if (attribute.type !== 'JSXAttribute') {
return false;
}
return hasFoundSpread && propName(attribute) === 'key';
});
}

/**
* Checks if the given node is a function expression or arrow function,
* and checks if there is a missing key prop in return statement's arguments
Expand Down
15 changes: 15 additions & 0 deletions tests/lib/rules/jsx-key.js
Original file line number Diff line number Diff line change
Expand Up @@ -409,5 +409,20 @@ ruleTester.run('jsx-key', rule, {
{ messageId: 'missingIterKey' },
],
},
{
code: `
const TestCase = () => {
const list = [1, 2, 3, 4, 5];
return (
<div>
{list.map(x => <div {...spread} key={x} />)}
</div>
);
};
`,
options: [{ checkKeyMustBeforeSpread: true }],
errors: [{ messageId: 'keyBeforeSpread' }],
},
]),
});

0 comments on commit 483ae9e

Please sign in to comment.