From 066f7e07d4f722573c6dbe7f64b0765504595644 Mon Sep 17 00:00:00 2001 From: Julien Martin Date: Tue, 2 Oct 2018 03:14:28 +0200 Subject: [PATCH] Update: camelcase rule ignoreList added (#10783) * New: camelcase rule now accept ignore list * Docs: Documentation updated for camelcase rule ignore list --- docs/rules/camelcase.md | 25 ++++++++++++++++++++ lib/rules/camelcase.js | 44 +++++++++++++++++++++++++++++------- tests/lib/rules/camelcase.js | 32 ++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 8 deletions(-) diff --git a/docs/rules/camelcase.md b/docs/rules/camelcase.md index cce3fd92470..1765f1852c4 100644 --- a/docs/rules/camelcase.md +++ b/docs/rules/camelcase.md @@ -14,6 +14,7 @@ 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 +* `allow` (`string[]`) list of properties to accept. Accept regex. ### properties: "always" @@ -151,6 +152,30 @@ var { category_id = 1 } = query; var { category_id: category_id } = query; ``` +## allow + +Examples of **correct** code for this rule with the `allow` option: + +```js +/*eslint camelcase: ["error", {allow: ["UNSAFE_componentWillMount"]}]*/ + +function UNSAFE_componentWillMount() { + // ... +} +``` + +```js +/*eslint camelcase: ["error", {allow: ["^UNSAFE_"]}]*/ + +function UNSAFE_componentWillMount() { + // ... +} + +function UNSAFE_componentWillMount() { + // ... +} +``` + ## When Not To Use It If you have established coding standards using a different naming convention (separating words with underscores), turn this rule off. diff --git a/lib/rules/camelcase.js b/lib/rules/camelcase.js index 3005963ab04..41040450f94 100644 --- a/lib/rules/camelcase.js +++ b/lib/rules/camelcase.js @@ -27,6 +27,16 @@ module.exports = { }, properties: { enum: ["always", "never"] + }, + allow: { + type: "array", + items: [ + { + type: "string" + } + ], + minItems: 0, + uniqueItems: true } }, additionalProperties: false @@ -40,6 +50,15 @@ module.exports = { create(context) { + const options = context.options[0] || {}; + let properties = options.properties || ""; + const ignoreDestructuring = options.ignoreDestructuring || false; + const allow = options.allow || []; + + if (properties !== "always" && properties !== "never") { + properties = "always"; + } + //-------------------------------------------------------------------------- // Helpers //-------------------------------------------------------------------------- @@ -60,6 +79,18 @@ module.exports = { return name.indexOf("_") > -1 && name !== name.toUpperCase(); } + /** + * Checks if a string match the ignore list + * @param {string} name The string to check. + * @returns {boolean} if the string is ignored + * @private + */ + function isAllowed(name) { + return allow.findIndex( + entry => name === entry || name.match(new RegExp(entry)) + ) !== -1; + } + /** * Checks if a parent of a node is an ObjectPattern. * @param {ASTNode} node The node to check. @@ -93,14 +124,6 @@ module.exports = { } } - const options = context.options[0] || {}; - let properties = options.properties || ""; - const ignoreDestructuring = options.ignoreDestructuring || false; - - if (properties !== "always" && properties !== "never") { - properties = "always"; - } - return { Identifier(node) { @@ -112,6 +135,11 @@ module.exports = { const name = node.name.replace(/^_+|_+$/g, ""), effectiveParent = (node.parent.type === "MemberExpression") ? node.parent.parent : node.parent; + // First, we ignore the node if it match the ignore list + if (isAllowed(name)) { + return; + } + // MemberExpressions get special rules if (node.parent.type === "MemberExpression") { diff --git a/tests/lib/rules/camelcase.js b/tests/lib/rules/camelcase.js index 481842f9739..3d2b7516c39 100644 --- a/tests/lib/rules/camelcase.js +++ b/tests/lib/rules/camelcase.js @@ -181,6 +181,18 @@ ruleTester.run("camelcase", rule, { { code: "function foo({ trailing_ }) {}", parserOptions: { ecmaVersion: 6 } + }, + { + code: "ignored_foo = 0;", + options: [{ allow: ["ignored_foo"] }] + }, + { + code: "ignored_foo = 0; ignored_bar = 1;", + options: [{ allow: ["ignored_foo", "ignored_bar"] }] + }, + { + code: "user_id = 0;", + options: [{ allow: ["_id$"] }] } ], invalid: [ @@ -555,6 +567,26 @@ ruleTester.run("camelcase", rule, { type: "Identifier" } ] + }, + { + code: "not_ignored_foo = 0;", + options: [{ allow: ["ignored_bar"] }], + errors: [ + { + message: "Identifier 'not_ignored_foo' is not in camel case.", + type: "Identifier" + } + ] + }, + { + code: "not_ignored_foo = 0;", + options: [{ allow: ["_id$"] }], + errors: [ + { + message: "Identifier 'not_ignored_foo' is not in camel case.", + type: "Identifier" + } + ] } ] });