Skip to content

Commit

Permalink
Merge pull request #331 from rambleraptor/map-quotes
Browse files Browse the repository at this point in the history
Ensure that all map keys are quoted
  • Loading branch information
kristerkari committed Jul 3, 2019
2 parents 73ce6a6 + 8628f64 commit 823c40e
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/rules/index.js
Expand Up @@ -33,6 +33,7 @@ import functionNoQuotedStrings from "./function-quote-no-quoted-strings-inside";
import functionNoUnquotedStrings from "./function-unquote-no-unquoted-strings-inside";
import mediaFeatureValueDollarVariable from "./media-feature-value-dollar-variable";
import noDollarVariables from "./no-dollar-variables";
import mapKeysQuotes from "./map-keys-quotes";
import noDuplicateDollarVariables from "./no-duplicate-dollar-variables";
import operatorNoNewlineAfter from "./operator-no-newline-after";
import operatorNoNewlineBefore from "./operator-no-newline-before";
Expand Down Expand Up @@ -77,6 +78,7 @@ export default {
"double-slash-comment-whitespace-inside": doubleSlashCommentWhitespaceInside,
"function-quote-no-quoted-strings-inside": functionNoQuotedStrings,
"function-unquote-no-unquoted-strings-inside": functionNoUnquotedStrings,
"map-keys-quotes": mapKeysQuotes,
"media-feature-value-dollar-variable": mediaFeatureValueDollarVariable,
"no-dollar-variables": noDollarVariables,
"no-duplicate-dollar-variables": noDuplicateDollarVariables,
Expand Down
26 changes: 26 additions & 0 deletions src/rules/map-keys-quotes/README.md
@@ -0,0 +1,26 @@
# map-keys-quotes

All map keys should be quoted.

```scss
$test: (Helvetica: 14px, Arial: 25px);
/** ↑ ↑
* These words should be quoted.
*/
```

## Options

### `always`

The following patterns are considered violations:

```scss
$test: (Helvetica: 14px, Arial: 25px);
```

The following patterns are _not_ considered violations:

```scss
$test: ("foo": 14px, "bar": 25px);
```
28 changes: 28 additions & 0 deletions src/rules/map-keys-quotes/__tests__/index.js
@@ -0,0 +1,28 @@
import rule, { ruleName, messages } from "..";

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

accept: [
{
code: `
$test: ("foo": 14px, "bar": 25px);
`,
description: "accepts strings without quotes"
}
],

reject: [
{
code: `
$test: (Helvetica: 25px, Arial: 50px)
`,
message: messages.expected,
description:
"does not accept variables representing strings that are quoted.",
location: 1
}
]
});
84 changes: 84 additions & 0 deletions src/rules/map-keys-quotes/index.js
@@ -0,0 +1,84 @@
import { utils } from "stylelint";
import { namespace } from "../../utils";
import valueParser from "postcss-value-parser";

export const ruleName = namespace("map-keys-quotes");

export const messages = utils.ruleMessages(ruleName, {
expected: "Expected keys in map to be quoted."
});

function rule(primary) {
return (root, result) => {
const validOptions = utils.validateOptions(result, ruleName, {
actual: primary,
possible: ["always"]
});

if (!validOptions) {
return;
}

root.walkDecls(decl => {
if (decl.prop[0] !== "$") {
return;
}

valueParser(decl.value).walk(node => {
if (
node.type === "function" &&
node.value === "" &&
isMap(node.nodes)
) {
// Identify all of the map-keys and see if they're strings (not words).
const mapKeys = returnMapKeys(node.nodes);

mapKeys.forEach(map_key => {
if (map_key.type === "word") {
utils.report({
message: messages.expected,
node: decl,
result,
ruleName
});
}
});
}
});
});
};
}

// Takes in a list of map nodes and identifies if they are a map.
// A map is identified by the pattern: [string/word colon(div) anything comma(div) ...]
function isMap(nodes) {
if (nodes.length < 4) {
return false;
}

if (nodes[0].type !== "word" && nodes[0].type !== "string") {
return false;
}

if (nodes[1].value !== ":") {
return false;
}

if (nodes[3].value !== ",") {
return false;
}

return true;
}

function returnMapKeys(array) {
const new_array = [];

for (let i = 0; i < array.length; i += 4) {
new_array.push(array[i]);
}

return new_array;
}

export default rule;

0 comments on commit 823c40e

Please sign in to comment.