From adbc14e60ab6f8a3a3b1b644f1fd0583ba3b31a4 Mon Sep 17 00:00:00 2001 From: Ori Riner Date: Sat, 31 Mar 2018 12:14:10 +0300 Subject: [PATCH] Add autofix for double-slash-comment-empty-line-before (#230) * Add autofix * Address PR comments --- .../__tests__/index.js | 40 ++++++++++++++++++- .../index.js | 24 ++++++++++- 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/rules/double-slash-comment-empty-line-before/__tests__/index.js b/src/rules/double-slash-comment-empty-line-before/__tests__/index.js index dd0f4fb9..d9b24fa5 100644 --- a/src/rules/double-slash-comment-empty-line-before/__tests__/index.js +++ b/src/rules/double-slash-comment-empty-line-before/__tests__/index.js @@ -53,18 +53,30 @@ const alwaysGeneralTests = { { code: ` // comment 1 + // comment 2 + `, + fixed: ` + // comment 1 + // comment 2 `, message: messages.expected }, { code: "// comment\r\n// comment", + fixed: "// comment\r\n\r\n// comment", description: "One windows newline between comments.", message: messages.expected }, { code: ` a { color: pink; + // comment w/o empty line + top: 0; } + `, + fixed: ` + a { color: pink; + // comment w/o empty line top: 0; } `, @@ -73,6 +85,8 @@ const alwaysGeneralTests = { { code: "a { color: pink;\r\n// comment w/o empty lines, Win style\r\ntop: 0; }", + fixed: + "a { color: pink;\r\n\r\n// comment w/o empty lines, Win style\r\ntop: 0; }", description: "One Windows newline before comment.", message: messages.expected } @@ -88,6 +102,7 @@ testRule(rule, { config: ["always"], syntax: "scss", skipBasicChecks: true, + fix: true, accept: alwaysGeneralTests.accept.concat([ { @@ -103,6 +118,11 @@ testRule(rule, { reject: alwaysGeneralTests.reject.concat([ { code: `a { + // First-nested, no empty line before. + color: pink; + }`, + fixed: `a { + // First-nested, no empty line before. color: pink; }`, @@ -119,16 +139,17 @@ testRule(rule, { config: ["always", { except: ["first-nested"] }], syntax: "scss", skipBasicChecks: true, + fix: true, accept: alwaysGeneralTests.accept.concat([ { code: ` a { - // First nested, now empty line. + // First nested, no empty line. color: pink; } `, - description: "First nested, now empty line." + description: "First nested, no empty line." } ]), @@ -137,6 +158,11 @@ testRule(rule, { code: ` a { + // First-nested, with empty line (rejected). + color: pink; + }`, + fixed: ` + a { // First-nested, with empty line (rejected). color: pink; }`, @@ -174,6 +200,7 @@ testRule(rule, { config: ["always", { ignore: ["between-comments"] }], syntax: "scss", skipBasicChecks: true, + fix: true, accept: [ { @@ -230,6 +257,15 @@ testRule(rule, { top: 0; } `, + fixed: ` + a { + color: pink; + + /// comment + /// comment + top: 0; + } + `, description: "Multiple comments, inside ruleset, no empty lines.", message: messages.expected } diff --git a/src/rules/double-slash-comment-empty-line-before/index.js b/src/rules/double-slash-comment-empty-line-before/index.js index f003c585..099697e9 100644 --- a/src/rules/double-slash-comment-empty-line-before/index.js +++ b/src/rules/double-slash-comment-empty-line-before/index.js @@ -15,7 +15,7 @@ export const messages = utils.ruleMessages(ruleName, { const stylelintCommandPrefix = "stylelint-"; -export default function(expectation, options) { +export default function(expectation, options, context) { return (root, result) => { const validOptions = utils.validateOptions( result, @@ -37,6 +37,17 @@ export default function(expectation, options) { return; } + const fix = (comment, match, replace) => { + const escapedMatch = match.replace( + /(\r)?\n/g, + (_, r) => (r ? "\\r\\n" : "\\n") + ); + comment.raws.before = comment.raws.before.replace( + new RegExp(`^${escapedMatch}`), + replace + ); + }; + root.walkComments(comment => { // Only process // comments if (!comment.raws.inline && !comment.inline) { @@ -90,6 +101,17 @@ export default function(expectation, options) { return; } + if (context.fix) { + if (expectEmptyLineBefore && !hasEmptyLineBefore) { + fix(comment, context.newline, context.newline + context.newline); + return; + } + if (!expectEmptyLineBefore && hasEmptyLineBefore) { + fix(comment, context.newline + context.newline, context.newline); + return; + } + } + const message = expectEmptyLineBefore ? messages.expected : messages.rejected;