Skip to content
Permalink
Browse files

New: add option for camelcase (fixes #12527) (#12528)

* 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 41b1e4308c1cb01c8b00cc8adc36440e77854117
Showing with 109 additions and 6 deletions.
  1. +32 −0 docs/rules/camelcase.md
  2. +19 −6 lib/rules/camelcase.js
  3. +58 −0 tests/lib/rules/camelcase.js
@@ -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"
@@ -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:
@@ -28,6 +28,10 @@ module.exports = {
type: "boolean",
default: false
},
ignoreImports: {
type: "boolean",
default: false
},
properties: {
enum: ["always", "never"]
},
@@ -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") {
@@ -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();
}

/**
@@ -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;
);
}

/**
@@ -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 } });
}
@@ -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);
}

@@ -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 }
@@ -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 },

0 comments on commit 41b1e43

Please sign in to comment.
You can’t perform that action at this time.