diff --git a/lib/rules/no-duplicate-selectors/__tests__/index.js b/lib/rules/no-duplicate-selectors/__tests__/index.js index ea916974f7..400e7b694f 100644 --- a/lib/rules/no-duplicate-selectors/__tests__/index.js +++ b/lib/rules/no-duplicate-selectors/__tests__/index.js @@ -73,6 +73,14 @@ testRule(rule, { line: 1, column: 1 }, + { + code: ".a, .a, .a {}", + message: messages.rejected(".a", 1), + line: 1, + column: 1, + description: + "duplicated selectors within one rule's selector list. 3 duplicates" + }, { code: "a {} b {} a {}", description: "duplicate simple selectors with another rule between", diff --git a/lib/rules/no-duplicate-selectors/index.js b/lib/rules/no-duplicate-selectors/index.js index 00fee878ff..cfe51f1882 100644 --- a/lib/rules/no-duplicate-selectors/index.js +++ b/lib/rules/no-duplicate-selectors/index.js @@ -114,20 +114,27 @@ const rule = function(actual, options) { }); } + const presentedSelectors = new Set(); + const reportedSelectors = new Set(); + // Or complain if one selector list contains the same selector more than one - rule.selectors.forEach((selector, i) => { - if ( - _.includes( - normalizedSelectorList.slice(0, i), - normalizeSelector(selector) - ) - ) { + rule.selectors.forEach(selector => { + const normalized = normalizeSelector(selector); + + if (presentedSelectors.has(normalized)) { + if (reportedSelectors.has(normalized)) { + return; + } + report({ result, ruleName, node: rule, message: messages.rejected(selector, selectorLine) }); + reportedSelectors.add(normalized); + } else { + presentedSelectors.add(normalized); } });