Repository: eslint/eslint (js)

Issue:
Stop reporting warning as errors when using tap reporter
<!--
    ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).

    This template is for requesting a change that is not a bug fix, rule change, or new rule. If you are here for another reason, please see below:

    1. To report a bug: https://eslint.org/docs/developer-guide/contributing/reporting-bugs
    2. To request a rule change: https://eslint.org/docs/developer-guide/contributing/rule-changes
    3. To propose a new rule: https://eslint.org/docs/developer-guide/contributing/new-rules
    4. If you have any questions, please stop by our chatroom: https://gitter.im/eslint/eslint

    Note that leaving sections blank will make it difficult for us to troubleshoot and we may have to close the issue.
-->

**The version of ESLint you are using.**
2.7.0

**The problem you want to solve.**
I am a sass-lint user (which relies on eslint-formaters)
When using the tap formatter, all messages are flagged as `not ok` no matter their severity. Messages with severity of 1 should be flagged as `ok` and should contain the warning message. I feel like it's odd to have a failing test result despite all tests are passing but containing some warnings.
However, this seems to be the expected behavior according to tests written in the project.

* Already reported here but closed because of inactivity: https://github.com/eslint/eslint/issues/6916

**Your take on the correct solution to problem.**
The issue is located in this file: https://github.com/eslint/eslint/blob/master/lib/formatters/tap.js#L53
I think it would be a good think for iterate on each message and flag the "message key" as "not ok" if a 
severity of 2 is found.

**Are you willing to submit a pull request to implement this change?**
Definitely, I just wanted to be sure this actual problem was not something "by design"

Thanks!

Pull request:
Fix: Manage severity of 1 with TAP reporter (fixes #11110)
<!--
    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)**

[ ] Documentation update
[X] 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)**
As reported in #11110, result with severity of 1 (ie. warning) were reported as errors (not ok)
This will allow:
- a result with one or many messages and all of them are of severity of 1 to be `ok`
- a result with many message with both severity of 1 and 2 to be still `not ok`

**Is there anything you'd like reviewers to focus on?**
Nothing!



Patch:
diff --git a/.eslintrc.js b/.eslintrc.js
index 22332c389..780368769 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -21,6 +21,7 @@ module.exports = {
         "eslint-plugin/prefer-output-null": "error",
         "eslint-plugin/prefer-placeholders": "error",
         "eslint-plugin/report-message-format": ["error", "[^a-z].*\\.$"],
+        "eslint-plugin/require-meta-type": "error",
         "eslint-plugin/test-case-property-ordering": "error",
         "eslint-plugin/test-case-shorthand-strings": "error",
         "rulesdir/multiline-comment-style": "error"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index eb63794e1..256f7b68f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,11 @@
+v5.12.0 - January 4, 2019
+
+* [`0d91e7d`](https://github.com/eslint/eslint/commit/0d91e7d28e5eba79a6032165cdef5d4549d26462) Update: Add sort-imports ignoreDeclarationSort (fixes #11019) (#11040) (Remco Haszing)
+* [`f92d6f0`](https://github.com/eslint/eslint/commit/f92d6f05c4dcd4a3a0616871e10b31edae9dfad5) Build: Add karma-chrome-launcher support (#11027) (薛定谔的猫)
+* [`166853d`](https://github.com/eslint/eslint/commit/166853d9c59db493f0b1bb68a67ad868662a4205) Upgrade: eslint-plugin-eslint-plugin@2.0.1 (#11220) (薛定谔的猫)
+* [`bfff77a`](https://github.com/eslint/eslint/commit/bfff77ad4eaa02e2e62481c986634df38d5db6e5) Fix: no-param-reassign parameter in ternary operator (fixes #11236) (#11239) (周昊宇)
+* [`258b654`](https://github.com/eslint/eslint/commit/258b6541f61dc3a9ae64e200680766a11c3dd316) Upgrade: require-uncached renamed to import-fresh (#11066) (薛定谔的猫)
+
 v5.11.1 - December 26, 2018
 
 * [`de79f10`](https://github.com/eslint/eslint/commit/de79f1026b7035f0296d7876f1db64f225cca1b8) Fix: handle optional catch bindings in no-useless-catch (#11205) (Colin Ihrig)
diff --git a/README.md b/README.md
index 65ee43400..cba920372 100644
--- a/README.md
+++ b/README.md
@@ -133,7 +133,7 @@ If you are trying to run locally:
 * Make sure your plugins (and ESLint) are both in your project's `package.json` as devDependencies (or dependencies, if your project uses ESLint at runtime).
 * Make sure you have run `npm install` and all your dependencies are installed.
 
-In all cases, make sure your plugins' peerDependencies have been installed as well. You can use `npm view eslint-plugin-myplugin peerDepencies` to see what peer dependencies `eslint-plugin-myplugin` has.
+In all cases, make sure your plugins' peerDependencies have been installed as well. You can use `npm view eslint-plugin-myplugin peerDependencies` to see what peer dependencies `eslint-plugin-myplugin` has.
 
 ### Does ESLint support JSX?
 
diff --git a/docs/developer-guide/working-with-custom-formatters.md b/docs/developer-guide/working-with-custom-formatters.md
index fe4c91464..58fe55936 100644
--- a/docs/developer-guide/working-with-custom-formatters.md
+++ b/docs/developer-guide/working-with-custom-formatters.md
@@ -1,25 +1,49 @@
 # Working with Custom Formatters
 
-Writing an ESLint custom formatter is simple. All that is needed is a module that exports a function that will receive the results from the execution of ESLint.
+While ESLint has some built-in formatters available to format the linting results, it's also possible to create and distribute your own custom formatters. You can include custom formatters in your project directly or create an npm package to distribute them separately.
 
-The simplest formatter will be something like:
+Each formatter is just a function that receives a `results` object and returns a string. For example, the following is how the `json` built-in formatter is implemented:
 
-```javascript
+```js
 //my-awesome-formatter.js
 module.exports = function(results) {
     return JSON.stringify(results, null, 2);
 };
 ```
 
-And to run `eslint` with this custom formatter:
+To run ESLint with this formatter, you can use the `-f` (or `--formatter`) command line flag:
 
 ```bash
-eslint -f './my-awesome-formatter.js' src/
+eslint -f ./my-awesome-formatter.js src/
 ```
 
-The output of the previous command will be something like this
+In order to use a local file as a custom formatter, you must begin the filename with a dot (such as `./my-awesome-formatter.js` or `../formatters/my-awesome-formatter.js`).
 
-```javascript
+## Packaging the Custom Formatter
+
+Custom formatters can also be distributed through npm packages. To do so, create an npm package with a name in the format of `eslint-formatter-*`, where `*` is the name of your formatter (such as `eslint-formatter-awesome`). Projects should then install the package and can use the custom formatter with the `-f` (or `--formatter`) flag like this:
+
+```bash
+eslint -f awesome src/
+```
+
+Because ESLint knows to look for packages beginning with `eslint-formatter-` when the specified formatter doesn't begin with a dot, there is no need to type `eslint-formatter-` when using a packaged custom formatter.
+
+Tips for `package.json`:
+
+* The `main` entry should be the JavaScript file implementing your custom formatter.
+* Add these `keywords` to help users find your formatter:
+    * `"eslint"`
+    * `"eslint-formatter"`
+    * `"eslintformatter"`
+
+See all [formatters on npm](https://www.npmjs.com/search?q=eslint-formatter);
+
+## The `results` Object
+
+The `results` object passed into a formatter is an array of objects containing the lint results for individual files. Here's some example output:
+
+```js
 [
     {
         filePath: "path/to/file.js",
@@ -56,30 +80,28 @@ The output of the previous command will be something like this
         fixableErrorCount: 0,
         fixableWarningCount: 0
     }
-];
+]
 ```
 
-As you can see the argument passed to the custom formatter function is just a list of results objects.
-
-## Description of the results
+### The `result` Object
 
-### the result object
+<!-- This section is copied from the "Node.js API" page. Changes to this section should
+also be manually applied to that page. -->
 
-You will receive a result object from each file `eslint` validates, each one of them containing
-the list of messages for `errors` and/or `warnings`.
+Each object in the `results` array is a `result` object. Each `result` object contains the path of the file that was linted and information about linting issues that were encountered. Here are the properties available on each `result` object:
 
-The following are the fields of the result object:
-
-*   **filePath**: The path to the file relative to the current working directory (the path from which ESLint was executed).
-*   **messages**: An array of message objects. See below for more info about messages.
+*   **filePath**: The absolute path to the file that was linted.
+*   **messages**: An array of `message` objects. See below for more info about messages.
 *   **errorCount**: The number of errors for the given file.
 *   **warningCount**: The number of warnings for the given file.
 *   **source**: The source code for the given file. This property is omitted if this file has no errors/warnings or if the `output` property is present.
 *   **output**: The source code for the given file with as many fixes applied as possible. This property is omitted if no fix is available.
 
-### The message object
+### The `message` Object
+
+Each `message` object contains information about the ESLint rule that was triggered by some source code. The properties available on each `message` object are:
 
-*   **ruleId**: the id of the rule that produced the error or warning.
+*   **ruleId**: the ID of the rule that produced the error or warning.
 *   **severity**: the severity of the failure, `1` for warnings and `2` for errors.
 *   **message**: the human readable description of the error.
 *   **line**: the line where the issue is located.
@@ -121,7 +143,7 @@ module.exports = function(results) {
 Running `eslint` with the previous custom formatter,
 
 ```bash
-eslint -f './my-awesome-formatter.js' src/
+eslint -f ./my-awesome-formatter.js src/
 ```
 
 Will produce the following output:
@@ -193,7 +215,7 @@ module.exports = function(results) {
 So running `eslint` with this custom formatter:
 
 ```bash
-eslint -f './my-awesome-formatter.js' src/
+eslint -f ./my-awesome-formatter.js src/
 ```
 
 The output will be
@@ -213,13 +235,15 @@ warning no-unused-vars
   src/configs/clean.js:3:6
 ```
 
-## Passing arguments to formatters:
+## Passing Arguments to Formatters
 
-### Using environment variables:
+While custom formatter do not receive arguments in addition to the results object, it is possible to pass additional data into formatters.
 
-Let's say we want to show only the messages that are actual errors and discard the warnings.
+## Using Environment Variables
 
-```javascript
+Custom formatters have access to environment variables and so can change their behavior based on environment variable data. Here's an example that uses a `AF_SKIP_WARNINGS` environment variable to determine whether or not to show warnings in the results:
+
+```js
 module.exports = function(results) {
     var skipWarnings = process.env.AF_SKIP_WARNINGS === "true"; //af stands for awesome-formatter
 
@@ -278,13 +302,13 @@ module.exports = function(results) {
 };
 ```
 
-So running `eslint` with this custom formatter:
+You would run ESLint with this custom formatter and an environment variable set like this:
 
 ```bash
-AF_SKIP_WARNINGS=true eslint -f './my-awesome-formatter.js' src/
+AF_SKIP_WARNINGS=true eslint -f ./my-awesome-formatter.js src/
 ```
 
-The output will not print the warnings
+The output would be:
 
 ```bash
 error space-infix-ops
@@ -294,24 +318,21 @@ error semi
   src/configs/bundler.js:6:10
 ```
 
-### Outputting to a standard format for other programs to consume
 
-You can use ESLint's built-in JSON formatter first, and pipe the output to another program that accepts JSON linter results.
+### Complex Argument Passing
+
+If you find the custom formatter pattern doesn't provide enough options for the way you'd like to format ESLint results, the best option is to use ESLint's built-in [JSON formatter](https://eslint.org/docs/user-guide/formatters/) and pipe the output to a second program. For example:
 
 ```bash
-eslint -f json src/ | your-program-that-reads-JSON
+eslint -f json src/ | your-program-that-reads-JSON --option
 ```
 
-You can read more about the built-in JSON formatter [here](https://eslint.org/docs/user-guide/formatters/).
+In this example, the `your-program-that-reads-json` program can accept the raw JSON of ESLint results and process it before outputting its own format of the results. You can pass as many command line arguments to that program as are necessary to customize the output.
 
-## Final words
+## Note: Formatting for Terminals
 
-More complex formatters could be written by grouping differently the errors and warnings and/or grouping the data by the ruleIds.
-
-When printing the files a recommended format will be something like this:
+Modern terminals like [iTerm2](https://www.iterm2.com/) or [Guake](http://guake-project.org/) expect a specific results format to automatically open filenames when they are clicked. Most terminals support this format for that purpose:
 
 ```bash
 file:line:column
 ```
-
-Since that allows modern fancy terminals (like [iTerm2](https://www.iterm2.com/) or [Guake](http://guake-project.org/)) to make them link to files that open in your favorite text editor.
diff --git a/docs/rules/sort-imports.md b/docs/rules/sort-imports.md
index d37527938..f6fd04f06 100644
--- a/docs/rules/sort-imports.md
+++ b/docs/rules/sort-imports.md
@@ -34,6 +34,7 @@ The `--fix` option on the command line automatically fixes some problems reporte
 This rule accepts an object with its properties as
 
 * `ignoreCase` (default: `false`)
+* `ignoreDeclarationSort` (default: `false`)
 * `ignoreMemberSort` (default: `false`)
 * `memberSyntaxSortOrder` (default: `["none", "all", "multiple", "single"]`); all 4 items must be present in the array, but you can change the order:
     * `none` = import module without exported bindings.
@@ -47,6 +48,7 @@ Default option settings are:
 {
     "sort-imports": ["error", {
         "ignoreCase": false,
+        "ignoreDeclarationSort": false,
         "ignoreMemberSort": false,
         "memberSyntaxSortOrder": ["none", "all", "multiple", "single"]
     }]
@@ -136,6 +138,34 @@ import c from 'baz.js';
 
 Default is `false`.
 
+### `ignoreDeclarationSort`
+
+Ignores the sorting of import declaration statements.
+
+Examples of **incorrect** code for this rule with the default `{ "ignoreDeclarationSort": false }` option:
+
+```js
+/*eslint sort-imports: ["error", { "ignoreDeclarationSort": false }]*/
+import b from 'foo.js'
+import a from 'bar.js'
+```
+
+Examples of **correct** code for this rule with the `{ "ignoreDeclarationSort": true }` option:
+
+```js
+/*eslint sort-imports: ["error", { "ignoreDeclarationSort": true }]*/
+import a from 'foo.js'
+import b from 'bar.js'
+```
+
+```js
+/*eslint sort-imports: ["error", { "ignoreDeclarationSort": true }]*/
+import b from 'foo.js'
+import a from 'bar.js'
+```
+
+Default is `false`.
+
 ### `ignoreMemberSort`
 
 Ignores the member sorting within a `multiple` member import declaration.
diff --git a/docs/user-guide/getting-started.md b/docs/user-guide/getting-started.md
index 4b98eb075..2e6e6617a 100644
--- a/docs/user-guide/getting-started.md
+++ b/docs/user-guide/getting-started.md
@@ -37,6 +37,14 @@ After that, you can run ESLint in your project's root directory like this:
 $ ./node_modules/.bin/eslint yourfile.js
 ```
 
+Instead of navigating to `./node_modules/.bin/` you may also use `npx` to run `eslint`:
+
+```
+$ npx eslint
+```
+
+**Note:** If ESLint wasn't manually installed (via `npm`), `npx` will install `eslint` to a temporary directory and execute it.
+
 Any plugins or shareable configs that you use must also be installed locally to work with a locally-installed ESLint.
 
 ### Global Installation and Usage
diff --git a/karma.conf.js b/karma.conf.js
index 0ffab8bc5..e8a027e54 100644
--- a/karma.conf.js
+++ b/karma.conf.js
@@ -1,5 +1,7 @@
 "use strict";
 
+process.env.CHROME_BIN = require("puppeteer").executablePath();
+
 module.exports = function(config) {
     config.set({
 
@@ -67,8 +69,13 @@ module.exports = function(config) {
 
         // start these browsers
         // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
-        browsers: ["PhantomJS"],
-
+        browsers: ["HeadlessChrome"],
+        customLaunchers: {
+          HeadlessChrome: {
+            base: 'ChromeHeadless',
+            flags: [ '--no-sandbox', ],
+             },
+            },
 
         // Continuous Integration mode
         // if true, Karma captures browsers, runs the tests and exits
diff --git a/lib/formatters/tap.js b/lib/formatters/tap.js
index 9651a2bcf..354872a0c 100644
--- a/lib/formatters/tap.js
+++ b/lib/formatters/tap.js
@@ -20,7 +20,6 @@ function getMessageType(message) {
         return "error";
     }
     return "warning";
-
 }
 
 /**
@@ -50,12 +49,11 @@ module.exports = function(results) {
         let diagnostics = {};
 
         if (messages.length > 0) {
-            testResult = "not ok";
-
             messages.forEach(message => {
+                const severity = getMessageType(message);
                 const diagnostic = {
                     message: message.message,
-                    severity: getMessageType(message),
+                    severity,
                     data: {
                         line: message.line || 0,
                         column: message.column || 0,
@@ -63,6 +61,11 @@ module.exports = function(results) {
                     }
                 };
 
+                // This ensures a warning message is not flagged as error
+                if (severity === "error") {
+                    testResult = "not ok";
+                }
+
                 /*
                  * If we have multiple messages place them under a messages key
                  * The first error will be logged as message key
diff --git a/lib/rules/block-spacing.js b/lib/rules/block-spacing.js
index 6496f8596..864bfc0c5 100644
--- a/lib/rules/block-spacing.js
+++ b/lib/rules/block-spacing.js
@@ -29,8 +29,8 @@ module.exports = {
         ],
 
         messages: {
-            missing: "Requires a space {{location}} '{{token}}'",
-            extra: "Unexpected space(s) {{location}} '{{token}}'"
+            missing: "Requires a space {{location}} '{{token}}'.",
+            extra: "Unexpected space(s) {{location}} '{{token}}'."
         }
     },
 
diff --git a/lib/rules/capitalized-comments.js b/lib/rules/capitalized-comments.js
index 86427ba7a..7947833b2 100644
--- a/lib/rules/capitalized-comments.js
+++ b/lib/rules/capitalized-comments.js
@@ -137,8 +137,8 @@ module.exports = {
         ],
 
         messages: {
-            unexpectedLowercaseComment: "Comments should not begin with a lowercase character",
-            unexpectedUppercaseComment: "Comments should not begin with an uppercase character"
+            unexpectedLowercaseComment: "Comments should not begin with a lowercase character.",
+            unexpectedUppercaseComment: "Comments should not begin with an uppercase character."
         }
     },
 
diff --git a/lib/rules/func-name-matching.js b/lib/rules/func-name-matching.js
index f14c998dc..5560c6920 100644
--- a/lib/rules/func-name-matching.js
+++ b/lib/rules/func-name-matching.js
@@ -92,10 +92,10 @@ module.exports = {
         },
 
         messages: {
-            matchProperty: "Function name `{{funcName}}` should match property name `{{name}}`",
-            matchVariable: "Function name `{{funcName}}` should match variable name `{{name}}`",
-            notMatchProperty: "Function name `{{funcName}}` should not match property name `{{name}}`",
-            notMatchVariable: "Function name `{{funcName}}` should not match variable name `{{name}}`"
+            matchProperty: "Function name `{{funcName}}` should match property name `{{name}}`.",
+            matchVariable: "Function name `{{funcName}}` should match variable name `{{name}}`.",
+            notMatchProperty: "Function name `{{funcName}}` should not match property name `{{name}}`.",
+            notMatchVariable: "Function name `{{funcName}}` should not match variable name `{{name}}`."
         }
     },
 
diff --git a/lib/rules/max-classes-per-file.js b/lib/rules/max-classes-per-file.js
index 3193a731c..ae7be904f 100644
--- a/lib/rules/max-classes-per-file.js
+++ b/lib/rules/max-classes-per-file.js
@@ -32,7 +32,7 @@ module.exports = {
         ],
 
         messages: {
-            maximumExceeded: "Number of classes per file must not exceed {{ max }}"
+            maximumExceeded: "Number of classes per file must not exceed {{ max }}."
         }
     },
     create(context) {
diff --git a/lib/rules/no-param-reassign.js b/lib/rules/no-param-reassign.js
index 243bb6412..349345c14 100644
--- a/lib/rules/no-param-reassign.js
+++ b/lib/rules/no-param-reassign.js
@@ -107,6 +107,14 @@ module.exports = {
 
                         break;
 
+                    // EXCLUDES: e.g. (foo ? a : b).c = bar;
+                    case "ConditionalExpression":
+                        if (parent.test === node) {
+                            return false;
+                        }
+
+                        break;
+
                     // no default
                 }
 
diff --git a/lib/rules/prefer-object-spread.js b/lib/rules/prefer-object-spread.js
index a8dac696b..4d724339d 100644
--- a/lib/rules/prefer-object-spread.js
+++ b/lib/rules/prefer-object-spread.js
@@ -226,8 +226,8 @@ module.exports = {
         fixable: "code",
 
         messages: {
-            useSpreadMessage: "Use an object spread instead of `Object.assign` eg: `{ ...foo }`",
-            useLiteralMessage: "Use an object literal instead of `Object.assign`. eg: `{ foo: bar }`"
+            useSpreadMessage: "Use an object spread instead of `Object.assign` eg: `{ ...foo }`.",
+            useLiteralMessage: "Use an object literal instead of `Object.assign`. eg: `{ foo: bar }`."
         }
     },
 
diff --git a/lib/rules/sort-imports.js b/lib/rules/sort-imports.js
index 76997cc73..1c0d13404 100644
--- a/lib/rules/sort-imports.js
+++ b/lib/rules/sort-imports.js
@@ -36,6 +36,9 @@ module.exports = {
                         minItems: 4,
                         maxItems: 4
                     },
+                    ignoreDeclarationSort: {
+                        type: "boolean"
+                    },
                     ignoreMemberSort: {
                         type: "boolean"
                     }
@@ -51,6 +54,7 @@ module.exports = {
 
         const configuration = context.options[0] || {},
             ignoreCase = configuration.ignoreCase || false,
+            ignoreDeclarationSort = configuration.ignoreDeclarationSort || false,
             ignoreMemberSort = configuration.ignoreMemberSort || false,
             memberSyntaxSortOrder = configuration.memberSyntaxSortOrder || ["none", "all", "multiple", "single"],
             sourceCode = context.getSourceCode();
@@ -105,44 +109,48 @@ module.exports = {
 
         return {
             ImportDeclaration(node) {
-                if (previousDeclaration) {
-                    const currentMemberSyntaxGroupIndex = getMemberParameterGroupIndex(node),
-                        previousMemberSyntaxGroupIndex = getMemberParameterGroupIndex(previousDeclaration);
-                    let currentLocalMemberName = getFirstLocalMemberName(node),
-                        previousLocalMemberName = getFirstLocalMemberName(previousDeclaration);
-
-                    if (ignoreCase) {
-                        previousLocalMemberName = previousLocalMemberName && previousLocalMemberName.toLowerCase();
-                        currentLocalMemberName = currentLocalMemberName && currentLocalMemberName.toLowerCase();
-                    }
-
-                    /*
-                     * When the current declaration uses a different member syntax,
-                     * then check if the ordering is correct.
-                     * Otherwise, make a default string compare (like rule sort-vars to be consistent) of the first used local member name.
-                     */
-                    if (currentMemberSyntaxGroupIndex !== previousMemberSyntaxGroupIndex) {
-                        if (currentMemberSyntaxGroupIndex < previousMemberSyntaxGroupIndex) {
-                            context.report({
-                                node,
-                                message: "Expected '{{syntaxA}}' syntax before '{{syntaxB}}' syntax.",
-                                data: {
-                                    syntaxA: memberSyntaxSortOrder[currentMemberSyntaxGroupIndex],
-                                    syntaxB: memberSyntaxSortOrder[previousMemberSyntaxGroupIndex]
-                                }
-                            });
+                if (!ignoreDeclarationSort) {
+                    if (previousDeclaration) {
+                        const currentMemberSyntaxGroupIndex = getMemberParameterGroupIndex(node),
+                            previousMemberSyntaxGroupIndex = getMemberParameterGroupIndex(previousDeclaration);
+                        let currentLocalMemberName = getFirstLocalMemberName(node),
+                            previousLocalMemberName = getFirstLocalMemberName(previousDeclaration);
+
+                        if (ignoreCase) {
+                            previousLocalMemberName = previousLocalMemberName && previousLocalMemberName.toLowerCase();
+                            currentLocalMemberName = currentLocalMemberName && currentLocalMemberName.toLowerCase();
                         }
-                    } else {
-                        if (previousLocalMemberName &&
-                            currentLocalMemberName &&
-                            currentLocalMemberName < previousLocalMemberName
-                        ) {
-                            context.report({
-                                node,
-                                message: "Imports should be sorted alphabetically."
-                            });
+
+                        /*
+                         * When the current declaration uses a different member syntax,
+                         * then check if the ordering is correct.
+                         * Otherwise, make a default string compare (like rule sort-vars to be consistent) of the first used local member name.
+                         */
+                        if (currentMemberSyntaxGroupIndex !== previousMemberSyntaxGroupIndex) {
+                            if (currentMemberSyntaxGroupIndex < previousMemberSyntaxGroupIndex) {
+                                context.report({
+                                    node,
+                                    message: "Expected '{{syntaxA}}' syntax before '{{syntaxB}}' syntax.",
+                                    data: {
+                                        syntaxA: memberSyntaxSortOrder[currentMemberSyntaxGroupIndex],
+                                        syntaxB: memberSyntaxSortOrder[previousMemberSyntaxGroupIndex]
+                                    }
+                                });
+                            }
+                        } else {
+                            if (previousLocalMemberName &&
+                                currentLocalMemberName &&
+                                currentLocalMemberName < previousLocalMemberName
+                            ) {
+                                context.report({
+                                    node,
+                                    message: "Imports should be sorted alphabetically."
+                                });
+                            }
                         }
                     }
+
+                    previousDeclaration = node;
                 }
 
                 if (!ignoreMemberSort) {
@@ -191,8 +199,6 @@ module.exports = {
                         });
                     }
                 }
-
-                previousDeclaration = node;
             }
         };
     }
diff --git a/package.json b/package.json
index bf356703e..cbcf117a8 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "eslint",
-  "version": "5.11.1",
+  "version": "5.12.0",
   "author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
   "description": "An AST-based pattern checker for JavaScript.",
   "bin": {
@@ -86,7 +86,7 @@
     "coveralls": "^3.0.1",
     "dateformat": "^3.0.3",
     "ejs": "^2.6.1",
-    "eslint-plugin-eslint-plugin": "^1.4.1",
+    "eslint-plugin-eslint-plugin": "^2.0.1",
     "eslint-plugin-node": "^8.0.0",
     "eslint-plugin-rulesdir": "^0.1.0",
     "eslint-release": "^1.2.0",
@@ -97,17 +97,17 @@
     "jsdoc": "^3.5.5",
     "karma": "^3.0.0",
     "karma-babel-preprocessor": "^7.0.0",
+    "karma-chrome-launcher": "^2.2.0",
     "karma-mocha": "^1.3.0",
     "karma-mocha-reporter": "^2.2.3",
-    "karma-phantomjs-launcher": "^1.0.4",
     "leche": "^2.2.3",
     "load-perf": "^0.2.0",
     "markdownlint": "^0.11.0",
     "mocha": "^5.0.5",
     "mock-fs": "^4.6.0",
     "npm-license": "^0.3.3",
-    "phantomjs-prebuilt": "^2.1.16",
     "proxyquire": "^2.0.1",
+    "puppeteer": "^1.9.0",
     "shelljs": "^0.8.2",
     "sinon": "^3.3.0",
     "temp": "^0.8.3",
diff --git a/tools/internal-rules/consistent-docs-description.js b/tools/internal-rules/consistent-docs-description.js
index b56c641a3..b3ee52241 100644
--- a/tools/internal-rules/consistent-docs-description.js
+++ b/tools/internal-rules/consistent-docs-description.js
@@ -115,7 +115,7 @@ module.exports = {
             category: "Internal",
             recommended: false
         },
-
+        type: "suggestion",
         schema: []
     },
 
diff --git a/tools/internal-rules/consistent-docs-url.js b/tools/internal-rules/consistent-docs-url.js
index 8e6652fc4..4d1344116 100644
--- a/tools/internal-rules/consistent-docs-url.js
+++ b/tools/internal-rules/consistent-docs-url.js
@@ -94,7 +94,7 @@ module.exports = {
             category: "Internal",
             recommended: false
         },
-
+        type: "suggestion",
         schema: []
     },
 
diff --git a/tools/internal-rules/consistent-meta-messages.js b/tools/internal-rules/consistent-meta-messages.js
index 43711c6ec..24facb189 100644
--- a/tools/internal-rules/consistent-meta-messages.js
+++ b/tools/internal-rules/consistent-meta-messages.js
@@ -65,8 +65,9 @@ module.exports = {
             recommended: false
         },
         schema: [],
+        type: "suggestion",
         messages: {
-            expectedMessages: "Expected `meta.messages` property"
+            expectedMessages: "Expected `meta.messages` property."
         }
     },
 
diff --git a/tools/internal-rules/no-invalid-meta.js b/tools/internal-rules/no-invalid-meta.js
index c0a9bc907..973b2a480 100644
--- a/tools/internal-rules/no-invalid-meta.js
+++ b/tools/internal-rules/no-invalid-meta.js
@@ -161,7 +161,7 @@ module.exports = {
             category: "Internal",
             recommended: false
         },
-
+        type: "problem",
         schema: []
     },
 


Test patch:
diff --git a/tests/lib/formatters/tap.js b/tests/lib/formatters/tap.js
index 7fc080a53..903af6a8b 100644
--- a/tests/lib/formatters/tap.js
+++ b/tests/lib/formatters/tap.js
@@ -72,7 +72,7 @@ describe("formatter:tap", () => {
             }]
         }];
 
-        it("should return a an error string", () => {
+        it("should return an error string", () => {
             const result = formatter(code);
 
             assert.include(result, "not ok");
@@ -80,7 +80,70 @@ describe("formatter:tap", () => {
         });
     });
 
-    describe("when passed multiple messages", () => {
+    describe("when passed a message with a severity of 1", () => {
+        const code = [{
+            filePath: "foo.js",
+            messages: [{
+                message: "Unexpected foo.",
+                severity: 1,
+                line: 5,
+                column: 10,
+                ruleId: "foo"
+            }]
+        }];
+
+        it("should return a warning string", () => {
+            const result = formatter(code);
+
+            assert.include(result, "ok");
+            assert.notInclude(result, "not ok");
+            assert.include(result, "warning");
+        });
+    });
+
+    describe("when passed multiple messages with a severity of 1", () => {
+        const code = [{
+            filePath: "foo.js",
+            messages: [{
+                message: "Foo.",
+                severity: 1,
+                line: 5,
+                column: 10,
+                ruleId: "foo"
+            }, {
+                message: "Bar.",
+                severity: 1,
+                line: 6,
+                column: 11,
+                ruleId: "bar"
+            }, {
+                message: "Baz.",
+                severity: 1,
+                line: 7,
+                column: 12,
+                ruleId: "baz"
+            }]
+        }];
+
+        it("should return a string with multiple entries", () => {
+            const result = formatter(code);
+
+            assert.include(result, "ok");
+            assert.notInclude(result, "not ok");
+            assert.include(result, "messages");
+            assert.include(result, "Foo.");
+            assert.include(result, "line: 5");
+            assert.include(result, "column: 10");
+            assert.include(result, "Bar.");
+            assert.include(result, "line: 6");
+            assert.include(result, "column: 11");
+            assert.include(result, "Baz.");
+            assert.include(result, "line: 7");
+            assert.include(result, "column: 12");
+        });
+    });
+
+    describe("when passed multiple messages with different error severity", () => {
         const code = [{
             filePath: "foo.js",
             messages: [{
@@ -146,7 +209,8 @@ describe("formatter:tap", () => {
             const result = formatter(code);
 
             assert.include(result, "not ok 1");
-            assert.include(result, "not ok 2");
+            assert.include(result, "ok 2");
+            assert.notInclude(result, "not ok 2");
         });
     });
 
diff --git a/tests/lib/rules/no-param-reassign.js b/tests/lib/rules/no-param-reassign.js
index 5d009c338..40156f481 100644
--- a/tests/lib/rules/no-param-reassign.js
+++ b/tests/lib/rules/no-param-reassign.js
@@ -32,6 +32,8 @@ ruleTester.run("no-param-reassign", rule, {
         { code: "function foo(a) { bar(a.b).c = 0; }", options: [{ props: true }] },
         { code: "function foo(a) { data[a.b] = 0; }", options: [{ props: true }] },
         { code: "function foo(a) { +a.b; }", options: [{ props: true }] },
+        { code: "function foo(a) { (a ? [] : [])[0] = 1; }", options: [{ props: true }] },
+        { code: "function foo(a) { (a.b ? [] : [])[0] = 1; }", options: [{ props: true }] },
         { code: "function foo(a) { a.b = 0; }", options: [{ props: true, ignorePropertyModificationsFor: ["a"] }] },
         { code: "function foo(a) { ++a.b; }", options: [{ props: true, ignorePropertyModificationsFor: ["a"] }] },
         { code: "function foo(a) { delete a.b; }", options: [{ props: true, ignorePropertyModificationsFor: ["a"] }] },
@@ -87,6 +89,11 @@ ruleTester.run("no-param-reassign", rule, {
             options: [{ props: true }],
             errors: [{ message: "Assignment to property of function parameter 'bar'." }]
         },
+        {
+            code: "function foo(bar) { (bar ? bar : [])[0] = 1; }",
+            options: [{ props: true }],
+            errors: [{ message: "Assignment to property of function parameter 'bar'." }]
+        },
         {
             code: "function foo(bar) { [bar.a] = []; }",
             options: [{ props: true }],
diff --git a/tests/lib/rules/sort-imports.js b/tests/lib/rules/sort-imports.js
index 4cee0a2c5..290505650 100644
--- a/tests/lib/rules/sort-imports.js
+++ b/tests/lib/rules/sort-imports.js
@@ -61,6 +61,14 @@ ruleTester.run("sort-imports", rule, {
             options: ignoreCaseArgs
         },
         "import {a, b, c, d} from 'foo.js';",
+        {
+            code:
+                "import a from 'foo.js';\n" +
+                "import B from 'bar.js';",
+            options: [{
+                ignoreDeclarationSort: true
+            }]
+        },
         {
             code: "import {b, A, C, d} from 'foo.js';",
             options: [{
@@ -175,6 +183,21 @@ ruleTester.run("sort-imports", rule, {
                 type: "ImportSpecifier"
             }]
         },
+        {
+            code:
+                "import {b, a, d, c} from 'foo.js';\n" +
+                "import {e, f, g, h} from 'bar.js';",
+            output:
+                "import {a, b, c, d} from 'foo.js';\n" +
+                "import {e, f, g, h} from 'bar.js';",
+            options: [{
+                ignoreDeclarationSort: true
+            }],
+            errors: [{
+                message: "Member 'a' of the import declaration should be sorted alphabetically.",
+                type: "ImportSpecifier"
+            }]
+        },
         {
             code: "import {a, B, c, D} from 'foo.js';",
             output: "import {B, D, a, c} from 'foo.js';",