From ef246a9387f45bb0988887cfdbfab86bc3650fb2 Mon Sep 17 00:00:00 2001 From: Alexander Afanasyev Date: Fri, 8 Jul 2016 20:17:27 -0400 Subject: [PATCH] feat(rules): 'use-first-last' rule to apply fixes --- lib/rules/use-first-last.js | 69 +++++++++++++++++++++++------------- test/rules/use-first-last.js | 30 ++++++++++++---- 2 files changed, 69 insertions(+), 30 deletions(-) diff --git a/lib/rules/use-first-last.js b/lib/rules/use-first-last.js index 73e5365..cfe0b36 100644 --- a/lib/rules/use-first-last.js +++ b/lib/rules/use-first-last.js @@ -5,38 +5,59 @@ * @author Alexander Afanasyev */ -module.exports = function (context) { - var valueFunction = { - '0': 'first()', - '-1': 'last()' - } +var valueFunction = { + '0': 'first()', + '-1': 'last()' +} + +module.exports = { + meta: { + fixable: 'code' + }, - function getFirstArgumentValue (methodArguments) { - var firstArgument = methodArguments[0] + create: function (context) { + function getFirstArgumentValue (methodArguments) { + var firstArgument = methodArguments[0] - if (firstArgument) { - if (firstArgument.value === 0) { - return 0 - } else if (firstArgument.operator === '-') { - return -firstArgument.argument.value + if (firstArgument) { + if (firstArgument.value === 0) { + return 0 + } else if (firstArgument.operator === '-') { + return -firstArgument.argument.value + } + } + } + + function createFirstLastAutoFixFunction (property, argument, argumentValue) { + var functionToUse = valueFunction[argumentValue] + var rangeStart = property.range[0] + var rangeEnd = argument.range[1] + 1 // 1 added for parenthesis + + return function (fixer) { + // replace get(0) with first(), get(-1) with last() + return fixer.replaceTextRange([rangeStart, rangeEnd], functionToUse) } } - } - return { - CallExpression: function (node) { - var property = node.callee.property + return { + CallExpression: function (node) { + var property = node.callee.property - if (property && property.name === 'get' && node.arguments) { - var argumentValue = getFirstArgumentValue(node.arguments) + if (property && property.name === 'get' && node.arguments) { + var argumentValue = getFirstArgumentValue(node.arguments) - if (argumentValue === 0 || argumentValue === -1) { - var object = node.callee.object - var callee = object.callee + if (argumentValue === 0 || argumentValue === -1) { + var object = node.callee.object + var callee = object.callee - if (callee && ((callee.property && (callee.property.name === 'all' || callee.property.name === '$$')) || - (callee.name === '$$'))) { - context.report(node, 'Unexpected "get(' + argumentValue + ')" call, use "' + valueFunction[argumentValue] + '" instead') + if (callee && ((callee.property && (callee.property.name === 'all' || callee.property.name === '$$')) || + (callee.name === '$$'))) { + context.report({ + node: callee, + message: 'Unexpected "get(' + argumentValue + ')" call, use "' + valueFunction[argumentValue] + '" instead', + fix: createFirstLastAutoFixFunction(property, node.arguments[0], argumentValue) + }) + } } } } diff --git a/test/rules/use-first-last.js b/test/rules/use-first-last.js index bb4a500..c202574 100644 --- a/test/rules/use-first-last.js +++ b/test/rules/use-first-last.js @@ -27,7 +27,8 @@ eslintTester.run('use-first-last', rule, { { message: 'Unexpected "get(0)" call, use "first()" instead' } - ] + ], + output: 'element.all(by.css(".class")).first();' }, { code: 'element(by.id("id")).all(by.css(".class")).get(-1);', @@ -35,7 +36,8 @@ eslintTester.run('use-first-last', rule, { { message: 'Unexpected "get(-1)" call, use "last()" instead' } - ] + ], + output: 'element(by.id("id")).all(by.css(".class")).last();' }, { code: '$$(".class").get(0);', @@ -43,7 +45,8 @@ eslintTester.run('use-first-last', rule, { { message: 'Unexpected "get(0)" call, use "first()" instead' } - ] + ], + output: '$$(".class").first();' }, { code: 'element(by.id("id")).$$(".class").get(-1);', @@ -51,7 +54,8 @@ eslintTester.run('use-first-last', rule, { { message: 'Unexpected "get(-1)" call, use "last()" instead' } - ] + ], + output: 'element(by.id("id")).$$(".class").last();' }, { code: 'element.all(by.css(".class")).get(0).getText();', @@ -59,7 +63,8 @@ eslintTester.run('use-first-last', rule, { { message: 'Unexpected "get(0)" call, use "first()" instead' } - ] + ], + output: 'element.all(by.css(".class")).first().getText();' }, { code: 'element.all(by.css(".class")).get(-1).getText();', @@ -67,7 +72,20 @@ eslintTester.run('use-first-last', rule, { { message: 'Unexpected "get(-1)" call, use "last()" instead' } - ] + ], + output: 'element.all(by.css(".class")).last().getText();' + }, + { + code: 'element.all(by.css(".class")).get(-1).all(by.css(".anotherclass")).get(0).getText();', + errors: [ + { + message: 'Unexpected "get(0)" call, use "first()" instead' + }, + { + message: 'Unexpected "get(-1)" call, use "last()" instead' + } + ], + output: 'element.all(by.css(".class")).last().all(by.css(".anotherclass")).first().getText();' } ] })