From 0c20bc068e608869981a10711bba88ffde1539d8 Mon Sep 17 00:00:00 2001 From: YeonJuan Date: Fri, 27 Mar 2020 04:51:25 +0900 Subject: [PATCH] Fix: check assignment property target in camelcase (fixes #13025) (#13027) * Fix: check assignment property target in camelcase (fixes #13025) * check camelcase * remove useless check * fix is isAssignmentTargetPropertyInDestructuring --- lib/rules/camelcase.js | 37 ++++++ tests/lib/rules/camelcase.js | 210 +++++++++++++++++++++++++++++++++++ 2 files changed, 247 insertions(+) diff --git a/lib/rules/camelcase.js b/lib/rules/camelcase.js index cd607114e60..04360837294 100644 --- a/lib/rules/camelcase.js +++ b/lib/rules/camelcase.js @@ -125,6 +125,40 @@ module.exports = { return false; } + /** + * Checks whether the given node represents assignment target property in destructuring. + * + * For examples: + * ({a: b.foo} = c); // => true for `foo` + * ([a.foo] = b); // => true for `foo` + * ([a.foo = 1] = b); // => true for `foo` + * ({...a.foo} = b); // => true for `foo` + * @param {ASTNode} node An Identifier node to check + * @returns {boolean} True if the node is an assignment target property in destructuring. + */ + function isAssignmentTargetPropertyInDestructuring(node) { + if ( + node.parent.type === "MemberExpression" && + node.parent.property === node && + !node.parent.computed + ) { + const effectiveParent = node.parent.parent; + + return ( + effectiveParent.type === "Property" && + effectiveParent.value === node.parent && + effectiveParent.parent.type === "ObjectPattern" || + effectiveParent.type === "ArrayPattern" || + effectiveParent.type === "RestElement" || + ( + effectiveParent.type === "AssignmentPattern" && + effectiveParent.left === node.parent + ) + ); + } + return false; + } + /** * Reports an AST node as a rule violation. * @param {ASTNode} node The node to report. @@ -170,6 +204,9 @@ module.exports = { // Report AssignmentExpressions only if they are the left side of the assignment } else if (effectiveParent.type === "AssignmentExpression" && nameIsUnderscored && (effectiveParent.right.type !== "MemberExpression" || effectiveParent.left.type === "MemberExpression" && effectiveParent.left.property.name === node.name)) { report(node); + + } else if (isAssignmentTargetPropertyInDestructuring(node) && nameIsUnderscored) { + report(node); } /* diff --git a/tests/lib/rules/camelcase.js b/tests/lib/rules/camelcase.js index 21f280adb35..1e3eecc2110 100644 --- a/tests/lib/rules/camelcase.js +++ b/tests/lib/rules/camelcase.js @@ -225,6 +225,59 @@ ruleTester.run("camelcase", rule, { code: "foo = { [computedBar]: 0 };", options: [{ ignoreDestructuring: true }], parserOptions: { ecmaVersion: 6 } + }, + { + code: "({ a: obj.fo_o } = bar);", + options: [{ allow: ["fo_o"] }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "({ a: obj.foo } = bar);", + options: [{ allow: ["fo_o"] }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "({ a: obj.fo_o } = bar);", + options: [{ properties: "never" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "({ a: obj.fo_o.b_ar } = bar);", + options: [{ properties: "never" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "({ a: { b: obj.fo_o } } = bar);", + options: [{ properties: "never" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "([obj.fo_o] = bar);", + options: [{ properties: "never" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "({ c: [ob.fo_o]} = bar);", + options: [{ properties: "never" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "([obj.fo_o.b_ar] = bar);", + options: [{ properties: "never" }], + parserOptions: { ecmaVersion: 6 } + }, + { + code: "({obj} = baz.fo_o);", + parserOptions: { ecmaVersion: 6 } + }, + { + code: "([obj] = baz.fo_o);", + parserOptions: { ecmaVersion: 6 } + }, + { + code: "([obj.foo = obj.fo_o] = bar);", + options: [{ properties: "always" }], + parserOptions: { ecmaVersion: 6 } } ], invalid: [ @@ -736,6 +789,163 @@ ruleTester.run("camelcase", rule, { type: "Identifier" } ] + }, + { + code: "({ a: obj.fo_o } = bar);", + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: "notCamelCase", + data: { name: "fo_o" }, + type: "Identifier" + } + ] + }, + { + code: "({ a: obj.fo_o } = bar);", + options: [{ ignoreDestructuring: true }], + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: "notCamelCase", + data: { name: "fo_o" }, + type: "Identifier" + } + ] + }, + { + code: "({ a: obj.fo_o.b_ar } = baz);", + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: "notCamelCase", + data: { name: "b_ar" }, + type: "Identifier" + } + ] + }, + { + code: "({ a: { b: { c: obj.fo_o } } } = bar);", + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: "notCamelCase", + data: { name: "fo_o" }, + type: "Identifier" + } + ] + }, + { + code: "({ a: { b: { c: obj.fo_o.b_ar } } } = baz);", + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: "notCamelCase", + data: { name: "b_ar" }, + type: "Identifier" + } + ] + }, + { + code: "([obj.fo_o] = bar);", + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: "notCamelCase", + data: { name: "fo_o" }, + type: "Identifier" + } + ] + }, + { + code: "([obj.fo_o] = bar);", + options: [{ ignoreDestructuring: true }], + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: "notCamelCase", + data: { name: "fo_o" }, + type: "Identifier" + } + ] + }, + { + code: "([obj.fo_o = 1] = bar);", + options: [{ properties: "always" }], + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: "notCamelCase", + data: { name: "fo_o" }, + type: "Identifier" + } + ] + }, + { + code: "({ a: [obj.fo_o] } = bar);", + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: "notCamelCase", + data: { name: "fo_o" }, + type: "Identifier" + } + ] + }, + { + code: "({ a: { b: [obj.fo_o] } } = bar);", + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: "notCamelCase", + data: { name: "fo_o" }, + type: "Identifier" + } + ] + }, + { + code: "([obj.fo_o.ba_r] = baz);", + parserOptions: { ecmaVersion: 6 }, + errors: [ + { + messageId: "notCamelCase", + data: { name: "ba_r" }, + type: "Identifier" + } + ] + }, + { + code: "({...obj.fo_o} = baz);", + parserOptions: { ecmaVersion: 9 }, + errors: [ + { + messageId: "notCamelCase", + data: { name: "fo_o" }, + type: "Identifier" + } + ] + }, + { + code: "({...obj.fo_o.ba_r} = baz);", + parserOptions: { ecmaVersion: 9 }, + errors: [ + { + messageId: "notCamelCase", + data: { name: "ba_r" }, + type: "Identifier" + } + ] + }, + { + code: "({c: {...obj.fo_o }} = baz);", + parserOptions: { ecmaVersion: 9 }, + errors: [ + { + messageId: "notCamelCase", + data: { name: "fo_o" }, + type: "Identifier" + } + ] } ] });