Skip to content

Commit

Permalink
Merge pull request #344 from rambleraptor/at-if-no-null
Browse files Browse the repository at this point in the history
New rule: `at-if-no-null`
  • Loading branch information
kristerkari committed Aug 26, 2019
2 parents c2b5b1f + 0b89e0e commit 859438c
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 0 deletions.
44 changes: 44 additions & 0 deletions src/rules/at-if-no-null/README.md
@@ -0,0 +1,44 @@
# at-if-no-null

Check for equality to null is unnecessarily explicit since `null` is falsey in Sass.

```scss
a {
@if $x == null {}
/** ↑ ↑
* == or != null is unncessary */
}
```

## Options

true

### `true`

The following patterns are considered warnings:
```scss
a {
@if $x == null {}
}
```

```scss
a {
@if $x != null {}
}
```

The following patterns are *not* considered warnings:

```scss
a {
@if $x {}
}
```

```scss
a {
@if not $x {}
}
```
47 changes: 47 additions & 0 deletions src/rules/at-if-no-null/__tests__/index.js
@@ -0,0 +1,47 @@
import rule, { ruleName, messages } from "..";

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

accept: [
{
code: `a {
@if $x {}
}`,
description: "does not use the != null format"
},
{
code: `a {
@if not $x {}
}`,
description: "does not use the == null format"
},
{
code: `a {
@if $x != null and $x > 1 {}
}`,
description: "does not use the == null format"
}
],

reject: [
{
code: `a {
@if $x == null {}
}`,
description: "uses the == null format",
message: messages.equals_null,
line: 2
},
{
code: `a {
@if $x != null {}
}`,
description: "uses the != null format",
message: messages.not_equals_null,
line: 2
}
]
});
49 changes: 49 additions & 0 deletions src/rules/at-if-no-null/index.js
@@ -0,0 +1,49 @@
import { namespace } from "../../utils";
import { utils } from "stylelint";

export const ruleName = namespace("at-if-no-null");

export const messages = utils.ruleMessages(ruleName, {
equals_null: "Expected @if not statement rather than @if statement == null",
not_equals_null: "Expected @if statement rather than @if statement != null"
});

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

if (!validOptions) {
return;
}

root.walkAtRules(atrule => {
// Do nothing if it's not an @if
if (atrule.name !== "if") {
return;
}

// If rule != null and (expr), skip
if (atrule.params.match(/\(?[ \t]*.* != null and .*\)?/)) {
return;
}

if (atrule.params.match(/\(?[ \t]*.* == null[ \t]*\)?/)) {
utils.report({
message: messages.equals_null,
node: atrule,
result,
ruleName
});
} else if (atrule.params.match(/\(?[ \t]*.* != null[ \t]*\)?/)) {
utils.report({
message: messages.not_equals_null,
node: atrule,
result,
ruleName
});
}
});
};
}
2 changes: 2 additions & 0 deletions src/rules/index.js
Expand Up @@ -8,6 +8,7 @@ import atFunctionParenthesesSpaceBefore from "./at-function-parentheses-space-be
import atFunctionPattern from "./at-function-pattern";
import atIfClosingBraceNewlineAfter from "./at-if-closing-brace-newline-after";
import atIfClosingBraceSpaceAfter from "./at-if-closing-brace-space-after";
import atIfNoNull from "./at-if-no-null";
import atImportNoPartialLeadingUnderscore from "./at-import-no-partial-leading-underscore";
import atImportPartialExtensionBlacklist from "./at-import-partial-extension-blacklist";
import atImportPartialExtensionWhitelist from "./at-import-partial-extension-whitelist";
Expand Down Expand Up @@ -57,6 +58,7 @@ export default {
"at-function-pattern": atFunctionPattern,
"at-if-closing-brace-newline-after": atIfClosingBraceNewlineAfter,
"at-if-closing-brace-space-after": atIfClosingBraceSpaceAfter,
"at-if-no-null": atIfNoNull,
"at-import-no-partial-leading-underscore": atImportNoPartialLeadingUnderscore,
"at-import-partial-extension-blacklist": atImportPartialExtensionBlacklist,
"at-import-partial-extension-whitelist": atImportPartialExtensionWhitelist,
Expand Down

0 comments on commit 859438c

Please sign in to comment.