diff --git a/src/index.js b/src/index.js index 52d5668c5..8f4ee7b55 100644 --- a/src/index.js +++ b/src/index.js @@ -8,6 +8,7 @@ export const rules = { 'no-mutable-exports': require('./rules/no-mutable-exports'), 'extensions': require('./rules/extensions'), 'no-restricted-paths': require('./rules/no-restricted-paths'), + 'no-self-import': require('./rules/no-self-import'), 'no-named-as-default': require('./rules/no-named-as-default'), 'no-named-as-default-member': require('./rules/no-named-as-default-member'), diff --git a/src/rules/no-self-import.js b/src/rules/no-self-import.js new file mode 100644 index 000000000..a439ce7cf --- /dev/null +++ b/src/rules/no-self-import.js @@ -0,0 +1,17 @@ +var path = require('path') + +module.exports = function (context) { + function checkSelfImport(node) { + var fileName = path.basename(context.getFilename()) + var fileNameNoExtension = path.basename(fileName, path.extname(fileName)) + var badPaths = ['./' + fileName, './' + fileNameNoExtension] + + if (~badPaths.indexOf(node.source.value)) { + context.report(node, 'Importing from the current file.') + } + } + + return { + 'ImportDeclaration': checkSelfImport.bind(null), + } +} diff --git a/tests/src/rules/no-self-import.js b/tests/src/rules/no-self-import.js new file mode 100644 index 000000000..32509f6c8 --- /dev/null +++ b/tests/src/rules/no-self-import.js @@ -0,0 +1,73 @@ +import { test, SYNTAX_CASES } from '../utils' +import { RuleTester } from 'eslint' + +const ruleTester = new RuleTester() + , rule = require('rules/no-self-import') + +ruleTester.run('no-self-import', rule, { + valid: [ + test({ filename: 'foo', code: 'import "./bar"' }), + test({ filename: 'foo', code: 'import "./bar.js"' }), + test({ filename: 'foo.js', code: 'import "./bar"' }), + test({ filename: 'foo.js', code: 'import "./bar.js"' }), + test({ filename: 'foo.jsx', code: 'import "./bar"' }), + test({ filename: 'foo.jsx', code: 'import "./bar.jsx"' }), + test({ filename: 'foo.jsx', code: 'import "./foo.js"' }), + + // es7 + test({ filename: 'foo.js', code: 'export bar, { foo } from "./bar";', parser: 'babel-eslint' }), + test({ filename: 'foo.js', code: 'export bar from "./bar";', parser: 'babel-eslint' }), + + ...SYNTAX_CASES, + ], + + invalid: [ + test({ + code: 'import "./foo";', + filename: 'foo.jsx', + errors: [ + { message: 'Importing from the current file.', type: 'ImportDeclaration' }, + ] + }), + + test({ + code: 'import "./foo.jsx";', + filename: 'foo.jsx', + errors: [ + { message: 'Importing from the current file.', type: 'ImportDeclaration' }, + ] + }), + + test({ + code: 'import foo from "./foo";', + filename: 'foo.jsx', + errors: [ + { message: 'Importing from the current file.', type: 'ImportDeclaration' }, + ] + }), + + test({ + code: 'import foo from "./foo.jsx";', + filename: 'foo.jsx', + errors: [ + { message: 'Importing from the current file.', type: 'ImportDeclaration' }, + ] + }), + + test({ + code: 'import { foo } from "./foo";', + filename: 'foo.jsx', + errors: [ + { message: 'Importing from the current file.', type: 'ImportDeclaration' }, + ] + }), + + test({ + code: 'import { foo } from "./foo.jsx";', + filename: 'foo.jsx', + errors: [ + { message: 'Importing from the current file.', type: 'ImportDeclaration' }, + ] + }), + ], +})