Skip to content

Commit 7739546

Browse files
Merge pull request #504 from Gillespie59/development
3.1.0
2 parents 1da9041 + 874106a commit 7739546

File tree

3 files changed

+115
-19
lines changed

3 files changed

+115
-19
lines changed

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": "3.0.2",
3+
"version": "3.1.0",
44
"description": "ESLint rules for AngularJS projects",
55
"main": "index.js",
66
"scripts": {

rules/file-name.js

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,38 @@ var path = require('path');
2323

2424
var utils = require('./utils/utils');
2525

26+
/**
27+
* The filename is the one for the import statement if we are in a module
28+
*
29+
* @param {any} node The current node being linted
30+
* @param {any} context The context
31+
* @param {any} defaultFilename The previous filename
32+
* @returns
33+
*/
34+
function handleModuleCase(node, context, defaultFilename) {
35+
if (context.parserOptions.sourceType !== 'module') {
36+
return defaultFilename;
37+
}
38+
39+
// Handle the module case.
40+
var name = node.arguments[1].name;
41+
var globalScope = context.getScope();
42+
43+
// Retrieve the import instruction.
44+
var variable = globalScope.variables.find(function(v) {
45+
return v.name === name;
46+
});
47+
48+
// Check that the definition is an import declaration.
49+
if (variable.defs[0].parent.type !== 'ImportDeclaration') {
50+
return defaultFilename;
51+
}
52+
53+
// Thanks to the chrome devtools to find the path of the filename. :-)
54+
var filename = path.basename(variable.defs[0].parent.source.value);
55+
return filename;
56+
}
57+
2658
module.exports = {
2759
meta: {
2860
schema: [{
@@ -117,7 +149,6 @@ module.exports = {
117149

118150
return function(context) {
119151
var options = context.options[0] || {};
120-
var filename = path.basename(context.getFilename());
121152
var componentTypeMappings = createComponentTypeMappings(options);
122153

123154
return {
@@ -135,6 +166,8 @@ module.exports = {
135166
return;
136167
}
137168
expectedName = filenameUtil.createExpectedName(name, type, options);
169+
var filename = path.basename(context.getFilename());
170+
filename = handleModuleCase(node, context, filename);
138171

139172
if (expectedName !== filename) {
140173
context.report(node, 'Filename must be "{{expectedName}}"', {

test/file-name.js

Lines changed: 80 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -259,42 +259,68 @@ angular.module(mod, [mod + '.core.angular', mod + '.thirdparty']);
259259
options: [{
260260
casing: 'pascal'
261261
}]
262+
}, {
263+
// import case
264+
filename: 'src/app/SomeOtherController.js',
265+
code: `
266+
var MyCtrl4 = function() {};
267+
import {MyCtrl1} from 'src/app/SomeController.js';
268+
import {MyCtrl2} from 'src/app/SomeDirective.js';
269+
import {MyCtrl3} from 'src/app/SomeService.js';
270+
app.controller("SomeController", MyCtrl1);
271+
app.directive("SomeDirective", MyCtrl2);
272+
app.service("SomeService", MyCtrl3);
273+
app.controller("SomeOtherController", MyCtrl4);`,
274+
parserOptions: {
275+
ecmaVersion: 6,
276+
sourceType: 'module'
277+
}
262278
}].concat(commonFalsePositives),
263279
invalid: [{
264280
filename: 'src/app/filters.js',
265281
code: 'app.filter("myFilter", function() {});',
266-
errors: [{message: 'Filename must be "myFilter.js"'}]
282+
errors: [{
283+
message: 'Filename must be "myFilter.js"'
284+
}]
267285
}, {
268286
filename: 'src/app/myFilter.js',
269287
code: 'app.filter("myFilter", function() {});',
270288
options: [{
271289
typeSeparator: 'dot'
272290
}],
273-
errors: [{message: 'Filename must be "myFilter.filter.js"'}]
291+
errors: [{
292+
message: 'Filename must be "myFilter.filter.js"'
293+
}]
274294
}, {
275295
// typeSeparator underscore with service
276296
filename: 'src/someService_controller.js',
277297
code: 'app.factory("someService", function() {});',
278298
options: [{
279299
typeSeparator: 'underscore'
280300
}],
281-
errors: [{message: 'Filename must be "someService_service.js"'}]
301+
errors: [{
302+
message: 'Filename must be "someService_service.js"'
303+
}]
282304
}, {
283305
// typeSeparator dot with controller, but no ignored type suffix
284306
filename: 'src/app/Avengers.controller.js',
285307
code: 'app.controller("AvengersController", function() {});',
286308
options: [{
287309
typeSeparator: 'dot'
288310
}],
289-
errors: [{message: 'Filename must be "AvengersController.controller.js"'}]
311+
errors: [{
312+
message: 'Filename must be "AvengersController.controller.js"'
313+
}]
290314
}, {
291315
// typeSeparator dot with component, but no ignored type suffix
292316
filename: 'src/app/Avengers.component.js',
293317
code: 'app.component("AvengersComponent", {});',
294318
options: [{
295319
typeSeparator: 'dot'
296320
}],
297-
errors: [{message: 'Filename must be "AvengersComponent.component.js"'}]
321+
errors: [{
322+
message: 'Filename must be "AvengersComponent.component.js"'
323+
}]
298324
}, {
299325
// typeSeparator dot with controller and ignored type suffix
300326
filename: 'src/app/AvengersController.controller.js',
@@ -303,7 +329,9 @@ angular.module(mod, [mod + '.core.angular', mod + '.thirdparty']);
303329
typeSeparator: 'dot',
304330
ignoreTypeSuffix: true
305331
}],
306-
errors: [{message: 'Filename must be "Avengers.controller.js"'}]
332+
errors: [{
333+
message: 'Filename must be "Avengers.controller.js"'
334+
}]
307335
}, {
308336
// typeSeparator dot with component and ignored type suffix
309337
filename: 'src/app/AvengersComponent.component.js',
@@ -312,7 +340,9 @@ angular.module(mod, [mod + '.core.angular', mod + '.thirdparty']);
312340
typeSeparator: 'dot',
313341
ignoreTypeSuffix: true
314342
}],
315-
errors: [{message: 'Filename must be "Avengers.component.js"'}]
343+
errors: [{
344+
message: 'Filename must be "Avengers.component.js"'
345+
}]
316346
}, {
317347
// nameStyle dash and typeSeparator dot with directive
318348
filename: 'src/app/avangerProfile.directive.js',
@@ -321,7 +351,9 @@ angular.module(mod, [mod + '.core.angular', mod + '.thirdparty']);
321351
typeSeparator: 'dot',
322352
nameStyle: 'dash'
323353
}],
324-
errors: [{message: 'Filename must be "avanger-profile.directive.js"'}]
354+
errors: [{
355+
message: 'Filename must be "avanger-profile.directive.js"'
356+
}]
325357
}, {
326358
// ignorePrefix xp
327359
filename: 'src/app/xpAsset.service.js',
@@ -331,7 +363,9 @@ angular.module(mod, [mod + '.core.angular', mod + '.thirdparty']);
331363
ignoreTypeSuffix: true,
332364
ignorePrefix: 'xp'
333365
}],
334-
errors: [{message: 'Filename must be "asset.service.js"'}]
366+
errors: [{
367+
message: 'Filename must be "asset.service.js"'
368+
}]
335369
}, {
336370
// ignorePrefix xp.
337371
filename: 'src/app/xpAsset.service.js',
@@ -341,7 +375,9 @@ angular.module(mod, [mod + '.core.angular', mod + '.thirdparty']);
341375
ignoreTypeSuffix: true,
342376
ignorePrefix: 'xp.'
343377
}],
344-
errors: [{message: 'Filename must be "asset.service.js"'}]
378+
errors: [{
379+
message: 'Filename must be "asset.service.js"'
380+
}]
345381
}, {
346382
// alphanumeric nameStyle dash and typeSeparator dash with service
347383
filename: 'src/app/app2utils-service.js',
@@ -350,7 +386,9 @@ angular.module(mod, [mod + '.core.angular', mod + '.thirdparty']);
350386
typeSeparator: 'dash',
351387
nameStyle: 'dash'
352388
}],
353-
errors: [{message: 'Filename must be "app2-utils-service.js"'}]
389+
errors: [{
390+
message: 'Filename must be "app2-utils-service.js"'
391+
}]
354392
}, {
355393
// alphanumeric nameStyle underscore and typeSeparator dot with directive
356394
filename: 'src/app/my2tab.directive.js',
@@ -359,7 +397,9 @@ angular.module(mod, [mod + '.core.angular', mod + '.thirdparty']);
359397
typeSeparator: 'dot',
360398
nameStyle: 'underscore'
361399
}],
362-
errors: [{message: 'Filename must be "my2_tab.directive.js"'}]
400+
errors: [{
401+
message: 'Filename must be "my2_tab.directive.js"'
402+
}]
363403
}, {
364404
// custom componentTypeMappings for provider
365405
filename: 'src/app/users.service.js',
@@ -370,7 +410,9 @@ angular.module(mod, [mod + '.core.angular', mod + '.thirdparty']);
370410
},
371411
typeSeparator: 'dot'
372412
}],
373-
errors: [{message: 'Filename must be "users.provider.js"'}]
413+
errors: [{
414+
message: 'Filename must be "users.provider.js"'
415+
}]
374416
}, {
375417
// camel casing, dot typeSeparator, ignoreTypeSuffix of true
376418
filename: 'src/app/SomeController.js',
@@ -380,15 +422,19 @@ angular.module(mod, [mod + '.core.angular', mod + '.thirdparty']);
380422
typeSeparator: 'dot',
381423
ignoreTypeSuffix: true
382424
}],
383-
errors: [{message: 'Filename must be "some.controller.js"'}]
425+
errors: [{
426+
message: 'Filename must be "some.controller.js"'
427+
}]
384428
}, {
385429
// camel casing
386430
filename: 'src/app/SomeController.js',
387431
code: 'app.controller("SomeController", function() {});',
388432
options: [{
389433
casing: 'camel'
390434
}],
391-
errors: [{message: 'Filename must be "someController.js"'}]
435+
errors: [{
436+
message: 'Filename must be "someController.js"'
437+
}]
392438
}, {
393439
// pascal casing, dot typeSeparator, ignoreTypeSuffix of true
394440
filename: 'src/app/someController.js',
@@ -398,14 +444,31 @@ angular.module(mod, [mod + '.core.angular', mod + '.thirdparty']);
398444
typeSeparator: 'dot',
399445
ignoreTypeSuffix: true
400446
}],
401-
errors: [{message: 'Filename must be "Some.controller.js"'}]
447+
errors: [{
448+
message: 'Filename must be "Some.controller.js"'
449+
}]
402450
}, {
403451
// pascal casing
404452
filename: 'src/app/someController.js',
405453
code: 'app.controller("SomeController", function() {});',
406454
options: [{
407455
casing: 'pascal'
408456
}],
409-
errors: [{message: 'Filename must be "SomeController.js"'}]
457+
errors: [{
458+
message: 'Filename must be "SomeController.js"'
459+
}]
460+
}, {
461+
// import case
462+
filename: 'src/app/SomeController.js',
463+
code: `
464+
import {MyCtrl} from 'src/app/main.js'
465+
app.controller("SomeController", MyCtrl);`,
466+
parserOptions: {
467+
ecmaVersion: 6,
468+
sourceType: 'module'
469+
},
470+
errors: [{
471+
message: 'Filename must be "SomeController.js"'
472+
}]
410473
}]
411474
});

0 commit comments

Comments
 (0)