From 3e991bf8a1434b2890a07fe886a5b9e95909a1b5 Mon Sep 17 00:00:00 2001 From: Imad Elyafi Date: Wed, 21 Dec 2016 14:13:27 -0800 Subject: [PATCH] Autofixer for newline-after-import. Fixes #686 --- .gitignore | 3 +++ docs/rules/newline-after-import.md | 1 + src/rules/newline-after-import.js | 18 ++++++++++++------ tests/src/rules/newline-after-import.js | 15 ++++++++++++++- 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 24ceac8ff2..25ab23821a 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,6 @@ node_modules # generated output lib/ **/.nyc_output/ + +# IDE files +.idea diff --git a/docs/rules/newline-after-import.md b/docs/rules/newline-after-import.md index 0ad2cba015..441fc29d7c 100644 --- a/docs/rules/newline-after-import.md +++ b/docs/rules/newline-after-import.md @@ -1,6 +1,7 @@ # newline-after-import Enforces having an empty line after the last top-level import statement or require call. ++(fixable) The `--fix` option on the [command line] automatically fixes problems reported by this rule. ## Rule Details diff --git a/src/rules/newline-after-import.js b/src/rules/newline-after-import.js index 3198a95792..49dad2b126 100644 --- a/src/rules/newline-after-import.js +++ b/src/rules/newline-after-import.js @@ -42,24 +42,29 @@ function isClassWithDecorator(node) { return node.type === 'ClassDeclaration' && node.decorators && node.decorators.length } +const EXPECTED_LINE_DIFFERENCE = 2; + module.exports = { meta: { docs: {}, + fixable: "code", }, create: function (context) { - let level = 0 - const requireCalls = [] + let level = 0; + const requireCalls = []; function checkForNewLine(node, nextNode, type) { if (isClassWithDecorator(nextNode)) { - nextNode = nextNode.decorators[0] + nextNode = nextNode.decorators[0]; } - if (getLineDifference(node, nextNode) < 2) { - let column = node.loc.start.column + const lineDifference = getLineDifference(node, nextNode); + + if (lineDifference < EXPECTED_LINE_DIFFERENCE) { + let column = node.loc.start.column; if (node.loc.start.line !== node.loc.end.line) { - column = 0 + column = 0; } context.report({ @@ -68,6 +73,7 @@ module.exports = { column, }, message: `Expected empty line after ${type} statement not followed by another ${type}.`, + fix: fixer => fixer.insertTextAfter(node, '\n'.repeat(EXPECTED_LINE_DIFFERENCE - lineDifference)), }) } } diff --git a/tests/src/rules/newline-after-import.js b/tests/src/rules/newline-after-import.js index afd942ef0b..2c41415adc 100644 --- a/tests/src/rules/newline-after-import.js +++ b/tests/src/rules/newline-after-import.js @@ -146,6 +146,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { invalid: [ { code: "import foo from 'foo';\nexport default function() {};", + output: "import foo from 'foo';\n\nexport default function() {};", errors: [ { line: 1, column: 1, @@ -155,6 +156,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { }, { code: "var foo = require('foo-module');\nvar something = 123;", + output: "var foo = require('foo-module');\n\nvar something = 123;", errors: [ { line: 1, column: 1, @@ -164,6 +166,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { }, { code: "import foo from 'foo';\nvar a = 123;\n\nimport { bar } from './bar-lib';\nvar b=456;", + output: "import foo from 'foo';\n\nvar a = 123;\n\nimport { bar } from './bar-lib';\n\nvar b=456;", errors: [ { line: 1, @@ -179,6 +182,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { }, { code: "var foo = require('foo-module');\nvar a = 123;\n\nvar bar = require('bar-lib');\nvar b=456;", + output: "var foo = require('foo-module');\n\nvar a = 123;\n\nvar bar = require('bar-lib');\n\nvar b=456;", errors: [ { line: 1, @@ -194,6 +198,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { }, { code: "var foo = require('foo-module');\nvar a = 123;\n\nrequire('bar-lib');\nvar b=456;", + output: "var foo = require('foo-module');\n\nvar a = 123;\n\nrequire('bar-lib');\n\nvar b=456;", errors: [ { line: 1, @@ -209,6 +214,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { }, { code: "var path = require('path');\nvar foo = require('foo');\nvar bar = 42;", + output: "var path = require('path');\nvar foo = require('foo');\n\nvar bar = 42;", errors: [ { line: 2, column: 1, @@ -217,6 +223,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { }, { code: "var assign = Object.assign || require('object-assign');\nvar foo = require('foo');\nvar bar = 42;", + output: "var assign = Object.assign || require('object-assign');\nvar foo = require('foo');\n\nvar bar = 42;", errors: [ { line: 2, column: 1, @@ -225,6 +232,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { }, { code: "require('a');\nfoo(require('b'), require('c'), require('d'));\nrequire('d');\nvar foo = 'bar';", + output: "require('a');\nfoo(require('b'), require('c'), require('d'));\nrequire('d');\n\nvar foo = 'bar';", errors: [ { line: 3, @@ -235,6 +243,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { }, { code: "require('a');\nfoo(\nrequire('b'),\nrequire('c'),\nrequire('d')\n);\nvar foo = 'bar';", + output: "require('a');\nfoo(\nrequire('b'),\nrequire('c'),\nrequire('d')\n);\n\nvar foo = 'bar';", errors: [ { line: 6, @@ -245,6 +254,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { }, { code: "import path from 'path';\nimport foo from 'foo';\nvar bar = 42;", + output: "import path from 'path';\nimport foo from 'foo';\n\nvar bar = 42;", errors: [ { line: 2, column: 1, @@ -254,6 +264,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { }, { code: "import path from 'path';import foo from 'foo';var bar = 42;", + output: "import path from 'path';import foo from 'foo';\n\nvar bar = 42;", errors: [ { line: 1, column: 25, @@ -263,6 +274,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { }, { code: "import foo from 'foo';\n@SomeDecorator(foo)\nclass Foo {}", + output: "import foo from 'foo';\n\n@SomeDecorator(foo)\nclass Foo {}", errors: [ { line: 1, column: 1, @@ -273,6 +285,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { }, { code: "var foo = require('foo');\n@SomeDecorator(foo)\nclass Foo {}", + output: "var foo = require('foo');\n\n@SomeDecorator(foo)\nclass Foo {}", errors: [ { line: 1, column: 1, @@ -282,4 +295,4 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { parser: 'babel-eslint', }, ], -}) +});