From baa939c08f3a41e671bcfccfe2f43b50add9ecad Mon Sep 17 00:00:00 2001 From: Victor Date: Thu, 3 Aug 2017 10:20:37 -0700 Subject: [PATCH] [fix] `jsx-sort-props`: enforce prop sort when reservedFirst is enabled If reservedFirst is enabled and noSortAlphabetically is off, then alphabetical order is only enforced in the reserved props but not in the other props. * Update generateFixerFunction to accept the reservedList. * Rename alphabeticalCompare to be propNameCompare. Accept a reservedFirst and reservedList parameters in order to be able to compare prop names according to the configuration. --- lib/rules/jsx-sort-props.js | 28 +++++++++++++++++++--------- tests/lib/rules/jsx-sort-props.js | 15 ++++++++++++++- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/lib/rules/jsx-sort-props.js b/lib/rules/jsx-sort-props.js index 10ca976af3..cb09747bb7 100644 --- a/lib/rules/jsx-sort-props.js +++ b/lib/rules/jsx-sort-props.js @@ -40,11 +40,21 @@ function isReservedPropName(name, list) { return list.indexOf(name) >= 0; } -function alphabeticalCompare(a, b, ignoreCase) { - if (ignoreCase) { +function propNameCompare(a, b, options) { + if (options.ignoreCase) { a = a.toLowerCase(); b = b.toLowerCase(); } + if (options.reservedFirst) { + const aIsReserved = isReservedPropName(a, options.reservedList); + const bIsReserved = isReservedPropName(b, options.reservedList); + if ((aIsReserved && bIsReserved) || (!aIsReserved && !bIsReserved)) { + return a.localeCompare(b); + } else if (aIsReserved && !bIsReserved) { + return -1; + } + return 1; + } return a.localeCompare(b); } @@ -77,11 +87,12 @@ function getGroupsOfSortableAttributes(attributes) { return sortableAttributeGroups; } -const generateFixerFunction = (node, context) => { +const generateFixerFunction = (node, context, reservedList) => { const sourceCode = context.getSourceCode(); const attributes = node.attributes.slice(0); const configuration = context.options[0] || {}; const ignoreCase = configuration.ignoreCase || false; + const reservedFirst = configuration.reservedFirst || false; // Sort props according to the context. Only supports ignoreCase. // Since we cannot safely move JSXSpreadAttribute (due to potential variable overrides), @@ -89,7 +100,7 @@ const generateFixerFunction = (node, context) => { const sortableAttributeGroups = getGroupsOfSortableAttributes(attributes); const sortedAttributeGroups = sortableAttributeGroups.slice(0).map(group => group.slice(0).sort((a, b) => - alphabeticalCompare(propName(a), propName(b), ignoreCase) + propNameCompare(propName(a), propName(b), {ignoreCase, reservedFirst, reservedList}) ) ); @@ -235,23 +246,22 @@ module.exports = { const previousIsReserved = isReservedPropName(previousPropName, reservedList); const currentIsReserved = isReservedPropName(currentPropName, reservedList); - if (previousIsReserved && currentIsReserved) { + if ((previousIsReserved && currentIsReserved) || (!previousIsReserved && !currentIsReserved)) { if (!noSortAlphabetically && currentPropName < previousPropName) { context.report({ node: decl, message: 'Props should be sorted alphabetically', - fix: generateFixerFunction(node, context) + fix: generateFixerFunction(node, context, reservedList) }); return memo; } - return decl; } if (!previousIsReserved && currentIsReserved) { context.report({ node: decl, - message: 'Reserved props must be listed before all other props' + message: 'Reserved props must be listed before all other props', + fix: generateFixerFunction(node, context, reservedList) }); - return memo; } return decl; } diff --git a/tests/lib/rules/jsx-sort-props.js b/tests/lib/rules/jsx-sort-props.js index 4cd54ce7b0..9439d4ea64 100644 --- a/tests/lib/rules/jsx-sort-props.js +++ b/tests/lib/rules/jsx-sort-props.js @@ -271,8 +271,21 @@ ruleTester.run('jsx-sort-props', rule, { errors: [expectedError] }, { - code: '', + code: '', options: reservedFirstAsBooleanArgs, + output: '', + errors: [expectedError] + }, + { + code: '', + options: reservedFirstAsBooleanArgs, + output: '', + errors: [expectedError] + }, + { + code: '', + options: reservedFirstAsBooleanArgs, + output: '', errors: [expectedReservedFirstError] }, {