Skip to content
This repository was archived by the owner on Mar 23, 2024. It is now read-only.

Commit 17daa29

Browse files
rhehmarkelog
authored andcommitted
New rule: require-imports-alphabetized
Requires imports to be alphabetised Fixes #2049 Closes gh-2091
1 parent 9c45089 commit 17daa29

File tree

3 files changed

+187
-0
lines changed

3 files changed

+187
-0
lines changed

lib/config/configuration.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -956,6 +956,7 @@ Configuration.prototype.registerDefaultRules = function() {
956956
this.registerRule(require('../rules/require-enhanced-object-literals'));
957957
this.registerRule(require('../rules/require-array-destructuring'));
958958
this.registerRule(require('../rules/disallow-var'));
959+
this.registerRule(require('../rules/require-imports-alphabetized'));
959960
/* ES6 only (end) */
960961

961962
this.registerRule(require('../rules/require-curly-braces'));
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/**
2+
* Requires imports to be alphabetised
3+
*
4+
* Types: `Boolean`
5+
*
6+
* Values: `true` to require imports to be ordered (A-Z)
7+
*
8+
* #### Example
9+
*
10+
* ```js
11+
* "requireImportAlphabetized": true
12+
* ```
13+
*
14+
* ##### Valid
15+
*
16+
* ```js
17+
* import a from 'a';
18+
* import c from 'c';
19+
* import z from 'z';
20+
* ```
21+
*
22+
* ##### Invalid
23+
*
24+
* ```js
25+
* import a from 'a';
26+
* import z from 'z';
27+
* import c from 'c';
28+
* ```
29+
*/
30+
31+
var assert = require('assert');
32+
33+
module.exports = function() {
34+
};
35+
36+
module.exports.prototype = {
37+
38+
configure: function(option) {
39+
assert(
40+
option === true,
41+
this.getOptionName() + ' option requires true value'
42+
);
43+
},
44+
45+
getOptionName: function() {
46+
return 'requireImportAlphabetized';
47+
},
48+
49+
check: function(file, errors) {
50+
51+
var previous;
52+
var current;
53+
54+
var createSpecHash = function(specifier) {
55+
56+
var imported = '';
57+
var local = '';
58+
59+
if (specifier.imported && specifier.imported.name) {
60+
imported = specifier.imported.name;
61+
}
62+
63+
if (specifier.local && specifier.local.name) {
64+
local = specifier.local.name;
65+
}
66+
67+
return imported === local ? imported : imported + local;
68+
69+
};
70+
71+
file.iterateNodesByType(
72+
'ImportDeclaration',
73+
function(node) {
74+
75+
current = '';
76+
77+
for (var i = 0; i < node.specifiers.length; i++) {
78+
current += createSpecHash(node.specifiers[i]);
79+
}
80+
81+
if (node.source && node.source.value) {
82+
current += node.source.value;
83+
}
84+
85+
if (previous && previous > current) {
86+
errors.add('imports must be alphabetized',
87+
node.loc.start.line, node.loc.start.column);
88+
}
89+
90+
previous = current;
91+
}
92+
);
93+
}
94+
};
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
var Checker = require('../../../lib/checker');
2+
var expect = require('chai').expect;
3+
4+
describe('rules/require-imports-aplhabetized', function() {
5+
var checker;
6+
7+
beforeEach(function() {
8+
checker = new Checker();
9+
checker.registerDefaultRules();
10+
checker.configure({ requireImportAlphabetized: true });
11+
});
12+
13+
it('should report no errors when there are no imports', function() {
14+
var code = '// no imports here;\n' +
15+
'var looping = function(n) {\n' +
16+
'var a = 0, b = 1, f = 1;\n' +
17+
'for(var i = 2; i <= n; i++) {\n' +
18+
'f = a + b;\n' +
19+
'a = b;\n' +
20+
'b = f;\n' +
21+
'}\n' +
22+
'return f; \n' +
23+
'};';
24+
25+
expect(checker.checkString(code)).to.have.no.errors();
26+
});
27+
28+
it('should report no errors for ordered imports', function() {
29+
var code = 'import A from \'A\';\nimport C from \'C\';\nimport Z from \'Z\';';
30+
expect(checker.checkString(code)).to.have.no.errors();
31+
});
32+
33+
it('should report no errors for ordered import multiline', function() {
34+
var code = 'import A\n from\n \'A\';\nimport C\n from \'C\';\nimport Z\n from \'Z\';';
35+
expect(checker.checkString(code)).to.have.no.errors();
36+
});
37+
38+
it('should report one error for un-ordered imports', function() {
39+
var code = 'import A from \'A\';\nimport Z from \'Z\';\nimport B from \'B\';';
40+
expect(checker.checkString(code)).to.have.one.error();
41+
});
42+
43+
it('should report no errors for ordered named imports', function() {
44+
var code = 'import { A as myNamed1, named2 } from \'src/mylib\';\n' +
45+
'import { B as myNamed1, named2 } from \'src/mylib\';\n' +
46+
'import { C as myNamed1, named2 } from \'src/mylib\';';
47+
48+
expect(checker.checkString(code)).to.have.no.errors();
49+
});
50+
51+
it('should report one error for un-ordered named imports', function() {
52+
var code = 'import { Z as myNamed1, named2 } from \'src/mylib\';\n' +
53+
'import { B as myNamed1, named2 } from \'src/mylib\';\n' +
54+
'import { C as myNamed1, named2 } from \'src/mylib\';';
55+
56+
expect(checker.checkString(code)).to.have.one.error();
57+
});
58+
59+
it('should report no errors for ordered module as an object import', function() {
60+
var code = 'import * from \'src/A\';\n' +
61+
'import * from \'src/B\';\n' +
62+
'import * from \'src/C\';';
63+
64+
expect(checker.checkString(code)).to.have.no.error();
65+
});
66+
67+
it('should report one error for un-ordered module as an object import', function() {
68+
var code = 'import * from \'src/A\';\n' +
69+
'import * from \'src/Z\';\n' +
70+
'import * from \'src/C\';';
71+
72+
expect(checker.checkString(code)).to.have.one.error();
73+
});
74+
75+
it('should report no errors for ordered module import', function() {
76+
var code = 'import \'src/A\';\n' +
77+
'import \'src/B\';\n' +
78+
'import \'src/C\';';
79+
80+
expect(checker.checkString(code)).to.have.no.error();
81+
});
82+
83+
it('should report one error for un-ordered module import', function() {
84+
var code = 'import \'src/Z\';\n import \'src/B\';\nimport \'src/C\';';
85+
expect(checker.checkString(code)).to.have.one.error();
86+
});
87+
88+
it('should report multiple errors for un-ordered module import', function() {
89+
var code = 'import \'src/C\';\n import \'src/B\';\nimport \'src/A\';';
90+
expect(checker.checkString(code)).to.have.validation.errors.from('requireImportAlphabetized');
91+
});
92+
});

0 commit comments

Comments
 (0)