Skip to content
Merged

2.3.0 #467

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 3 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ Since the 0.0.4 release, some rules defined in [John Papa's Guideline](https://g

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

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.

1. Install `eslint` as a dev-dependency:

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

3. Install `eslint-config-angular` as a dev-dependency:

```shell
npm install --save-dev eslint-config-angular
```

4. Use the shareable config by adding it to your `.eslintrc`:
3. Use the shareable config by adding it to your `.eslintrc`:

```yaml
extends: angular
extends: plugin:angular/johnpapa
```


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

The following rules detect patterns that can lead to errors.

* [avoid-scope-typos](docs/avoid-scope-typos.md) - Avoid mistakes when naming methods defined on the scope object
* [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))
* [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))
* [no-private-call](docs/no-private-call.md) - disallow use of internal angular properties prefixed with $$
Expand Down
42 changes: 42 additions & 0 deletions docs/avoid-scope-typos.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<!-- WARNING: Generated documentation. Edit docs and examples in the rule and examples file ('rules/avoid-scope-typos.js', 'examples/avoid-scope-typos.js'). -->

# avoid-scope-typos - Avoid mistakes when naming methods defined on the scope object

For example, you want to use $scope.$watch instead of $scope.watch

**Rule based on Angular 1.x**

## Examples

The following patterns are considered problems;

/*eslint angular/avoid-scope-typos: 2*/

// invalid
$scope.apply.forEach(function (watcher) {
// ...
}); // error: The apply method should be replaced by $apply, or you should rename it in order to avoid confusions

// invalid
$rootScope.apply.forEach(function (watcher) {
// ...
}); // error: The apply method should be replaced by $apply, or you should rename it in order to avoid confusions

The following patterns are **not** considered problems;

/*eslint angular/avoid-scope-typos: 2*/

// valid
$scope.$apply();

// valid
$rootScope.$apply();

## Version

This rule was introduced in eslint-plugin-angular 2.3.0

## Links

* [Rule source](../rules/avoid-scope-typos.js)
* [Example source](../examples/avoid-scope-typos.js)
15 changes: 15 additions & 0 deletions examples/avoid-scope-typos.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// example - valid: true
$scope.$apply();

// example - valid: false, errorMessage: "The apply method should be replaced by $apply, or you should rename it in order to avoid confusions"
$scope.apply.forEach(function (watcher) {
// ...
});

// example - valid: true
$rootScope.$apply();

// example - valid: false, errorMessage: "The apply method should be replaced by $apply, or you should rename it in order to avoid confusions"
$rootScope.apply.forEach(function (watcher) {
// ...
});
58 changes: 57 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,61 @@ fs.readdirSync(ruleDir).forEach(function(name) {

module.exports = {
rules: rules,
environments: require('./environments')
environments: require('./environments'),
configs: {
johnpapa: {
plugins: [
'angular'
],
rules: {
'angular/component-name': 2,
'angular/constant-name': 2,
'angular/controller-as-route': 2,
'angular/controller-as-vm': 2,
'angular/controller-as': 2,
'angular/controller-name': 2,
'angular/directive-name': 2,
'angular/directive-restrict': 2,
'angular/document-service': 2,
'angular/factory-name': 2,
'angular/file-name': 2,
'angular/filter-name': 2,
'angular/function-type': 2,
'angular/interval-service': 2,
'angular/module-getter': 2,
'angular/module-name': 2,
'angular/module-setter': 2,
'angular/no-run-logic': 2,
'angular/no-service-method': 2,
'angular/provider-name': 2,
'angular/service-name': 2,
'angular/timeout-service': 2,
'angular/value-name': 2,
'angular/window-service': 2
}
},
bestpractices: {
plugins: [
'angular'
],
rules: {
'angular/component-name': 2,
'angular/constant-name': 2,
'angular/controller-as-route': 2,
'angular/controller-as-vm': 2,
'angular/controller-as': 2,
'angular/deferred': 2,
'angular/di-unused': 2,
'angular/directive-restrict': 2,
'angular/empty-controller': 2,
'angular/no-controller': 2,
'angular/no-inline-template': 2,
'angular/no-run-logic': 2,
'angular/no-service-method': 2,
'angular/no-services': 2,
'angular/on-watch': 2,
'angular/prefer-component': 2
}
}
}
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "eslint-plugin-angular",
"version": "2.2.1",
"version": "2.3.0",
"description": "ESLint rules for AngularJS projects",
"main": "index.js",
"scripts": {
Expand Down
33 changes: 33 additions & 0 deletions rules/avoid-scope-typos.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* Avoid mistakes when naming methods defined on the scope object
*
* For example, you want to use $scope.$watch instead of $scope.watch
*
* @version 2.3.0
* @category possibleError
* @sinceAngularVersion 1.x
*/
'use strict';

const bad = ['new', 'watch', 'watchGroup', 'watchCollection',
'digest', 'destroy', 'eval', 'evalAsync', 'apply',
'applyAsync', 'on', 'emit', 'broadcast'];

module.exports = {
meta: {
schema: [ ]
},
create: function(context) {
function check(node, name) {
if (bad.indexOf(name) >= 0) {
context.report(node, `The ${name} method should be replaced by $${name}, or you should rename it in order to avoid confusions`, {});
}
}
return {

Identifier: function(node) {
check(node, node.name);
}
};
}
};
2 changes: 1 addition & 1 deletion rules/utils/angular-rule.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ function angularRule(ruleDefinition) {
if (node.type === 'ArrayExpression') {
node = node.elements[node.elements.length - 1] || {};
}
if (node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration') {
if (node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression' || node.type === 'FunctionDeclaration') {
return node;
}
if (node.type !== 'Identifier') {
Expand Down
44 changes: 44 additions & 0 deletions test/avoid-scope-typos.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
'use strict';

// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------

const rule = require('../rules/avoid-scope-typos');
const RuleTester = require('eslint').RuleTester;
const commonFalsePositives = require('./utils/commonFalsePositives');

// ------------------------------------------------------------------------------
// Tests
// ------------------------------------------------------------------------------

const eslintTester = new RuleTester();

const variables = ['$scope', '$rootScope'];
const bad = ['new', 'watch', 'watchGroup', 'watchCollection',
'digest', 'destroy', 'eval', 'evalAsync', 'apply',
'applyAsync', 'on', 'emit', 'broadcast'];

var invalid = [];
var valid = [];

variables.forEach(function(variable) {
bad.forEach(function(b) {
invalid.push({
code: variable + '.' + b,
errors: [{message: `The ${b} method should be replaced by $${b}, or you should rename it in order to avoid confusions`}]
});
});
});

variables.forEach(function(variable) {
bad.forEach(function(b) {
valid.push({
code: variable + '.$' + b
});
});
});
eslintTester.run('avoid-scope-typos', rule, {
valid: valid.concat(commonFalsePositives),
invalid
});
19 changes: 19 additions & 0 deletions test/di-unused.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ eslintTester.run('di-unused', rule, {
code: 'angular.module("").controller("", fn); function fn($q) {}',
errors: [{message: 'Unused injected value $q'}]
},
{
code: 'angular.module("").controller("", ["$q", ($q) => {}]);',
parserOptions: {ecmaVersion: 6},
errors: [{message: 'Unused injected value $q'}]
},
{
code: 'angular.module("").controller("", ($q) => {});',
parserOptions: {ecmaVersion: 6},
errors: [{message: 'Unused injected value $q'}]
},
// directive
{
code: 'angular.module("").directive("", function($q) {});',
Expand All @@ -96,9 +106,18 @@ eslintTester.run('di-unused', rule, {
{
code: 'angular.module("").factory("", function($q) {});',
errors: [{message: 'Unused injected value $q'}]
},
{
code: 'angular.module("").factory("", $q => {});',
errors: [{message: 'Unused injected value $q'}],
parserOptions: {ecmaVersion: 6}
}, {
code: 'angular.module("").factory("", ["q", function($q) {}]);',
errors: [{message: 'Unused injected value $q'}]
}, {
code: 'angular.module("").factory("", ["q", $q => {}]);',
errors: [{message: 'Unused injected value $q'}],
parserOptions: {ecmaVersion: 6}
}, {
code: 'var app = angular.module(""); app.factory("", function($q) {});',
errors: [{message: 'Unused injected value $q'}]
Expand Down
1 change: 1 addition & 0 deletions test/no-run-logic.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ var RuleTester = require('eslint').RuleTester;
var eslintTester = new RuleTester();
eslintTester.run('no-run-logic', rule, {
valid: [
'\'use strict;\'',
'angular.module("").run();',
'angular.module("").run(function() {});',
'angular.module("").run(function() {foo()});',
Expand Down
Loading