Repository: eslint/eslint
Pull request #10748 (2018-08-09 00:29:24)

Update: Improve no-extra-parens error message
When I encountered this error, it was not unclear to me what the
problem was or what alternative would be preferred.

The input was:

```js
return ( { foo: 1, bar: 2 }[ key ] || 0 );
```

Receiving the following in Atom's footer:

```
eslint (0|4), Gratuitous parentheses around expression., Line 165, Column 17
```

**What is the purpose of this pull request? (put an "X" next to item)**

[x] Changes an existing rule ([template](https://raw.githubusercontent.com/eslint/eslint/master/templates/rule-change-proposal.md))


jsf-clabot: [![CLA assistant check](https://cla.js.foundation/pull/badge/not_signed)](https://cla.js.foundation/eslint/eslint?pullRequest=10748) <br/>Thank you for your submission, we really appreciate it. Like many open source projects, we ask that you sign our [Contributor License Agreement](https://cla.js.foundation/eslint/eslint?pullRequest=10748) before we can accept your contribution.<br/>
platinumazure: :+1: for plain English, thanks for contributing!

We do need a CLA signature before we can merge. Let us know if you need help with that. Thanks!
not-an-aardvark: I don't feel strongly about it, but how about the word "Unnecessary" instead of "Unexpected"? "Unexpected" sort of makes it sound like the rule is broken and isn't able to handle code with parentheses, when in fact it's working as expected by reporting the parentheses.

Patch:
diff --git a/Makefile.js b/Makefile.js
index 902ee5857..3c514af09 100644
--- a/Makefile.js
+++ b/Makefile.js
@@ -871,7 +871,7 @@ target.checkRuleFiles = function() {
          * @private
          */
         function isInConfig() {
-            return eslintRecommended.hasOwnProperty(basename);
+            return Object.prototype.hasOwnProperty.call(eslintRecommended, basename);
         }
 
         /**
diff --git a/lib/cli-engine.js b/lib/cli-engine.js
index 9d7246d1e..5b52459ac 100644
--- a/lib/cli-engine.js
+++ b/lib/cli-engine.js
@@ -30,7 +30,6 @@ const fs = require("fs"),
     pkg = require("../package.json");
 
 const debug = require("debug")("eslint:cli-engine");
-
 const resolver = new ModuleResolver();
 
 //------------------------------------------------------------------------------
@@ -469,7 +468,7 @@ class CLIEngine {
      * @returns {void}
      */
     static outputFixes(report) {
-        report.results.filter(result => result.hasOwnProperty("output")).forEach(result => {
+        report.results.filter(result => Object.prototype.hasOwnProperty.call(result, "output")).forEach(result => {
             fs.writeFileSync(result.filePath, result.output);
         });
     }
diff --git a/lib/rules/comma-style.js b/lib/rules/comma-style.js
index bd98d7acc..7f996b344 100644
--- a/lib/rules/comma-style.js
+++ b/lib/rules/comma-style.js
@@ -58,7 +58,7 @@ module.exports = {
             NewExpression: true
         };
 
-        if (context.options.length === 2 && context.options[1].hasOwnProperty("exceptions")) {
+        if (context.options.length === 2 && Object.prototype.hasOwnProperty.call(context.options[1], "exceptions")) {
             const keys = Object.keys(context.options[1].exceptions);
 
             for (let i = 0; i < keys.length; i++) {
diff --git a/lib/rules/complexity.js b/lib/rules/complexity.js
index f25194595..bc66d303b 100644
--- a/lib/rules/complexity.js
+++ b/lib/rules/complexity.js
@@ -61,10 +61,10 @@ module.exports = {
         const option = context.options[0];
         let THRESHOLD = 20;
 
-        if (typeof option === "object" && option.hasOwnProperty("maximum") && typeof option.maximum === "number") {
+        if (typeof option === "object" && Object.prototype.hasOwnProperty.call(option, "maximum") && typeof option.maximum === "number") {
             THRESHOLD = option.maximum;
         }
-        if (typeof option === "object" && option.hasOwnProperty("max") && typeof option.max === "number") {
+        if (typeof option === "object" && Object.prototype.hasOwnProperty.call(option, "max") && typeof option.max === "number") {
             THRESHOLD = option.max;
         }
         if (typeof option === "number") {
diff --git a/lib/rules/indent.js b/lib/rules/indent.js
index 716167d2c..940c080a0 100644
--- a/lib/rules/indent.js
+++ b/lib/rules/indent.js
@@ -1333,7 +1333,9 @@ module.exports = {
                 node.expressions.forEach((expression, index) => {
                     const previousQuasi = node.quasis[index];
                     const nextQuasi = node.quasis[index + 1];
-                    const tokenToAlignFrom = previousQuasi.loc.start.line === previousQuasi.loc.end.line ? sourceCode.getFirstToken(previousQuasi) : null;
+                    const tokenToAlignFrom = previousQuasi.loc.start.line === previousQuasi.loc.end.line
+                        ? sourceCode.getFirstToken(previousQuasi)
+                        : null;
 
                     offsets.setDesiredOffsets([previousQuasi.range[1], nextQuasi.range[0]], tokenToAlignFrom, 1);
                     offsets.setDesiredOffset(sourceCode.getFirstToken(nextQuasi), tokenToAlignFrom, 0);
@@ -1341,7 +1343,9 @@ module.exports = {
             },
 
             VariableDeclaration(node) {
-                const variableIndent = options.VariableDeclarator.hasOwnProperty(node.kind) ? options.VariableDeclarator[node.kind] : DEFAULT_VARIABLE_INDENT;
+                const variableIndent = Object.prototype.hasOwnProperty.call(options.VariableDeclarator, node.kind)
+                    ? options.VariableDeclarator[node.kind]
+                    : DEFAULT_VARIABLE_INDENT;
 
                 if (node.declarations[node.declarations.length - 1].loc.start.line > node.loc.start.line) {
 
diff --git a/lib/rules/line-comment-position.js b/lib/rules/line-comment-position.js
index 4327e70e1..7f45a94b6 100644
--- a/lib/rules/line-comment-position.js
+++ b/lib/rules/line-comment-position.js
@@ -62,7 +62,7 @@ module.exports = {
             above = !options.position || options.position === "above";
             ignorePattern = options.ignorePattern;
 
-            if (options.hasOwnProperty("applyDefaultIgnorePatterns")) {
+            if (Object.prototype.hasOwnProperty.call(options, "applyDefaultIgnorePatterns")) {
                 applyDefaultIgnorePatterns = options.applyDefaultIgnorePatterns !== false;
             } else {
                 applyDefaultIgnorePatterns = options.applyDefaultPatterns !== false;
diff --git a/lib/rules/max-depth.js b/lib/rules/max-depth.js
index ead44b90c..368dcfa66 100644
--- a/lib/rules/max-depth.js
+++ b/lib/rules/max-depth.js
@@ -54,10 +54,10 @@ module.exports = {
             option = context.options[0];
         let maxDepth = 4;
 
-        if (typeof option === "object" && option.hasOwnProperty("maximum") && typeof option.maximum === "number") {
+        if (typeof option === "object" && Object.prototype.hasOwnProperty.call(option, "maximum") && typeof option.maximum === "number") {
             maxDepth = option.maximum;
         }
-        if (typeof option === "object" && option.hasOwnProperty("max") && typeof option.max === "number") {
+        if (typeof option === "object" && Object.prototype.hasOwnProperty.call(option, "max") && typeof option.max === "number") {
             maxDepth = option.max;
         }
         if (typeof option === "number") {
diff --git a/lib/rules/max-lines.js b/lib/rules/max-lines.js
index e3fccb314..7eb959795 100644
--- a/lib/rules/max-lines.js
+++ b/lib/rules/max-lines.js
@@ -56,7 +56,7 @@ module.exports = {
         const option = context.options[0];
         let max = 300;
 
-        if (typeof option === "object" && option.hasOwnProperty("max") && typeof option.max === "number") {
+        if (typeof option === "object" && Object.prototype.hasOwnProperty.call(option, "max") && typeof option.max === "number") {
             max = option.max;
         }
 
diff --git a/lib/rules/max-nested-callbacks.js b/lib/rules/max-nested-callbacks.js
index 7d7386ec1..8cc80ae7a 100644
--- a/lib/rules/max-nested-callbacks.js
+++ b/lib/rules/max-nested-callbacks.js
@@ -52,10 +52,10 @@ module.exports = {
         const option = context.options[0];
         let THRESHOLD = 10;
 
-        if (typeof option === "object" && option.hasOwnProperty("maximum") && typeof option.maximum === "number") {
+        if (typeof option === "object" && Object.prototype.hasOwnProperty.call(option, "maximum") && typeof option.maximum === "number") {
             THRESHOLD = option.maximum;
         }
-        if (typeof option === "object" && option.hasOwnProperty("max") && typeof option.max === "number") {
+        if (typeof option === "object" && Object.prototype.hasOwnProperty.call(option, "max") && typeof option.max === "number") {
             THRESHOLD = option.max;
         }
         if (typeof option === "number") {
diff --git a/lib/rules/max-params.js b/lib/rules/max-params.js
index 43c649ee8..902391b74 100644
--- a/lib/rules/max-params.js
+++ b/lib/rules/max-params.js
@@ -57,10 +57,10 @@ module.exports = {
         const option = context.options[0];
         let numParams = 3;
 
-        if (typeof option === "object" && option.hasOwnProperty("maximum") && typeof option.maximum === "number") {
+        if (typeof option === "object" && Object.prototype.hasOwnProperty.call(option, "maximum") && typeof option.maximum === "number") {
             numParams = option.maximum;
         }
-        if (typeof option === "object" && option.hasOwnProperty("max") && typeof option.max === "number") {
+        if (typeof option === "object" && Object.prototype.hasOwnProperty.call(option, "max") && typeof option.max === "number") {
             numParams = option.max;
         }
         if (typeof option === "number") {
diff --git a/lib/rules/max-statements.js b/lib/rules/max-statements.js
index 8501fd688..525790df8 100644
--- a/lib/rules/max-statements.js
+++ b/lib/rules/max-statements.js
@@ -73,10 +73,10 @@ module.exports = {
             topLevelFunctions = [];
         let maxStatements = 10;
 
-        if (typeof option === "object" && option.hasOwnProperty("maximum") && typeof option.maximum === "number") {
+        if (typeof option === "object" && Object.prototype.hasOwnProperty.call(option, "maximum") && typeof option.maximum === "number") {
             maxStatements = option.maximum;
         }
-        if (typeof option === "object" && option.hasOwnProperty("max") && typeof option.max === "number") {
+        if (typeof option === "object" && Object.prototype.hasOwnProperty.call(option, "max") && typeof option.max === "number") {
             maxStatements = option.max;
         }
         if (typeof option === "number") {
diff --git a/lib/rules/no-extra-parens.js b/lib/rules/no-extra-parens.js
index 814cf0faf..47c58946c 100644
--- a/lib/rules/no-extra-parens.js
+++ b/lib/rules/no-extra-parens.js
@@ -58,7 +58,7 @@ module.exports = {
         },
 
         messages: {
-            unexpected: "Gratuitous parentheses around expression."
+            unexpected: "Unnecessary parentheses around expression."
         }
     },
 
diff --git a/lib/rules/no-restricted-globals.js b/lib/rules/no-restricted-globals.js
index 691e55d19..72b02c032 100644
--- a/lib/rules/no-restricted-globals.js
+++ b/lib/rules/no-restricted-globals.js
@@ -94,7 +94,7 @@ module.exports = {
          * @private
          */
         function isRestricted(name) {
-            return restrictedGlobalMessages.hasOwnProperty(name);
+            return Object.prototype.hasOwnProperty.call(restrictedGlobalMessages, name);
         }
 
         return {
diff --git a/lib/rules/no-restricted-imports.js b/lib/rules/no-restricted-imports.js
index 11d09d6d2..fdebb8ca3 100644
--- a/lib/rules/no-restricted-imports.js
+++ b/lib/rules/no-restricted-imports.js
@@ -83,7 +83,7 @@ module.exports = {
         const options = Array.isArray(context.options) ? context.options : [];
         const isPathAndPatternsObject =
             typeof options[0] === "object" &&
-            (options[0].hasOwnProperty("paths") || options[0].hasOwnProperty("patterns"));
+            (Object.prototype.hasOwnProperty.call(options[0], "paths") || Object.prototype.hasOwnProperty.call(options[0], "patterns"));
 
         const restrictedPaths = (isPathAndPatternsObject ? options[0].paths : context.options) || [];
         const restrictedPatterns = (isPathAndPatternsObject ? options[0].patterns : []) || [];
diff --git a/lib/rules/no-restricted-modules.js b/lib/rules/no-restricted-modules.js
index 54271094f..d63d2ce4f 100644
--- a/lib/rules/no-restricted-modules.js
+++ b/lib/rules/no-restricted-modules.js
@@ -77,7 +77,7 @@ module.exports = {
         const options = Array.isArray(context.options) ? context.options : [];
         const isPathAndPatternsObject =
             typeof options[0] === "object" &&
-            (options[0].hasOwnProperty("paths") || options[0].hasOwnProperty("patterns"));
+            (Object.prototype.hasOwnProperty.call(options[0], "paths") || Object.prototype.hasOwnProperty.call(options[0], "patterns"));
 
         const restrictedPaths = (isPathAndPatternsObject ? options[0].paths : context.options) || [];
         const restrictedPatterns = (isPathAndPatternsObject ? options[0].patterns : []) || [];
diff --git a/lib/rules/one-var.js b/lib/rules/one-var.js
index 412fe615d..13ab72b04 100644
--- a/lib/rules/one-var.js
+++ b/lib/rules/one-var.js
@@ -74,19 +74,19 @@ module.exports = {
             options.let = { uninitialized: mode, initialized: mode };
             options.const = { uninitialized: mode, initialized: mode };
         } else if (typeof mode === "object") { // options configuration is an object
-            if (mode.hasOwnProperty("separateRequires")) {
+            if (Object.prototype.hasOwnProperty.call(mode, "separateRequires")) {
                 options.separateRequires = !!mode.separateRequires;
             }
-            if (mode.hasOwnProperty("var")) {
+            if (Object.prototype.hasOwnProperty.call(mode, "var")) {
                 options.var = { uninitialized: mode.var, initialized: mode.var };
             }
-            if (mode.hasOwnProperty("let")) {
+            if (Object.prototype.hasOwnProperty.call(mode, "let")) {
                 options.let = { uninitialized: mode.let, initialized: mode.let };
             }
-            if (mode.hasOwnProperty("const")) {
+            if (Object.prototype.hasOwnProperty.call(mode, "const")) {
                 options.const = { uninitialized: mode.const, initialized: mode.const };
             }
-            if (mode.hasOwnProperty("uninitialized")) {
+            if (Object.prototype.hasOwnProperty.call(mode, "uninitialized")) {
                 if (!options.var) {
                     options.var = {};
                 }
@@ -100,7 +100,7 @@ module.exports = {
                 options.let.uninitialized = mode.uninitialized;
                 options.const.uninitialized = mode.uninitialized;
             }
-            if (mode.hasOwnProperty("initialized")) {
+            if (Object.prototype.hasOwnProperty.call(mode, "initialized")) {
                 if (!options.var) {
                     options.var = {};
                 }
diff --git a/lib/rules/padded-blocks.js b/lib/rules/padded-blocks.js
index 2fbb26712..370d47bcc 100644
--- a/lib/rules/padded-blocks.js
+++ b/lib/rules/padded-blocks.js
@@ -58,13 +58,13 @@ module.exports = {
             options.switches = shouldHavePadding;
             options.classes = shouldHavePadding;
         } else {
-            if (config.hasOwnProperty("blocks")) {
+            if (Object.prototype.hasOwnProperty.call(config, "blocks")) {
                 options.blocks = config.blocks === "always";
             }
-            if (config.hasOwnProperty("switches")) {
+            if (Object.prototype.hasOwnProperty.call(config, "switches")) {
                 options.switches = config.switches === "always";
             }
-            if (config.hasOwnProperty("classes")) {
+            if (Object.prototype.hasOwnProperty.call(config, "classes")) {
                 options.classes = config.classes === "always";
             }
         }
@@ -225,7 +225,7 @@ module.exports = {
 
         const rule = {};
 
-        if (options.hasOwnProperty("switches")) {
+        if (Object.prototype.hasOwnProperty.call(options, "switches")) {
             rule.SwitchStatement = function(node) {
                 if (node.cases.length === 0) {
                     return;
@@ -234,7 +234,7 @@ module.exports = {
             };
         }
 
-        if (options.hasOwnProperty("blocks")) {
+        if (Object.prototype.hasOwnProperty.call(options, "blocks")) {
             rule.BlockStatement = function(node) {
                 if (node.body.length === 0) {
                     return;
@@ -243,7 +243,7 @@ module.exports = {
             };
         }
 
-        if (options.hasOwnProperty("classes")) {
+        if (Object.prototype.hasOwnProperty.call(options, "classes")) {
             rule.ClassBody = function(node) {
                 if (node.body.length === 0) {
                     return;
diff --git a/lib/rules/prefer-reflect.js b/lib/rules/prefer-reflect.js
index 56e841ff1..765163e0e 100644
--- a/lib/rules/prefer-reflect.js
+++ b/lib/rules/prefer-reflect.js
@@ -98,7 +98,7 @@ module.exports = {
             CallExpression(node) {
                 const methodName = (node.callee.property || {}).name;
                 const isReflectCall = (node.callee.object || {}).name === "Reflect";
-                const hasReflectSubsitute = reflectSubsitutes.hasOwnProperty(methodName);
+                const hasReflectSubsitute = Object.prototype.hasOwnProperty.call(reflectSubsitutes, methodName);
                 const userConfiguredException = exceptions.indexOf(methodName) !== -1;
 
                 if (hasReflectSubsitute && !isReflectCall && !userConfiguredException) {
diff --git a/lib/rules/semi-spacing.js b/lib/rules/semi-spacing.js
index cde93abf3..75b53055a 100644
--- a/lib/rules/semi-spacing.js
+++ b/lib/rules/semi-spacing.js
@@ -46,10 +46,10 @@ module.exports = {
             requireSpaceAfter = true;
 
         if (typeof config === "object") {
-            if (config.hasOwnProperty("before")) {
+            if (Object.prototype.hasOwnProperty.call(config, "before")) {
                 requireSpaceBefore = config.before;
             }
-            if (config.hasOwnProperty("after")) {
+            if (Object.prototype.hasOwnProperty.call(config, "after")) {
                 requireSpaceAfter = config.after;
             }
         }
diff --git a/lib/rules/space-unary-ops.js b/lib/rules/space-unary-ops.js
index 6fe25443c..5032b46c3 100644
--- a/lib/rules/space-unary-ops.js
+++ b/lib/rules/space-unary-ops.js
@@ -72,7 +72,7 @@ module.exports = {
          * @returns {boolean} Whether or not an override has been provided for the operator
          */
         function overrideExistsForOperator(operator) {
-            return options.overrides && options.overrides.hasOwnProperty(operator);
+            return options.overrides && Object.prototype.hasOwnProperty.call(options.overrides, operator);
         }
 
         /**
diff --git a/lib/rules/valid-jsdoc.js b/lib/rules/valid-jsdoc.js
index 44c0f9999..42d66a8a7 100644
--- a/lib/rules/valid-jsdoc.js
+++ b/lib/rules/valid-jsdoc.js
@@ -322,7 +322,7 @@ module.exports = {
                     }
 
                     // check tag preferences
-                    if (prefer.hasOwnProperty(tag.title) && tag.title !== prefer[tag.title]) {
+                    if (Object.prototype.hasOwnProperty.call(prefer, tag.title) && tag.title !== prefer[tag.title]) {
                         const entireTagRange = getAbsoluteRange(jsdocNode, tag);
 
                         context.report({
diff --git a/lib/util/file-finder.js b/lib/util/file-finder.js
index 5d4b48a62..e273e4d46 100644
--- a/lib/util/file-finder.js
+++ b/lib/util/file-finder.js
@@ -89,7 +89,7 @@ class FileFinder {
             ? path.resolve(this.cwd, relativeDirectory)
             : this.cwd;
 
-        if (cache.hasOwnProperty(initialDirectory)) {
+        if (Object.prototype.hasOwnProperty.call(cache, initialDirectory)) {
             yield* cache[initialDirectory];
             return; // to avoid doing the normal loop afterwards
         }
@@ -130,7 +130,7 @@ class FileFinder {
                 return;
             }
 
-        } while (!cache.hasOwnProperty(directory));
+        } while (!Object.prototype.hasOwnProperty.call(cache, directory));
 
         // Add what has been cached previously to the cache of each directory searched.
         for (let i = 0; i < searched; i++) {
diff --git a/lib/util/lint-result-cache.js b/lib/util/lint-result-cache.js
index 29b432bd5..f1e5aabfe 100644
--- a/lib/util/lint-result-cache.js
+++ b/lib/util/lint-result-cache.js
@@ -109,7 +109,7 @@ class LintResultCache {
      * @returns {void}
      */
     setCachedLintResults(filePath, result) {
-        if (result && result.hasOwnProperty("output")) {
+        if (result && Object.prototype.hasOwnProperty.call(result, "output")) {
             return;
         }
 
@@ -125,7 +125,7 @@ class LintResultCache {
              * In `getCachedLintResults`, if source is explicitly null, we will
              * read the file from the filesystem to set the value again.
              */
-            if (resultToSerialize.hasOwnProperty("source")) {
+            if (Object.prototype.hasOwnProperty.call(resultToSerialize, "source")) {
                 resultToSerialize.source = null;
             }
 
diff --git a/lib/util/source-code-fixer.js b/lib/util/source-code-fixer.js
index b5bfc7457..b3354d4d7 100644
--- a/lib/util/source-code-fixer.js
+++ b/lib/util/source-code-fixer.js
@@ -107,7 +107,7 @@ SourceCodeFixer.applyFixes = function(sourceText, messages, shouldFix) {
     }
 
     messages.forEach(problem => {
-        if (problem.hasOwnProperty("fix")) {
+        if (Object.prototype.hasOwnProperty.call(problem, "fix")) {
             fixes.push(problem);
         } else {
             remainingMessages.push(problem);
diff --git a/packages/eslint-config-eslint/default.yml b/packages/eslint-config-eslint/default.yml
index 127e7d7d7..73c244bf3 100644
--- a/packages/eslint-config-eslint/default.yml
+++ b/packages/eslint-config-eslint/default.yml
@@ -88,6 +88,7 @@ rules:
     no-path-concat: "error"
     no-process-exit: "error"
     no-proto: "error"
+    no-prototype-builtins: "error"
     no-redeclare: "error"
     no-restricted-properties: [
         "error",
diff --git a/tools/internal-rules/consistent-docs-url.js b/tools/internal-rules/consistent-docs-url.js
index ae7fe67d3..0082ecf76 100644
--- a/tools/internal-rules/consistent-docs-url.js
+++ b/tools/internal-rules/consistent-docs-url.js
@@ -48,6 +48,14 @@ function checkMetaDocsUrl(context, exportsNode) {
     const metaDocs = metaProperty && getPropertyFromObject("docs", metaProperty.value);
     const metaDocsUrl = metaDocs && getPropertyFromObject("url", metaDocs.value);
 
+    if (!metaDocs) {
+        context.report({
+            node: metaProperty,
+            message: "Rule is missing a meta.docs property"
+        });
+        return;
+    }
+
     if (!metaDocsUrl) {
         context.report({
             node: metaDocs,


Test patch:
diff --git a/lib/testers/rule-tester.js b/lib/testers/rule-tester.js
index d7e4c2bfa..9fbca945b 100644
--- a/lib/testers/rule-tester.js
+++ b/lib/testers/rule-tester.js
@@ -533,19 +533,19 @@ class RuleTester {
                             assert.strictEqual(message.nodeType, error.type, `Error type should be ${error.type}, found ${message.nodeType}`);
                         }
 
-                        if (error.hasOwnProperty("line")) {
+                        if (Object.prototype.hasOwnProperty.call(error, "line")) {
                             assert.strictEqual(message.line, error.line, `Error line should be ${error.line}`);
                         }
 
-                        if (error.hasOwnProperty("column")) {
+                        if (Object.prototype.hasOwnProperty.call(error, "column")) {
                             assert.strictEqual(message.column, error.column, `Error column should be ${error.column}`);
                         }
 
-                        if (error.hasOwnProperty("endLine")) {
+                        if (Object.prototype.hasOwnProperty.call(error, "endLine")) {
                             assert.strictEqual(message.endLine, error.endLine, `Error endLine should be ${error.endLine}`);
                         }
 
-                        if (error.hasOwnProperty("endColumn")) {
+                        if (Object.prototype.hasOwnProperty.call(error, "endColumn")) {
                             assert.strictEqual(message.endColumn, error.endColumn, `Error endColumn should be ${error.endColumn}`);
                         }
                     } else {
@@ -556,7 +556,7 @@ class RuleTester {
                 }
             }
 
-            if (item.hasOwnProperty("output")) {
+            if (Object.prototype.hasOwnProperty.call(item, "output")) {
                 if (item.output === null) {
                     assert.strictEqual(
                         messages.filter(message => message.fix).length,
diff --git a/tests/bench/large.js b/tests/bench/large.js
index eb823a10e..24ba7271c 100644
--- a/tests/bench/large.js
+++ b/tests/bench/large.js
@@ -50435,7 +50435,7 @@ assert.ifError = function(err) { if (err) {throw err;}};
 var objectKeys = Object.keys || function (obj) {
   var keys = [];
   for (var key in obj) {
-    if (hasOwn.call(obj, key)) keys.push(key);
+    if (Object.prototype.hasOwnProperty.call(obj, key)) keys.push(key);
   }
   return keys;
 };
diff --git a/tests/bench/medium.js b/tests/bench/medium.js
index 26806b877..3edf835fd 100644
--- a/tests/bench/medium.js
+++ b/tests/bench/medium.js
@@ -285,7 +285,7 @@ jQuery.extend({
 		// https://bugzilla.mozilla.org/show_bug.cgi?id=814622
 		try {
 			if ( obj.constructor &&
-					!hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
+					!Object.prototype.hasOwnProperty.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
 				return false;
 			}
 		} catch ( e ) {
@@ -1412,7 +1412,7 @@ Sizzle.attr = function( elem, name ) {
 
 	var fn = Expr.attrHandle[ name.toLowerCase() ],
 		// Don't get fooled by Object.prototype properties (jQuery #13807)
-		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
+		val = fn && Object.prototype.hasOwnProperty.call( Expr.attrHandle, name.toLowerCase() ) ?
 			fn( elem, name, !documentIsHTML ) :
 			undefined;
 
@@ -4201,8 +4201,8 @@ jQuery.event = {
 
 		var i, cur, tmp, bubbleType, ontype, handle, special,
 			eventPath = [ elem || document ],
-			type = hasOwn.call( event, "type" ) ? event.type : event,
-			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
+			type = Object.prototype.hasOwnProperty.call( event, "type" ) ? event.type : event,
+			namespaces = Object.prototype.hasOwnProperty.call( event, "namespace" ) ? event.namespace.split(".") : [];
 
 		cur = tmp = elem = elem || document;
 
diff --git a/tests/lib/config.js b/tests/lib/config.js
index acf68e258..ba107e45c 100644
--- a/tests/lib/config.js
+++ b/tests/lib/config.js
@@ -1367,7 +1367,7 @@ describe("Config", () => {
             function onWarning(w) { // eslint-disable-line require-jsdoc
 
                 // Node.js 6.x does not have 'w.code' property.
-                if (!w.hasOwnProperty("code") || typeof w.code === "string" && w.code.startsWith("ESLINT_")) {
+                if (!Object.prototype.hasOwnProperty.call(w, "code") || typeof w.code === "string" && w.code.startsWith("ESLINT_")) {
                     warning = w;
                 }
             }
diff --git a/tests/lib/config/config-file.js b/tests/lib/config/config-file.js
index 4b74d0475..21fd94583 100644
--- a/tests/lib/config/config-file.js
+++ b/tests/lib/config/config-file.js
@@ -119,7 +119,7 @@ function createStubModuleResolver(mapping) {
      */
     return class StubModuleResolver {
         resolve(name) { // eslint-disable-line class-methods-use-this
-            if (mapping.hasOwnProperty(name)) {
+            if (Object.prototype.hasOwnProperty.call(mapping, name)) {
                 return mapping[name];
             }
 
@@ -140,7 +140,7 @@ function overrideNativeResolve(mapping) {
     beforeEach(() => {
         originalFindPath = Module._findPath; // eslint-disable-line no-underscore-dangle
         Module._findPath = function(request, paths, isMain) { // eslint-disable-line no-underscore-dangle
-            if (mapping.hasOwnProperty(request)) {
+            if (Object.prototype.hasOwnProperty.call(mapping, request)) {
                 return mapping[request];
             }
             return originalFindPath.call(this, request, paths, isMain);
diff --git a/tests/lib/rules/no-restricted-globals.js b/tests/lib/rules/no-restricted-globals.js
index a7ce1166a..8d4a69941 100644
--- a/tests/lib/rules/no-restricted-globals.js
+++ b/tests/lib/rules/no-restricted-globals.js
@@ -170,6 +170,12 @@ ruleTester.run("no-restricted-globals", rule, {
             code: "foo.bar()",
             options: [{ name: "foo", message: "Use bar instead." }],
             errors: [{ message: "Unexpected use of 'foo'. Use bar instead.", type: "Identifier" }]
+        },
+        {
+            code: "var foo = obj => hasOwnProperty(obj, 'name');",
+            options: ["hasOwnProperty"],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [{ message: "Unexpected use of 'hasOwnProperty'.", type: "Identifier" }]
         }
     ]
 });
diff --git a/tests/tools/internal-rules/consistent-docs-url.js b/tests/tools/internal-rules/consistent-docs-url.js
index 3d95dac06..cccbc95ac 100644
--- a/tests/tools/internal-rules/consistent-docs-url.js
+++ b/tests/tools/internal-rules/consistent-docs-url.js
@@ -43,6 +43,23 @@ ruleTester.run("consistent-docs-url", rule, {
         ].join("\n")
     ],
     invalid: [
+        {
+            code: [
+                "module.exports = {",
+                "    meta: {",
+                "    },",
+
+                "    create: function(context) {",
+                "        return {};",
+                "    }",
+                "};"
+            ].join("\n"),
+            errors: [{
+                message: "Rule is missing a meta.docs property",
+                line: 2,
+                column: 5
+            }]
+        },
         {
             code: [
                 "module.exports = {",