Skip to content

Commit 11dd630

Browse files
committed
Merge pull request #230 from rayners/master
Added a $inject option for the di rule
2 parents 61a0abb + 4b4ce82 commit 11dd630

File tree

3 files changed

+99
-6
lines changed

3 files changed

+99
-6
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ Users may use the shareable [eslint-config-angular](https://github.com/dustinspe
172172
| controller-name | All your controllers should have a name starting with the parameter you can define in your config object. The second parameter can be a Regexp wrapped in quotes. ("controller-name": [2, "ng"]) [Y123](https://github.com/johnpapa/angular-styleguide#style-y123), [Y124](https://github.com/johnpapa/angular-styleguide#style-y124)|
173173
| deferred | When you want to create a new promise, you should not use the $q.deferred anymore. Prefer the new syntax : $q(function(resolve, reject){}) |
174174
| definedundefined | You should use the angular.isUndefined or angular.isDefined methods instead of using the keyword undefined. We also check the use of !angular.isUndefined and !angular.isDefined (should prefer the reverse function)|
175-
| di | All your DI should use the same syntax : the Array or function syntaxes ("di": [2, "function or array"])|
175+
| di | All your DI should use the same syntax : the Array, function, or $inject syntaxes ("di": [2, "array, function, or $inject"])|
176176
| di-order | Injected dependencies should be sorted alphabetically. If the second parameter is set to false, values which start and end with an underscore those underscores are stripped. This means for example that `_$httpBackend_` goes before `_$http_`. |
177177
| di-unused | Unused dependencies should not be injected. |
178178
| directive-name | All your directives should have a name starting with the parameter you can define in your config object. The second parameter can be a Regexp wrapped in quotes. You can not prefix your directives by "ng" (reserved keyword for AngularJS directives) ("directive-name": [2, "ng"]) [Y073](https://github.com/johnpapa/angular-styleguide#style-y073), [Y126](https://github.com/johnpapa/angular-styleguide#style-y126) |

rules/di.js

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,46 @@ module.exports = function(context) {
1111
});
1212
}
1313

14+
var noninjectedFunctions = {};
15+
var injectedFunctions = [];
16+
1417
function checkDi(syntax, node, param) {
1518
if (syntax === 'function' && (!utils.isFunctionType(param) && !utils.isIdentifierType(param))) {
1619
report(node, syntax);
17-
}
18-
if (syntax === 'array') {
19-
if (!utils.isArrayType(param)) {
20-
report(node, syntax);
21-
} else {
20+
} else if (syntax === 'array') {
21+
if (utils.isArrayType(param)) {
2222
var fn = param.elements[param.elements.length - 1];
2323
if (utils.isFunctionType(fn) && fn.params.length !== param.elements.length - 1) {
2424
context.report(fn, 'The signature of the method is incorrect', {});
2525
}
26+
} else {
27+
report(node, syntax);
28+
}
29+
} else if (syntax === '$inject') {
30+
if (utils.isIdentifierType(param)) {
31+
noninjectedFunctions[param.name] = node;
32+
} else {
33+
report(node, syntax);
34+
}
35+
}
36+
}
37+
38+
function maybeNoteInjection(syntax, node) {
39+
if (syntax === '$inject' && node.left && node.left.property &&
40+
((utils.isLiteralType(node.left.property) && node.left.property.value === '$inject') ||
41+
(utils.isIdentifierType(node.left.property) && node.left.property.name === '$inject'))) {
42+
injectedFunctions.push(node.left.object.name);
43+
}
44+
}
45+
46+
function verifyInjections(syntax) {
47+
if (syntax === '$inject') {
48+
injectedFunctions.forEach(function(f) {
49+
delete noninjectedFunctions[f];
50+
});
51+
52+
for (var func in noninjectedFunctions) {
53+
report(noninjectedFunctions[func], syntax);
2654
}
2755
}
2856
}
@@ -41,6 +69,12 @@ module.exports = function(context) {
4169
*/
4270
checkDi(context.options[0], node, node.arguments[0]);
4371
}
72+
},
73+
AssignmentExpression: function(node) {
74+
maybeNoteInjection(context.options[0], node);
75+
},
76+
'Program:exit': function() {
77+
verifyInjections(context.options[0]);
4478
}
4579
};
4680
};

test/di.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,21 @@ angularObjectList.forEach(function(object) {
2828
}, {
2929
code: 'angular.' + object + '(myFunction);function MyFunction() {}',
3030
options: ['function']
31+
}, {
32+
code: 'angular.' + object + '(myFunction);myFunction.$inject=[];function myFunction() {}',
33+
options: ['$inject']
34+
}, {
35+
code: 'angular.' + object + '(myFunction);myFunction["$inject"]=[];function myFunction() {}',
36+
options: ['$inject']
37+
}, {
38+
code: 'myFunction.$inject=[];function myFunction() {} angular.' + object + '(myFunction);',
39+
options: ['$inject']
40+
}, {
41+
code: 'function myFunction() {} myFunction.$inject=[];angular.' + object + '(myFunction);',
42+
options: ['$inject']
43+
}, {
44+
code: 'var myFunction = function() {}; myFunction.$inject=[];angular.' + object + '(myFunction);',
45+
options: ['$inject']
3146
});
3247

3348
invalid.push({
@@ -46,6 +61,22 @@ angularObjectList.forEach(function(object) {
4661
code: 'angular.' + object + '([function(Service1) {}]);',
4762
options: ['array'],
4863
errors: [{message: 'The signature of the method is incorrect'}]
64+
}, {
65+
code: 'angular.' + object + '(myFunction); function myFunction() {}',
66+
options: ['$inject'],
67+
errors: [{message: 'You should use the $inject syntax for DI'}]
68+
}, {
69+
code: 'function myFunction() {} angular.' + object + '(myFunction);',
70+
options: ['$inject'],
71+
errors: [{message: 'You should use the $inject syntax for DI'}]
72+
}, {
73+
code: 'var myFunction = function() {};angular.' + object + '(myFunction);',
74+
options: ['$inject'],
75+
errors: [{message: 'You should use the $inject syntax for DI'}]
76+
}, {
77+
code: 'angular.' + object + '(function() {});',
78+
options: ['$inject'],
79+
errors: [{message: 'You should use the $inject syntax for DI'}]
4980
});
5081
});
5182

@@ -62,6 +93,18 @@ angularNamedObjectList.forEach(function(object) {
6293
}, {
6394
code: 'angular.' + object + '("name", myFunction);function MyFunction() {}',
6495
options: ['function']
96+
}, {
97+
code: 'angular.' + object + '("name", myFunction);myFunction.$inject=[];function myFunction() {}',
98+
options: ['$inject']
99+
}, {
100+
code: 'myFunction.$inject=[];function myFunction() {} angular.' + object + '("name", myFunction);',
101+
options: ['$inject']
102+
}, {
103+
code: 'function myFunction() {} myFunction.$inject=[];angular.' + object + '("name", myFunction);',
104+
options: ['$inject']
105+
}, {
106+
code: 'var myFunction = function() {}; myFunction.$inject=[];angular.' + object + '("name", myFunction);',
107+
options: ['$inject']
65108
});
66109

67110
invalid.push({
@@ -80,6 +123,22 @@ angularNamedObjectList.forEach(function(object) {
80123
code: 'angular.' + object + '("name", [function(Service1) {}]);',
81124
options: ['array'],
82125
errors: [{message: 'The signature of the method is incorrect'}]
126+
}, {
127+
code: 'angular.' + object + '("name", myFunction); function myFunction() {}',
128+
options: ['$inject'],
129+
errors: [{message: 'You should use the $inject syntax for DI'}]
130+
}, {
131+
code: 'function myFunction() {} angular.' + object + '("name", myFunction);',
132+
options: ['$inject'],
133+
errors: [{message: 'You should use the $inject syntax for DI'}]
134+
}, {
135+
code: 'var myFunction = function () {};angular.' + object + '("name", myFunction);',
136+
options: ['$inject'],
137+
errors: [{message: 'You should use the $inject syntax for DI'}]
138+
}, {
139+
code: 'angular.' + object + '("name", function() {});',
140+
options: ['$inject'],
141+
errors: [{message: 'You should use the $inject syntax for DI'}]
83142
});
84143
});
85144

0 commit comments

Comments
 (0)