This repository has been archived by the owner on Mar 23, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 515
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New rule: require-imports-alphabetized
- Loading branch information
Showing
3 changed files
with
187 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
/** | ||
* Requires imports to be alphabetised | ||
* | ||
* Types: `Boolean` | ||
* | ||
* Values: `true` to require imports to be ordered (A-Z) | ||
* | ||
* #### Example | ||
* | ||
* ```js | ||
* "requireImportAlphabetized": true | ||
* ``` | ||
* | ||
* ##### Valid | ||
* | ||
* ```js | ||
* import a from 'a'; | ||
* import c from 'c'; | ||
* import z from 'z'; | ||
* ``` | ||
* | ||
* ##### Invalid | ||
* | ||
* ```js | ||
* import a from 'a'; | ||
* import z from 'z'; | ||
* import c from 'c'; | ||
* ``` | ||
*/ | ||
|
||
var assert = require('assert'); | ||
|
||
module.exports = function() { | ||
}; | ||
|
||
module.exports.prototype = { | ||
|
||
configure: function(option) { | ||
assert( | ||
option === true, | ||
this.getOptionName() + ' option requires true value' | ||
); | ||
}, | ||
|
||
getOptionName: function() { | ||
return 'requireImportAlphabetized'; | ||
}, | ||
|
||
check: function(file, errors) { | ||
|
||
var previous; | ||
var current; | ||
|
||
var createSpecHash = function(specifier) { | ||
|
||
var imported = ''; | ||
var local = ''; | ||
|
||
if (specifier.imported && specifier.imported.name) { | ||
imported = specifier.imported.name; | ||
} | ||
|
||
if (specifier.local && specifier.local.name) { | ||
local = specifier.local.name; | ||
} | ||
|
||
return imported === local ? imported : imported + local; | ||
|
||
}; | ||
|
||
file.iterateNodesByType( | ||
'ImportDeclaration', | ||
function(node) { | ||
|
||
current = ''; | ||
|
||
for (var i = 0; i < node.specifiers.length; i++) { | ||
current += createSpecHash(node.specifiers[i]); | ||
} | ||
|
||
if (node.source && node.source.value) { | ||
current += node.source.value; | ||
} | ||
|
||
if (previous && previous > current) { | ||
errors.add('imports must be alphabetized', | ||
node.loc.start.line, node.loc.start.column); | ||
} | ||
|
||
previous = current; | ||
} | ||
); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
var Checker = require('../../../lib/checker'); | ||
var expect = require('chai').expect; | ||
|
||
describe('rules/require-imports-aplhabetized', function() { | ||
var checker; | ||
|
||
beforeEach(function() { | ||
checker = new Checker(); | ||
checker.registerDefaultRules(); | ||
checker.configure({ requireImportAlphabetized: true }); | ||
}); | ||
|
||
it('should report no errors when there are no imports', function() { | ||
var code = '// no imports here;\n' + | ||
'var looping = function(n) {\n' + | ||
'var a = 0, b = 1, f = 1;\n' + | ||
'for(var i = 2; i <= n; i++) {\n' + | ||
'f = a + b;\n' + | ||
'a = b;\n' + | ||
'b = f;\n' + | ||
'}\n' + | ||
'return f; \n' + | ||
'};'; | ||
|
||
expect(checker.checkString(code)).to.have.no.errors(); | ||
}); | ||
|
||
it('should report no errors for ordered imports', function() { | ||
var code = 'import A from \'A\';\nimport C from \'C\';\nimport Z from \'Z\';'; | ||
expect(checker.checkString(code)).to.have.no.errors(); | ||
}); | ||
|
||
it('should report no errors for ordered import multiline', function() { | ||
var code = 'import A\n from\n \'A\';\nimport C\n from \'C\';\nimport Z\n from \'Z\';'; | ||
expect(checker.checkString(code)).to.have.no.errors(); | ||
}); | ||
|
||
it('should report one error for un-ordered imports', function() { | ||
var code = 'import A from \'A\';\nimport Z from \'Z\';\nimport B from \'B\';'; | ||
expect(checker.checkString(code)).to.have.one.error(); | ||
}); | ||
|
||
it('should report no errors for ordered named imports', function() { | ||
var code = 'import { A as myNamed1, named2 } from \'src/mylib\';\n' + | ||
'import { B as myNamed1, named2 } from \'src/mylib\';\n' + | ||
'import { C as myNamed1, named2 } from \'src/mylib\';'; | ||
|
||
expect(checker.checkString(code)).to.have.no.errors(); | ||
}); | ||
|
||
it('should report one error for un-ordered named imports', function() { | ||
var code = 'import { Z as myNamed1, named2 } from \'src/mylib\';\n' + | ||
'import { B as myNamed1, named2 } from \'src/mylib\';\n' + | ||
'import { C as myNamed1, named2 } from \'src/mylib\';'; | ||
|
||
expect(checker.checkString(code)).to.have.one.error(); | ||
}); | ||
|
||
it('should report no errors for ordered module as an object import', function() { | ||
var code = 'import * from \'src/A\';\n' + | ||
'import * from \'src/B\';\n' + | ||
'import * from \'src/C\';'; | ||
|
||
expect(checker.checkString(code)).to.have.no.error(); | ||
}); | ||
|
||
it('should report one error for un-ordered module as an object import', function() { | ||
var code = 'import * from \'src/A\';\n' + | ||
'import * from \'src/Z\';\n' + | ||
'import * from \'src/C\';'; | ||
|
||
expect(checker.checkString(code)).to.have.one.error(); | ||
}); | ||
|
||
it('should report no errors for ordered module import', function() { | ||
var code = 'import \'src/A\';\n' + | ||
'import \'src/B\';\n' + | ||
'import \'src/C\';'; | ||
|
||
expect(checker.checkString(code)).to.have.no.error(); | ||
}); | ||
|
||
it('should report one error for un-ordered module import', function() { | ||
var code = 'import \'src/Z\';\n import \'src/B\';\nimport \'src/C\';'; | ||
expect(checker.checkString(code)).to.have.one.error(); | ||
}); | ||
|
||
it('should report multiple errors for un-ordered module import', function() { | ||
var code = 'import \'src/C\';\n import \'src/B\';\nimport \'src/A\';'; | ||
expect(checker.checkString(code)).to.have.validation.errors.from('requireImportAlphabetized'); | ||
}); | ||
}); |