Skip to content

Commit 1d1394e

Browse files
Merge pull request #467 from Gillespie59/development
2.3.0
2 parents 46d0ef9 + 6b9acd1 commit 1d1394e

File tree

11 files changed

+2658
-13
lines changed

11 files changed

+2658
-13
lines changed

README.md

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ Since the 0.0.4 release, some rules defined in [John Papa's Guideline](https://g
3131

3232
## Usage with [shareable](http://eslint.org/docs/developer-guide/shareable-configs.html) config
3333

34-
Users may use the shareable [eslint-config-angular](https://github.com/dustinspecker/eslint-config-angular) to quickly setup eslint-plugin-angular. It also marks Angular as a global variable and defines required ESLint rules to use this plugin.
35-
3634
1. Install `eslint` as a dev-dependency:
3735

3836
```shell
@@ -45,16 +43,10 @@ Users may use the shareable [eslint-config-angular](https://github.com/dustinspe
4543
npm install --save-dev eslint-plugin-angular
4644
```
4745

48-
3. Install `eslint-config-angular` as a dev-dependency:
49-
50-
```shell
51-
npm install --save-dev eslint-config-angular
52-
```
53-
54-
4. Use the shareable config by adding it to your `.eslintrc`:
46+
3. Use the shareable config by adding it to your `.eslintrc`:
5547

5648
```yaml
57-
extends: angular
49+
extends: plugin:angular/johnpapa
5850
```
5951

6052

@@ -100,6 +92,7 @@ Rules in eslint-plugin-angular are divided into several categories to help you b
10092

10193
The following rules detect patterns that can lead to errors.
10294

95+
* [avoid-scope-typos](docs/avoid-scope-typos.md) - Avoid mistakes when naming methods defined on the scope object
10396
* [module-getter](docs/module-getter.md) - disallow to reference modules with variables and require to use the getter syntax instead `angular.module('myModule')` ([y022](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y022))
10497
* [module-setter](docs/module-setter.md) - disallow to assign modules to variables (linked to [module-getter](docs/module-getter.md) ([y021](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y021))
10598
* [no-private-call](docs/no-private-call.md) - disallow use of internal angular properties prefixed with $$

docs/avoid-scope-typos.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<!-- WARNING: Generated documentation. Edit docs and examples in the rule and examples file ('rules/avoid-scope-typos.js', 'examples/avoid-scope-typos.js'). -->
2+
3+
# avoid-scope-typos - Avoid mistakes when naming methods defined on the scope object
4+
5+
For example, you want to use $scope.$watch instead of $scope.watch
6+
7+
**Rule based on Angular 1.x**
8+
9+
## Examples
10+
11+
The following patterns are considered problems;
12+
13+
/*eslint angular/avoid-scope-typos: 2*/
14+
15+
// invalid
16+
$scope.apply.forEach(function (watcher) {
17+
// ...
18+
}); // error: The apply method should be replaced by $apply, or you should rename it in order to avoid confusions
19+
20+
// invalid
21+
$rootScope.apply.forEach(function (watcher) {
22+
// ...
23+
}); // error: The apply method should be replaced by $apply, or you should rename it in order to avoid confusions
24+
25+
The following patterns are **not** considered problems;
26+
27+
/*eslint angular/avoid-scope-typos: 2*/
28+
29+
// valid
30+
$scope.$apply();
31+
32+
// valid
33+
$rootScope.$apply();
34+
35+
## Version
36+
37+
This rule was introduced in eslint-plugin-angular 2.3.0
38+
39+
## Links
40+
41+
* [Rule source](../rules/avoid-scope-typos.js)
42+
* [Example source](../examples/avoid-scope-typos.js)

examples/avoid-scope-typos.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// example - valid: true
2+
$scope.$apply();
3+
4+
// example - valid: false, errorMessage: "The apply method should be replaced by $apply, or you should rename it in order to avoid confusions"
5+
$scope.apply.forEach(function (watcher) {
6+
// ...
7+
});
8+
9+
// example - valid: true
10+
$rootScope.$apply();
11+
12+
// example - valid: false, errorMessage: "The apply method should be replaced by $apply, or you should rename it in order to avoid confusions"
13+
$rootScope.apply.forEach(function (watcher) {
14+
// ...
15+
});

index.js

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,61 @@ fs.readdirSync(ruleDir).forEach(function(name) {
1717

1818
module.exports = {
1919
rules: rules,
20-
environments: require('./environments')
20+
environments: require('./environments'),
21+
configs: {
22+
johnpapa: {
23+
plugins: [
24+
'angular'
25+
],
26+
rules: {
27+
'angular/component-name': 2,
28+
'angular/constant-name': 2,
29+
'angular/controller-as-route': 2,
30+
'angular/controller-as-vm': 2,
31+
'angular/controller-as': 2,
32+
'angular/controller-name': 2,
33+
'angular/directive-name': 2,
34+
'angular/directive-restrict': 2,
35+
'angular/document-service': 2,
36+
'angular/factory-name': 2,
37+
'angular/file-name': 2,
38+
'angular/filter-name': 2,
39+
'angular/function-type': 2,
40+
'angular/interval-service': 2,
41+
'angular/module-getter': 2,
42+
'angular/module-name': 2,
43+
'angular/module-setter': 2,
44+
'angular/no-run-logic': 2,
45+
'angular/no-service-method': 2,
46+
'angular/provider-name': 2,
47+
'angular/service-name': 2,
48+
'angular/timeout-service': 2,
49+
'angular/value-name': 2,
50+
'angular/window-service': 2
51+
}
52+
},
53+
bestpractices: {
54+
plugins: [
55+
'angular'
56+
],
57+
rules: {
58+
'angular/component-name': 2,
59+
'angular/constant-name': 2,
60+
'angular/controller-as-route': 2,
61+
'angular/controller-as-vm': 2,
62+
'angular/controller-as': 2,
63+
'angular/deferred': 2,
64+
'angular/di-unused': 2,
65+
'angular/directive-restrict': 2,
66+
'angular/empty-controller': 2,
67+
'angular/no-controller': 2,
68+
'angular/no-inline-template': 2,
69+
'angular/no-run-logic': 2,
70+
'angular/no-service-method': 2,
71+
'angular/no-services': 2,
72+
'angular/on-watch': 2,
73+
'angular/prefer-component': 2
74+
}
75+
}
76+
}
2177
};

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "eslint-plugin-angular",
3-
"version": "2.2.1",
3+
"version": "2.3.0",
44
"description": "ESLint rules for AngularJS projects",
55
"main": "index.js",
66
"scripts": {

rules/avoid-scope-typos.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* Avoid mistakes when naming methods defined on the scope object
3+
*
4+
* For example, you want to use $scope.$watch instead of $scope.watch
5+
*
6+
* @version 2.3.0
7+
* @category possibleError
8+
* @sinceAngularVersion 1.x
9+
*/
10+
'use strict';
11+
12+
const bad = ['new', 'watch', 'watchGroup', 'watchCollection',
13+
'digest', 'destroy', 'eval', 'evalAsync', 'apply',
14+
'applyAsync', 'on', 'emit', 'broadcast'];
15+
16+
module.exports = {
17+
meta: {
18+
schema: [ ]
19+
},
20+
create: function(context) {
21+
function check(node, name) {
22+
if (bad.indexOf(name) >= 0) {
23+
context.report(node, `The ${name} method should be replaced by $${name}, or you should rename it in order to avoid confusions`, {});
24+
}
25+
}
26+
return {
27+
28+
Identifier: function(node) {
29+
check(node, node.name);
30+
}
31+
};
32+
}
33+
};

rules/utils/angular-rule.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ function angularRule(ruleDefinition) {
199199
if (node.type === 'ArrayExpression') {
200200
node = node.elements[node.elements.length - 1] || {};
201201
}
202-
if (node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration') {
202+
if (node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression' || node.type === 'FunctionDeclaration') {
203203
return node;
204204
}
205205
if (node.type !== 'Identifier') {

test/avoid-scope-typos.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
'use strict';
2+
3+
// ------------------------------------------------------------------------------
4+
// Requirements
5+
// ------------------------------------------------------------------------------
6+
7+
const rule = require('../rules/avoid-scope-typos');
8+
const RuleTester = require('eslint').RuleTester;
9+
const commonFalsePositives = require('./utils/commonFalsePositives');
10+
11+
// ------------------------------------------------------------------------------
12+
// Tests
13+
// ------------------------------------------------------------------------------
14+
15+
const eslintTester = new RuleTester();
16+
17+
const variables = ['$scope', '$rootScope'];
18+
const bad = ['new', 'watch', 'watchGroup', 'watchCollection',
19+
'digest', 'destroy', 'eval', 'evalAsync', 'apply',
20+
'applyAsync', 'on', 'emit', 'broadcast'];
21+
22+
var invalid = [];
23+
var valid = [];
24+
25+
variables.forEach(function(variable) {
26+
bad.forEach(function(b) {
27+
invalid.push({
28+
code: variable + '.' + b,
29+
errors: [{message: `The ${b} method should be replaced by $${b}, or you should rename it in order to avoid confusions`}]
30+
});
31+
});
32+
});
33+
34+
variables.forEach(function(variable) {
35+
bad.forEach(function(b) {
36+
valid.push({
37+
code: variable + '.$' + b
38+
});
39+
});
40+
});
41+
eslintTester.run('avoid-scope-typos', rule, {
42+
valid: valid.concat(commonFalsePositives),
43+
invalid
44+
});

test/di-unused.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,16 @@ eslintTester.run('di-unused', rule, {
7878
code: 'angular.module("").controller("", fn); function fn($q) {}',
7979
errors: [{message: 'Unused injected value $q'}]
8080
},
81+
{
82+
code: 'angular.module("").controller("", ["$q", ($q) => {}]);',
83+
parserOptions: {ecmaVersion: 6},
84+
errors: [{message: 'Unused injected value $q'}]
85+
},
86+
{
87+
code: 'angular.module("").controller("", ($q) => {});',
88+
parserOptions: {ecmaVersion: 6},
89+
errors: [{message: 'Unused injected value $q'}]
90+
},
8191
// directive
8292
{
8393
code: 'angular.module("").directive("", function($q) {});',
@@ -96,9 +106,18 @@ eslintTester.run('di-unused', rule, {
96106
{
97107
code: 'angular.module("").factory("", function($q) {});',
98108
errors: [{message: 'Unused injected value $q'}]
109+
},
110+
{
111+
code: 'angular.module("").factory("", $q => {});',
112+
errors: [{message: 'Unused injected value $q'}],
113+
parserOptions: {ecmaVersion: 6}
99114
}, {
100115
code: 'angular.module("").factory("", ["q", function($q) {}]);',
101116
errors: [{message: 'Unused injected value $q'}]
117+
}, {
118+
code: 'angular.module("").factory("", ["q", $q => {}]);',
119+
errors: [{message: 'Unused injected value $q'}],
120+
parserOptions: {ecmaVersion: 6}
102121
}, {
103122
code: 'var app = angular.module(""); app.factory("", function($q) {});',
104123
errors: [{message: 'Unused injected value $q'}]

test/no-run-logic.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ var RuleTester = require('eslint').RuleTester;
1414
var eslintTester = new RuleTester();
1515
eslintTester.run('no-run-logic', rule, {
1616
valid: [
17+
'\'use strict;\'',
1718
'angular.module("").run();',
1819
'angular.module("").run(function() {});',
1920
'angular.module("").run(function() {foo()});',

0 commit comments

Comments
 (0)