Skip to content

Commit

Permalink
Merge pull request #351 from rambleraptor/at-rule-no-parentheses
Browse files Browse the repository at this point in the history
New rule: at-conditional-rule-no-parentheses
  • Loading branch information
kristerkari committed Aug 26, 2019
2 parents 859438c + a6d304e commit 5690c68
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 0 deletions.
43 changes: 43 additions & 0 deletions src/rules/at-rule-conditional-no-parentheses/README.md
@@ -0,0 +1,43 @@
# at-rule-conditional-no-parentheses

Disallow parentheses in conditional @ rules (if, elsif, while)

```css
@if (true) {}
/** ↑ ↑
* Get rid of parentheses like this. */
```



## Options

### `true`

The following patterns are considered warnings:

```scss
@if(true)
```

```scss
@else if(true)
```

```scss
@while(true)
```

The following patterns are *not* considered warnings:

```scss
@if true
```

```scss
@else if true
```

```scss
@while true
```
57 changes: 57 additions & 0 deletions src/rules/at-rule-conditional-no-parentheses/__tests__/index.js
@@ -0,0 +1,57 @@
import rule, { ruleName, messages } from "..";

testRule(rule, {
ruleName,
config: [true],
syntax: "scss",
fix: true,

accept: [
{
code: "@if true {}",
description: "accepts @if with no parentheses"
},
{
code: "@if (1 + 1) == 2 {}",
description: "accepts parentheses statement where () used for math"
},
{
code: "@while true {}",
description: "accepts @while with no parentheses"
},
{
code: `@if true {}
@else if true {}`,
description: "accepts @else if with no parentheses"
},
{
code: `@if true {}
@else if true {}
@else {}`,
description: "accepts @else unconditionally"
}
],

reject: [
{
code: "@if(true) {}",
fixed: "@if true {}",
message: messages.rejected,
description: "does not accept @if with parentheses"
},
{
code: "@while(true) {}",
fixed: "@while true {}",
message: messages.rejected,
description: "does not accept @while with parentheses"
},
{
code: `@if true {}
@else if(true) {}`,
fixed: `@if true {}
@else if true {}`,
message: messages.rejected,
description: "does not accept @else if with parentheses"
}
]
});
70 changes: 70 additions & 0 deletions src/rules/at-rule-conditional-no-parentheses/index.js
@@ -0,0 +1,70 @@
import { utils } from "stylelint";
import { namespace } from "../../utils";
import _ from "lodash";

export const ruleName = namespace("at-rule-conditional-no-parentheses");

export const messages = utils.ruleMessages(ruleName, {
rejected: "Unexpected () used to surround statements for @-rules"
});

// postcss picks up else-if as else.
const conditional_rules = ["if", "while", "else"];

function report(atrule, result) {
utils.report({
message: messages.rejected,
node: atrule,
result,
ruleName
});
}

function fix(atrule) {
const regex = /(if)? ?\((.*)\)/;

// 2 regex groups: 'if ' and cond.
const groups = atrule.params.match(regex).slice(1);

atrule.params = _.uniq(groups).join(" ");
}

export default function(primary, _unused, context) {
return (root, result) => {
const validOptions = utils.validateOptions(result, ruleName, {
actual: primary
});

if (!validOptions) {
return;
}

root.walkAtRules(atrule => {
// Check if this is a conditional rule.
if (!_.includes(conditional_rules, atrule.name)) {
return;
}

// Else uses a different regex
// params are of format "`if (cond)` or `if cond`
// instead of `(cond)` or `cond`"
if (atrule.name === "else") {
if (atrule.params.match(/ ?if ?\(.*\) ?$/)) {
if (context.fix) {
fix(atrule);
} else {
report(atrule, result);
}
}
} else {
if (atrule.params.match(/ ?\(.*\) ?$/)) {
if (context.fix) {
fix(atrule);
} else {
report(atrule, result);
}
}
}
});
};
}
2 changes: 2 additions & 0 deletions src/rules/index.js
Expand Up @@ -17,6 +17,7 @@ import atMixinNamedArguments from "./at-mixin-named-arguments";
import atMixinParenthesesSpaceBefore from "./at-mixin-parentheses-space-before";
import atMixinPattern from "./at-mixin-pattern";
import atEachKeyValue from "./at-each-key-value-single-line";
import atRuleConditionalNoParen from "./at-rule-conditional-no-parentheses";
import atRuleNoUnknown from "./at-rule-no-unknown";
import commentNoLoud from "./comment-no-loud";
import declarationNestedProperties from "./declaration-nested-properties";
Expand Down Expand Up @@ -67,6 +68,7 @@ export default {
"at-mixin-parentheses-space-before": atMixinParenthesesSpaceBefore,
"at-mixin-pattern": atMixinPattern,
"at-each-key-value-single-line": atEachKeyValue,
"at-rule-conditional-no-parentheses": atRuleConditionalNoParen,
"at-rule-no-unknown": atRuleNoUnknown,
"comment-no-loud": commentNoLoud,
"declaration-nested-properties": declarationNestedProperties,
Expand Down

0 comments on commit 5690c68

Please sign in to comment.