From 085878245489e61bf47b02f917bb057c477da344 Mon Sep 17 00:00:00 2001 From: Ivan Kopeykin Date: Fri, 13 Sep 2019 19:44:08 +0200 Subject: [PATCH] Fix *-max-empty-lines to only report one violation per function, selector, value list (#4260) * fix: selector-max-empty-lines * fix: function-max-empty-lines * fix: value-list-max-empty-lines * fix tests --- .../__tests__/index.js | 92 +-- lib/rules/function-max-empty-lines/index.js | 131 ++-- .../__tests__/index.js | 654 +++++++----------- lib/rules/selector-max-empty-lines/index.js | 90 ++- .../__tests__/index.js | 47 +- lib/rules/value-list-max-empty-lines/index.js | 88 +-- .../005/__snapshots__/005.test.js.snap | 8 +- 7 files changed, 492 insertions(+), 618 deletions(-) diff --git a/lib/rules/function-max-empty-lines/__tests__/index.js b/lib/rules/function-max-empty-lines/__tests__/index.js index 6c191cc9ba..47f5fd9a84 100644 --- a/lib/rules/function-max-empty-lines/__tests__/index.js +++ b/lib/rules/function-max-empty-lines/__tests__/index.js @@ -54,84 +54,84 @@ testRule(rule, { fixed: "a { transform: translate(/*c*/\n1,1); }", message: messages.expected(0), line: 1, - column: 31 + column: 15 }, { code: "a { transform: /*c*/translate(\n\n\n1,1); }", fixed: "a { transform: /*c*/translate(\n1,1); }", message: messages.expected(0), line: 1, - column: 31 + column: 20 }, { code: "a { transform: translate(\n\n1\n,\n1\n); }", fixed: "a { transform: translate(\n1\n,\n1\n); }", message: messages.expected(0), line: 1, - column: 26 + column: 15 }, { code: "a { transform: translate(\n\n1\n,\n1\n\n); }", fixed: "a { transform: translate(\n1\n,\n1\n); }", message: messages.expected(0), line: 1, - column: 26 + column: 15 }, { code: "a { transform: translate(\n\n1\n\n,\n1\n\n); }", fixed: "a { transform: translate(\n1\n,\n1\n); }", message: messages.expected(0), line: 1, - column: 26 + column: 15 }, { code: "a { transform: translate(\r\n\r\n1\r\n,\r\n1\r\n); }", fixed: "a { transform: translate(\r\n1\r\n,\r\n1\r\n); }", message: messages.expected(0), line: 1, - column: 26 + column: 15 }, { code: "a { transform: translate(\n1\n\n,\n1\n); }", fixed: "a { transform: translate(\n1\n,\n1\n); }", message: messages.expected(0), - line: 2, - column: 2 + line: 1, + column: 15 }, { code: "a { transform: translate(\r\n1\r\n\r\n,\r\n1\r\n); }", fixed: "a { transform: translate(\r\n1\r\n,\r\n1\r\n); }", message: messages.expected(0), - line: 2, - column: 2 + line: 1, + column: 15 }, { code: "a { transform: translate(\n1\n,\n\n1\n); }", fixed: "a { transform: translate(\n1\n,\n1\n); }", message: messages.expected(0), - line: 3, - column: 2 + line: 1, + column: 15 }, { code: "a { transform: translate(\r\n1\r\n,\r\n\r\n1\r\n); }", fixed: "a { transform: translate(\r\n1\r\n,\r\n1\r\n); }", message: messages.expected(0), - line: 3, - column: 2 + line: 1, + column: 15 }, { code: "a { transform: translate(\n1\n,\n1\n\n); }", fixed: "a { transform: translate(\n1\n,\n1\n); }", message: messages.expected(0), - line: 4, - column: 2 + line: 1, + column: 15 }, { code: "a { transform: translate(\r\n1\r\n,\r\n1\r\n\r\n); }", fixed: "a { transform: translate(\r\n1\r\n,\r\n1\r\n); }", message: messages.expected(0), - line: 4, - column: 2 + line: 1, + column: 15 } ] }); @@ -180,56 +180,56 @@ testRule(rule, { fixed: "a { transform: translate(\n\n1\n,\n1\n); }", message: messages.expected(1), line: 1, - column: 26 + column: 15 }, { code: "a { transform: translate(\r\n\r\n\r\n1\r\n,\r\n1\r\n); }", fixed: "a { transform: translate(\r\n\r\n1\r\n,\r\n1\r\n); }", message: messages.expected(1), line: 1, - column: 26 + column: 15 }, { code: "a { transform: translate(\n1\n\n\n,\n1\n); }", fixed: "a { transform: translate(\n1\n\n,\n1\n); }", message: messages.expected(1), - line: 2, - column: 2 + line: 1, + column: 15 }, { code: "a { transform: translate(\r\n1\r\n\r\n\r\n,\r\n1\r\n); }", fixed: "a { transform: translate(\r\n1\r\n\r\n,\r\n1\r\n); }", message: messages.expected(1), - line: 2, - column: 2 + line: 1, + column: 15 }, { code: "a { transform: translate(\n1\n,\n\n\n1\n); }", fixed: "a { transform: translate(\n1\n,\n\n1\n); }", message: messages.expected(1), - line: 3, - column: 2 + line: 1, + column: 15 }, { code: "a { transform: translate(\r\n1\r\n,\r\n\r\n\r\n1\r\n); }", fixed: "a { transform: translate(\r\n1\r\n,\r\n\r\n1\r\n); }", message: messages.expected(1), - line: 3, - column: 2 + line: 1, + column: 15 }, { code: "a { transform: translate(\n1\n,\n1\n\n\n); }", fixed: "a { transform: translate(\n1\n,\n1\n\n); }", message: messages.expected(1), - line: 4, - column: 2 + line: 1, + column: 15 }, { code: "a { transform: translate(\r\n1\r\n,\r\n1\r\n\r\n\r\n); }", fixed: "a { transform: translate(\r\n1\r\n,\r\n1\r\n\r\n); }", message: messages.expected(1), - line: 4, - column: 2 + line: 1, + column: 15 } ] }); @@ -302,56 +302,56 @@ testRule(rule, { fixed: "a { transform: translate(\n\n\n1\n,\n1\n); }", message: messages.expected(2), line: 1, - column: 26 + column: 15 }, { code: "a { transform: translate(\r\n\r\n\r\n\r\n1\r\n,\r\n1\r\n); }", fixed: "a { transform: translate(\r\n\r\n\r\n1\r\n,\r\n1\r\n); }", message: messages.expected(2), line: 1, - column: 26 + column: 15 }, { code: "a { transform: translate(\n1\n\n\n\n,\n1\n); }", fixed: "a { transform: translate(\n1\n\n\n,\n1\n); }", message: messages.expected(2), - line: 2, - column: 2 + line: 1, + column: 15 }, { code: "a { transform: translate(\r\n1\r\n\r\n\r\n\r\n,\r\n1\r\n); }", fixed: "a { transform: translate(\r\n1\r\n\r\n\r\n,\r\n1\r\n); }", message: messages.expected(2), - line: 2, - column: 2 + line: 1, + column: 15 }, { code: "a { transform: translate(\n1\n,\n\n\n\n1\n); }", fixed: "a { transform: translate(\n1\n,\n\n\n1\n); }", message: messages.expected(2), - line: 3, - column: 2 + line: 1, + column: 15 }, { code: "a { transform: translate(\r\n1\r\n,\r\n\r\n\r\n\r\n1\r\n); }", fixed: "a { transform: translate(\r\n1\r\n,\r\n\r\n\r\n1\r\n); }", message: messages.expected(2), - line: 3, - column: 2 + line: 1, + column: 15 }, { code: "a { transform: translate(\n1\n,\n1\n\n\n\n); }", fixed: "a { transform: translate(\n1\n,\n1\n\n\n); }", message: messages.expected(2), - line: 4, - column: 2 + line: 1, + column: 15 }, { code: "a { transform: translate(\r\n1\r\n,\r\n1\r\n\r\n\r\n\r\n); }", fixed: "a { transform: translate(\r\n1\r\n,\r\n1\r\n\r\n\r\n); }", message: messages.expected(2), - line: 4, - column: 2 + line: 1, + column: 15 } ] }); diff --git a/lib/rules/function-max-empty-lines/index.js b/lib/rules/function-max-empty-lines/index.js index 849f349ee4..4d16754dbf 100644 --- a/lib/rules/function-max-empty-lines/index.js +++ b/lib/rules/function-max-empty-lines/index.js @@ -1,11 +1,10 @@ "use strict"; const _ = require("lodash"); -const declarationValueIndex = require("../../utils/declarationValueIndex"); const report = require("../../utils/report"); const ruleMessages = require("../../utils/ruleMessages"); -const styleSearch = require("style-search"); const validateOptions = require("../../utils/validateOptions"); +const valueParser = require("postcss-value-parser"); const ruleName = "function-max-empty-lines"; @@ -14,6 +13,10 @@ const messages = ruleMessages(ruleName, { `Expected no more than ${max} empty ${max === 1 ? "line" : "lines"}` }); +function placeIndexOnValueStart(decl) { + return decl.prop.length + decl.raws.between.length - 1; +} + const rule = function(max, options, context) { const maxAdjacentNewlines = max + 1; @@ -27,66 +30,82 @@ const rule = function(max, options, context) { return; } + const violatedCRLFNewLinesRegex = new RegExp( + `(?:\r\n){${maxAdjacentNewlines + 1},}` + ); + const violatedLFNewLinesRegex = new RegExp( + `\n{${maxAdjacentNewlines + 1},}` + ); + const allowedLFNewLinesString = context.fix + ? _.repeat("\n", maxAdjacentNewlines) + : ""; + const allowedCRLFNewLinesString = context.fix + ? _.repeat("\r\n", maxAdjacentNewlines) + : ""; + root.walkDecls(decl => { if (decl.value.indexOf("(") === -1) { return; } - const declString = decl.toString(); - const repeatLFNewLines = _.repeat("\n", maxAdjacentNewlines); - const repeatCRLFNewLines = _.repeat("\r\n", maxAdjacentNewlines); - const matches = []; - - styleSearch( - { - source: declString, - target: "\n", - functionArguments: "only" - }, - match => { - if ( - declString.substr(match.startIndex + 1, maxAdjacentNewlines) === - repeatLFNewLines || - declString.substr(match.startIndex + 1, maxAdjacentNewlines * 2) === - repeatCRLFNewLines - ) { - // Put index at `\r` if it's CRLF, otherwise leave it at `\n` - let index = match.startIndex; - - if (declString[index - 1] === "\r") { - index -= 1; - } - - if (context.fix) { - matches.push({ start: index, end: match.endIndex }); - - return; - } - - report({ - message: messages.expected(max), - node: decl, - index, - result, - ruleName - }); - } + const stringValue = decl.raws.value ? decl.raws.value.raw : decl.value; + const splittedValue = []; + let sourceIndexStart = 0; + + valueParser(stringValue).walk(node => { + if ( + node.type !== "function" /* ignore non functions */ || + node.value.length === 0 /* ignore sass lists */ + ) { + return; + } + + const stringifiedNode = valueParser.stringify(node); + + if ( + !violatedLFNewLinesRegex.test(stringifiedNode) && + !violatedCRLFNewLinesRegex.test(stringifiedNode) + ) { + return; + } + + if (context.fix) { + const newNodeString = stringifiedNode + .replace( + new RegExp(violatedLFNewLinesRegex, "gm"), + allowedLFNewLinesString + ) + .replace( + new RegExp(violatedCRLFNewLinesRegex, "gm"), + allowedCRLFNewLinesString + ); + + splittedValue.push([ + stringValue.slice(sourceIndexStart, node.sourceIndex), + newNodeString + ]); + sourceIndexStart = node.sourceIndex + stringifiedNode.length; + } else { + report({ + message: messages.expected(max), + node: decl, + index: placeIndexOnValueStart(decl) + node.sourceIndex, + result, + ruleName + }); + } + }); + + if (context.fix && splittedValue.length > 0) { + const updatedValue = + splittedValue.reduce((acc, curr) => acc + curr[0] + curr[1], "") + + stringValue.slice(sourceIndexStart); + + if (decl.raws.value) { + decl.raws.value.raw = updatedValue; + } else { + decl.value = updatedValue; } - ); - - if (context.fix && matches.length) { - matches.reverse().forEach(item => { - const updatedValue = ( - decl.toString().substring(0, item.start) + - decl.toString().substring(item.end) - ).substring(declarationValueIndex(decl)); - - if (decl.raws.value) { - decl.raws.value.raw = updatedValue; - } else { - decl.value = updatedValue; - } - }); } }); }; diff --git a/lib/rules/selector-max-empty-lines/__tests__/index.js b/lib/rules/selector-max-empty-lines/__tests__/index.js index 508ede6e38..ad14081328 100644 --- a/lib/rules/selector-max-empty-lines/__tests__/index.js +++ b/lib/rules/selector-max-empty-lines/__tests__/index.js @@ -546,560 +546,518 @@ testRule(rule, { fixed: ".foo\n.bar { }", message: messages.expected(0), line: 1, - column: 5 + column: 1 }, { code: ".foo\r\n\r\n.bar { }", fixed: ".foo\r\n.bar { }", message: messages.expected(0), line: 1, - column: 5 + column: 1 }, { code: ".foo,\n\n.bar { }", fixed: ".foo,\n.bar { }", message: messages.expected(0), line: 1, - column: 6 + column: 1 }, { code: ".foo,\r\n\r\n.bar { }", fixed: ".foo,\r\n.bar { }", message: messages.expected(0), line: 1, - column: 6 + column: 1 }, { code: ".foo\n\n,.bar { }", fixed: ".foo\n,.bar { }", message: messages.expected(0), line: 1, - column: 5 + column: 1 }, { code: ".foo\r\n\r\n,.bar { }", fixed: ".foo\r\n,.bar { }", message: messages.expected(0), line: 1, - column: 5 + column: 1 }, { code: ".foo, .bar,\n\n.other { }", fixed: ".foo, .bar,\n.other { }", message: messages.expected(0), line: 1, - column: 12 + column: 1 }, { code: ".foo, .bar,\r\n\r\n.other { }", fixed: ".foo, .bar,\r\n.other { }", message: messages.expected(0), line: 1, - column: 12 + column: 1 }, { code: ".foo,\n.bar,\n\n.other { }", fixed: ".foo,\n.bar,\n.other { }", message: messages.expected(0), - line: 2, - column: 6 + line: 1, + column: 1 }, { code: ".foo,\r\n.bar,\r\n\r\n.other { }", fixed: ".foo,\r\n.bar,\r\n.other { }", message: messages.expected(0), - line: 2, - column: 6 + line: 1, + column: 1 }, { code: ".foo,\n.bar,\n\n.other\n{ }", fixed: ".foo,\n.bar,\n.other\n{ }", message: messages.expected(0), - line: 2, - column: 6 + line: 1, + column: 1 }, { code: ".foo,\r\n.bar,\r\n\r\n.other\r\n{ }", fixed: ".foo,\r\n.bar,\r\n.other\r\n{ }", message: messages.expected(0), - line: 2, - column: 6 + line: 1, + column: 1 }, { code: ".foo,\n.bar,\n\n.other\n\n{ }", fixed: ".foo,\n.bar,\n.other\n\n{ }", message: messages.expected(0), - line: 2, - column: 6 + line: 1, + column: 1 }, { code: ".foo,\r\n.bar,\r\n\r\n.other\r\n\r\n{ }", fixed: ".foo,\r\n.bar,\r\n.other\r\n\r\n{ }", message: messages.expected(0), - line: 2, - column: 6 + line: 1, + column: 1 }, { code: "\n.foo,\n.bar,\n\n.other\n\n{ }", fixed: "\n.foo,\n.bar,\n.other\n\n{ }", message: messages.expected(0), - line: 3, - column: 6 + line: 2, + column: 1 }, { code: "\r\n.foo,\r\n.bar,\r\n\r\n.other\r\n\r\n{ }", fixed: "\r\n.foo,\r\n.bar,\r\n.other\r\n\r\n{ }", message: messages.expected(0), - line: 3, - column: 6 + line: 2, + column: 1 }, { code: "\n\n.foo,\n.bar,\n\n.other\n\n{ }", fixed: "\n\n.foo,\n.bar,\n.other\n\n{ }", message: messages.expected(0), - line: 4, - column: 6 + line: 3, + column: 1 }, { code: "\r\n\r\n.foo,\r\n.bar,\r\n\r\n.other\r\n\r\n{ }", fixed: "\r\n\r\n.foo,\r\n.bar,\r\n.other\r\n\r\n{ }", message: messages.expected(0), - line: 4, - column: 6 + line: 3, + column: 1 }, { code: ".foo\n\n.bar { }", fixed: ".foo\n.bar { }", message: messages.expected(0), line: 1, - column: 5 + column: 1 }, { code: ".foo\r\n\r\n.bar { }", fixed: ".foo\r\n.bar { }", - message: messages.expected(0), - line: 1, - column: 5 + message: messages.expected(0) }, { code: ".foo .bar\n\n.other { }", fixed: ".foo .bar\n.other { }", - message: messages.expected(0), - line: 1, - column: 10 + message: messages.expected(0) }, { code: ".foo .bar\r\n\r\n.other { }", fixed: ".foo .bar\r\n.other { }", - message: messages.expected(0), - line: 1, - column: 10 + message: messages.expected(0) }, { code: ".foo\n.bar\n\n.other { }", fixed: ".foo\n.bar\n.other { }", - message: messages.expected(0), - line: 2, - column: 5 + message: messages.expected(0) }, { code: ".foo\r\n.bar\r\n\r\n.other { }", fixed: ".foo\r\n.bar\r\n.other { }", - message: messages.expected(0), - line: 2, - column: 5 + message: messages.expected(0) }, { code: ".foo\n.bar\n\n.other\n{ }", fixed: ".foo\n.bar\n.other\n{ }", - message: messages.expected(0), - line: 2, - column: 5 + message: messages.expected(0) }, { code: ".foo\r\n.bar\r\n\r\n.other\r\n{ }", fixed: ".foo\r\n.bar\r\n.other\r\n{ }", - message: messages.expected(0), - line: 2, - column: 5 + message: messages.expected(0) }, { code: ".foo\n.bar\n\n.other\n\n{ }", fixed: ".foo\n.bar\n.other\n\n{ }", - message: messages.expected(0), - line: 2, - column: 5 + message: messages.expected(0) }, { code: ".foo\r\n.bar\r\n\r\n.other\r\n\r\n{ }", fixed: ".foo\r\n.bar\r\n.other\r\n\r\n{ }", - message: messages.expected(0), - line: 2, - column: 5 + message: messages.expected(0) }, { code: "\n.foo\n.bar\n\n.other\n\n{ }", fixed: "\n.foo\n.bar\n.other\n\n{ }", - message: messages.expected(0), - line: 3, - column: 5 + message: messages.expected(0) }, { code: "\r\n.foo\r\n.bar\r\n\r\n.other\r\n\r\n{ }", fixed: "\r\n.foo\r\n.bar\r\n.other\r\n\r\n{ }", - message: messages.expected(0), - line: 3, - column: 5 + message: messages.expected(0) }, { code: "\n\n.foo\n.bar\n\n.other\n\n{ }", fixed: "\n\n.foo\n.bar\n.other\n\n{ }", - message: messages.expected(0), - line: 4, - column: 5 + message: messages.expected(0) }, { code: "\r\n\r\n.foo\r\n.bar\r\n\r\n.other\r\n\r\n{ }", fixed: "\r\n\r\n.foo\r\n.bar\r\n.other\r\n\r\n{ }", - message: messages.expected(0), - line: 4, - column: 5 + message: messages.expected(0) }, { code: ".foo >\n\n.bar { }", fixed: ".foo >\n.bar { }", message: messages.expected(0), line: 1, - column: 7 + column: 1 }, { code: ".foo >\r\n\r\n.bar { }", fixed: ".foo >\r\n.bar { }", message: messages.expected(0), line: 1, - column: 7 + column: 1 }, { code: ".foo\n\n>.bar { }", fixed: ".foo\n>.bar { }", message: messages.expected(0), line: 1, - column: 5 + column: 1 }, { code: ".foo\r\n\r\n> .bar { }", fixed: ".foo\r\n> .bar { }", message: messages.expected(0), line: 1, - column: 5 + column: 1 }, { code: ".foo .bar >\n\n.other { }", fixed: ".foo .bar >\n.other { }", message: messages.expected(0), line: 1, - column: 12 + column: 1 }, { code: ".foo .bar >\r\n\r\n .other { }", fixed: ".foo .bar >\r\n .other { }", message: messages.expected(0), line: 1, - column: 12 + column: 1 }, { code: ".foo .bar\n\n> .other { }", fixed: ".foo .bar\n> .other { }", - message: messages.expected(0), - line: 1, - column: 10 + message: messages.expected(0) }, { code: ".foo .bar\r\n\r\n> .other { }", fixed: ".foo .bar\r\n> .other { }", message: messages.expected(0), line: 1, - column: 10 + column: 1 }, { code: ".foo\n.bar >\n\n.other { }", fixed: ".foo\n.bar >\n.other { }", message: messages.expected(0), - line: 2, - column: 7 + line: 1, + column: 1 }, { code: ".foo\r\n.bar >\r\n\r\n.other { }", fixed: ".foo\r\n.bar >\r\n.other { }", message: messages.expected(0), - line: 2, - column: 7 + line: 1, + column: 1 }, { code: ".foo\n.bar\n\n> .other { }", fixed: ".foo\n.bar\n> .other { }", message: messages.expected(0), - line: 2, - column: 5 + line: 1, + column: 1 }, { code: ".foo\r\n.bar\r\n\r\n> .other { }", fixed: ".foo\r\n.bar\r\n> .other { }", message: messages.expected(0), - line: 2, - column: 5 + line: 1, + column: 1 }, { code: ".foo\n.bar >\n\n.other\n{ }", fixed: ".foo\n.bar >\n.other\n{ }", message: messages.expected(0), - line: 2, - column: 7 + line: 1, + column: 1 }, { code: ".foo\r\n.bar >\r\n\r\n.other\r\n{ }", fixed: ".foo\r\n.bar >\r\n.other\r\n{ }", message: messages.expected(0), - line: 2, - column: 7 + line: 1, + column: 1 }, { code: ".foo\n.bar\n\n> .other\n{ }", fixed: ".foo\n.bar\n> .other\n{ }", message: messages.expected(0), - line: 2, - column: 5 + line: 1, + column: 1 }, { code: ".foo\r\n.bar\r\n\r\n > .other\r\n{ }", fixed: ".foo\r\n.bar\r\n > .other\r\n{ }", message: messages.expected(0), - line: 2, - column: 5 + line: 1, + column: 1 }, { code: ".foo\n.bar >\n\n.other\n\n{ }", fixed: ".foo\n.bar >\n.other\n\n{ }", message: messages.expected(0), - line: 2, - column: 7 + line: 1, + column: 1 }, { code: ".foo\r\n.bar >\r\n\r\n.other\r\n\r\n{ }", fixed: ".foo\r\n.bar >\r\n.other\r\n\r\n{ }", message: messages.expected(0), - line: 2, - column: 7 + line: 1, + column: 1 }, { code: ".foo\n.bar\n\n> .other\n\n{ }", fixed: ".foo\n.bar\n> .other\n\n{ }", - message: messages.expected(0), - line: 2, - column: 5 + message: messages.expected(0) }, { code: ".foo\r\n.bar\r\n\r\n> .other\r\n\r\n{ }", fixed: ".foo\r\n.bar\r\n> .other\r\n\r\n{ }", - message: messages.expected(0), - line: 2, - column: 5 + message: messages.expected(0) }, { code: "\n.foo\n.bar >\n\n.other\n\n{ }", fixed: "\n.foo\n.bar >\n.other\n\n{ }", - message: messages.expected(0), - line: 3, - column: 7 + message: messages.expected(0) }, { code: "\r\n.foo\r\n.bar >\r\n\r\n.other\r\n\r\n{ }", fixed: "\r\n.foo\r\n.bar >\r\n.other\r\n\r\n{ }", message: messages.expected(0), - line: 3, - column: 7 + line: 2, + column: 1 }, { code: "\n.foo\n.bar\n\n> .other\n\n{ }", fixed: "\n.foo\n.bar\n> .other\n\n{ }", message: messages.expected(0), - line: 3, - column: 5 + line: 2, + column: 1 }, { code: "\r\n.foo\r\n.bar\r\n\r\n> .other\r\n\r\n{ }", fixed: "\r\n.foo\r\n.bar\r\n> .other\r\n\r\n{ }", message: messages.expected(0), - line: 3, - column: 5 + line: 2, + column: 1 }, { code: "\n\n.foo\n.bar >\n\n.other\n\n{ }", fixed: "\n\n.foo\n.bar >\n.other\n\n{ }", message: messages.expected(0), - line: 4, - column: 7 + line: 3, + column: 1 }, { code: "\r\n\r\n.foo\r\n.bar >\r\n\r\n.other\r\n\r\n{ }", fixed: "\r\n\r\n.foo\r\n.bar >\r\n.other\r\n\r\n{ }", message: messages.expected(0), - line: 4, - column: 7 + line: 3, + column: 1 }, { code: "\n\n.foo\n.bar\n\n >.other\n\n{ }", fixed: "\n\n.foo\n.bar\n >.other\n\n{ }", - message: messages.expected(0), - line: 4, - column: 5 + message: messages.expected(0) }, { code: "\r\n\r\n.foo\r\n.bar\r\n\r\n> .other\r\n\r\n{ }", fixed: "\r\n\r\n.foo\r\n.bar\r\n> .other\r\n\r\n{ }", - message: messages.expected(0), - line: 4, - column: 5 + message: messages.expected(0) }, { code: "a[\n\nitemprop=url] { }", fixed: "a[\nitemprop=url] { }", message: messages.expected(0), line: 1, - column: 3 + column: 1 }, { code: "a[\r\n\r\nitemprop=url] { }", fixed: "a[\r\nitemprop=url] { }", message: messages.expected(0), line: 1, - column: 3 + column: 1 }, { code: "a[itemprop\n\n=url] { }", fixed: "a[itemprop\n=url] { }", message: messages.expected(0), line: 1, - column: 11 + column: 1 }, { code: "a[itemprop\r\n\r\n=url] { }", fixed: "a[itemprop\r\n=url] { }", message: messages.expected(0), line: 1, - column: 11 + column: 1 }, { code: "a[itemprop=\n\nurl] { }", fixed: "a[itemprop=\nurl] { }", message: messages.expected(0), line: 1, - column: 12 + column: 1 }, { code: "a[itemprop=\r\n\r\nurl] { }", fixed: "a[itemprop=\r\nurl] { }", - message: messages.expected(0), - line: 1, - column: 12 + message: messages.expected(0) }, { code: "a[itemprop=url\n\n] { }", fixed: "a[itemprop=url\n] { }", message: messages.expected(0), line: 1, - column: 15 + column: 1 }, { code: "a[itemprop=url\r\n\r\n] { }", fixed: "a[itemprop=url\r\n] { }", message: messages.expected(0), line: 1, - column: 15 + column: 1 }, { code: "a\n\n:hover { }", fixed: "a\n:hover { }", message: messages.expected(0), line: 1, - column: 2 + column: 1 }, { code: "a\r\n\r\n:hover { }", fixed: "a\r\n:hover { }", - message: messages.expected(0), - line: 1, - column: 2 + message: messages.expected(0) }, { code: "a:\n\nhover { }", fixed: "a:\nhover { }", message: messages.expected(0), line: 1, - column: 3 + column: 1 }, { code: "a:\r\n\r\nhover { }", fixed: "a:\r\nhover { }", message: messages.expected(0), line: 1, - column: 3 + column: 1 }, { code: "a\n\n::before { }", fixed: "a\n::before { }", message: messages.expected(0), line: 1, - column: 2 + column: 1 }, { code: "a\r\n\r\n::before { }", fixed: "a\r\n::before { }", message: messages.expected(0), line: 1, - column: 2 + column: 1 }, { - code: "a::\n\nbefore { }", - fixed: "a::\nbefore { }", + code: "a { }\na::\n\nbefore { }", + fixed: "a { }\na::\nbefore { }", message: messages.expected(0), - line: 1, - column: 4 + line: 2, + column: 1 }, { code: "a::\r\n\r\nbefore { }", fixed: "a::\r\nbefore { }", message: messages.expected(0), line: 1, - column: 4 + column: 1 }, { code: ".foo\n\n/*comment*/ .bar { }", fixed: ".foo\n/*comment*/ .bar { }", message: messages.expected(0), line: 1, - column: 5 + column: 1 }, { code: ".foo\n/*comment*/\n\n.bar { }", fixed: ".foo\n/*comment*/\n.bar { }", message: messages.expected(0), - line: 2, - column: 12 + line: 1, + column: 1 }, { code: ".foo\r\n\r\n/*comment*/ .bar { }", fixed: ".foo\r\n/*comment*/ .bar { }", message: messages.expected(0), line: 1, - column: 5 + column: 1 }, { code: ".foo\r\n/*comment*/\r\n\r\n.bar { }", fixed: ".foo\r\n/*comment*/\r\n.bar { }", message: messages.expected(0), - line: 2, - column: 12 + line: 1, + column: 1 } ] }); @@ -1745,798 +1703,716 @@ testRule(rule, { fixed: ".foo\n\n.bar { }", message: messages.expected(1), line: 1, - column: 5 + column: 1 }, { code: ".foo\r\n\r\n\r\n.bar { }", fixed: ".foo\r\n\r\n.bar { }", message: messages.expected(1), line: 1, - column: 5 + column: 1 }, { code: ".foo,\n\n\n.bar { }", fixed: ".foo,\n\n.bar { }", message: messages.expected(1), line: 1, - column: 6 + column: 1 }, { code: ".foo,\r\n\r\n\r\n.bar { }", fixed: ".foo,\r\n\r\n.bar { }", message: messages.expected(1), line: 1, - column: 6 + column: 1 }, { code: ".foo, .bar,\n\n\n.other { }", fixed: ".foo, .bar,\n\n.other { }", message: messages.expected(1), line: 1, - column: 12 + column: 1 }, { code: ".foo, .bar,\r\n\r\n\r\n.other { }", fixed: ".foo, .bar,\r\n\r\n.other { }", message: messages.expected(1), line: 1, - column: 12 + column: 1 }, { code: ".foo,\n.bar,\n\n\n.other { }", fixed: ".foo,\n.bar,\n\n.other { }", message: messages.expected(1), - line: 2, - column: 6 + line: 1, + column: 1 }, { code: ".foo,\r\n.bar,\r\n\r\n\r\n.other { }", fixed: ".foo,\r\n.bar,\r\n\r\n.other { }", message: messages.expected(1), - line: 2, - column: 6 + line: 1, + column: 1 }, { code: ".foo,\n\n.bar,\n\n\n.other { }", fixed: ".foo,\n\n.bar,\n\n.other { }", message: messages.expected(1), - line: 3, - column: 6 + line: 1, + column: 1 }, { code: ".foo,\r\n\r\n.bar,\r\n\r\n\r\n.other { }", fixed: ".foo,\r\n\r\n.bar,\r\n\r\n.other { }", message: messages.expected(1), - line: 3, - column: 6 + line: 1, + column: 1 }, { code: ".foo,\n.bar,\n\n\n.other\n{ }", fixed: ".foo,\n.bar,\n\n.other\n{ }", - message: messages.expected(1), - line: 2, - column: 6 + message: messages.expected(1) }, { code: ".foo,\r\n.bar,\r\n\r\n\r\n.other\r\n{ }", fixed: ".foo,\r\n.bar,\r\n\r\n.other\r\n{ }", message: messages.expected(1), - line: 2, - column: 6 + line: 1, + column: 1 }, { code: ".foo,\n\n.bar,\n\n\n.other\n{ }", fixed: ".foo,\n\n.bar,\n\n.other\n{ }", message: messages.expected(1), - line: 3, - column: 6 + line: 1, + column: 1 }, { code: ".foo,\r\n\r\n.bar,\r\n\r\n\r\n.other\r\n{ }", fixed: ".foo,\r\n\r\n.bar,\r\n\r\n.other\r\n{ }", message: messages.expected(1), - line: 3, - column: 6 + line: 1, + column: 1 }, { code: ".foo,\n.bar,\n\n\n.other\n\n{ }", fixed: ".foo,\n.bar,\n\n.other\n\n{ }", message: messages.expected(1), - line: 2, - column: 6 + line: 1, + column: 1 }, { code: ".foo,\r\n.bar,\r\n\r\n\r\n.other\r\n\r\n{ }", fixed: ".foo,\r\n.bar,\r\n\r\n.other\r\n\r\n{ }", message: messages.expected(1), - line: 2, - column: 6 + line: 1, + column: 1 }, { code: ".foo,\n\n.bar,\n\n\n.other\n\n\n{ }", fixed: ".foo,\n\n.bar,\n\n.other\n\n\n{ }", message: messages.expected(1), - line: 3, - column: 6 + line: 1, + column: 1 }, { code: ".foo,\r\n\r\n.bar,\r\n\r\n\r\n.other\r\n\r\n\r\n{ }", fixed: ".foo,\r\n\r\n.bar,\r\n\r\n.other\r\n\r\n\r\n{ }", message: messages.expected(1), - line: 3, - column: 6 + line: 1, + column: 1 }, { code: "\n.foo,\n.bar,\n\n\n.other\n\n{ }", fixed: "\n.foo,\n.bar,\n\n.other\n\n{ }", - message: messages.expected(1), - line: 3, - column: 6 + message: messages.expected(1) }, { code: "\r\n.foo,\r\n.bar,\r\n\r\n\r\n.other\r\n\r\n{ }", fixed: "\r\n.foo,\r\n.bar,\r\n\r\n.other\r\n\r\n{ }", message: messages.expected(1), - line: 3, - column: 6 + line: 2, + column: 1 }, { code: "\n\n.foo,\n\n.bar,\n\n\n.other\n\n\n{ }", fixed: "\n\n.foo,\n\n.bar,\n\n.other\n\n\n{ }", message: messages.expected(1), - line: 5, - column: 6 + line: 3, + column: 1 }, { code: "\r\n\r\n.foo,\r\n\r\n.bar,\r\n\r\n\r\n.other\r\n\r\n\r\n{ }", fixed: "\r\n\r\n.foo,\r\n\r\n.bar,\r\n\r\n.other\r\n\r\n\r\n{ }", message: messages.expected(1), - line: 5, - column: 6 + line: 3, + column: 1 }, { code: "\n\n.foo,\n.bar,\n\n\n.other\n\n{ }", fixed: "\n\n.foo,\n.bar,\n\n.other\n\n{ }", message: messages.expected(1), - line: 4, - column: 6 + line: 3, + column: 1 }, { code: "\r\n\r\n.foo,\r\n.bar,\r\n\r\n\r\n.other\r\n\r\n{ }", fixed: "\r\n\r\n.foo,\r\n.bar,\r\n\r\n.other\r\n\r\n{ }", message: messages.expected(1), - line: 4, - column: 6 + line: 3, + column: 1 }, { code: "\n\n\n.foo,\n\n.bar,\n\n\n.other\n\n\n{ }", fixed: "\n\n\n.foo,\n\n.bar,\n\n.other\n\n\n{ }", message: messages.expected(1), - line: 6, - column: 6 + line: 4, + column: 1 }, { code: "\r\n\r\n\r\n.foo,\r\n\r\n.bar,\r\n\r\n\r\n.other\r\n\r\n\r\n{ }", fixed: "\r\n\r\n\r\n.foo,\r\n\r\n.bar,\r\n\r\n.other\r\n\r\n\r\n{ }", message: messages.expected(1), - line: 6, - column: 6 + line: 4, + column: 1 }, { code: ".foo .bar\n\n\n.other { }", fixed: ".foo .bar\n\n.other { }", - message: messages.expected(1), - line: 1, - column: 10 + message: messages.expected(1) }, { code: ".foo .bar\r\n\r\n\r\n.other { }", fixed: ".foo .bar\r\n\r\n.other { }", - message: messages.expected(1), - line: 1, - column: 10 + message: messages.expected(1) }, { code: ".foo\n.bar\n\n\n.other { }", fixed: ".foo\n.bar\n\n.other { }", - message: messages.expected(1), - line: 2, - column: 5 + message: messages.expected(1) }, { code: ".foo\r\n.bar\r\n\r\n\r\n.other { }", fixed: ".foo\r\n.bar\r\n\r\n.other { }", - message: messages.expected(1), - line: 2, - column: 5 + message: messages.expected(1) }, { code: ".foo\n\n.bar\n\n\n.other { }", fixed: ".foo\n\n.bar\n\n.other { }", - message: messages.expected(1), - line: 3, - column: 5 + message: messages.expected(1) }, { code: ".foo\r\n\r\n.bar\r\n\r\n\r\n.other { }", fixed: ".foo\r\n\r\n.bar\r\n\r\n.other { }", - message: messages.expected(1), - line: 3, - column: 5 + message: messages.expected(1) }, { code: ".foo\n.bar\n\n\n.other\n{ }", fixed: ".foo\n.bar\n\n.other\n{ }", - message: messages.expected(1), - line: 2, - column: 5 + message: messages.expected(1) }, { code: ".foo\r\n.bar\r\n\r\n\r\n.other\r\n{ }", fixed: ".foo\r\n.bar\r\n\r\n.other\r\n{ }", - message: messages.expected(1), - line: 2, - column: 5 + message: messages.expected(1) }, { code: ".foo\n\n.bar\n\n\n.other\n\n{ }", fixed: ".foo\n\n.bar\n\n.other\n\n{ }", - message: messages.expected(1), - line: 3, - column: 5 + message: messages.expected(1) }, { code: ".foo\r\n\r\n.bar\r\n\r\n\r\n.other\r\n\r\n{ }", fixed: ".foo\r\n\r\n.bar\r\n\r\n.other\r\n\r\n{ }", - message: messages.expected(1), - line: 3, - column: 5 + message: messages.expected(1) }, { code: ".foo\n.bar\n\n\n.other\n\n{ }", fixed: ".foo\n.bar\n\n.other\n\n{ }", - message: messages.expected(1), - line: 2, - column: 5 + message: messages.expected(1) }, { code: ".foo\r\n.bar\r\n\r\n\r\n.other\r\n\r\n{ }", fixed: ".foo\r\n.bar\r\n\r\n.other\r\n\r\n{ }", - message: messages.expected(1), - line: 2, - column: 5 + message: messages.expected(1) }, { code: ".foo\n\n.bar\n\n\n.other\n\n\n{ }", fixed: ".foo\n\n.bar\n\n.other\n\n\n{ }", - message: messages.expected(1), - line: 3, - column: 5 + message: messages.expected(1) }, { code: ".foo\r\n\r\n.bar\r\n\r\n\r\n.other\r\n\r\n\r\n{ }", fixed: ".foo\r\n\r\n.bar\r\n\r\n.other\r\n\r\n\r\n{ }", - message: messages.expected(1), - line: 3, - column: 5 + message: messages.expected(1) }, { code: "\n.foo\n.bar\n\n\n.other\n\n{ }", fixed: "\n.foo\n.bar\n\n.other\n\n{ }", - message: messages.expected(1), - line: 3, - column: 5 + message: messages.expected(1) }, { code: "\r\n.foo\r\n.bar\r\n\r\n\r\n.other\r\n\r\n{ }", fixed: "\r\n.foo\r\n.bar\r\n\r\n.other\r\n\r\n{ }", - message: messages.expected(1), - line: 3, - column: 5 + message: messages.expected(1) }, { code: "\n\n.foo\n\n.bar\n\n\n.other\n\n\n{ }", fixed: "\n\n.foo\n\n.bar\n\n.other\n\n\n{ }", - message: messages.expected(1), - line: 5, - column: 5 + message: messages.expected(1) }, { code: "\r\n\r\n.foo\r\n\r\n.bar\r\n\r\n\r\n.other\r\n\r\n\r\n{ }", fixed: "\r\n\r\n.foo\r\n\r\n.bar\r\n\r\n.other\r\n\r\n\r\n{ }", - message: messages.expected(1), - line: 5, - column: 5 + message: messages.expected(1) }, { code: "\n\n.foo\n.bar\n\n\n.other\n\n{ }", fixed: "\n\n.foo\n.bar\n\n.other\n\n{ }", - message: messages.expected(1), - line: 4, - column: 5 + message: messages.expected(1) }, { code: "\r\n\r\n.foo\r\n.bar\r\n\r\n\r\n.other\r\n\r\n{ }", fixed: "\r\n\r\n.foo\r\n.bar\r\n\r\n.other\r\n\r\n{ }", - message: messages.expected(1), - line: 4, - column: 5 + message: messages.expected(1) }, { code: "\n\n\n.foo\n\n.bar\n\n\n.other\n\n\n{ }", fixed: "\n\n\n.foo\n\n.bar\n\n.other\n\n\n{ }", - message: messages.expected(1), - line: 6, - column: 5 + message: messages.expected(1) }, { code: "\r\n\r\n\r\n.foo\r\n\r\n.bar\r\n\r\n\r\n.other\r\n\r\n\r\n{ }", fixed: "\r\n\r\n\r\n.foo\r\n\r\n.bar\r\n\r\n.other\r\n\r\n\r\n{ }", - message: messages.expected(1), - line: 6, - column: 5 + message: messages.expected(1) }, { code: ".foo >\n\n\n.bar { }", fixed: ".foo >\n\n.bar { }", message: messages.expected(1), line: 1, - column: 7 + column: 1 }, { code: ".foo >\r\n\r\n\r\n.bar { }", fixed: ".foo >\r\n\r\n.bar { }", message: messages.expected(1), line: 1, - column: 7 + column: 1 }, { code: ".foo\n\n\n>.bar { }", fixed: ".foo\n\n>.bar { }", message: messages.expected(1), line: 1, - column: 5 + column: 1 }, { code: ".foo\r\n\r\n\r\n> .bar { }", fixed: ".foo\r\n\r\n> .bar { }", message: messages.expected(1), line: 1, - column: 5 + column: 1 }, { code: ".foo .bar >\n\n\n.other { }", fixed: ".foo .bar >\n\n.other { }", message: messages.expected(1), line: 1, - column: 12 + column: 1 }, { code: ".foo .bar >\r\n\r\n\r\n .other { }", fixed: ".foo .bar >\r\n\r\n .other { }", message: messages.expected(1), line: 1, - column: 12 + column: 1 }, { code: ".foo .bar\n\n\n> .other { }", fixed: ".foo .bar\n\n> .other { }", message: messages.expected(1), line: 1, - column: 10 + column: 1 }, { code: ".foo .bar\r\n\r\n\r\n> .other { }", fixed: ".foo .bar\r\n\r\n> .other { }", message: messages.expected(1), line: 1, - column: 10 + column: 1 }, { code: ".foo\n.bar >\n\n\n.other { }", fixed: ".foo\n.bar >\n\n.other { }", message: messages.expected(1), - line: 2, - column: 7 + line: 1, + column: 1 }, { code: ".foo\r\n.bar >\r\n\r\n\r\n.other { }", fixed: ".foo\r\n.bar >\r\n\r\n.other { }", message: messages.expected(1), - line: 2, - column: 7 + line: 1, + column: 1 }, { code: ".foo\n\n.bar >\n\n\n.other { }", fixed: ".foo\n\n.bar >\n\n.other { }", - message: messages.expected(1), - line: 3, - column: 7 + message: messages.expected(1) }, { code: ".foo\r\n\r\n.bar >\r\n\r\n\r\n.other { }", fixed: ".foo\r\n\r\n.bar >\r\n\r\n.other { }", message: messages.expected(1), - line: 3, - column: 7 + line: 1, + column: 1 }, { code: ".foo\n.bar\n\n\n> .other { }", fixed: ".foo\n.bar\n\n> .other { }", message: messages.expected(1), - line: 2, - column: 5 + line: 1, + column: 1 }, { code: ".foo\r\n.bar\r\n\r\n\r\n> .other { }", fixed: ".foo\r\n.bar\r\n\r\n> .other { }", message: messages.expected(1), - line: 2, - column: 5 + line: 1, + column: 1 }, { code: ".foo\n\n.bar\n\n\n> .other { }", fixed: ".foo\n\n.bar\n\n> .other { }", message: messages.expected(1), - line: 3, - column: 5 + line: 1, + column: 1 }, { code: ".foo\r\n\r\n.bar\r\n\r\n\r\n> .other { }", fixed: ".foo\r\n\r\n.bar\r\n\r\n> .other { }", message: messages.expected(1), - line: 3, - column: 5 + line: 1, + column: 1 }, { code: ".foo\n.bar >\n\n\n.other\n{ }", fixed: ".foo\n.bar >\n\n.other\n{ }", message: messages.expected(1), - line: 2, - column: 7 + line: 1, + column: 1 }, { code: ".foo\r\n.bar >\r\n\r\n\r\n.other\r\n{ }", fixed: ".foo\r\n.bar >\r\n\r\n.other\r\n{ }", message: messages.expected(1), - line: 2, - column: 7 + line: 1, + column: 1 }, { code: ".foo\n\n.bar >\n\n\n.other\n\n{ }", fixed: ".foo\n\n.bar >\n\n.other\n\n{ }", - message: messages.expected(1), - line: 3, - column: 7 + message: messages.expected(1) }, { code: ".foo\r\n\r\n.bar >\r\n\r\n\r\n.other\r\n\r\n{ }", fixed: ".foo\r\n\r\n.bar >\r\n\r\n.other\r\n\r\n{ }", message: messages.expected(1), - line: 3, - column: 7 + line: 1, + column: 1 }, { code: ".foo\n.bar\n\n\n> .other\n{ }", fixed: ".foo\n.bar\n\n> .other\n{ }", message: messages.expected(1), - line: 2, - column: 5 + line: 1, + column: 1 }, { code: ".foo\r\n.bar\r\n\r\n\r\n > .other\r\n{ }", fixed: ".foo\r\n.bar\r\n\r\n > .other\r\n{ }", message: messages.expected(1), - line: 2, - column: 5 + line: 1, + column: 1 }, { code: ".foo\n\n.bar\n\n\n> .other\n\n{ }", fixed: ".foo\n\n.bar\n\n> .other\n\n{ }", - message: messages.expected(1), - line: 3, - column: 5 + message: messages.expected(1) }, { code: ".foo\r\n\r\n.bar\r\n\r\n\r\n > .other\r\n\r\n{ }", fixed: ".foo\r\n\r\n.bar\r\n\r\n > .other\r\n\r\n{ }", - message: messages.expected(1), - line: 3, - column: 5 + message: messages.expected(1) }, { code: ".foo\n.bar >\n\n\n.other\n\n{ }", fixed: ".foo\n.bar >\n\n.other\n\n{ }", - message: messages.expected(1), - line: 2, - column: 7 + message: messages.expected(1) }, { code: ".foo\r\n.bar >\r\n\r\n\r\n.other\r\n\r\n{ }", fixed: ".foo\r\n.bar >\r\n\r\n.other\r\n\r\n{ }", - message: messages.expected(1), - line: 2, - column: 7 + message: messages.expected(1) }, { code: ".foo\n\n.bar >\n\n\n.other\n\n\n{ }", fixed: ".foo\n\n.bar >\n\n.other\n\n\n{ }", - message: messages.expected(1), - line: 3, - column: 7 + message: messages.expected(1) }, { code: ".foo\r\n\r\n.bar >\r\n\r\n\r\n.other\r\n\r\n\r\n{ }", fixed: ".foo\r\n\r\n.bar >\r\n\r\n.other\r\n\r\n\r\n{ }", - message: messages.expected(1), - line: 3, - column: 7 + message: messages.expected(1) }, { code: ".foo\n.bar\n\n\n> .other\n\n{ }", fixed: ".foo\n.bar\n\n> .other\n\n{ }", - message: messages.expected(1), - line: 2, - column: 5 + message: messages.expected(1) }, { code: ".foo\r\n.bar\r\n\r\n\r\n> .other\r\n\r\n{ }", fixed: ".foo\r\n.bar\r\n\r\n> .other\r\n\r\n{ }", - message: messages.expected(1), - line: 2, - column: 5 + message: messages.expected(1) }, { code: ".foo\n\n.bar\n\n\n> .other\n\n\n{ }", fixed: ".foo\n\n.bar\n\n> .other\n\n\n{ }", - message: messages.expected(1), - line: 3, - column: 5 + message: messages.expected(1) }, { code: ".foo\r\n\r\n.bar\r\n\r\n\r\n> .other\r\n\r\n\r\n{ }", fixed: ".foo\r\n\r\n.bar\r\n\r\n> .other\r\n\r\n\r\n{ }", - message: messages.expected(1), - line: 3, - column: 5 + message: messages.expected(1) }, { code: "\n.foo\n.bar >\n\n\n.other\n\n{ }", fixed: "\n.foo\n.bar >\n\n.other\n\n{ }", - message: messages.expected(1), - line: 3, - column: 7 + message: messages.expected(1) }, { code: "\r\n.foo\r\n.bar >\r\n\r\n\r\n.other\r\n\r\n{ }", fixed: "\r\n.foo\r\n.bar >\r\n\r\n.other\r\n\r\n{ }", message: messages.expected(1), - line: 3, - column: 7 + line: 2, + column: 1 }, { code: "\n\n.foo\n\n.bar >\n\n\n.other\n\n\n{ }", fixed: "\n\n.foo\n\n.bar >\n\n.other\n\n\n{ }", message: messages.expected(1), - line: 5, - column: 7 + line: 3, + column: 1 }, { code: "\r\n\r\n.foo\r\n\r\n.bar >\r\n\r\n\r\n.other\r\n\r\n\r\n{ }", fixed: "\r\n\r\n.foo\r\n\r\n.bar >\r\n\r\n.other\r\n\r\n\r\n{ }", message: messages.expected(1), - line: 5, - column: 7 + line: 3, + column: 1 }, { code: "\n.foo\n.bar\n\n\n> .other\n\n{ }", fixed: "\n.foo\n.bar\n\n> .other\n\n{ }", - message: messages.expected(1), - line: 3, - column: 5 + message: messages.expected(1) }, { code: "\r\n.foo\r\n.bar\r\n\r\n\r\n> .other\r\n\r\n{ }", fixed: "\r\n.foo\r\n.bar\r\n\r\n> .other\r\n\r\n{ }", message: messages.expected(1), - line: 3, - column: 5 + line: 2, + column: 1 }, { code: "\n\n.foo\n\n.bar\n\n\n> .other\n\n\n{ }", fixed: "\n\n.foo\n\n.bar\n\n> .other\n\n\n{ }", message: messages.expected(1), - line: 5, - column: 5 + line: 3, + column: 1 }, { code: "\r\n\r\n.foo\r\n\r\n.bar\r\n\r\n\r\n> .other\r\n\r\n\r\n{ }", fixed: "\r\n\r\n.foo\r\n\r\n.bar\r\n\r\n> .other\r\n\r\n\r\n{ }", message: messages.expected(1), - line: 5, - column: 5 + line: 3, + column: 1 }, { code: "\n\n.foo\n.bar >\n\n\n.other\n\n{ }", fixed: "\n\n.foo\n.bar >\n\n.other\n\n{ }", message: messages.expected(1), - line: 4, - column: 7 + line: 3, + column: 1 }, { code: "\r\n\r\n.foo\r\n.bar >\r\n\r\n\r\n.other\r\n\r\n{ }", fixed: "\r\n\r\n.foo\r\n.bar >\r\n\r\n.other\r\n\r\n{ }", message: messages.expected(1), - line: 4, - column: 7 + line: 3, + column: 1 }, { code: "\n\n\n.foo\n\n.bar >\n\n\n.other\n\n\n{ }", fixed: "\n\n\n.foo\n\n.bar >\n\n.other\n\n\n{ }", message: messages.expected(1), - line: 6, - column: 7 + line: 4, + column: 1 }, { code: "\r\n\r\n\r\n.foo\r\n\r\n.bar >\r\n\r\n\r\n.other\r\n\r\n\r\n{ }", fixed: "\r\n\r\n\r\n.foo\r\n\r\n.bar >\r\n\r\n.other\r\n\r\n\r\n{ }", message: messages.expected(1), - line: 6, - column: 7 + line: 4, + column: 1 }, { code: "\n\n.foo\n.bar\n\n\n >.other\n\n{ }", fixed: "\n\n.foo\n.bar\n\n >.other\n\n{ }", message: messages.expected(1), - line: 4, - column: 5 + line: 3, + column: 1 }, { code: "\r\n\r\n.foo\r\n.bar\r\n\r\n\r\n> .other\r\n\r\n{ }", fixed: "\r\n\r\n.foo\r\n.bar\r\n\r\n> .other\r\n\r\n{ }", - message: messages.expected(1), - line: 4, - column: 5 + message: messages.expected(1) }, { code: "\n\n\n.foo\n\n.bar\n\n\n >.other\n\n\n{ }", fixed: "\n\n\n.foo\n\n.bar\n\n >.other\n\n\n{ }", - message: messages.expected(1), - line: 6, - column: 5 + message: messages.expected(1) }, { code: "\r\n\r\n\r\n.foo\r\n\r\n.bar\r\n\r\n\r\n> .other\r\n\r\n\r\n{ }", fixed: "\r\n\r\n\r\n.foo\r\n\r\n.bar\r\n\r\n> .other\r\n\r\n\r\n{ }", - message: messages.expected(1), - line: 6, - column: 5 + message: messages.expected(1) }, { code: "a[\n\n\nitemprop=url] { }", fixed: "a[\n\nitemprop=url] { }", message: messages.expected(1), line: 1, - column: 3 + column: 1 }, { code: "a[\r\n\r\n\r\nitemprop=url] { }", fixed: "a[\r\n\r\nitemprop=url] { }", message: messages.expected(1), line: 1, - column: 3 + column: 1 }, { code: "a[itemprop\n\n\n=url] { }", fixed: "a[itemprop\n\n=url] { }", message: messages.expected(1), line: 1, - column: 11 + column: 1 }, { code: "a[itemprop\r\n\r\n\r\n=url] { }", fixed: "a[itemprop\r\n\r\n=url] { }", message: messages.expected(1), line: 1, - column: 11 + column: 1 }, { code: "a[itemprop=\n\n\nurl] { }", fixed: "a[itemprop=\n\nurl] { }", message: messages.expected(1), line: 1, - column: 12 + column: 1 }, { code: "a[itemprop=\r\n\r\n\r\nurl] { }", fixed: "a[itemprop=\r\n\r\nurl] { }", message: messages.expected(1), line: 1, - column: 12 + column: 1 }, { code: "a[itemprop=url\n\n\n] { }", fixed: "a[itemprop=url\n\n] { }", message: messages.expected(1), line: 1, - column: 15 + column: 1 }, { code: "a[itemprop=url\r\n\r\n\r\n] { }", fixed: "a[itemprop=url\r\n\r\n] { }", message: messages.expected(1), line: 1, - column: 15 + column: 1 }, { code: "a\n\n\n:hover { }", fixed: "a\n\n:hover { }", message: messages.expected(1), line: 1, - column: 2 + column: 1 }, { code: "a\r\n\r\n\r\n:hover { }", fixed: "a\r\n\r\n:hover { }", message: messages.expected(1), line: 1, - column: 2 + column: 1 }, { code: "a:\n\n\nhover { }", fixed: "a:\n\nhover { }", message: messages.expected(1), line: 1, - column: 3 + column: 1 }, { code: "a:\r\n\r\n\r\nhover { }", fixed: "a:\r\n\r\nhover { }", message: messages.expected(1), line: 1, - column: 3 + column: 1 }, { code: "a\n\n\n::before { }", fixed: "a\n\n::before { }", message: messages.expected(1), line: 1, - column: 2 + column: 1 }, { code: "a\r\n\r\n\r\n::before { }", fixed: "a\r\n\r\n::before { }", message: messages.expected(1), line: 1, - column: 2 + column: 1 }, { code: "a::\n\n\nbefore { }", fixed: "a::\n\nbefore { }", message: messages.expected(1), line: 1, - column: 4 + column: 1 }, { code: "a::\r\n\r\n\r\nbefore { }", fixed: "a::\r\n\r\nbefore { }", message: messages.expected(1), line: 1, - column: 4 + column: 1 }, { code: ".foo\n\n\n/*comment*/.bar { }", fixed: ".foo\n\n/*comment*/.bar { }", message: messages.expected(1), line: 1, - column: 5 + column: 1 }, { code: ".foo\r\n\r\n\r\n/*comment*/.bar { }", fixed: ".foo\r\n\r\n/*comment*/.bar { }", message: messages.expected(1), line: 1, - column: 5 + column: 1 } ] }); diff --git a/lib/rules/selector-max-empty-lines/index.js b/lib/rules/selector-max-empty-lines/index.js index d14763f9bb..10708d3a3e 100644 --- a/lib/rules/selector-max-empty-lines/index.js +++ b/lib/rules/selector-max-empty-lines/index.js @@ -3,7 +3,6 @@ const _ = require("lodash"); const report = require("../../utils/report"); const ruleMessages = require("../../utils/ruleMessages"); -const styleSearch = require("style-search"); const validateOptions = require("../../utils/validateOptions"); const ruleName = "selector-max-empty-lines"; @@ -26,61 +25,52 @@ const rule = function(max, options, context) { return; } + const violatedCRLFNewLinesRegex = new RegExp( + `(?:\r\n){${maxAdjacentNewlines + 1},}` + ); + const violatedLFNewLinesRegex = new RegExp( + `\n{${maxAdjacentNewlines + 1},}` + ); + const allowedLFNewLinesString = context.fix + ? _.repeat("\n", maxAdjacentNewlines) + : ""; + const allowedCRLFNewLinesString = context.fix + ? _.repeat("\r\n", maxAdjacentNewlines) + : ""; + root.walkRules(rule => { const selector = rule.raws.selector ? rule.raws.selector.raw : rule.selector; - const repeatLFNewLines = _.repeat("\n", maxAdjacentNewlines); - const repeatCRLFNewLines = _.repeat("\r\n", maxAdjacentNewlines); - - styleSearch({ source: selector, target: "\n" }, match => { - if ( - selector.substr(match.startIndex + 1, maxAdjacentNewlines) === - repeatLFNewLines || - selector.substr(match.startIndex + 1, maxAdjacentNewlines * 2) === - repeatCRLFNewLines - ) { - // Put index at `\r` if it's CRLF, otherwise leave it at `\n` - let index = match.startIndex; - - if (selector[index - 1] === "\r") { - index -= 1; - } - - if (context.fix) { - const violationsAdjacentNewlines = max + 2; - - const regexLF = new RegExp( - "(?:\n){" + violationsAdjacentNewlines + ",}", - "gm" - ); - const regexCRLF = new RegExp( - "(?:\r\n){" + violationsAdjacentNewlines + ",}", - "gm" - ); - - const newSelectorStr = selector - .replace(regexCRLF, repeatCRLFNewLines) - .replace(regexLF, repeatLFNewLines); - - if (rule.raws.selector) { - rule.raws.selector.raw = newSelectorStr; - } else { - rule.selector = newSelectorStr; - } - - return; - } - report({ - message: messages.expected(max), - node: rule, - index, - result, - ruleName - }); + if (context.fix) { + const newSelectorString = selector + .replace( + new RegExp(violatedLFNewLinesRegex, "gm"), + allowedLFNewLinesString + ) + .replace( + new RegExp(violatedCRLFNewLinesRegex, "gm"), + allowedCRLFNewLinesString + ); + + if (rule.raws.selector) { + rule.raws.selector.raw = newSelectorString; + } else { + rule.selector = newSelectorString; } - }); + } else if ( + violatedLFNewLinesRegex.test(selector) || + violatedCRLFNewLinesRegex.test(selector) + ) { + report({ + message: messages.expected(max), + node: rule, + index: 0, + result, + ruleName + }); + } }); }; }; diff --git a/lib/rules/value-list-max-empty-lines/__tests__/index.js b/lib/rules/value-list-max-empty-lines/__tests__/index.js index f348fac206..8cd3446224 100644 --- a/lib/rules/value-list-max-empty-lines/__tests__/index.js +++ b/lib/rules/value-list-max-empty-lines/__tests__/index.js @@ -50,68 +50,73 @@ testRule(rule, { }, { code: "a { box-shadow: inset 0 2px 0 #dcffa6,\r\n0 2px 5px #000; }" - }, - { - code: "a { padding: 10px /*\n\n\n\n\n\n*/ 10px 10px 10px }" } ], reject: [ + { + code: "a { padding: 10px /*\n\n\n\n\n\n*/ 10px 10px 10px }", + fixed: "a { padding: 10px /*\n*/ 10px 10px 10px }", + description: "comments are not skipped", + message: messages.expected(0), + line: 1, + column: 5 + }, { code: "a { padding: 10px\n\n10px 10px 10px }", fixed: "a { padding: 10px\n10px 10px 10px }", message: messages.expected(0), line: 1, - column: 9 + column: 5 }, { code: "a { padding: 10px\r\n\r\n10px 10px 10px }", fixed: "a { padding: 10px\r\n10px 10px 10px }", message: messages.expected(0), line: 1, - column: 9 + column: 5 }, { code: "a { padding: 10px 10px 10px\n\n10px }", fixed: "a { padding: 10px 10px 10px\n10px }", message: messages.expected(0), line: 1, - column: 19 + column: 5 }, { code: "a { padding: 10px 10px 10px\r\n\r\n10px }", fixed: "a { padding: 10px 10px 10px\r\n10px }", message: messages.expected(0), line: 1, - column: 19 + column: 5 }, { code: "a { box-shadow: inset 0 2px 0 #dcffa6,\n\n0 2px 5px #000; }", fixed: "a { box-shadow: inset 0 2px 0 #dcffa6,\n0 2px 5px #000; }", message: messages.expected(0), line: 1, - column: 27 + column: 5 }, { code: "a { box-shadow: inset 0 2px 0 #dcffa6,\r\n\r\n0 2px 5px #000; }", fixed: "a { box-shadow: inset 0 2px 0 #dcffa6,\r\n0 2px 5px #000; }", message: messages.expected(0), line: 1, - column: 27 + column: 5 }, { code: "a { padding: 10px\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n10px 10px 10px }", fixed: "a { padding: 10px\n10px 10px 10px }", message: messages.expected(0), line: 1, - column: 9 + column: 5 }, { code: "a { padding: 10px\n\n\n\n10px\n\n\n10px\n\n10px }", fixed: "a { padding: 10px\n10px\n10px\n10px }", message: messages.expected(0), line: 1, - column: 9 + column: 5 }, { code: @@ -119,28 +124,28 @@ testRule(rule, { fixed: "a { padding: 10px\r\n10px\r\n10px\r\n10px }", message: messages.expected(0), line: 1, - column: 9 + column: 5 }, { code: "a { padding: 10px\n\n /*comment*/ 10px 10px 10px }", fixed: "a { padding: 10px\n /*comment*/ 10px 10px 10px }", message: messages.expected(0), line: 1, - column: 9 + column: 5 }, { code: "a { padding: 10px\r\n\r\n /*comment*/ 10px 10px 10px }", fixed: "a { padding: 10px\r\n /*comment*/ 10px 10px 10px }", message: messages.expected(0), line: 1, - column: 9 + column: 5 }, { code: "a { padding: 10px\n\n \n\n\t\n\n10px 10px 10px }", fixed: "a { padding: 10px\n \n\t\n10px 10px 10px }", message: messages.expected(0), line: 1, - column: 9 + column: 5 } ] }); @@ -180,35 +185,35 @@ testRule(rule, { fixed: "a { padding: 10px\n\n10px 10px 10px }", message: messages.expected(1), line: 1, - column: 9 + column: 5 }, { code: "a { padding: 10px\r\n\r\n\r\n10px 10px 10px }", fixed: "a { padding: 10px\r\n\r\n10px 10px 10px }", message: messages.expected(1), line: 1, - column: 9 + column: 5 }, { code: "a { padding: 10px 10px 10px\n\n\n10px }", fixed: "a { padding: 10px 10px 10px\n\n10px }", message: messages.expected(1), line: 1, - column: 19 + column: 5 }, { code: "a { padding: 10px 10px 10px\r\n\r\n\r\n10px }", fixed: "a { padding: 10px 10px 10px\r\n\r\n10px }", message: messages.expected(1), line: 1, - column: 19 + column: 5 }, { code: "a { box-shadow: inset 0 2px 0 #dcffa6,\n\n\n0 2px 5px #000; }", fixed: "a { box-shadow: inset 0 2px 0 #dcffa6,\n\n0 2px 5px #000; }", message: messages.expected(1), line: 1, - column: 27 + column: 5 }, { code: @@ -216,7 +221,7 @@ testRule(rule, { fixed: "a { box-shadow: inset 0 2px 0 #dcffa6,\r\n\r\n0 2px 5px #000; }", message: messages.expected(1), line: 1, - column: 27 + column: 5 } ] }); diff --git a/lib/rules/value-list-max-empty-lines/index.js b/lib/rules/value-list-max-empty-lines/index.js index 23ce11f0ec..bdf3889422 100644 --- a/lib/rules/value-list-max-empty-lines/index.js +++ b/lib/rules/value-list-max-empty-lines/index.js @@ -3,7 +3,6 @@ const _ = require("lodash"); const report = require("../../utils/report"); const ruleMessages = require("../../utils/ruleMessages"); -const styleSearch = require("style-search"); const validateOptions = require("../../utils/validateOptions"); const ruleName = "value-list-max-empty-lines"; @@ -26,64 +25,49 @@ const rule = function(max, options, context) { return; } + const violatedCRLFNewLinesRegex = new RegExp( + `(?:\r\n){${maxAdjacentNewlines + 1},}` + ); + const violatedLFNewLinesRegex = new RegExp( + `\n{${maxAdjacentNewlines + 1},}` + ); + const allowedLFNewLinesString = context.fix + ? _.repeat("\n", maxAdjacentNewlines) + : ""; + const allowedCRLFNewLinesString = context.fix + ? _.repeat("\r\n", maxAdjacentNewlines) + : ""; + root.walkDecls(decl => { const value = decl.raws.value ? decl.raws.value.raw : decl.value; - const repeatLFNewLines = _.repeat("\n", maxAdjacentNewlines); - const repeatCRLFNewLines = _.repeat("\r\n", maxAdjacentNewlines); - - const fixIndices = []; - - styleSearch({ source: value, target: "\n" }, match => { - if ( - value.substr(match.startIndex + 1, maxAdjacentNewlines) === - repeatLFNewLines || - value.substr(match.startIndex + 1, maxAdjacentNewlines * 2) === - repeatCRLFNewLines - ) { - // Put index at `\r` if it's CRLF, otherwise leave it at `\n` - let index = match.startIndex; - - if (value[index - 1] === "\r") { - index -= 1; - } - - if (context.fix) { - fixIndices.push(index); - - return; - } - - report({ - message: messages.expected(max), - node: decl, - index, - result, - ruleName - }); - } - }); - - if (fixIndices.length) { - const maxAdjacentNewLinesStr = _.repeat( - context.newline, - maxAdjacentNewlines - ); - let fixedValue = value; - fixIndices - .sort((a, b) => b - a) - .forEach(index => { - fixedValue = - fixedValue.slice(0, index) + - maxAdjacentNewLinesStr + - fixedValue.slice(index).replace(/^[\r\n]*/, ""); - }); + if (context.fix) { + const newValueString = value + .replace( + new RegExp(violatedLFNewLinesRegex, "gm"), + allowedLFNewLinesString + ) + .replace( + new RegExp(violatedCRLFNewLinesRegex, "gm"), + allowedCRLFNewLinesString + ); if (decl.raws.value) { - decl.raws.value.raw = fixedValue; + decl.raws.value.raw = newValueString; } else { - decl.value = fixedValue; + decl.value = newValueString; } + } else if ( + violatedLFNewLinesRegex.test(value) || + violatedCRLFNewLinesRegex.test(value) + ) { + report({ + message: messages.expected(max), + node: decl, + index: 0, + result, + ruleName + }); } }); }; diff --git a/system-tests/005/__snapshots__/005.test.js.snap b/system-tests/005/__snapshots__/005.test.js.snap index d93eab5973..477c5aef8b 100644 --- a/system-tests/005/__snapshots__/005.test.js.snap +++ b/system-tests/005/__snapshots__/005.test.js.snap @@ -10088,7 +10088,7 @@ Array [ "text": "Unexpected nonstandard direction (function-linear-gradient-no-nonstandard-direction)", }, Object { - "column": 15, + "column": 4, "line": 90, "rule": "function-max-empty-lines", "severity": "error", @@ -16448,7 +16448,7 @@ b\\" to have no more than 0 combinators (selector-max-combinators)", "text": "Expected \\".foo .bar .baz .lorem\\" to have no more than 3 compound selectors (selector-max-compound-selectors)", }, Object { - "column": 2, + "column": 1, "line": 188, "rule": "selector-max-empty-lines", "severity": "error", @@ -18190,14 +18190,14 @@ b\\" to have no more than 0 type selectors (selector-max-type)", "text": "Expected single space before \\",\\" (value-list-comma-space-before)", }, Object { - "column": 13, + "column": 3, "line": 89, "rule": "value-list-max-empty-lines", "severity": "error", "text": "Expected no more than 0 empty lines (value-list-max-empty-lines)", }, Object { - "column": 7, + "column": 3, "line": 246, "rule": "value-list-max-empty-lines", "severity": "error",