diff --git a/src/rules/no-unused-private-members/__tests__/index.js b/src/rules/no-unused-private-members/__tests__/index.js index 34094dc3..d8f058b7 100644 --- a/src/rules/no-unused-private-members/__tests__/index.js +++ b/src/rules/no-unused-private-members/__tests__/index.js @@ -341,3 +341,203 @@ testRule({ } ] }); + +testRule({ + ruleName, + config: [true, { enableAutoFix: 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("%-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 d3c7616d..f97572f7 100644 --- a/src/rules/no-unused-private-members/index.js +++ b/src/rules/no-unused-private-members/index.js @@ -3,6 +3,7 @@ const { utils } = require("stylelint"); const namespace = require("../../utils/namespace"); const ruleUrl = require("../../utils/ruleUrl"); +const { isBoolean } = require("../../utils/validateTypes"); const ruleName = namespace("no-unused-private-members"); @@ -25,11 +26,22 @@ function getPrivateMembers(inputString) { return matches; } -function rule(primaryOption) { +function rule(primaryOption, secondaryOptions, context) { return (root, result) => { - const validOptions = utils.validateOptions(result, ruleName, { - actual: primaryOption - }); + const validOptions = utils.validateOptions( + result, + ruleName, + { + actual: primaryOption + }, + { + actual: secondaryOptions, + possible: { + enableAutoFix: [isBoolean] + }, + optional: true + } + ); if (!validOptions) { return; @@ -133,10 +145,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 && secondaryOptions?.enableAutoFix) { + node.remove(); + return; + } utils.report({ message: messages.expected(key), - node: value, + node, result, ruleName });