Skip to content

Commit 86d079c

Browse files
committed
feat(rules): add 'use-first-last' rule
1 parent 9dbabb6 commit 86d079c

File tree

5 files changed

+148
-1
lines changed

5 files changed

+148
-1
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ Rule | Default | Options
4343
[use-angular-locators][] | 1 |
4444
[use-simple-repeaters][] | 1 |
4545
[no-shadowing][] | 1 |
46+
[use-first-last][] | 1 |
4647
[by-css-shortcut][] | 0 |
4748

4849
For example, the `missing-perform` rule is enabled by default and will cause
@@ -70,6 +71,7 @@ See [configuring rules][] for more information.
7071
[use-angular-locators]: docs/rules/use-angular-locators.md
7172
[use-simple-repeaters]: docs/rules/use-simple-repeaters.md
7273
[no-shadowing]: docs/rules/no-shadowing.md
74+
[use-first-last]: docs/rules/use-first-last.md
7375
[by-css-shortcut]: docs/rules/by-css-shortcut.md
7476
[configuring rules]: http://eslint.org/docs/user-guide/configuring#configuring-rules
7577

docs/rules/use-first-last.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Recommend using `first()` instead of `get(0)` and `last()` instead of `get(-1)`
2+
3+
The `first()` and `last()` shortcuts is, generally speaking, more readable than `get(0)` and `get(-1)`.
4+
5+
## Rule details
6+
7+
Any use of the following patterns are considered warnings:
8+
9+
```js
10+
element.all(by.css(".class")).get(0);
11+
element(by.id("id")).all(by.css(".class")).get(-1);
12+
$$(".class").get(0);
13+
element(by.id("id")).$$(".class").get(-1);
14+
element.all(by.css(".class")).get(0).getText();
15+
element.all(by.css(".class")).get(-1).getText();
16+
```
17+
18+
The following patterns are not warnings:
19+
20+
```js
21+
element.all(by.css(".class")).first();
22+
element(by.id("id")).all(by.css(".class")).last();
23+
$$(".class").first();
24+
element(by.id("id")).$$(".class").last();
25+
element.all(by.css(".class")).get(1);
26+
element(by.id("id")).all(by.css(".class")).get(-10).getText();
27+
$$(".class").get(10);
28+
element(by.id("id")).$$(".class").get(-10);
29+
var myMap = new Map(); myMap.get(0);
30+
var myMap = new Map(); myMap.get(-1);
31+
```

index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ module.exports = {
1212
'no-angular-classes': require('./lib/rules/no-angular-classes'),
1313
'use-angular-locators': require('./lib/rules/use-angular-locators'),
1414
'use-simple-repeaters': require('./lib/rules/use-simple-repeaters'),
15-
'no-shadowing': require('./lib/rules/no-shadowing')
15+
'no-shadowing': require('./lib/rules/no-shadowing'),
16+
'use-first-last': require('./lib/rules/use-first-last')
1617
},
1718
configs: {
1819
recommended: {
@@ -27,6 +28,7 @@ module.exports = {
2728
'protractor/use-angular-locators': 1,
2829
'protractor/use-simple-repeaters': 1,
2930
'protractor/no-shadowing': 1,
31+
'protractor/use-first-last': 1,
3032
'protractor/by-css-shortcut': 0
3133
}
3234
}

lib/rules/use-first-last.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
'use strict'
2+
3+
/**
4+
* @fileoverview Recommend using `first()` instead of `get(0)` and `last()` instead of `get(-1)`
5+
* @author Alexander Afanasyev
6+
*/
7+
8+
module.exports = function (context) {
9+
var valueFunction = {
10+
'0': 'first()',
11+
'-1': 'last()'
12+
}
13+
14+
return {
15+
CallExpression: function (node) {
16+
var property = node.callee.property
17+
18+
if (property && property.name === 'get' && node.arguments) {
19+
var argument = node.arguments[0]
20+
var argumentValue
21+
22+
if (argument.value === 0) {
23+
argumentValue = 0
24+
} else if (argument.operator === '-' && argument.argument && argument.argument.value === 1) {
25+
argumentValue = -1
26+
}
27+
28+
if (argumentValue === 0 || argumentValue === -1) {
29+
var object = node.callee.object
30+
var callee = object.callee
31+
32+
if (callee && ((callee.property && (callee.property.name === 'all' || callee.property.name === '$$')) ||
33+
(callee.name === '$$'))) {
34+
context.report(node, 'Unexpected "get(' + argumentValue + ')" call, use "' + valueFunction[argumentValue] + '" instead')
35+
}
36+
}
37+
}
38+
}
39+
}
40+
}

test/rules/use-first-last.js

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
'use strict'
2+
3+
var rule = require('../../lib/rules/use-first-last')
4+
var RuleTester = require('eslint').RuleTester
5+
6+
var eslintTester = new RuleTester()
7+
8+
eslintTester.run('use-first-last', rule, {
9+
valid: [
10+
'element.all(by.css(".class")).first();',
11+
'element(by.id("id")).all(by.css(".class")).last();',
12+
'$$(".class").first();',
13+
'element(by.id("id")).$$(".class").last();',
14+
'element.all(by.css(".class")).get(1);',
15+
'element(by.id("id")).all(by.css(".class")).get(-10).getText();',
16+
'$$(".class").get(10);',
17+
'element(by.id("id")).$$(".class").get(-10);',
18+
'var myMap = new Map(); myMap.get(0);',
19+
'var myMap = new Map(); myMap.get(-1);'
20+
],
21+
22+
invalid: [
23+
{
24+
code: 'element.all(by.css(".class")).get(0);',
25+
errors: [
26+
{
27+
message: 'Unexpected "get(0)" call, use "first()" instead'
28+
}
29+
]
30+
},
31+
{
32+
code: 'element(by.id("id")).all(by.css(".class")).get(-1);',
33+
errors: [
34+
{
35+
message: 'Unexpected "get(-1)" call, use "last()" instead'
36+
}
37+
]
38+
},
39+
{
40+
code: '$$(".class").get(0);',
41+
errors: [
42+
{
43+
message: 'Unexpected "get(0)" call, use "first()" instead'
44+
}
45+
]
46+
},
47+
{
48+
code: 'element(by.id("id")).$$(".class").get(-1);',
49+
errors: [
50+
{
51+
message: 'Unexpected "get(-1)" call, use "last()" instead'
52+
}
53+
]
54+
},
55+
{
56+
code: 'element.all(by.css(".class")).get(0).getText();',
57+
errors: [
58+
{
59+
message: 'Unexpected "get(0)" call, use "first()" instead'
60+
}
61+
]
62+
},
63+
{
64+
code: 'element.all(by.css(".class")).get(-1).getText();',
65+
errors: [
66+
{
67+
message: 'Unexpected "get(-1)" call, use "last()" instead'
68+
}
69+
]
70+
}
71+
]
72+
})

0 commit comments

Comments
 (0)