Skip to content

Commit

Permalink
New: add option for camelcase (fixes #12527) (#12528)
Browse files Browse the repository at this point in the history
* New: add option for camelcase (fixes #12527)

* Docs: add docs about `ignoreImports`

* Chore: add more tests

* Docs: add notice
  • Loading branch information
g-plane authored and ilyavolodin committed Nov 10, 2019
1 parent f49f1e0 commit 41b1e43
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 6 deletions.
32 changes: 32 additions & 0 deletions docs/rules/camelcase.md
Expand Up @@ -14,6 +14,8 @@ This rule has an object option:
* `"properties": "never"` does not check property names
* `"ignoreDestructuring": false` (default) enforces camelcase style for destructured identifiers
* `"ignoreDestructuring": true` does not check destructured identifiers
* `"ignoreImports": false` (default) enforces camelcase style for ES2015 imports
* `"ignoreImports": true` does not check ES2015 imports (but still checks any use of the imports later in the code except function arguments)
* `allow` (`string[]`) list of properties to accept. Accept regex.

### properties: "always"
Expand Down Expand Up @@ -152,6 +154,36 @@ var { category_id = 1 } = query;
var { category_id: category_id } = query;
```

### ignoreImports: false

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

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

import { snake_cased } from 'mod';
```

### ignoreImports: true

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

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

import default_import from 'mod';

import * as namespaced_import from 'mod';
```

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

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

import { snake_cased } from 'mod';
```

## allow

Examples of **correct** code for this rule with the `allow` option:
Expand Down
25 changes: 19 additions & 6 deletions lib/rules/camelcase.js
Expand Up @@ -28,6 +28,10 @@ module.exports = {
type: "boolean",
default: false
},
ignoreImports: {
type: "boolean",
default: false
},
properties: {
enum: ["always", "never"]
},
Expand Down Expand Up @@ -56,6 +60,7 @@ module.exports = {
const options = context.options[0] || {};
let properties = options.properties || "";
const ignoreDestructuring = options.ignoreDestructuring;
const ignoreImports = options.ignoreImports;
const allow = options.allow || [];

if (properties !== "always" && properties !== "never") {
Expand All @@ -79,7 +84,7 @@ module.exports = {
function isUnderscored(name) {

// if there's an underscore, it might be A_CONSTANT, which is okay
return name.indexOf("_") > -1 && name !== name.toUpperCase();
return name.includes("_") && name !== name.toUpperCase();
}

/**
Expand All @@ -89,9 +94,9 @@ module.exports = {
* @private
*/
function isAllowed(name) {
return allow.findIndex(
return allow.some(
entry => name === entry || name.match(new RegExp(entry, "u"))
) !== -1;
);
}

/**
Expand Down Expand Up @@ -127,7 +132,7 @@ module.exports = {
* @private
*/
function report(node) {
if (reported.indexOf(node) < 0) {
if (!reported.includes(node)) {
reported.push(node);
context.report({ node, messageId: "notCamelCase", data: { name: node.name } });
}
Expand Down Expand Up @@ -209,10 +214,18 @@ module.exports = {
}

// Check if it's an import specifier
} else if (["ImportSpecifier", "ImportNamespaceSpecifier", "ImportDefaultSpecifier"].indexOf(node.parent.type) >= 0) {
} else if (["ImportSpecifier", "ImportNamespaceSpecifier", "ImportDefaultSpecifier"].includes(node.parent.type)) {

if (node.parent.type === "ImportSpecifier" && ignoreImports) {
return;
}

// Report only if the local imported identifier is underscored
if (node.parent.local && node.parent.local.name === node.name && nameIsUnderscored) {
if (
node.parent.local &&
node.parent.local.name === node.name &&
nameIsUnderscored
) {
report(node);
}

Expand Down
58 changes: 58 additions & 0 deletions tests/lib/rules/camelcase.js
Expand Up @@ -151,6 +151,16 @@ ruleTester.run("camelcase", rule, {
code: "import { no_camelcased as camelCased, anoterCamelCased } from \"external-module\";",
parserOptions: { ecmaVersion: 6, sourceType: "module" }
},
{
code: "import { snake_cased } from 'mod'",
options: [{ ignoreImports: true }],
parserOptions: { ecmaVersion: 6, sourceType: "module" }
},
{
code: "import { camelCased } from 'mod'",
options: [{ ignoreImports: false }],
parserOptions: { ecmaVersion: 6, sourceType: "module" }
},
{
code: "function foo({ no_camelcased: camelCased }) {};",
parserOptions: { ecmaVersion: 6 }
Expand Down Expand Up @@ -532,6 +542,54 @@ ruleTester.run("camelcase", rule, {
}
]
},
{
code: "import snake_cased from 'mod'",
options: [{ ignoreImports: true }],
parserOptions: { ecmaVersion: 6, sourceType: "module" },
errors: [
{
messageId: "notCamelCase",
data: { name: "snake_cased" },
type: "Identifier"
}
]
},
{
code: "import * as snake_cased from 'mod'",
options: [{ ignoreImports: true }],
parserOptions: { ecmaVersion: 6, sourceType: "module" },
errors: [
{
messageId: "notCamelCase",
data: { name: "snake_cased" },
type: "Identifier"
}
]
},
{
code: "import snake_cased from 'mod'",
options: [{ ignoreImports: false }],
parserOptions: { ecmaVersion: 6, sourceType: "module" },
errors: [
{
messageId: "notCamelCase",
data: { name: "snake_cased" },
type: "Identifier"
}
]
},
{
code: "import * as snake_cased from 'mod'",
options: [{ ignoreImports: false }],
parserOptions: { ecmaVersion: 6, sourceType: "module" },
errors: [
{
messageId: "notCamelCase",
data: { name: "snake_cased" },
type: "Identifier"
}
]
},
{
code: "function foo({ no_camelcased }) {};",
parserOptions: { ecmaVersion: 6 },
Expand Down

0 comments on commit 41b1e43

Please sign in to comment.