diff --git a/conf/eslint.json b/conf/eslint.json index 2c74c8cdff6..53b2e755906 100755 --- a/conf/eslint.json +++ b/conf/eslint.json @@ -99,6 +99,7 @@ "no-spaced-func": "off", "no-sparse-arrays": "error", "no-sync": "off", + "no-tabs": "off", "no-ternary": "off", "no-trailing-spaces": "off", "no-this-before-super": "error", diff --git a/docs/rules/no-tabs.md b/docs/rules/no-tabs.md new file mode 100644 index 00000000000..0829a2c692a --- /dev/null +++ b/docs/rules/no-tabs.md @@ -0,0 +1,41 @@ +# Disallow tabs in file (no-tabs) + +some style guides don't allow the use of tab characters anywhere. So they would want to disallow tab anywhere inside a file including comments. + +## Rule Details + +This rule looks for tabs inside the file. It can abe anywhere inside code or comments or anything. + +Examples of **incorrect** code for this rule: + +```js +var a /t= 2; + +/** +* /t/t its a test function +*/ +function test(){} + +var x = 1; // /t test +``` + +Examples of **correct** code for this rule: + +```js +var a = 2; + +/** +* its a test function +*/ +function test(){} + +var x = 1; // test +``` + +## When Not To Use It + +If you have established a standard where having tabs is fine. + +## Compatibility + +* **JSCS**: [disallowTabs](http://jscs.info/rule/disallowTabs) diff --git a/lib/rules/no-tabs.js b/lib/rules/no-tabs.js new file mode 100644 index 00000000000..ef873db2bdb --- /dev/null +++ b/lib/rules/no-tabs.js @@ -0,0 +1,47 @@ +/** + * @fileoverview Rule to check for tabs inside a file + * @author Gyandeep Singh + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ +const regex = /\t/; + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + docs: { + description: "Disallow tabs in file", + category: "Stylistic Issues", + recommended: false + }, + schema: [] + }, + + create(context) { + return { + Program(node) { + context.getSourceLines().forEach((line, index) => { + const match = regex.exec(line); + + if (match) { + context.report( + node, + { + line: index + 1, + column: match.index + 1 + }, + "Unexpected tab character." + ); + } + }); + } + }; + } +}; diff --git a/packages/eslint-config-eslint/default.yml b/packages/eslint-config-eslint/default.yml index 64d9a3b481e..f604776f8cd 100644 --- a/packages/eslint-config-eslint/default.yml +++ b/packages/eslint-config-eslint/default.yml @@ -72,6 +72,7 @@ rules: no-shadow: "error" no-shadow-restricted-names: "error" no-spaced-func: "error" + no-tabs: "error" no-trailing-spaces: "error" no-undef: "error" no-undef-init: "error" diff --git a/tests/lib/rules/no-tabs.js b/tests/lib/rules/no-tabs.js new file mode 100644 index 00000000000..43db670a209 --- /dev/null +++ b/tests/lib/rules/no-tabs.js @@ -0,0 +1,86 @@ +/** + * @fileoverview Tests for no-tabs rule + * @author Gyandeep Singh + */ +"use strict"; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const rule = require("../../../lib/rules/no-tabs"); +const RuleTester = require("../../../lib/testers/rule-tester"); + +//------------------------------------------------------------------------------ +// Tests +//------------------------------------------------------------------------------ + +const ruleTester = new RuleTester(); +const ERROR_MESSAGE = "Unexpected tab character."; + +ruleTester.run("no-tabs", rule, { + valid: [ + "function test(){\n}", + "function test(){\n" + + " // sdfdsf \n" + + "}", + ], + invalid: [ + { + code: "function test(){\t}", + errors: [{ + message: ERROR_MESSAGE, + line: 1, + column: 18 + }] + }, + { + code: "/** \t comment test */", + errors: [{ + message: ERROR_MESSAGE, + line: 1, + column: 6 + }] + }, + { + code: + "function test(){\n" + + " //\tsdfdsf \n" + + "}", + errors: [{ + message: ERROR_MESSAGE, + line: 2, + column: 6 + }] + }, + { + code: + "function\ttest(){\n" + + " //sdfdsf \n" + + "}", + errors: [{ + message: ERROR_MESSAGE, + line: 1, + column: 10 + }] + }, + { + code: + "function test(){\n" + + " //\tsdfdsf \n" + + "\t}", + errors: [ + { + message: ERROR_MESSAGE, + line: 2, + column: 6 + }, + { + message: ERROR_MESSAGE, + line: 3, + column: 2 + } + ] + } + ] +}); diff --git a/tests/lib/rules/no-underscore-dangle.js b/tests/lib/rules/no-underscore-dangle.js index 566c09e27b1..f739669570e 100644 --- a/tests/lib/rules/no-underscore-dangle.js +++ b/tests/lib/rules/no-underscore-dangle.js @@ -43,6 +43,6 @@ ruleTester.run("no-underscore-dangle", rule, { { code: "foo._bar;", errors: [{ message: "Unexpected dangling '_' in '_bar'.", type: "MemberExpression"}] }, { code: "this._prop;", errors: [{ message: "Unexpected dangling '_' in '_prop'.", type: "MemberExpression"}] }, { code: "class foo { constructor() { super._prop; } }", parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Unexpected dangling '_' in '_prop'.", type: "MemberExpression"}] }, - { code: "class foo { constructor() { this._prop; } }", options: [{allowAfterSuper: true}], parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Unexpected dangling '_' in '_prop'.", type: "MemberExpression"}] } + { code: "class foo { constructor() { this._prop; } }", options: [{allowAfterSuper: true}], parserOptions: { ecmaVersion: 6 }, errors: [{ message: "Unexpected dangling '_' in '_prop'.", type: "MemberExpression"}] } ] });