Skip to content

Commit

Permalink
Update: Add ignoreDestructing option to camelcase rule (fixes #9807) (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
alunny authored and kaicataldo committed Jun 9, 2018
1 parent e2b394d commit abf400d
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 9 deletions.
48 changes: 46 additions & 2 deletions docs/rules/camelcase.md
Expand Up @@ -12,8 +12,10 @@ This rule has an object option:

* `"properties": "always"` (default) enforces camelcase style for property names
* `"properties": "never"` does not check property names
* `"ignoreDestructuring": false` (default) enforces camelcase style for destructured identifiers
* `"ignoreDestructuring": true` does not check destructured identifiers

### always
### properties: "always"

Examples of **incorrect** code for this rule with the default `{ "properties": "always" }` option:

Expand Down Expand Up @@ -95,7 +97,7 @@ var { foo: isCamelCased = 1 } = quz;

```

### never
### properties: "never"

Examples of **correct** code for this rule with the `{ "properties": "never" }` option:

Expand All @@ -107,6 +109,48 @@ var obj = {
};
```

### ignoreDestructuring: false

Examples of **incorrect** code for this rule with the default `{ "ignoreDestructuring": false }` option:

```js
/*eslint camelcase: "error"*/

var { category_id } = query;

var { category_id = 1 } = query;

var { category_id: category_id } = query;

var { category_id: category_alias } = query;

var { category_id: categoryId, ...other_props } = query;
```

### ignoreDestructuring: true

Examples of **incorrect** code for this rule with the `{ "ignoreDestructuring": true }` option:

```js
/*eslint camelcase: ["error", {ignoreDestructuring: true}]*/

var { category_id: category_alias } = query;

var { category_id, ...other_props } = query;
```

Examples of **correct** code for this rule with the `{ "ignoreDestructuring": true }` option:

```js
/*eslint camelcase: ["error", {ignoreDestructuring: true}]*/

var { category_id } = query;

var { category_id = 1 } = query;

var { category_id: category_id } = query;
```

## When Not To Use It

If you have established coding standards using a different naming convention (separating words with underscores), turn this rule off.
38 changes: 33 additions & 5 deletions lib/rules/camelcase.js
Expand Up @@ -22,6 +22,9 @@ module.exports = {
{
type: "object",
properties: {
ignoreDestructuring: {
type: "boolean"
},
properties: {
enum: ["always", "never"]
}
Expand Down Expand Up @@ -57,6 +60,26 @@ module.exports = {
return name.indexOf("_") > -1 && name !== name.toUpperCase();
}

/**
* Checks if a parent of a node is an ObjectPattern.
* @param {ASTNode} node The node to check.
* @returns {boolean} if the node is inside an ObjectPattern
* @private
*/
function isInsideObjectPattern(node) {
let { parent } = node;

while (parent) {
if (parent.type === "ObjectPattern") {
return true;
}

parent = parent.parent;
}

return false;
}

/**
* Reports an AST node as a rule violation.
* @param {ASTNode} node The node to report.
Expand All @@ -72,6 +95,7 @@ module.exports = {

const options = context.options[0] || {};
let properties = options.properties || "";
const ignoreDestructuring = options.ignoreDestructuring || false;

if (properties !== "always" && properties !== "never") {
properties = "always";
Expand Down Expand Up @@ -113,24 +137,28 @@ module.exports = {
} else if (node.parent.type === "Property" || node.parent.type === "AssignmentPattern") {

if (node.parent.parent && node.parent.parent.type === "ObjectPattern") {

if (node.parent.shorthand && node.parent.value.left && isUnderscored(name)) {

report(node);
}

const assignmentKeyEqualsValue = node.parent.key.name === node.parent.value.name;

// prevent checking righthand side of destructured object
if (node.parent.key === node && node.parent.value !== node) {
if (!assignmentKeyEqualsValue && node.parent.key === node) {
return;
}

if (node.parent.value.name && isUnderscored(name)) {
const valueIsUnderscored = node.parent.value.name && isUnderscored(name);

// ignore destructuring if the option is set, unless a new identifier is created
if (valueIsUnderscored && !(assignmentKeyEqualsValue && ignoreDestructuring)) {
report(node);
}
}

// "never" check properties
if (properties === "never") {
// "never" check properties or always ignore destructuring
if (properties === "never" || (ignoreDestructuring && isInsideObjectPattern(node))) {
return;
}

Expand Down
43 changes: 41 additions & 2 deletions tests/lib/rules/camelcase.js
Expand Up @@ -91,6 +91,21 @@ ruleTester.run("camelcase", rule, {
code: "obj.foo_bar = function(){};",
options: [{ properties: "never" }]
},
{
code: "var { category_id } = query;",
options: [{ ignoreDestructuring: true }],
parserOptions: { ecmaVersion: 6 }
},
{
code: "var { category_id: category_id } = query;",
options: [{ ignoreDestructuring: true }],
parserOptions: { ecmaVersion: 6 }
},
{
code: "var { category_id = 1 } = query;",
options: [{ ignoreDestructuring: true }],
parserOptions: { ecmaVersion: 6 }
},
{
code: "var { category_id: category } = query;",
parserOptions: { ecmaVersion: 6 }
Expand Down Expand Up @@ -292,12 +307,36 @@ ruleTester.run("camelcase", rule, {
]
},
{
code: "var { category_id: category_id } = query;",
code: "var { category_id: category_alias } = query;",
parserOptions: { ecmaVersion: 6 },
errors: [
{
messageId: "notCamelCase",
data: { name: "category_id" },
data: { name: "category_alias" },
type: "Identifier"
}
]
},
{
code: "var { category_id: category_alias } = query;",
options: [{ ignoreDestructuring: true }],
parserOptions: { ecmaVersion: 6 },
errors: [
{
messageId: "notCamelCase",
data: { name: "category_alias" },
type: "Identifier"
}
]
},
{
code: "var { category_id: categoryId, ...other_props } = query;",
options: [{ ignoreDestructuring: true }],
parserOptions: { ecmaVersion: 2018 },
errors: [
{
messageId: "notCamelCase",
data: { name: "other_props" },
type: "Identifier"
}
]
Expand Down

0 comments on commit abf400d

Please sign in to comment.