diff --git a/src/rules/no-unused-private-members/__tests__/index.js b/src/rules/no-unused-private-members/__tests__/index.js index b096defe..86cc77ed 100644 --- a/src/rules/no-unused-private-members/__tests__/index.js +++ b/src/rules/no-unused-private-members/__tests__/index.js @@ -134,12 +134,8 @@ testRule({ %-toolbelt { box-sizing: border-box; } - - %-toolbelt:hover { - color: red; - } - - .b.%-toolbelt{ + + .b { color: blue; } `, @@ -163,10 +159,210 @@ testRule({ color: blue; } `, - message: messages.expected("%-b"), + message: messages.expected(".a.%-b"), line: 6, column: 7, description: "Private placeholder selector with class" } ] }); + +testRule({ + ruleName, + config: [true], + customSyntax: "postcss-scss", + fix: true, + + accept: [ + { + code: ` + @function _addNums($n1, $n2) { + @return calc($n1 + $n2); + } + + @function one($n1) { + @return $n1; + } + + .sidebar { + margin-left: _addNums(4, 6); + } + `, + description: "Private function" + }, + { + code: ` + @mixin _reset-list { + margin: 0; + } + + nav ul { + @include _reset-list; + } + `, + description: "Private mixin" + }, + { + code: ` + $-radius: 3px; + + .rounded { + border-radius: $-radius; + } + `, + description: "Private variable" + }, + { + code: ` + %-toolbelt:hover { + color: red; + } + + .a.%-b { + margin: 1px; + } + + .action-buttons { + @extend %-toolbelt; + @extend %-b; + color: blue; + } + `, + description: "Private placeholder selector" + }, + { + code: ` + @import "fff" + $-radius: 3px; + + rounded { + border-radius: 0px; + } + `, + message: messages.expected("$-radius"), + description: "Skip files using @import", + line: 2, + column: 7 + } + ], + + reject: [ + { + code: ` + @function _addNums($n1, $n2) { + @return calc($n1 + $n2); + } + + @function _one($n1) { + @return $n1; + } + + .sidebar { + margin-left: _addNums(4, 6); + } + `, + fixed: ` + @function _addNums($n1, $n2) { + @return calc($n1 + $n2); + } + + .sidebar { + margin-left: _addNums(4, 6); + } + `, + message: messages.expected("_one"), + description: "Private function", + line: 6, + column: 7 + }, + { + code: ` + @mixin _reset-list { + margin: 0; + padding: 0; + list-style: none; + } + nav ul { + margin: 0; + } + `, + fixed: ` + nav ul { + margin: 0; + } + `, + message: messages.expected("_reset-list"), + description: "Private mixin", + line: 2, + column: 7 + }, + { + code: ` + $-radius: 3px; + + rounded { + border-radius: 0px; + } + `, + fixed: ` + rounded { + border-radius: 0px; + } + `, + message: messages.expected("$-radius"), + description: "Private variable", + line: 2, + column: 7 + }, + { + code: ` + %-toolbelt { + border-radius: 0px; + } + + .b { + color: blue; + } + `, + fixed: ` + .b { + color: blue; + } + `, + message: messages.expected("%-toolbelt"), + description: "Private placeholder selector", + line: 2, + column: 7 + }, + { + code: ` + %-toolbelt:hover { + color: red; + } + + .a.%-b { + margin: 1px; + } + + .action-buttons { + @extend %-toolbelt; + color: blue; + } + `, + fixed: ` + %-toolbelt:hover { + color: red; + } + + .action-buttons { + @extend %-toolbelt; + color: blue; + } + `, + message: messages.expected(".a.%-b"), + line: 6, + column: 9, + description: "Private placeholder selector with class" + } + ] +}); diff --git a/src/rules/no-unused-private-members/index.js b/src/rules/no-unused-private-members/index.js index 54fec862..f03a5587 100644 --- a/src/rules/no-unused-private-members/index.js +++ b/src/rules/no-unused-private-members/index.js @@ -20,7 +20,7 @@ function extractFunctionName(inputString) { return [...matches].flat(); } -function rule(primaryOption) { +function rule(primaryOption, _, context) { return (root, result) => { const validOptions = utils.validateOptions(result, ruleName, { actual: primaryOption @@ -46,16 +46,7 @@ function rule(primaryOption) { node.type === "rule" && (node.selector.includes("%-") || node.selector.includes("%_")); if (isPrivatePlaceholderSelector) { - const selectors = node.selector - .split(/:|\./g) - .filter( - selector => selector.startsWith("%-") | selector.includes("%_") - ); - selectors.forEach(selector => { - if (!privateMembers.selectors.has(selector)) { - privateMembers.selectors.set(selector, node); - } - }); + privateMembers.selectors.set(node.selector, node); } // Private variables @@ -88,8 +79,12 @@ function rule(primaryOption) { }); root.walkAtRules(node => { - if (node.name === "extend" && privateMembers.selectors.has(node.params)) { - privateMembers.selectors.delete(node.params); + if (node.name === "extend") { + for (let selector of privateMembers.selectors.keys()) { + if (selector.includes(node.params)) { + privateMembers.selectors.delete(selector); + } + } } if (node.name === "include" && privateMembers.mixins.has(node.params)) { privateMembers.mixins.delete(node.params); @@ -110,10 +105,14 @@ function rule(primaryOption) { }); for (const types in privateMembers) { - for (const [key, value] of privateMembers[types].entries()) { + for (const [key, node] of privateMembers[types].entries()) { + if (context.fix) { + node.remove(); + return; + } utils.report({ message: messages.expected(key), - node: value, + node: node, result, ruleName });