Skip to content

Commit

Permalink
feat(rules): add 'no-shadowing' rule
Browse files Browse the repository at this point in the history
  • Loading branch information
alecxe committed Jun 22, 2016
1 parent 41f131b commit 367a47a
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Rule | Default | Options
---- | ------- | -------
[missing-perform][] | 2 |
[no-browser-pause][] | 2 |
[no-shadowing][] | 2 |
[missing-wait-message][] | 1 |
[no-browser-sleep][] | 1 |
[no-by-xpath][] | 1 |
Expand All @@ -61,6 +62,7 @@ See [configuring rules][] for more information.

[missing-perform]: docs/rules/missing-perform.md
[no-browser-pause]: docs/rules/no-browser-pause.md
[no-shadowing]: docs/rules/no-shadowing.md
[missing-wait-message]: docs/rules/missing-wait-message.md
[no-browser-sleep]: docs/rules/no-browser-sleep.md
[no-by-xpath]: docs/rules/no-by-xpath.md
Expand Down
41 changes: 41 additions & 0 deletions docs/rules/no-shadowing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Don't allow to shadow the built-in Protractor globals

The rule is to prevent shadowing the built-in Protractor globals, like `element` or `by`.

## Rule details

Here is the list of global variables checked for not to be shadowed:

* `browser`
* `protractor`
* `element`
* `by`
* `$`
* `$$`

The following patterns are considered warnings:

```js
var element = "something";
function test (browser) {};
var protractor;
function by () {};
var $ = 1;
var a = 2, $$ = 3;
for (var by = 0; by < 10; ++by) {}
try { json = JSON.parse(input) } catch (browser) {}
switch (element) { case 1: break; default: break; }
```

The following patterns are not warnings:

```js
var element2 = "something";
element(by.id("test"));
var EC = protractor.ExpectedConditions;
var elm = $(".myclass");
var elements = $$(".myclass");
for (var i = 0; i < 10; ++i) {}
try { json = JSON.parse(input) } catch (e) {}
switch (a) { case 1: break; default: break; }
```
2 changes: 2 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module.exports = {
rules: {
'missing-perform': require('./lib/rules/missing-perform'),
'no-browser-pause': require('./lib/rules/no-browser-pause'),
'no-shadowing': require('./lib/rules/no-shadowing'),
'missing-wait-message': require('./lib/rules/missing-wait-message'),
'no-browser-sleep': require('./lib/rules/no-browser-sleep'),
'no-by-xpath': require('./lib/rules/no-by-xpath'),
Expand All @@ -18,6 +19,7 @@ module.exports = {
rules: {
'protractor/missing-perform': 2,
'protractor/no-browser-pause': 2,
'protractor/no-shadowing': 2,
'protractor/missing-wait-message': 1,
'protractor/no-browser-sleep': 1,
'protractor/no-by-xpath': 1,
Expand Down
41 changes: 41 additions & 0 deletions lib/rules/no-shadowing.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
'use strict'

/**
* @fileoverview Don't allow to shadow the built-in Protractor globals
* @author Alexander Afanasyev
*/

module.exports = function (context) {
var protractorGlobals = [
'browser',
'protractor',
'element',
'by',
'$',
'$$'
]

function checkVariables (node) {
var variables = context.getDeclaredVariables(node)
for (var i = 0; i < variables.length; ++i) {
if (protractorGlobals.indexOf(variables[i].name) !== -1) {
context.report(node, 'Unexpected Protractor built-in global variable shadowing')
}
}

// handling switch manually - getDeclaredVariables() does not return the switch discriminant
if (node.type === 'SwitchStatement' && node.discriminant) {
if (protractorGlobals.indexOf(node.discriminant.name) !== -1) {
context.report(node, 'Unexpected Protractor built-in global variable shadowing')
}
}
}

return {
'VariableDeclaration': checkVariables,
'FunctionDeclaration': checkVariables,
'FunctionExpression': checkVariables,
'CatchClause': checkVariables,
'SwitchStatement': checkVariables
}
}
94 changes: 94 additions & 0 deletions test/rules/no-shadowing.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
'use strict'

var rule = require('../../lib/rules/no-shadowing')
var RuleTester = require('eslint').RuleTester

var eslintTester = new RuleTester()

eslintTester.run('no-shadowing', rule, {
valid: [
'var element2 = "something";',
'element(by.id("test"));',
'var EC = protractor.ExpectedConditions;',
'var elm = $(".myclass");',
'var elements = $$(".myclass");',
'for (var i = 0; i < variables.length; ++i) {}',
'try { json = JSON.parse(input) } catch (e) {}',
'switch (a) { case 1: break; default: break; }'
],

invalid: [
{
code: 'var element = "something";',
errors: [
{
message: 'Unexpected Protractor built-in global variable shadowing'
}
]
},
{
code: 'function test (browser) {};',
errors: [
{
message: 'Unexpected Protractor built-in global variable shadowing'
}
]
},
{
code: 'var protractor;',
errors: [
{
message: 'Unexpected Protractor built-in global variable shadowing'
}
]
},
{
code: 'function by () {};',
errors: [
{
message: 'Unexpected Protractor built-in global variable shadowing'
}
]
},
{
code: 'var $ = 1;',
errors: [
{
message: 'Unexpected Protractor built-in global variable shadowing'
}
]
},
{
code: 'var a = 2, $$ = 3;',
errors: [
{
message: 'Unexpected Protractor built-in global variable shadowing'
}
]
},
{
code: 'for (var by = 0; by < 10; ++by) {}',
errors: [
{
message: 'Unexpected Protractor built-in global variable shadowing'
}
]
},
{
code: 'try { json = JSON.parse(input) } catch (browser) {}',
errors: [
{
message: 'Unexpected Protractor built-in global variable shadowing'
}
]
},
{
code: 'switch (element) { case 1: break; default: break; }',
errors: [
{
message: 'Unexpected Protractor built-in global variable shadowing'
}
]
}
]
})

0 comments on commit 367a47a

Please sign in to comment.