Repository: eslint/eslint
Pull request #9498 (2017-10-21 23:21:59)

Docs: Amend rule document to correct and complete it (refs #6251).
<!--
    ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
-->

**What is the purpose of this pull request? (put an "X" next to item)**

[X] Documentation update
[ ] Bug fix ([template](https://raw.githubusercontent.com/eslint/eslint/master/templates/bug-report.md))
[ ] New rule ([template](https://raw.githubusercontent.com/eslint/eslint/master/templates/rule-proposal.md))
[ ] Changes an existing rule ([template](https://raw.githubusercontent.com/eslint/eslint/master/templates/rule-change-proposal.md))
[ ] Add autofixing to a rule
[ ] Add a CLI option
[ ] Add something to the core
[ ] Other, please explain:

<!--
    If the item you've checked above has a template, please paste the template questions below and answer them. (If this pull request is addressing an issue, you can just paste a link to the issue here instead.)
-->

<!--
    Please ensure your pull request is ready:

    - Read the pull request guide (https://eslint.org/docs/developer-guide/contributing/pull-requests)
    - Include tests for this change
    - Update documentation for this change (if appropriate)
-->

<!--
    The following is required for all pull requests:
-->

**What changes did you make? (Give an overview)**
Corrected and completed documentation on rule `object-property-newline` to complete step 1 of plan to handle issue #6251.

**Is there anything you'd like reviewers to focus on?**
This rule seems to treat shorthand and computed properties correctly without the ecmaversion: 6 parser option. Should the documentation nevertheless instruct users to invoke that option for these property syntaxes? Also, the tests include experimental object rest spread cases, but the general user documentation cautions against writing rules for this syntax. Should this rule’s documentation state that this syntax is supported?

eslintbot: LGTM
eslintbot: LGTM

Patch:
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index e8ad7ffbe..d33ca1105 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -32,7 +32,7 @@
 
 </details>
 
-**What did you do? Please include the actual source code causing the issue.**
+**What did you do? Please include the actual source code causing the issue, as well as the command that you used to run ESLint.**
 
 <!-- Paste the source code below: -->
 ```js
@@ -41,6 +41,11 @@
 
 
 
+```
+
+<!-- Paste the command you used to run ESLint: -->
+```bash
+
 ```
 
 **What did you expect to happen?**
diff --git a/Makefile.js b/Makefile.js
index 01b0cc2b1..30220062d 100644
--- a/Makefile.js
+++ b/Makefile.js
@@ -85,9 +85,6 @@ const NODE = "node ", // intentional extra space
     PERF_MULTIFILES_TARGET_DIR = path.join(PERF_TMP_DIR, "eslint"),
     PERF_MULTIFILES_TARGETS = `"${PERF_MULTIFILES_TARGET_DIR + path.sep}{lib,tests${path.sep}lib}${path.sep}**${path.sep}*.js"`,
 
-    // Regex
-    TAG_REGEX = /^(?:Breaking|Build|Chore|Docs|Fix|New|Update|Upgrade):/,
-
     // Settings
     MOCHA_TIMEOUT = 10000;
 
@@ -106,7 +103,7 @@ function getTestFilePatterns() {
             initialValue.push(`"tests/lib/${currentValues}/**/*.js"`);
         }
         return initialValue;
-    }, ["tests/lib/rules/**/*.js", "tests/lib/*.js", "tests/templates/*.js", "tests/bin/**/*.js", "tests/tools/**/*.js"]).join(" ");
+    }, ["tests/lib/rules/**/*.js", "tests/lib/*.js", "tests/bin/**/*.js", "tests/tools/**/*.js"]).join(" ");
 }
 
 /**
@@ -383,24 +380,6 @@ function getFirstVersionOfDeletion(filePath) {
         .sort(semver.compare)[0];
 }
 
-
-/**
- * Returns all the branch names
- * @returns {string[]} branch names
- * @private
- */
-function getBranches() {
-    const branchesRaw = splitCommandResultToLines(execSilent("git branch --list")),
-        branches = [];
-
-    for (let i = 0; i < branchesRaw.length; i++) {
-        const branchName = branchesRaw[i].replace(/^\*(.*)/, "$1").trim();
-
-        branches.push(branchName);
-    }
-    return branches;
-}
-
 /**
  * Lints Markdown files.
  * @param {array} files Array of file names to lint.
@@ -445,18 +424,6 @@ function lintMarkdown(files) {
     return { code: returnCode };
 }
 
-/**
- * Check if the branch name is valid
- * @param {string} branchName Branch name to check
- * @returns {boolean} true is branch exists
- * @private
- */
-function hasBranch(branchName) {
-    const branches = getBranches();
-
-    return branches.indexOf(branchName) !== -1;
-}
-
 /**
  * Gets linting results from every formatter, based on a hard-coded snippet and config
  * @returns {Object} Output from each formatter
@@ -954,57 +921,6 @@ target.checkLicenses = function() {
     });
 };
 
-target.checkGitCommit = function() {
-    let commitMsgs,
-        failed;
-
-    if (hasBranch("master")) {
-        commitMsgs = splitCommandResultToLines(execSilent("git log HEAD --not master --format=format:%s --no-merges"));
-    } else {
-        commitMsgs = [execSilent("git log -1 --format=format:%s --no-merges")];
-    }
-
-    echo("Validating Commit Message");
-
-    // No commit since master should not cause test to fail
-    if (commitMsgs[0] === "") {
-        return;
-    }
-
-    // Check for more than one commit
-    if (commitMsgs.length > 1) {
-        echo(" - More than one commit found, please squash.");
-        failed = true;
-    }
-
-    // Only check non-release messages
-    if (!semver.valid(commitMsgs[0]) && !/^Revert /.test(commitMsgs[0])) {
-        if (commitMsgs[0].split(/\r?\n/)[0].length > 72) {
-            echo(" - First line of commit message must not exceed 72 characters");
-            failed = true;
-        }
-
-        // Check for tag at start of message
-        if (!TAG_REGEX.test(commitMsgs[0])) {
-            echo([" - Commit summary must start with one of:",
-                "    'Fix:'",
-                "    'Update:'",
-                "    'Breaking:'",
-                "    'Docs:'",
-                "    'Build:'",
-                "    'New:'",
-                "    'Upgrade:'",
-                "    'Chore:'",
-                "   Please refer to the contribution guidelines for more details."].join("\n"));
-            failed = true;
-        }
-    }
-
-    if (failed) {
-        exit(1);
-    }
-};
-
 /**
  * Downloads a repository which has many js files to test performance with multi files.
  * Here, it's eslint@1.10.3 (450 files)
diff --git a/docs/developer-guide/contributing/pull-requests.md b/docs/developer-guide/contributing/pull-requests.md
index efeca5fcd..84990a758 100644
--- a/docs/developer-guide/contributing/pull-requests.md
+++ b/docs/developer-guide/contributing/pull-requests.md
@@ -105,7 +105,7 @@ If there are any failing tests, update your code until all tests pass.
 
 With your code ready to go, this is a good time to double-check your submission to make sure it follows our conventions. Here are the things to check:
 
-* Run `npm run check-commit` to double-check that your commit is formatted correctly.
+* Make sure your commit is formatted correctly.
 * The pull request must have a description. The description should explain what you did and how its effects can be seen.
 * The commit message is properly formatted.
 * The change introduces no functional regression. Be sure to run `npm test` to verify your changes before submitting a pull request.
diff --git a/docs/developer-guide/contributing/working-on-issues.md b/docs/developer-guide/contributing/working-on-issues.md
index 95282aa9c..c1878dbea 100644
--- a/docs/developer-guide/contributing/working-on-issues.md
+++ b/docs/developer-guide/contributing/working-on-issues.md
@@ -4,29 +4,19 @@ Our public [issues tracker](https://github.com/eslint/eslint/issues) lists all o
 
 ## Issue Labels
 
-We use labels to indicate the status of issues. The most important labels are:
+We use labels to indicate the status of issues. The most complete documentation on the labels is found in the [Maintainer Guide](https://eslint.org/docs/maintainer-guide/issues.html#when-an-issue-is-opened), but most contributors should find the information on this page sufficient. The most important questions that labels can help you, as a contributor, answer are:
 
-1. [`triage`](https://github.com/eslint/eslint/issues?labels=triage&milestone=&page=1&state=open) - When an issue is first submitted, it is labeled as `triage`, which means the ESLint team needs to investigate and determine if the request is a bug report, a feature request, or something else. It's best not to work on tickets marked as `triage`, because we're not yet sure if we will accept the issue to work on.
-1. [`accepted`](https://github.com/eslint/eslint/issues?labels=accepted&milestone=&page=1&state=open) - Once an issue has been properly triaged and the team decides it must be addressed, someone will assign the `accepted` label to an issue. When an issue is accepted, anyone is free to work on it.
-1. [`bug`](https://github.com/eslint/eslint/issues?labels=bug&milestone=&page=1&state=open) - Indicates that the issue is reporting a problem. When submitting a pull request to work on this type of issue, be sure to prefix the commit message with "Fix:".
-1. [`feature`](https://github.com/eslint/eslint/issues?labels=feature&milestone=&page=1&state=open) - Indicates that the issue is requesting a new feature. Features are functionality that doesn't already exist in the project. When submitting a pull request to work on this type of issue, be sure to prefix the commit message with "New:".
-1. [`enhancement`](https://github.com/eslint/eslint/issues?labels=enhancement&milestone=&page=1&state=open) - Indicates that the issue is requesting a change to existing functionality. When submitting a pull request to work on this type of issue, be sure to prefix the commit message with "Update:".
-1. [`beginner`](https://github.com/eslint/eslint/issues?labels=beginner&milestone=&page=1&state=open) - Indicates that the issue is simple enough that it would be a good first contribution for a new contributor. If you're looking to get started helping out with ESLint, take a look at the beginner issues.
-1. [`help wanted`](https://github.com/eslint/eslint/issues?labels=help%20wanted&milestone=&page=1&state=open) - Indicates that the core team won't be working on this issue, however, we will accept pull requests from contributors. This basically means the issue isn't on the formal roadmap but it will be accepted if a contributor wants to implement it.
+1. Is this issue available for me to work on? If you have little or no experience contributing to ESLint, the [`beginner`](https://github.com/eslint/eslint/labels/beginner) label marks appropriate issues. Otherwise, the [`help wanted`](https://github.com/eslint/eslint/labels/help%20wanted) label is an invitation to work on the issue. If you have more experience, you can try working on other issues labeled [`accepted`](https://github.com/eslint/eslint/labels/accepted). Conversely, issues not yet ready to work on are labeled `triage`, `evaluating`, and/or `needs bikeshedding`, and issues that cannot currently be worked on because of something else, such as a bug in a dependency, are labeled `blocked`.
+1. What is this issue about? Labels describing the nature of issues include `bug`, `enhancement`, `feature`, `question`, `rule`, `documentation`, `core`, `build`, `cli`, `infrastructure`, `breaking`, and `chore`. These are documented in the [Maintainer Guide](https://eslint.org/docs/maintainer-guide/issues.html#types-of-issues).
+1. What is the priority of this issue? Because we have a lot of issues, we prioritize certain issues above others. The following is the list of priorities, from highest to lowest:
 
-## Bounty Issues
+    1. **Bugs** - problems with the project are actively affecting users. We want to get these resolved as quickly as possible.
+    1. **Documentation** - documentation issues are a type of bug in that they actively affect current users. As such, we want to address documentation issues as quickly as possible.
+    1. **Features** - new functionality that will aid users in the future.
+    1. **Enhancements** - requested improvements for existing functionality.
+    1. **Other** - anything else.
 
-We accept and assign issue bounties using [BountySource](https://www.bountysource.com/teams/eslint/issues).
-
-## Issue Priority
-
-Because we have a lot of issues, we prioritize certain issues above others. The following is the list of priorities, from highest to lowest:
-
-1. **Bugs** - problems with the project are actively affecting users. We want to get these resolved as quickly as possible.
-1. **Documentation** - documentation issues are a type of bug in that they actively affect current users. As such, we want to address documentation issues as quickly as possible.
-1. **Features** - new functionality that will aid users in the future.
-1. **Enhancements** - requested improvements for existing functionality.
-1. **Other** - anything else.
+    Some issues have had monetary rewards attached to them. Those are labeled `bounty`. Bounties are assigned via [BountySource](https://www.bountysource.com/teams/eslint/issues).
 
 ## Starting Work
 
diff --git a/docs/developer-guide/nodejs-api.md b/docs/developer-guide/nodejs-api.md
index 2aecd961e..b668afc82 100644
--- a/docs/developer-guide/nodejs-api.md
+++ b/docs/developer-guide/nodejs-api.md
@@ -706,8 +706,8 @@ Example usage:
 ```js
 "use strict";
 
-const rule = require("../../../lib/rules/my-rule");
-const RuleTester = require("eslint").RuleTester;
+const rule = require("../../../lib/rules/my-rule"),
+    RuleTester = require("eslint").RuleTester;
 
 const ruleTester = new RuleTester();
 
@@ -789,9 +789,9 @@ Example of customizing `RuleTester`:
 ```js
 "use strict";
 
-const RuleTester = require("eslint").RuleTester;
-const test = require("my-test-runner");
-const myRule = require("../../../lib/rules/my-rule");
+const RuleTester = require("eslint").RuleTester,
+    test = require("my-test-runner"),
+    myRule = require("../../../lib/rules/my-rule");
 
 RuleTester.describe = function(text, method) {
     RuleTester.it.title = text;
diff --git a/docs/maintainer-guide/README.md b/docs/maintainer-guide/README.md
index 845a5bade..19c1fb9ee 100644
--- a/docs/maintainer-guide/README.md
+++ b/docs/maintainer-guide/README.md
@@ -2,18 +2,18 @@
 
 This guide is intended for those who work as part of the ESLint project team.
 
-## [Managing Issues](issues.html)
+## [Managing Issues](issues.md)
 
 Describes how to deal with issues when they're opened, when interacting with users, and how to close them effectively.
 
-## [Reviewing Pull Requests](pullrequests.html)
+## [Reviewing Pull Requests](pullrequests.md)
 
 Describes how to review incoming pull requests.
 
-## [Managing Releases](releases.html)
+## [Managing Releases](releases.md)
 
 Describes how to do an ESLint project release.
 
-## [Governance](governance.html)
+## [Governance](governance.md)
 
 Describes the governance policy for ESLint, including the rights and privileges of individuals inside the project.
diff --git a/docs/maintainer-guide/issues.md b/docs/maintainer-guide/issues.md
index 780508b30..cb4c71070 100644
--- a/docs/maintainer-guide/issues.md
+++ b/docs/maintainer-guide/issues.md
@@ -41,10 +41,10 @@ The steps for triaging an issue are:
             * "documentation" - related to content on eslint.org
             * "infrastructure" - related to resources needed for builds or deployment (VMs, CI tools, bots, etc.)
 1. Once it's clear what type of issue it is, make sure all of the relevant information is provided:
-    * **Bugs**: See [bug reporting guidelines](/docs/developer-guide/contributing/reporting-bugs)
-    * **New Rules:** See [rule proposal guidelines](/docs/developer-guide/contributing/new-rules)
-    * **Rule Changes:** See [rule change proposal guidelines](/docs/developer-guide/contributing/rule-changes)
-    * **Other Changes:** See [change proposal guidelines](https://eslint.org/docs/developer-guide/contributing/changes)
+    * **Bugs**: See [bug reporting guidelines](/docs/developer-guide/contributing/reporting-bugs.md)
+    * **New Rules:** See [rule proposal guidelines](/docs/developer-guide/contributing/new-rules.md)
+    * **Rule Changes:** See [rule change proposal guidelines](/docs/developer-guide/contributing/rule-changes.md)
+    * **Other Changes:** See [change proposal guidelines](/docs/developer-guide/contributing/changes.md)
 1. Next steps:
     * **Questions:** answer the question and close the issue when the conversation is over.
     * **Bugs:** if you can verify the bug, add the "accepted" label and ask if they would like to submit a pull request.
diff --git a/docs/rules/comma-spacing.md b/docs/rules/comma-spacing.md
index 759494bf3..a04d5ae5e 100644
--- a/docs/rules/comma-spacing.md
+++ b/docs/rules/comma-spacing.md
@@ -124,6 +124,6 @@ If your project will not be following a consistent comma-spacing pattern, turn t
 * [space-in-brackets](space-in-brackets.md) (deprecated)
 * [space-in-parens](space-in-parens.md)
 * [space-infix-ops](space-infix-ops.md)
-* [space-after-keywords](space-after-keywords)
-* [space-unary-ops](space-unary-ops)
-* [space-return-throw-case](space-return-throw-case)
+* [space-after-keywords](space-after-keywords.md)
+* [space-unary-ops](space-unary-ops.md)
+* [space-return-throw-case](space-return-throw-case.md)
diff --git a/docs/rules/indent.md b/docs/rules/indent.md
index 9b375d864..beec36748 100644
--- a/docs/rules/indent.md
+++ b/docs/rules/indent.md
@@ -84,7 +84,7 @@ This rule has an object option:
 * `"ObjectExpression"` (default: 1) enforces indentation level for properties in objects. It can be set to the string `"first"`, indicating that all properties in the object should be aligned with the first property. This can also be set to `"off"` to disable checking for object properties.
 * `"ImportDeclaration"` (default: 1) enforces indentation level for import statements. It can be set to the string `"first"`, indicating that all imported members from a module should be aligned with the first member in the list. This can also be set to `"off"` to disable checking for imported module members.
 * `"flatTernaryExpressions": true` (`false` by default) requires no indentation for ternary expressions which are nested in other ternary expressions.
-* `ignoredNodes` accepts an array of [selectors](/docs/developer-guide/selectors). If an AST node is matched by any of the selectors, the indentation of tokens which are direct children of that node will be ignored. This can be used as an escape hatch to relax the rule if you disagree with the indentation that it enforces for a particular syntactic pattern.
+* `ignoredNodes` accepts an array of [selectors](/docs/developer-guide/selectors.md). If an AST node is matched by any of the selectors, the indentation of tokens which are direct children of that node will be ignored. This can be used as an escape hatch to relax the rule if you disagree with the indentation that it enforces for a particular syntactic pattern.
 
 Level of indentation denotes the multiple of the indent specified. Example:
 
diff --git a/docs/rules/no-multi-spaces.md b/docs/rules/no-multi-spaces.md
index f3270cb7d..07cd0e901 100644
--- a/docs/rules/no-multi-spaces.md
+++ b/docs/rules/no-multi-spaces.md
@@ -166,6 +166,6 @@ If you don't want to check and disallow multiple spaces, then you should turn th
 * [space-infix-ops](space-infix-ops.md)
 * [space-in-brackets](space-in-brackets.md) (deprecated)
 * [space-in-parens](space-in-parens.md)
-* [space-after-keywords](space-after-keywords)
-* [space-unary-ops](space-unary-ops)
-* [space-return-throw-case](space-return-throw-case)
+* [space-after-keywords](space-after-keywords.md)
+* [space-unary-ops](space-unary-ops.md)
+* [space-return-throw-case](space-return-throw-case.md)
diff --git a/docs/rules/no-undef.md b/docs/rules/no-undef.md
index 3bd7d5114..4b21f2c05 100644
--- a/docs/rules/no-undef.md
+++ b/docs/rules/no-undef.md
@@ -75,7 +75,7 @@ if(typeof a === "string"){}
 
 ## Environments
 
-For convenience, ESLint provides shortcuts that pre-define global variables exposed by popular libraries and runtime environments. This rule supports these environments, as listed in [Specifying Environments](https://eslint.org/docs/user-guide/configuring#specifying-environments).  A few examples are given below.
+For convenience, ESLint provides shortcuts that pre-define global variables exposed by popular libraries and runtime environments. This rule supports these environments, as listed in [Specifying Environments](../user-guide/configuring.md#specifying-environments).  A few examples are given below.
 
 ### browser
 
diff --git a/docs/rules/object-property-newline.md b/docs/rules/object-property-newline.md
index 6104c2b9a..3e0e5a661 100644
--- a/docs/rules/object-property-newline.md
+++ b/docs/rules/object-property-newline.md
@@ -1,11 +1,63 @@
 # enforce placing object properties on separate lines (object-property-newline)
 
-While formatting preferences are very personal, a number of style guides require that object properties be placed on separate lines for better readability.
+This rule permits you to restrict the locations of property specifications in object literals. You may prohibit any part of any property specification from appearing on the same line as any part of any other property specification. You may make this prohibition absolute, or, by invoking an object option, you may allow an exception, permitting an object literal to have all parts of all of its property specifications on a single line.
 
-Another argument in favor of this style is that it improves the readability of diffs when a property is changed:
+## Rule Details
+
+### Motivations
+
+This rule makes it possible to ensure, as some style guides require, that property specifications appear on separate lines for better readability. For example, you can prohibit all of these:
+
+```js
+const newObject = {a: 1, b: [2, {a: 3, b: 4}]};
+const newObject = {
+    a: 1, b: [2, {a: 3, b: 4}]
+};
+const newObject = {
+    a: 1,
+    b: [2, {a: 3, b: 4}]
+};
+const newObject = {
+    a: 1,
+    b: [
+        2,
+        {a: 3, b: 4}
+    ]
+};
+
+```
+
+Instead of those, you can comply with the rule by writing
+
+```js
+const newObject = {
+    a: 1,
+    b: [2, {
+        a: 3,
+        b: 4
+    }]
+};
+```
+
+or
+
+```js
+const newObject = {
+    a: 1,
+    b: [
+        2,
+        {
+            a: 3,
+            b: 4
+        }
+    ]
+};
+```
+
+Another benefit of this rule is specificity of diffs when a property is changed:
 
 ```diff
-// More readable
+// More specific
  var obj = {
      foo: "foo",
 -    bar: "bar",
@@ -15,51 +67,164 @@ Another argument in favor of this style is that it improves the readability of d
 ```
 
 ```diff
-// Less readable
+// Less specific
 -var obj = { foo: "foo", bar: "bar", baz: "baz" };
 +var obj = { foo: "foo", bar: "bazz", baz: "baz" };
 ```
 
-## Rule Details
+### Optional Exception
+
+The rule offers one object option, `allowMultiplePropertiesPerLine`. If you set it to `true`, object literals such as the first two above, with all property specifications on the same line, will be permitted, but one like
+
+```js
+const newObject = {
+    a: 'a.m.', b: 'p.m.',
+    c: 'daylight saving time'
+};
+
+```
+
+will be prohibited, because two properties, but not all properties, appear on the same line.
+
+### Notations
+
+This rule applies equally to all property specifications, regardless of notation, including:
+
+- `a: 1` (ES5)
+- `a` (ES2015 shorthand property)
+- ``[`prop${a}`]`` (computed property name)
+
+Thus, the rule (without the object option) prohibits both of these:
+
+```js
+const newObject = {
+    a: 1, [
+        process.argv[4]
+    ]: '01'
+};
+const newObject = {
+    a: 1, [process.argv[4]]: '01'
+};
+```
+
+(This behavior differs from that of the JSCS rule cited below, which does not treat the leading `[` of a computed property name as part of that property specification. The JSCS rule prohibits the second of these formats but permits the first.)
 
-This rule aims to maintain consistency of newlines between object properties.
+### Multiline Properties
 
-Examples of **incorrect** code for this rule:
+The rule prohibits the colocation on any line of at least 1 character of one property specification with at least 1 character of any other property specification. For example, the rule prohibits
+
+```js
+const newObject = {a: [
+    'Officiële website van de Europese Unie',
+    'Официален уебсайт на Европейския съюз'
+], b: 2};
+```
+
+because 1 character of the specification of `a` (i.e. the trailing `]` of its value) is on the same line as the specification of `b`.
+
+The optional exception does not excuse this case, because the entire collection of property specifications spans 4 lines, not 1.
+
+### Inter-property Delimiters
+
+The comma and any whitespace that delimit property specifications are not considered parts of them. Therefore, the rule permits both of these formats:
+
+```js
+const newFunction = multiplier => ({
+    a: 2 * multiplier,
+    b: 4 * multiplier,
+    c: 8 * multiplier
+});
+const newFunction = multiplier => ({
+    a: 2 * multiplier
+    , b: 4 * multiplier
+    , c: 8 * multiplier
+});
+```
+
+(This behavior differs from that of the JSCS rule cited below, which permits the first but prohibits the second format.)
+
+### --fix
+
+If this rule is invoked with the command-line `--fix` option, object literals that violate the rule are generally modified to comply with it. The modification in each case is to move a property specification to the next line whenever there is part or all of a previous property specification on the same line. For example,
+
+```js
+const newObject = {
+    a: 'a.m.', b: 'p.m.',
+    c: 'daylight saving time'
+};
+```
+
+is converted to
+
+```js
+const newObject = {
+    a: 'a.m.',
+b: 'p.m.',
+    c: 'daylight saving time'
+};
+```
+
+The modification does not depend on whether the object option is set to `true`. In other words, ESLint never collects all the property specifications onto a single line, even when the object option would permit that.
+
+ESLint does not correct a violation of this rule if a comment immediately precedes the second or subsequent property specification on a line, since ESLint cannot determine which line to put the comment onto.
+
+As illustrated above, the `--fix` option, applied to this rule, does not comply with other rules, such as `indent`, but, if those other rules are also in effect, the option applies them, too.
+
+## Examples
+
+Examples of **incorrect** code for this rule, with no object option or with `allowMultiplePropertiesPerLine` set to `false`:
 
 ```js
 /*eslint object-property-newline: "error"*/
 
-var obj = { foo: "foo", bar: "bar", baz: "baz" };
+const obj0 = { foo: "foo", bar: "bar", baz: "baz" };
 
-var obj2 = {
+const obj1 = {
     foo: "foo", bar: "bar", baz: "baz"
 };
 
-var obj3 = {
+const obj2 = {
     foo: "foo", bar: "bar",
     baz: "baz"
 };
+
+const obj3 = {
+    [process.argv[3] ? "foo" : "bar"]: 0, baz: [
+        1,
+        2,
+        4,
+        8
+    ]
+};
+
+const a = "antidisestablishmentarianistically";
+const b = "yugoslavyalılaştırabildiklerimizdenmişsiniz";
+const obj4 = {a, b};
 ```
 
-Examples of **correct** code for this rule:
+Examples of **correct** code for this rule, with no object option or with `allowMultiplePropertiesPerLine` set to `false`:
 
 ```js
 /*eslint object-property-newline: "error"*/
 
-var obj = {
+const obj = {
     foo: "foo",
     bar: "bar",
     baz: "baz"
 };
-```
-
-## Options
-
-This rule has an object option:
 
-* `"allowMultiplePropertiesPerLine"`: `true` allows all keys and values to be on the same line
-
-### allowMultiplePropertiesPerLine
+const user = process.argv[2];
+const obj3 = {
+    user,
+    [process.argv[3] ? "foo" : "bar"]: 0,
+    baz: [
+        1,
+        2,
+        4,
+        8
+    ]
+};
+```
 
 Examples of additional **correct** code for this rule with the `{ "allowMultiplePropertiesPerLine": true }` option:
 
@@ -71,19 +236,23 @@ var obj = { foo: "foo", bar: "bar", baz: "baz" };
 var obj2 = {
     foo: "foo", bar: "bar", baz: "baz"
 };
+const user = process.argv[2];
+const obj3 = {
+    user, [process.argv[3] ? "foo" : "bar"]: 0, baz: [1, 2, 4, 8]
+};
 ```
 
 ## When Not To Use It
 
-You can turn this rule off if you are not concerned with the consistency of newlines between object properties.
+You can turn this rule off if you want to decide, case-by-case, whether to place property specifications on separate lines.
 
 ## Compatibility
 
-* **JSCS**: [requireObjectKeysOnNewLine](http://jscs.info/rule/requireObjectKeysOnNewLine)
+- **JSCS**: This rule provides partial compatibility with [requireObjectKeysOnNewLine](http://jscs.info/rule/requireObjectKeysOnNewLine).
 
 ## Related Rules
 
-* [brace-style](brace-style.md)
-* [comma-dangle](comma-dangle.md)
-* [key-spacing](key-spacing.md)
-* [object-curly-spacing](object-curly-spacing.md)
+- [brace-style](brace-style.md)
+- [comma-dangle](comma-dangle.md)
+- [key-spacing](key-spacing.md)
+- [object-curly-spacing](object-curly-spacing.md)
diff --git a/docs/rules/prefer-promise-reject-errors.md b/docs/rules/prefer-promise-reject-errors.md
index 353135a8f..ac0a227d1 100644
--- a/docs/rules/prefer-promise-reject-errors.md
+++ b/docs/rules/prefer-promise-reject-errors.md
@@ -65,7 +65,7 @@ new Promise(function(resolve, reject) {
 
 ## Known Limitations
 
-Due to the limits of static analysis, this rule cannot guarantee that you will only reject Promises with `Error` objects. While the rule will report cases where it can guarantee that the rejection reason is clearly not an `Error`, it will not report cases where there is uncertainty about whether a given reason is an `Error`. For more information on this caveat, see the [similar limitations](https://eslint.org/docs/rules/no-throw-literal#known-limitations) in the `no-throw-literal` rule.
+Due to the limits of static analysis, this rule cannot guarantee that you will only reject Promises with `Error` objects. While the rule will report cases where it can guarantee that the rejection reason is clearly not an `Error`, it will not report cases where there is uncertainty about whether a given reason is an `Error`. For more information on this caveat, see the [similar limitations](no-throw-literal.md#known-limitations) in the `no-throw-literal` rule.
 
 To avoid conflicts between rules, this rule does not report non-error values used in `throw` statements in async functions, even though these lead to Promise rejections. To lint for these cases, use the [`no-throw-literal`](https://eslint.org/docs/rules/no-throw-literal) rule.
 
diff --git a/docs/rules/rest-spread-spacing.md b/docs/rules/rest-spread-spacing.md
index d66669455..27cc626c1 100644
--- a/docs/rules/rest-spread-spacing.md
+++ b/docs/rules/rest-spread-spacing.md
@@ -54,7 +54,7 @@ This rule aims to enforce consistent spacing between rest and spread operators a
 }
 ```
 
-Please read the user guide's section on [configuring parser options](https://eslint.org/docs/user-guide/configuring#specifying-parser-options) to learn more.
+Please read the user guide's section on [configuring parser options](/docs/user-guide/configuring#specifying-parser-options) to learn more.
 
 ## Options
 
diff --git a/docs/rules/sort-imports.md b/docs/rules/sort-imports.md
index 9d610f48f..51daad5fa 100644
--- a/docs/rules/sort-imports.md
+++ b/docs/rules/sort-imports.md
@@ -203,5 +203,5 @@ This rule is a formatting preference and not following it won't negatively affec
 
 ## Related Rules
 
-* [sort-keys](https://eslint.org/docs/rules/sort-keys)
-* [sort-vars](https://eslint.org/docs/rules/sort-vars)
+* [sort-keys](sort-keys.md)
+* [sort-vars](sort-vars.md)
diff --git a/docs/rules/sort-keys.md b/docs/rules/sort-keys.md
index 1960b4f75..43d3dc522 100644
--- a/docs/rules/sort-keys.md
+++ b/docs/rules/sort-keys.md
@@ -170,8 +170,8 @@ If you don't want to notify about properties' order, then it's safe to disable t
 
 ## Related Rules
 
-* [sort-imports](https://eslint.org/docs/rules/sort-imports)
-* [sort-vars](https://eslint.org/docs/rules/sort-vars)
+* [sort-imports](sort-imports.md)
+* [sort-vars](sort-vars.md)
 
 ## Compatibility
 
diff --git a/docs/rules/sort-vars.md b/docs/rules/sort-vars.md
index 59600873c..8a201f358 100644
--- a/docs/rules/sort-vars.md
+++ b/docs/rules/sort-vars.md
@@ -74,5 +74,5 @@ This rule is a formatting preference and not following it won't negatively affec
 
 ## Related Rules
 
-* [sort-keys](https://eslint.org/docs/rules/sort-keys)
-* [sort-imports](https://eslint.org/docs/rules/sort-imports)
+* [sort-keys](sort-keys.md)
+* [sort-imports](sort-imports.md)
diff --git a/docs/rules/strict.md b/docs/rules/strict.md
index e1cc4b7c6..1672f7e38 100644
--- a/docs/rules/strict.md
+++ b/docs/rules/strict.md
@@ -269,4 +269,4 @@ function foo() {
 
 ## When Not To Use It
 
-In a codebase that has both strict and non-strict code, either turn this rule off, or [selectively disable it](https://eslint.org/docs/user-guide/configuring) where necessary. For example, functions referencing `arguments.callee` are invalid in strict mode. A [full list of strict mode differences](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode/Transitioning_to_strict_mode#Differences_from_non-strict_to_strict) is available on MDN.
+In a codebase that has both strict and non-strict code, either turn this rule off, or [selectively disable it](/docs/user-guide/configuring.md) where necessary. For example, functions referencing `arguments.callee` are invalid in strict mode. A [full list of strict mode differences](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode/Transitioning_to_strict_mode#Differences_from_non-strict_to_strict) is available on MDN.
diff --git a/docs/user-guide/command-line-interface.md b/docs/user-guide/command-line-interface.md
index 0728a96b0..3e6a5a31b 100644
--- a/docs/user-guide/command-line-interface.md
+++ b/docs/user-guide/command-line-interface.md
@@ -116,7 +116,7 @@ Example:
 
 #### `--env`
 
-This option enables specific environments. Details about the global variables defined by each environment are available on the [configuration](configuring) documentation. This option only enables environments; it does not disable environments set in other configuration files. To specify multiple environments, separate them using commas, or use the option multiple times.
+This option enables specific environments. Details about the global variables defined by each environment are available on the [configuration](configuring.md) documentation. This option only enables environments; it does not disable environments set in other configuration files. To specify multiple environments, separate them using commas, or use the option multiple times.
 
 Examples:
 
@@ -310,18 +310,18 @@ When specified, the given format is output into the provided file name.
 
 This option specifies the output format for the console. Possible formats are:
 
-* [checkstyle](formatters/#checkstyle)
-* [codeframe](formatters/#codeframe)
-* [compact](formatters/#compact)
-* [html](formatters/#html)
-* [jslint-xml](formatters/#jslint-xml)
-* [json](formatters/#json)
-* [junit](formatters/#junit)
-* [stylish](formatters/#stylish) (the default)
-* [table](formatters/#table)
-* [tap](formatters/#tap)
-* [unix](formatters/#unix)
-* [visualstudio](formatters/#visualstudio)
+* [checkstyle](formatters.md/#checkstyle)
+* [codeframe](formatters.md/#codeframe)
+* [compact](formatters.md/#compact)
+* [html](formatters.md/#html)
+* [jslint-xml](formatters.md/#jslint-xml)
+* [json](formatters.md/#json)
+* [junit](formatters.md/#junit)
+* [stylish](formatters.md/#stylish) (the default)
+* [table](formatters.md/#table)
+* [tap](formatters.md/#tap)
+* [unix](formatters.md/#unix)
+* [visualstudio](formatters.md/#visualstudio)
 
 Example:
 
@@ -432,4 +432,4 @@ ESLint supports `.eslintignore` files to exclude files from the linting process
     node_modules/*
     **/vendor/*.js
 
-A more detailed breakdown of supported patterns and directories ESLint ignores by default can be found in [Configuring ESLint](https://eslint.org/docs/user-guide/configuring#ignoring-files-and-directories).
+A more detailed breakdown of supported patterns and directories ESLint ignores by default can be found in [Configuring ESLint](configuring.md#ignoring-files-and-directories).
diff --git a/docs/user-guide/configuring.md b/docs/user-guide/configuring.md
index b9d0123c2..f8cb3222d 100644
--- a/docs/user-guide/configuring.md
+++ b/docs/user-guide/configuring.md
@@ -259,7 +259,7 @@ And in YAML:
     - eslint-plugin-plugin2
 ```
 
-**Note:** A globally-installed instance of ESLint can only use globally-installed ESLint plugins. A locally-installed ESLint can make use of both locally- and globally- installed ESLint plugins.
+**Note:** Due to the behaviour of Node's `require` function, a globally-installed instance of ESLint can only use globally-installed ESLint plugins, and locally-installed version can only use *locally-installed* plugins. Mixing local and global plugins is not supported.
 
 ## Configuring Rules
 
diff --git a/docs/user-guide/getting-started.md b/docs/user-guide/getting-started.md
index 8286468ba..dce5f224b 100644
--- a/docs/user-guide/getting-started.md
+++ b/docs/user-guide/getting-started.md
@@ -65,7 +65,7 @@ Any plugins or shareable configs that you use must also be installed globally to
 
 ## Configuration
 
-**Note:** If you are coming from a version before 1.0.0 please see the [migration guide](https://eslint.org/docs/user-guide/migrating-to-1.0.0).
+**Note:** If you are coming from a version before 1.0.0 please see the [migration guide](migrating-to-1.0.0.md).
 
 After running `eslint --init`, you'll have a `.eslintrc` file in your directory. In it, you'll see some rules configured like this:
 
@@ -78,13 +78,13 @@ After running `eslint --init`, you'll have a `.eslintrc` file in your directory.
 }
 ```
 
-The names `"semi"` and `"quotes"` are the names of [rules](https://eslint.org/docs/rules) in ESLint. The first value is the error level of the rule and can be one of these values:
+The names `"semi"` and `"quotes"` are the names of [rules](/docs/rules) in ESLint. The first value is the error level of the rule and can be one of these values:
 
 * `"off"` or `0` - turn the rule off
 * `"warn"` or `1` - turn the rule on as a warning (doesn't affect exit code)
 * `"error"` or `2` - turn the rule on as an error (exit code will be 1)
 
-The three error levels allow you fine-grained control over how ESLint applies rules (for more configuration options and details, see the [configuration docs](https://eslint.org/docs/user-guide/configuring)).
+The three error levels allow you fine-grained control over how ESLint applies rules (for more configuration options and details, see the [configuration docs](configuring.md)).
 
 Your `.eslintrc` configuration file will also include the line:
 
@@ -92,14 +92,14 @@ Your `.eslintrc` configuration file will also include the line:
     "extends": "eslint:recommended"
 ```
 
-Because of this line, all of the rules marked "(recommended)" on the [rules page](https://eslint.org/docs/rules) will be turned on.  Alternatively, you can use configurations that others have created by searching for "eslint-config" on [npmjs.com](https://www.npmjs.com/search?q=eslint-config).  ESLint will not lint your code unless you extend from a shared configuration or explicitly turn rules on in your configuration.
+Because of this line, all of the rules marked "(recommended)" on the [rules page](/docs/rules) will be turned on.  Alternatively, you can use configurations that others have created by searching for "eslint-config" on [npmjs.com](https://www.npmjs.com/search?q=eslint-config).  ESLint will not lint your code unless you extend from a shared configuration or explicitly turn rules on in your configuration.
 
 ---
 
 ## Next Steps
 
-* Learn about [advanced configuration](https://eslint.org/docs/user-guide/configuring) of ESLint.
-* Get familiar with the [command line options](/docs/user-guide/command-line-interface).
-* Explore [ESLint integrations](https://eslint.org/docs/user-guide/integrations) into other tools like editors, build systems, and more.
-* Can't find just the right rule?  Make your own [custom rule](https://eslint.org/docs/developer-guide/working-with-rules).
-* Make ESLint even better by [contributing](https://eslint.org/docs/developer-guide/contributing).
+* Learn about [advanced configuration](configuring.md) of ESLint.
+* Get familiar with the [command line options](command-line-interface.md).
+* Explore [ESLint integrations](integrations.md) into other tools like editors, build systems, and more.
+* Can't find just the right rule?  Make your own [custom rule](/docs/developer-guide/working-with-rules.md).
+* Make ESLint even better by [contributing](/docs/developer-guide/contributing/README.md).
diff --git a/lib/cli-engine.js b/lib/cli-engine.js
index 38c49cb31..5fc35ae0a 100644
--- a/lib/cli-engine.js
+++ b/lib/cli-engine.js
@@ -240,8 +240,8 @@ function processFile(filename, configHelper, options, linter) {
 function createIgnoreResult(filePath, baseDir) {
     let message;
     const isHidden = /^\./.test(path.basename(filePath));
-    const isInNodeModules = baseDir && /^node_modules/.test(path.relative(baseDir, filePath));
-    const isInBowerComponents = baseDir && /^bower_components/.test(path.relative(baseDir, filePath));
+    const isInNodeModules = baseDir && path.relative(baseDir, filePath).startsWith("node_modules");
+    const isInBowerComponents = baseDir && path.relative(baseDir, filePath).startsWith("bower_components");
 
     if (isHidden) {
         message = "File ignored by default.  Use a negated ignore pattern (like \"--ignore-pattern '!<relative/path/to/filename>'\") to override.";
diff --git a/lib/cli.js b/lib/cli.js
index f04448097..6a5482bf9 100644
--- a/lib/cli.js
+++ b/lib/cli.js
@@ -144,6 +144,8 @@ const cli = {
 
         const files = currentOptions._;
 
+        const useStdin = typeof text === "string";
+
         if (currentOptions.version) { // version from package.json
 
             log.info(`v${require("../package.json").version}`);
@@ -153,7 +155,7 @@ const cli = {
                 log.error("The --print-config option must be used with exactly one file name.");
                 return 1;
             }
-            if (text) {
+            if (useStdin) {
                 log.error("The --print-config option is not available for piped-in code.");
                 return 1;
             }
@@ -164,27 +166,27 @@ const cli = {
 
             log.info(JSON.stringify(fileConfig, null, "  "));
             return 0;
-        } else if (currentOptions.help || (!files.length && !text)) {
+        } else if (currentOptions.help || (!files.length && !useStdin)) {
 
             log.info(options.generateHelp());
 
         } else {
 
-            debug(`Running on ${text ? "text" : "files"}`);
+            debug(`Running on ${useStdin ? "text" : "files"}`);
 
             if (currentOptions.fix && currentOptions.fixDryRun) {
                 log.error("The --fix option and the --fix-dry-run option cannot be used together.");
                 return 1;
             }
 
-            if (text && currentOptions.fix) {
+            if (useStdin && currentOptions.fix) {
                 log.error("The --fix option is not available for piped-in code; use --fix-dry-run instead.");
                 return 1;
             }
 
             const engine = new CLIEngine(translateOptions(currentOptions));
 
-            const report = text ? engine.executeOnText(text, currentOptions.stdinFilename, true) : engine.executeOnFiles(files);
+            const report = useStdin ? engine.executeOnText(text, currentOptions.stdinFilename, true) : engine.executeOnFiles(files);
 
             if (currentOptions.fix) {
                 debug("Fix mode enabled - applying fixes");
diff --git a/lib/rules/comma-style.js b/lib/rules/comma-style.js
index 1a9382bea..4c65338a4 100644
--- a/lib/rules/comma-style.js
+++ b/lib/rules/comma-style.js
@@ -208,7 +208,9 @@ module.exports = {
                     if (item) {
                         const tokenAfterItem = sourceCode.getTokenAfter(item, astUtils.isNotClosingParenToken);
 
-                        previousItemToken = tokenAfterItem ? sourceCode.getTokenBefore(tokenAfterItem) : sourceCode.ast.tokens[sourceCode.ast.tokens.length - 1];
+                        previousItemToken = tokenAfterItem
+                            ? sourceCode.getTokenBefore(tokenAfterItem)
+                            : sourceCode.ast.tokens[sourceCode.ast.tokens.length - 1];
                     }
                 });
 
diff --git a/lib/rules/indent-legacy.js b/lib/rules/indent-legacy.js
index 5534944e6..a5db2bb5d 100644
--- a/lib/rules/indent-legacy.js
+++ b/lib/rules/indent-legacy.js
@@ -733,7 +733,9 @@ module.exports = {
                         } else if (parent.type === "ObjectExpression" || parent.type === "ArrayExpression") {
                             const parentElements = node.parent.type === "ObjectExpression" ? node.parent.properties : node.parent.elements;
 
-                            if (parentElements[0] && parentElements[0].loc.start.line === parent.loc.start.line && parentElements[0].loc.end.line !== parent.loc.start.line) {
+                            if (parentElements[0] &&
+                                    parentElements[0].loc.start.line === parent.loc.start.line &&
+                                    parentElements[0].loc.end.line !== parent.loc.start.line) {
 
                                 /*
                                  * If the first element of the array spans multiple lines, don't increase the expected indentation of the rest.
@@ -797,7 +799,8 @@ module.exports = {
                 }
             }
 
-            checkLastNodeLineIndent(node, nodeIndent + (isNodeInVarOnTop(node, parentVarNode) ? options.VariableDeclarator[parentVarNode.parent.kind] * indentSize : 0));
+            checkLastNodeLineIndent(node, nodeIndent +
+                (isNodeInVarOnTop(node, parentVarNode) ? options.VariableDeclarator[parentVarNode.parent.kind] * indentSize : 0));
         }
 
         /**
diff --git a/lib/rules/indent.js b/lib/rules/indent.js
index d33ed1ab9..a804f544a 100644
--- a/lib/rules/indent.js
+++ b/lib/rules/indent.js
@@ -1245,7 +1245,9 @@ module.exports = {
             NewExpression(node) {
 
                 // Only indent the arguments if the NewExpression has parens (e.g. `new Foo(bar)` or `new Foo()`, but not `new Foo`
-                if (node.arguments.length > 0 || astUtils.isClosingParenToken(sourceCode.getLastToken(node)) && astUtils.isOpeningParenToken(sourceCode.getLastToken(node, 1))) {
+                if (node.arguments.length > 0 ||
+                        astUtils.isClosingParenToken(sourceCode.getLastToken(node)) &&
+                        astUtils.isOpeningParenToken(sourceCode.getLastToken(node, 1))) {
                     addFunctionCallIndent(node);
                 }
             },
diff --git a/lib/rules/lines-around-comment.js b/lib/rules/lines-around-comment.js
index 6c130c22b..3df9cb86f 100644
--- a/lib/rules/lines-around-comment.js
+++ b/lib/rules/lines-around-comment.js
@@ -308,7 +308,10 @@ module.exports = {
                 nextLineNum = token.loc.end.line + 1,
                 commentIsNotAlone = codeAroundComment(token);
 
-            const blockStartAllowed = options.allowBlockStart && isCommentAtBlockStart(token) && !(options.allowClassStart === false && isCommentAtClassStart(token)),
+            const blockStartAllowed = options.allowBlockStart &&
+                    isCommentAtBlockStart(token) &&
+                    !(options.allowClassStart === false &&
+                    isCommentAtClassStart(token)),
                 blockEndAllowed = options.allowBlockEnd && isCommentAtBlockEnd(token) && !(options.allowClassEnd === false && isCommentAtClassEnd(token)),
                 classStartAllowed = options.allowClassStart && isCommentAtClassStart(token),
                 classEndAllowed = options.allowClassEnd && isCommentAtClassEnd(token),
diff --git a/lib/rules/multiline-comment-style.js b/lib/rules/multiline-comment-style.js
index 0972b7cc7..db4f76844 100644
--- a/lib/rules/multiline-comment-style.js
+++ b/lib/rules/multiline-comment-style.js
@@ -125,10 +125,12 @@ module.exports = {
                         },
                         message: EXPECTED_BLOCK_ERROR,
                         fix(fixer) {
-                            return fixer.replaceTextRange(
-                                [commentGroup[0].range[0], commentGroup[commentGroup.length - 1].range[1]],
-                                `/*${convertToStarredBlock(commentGroup[0], commentLines)}*/`
-                            );
+                            const range = [commentGroup[0].range[0], commentGroup[commentGroup.length - 1].range[1]];
+                            const starredBlock = `/*${convertToStarredBlock(commentGroup[0], commentLines)}*/`;
+
+                            return commentLines.some(value => value.startsWith("/"))
+                                ? null
+                                : fixer.replaceTextRange(range, starredBlock);
                         }
                     });
                 } else {
@@ -269,10 +271,13 @@ module.exports = {
                         return !tokenBefore || tokenBefore.loc.end.line < comment.loc.start.line;
                     })
                     .reduce((commentGroups, comment, index, commentList) => {
+                        const tokenBefore = sourceCode.getTokenBefore(comment, { includeComments: true });
+
                         if (
                             comment.type === "Line" &&
                             index && commentList[index - 1].type === "Line" &&
-                            sourceCode.getTokenBefore(comment, { includeComments: true }) === commentList[index - 1]
+                            tokenBefore && tokenBefore.loc.end.line === comment.loc.start.line - 1 &&
+                            tokenBefore === commentList[index - 1]
                         ) {
                             commentGroups[commentGroups.length - 1].push(comment);
                         } else {
diff --git a/lib/rules/no-lonely-if.js b/lib/rules/no-lonely-if.js
index 31f47b90e..db127d194 100644
--- a/lib/rules/no-lonely-if.js
+++ b/lib/rules/no-lonely-if.js
@@ -45,7 +45,8 @@ module.exports = {
                             const lastIfToken = sourceCode.getLastToken(node.consequent);
                             const sourceText = sourceCode.getText();
 
-                            if (sourceText.slice(openingElseCurly.range[1], node.range[0]).trim() || sourceText.slice(node.range[1], closingElseCurly.range[0]).trim()) {
+                            if (sourceText.slice(openingElseCurly.range[1],
+                                node.range[0]).trim() || sourceText.slice(node.range[1], closingElseCurly.range[0]).trim()) {
 
                                 // Don't fix if there are any non-whitespace characters interfering (e.g. comments)
                                 return null;
diff --git a/lib/rules/no-unneeded-ternary.js b/lib/rules/no-unneeded-ternary.js
index 929991f86..574553780 100644
--- a/lib/rules/no-unneeded-ternary.js
+++ b/lib/rules/no-unneeded-ternary.js
@@ -72,8 +72,10 @@ module.exports = {
                     node.right,
                     token => token.value === node.operator
                 );
+                const text = sourceCode.getText();
 
-                return sourceCode.getText().slice(node.range[0], operatorToken.range[0]) + OPERATOR_INVERSES[node.operator] + sourceCode.getText().slice(operatorToken.range[1], node.range[1]);
+                return text.slice(node.range[0],
+                    operatorToken.range[0]) + OPERATOR_INVERSES[node.operator] + text.slice(operatorToken.range[1], node.range[1]);
             }
 
             if (astUtils.getPrecedence(node) < astUtils.getPrecedence({ type: "UnaryExpression" })) {
diff --git a/lib/rules/no-unused-labels.js b/lib/rules/no-unused-labels.js
index 12f60ca18..bcd3cfdc4 100644
--- a/lib/rules/no-unused-labels.js
+++ b/lib/rules/no-unused-labels.js
@@ -59,7 +59,8 @@ module.exports = {
                          * Only perform a fix if there are no comments between the label and the body. This will be the case
                          * when there is exactly one token/comment (the ":") between the label and the body.
                          */
-                        if (sourceCode.getTokenAfter(node.label, { includeComments: true }) === sourceCode.getTokenBefore(node.body, { includeComments: true })) {
+                        if (sourceCode.getTokenAfter(node.label, { includeComments: true }) ===
+                                sourceCode.getTokenBefore(node.body, { includeComments: true })) {
                             return fixer.removeRange([node.range[0], node.body.range[0]]);
                         }
 
diff --git a/lib/rules/no-useless-computed-key.js b/lib/rules/no-useless-computed-key.js
index 23de2f373..f8114ab75 100644
--- a/lib/rules/no-useless-computed-key.js
+++ b/lib/rules/no-useless-computed-key.js
@@ -50,7 +50,8 @@ module.exports = {
                             const rightSquareBracket = sourceCode.getFirstTokenBetween(node.key, node.value, astUtils.isClosingBracketToken);
                             const tokensBetween = sourceCode.getTokensBetween(leftSquareBracket, rightSquareBracket, 1);
 
-                            if (tokensBetween.slice(0, -1).some((token, index) => sourceCode.getText().slice(token.range[1], tokensBetween[index + 1].range[0]).trim())) {
+                            if (tokensBetween.slice(0, -1).some((token, index) =>
+                                sourceCode.getText().slice(token.range[1], tokensBetween[index + 1].range[0]).trim())) {
 
                                 // If there are comments between the brackets and the property name, don't do a fix.
                                 return null;
diff --git a/lib/rules/no-useless-escape.js b/lib/rules/no-useless-escape.js
index 0212bd60e..9e39eb6f4 100644
--- a/lib/rules/no-useless-escape.js
+++ b/lib/rules/no-useless-escape.js
@@ -63,7 +63,14 @@ function parseRegExp(regExpText) {
                 return Object.assign(state, { inCharClass: false, startingCharClass: false });
             }
         }
-        charList.push({ text: char, index, escaped: state.escapeNextChar, inCharClass: state.inCharClass, startsCharClass: state.startingCharClass, endsCharClass: false });
+        charList.push({
+            text: char,
+            index,
+            escaped: state.escapeNextChar,
+            inCharClass: state.inCharClass,
+            startsCharClass: state.startingCharClass,
+            endsCharClass: false
+        });
         return Object.assign(state, { escapeNextChar: false, startingCharClass: false });
     }, { escapeNextChar: false, inCharClass: false, startingCharClass: false });
 
diff --git a/lib/rules/no-var.js b/lib/rules/no-var.js
index c74e0b9ad..d3c163e55 100644
--- a/lib/rules/no-var.js
+++ b/lib/rules/no-var.js
@@ -15,6 +15,15 @@ const astUtils = require("../ast-utils");
 // Helpers
 //------------------------------------------------------------------------------
 
+/**
+ * Check whether a given variable is a global variable or not.
+ * @param {eslint-scope.Variable} variable The variable to check.
+ * @returns {boolean} `true` if the variable is a global variable.
+ */
+function isGlobal(variable) {
+    return Boolean(variable.scope) && variable.scope.type === "global";
+}
+
 /**
  * Finds the nearest function scope or global scope walking up the scope
  * hierarchy.
@@ -203,6 +212,7 @@ module.exports = {
          * Checks whether it can fix a given variable declaration or not.
          * It cannot fix if the following cases:
          *
+         * - A variable is a global variable.
          * - A variable is declared on a SwitchCase node.
          * - A variable is redeclared.
          * - A variable is used from outside the scope.
@@ -256,6 +266,7 @@ module.exports = {
 
             if (node.parent.type === "SwitchCase" ||
                 node.declarations.some(hasSelfReferenceInTDZ) ||
+                variables.some(isGlobal) ||
                 variables.some(isRedeclared) ||
                 variables.some(isUsedFromOutsideOf(scopeNode))
             ) {
diff --git a/lib/rules/object-shorthand.js b/lib/rules/object-shorthand.js
index 2f7b0ccf9..dfd8d1a64 100644
--- a/lib/rules/object-shorthand.js
+++ b/lib/rules/object-shorthand.js
@@ -215,8 +215,12 @@ module.exports = {
         * @returns {Object} A fix for this node
         */
         function makeFunctionShorthand(fixer, node) {
-            const firstKeyToken = node.computed ? sourceCode.getFirstToken(node, astUtils.isOpeningBracketToken) : sourceCode.getFirstToken(node.key);
-            const lastKeyToken = node.computed ? sourceCode.getFirstTokenBetween(node.key, node.value, astUtils.isClosingBracketToken) : sourceCode.getLastToken(node.key);
+            const firstKeyToken = node.computed
+                ? sourceCode.getFirstToken(node, astUtils.isOpeningBracketToken)
+                : sourceCode.getFirstToken(node.key);
+            const lastKeyToken = node.computed
+                ? sourceCode.getFirstTokenBetween(node.key, node.value, astUtils.isClosingBracketToken)
+                : sourceCode.getLastToken(node.key);
             const keyText = sourceCode.text.slice(firstKeyToken.range[0], lastKeyToken.range[1]);
             let keyPrefix = "";
 
diff --git a/lib/rules/operator-linebreak.js b/lib/rules/operator-linebreak.js
index 8253094c5..809da1fc8 100644
--- a/lib/rules/operator-linebreak.js
+++ b/lib/rules/operator-linebreak.js
@@ -87,7 +87,9 @@ module.exports = {
                 if (hasLinebreakBefore !== hasLinebreakAfter && desiredStyle !== "none") {
 
                     // If there is a comment before and after the operator, don't do a fix.
-                    if (sourceCode.getTokenBefore(operatorToken, { includeComments: true }) !== tokenBefore && sourceCode.getTokenAfter(operatorToken, { includeComments: true }) !== tokenAfter) {
+                    if (sourceCode.getTokenBefore(operatorToken, { includeComments: true }) !== tokenBefore &&
+                        sourceCode.getTokenAfter(operatorToken, { includeComments: true }) !== tokenAfter) {
+
                         return null;
                     }
 
diff --git a/lib/rules/sort-imports.js b/lib/rules/sort-imports.js
index 9f82a025a..be1605dc4 100644
--- a/lib/rules/sort-imports.js
+++ b/lib/rules/sort-imports.js
@@ -151,7 +151,8 @@ module.exports = {
                             message: "Member '{{memberName}}' of the import declaration should be sorted alphabetically.",
                             data: { memberName: importSpecifiers[firstUnsortedIndex].local.name },
                             fix(fixer) {
-                                if (importSpecifiers.some(specifier => sourceCode.getCommentsBefore(specifier).length || sourceCode.getCommentsAfter(specifier).length)) {
+                                if (importSpecifiers.some(specifier =>
+                                    sourceCode.getCommentsBefore(specifier).length || sourceCode.getCommentsAfter(specifier).length)) {
 
                                     // If there are comments in the ImportSpecifier list, don't rearrange the specifiers.
                                     return null;
diff --git a/lib/rules/valid-jsdoc.js b/lib/rules/valid-jsdoc.js
index d4ee4e073..ea60b115c 100644
--- a/lib/rules/valid-jsdoc.js
+++ b/lib/rules/valid-jsdoc.js
@@ -226,8 +226,10 @@ module.exports = {
         function checkJSDoc(node) {
             const jsdocNode = sourceCode.getJSDocComment(node),
                 functionData = fns.pop(),
-                params = Object.create(null);
+                params = Object.create(null),
+                paramsTags = [];
             let hasReturns = false,
+                returnsTag,
                 hasConstructor = false,
                 isInterface = false,
                 isOverride = false,
@@ -261,43 +263,13 @@ module.exports = {
                         case "param":
                         case "arg":
                         case "argument":
-                            if (!tag.type) {
-                                context.report({ node: jsdocNode, message: "Missing JSDoc parameter type for '{{name}}'.", data: { name: tag.name } });
-                            }
-
-                            if (!tag.description && requireParamDescription) {
-                                context.report({ node: jsdocNode, message: "Missing JSDoc parameter description for '{{name}}'.", data: { name: tag.name } });
-                            }
-
-                            if (params[tag.name]) {
-                                context.report({ node: jsdocNode, message: "Duplicate JSDoc parameter '{{name}}'.", data: { name: tag.name } });
-                            } else if (tag.name.indexOf(".") === -1) {
-                                params[tag.name] = 1;
-                            }
+                            paramsTags.push(tag);
                             break;
 
                         case "return":
                         case "returns":
                             hasReturns = true;
-
-                            if (!requireReturn && !functionData.returnPresent && (tag.type === null || !isValidReturnType(tag)) && !isAbstract) {
-                                context.report({
-                                    node: jsdocNode,
-                                    message: "Unexpected @{{title}} tag; function has no return statement.",
-                                    data: {
-                                        title: tag.title
-                                    }
-                                });
-                            } else {
-                                if (requireReturnType && !tag.type) {
-                                    context.report({ node: jsdocNode, message: "Missing JSDoc return type." });
-                                }
-
-                                if (!isValidReturnType(tag) && !tag.description && requireReturnDescription) {
-                                    context.report({ node: jsdocNode, message: "Missing JSDoc return description." });
-                                }
-                            }
-
+                            returnsTag = tag;
                             break;
 
                         case "constructor":
@@ -333,6 +305,40 @@ module.exports = {
                     }
                 });
 
+                paramsTags.forEach(param => {
+                    if (!param.type) {
+                        context.report({ node: jsdocNode, message: "Missing JSDoc parameter type for '{{name}}'.", data: { name: param.name } });
+                    }
+                    if (!param.description && requireParamDescription) {
+                        context.report({ node: jsdocNode, message: "Missing JSDoc parameter description for '{{name}}'.", data: { name: param.name } });
+                    }
+                    if (params[param.name]) {
+                        context.report({ node: jsdocNode, message: "Duplicate JSDoc parameter '{{name}}'.", data: { name: param.name } });
+                    } else if (param.name.indexOf(".") === -1) {
+                        params[param.name] = 1;
+                    }
+                });
+
+                if (hasReturns) {
+                    if (!requireReturn && !functionData.returnPresent && (returnsTag.type === null || !isValidReturnType(returnsTag)) && !isAbstract) {
+                        context.report({
+                            node: jsdocNode,
+                            message: "Unexpected @{{title}} tag; function has no return statement.",
+                            data: {
+                                title: returnsTag.title
+                            }
+                        });
+                    } else {
+                        if (requireReturnType && !returnsTag.type) {
+                            context.report({ node: jsdocNode, message: "Missing JSDoc return type." });
+                        }
+
+                        if (!isValidReturnType(returnsTag) && !returnsTag.description && requireReturnDescription) {
+                            context.report({ node: jsdocNode, message: "Missing JSDoc return description." });
+                        }
+                    }
+                }
+
                 // check for functions missing @returns
                 if (!isOverride && !hasReturns && !hasConstructor && !isInterface &&
                     node.parent.kind !== "get" && node.parent.kind !== "constructor" &&
diff --git a/package.json b/package.json
index 9bc6d9ed4..6db06e806 100644
--- a/package.json
+++ b/package.json
@@ -20,8 +20,7 @@
     "browserify": "node Makefile.js browserify",
     "perf": "node Makefile.js perf",
     "profile": "beefy tests/bench/bench.js --open -- -t brfs -t ./tests/bench/xform-rules.js -r espree",
-    "coveralls": "cat ./coverage/lcov.info | coveralls",
-    "check-commit": "node Makefile.js checkGitCommit"
+    "coveralls": "cat ./coverage/lcov.info | coveralls"
   },
   "files": [
     "LICENSE",
diff --git a/packages/eslint-config-eslint/default.yml b/packages/eslint-config-eslint/default.yml
index e83d76546..f901651e6 100644
--- a/packages/eslint-config-eslint/default.yml
+++ b/packages/eslint-config-eslint/default.yml
@@ -40,6 +40,13 @@ rules:
         beforeLineComment: true,
         afterLineComment: false
     }]
+    max-len: ["error", 160, {
+        "ignoreComments": true,
+        "ignoreUrls": true,
+        "ignoreStrings": true,
+        "ignoreTemplateLiterals": true,
+        "ignoreRegExpLiterals": true
+    }]
     max-statements-per-line: "error"
     new-cap: "error"
     new-parens: "error"
diff --git a/templates/issue-create.md.ejs b/templates/issue-create.md.ejs
deleted file mode 100644
index 71296ea5f..000000000
--- a/templates/issue-create.md.ejs
+++ /dev/null
@@ -1,8 +0,0 @@
-@<%= payload.sender.login %> Thanks for the issue! If you're reporting a bug, please be sure to include:
-
-1. The version of ESLint you are using (run `eslint -v`)
-2. What you did (the source code and ESLint configuration)
-3. The actual ESLint output complete with numbers
-4. What you expected to happen instead
-
-Requesting a new rule? Please see [Proposing a New Rule](https://eslint.org/docs/developer-guide/contributing/new-rules) for instructions.
diff --git a/templates/needs-info.md.ejs b/templates/needs-info.md.ejs
deleted file mode 100644
index d1eb6d4a5..000000000
--- a/templates/needs-info.md.ejs
+++ /dev/null
@@ -1,14 +0,0 @@
-Hi @<%= payload.issue.user.login %>, thanks for the issue. It looks like there's not enough information for us to know how to help you.
-
-If you're reporting a bug, please be sure to include:
-
-1. The version of ESLint you are using (run `eslint -v`)
-2. What you did (the source code and ESLint configuration)
-3. The actual ESLint output complete with numbers
-4. What you expected to happen instead
-
-Requesting a new rule? Please see [Proposing a New Rule](https://eslint.org/docs/developer-guide/contributing/new-rules) for instructions.
-
-Requesting a rule change? Please see [Proposing a Rule Change](https://eslint.org/docs/developer-guide/contributing/rule-changes) for instructions.
-
-If it's something else, please just provide as much additional information as possible. Thanks!
diff --git a/templates/pr-create.md.ejs b/templates/pr-create.md.ejs
deleted file mode 100644
index 1ff9e16b7..000000000
--- a/templates/pr-create.md.ejs
+++ /dev/null
@@ -1,39 +0,0 @@
-<%
-
-var FLAG_PATTERN = /^(Breaking|Build|Chore|Docs|Fix|New|Update|Upgrade):/,
-    ISSUE_REF_PATTERN = /\((fixes|refs) #\d+.*?\)$/;
-
-function isValidCommitFlag(log) {
-    var result = log.match(FLAG_PATTERN);
-    return !!result || log.indexOf("Revert \"") === 0;
-}
-
-var problems = [];
-
-// Check for one commit per pull request
-if (meta.commits) {
-    // get just the first line of the commit message
-    var log = meta.commits[0].commit.message.split(/\r?\n/g)[0];
-
-    if (!isValidCommitFlag(log)) {
-        problems.push("The commit summary needs to begin with a tag (such as `Fix:` or `Update:`). Please check out our [guide](https://eslint.org/docs/developer-guide/contributing/pull-requests#step-2-make-your-changes) for how to properly format your commit summary and [update](https://eslint.org/docs/developer-guide/contributing/pull-requests#updating-the-commit-message) it on this pull request.")
-    }
-
-    if (log.length > 72) {
-        problems.push("The commit summary must be 72 characters or shorter. Please check out our [guide](https://eslint.org/docs/developer-guide/contributing/pull-requests#step-2-make-your-changes) for how to properly format your commit summary and [update](https://eslint.org/docs/developer-guide/contributing/pull-requests#updating-the-commit-message) it on this pull request.");
-    }
-}
-
-if (problems.length) { %>
-Thanks for the pull request, @<%= payload.sender.login %>! I took a look to make sure it's ready for merging and found some changes are needed:
-
-<% problems.forEach(function(problem) { %>
-* <%- problem %>
-<% }); %>
-
-Can you please update the pull request to address these?
-
-(More information can be found in our [pull request guide](https://eslint.org/docs/developer-guide/contributing/pull-requests).)
-<% } else { %>
-LGTM
-<% } %>


Test patch:
diff --git a/tests/lib/cli.js b/tests/lib/cli.js
index b77cfcde7..8a8bc938a 100644
--- a/tests/lib/cli.js
+++ b/tests/lib/cli.js
@@ -101,6 +101,13 @@ describe("cli", () => {
             assert.strictEqual(result, 1);
         });
 
+        it("should not print debug info when passed the empty string as text", () => {
+            const result = cli.execute(["--stdin", "--no-eslintrc"], "");
+
+            assert.strictEqual(result, 0);
+            assert.isTrue(log.info.notCalled);
+        });
+
         it("should return no error when --ext .js2 is specified", () => {
             const filePath = getFixturePath("files");
             const result = cli.execute(`--ext .js2 ${filePath}`);
diff --git a/tests/lib/rules/multiline-comment-style.js b/tests/lib/rules/multiline-comment-style.js
index 9da55a995..7f0cb4250 100644
--- a/tests/lib/rules/multiline-comment-style.js
+++ b/tests/lib/rules/multiline-comment-style.js
@@ -151,6 +151,30 @@ ruleTester.run("multiline-comment-style", rule, {
             `,
             options: ["separate-lines"]
         },
+        {
+            code: `
+                // a comment
+
+                // another comment
+            `,
+            options: ["separate-lines"]
+        },
+        {
+            code: `
+                // a comment
+
+                // another comment
+            `,
+            options: ["bare-block"]
+        },
+        {
+            code: `
+                // a comment
+
+                // another comment
+            `,
+            options: ["starred-block"]
+        },
         {
             code: `
                 /* eslint semi: "error" */
@@ -230,6 +254,35 @@ ruleTester.run("multiline-comment-style", rule, {
             `,
             errors: [{ message: EXPECTED_BLOCK_ERROR, line: 2 }]
         },
+        {
+            code: `
+                //foo
+                ///bar
+            `,
+            output: null,
+            errors: [{ message: EXPECTED_BLOCK_ERROR, line: 2 }]
+        },
+        {
+            code: `
+                // foo
+                // bar
+
+                // baz
+                // qux
+            `,
+            output: `
+                /*
+                 * foo
+                 * bar
+                 */
+
+                /*
+                 * baz
+                 * qux
+                 */
+            `,
+            errors: [{ message: EXPECTED_BLOCK_ERROR, line: 2 }, { message: EXPECTED_BLOCK_ERROR, line: 5 }]
+        },
         {
             code: `
                 /* this block
diff --git a/tests/lib/rules/no-var.js b/tests/lib/rules/no-var.js
index 830104180..48511d825 100644
--- a/tests/lib/rules/no-var.js
+++ b/tests/lib/rules/no-var.js
@@ -21,13 +21,22 @@ const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
 ruleTester.run("no-var", rule, {
     valid: [
         "const JOE = 'schmoe';",
-        "let moo = 'car';"
+        "let moo = 'car';",
+        {
+            code: "const JOE = 'schmoe';",
+            parserOptions: { ecmaFeatures: { globalReturn: true } }
+        },
+        {
+            code: "let moo = 'car';",
+            parserOptions: { ecmaFeatures: { globalReturn: true } }
+        }
     ],
 
     invalid: [
         {
             code: "var foo = bar;",
             output: "let foo = bar;",
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 {
                     message: "Unexpected var, use let or const instead.",
@@ -38,6 +47,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "var foo = bar, toast = most;",
             output: "let foo = bar, toast = most;",
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 {
                     message: "Unexpected var, use let or const instead.",
@@ -48,6 +58,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "var foo = bar; let toast = most;",
             output: "let foo = bar; let toast = most;",
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 {
                     message: "Unexpected var, use let or const instead.",
@@ -58,6 +69,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "for (var a of b) { console.log(a); }",
             output: "for (let a of b) { console.log(a); }",
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 {
                     message: "Unexpected var, use let or const instead.",
@@ -68,6 +80,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "for (var a in b) { console.log(a); }",
             output: "for (let a in b) { console.log(a); }",
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 {
                     message: "Unexpected var, use let or const instead.",
@@ -78,6 +91,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "for (let a of b) { var c = 1; console.log(c); }",
             output: "for (let a of b) { let c = 1; console.log(c); }",
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 {
                     message: "Unexpected var, use let or const instead.",
@@ -88,6 +102,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "for (var i = 0; i < list.length; ++i) { foo(i) }",
             output: "for (let i = 0; i < list.length; ++i) { foo(i) }",
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 { message: "Unexpected var, use let or const instead.", type: "VariableDeclaration" }
             ]
@@ -95,6 +110,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "for (var i = 0, i = 0; false;);",
             output: null,
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 { message: "Unexpected var, use let or const instead.", type: "VariableDeclaration" }
             ]
@@ -102,6 +118,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "var i = 0; for (var i = 1; false;); console.log(i);",
             output: null,
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 { message: "Unexpected var, use let or const instead.", type: "VariableDeclaration" },
                 { message: "Unexpected var, use let or const instead.", type: "VariableDeclaration" }
@@ -112,6 +129,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "var a, b, c; var a;",
             output: null,
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead.",
                 "Unexpected var, use let or const instead."
@@ -120,6 +138,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "var a; if (b) { var a; }",
             output: null,
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead.",
                 "Unexpected var, use let or const instead."
@@ -128,6 +147,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "if (foo) { var a, b, c; } a;",
             output: null,
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead."
             ]
@@ -135,6 +155,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "for (var i = 0; i < 10; ++i) {} i;",
             output: null,
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead."
             ]
@@ -142,6 +163,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "for (var a in obj) {} a;",
             output: null,
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead."
             ]
@@ -149,6 +171,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "for (var a of list) {} a;",
             output: null,
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead."
             ]
@@ -156,6 +179,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "switch (a) { case 0: var b = 1 }",
             output: null,
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead."
             ]
@@ -165,6 +189,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "for (var a of b) { arr.push(() => a); }",
             output: null,
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead."
             ]
@@ -172,6 +197,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "for (let a of b) { var c; console.log(c); c = 'hello'; }",
             output: null,
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead."
             ]
@@ -181,6 +207,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "var a = a",
             output: null,
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead."
             ]
@@ -188,7 +215,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "var {a = a} = {}",
             output: null,
-            parserOptions: { ecmaVersion: 2015 },
+            parserOptions: { ecmaVersion: 2015, ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead."
             ]
@@ -196,7 +223,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "var {a = b, b} = {}",
             output: null,
-            parserOptions: { ecmaVersion: 2015 },
+            parserOptions: { ecmaVersion: 2015, ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead."
             ]
@@ -204,7 +231,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "var {a, b = a} = {}",
             output: "let {a, b = a} = {}",
-            parserOptions: { ecmaVersion: 2015 },
+            parserOptions: { ecmaVersion: 2015, ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead."
             ]
@@ -212,7 +239,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "var a = b, b = 1",
             output: null,
-            parserOptions: { ecmaVersion: 2015 },
+            parserOptions: { ecmaVersion: 2015, ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead."
             ]
@@ -220,7 +247,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "var a = b; var b = 1",
             output: "let a = b; var b = 1",
-            parserOptions: { ecmaVersion: 2015 },
+            parserOptions: { ecmaVersion: 2015, ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead.",
                 "Unexpected var, use let or const instead."
@@ -232,7 +259,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "function foo() { a } var a = 1; foo()",
             output: null,
-            parserOptions: { ecmaVersion: 2015 },
+            parserOptions: { ecmaVersion: 2015, ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead."
             ]
@@ -242,9 +269,33 @@ ruleTester.run("no-var", rule, {
         {
             code: "if (foo) var bar = 1;",
             output: null,
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 { message: "Unexpected var, use let or const instead.", type: "VariableDeclaration" }
             ]
+        },
+
+        // https://github.com/eslint/eslint/issues/9520
+        {
+            code: "var foo = 1",
+            output: null,
+            errors: ["Unexpected var, use let or const instead."]
+        },
+        {
+            code: "{ var foo = 1 }",
+            output: null,
+            errors: ["Unexpected var, use let or const instead."]
+        },
+        {
+            code: "if (true) { var foo = 1 }",
+            output: null,
+            errors: ["Unexpected var, use let or const instead."]
+        },
+        {
+            code: "var foo = 1",
+            output: "let foo = 1",
+            parserOptions: { sourceType: "module" },
+            errors: ["Unexpected var, use let or const instead."]
         }
     ]
 });
diff --git a/tests/lib/rules/object-property-newline.js b/tests/lib/rules/object-property-newline.js
index dea82a26a..350ecfb17 100644
--- a/tests/lib/rules/object-property-newline.js
+++ b/tests/lib/rules/object-property-newline.js
@@ -56,7 +56,10 @@ ruleTester.run("object-property-newline", rule, {
         { code: "foo({ bar() {}, baz });", options: [{ allowMultiplePropertiesPerLine: true }], parserOptions: { ecmaVersion: 6 } },
         { code: "foo({ [bar]: 'baz', baz })", options: [{ allowMultiplePropertiesPerLine: true }], parserOptions: { ecmaVersion: 6 } },
         { code: "foo({ 'k1': 'val1', k2: 'val2', ...{} });", options: [{ allowMultiplePropertiesPerLine: true }], parserOptions: { ecmaVersion: 6, ecmaFeatures: { experimentalObjectRestSpread: true } } },
-        { code: "foo({\n'k1': 'val1', k2: 'val2', ...{}\n});", options: [{ allowMultiplePropertiesPerLine: true }], parserOptions: { ecmaVersion: 6, ecmaFeatures: { experimentalObjectRestSpread: true } } }
+        { code: "foo({\n'k1': 'val1', k2: 'val2', ...{}\n});", options: [{ allowMultiplePropertiesPerLine: true }], parserOptions: { ecmaVersion: 6, ecmaFeatures: { experimentalObjectRestSpread: true } } },
+        { code: "var obj = {k1: ['foo', 'bar'], k2: 'val1', k3: 'val2'};", options: [{ allowMultiplePropertiesPerLine: true }] },
+        { code: "var obj = {\nk1: ['foo', 'bar'], k2: 'val1', k3: 'val2'\n};", options: [{ allowMultiplePropertiesPerLine: true }] },
+        { code: "var obj = {\nk1: 'val1', k2: {e1: 'foo', e2: 'bar'}, k3: 'val2'\n};", options: [{ allowMultiplePropertiesPerLine: true }] }
     ],
 
     invalid: [
@@ -110,6 +113,66 @@ ruleTester.run("object-property-newline", rule, {
                 }
             ]
         },
+        {
+            code: "var obj = {k1: ['foo', 'bar'], k2: 'val1'};",
+            output: "var obj = {k1: ['foo', 'bar'],\nk2: 'val1'};",
+            errors: [
+                {
+                    message: "Object properties must go on a new line.",
+                    type: "ObjectExpression",
+                    line: 1,
+                    column: 32
+                }
+            ]
+        },
+        {
+            code: "var obj = {k1: [\n'foo', 'bar'\n], k2: 'val1'};",
+            output: "var obj = {k1: [\n'foo', 'bar'\n],\nk2: 'val1'};",
+            errors: [
+                {
+                    message: "Object properties must go on a new line.",
+                    type: "ObjectExpression",
+                    line: 3,
+                    column: 4
+                }
+            ]
+        },
+        {
+            code: "var obj = {\nk1: 'val1', k2: {e1: 'foo', e2: 'bar'}, k3: 'val2'\n};",
+            output: "var obj = {\nk1: 'val1',\nk2: {e1: 'foo',\ne2: 'bar'},\nk3: 'val2'\n};",
+            errors: [
+                {
+                    message: "Object properties must go on a new line.",
+                    type: "ObjectExpression",
+                    line: 2,
+                    column: 13
+                },
+                {
+                    message: "Object properties must go on a new line.",
+                    type: "ObjectExpression",
+                    line: 2,
+                    column: 29
+                },
+                {
+                    message: "Object properties must go on a new line.",
+                    type: "ObjectExpression",
+                    line: 2,
+                    column: 41
+                }
+            ]
+        },
+        {
+            code: "var obj = {\nk1: 'val1',\nk2: {e1: 'foo', e2: 'bar'},\nk3: 'val2'\n};",
+            output: "var obj = {\nk1: 'val1',\nk2: {e1: 'foo',\ne2: 'bar'},\nk3: 'val2'\n};",
+            errors: [
+                {
+                    message: "Object properties must go on a new line.",
+                    type: "ObjectExpression",
+                    line: 3,
+                    column: 17
+                }
+            ]
+        },
         {
             code: "var obj = { k1: 'val1', [\nk2]: 'val2' };",
             output: "var obj = { k1: 'val1',\n[\nk2]: 'val2' };",
@@ -276,6 +339,30 @@ ruleTester.run("object-property-newline", rule, {
                 }
             ]
         },
+        {
+            code: "({ foo: 1 /* comment */, bar: 2 })",
+            output: "({ foo: 1 /* comment */,\nbar: 2 })",
+            errors: [
+                {
+                    message: "Object properties must go on a new line.",
+                    type: "ObjectExpression",
+                    line: 1,
+                    column: 26
+                }
+            ]
+        },
+        {
+            code: "({ foo: 1, /* comment */ bar: 2 })",
+            output: null, // not fixed due to comment
+            errors: [
+                {
+                    message: "Object properties must go on a new line.",
+                    type: "ObjectExpression",
+                    line: 1,
+                    column: 26
+                }
+            ]
+        },
 
         // allowMultiplePropertiesPerLine: true
         {
@@ -291,6 +378,51 @@ ruleTester.run("object-property-newline", rule, {
                 }
             ]
         },
+        {
+            code: "var obj = {k1: [\n'foo',\n'bar'\n], k2: 'val1'};",
+            output: "var obj = {k1: [\n'foo',\n'bar'\n],\nk2: 'val1'};",
+            options: [{ allowMultiplePropertiesPerLine: true }],
+            errors: [
+                {
+                    message: "Object properties must go on a new line if they aren't all on the same line.",
+                    type: "ObjectExpression",
+                    line: 4,
+                    column: 4
+                }
+            ]
+        },
+        {
+            code: "var obj = {k1: [\n'foo', 'bar'\n], k2: 'val1'};",
+            output: "var obj = {k1: [\n'foo', 'bar'\n],\nk2: 'val1'};",
+            options: [{ allowMultiplePropertiesPerLine: true }],
+            errors: [
+                {
+                    message: "Object properties must go on a new line if they aren't all on the same line.",
+                    type: "ObjectExpression",
+                    line: 3,
+                    column: 4
+                }
+            ]
+        },
+        {
+            code: "var obj = {\nk1: 'val1', k2: {\ne1: 'foo', e2: 'bar'\n}, k3: 'val2'\n};",
+            output: "var obj = {\nk1: 'val1',\nk2: {\ne1: 'foo', e2: 'bar'\n},\nk3: 'val2'\n};",
+            options: [{ allowMultiplePropertiesPerLine: true }],
+            errors: [
+                {
+                    message: "Object properties must go on a new line if they aren't all on the same line.",
+                    type: "ObjectExpression",
+                    line: 2,
+                    column: 13
+                },
+                {
+                    message: "Object properties must go on a new line if they aren't all on the same line.",
+                    type: "ObjectExpression",
+                    line: 4,
+                    column: 4
+                }
+            ]
+        },
         {
             code: "var obj = { [\nk1]: 'val1', k2: 'val2' };",
             output: "var obj = { [\nk1]: 'val1',\nk2: 'val2' };",
@@ -374,30 +506,6 @@ ruleTester.run("object-property-newline", rule, {
                     column: 13
                 }
             ]
-        },
-        {
-            code: "({ foo: 1 /* comment */, bar: 2 })",
-            output: "({ foo: 1 /* comment */,\nbar: 2 })",
-            errors: [
-                {
-                    message: "Object properties must go on a new line.",
-                    type: "ObjectExpression",
-                    line: 1,
-                    column: 26
-                }
-            ]
-        },
-        {
-            code: "({ foo: 1, /* comment */ bar: 2 })",
-            output: null, // not fixed due to comment
-            errors: [
-                {
-                    message: "Object properties must go on a new line.",
-                    type: "ObjectExpression",
-                    line: 1,
-                    column: 26
-                }
-            ]
         }
     ]
 });
diff --git a/tests/lib/rules/valid-jsdoc.js b/tests/lib/rules/valid-jsdoc.js
index e9519278a..54fea8d8f 100644
--- a/tests/lib/rules/valid-jsdoc.js
+++ b/tests/lib/rules/valid-jsdoc.js
@@ -499,6 +499,434 @@ ruleTester.run("valid-jsdoc", rule, {
             "function foo(){ throw new Error('Not Implemented'); }",
             options: [{ requireReturn: false }]
         },
+
+        // https://github.com/eslint/eslint/issues/9412 - different orders for jsodc tags
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @return {Number} desc\n" +
+            "* @constructor \n" +
+            "* @override\n" +
+            "* @abstract\n" +
+            "* @interface\n" +
+            "* @param {string} hi - desc\n" +
+            "*/\n" +
+            "function foo(hi){ return 1; }",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @returns {Number} desc\n" +
+            "* @class \n" +
+            "* @inheritdoc\n" +
+            "* @virtual\n" +
+            "* @interface\n" +
+            "* @param {string} hi - desc\n" +
+            "*/\n" +
+            "function foo(hi){ return 1; }",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @return {Number} desc\n" +
+            "* @constructor \n" +
+            "* @override\n" +
+            "* @abstract\n" +
+            "* @interface\n" +
+            "* @arg {string} hi - desc\n" +
+            "*/\n" +
+            "function foo(hi){ return 1; }",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @returns {Number} desc\n" +
+            "* @class \n" +
+            "* @inheritdoc\n" +
+            "* @virtual\n" +
+            "* @interface\n" +
+            "* @arg {string} hi - desc\n" +
+            "*/\n" +
+            "function foo(hi){ return 1; }",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @return {Number} desc\n" +
+            "* @constructor \n" +
+            "* @override\n" +
+            "* @abstract\n" +
+            "* @interface\n" +
+            "* @argument {string} hi - desc\n" +
+            "*/\n" +
+            "function foo(hi){ return 1; }",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @returns {Number} desc\n" +
+            "* @class \n" +
+            "* @inheritdoc\n" +
+            "* @virtual\n" +
+            "* @interface\n" +
+            "* @argument {string} hi - desc\n" +
+            "*/\n" +
+            "function foo(hi){ return 1; }",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @constructor \n" +
+            "* @override\n" +
+            "* @abstract\n" +
+            "* @interface\n" +
+            "* @param {string} hi - desc\n" +
+            "* @return {Number} desc\n" +
+            "*/\n" +
+            "function foo(hi){ return 1; }",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @class \n" +
+            "* @inheritdoc\n" +
+            "* @virtual\n" +
+            "* @interface\n" +
+            "* @arg {string} hi - desc\n" +
+            "* @return {Number} desc\n" +
+            "*/\n" +
+            "function foo(hi){ return 1; }",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @argument {string} hi - desc\n" +
+            "* @return {Number} desc\n" +
+            "*/\n" +
+            "function foo(hi){ return 1; }",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @constructor \n" +
+            "* @override\n" +
+            "* @abstract\n" +
+            "* @interface\n" +
+            "* @param {string} hi - desc\n" +
+            "* @returns {Number} desc\n" +
+            "*/\n" +
+            "function foo(hi){ return 1; }",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @class \n" +
+            "* @inheritdoc\n" +
+            "* @virtual\n" +
+            "* @interface\n" +
+            "* @arg {string} hi - desc\n" +
+            "* @returns {Number} desc\n" +
+            "*/\n" +
+            "function foo(hi){ return 1; }",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @argument {string} hi - desc\n" +
+            "* @returns {Number} desc\n" +
+            "*/\n" +
+            "function foo(hi){ return 1; }",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @override\n" +
+            "* @abstract\n" +
+            "* @interface\n" +
+            "* @param {string} hi - desc\n" +
+            "* @return {Number} desc\n" +
+            "* @constructor\n" +
+            "*/\n" +
+            "function foo(hi){ return 1; }",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @inheritdoc\n" +
+            "* @virtual\n" +
+            "* @interface\n" +
+            "* @arg {string} hi - desc\n" +
+            "* @returns {Number} desc\n" +
+            "* @constructor\n" +
+            "*/\n" +
+            "function foo(hi){ return 1; }",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @argument {string} hi - desc\n" +
+            "* @constructor\n" +
+            "*/\n" +
+            "function foo(hi){}",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @override\n" +
+            "* @abstract\n" +
+            "* @interface\n" +
+            "* @param {string} hi - desc\n" +
+            "* @return {Number} desc\n" +
+            "* @class\n" +
+            "*/\n" +
+            "function foo(hi){ return 1; }",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @inheritdoc\n" +
+            "* @virtual\n" +
+            "* @interface\n" +
+            "* @arg {string} hi - desc\n" +
+            "* @returns {Number} desc\n" +
+            "* @class\n" +
+            "*/\n" +
+            "function foo(hi){ return 1; }",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @argument {string} hi - desc\n" +
+            "* @class \n" +
+            "*/\n" +
+            "function foo(hi){}",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @abstract\n" +
+            "* @interface\n" +
+            "* @param {string} hi - desc\n" +
+            "* @return {Number} desc\n" +
+            "* @constructor\n" +
+            "* @override\n" +
+            "*/\n" +
+            "function foo(hi){ return 1; }",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @virtual\n" +
+            "* @interface\n" +
+            "* @arg {string} hi - desc\n" +
+            "* @returns {Number} desc\n" +
+            "* @class\n" +
+            "* @override\n" +
+            "*/\n" +
+            "function foo(hi){ return 1; }",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @argument {string} hi - desc\n" +
+            "* @override\n" +
+            "*/\n" +
+            "function foo(hi){}",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @abstract\n" +
+            "* @interface\n" +
+            "* @param {string} hi - desc\n" +
+            "* @return {Number} desc\n" +
+            "* @constructor\n" +
+            "* @inheritdoc\n" +
+            "*/\n" +
+            "function foo(hi){ return 1; }",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @virtual\n" +
+            "* @interface\n" +
+            "* @arg {string} hi - desc\n" +
+            "* @returns {Number} desc\n" +
+            "* @class\n" +
+            "* @inheritdoc\n" +
+            "*/\n" +
+            "function foo(hi){ return 1; }",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @argument {string} hi - desc\n" +
+            "* @inheritdoc\n" +
+            "*/\n" +
+            "function foo(hi){}",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @interface\n" +
+            "* @param {string} hi - desc\n" +
+            "* @return {Number} desc\n" +
+            "* @constructor\n" +
+            "* @override\n" +
+            "* @abstract\n" +
+            "*/\n" +
+            "function foo(hi){ return 1; }",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @interface\n" +
+            "* @arg {string} hi - desc\n" +
+            "* @returns {Number} desc\n" +
+            "* @class\n" +
+            "* @override\n" +
+            "* @abstract\n" +
+            "*/\n" +
+            "function foo(hi){ return 1; }",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @argument {string} hi - desc\n" +
+            "* @abstract\n" +
+            "*/\n" +
+            "function foo(hi){}",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @interface\n" +
+            "* @param {string} hi - desc\n" +
+            "* @return {Number} desc\n" +
+            "* @constructor\n" +
+            "* @override\n" +
+            "* @virtual\n" +
+            "*/\n" +
+            "function foo(hi){ return 1; }",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @interface\n" +
+            "* @arg {string} hi - desc\n" +
+            "* @returns {Number} desc\n" +
+            "* @class\n" +
+            "* @override\n" +
+            "* @virtual\n" +
+            "*/\n" +
+            "function foo(hi){ return 1; }",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @argument {string} hi - desc\n" +
+            "* @virtual\n" +
+            "*/\n" +
+            "function foo(hi){}",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @param {string} hi - desc\n" +
+            "* @return {Number} desc\n" +
+            "* @constructor \n" +
+            "* @override\n" +
+            "* @abstract\n" +
+            "* @interface\n" +
+            "*/\n" +
+            "function foo(hi){ return 1; }",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @arg {string} hi - desc\n" +
+            "* @returns {Number} desc\n" +
+            "* @class\n" +
+            "* @override\n" +
+            "* @virtual\n" +
+            "* @interface\n" +
+            "*/\n" +
+            "function foo(hi){ return 1; }",
+            options: [{ requireReturn: false }]
+        },
+        {
+            code:
+            "/**\n" +
+            "* Description\n" +
+            "* @argument {string} hi - desc\n" +
+            "* @interface\n" +
+            "*/\n" +
+            "function foo(hi){}",
+            options: [{ requireReturn: false }]
+        },
         {
             code:
             "/**\n" +
diff --git a/tests/templates/pr-create.md.ejs.js b/tests/templates/pr-create.md.ejs.js
deleted file mode 100644
index 974fbf188..000000000
--- a/tests/templates/pr-create.md.ejs.js
+++ /dev/null
@@ -1,160 +0,0 @@
-/**
- * @fileoverview Tests for pr-create.md.ejs
- * @author Nicholas C. Zakas
- */
-
-"use strict";
-
-//------------------------------------------------------------------------------
-// Requirements
-//------------------------------------------------------------------------------
-
-const assert = require("chai").assert,
-    fs = require("fs"),
-    path = require("path"),
-    ejs = require("ejs");
-
-//------------------------------------------------------------------------------
-// Data
-//------------------------------------------------------------------------------
-
-const TEMPLATE_TEXT = fs.readFileSync(path.resolve(__dirname, "../../templates/pr-create.md.ejs"), "utf8");
-
-//------------------------------------------------------------------------------
-// Tests
-//------------------------------------------------------------------------------
-
-describe("pr-create.md.ejs", () => {
-
-    it("should say LGTM when there are no problems with the pull request", () => {
-        const result = ejs.render(TEMPLATE_TEXT, {
-            payload: {
-                sender: {
-                    login: "nzakas"
-                },
-                commits: 1
-            },
-            meta: {}
-        });
-
-        assert.strictEqual(result.trim(), "LGTM");
-    });
-
-    it("should mention commit message format when there's one commit and an invalid commit message is found", () => {
-        const result = ejs.render(TEMPLATE_TEXT, {
-            payload: {
-                sender: {
-                    login: "nzakas"
-                },
-                commits: 1
-            },
-            meta: {
-                cla: true,
-                commits: [
-                    {
-                        commit: {
-                            message: "Foo bar"
-                        }
-                    }
-                ]
-            }
-        });
-
-        assert.ok(result.indexOf("begin with a tag") > -1);
-    });
-
-    it("should mention commit message length when there's a message longer than 72 characters", () => {
-        const result = ejs.render(TEMPLATE_TEXT, {
-            payload: {
-                sender: {
-                    login: "nzakas"
-                },
-                commits: 1
-            },
-            meta: {
-                cla: true,
-                commits: [
-                    {
-                        commit: {
-                            message: "Fix:56789012345678901234567890123456789012345678901234567890(fixes #9012)"
-                        }
-                    }
-                ]
-            }
-        });
-
-        assert.ok(result.indexOf("72 characters") > -1);
-    });
-
-    it("should not mention commit message length when there's a multi-line message with first line not over 72 characters", () => {
-        const result = ejs.render(TEMPLATE_TEXT, {
-            payload: {
-                sender: {
-                    login: "nzakas"
-                },
-                commits: 1
-            },
-            meta: {
-                cla: true,
-                commits: [
-                    {
-                        commit: {
-                            message: "Fix:56789012345678901234567890123456789012345678901234567890(fixes #901)\r\n1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
-                        }
-                    }
-                ]
-            }
-        });
-
-        assert.strictEqual(result.trim(), "LGTM");
-    });
-
-    it("should not mention missing issue when there's one documentation commit", () => {
-        const result = ejs.render(TEMPLATE_TEXT, {
-            payload: {
-                sender: {
-                    login: "nzakas"
-                },
-                commits: 1
-            },
-            meta: {
-                cla: true,
-                commits: [
-                    {
-                        commit: {
-                            message: "Docs: Foo bar"
-                        }
-                    }
-                ]
-            }
-        });
-
-        assert.strictEqual(result.trim(), "LGTM");
-    });
-
-    ["Breaking", "Build", "Chore", "Docs", "Fix", "New", "Update", "Upgrade"].forEach(type => {
-        it(`should not mention missing issue or length check when there's one ${type} commit`, () => {
-            const result = ejs.render(TEMPLATE_TEXT, {
-                payload: {
-                    sender: {
-                        login: "nzakas"
-                    },
-                    commits: 1
-                },
-                meta: {
-                    cla: true,
-                    commits: [
-                        {
-                            commit: {
-                                message: `${type}: Foo bar (fixes #1234)\nSome really long string. abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz`
-                            }
-                        }
-                    ]
-                }
-            });
-
-            assert.strictEqual(result.trim(), "LGTM");
-        });
-    });
-
-});