From d480f4d4f5b4dfc05c9ffd44a623535a7b37675d Mon Sep 17 00:00:00 2001 From: David Buchan-Swanson Date: Tue, 19 Sep 2017 13:35:27 +1000 Subject: [PATCH] feat: add an auto-fix option to sortKeys --- src/rules/sortKeys.js | 36 ++++++++++++++++++++++++++++++ tests/rules/assertions/sortKeys.js | 22 ++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/src/rules/sortKeys.js b/src/rules/sortKeys.js index 5570c3d1..6fce3cb0 100644 --- a/src/rules/sortKeys.js +++ b/src/rules/sortKeys.js @@ -65,6 +65,17 @@ const isValidOrders = { } }; +const generateOrderedList = (context, sort, properties) => { + return properties.map((property) => { + const name = getParameterName(property, context); + const value = context.getSourceCode().getFirstToken(property.value).value; + + return [name, value]; + }) + .sort((first, second) => { return sort(first[0], second[0]) ? -1 : 1; }) + .map((item) => { return item[0] + ': ' + item[1]; }); +}; + const create = (context) => { const order = _.get(context, ['options', 0], 'asc'); const {natural, caseSensitive} = _.get(context, ['options', 1], defaults); @@ -96,6 +107,31 @@ const create = (context) => { natural: natural ? 'natural ' : '', order }, + fix (fixer) { + // this could be done much more cleanly in ESLint >=4 + // as we can apply multiple fixes. That also means we can + // maintain code style in a much nicer way + let nodeText; + const newTypes = generateOrderedList(context, isValidOrder, node.properties); + const source = context.getSourceCode(node); + + const originalSubstring = source.getText(node); + + nodeText = originalSubstring; + + node.properties.forEach((property, index) => { + const subString = source.getText(property); + const addComma = subString[subString.length - 1] === ','; + + nodeText = nodeText.replace(subString, '$' + index + (addComma ? ',' : '')); + }); + + newTypes.forEach((item, index) => { + nodeText = nodeText.replace('$' + index, item); + }); + + return fixer.replaceText(node, nodeText); + }, loc: identifierNode.loc, message: 'Expected type annotations to be in {{natural}}{{insensitive}}{{order}}ending order. "{{current}}" should be before "{{last}}".', node: identifierNode diff --git a/tests/rules/assertions/sortKeys.js b/tests/rules/assertions/sortKeys.js index 06ec998c..60b408bb 100644 --- a/tests/rules/assertions/sortKeys.js +++ b/tests/rules/assertions/sortKeys.js @@ -41,6 +41,28 @@ export default { code: 'type FooType = { 1: number, 10: number, 2: boolean }', errors: [{message: 'Expected type annotations to be in natural ascending order. "2" should be before "10".'}], options: ['asc', {natural: true}] + }, + { + code: 'type FooType = { a: number, c: number, b: string }', + errors: [{message: 'Expected type annotations to be in ascending order. "b" should be before "c".'}], + output: 'type FooType = { a: number, b: string, c: number }' + }, + { + code: [ + 'type FooType = {', + ' a: number,', + ' c: number,', + ' b: string,', + '}' + ].join('\n'), + errors: [{message: 'Expected type annotations to be in ascending order. "b" should be before "c".'}], + output: [ + 'type FooType = {', + ' a: number,', + ' b: string,', + ' c: number,', + '}' + ].join('\n') } ], misconfigured: [