Repository: eslint/eslint (js)

Issue:
ESLint v5.14.0 now requires Node.js to be compiled with crypto
I came across this on Twitter. It appears that upgrading file-entry-cache means that ESLint now requires Node.js to be compiled with crypto because of how the cache is generated now. More details:

https://github.com/nodejs/node/pull/26182

We should decide if this is something we are okay with going forward. 

I’m guessing there aren’t a lot of folks using Node.js without crypto, so maybe not a big deal, but at a minimum it seems like we should acknowledge this requirement in our docs somewhere. 

Pull request description:
Docs: Add note about Node.js requiring SSL support (fixes #11413)
<!--
    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)**

Adds a small note that Node.js requires SSL to be built in. While this hasn't affected many users, it's good to document in case this comes up in the future. (And the Node.js project itself did run into this as a problem.)

I also removed the notice about the npm version as we always support the npm version shipping with the supported Node.js versions.

**Is there anything you'd like reviewers to focus on?**




Patch:
diff --git a/README.md b/README.md
index dd414f1d1..f28cfb230 100644
--- a/README.md
+++ b/README.md
@@ -40,7 +40,7 @@ ESLint is a tool for identifying and reporting on patterns found in ECMAScript/J
 
 ## <a name="installation-and-usage"></a>Installation and Usage
 
-Prerequisites: [Node.js](https://nodejs.org/) (`^8.10.0`, `^10.13.0`, or `>=11.10.1`), npm version 3+.
+Prerequisites: [Node.js](https://nodejs.org/) (`^8.10.0`, `^10.13.0`, or `>=11.10.1`) built with SSL support. (If you are using an official Node.js distribution, SSL is always built in.)
 
 You can install ESLint using npm:
 
@@ -265,7 +265,7 @@ The following companies, organizations, and individuals support ESLint's ongoing
 <h3>Gold Sponsors</h3>
 <p><a href="https://www.shopify.com"><img src="https://images.opencollective.com/shopify/eeb91aa/logo.png" alt="Shopify" height="96"></a> <a href="http://engineering.salesforce.com"><img src="https://images.opencollective.com/salesforce/ca8f997/logo.png" alt="Salesforce" height="96"></a> <a href="https://badoo.com/team?utm_source=eslint"><img src="https://images.opencollective.com/badoo/2826a3b/logo.png" alt="Badoo" height="96"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/d327d66/logo.png" alt="Airbnb" height="96"></a> <a href="https://opensource.facebook.com"><img src="https://images.opencollective.com/fbopensource/fbb8a5b/logo.png" alt="Facebook Open Source" height="96"></a></p><h3>Silver Sponsors</h3>
 <p><a href="https://www.ampproject.org/"><img src="https://images.opencollective.com/amp/c8a3b25/logo.png" alt="AMP Project" height="64"></a></p><h3>Bronze Sponsors</h3>
-<p><a href="https://clay.global"><img src="https://images.opencollective.com/clayglobal/2468f34/logo.png" alt="clay" height="32"></a> <a href="https://www.crosswordsolver.com"><img src="https://images.opencollective.com/crosswordsolver/d4481d6/logo.png" alt="Crosswordsolver" height="32"></a> <a href="https://www.codacy.com/?utm_source=eslint&utm_medium=cpm&utm_campaign=eslint-sponsorship"><img src="https://images.opencollective.com/codacy/ed22716/logo.png" alt="Codacy" height="32"></a> <a href="https://mixpanel.com"><img src="https://images.opencollective.com/mixpanel/cd682f7/logo.png" alt="Mixpanel" height="32"></a> <a href="https://www.vpsserver.com"><img src="https://images.opencollective.com/vpsservercom/logo.png" alt="VPS Server" height="32"></a> <a href="https://icons8.com"><img src="https://images.opencollective.com/icons8/0b37d14/logo.png" alt="Free Icons by Icons8" height="32"></a> <a href="https://uxplanet.org/top-ui-ux-design-agencies-user-experience-firms-8c54697e290"><img src="https://images.opencollective.com/ui-ux-design-agencies/cae5dfe/logo.png" alt="UI UX Design Agencies" height="32"></a> <a href="https://www.minitool.com"><img src="https://images.opencollective.com/minitool-software-ltd/6d68e16/logo.png" alt="MiniTool Software Ltd" height="32"></a> <a href="https://discordapp.com"><img src="https://images.opencollective.com/discordapp/7e3d9a9/logo.png" alt="Discord" height="32"></a> <a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://tekhattan.com"><img src="https://images.opencollective.com/tekhattan/bc73c28/logo.png" alt="TekHattan" height="32"></a> <a href="https://www.marfeel.com/"><img src="https://images.opencollective.com/marfeel/4b88e30/logo.png" alt="Marfeel" height="32"></a> <a href="http://www.firesticktricks.com"><img src="https://images.opencollective.com/fire-stick-tricks/b8fbe2c/logo.png" alt="Fire Stick Tricks" height="32"></a> <a href="https://jsheroes.io/"><img src="https://images.opencollective.com/jsheroes1/9fedf0b/logo.png" alt="JSHeroes " height="32"></a></p>
+<p><a href="https://uxplanet.org/top-ui-ux-design-agencies-user-experience-firms-8c54697e290"><img src="https://images.opencollective.com/ui-ux-design-agencies/cae5dfe/logo.png" alt="UI UX Design Agencies" height="32"></a> <a href="https://www.bugsnag.com/platforms/react-error-reporting?utm_source=MobX&utm_medium=Website&utm_content=open-source&utm_campaign=2019-community&utm_term=20190913"><img src="https://images.opencollective.com/bugsnag-stability-monitoring/c2cef36/logo.png" alt="Bugsnag Stability Monitoring" height="32"></a> <a href="https://www.minitool.com"><img src="https://images.opencollective.com/minitool-software-ltd/6d68e16/logo.png" alt="MiniTool Software Ltd" height="32"></a> <a href="https://www.codacy.com/?utm_source=eslint&utm_medium=cpm&utm_campaign=eslint-sponsorship"><img src="https://images.opencollective.com/codacy/ed22716/logo.png" alt="Codacy" height="32"></a> <a href="https://mixpanel.com"><img src="https://images.opencollective.com/mixpanel/cd682f7/logo.png" alt="Mixpanel" height="32"></a> <a href="https://www.vpsserver.com"><img src="https://images.opencollective.com/vpsservercom/logo.png" alt="VPS Server" height="32"></a> <a href="https://icons8.com"><img src="https://images.opencollective.com/icons8/0b37d14/logo.png" alt="Free Icons by Icons8" height="32"></a> <a href="https://www.crosswordsolver.com"><img src="https://images.opencollective.com/crosswordsolver/d4481d6/logo.png" alt="Crosswordsolver" height="32"></a> <a href="https://clay.global"><img src="https://images.opencollective.com/clayglobal/2468f34/logo.png" alt="clay" height="32"></a> <a href="https://discordapp.com"><img src="https://images.opencollective.com/discordapp/7e3d9a9/logo.png" alt="Discord" height="32"></a> <a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://tekhattan.com"><img src="https://images.opencollective.com/tekhattan/bc73c28/logo.png" alt="TekHattan" height="32"></a> <a href="https://www.marfeel.com/"><img src="https://images.opencollective.com/marfeel/4b88e30/logo.png" alt="Marfeel" height="32"></a> <a href="http://www.firesticktricks.com"><img src="https://images.opencollective.com/fire-stick-tricks/b8fbe2c/logo.png" alt="Fire Stick Tricks" height="32"></a> <a href="https://jsheroes.io/"><img src="https://images.opencollective.com/jsheroes1/9fedf0b/logo.png" alt="JSHeroes " height="32"></a></p>
 <!--sponsorsend-->
 
 ## <a name="technology-sponsors"></a>Technology Sponsors
diff --git a/docs/rules/no-unneeded-ternary.md b/docs/rules/no-unneeded-ternary.md
index b4caddf58..e5d4e8011 100644
--- a/docs/rules/no-unneeded-ternary.md
+++ b/docs/rules/no-unneeded-ternary.md
@@ -41,8 +41,6 @@ Examples of **incorrect** code for this rule:
 var a = x === 2 ? true : false;
 
 var a = x ? true : false;
-
-var a = f(x ? x : 1);
 ```
 
 Examples of **correct** code for this rule:
@@ -58,7 +56,7 @@ var a = x ? "Yes" : "No";
 
 var a = x ? y : x;
 
-var a = x ? x : 1;  // Note that this is only allowed as it on the right hand side of an assignment; this type of ternary is disallowed everywhere else. See defaultAssignment option below for more details.
+f(x ? x : 1); // default assignment - would be disallowed if defaultAssignment option set to false. See option details below.
 ```
 
 ## Options
@@ -70,7 +68,7 @@ This rule has an object option:
 
 ### defaultAssignment
 
-The defaultAssignment option allows expressions of the form `x ? x : expr` (where `x` is any identifier and `expr` is any expression) as the right hand side of assignments (but nowhere else).
+When set to `true`, which it is by default, The defaultAssignment option allows expressions of the form `x ? x : expr` (where `x` is any identifier and `expr` is any expression).
 
 Examples of additional **incorrect** code for this rule with the `{ "defaultAssignment": false }` option:
 
@@ -78,8 +76,12 @@ Examples of additional **incorrect** code for this rule with the `{ "defaultAssi
 /*eslint no-unneeded-ternary: ["error", { "defaultAssignment": false }]*/
 
 var a = x ? x : 1;
+
+f(x ? x : 1);
 ```
 
+Note that `defaultAssignment: false` still allows expressions of the form `x ? expr : x` (where the identifier is on the right hand side of the ternary).
+
 ## When Not To Use It
 
 You can turn this rule off if you are not concerned with unnecessary complexity in conditional expressions.
diff --git a/docs/user-guide/getting-started.md b/docs/user-guide/getting-started.md
index 1bebf7d69..b457ea940 100644
--- a/docs/user-guide/getting-started.md
+++ b/docs/user-guide/getting-started.md
@@ -13,7 +13,7 @@ ESLint is a tool for identifying and reporting on patterns found in ECMAScript/J
 
 ## Installation and Usage
 
-Prerequisites: [Node.js](https://nodejs.org/en/) (>=8.10), npm version 3+.
+Prerequisites: [Node.js](https://nodejs.org/en/) (`^8.10.0`, `^10.13.0`, or `>=11.10.1`) built with SSL support. (If you are using an official Node.js distribution, SSL is always built in.)
 
 You can install ESLint using npm:
 
diff --git a/lib/linter/linter.js b/lib/linter/linter.js
index 8bd29b947..6d88cb5aa 100644
--- a/lib/linter/linter.js
+++ b/lib/linter/linter.js
@@ -666,6 +666,8 @@ function parse(text, parser, providedParserOptions, filePath) {
         // If the message includes a leading line number, strip it:
         const message = `Parsing error: ${ex.message.replace(/^line \d+:/iu, "").trim()}`;
 
+        debug("%s\n%s", message, ex.stack);
+
         return {
             success: false,
             error: {
diff --git a/lib/rules/comma-dangle.js b/lib/rules/comma-dangle.js
index 0c177296e..fb2d167c7 100644
--- a/lib/rules/comma-dangle.js
+++ b/lib/rules/comma-dangle.js
@@ -41,18 +41,17 @@ function isTrailingCommaAllowed(lastItem) {
 /**
  * Normalize option value.
  * @param {string|Object|undefined} optionValue The 1st option value to normalize.
+ * @param {number} ecmaVersion The normalized ECMAScript version.
  * @returns {Object} The normalized option value.
  */
-function normalizeOptions(optionValue) {
+function normalizeOptions(optionValue, ecmaVersion) {
     if (typeof optionValue === "string") {
         return {
             arrays: optionValue,
             objects: optionValue,
             imports: optionValue,
             exports: optionValue,
-
-            // For backward compatibility, always ignore functions.
-            functions: "ignore"
+            functions: (!ecmaVersion || ecmaVersion < 8) ? "ignore" : optionValue
         };
     }
     if (typeof optionValue === "object" && optionValue !== null) {
@@ -135,7 +134,8 @@ module.exports = {
     },
 
     create(context) {
-        const options = normalizeOptions(context.options[0]);
+        const options = normalizeOptions(context.options[0], context.parserOptions.ecmaVersion);
+
         const sourceCode = context.getSourceCode();
 
         /**
diff --git a/lib/rules/no-tabs.js b/lib/rules/no-tabs.js
index 0c0a22011..3fc0b78b6 100644
--- a/lib/rules/no-tabs.js
+++ b/lib/rules/no-tabs.js
@@ -55,8 +55,14 @@ module.exports = {
                         context.report({
                             node,
                             loc: {
-                                line: index + 1,
-                                column: match.index
+                                start: {
+                                    line: index + 1,
+                                    column: match.index
+                                },
+                                end: {
+                                    line: index + 1,
+                                    column: match.index + match[0].length
+                                }
                             },
                             message: "Unexpected tab character."
                         });


Test patch:
diff --git a/tests/lib/rules/comma-dangle.js b/tests/lib/rules/comma-dangle.js
index 573c0c2bd..6d51825eb 100644
--- a/tests/lib/rules/comma-dangle.js
+++ b/tests/lib/rules/comma-dangle.js
@@ -235,31 +235,100 @@ ruleTester.run("comma-dangle", rule, {
             options: ["only-multiline"],
             parserOptions: { ecmaVersion: 6, sourceType: "module" }
         },
-
-
-        // trailing comma in functions -- ignore by default
         {
-            code: "function foo(a,) {}",
+            code: "function foo(a) {}",
+            options: ["always"]
+        },
+        {
+            code: "foo(a)",
+            options: ["always"]
+        },
+        {
+            code: "function foo(a) {}",
+            options: ["never"]
+        },
+        {
+            code: "foo(a)",
+            options: ["never"]
+        },
+        {
+            code: "function foo(a,\nb) {}",
+            options: ["always-multiline"]
+        },
+        {
+            code: "foo(a,\nb)",
+            options: ["always-multiline"]
+        },
+        {
+            code: "function foo(a,\nb) {}",
+            options: ["only-multiline"]
+        },
+        {
+            code: "foo(a,\nb)",
+            options: ["only-multiline"]
+        },
+        {
+            code: "function foo(a) {}",
+            options: ["always"],
+            parserOptions: { ecmaVersion: 7 }
+        },
+        {
+            code: "foo(a)",
+            options: ["always"],
+            parserOptions: { ecmaVersion: 7 }
+        },
+        {
+            code: "function foo(a) {}",
+            options: ["never"],
+            parserOptions: { ecmaVersion: 7 }
+        },
+        {
+            code: "foo(a)",
+            options: ["never"],
+            parserOptions: { ecmaVersion: 7 }
+        },
+        {
+            code: "function foo(a,\nb) {}",
+            options: ["always-multiline"],
+            parserOptions: { ecmaVersion: 7 }
+        },
+        {
+            code: "foo(a,\nb)",
+            options: ["always-multiline"],
+            parserOptions: { ecmaVersion: 7 }
+        },
+        {
+            code: "function foo(a,\nb) {}",
+            options: ["only-multiline"],
+            parserOptions: { ecmaVersion: 7 }
+        },
+        {
+            code: "foo(a,\nb)",
+            options: ["only-multiline"],
+            parserOptions: { ecmaVersion: 7 }
+        },
+        {
+            code: "function foo(a) {}",
             options: ["never"],
             parserOptions: { ecmaVersion: 8 }
         },
         {
-            code: "foo(a,)",
+            code: "foo(a)",
             options: ["never"],
             parserOptions: { ecmaVersion: 8 }
         },
         {
-            code: "function foo(a) {}",
+            code: "function foo(a,) {}",
             options: ["always"],
             parserOptions: { ecmaVersion: 8 }
         },
         {
-            code: "foo(a)",
+            code: "foo(a,)",
             options: ["always"],
             parserOptions: { ecmaVersion: 8 }
         },
         {
-            code: "function foo(\na,\nb\n) {}",
+            code: "function foo(\na,\nb,\n) {}",
             options: ["always-multiline"],
             parserOptions: { ecmaVersion: 8 }
         },
@@ -269,22 +338,22 @@ ruleTester.run("comma-dangle", rule, {
             parserOptions: { ecmaVersion: 8 }
         },
         {
-            code: "function foo(a,b,) {}",
+            code: "function foo(a,b) {}",
             options: ["always-multiline"],
             parserOptions: { ecmaVersion: 8 }
         },
         {
-            code: "foo(a,b,)",
+            code: "foo(a,b)",
             options: ["always-multiline"],
             parserOptions: { ecmaVersion: 8 }
         },
         {
-            code: "function foo(a,b,) {}",
+            code: "function foo(a,b) {}",
             options: ["only-multiline"],
             parserOptions: { ecmaVersion: 8 }
         },
         {
-            code: "foo(a,b,)",
+            code: "foo(a,b)",
             options: ["only-multiline"],
             parserOptions: { ecmaVersion: 8 }
         },
@@ -315,6 +384,11 @@ ruleTester.run("comma-dangle", rule, {
             options: [{ functions: "always" }],
             parserOptions: { ecmaVersion: 8 }
         },
+        {
+            code: "foo(a,)",
+            options: [{ functions: "always" }],
+            parserOptions: { ecmaVersion: 9 }
+        },
         {
             code: "bar(...a,)",
             options: [{ functions: "always" }],
@@ -1283,6 +1357,208 @@ ruleTester.run("comma-dangle", rule, {
             parserOptions: { ecmaVersion: 8 },
             errors: [{ messageId: "unexpected", type: "SpreadElement" }]
         },
+        {
+            code: "function foo(a,) {}",
+            output: "function foo(a) {}",
+            options: ["never"],
+            parserOptions: { ecmaVersion: 8 },
+            errors: [{ messageId: "unexpected", type: "Identifier" }]
+        },
+        {
+            code: "(function foo(a,) {})",
+            output: "(function foo(a) {})",
+            options: ["never"],
+            parserOptions: { ecmaVersion: 8 },
+            errors: [{ messageId: "unexpected", type: "Identifier" }]
+        },
+        {
+            code: "(a,) => a",
+            output: "(a) => a",
+            options: ["never"],
+            parserOptions: { ecmaVersion: 8 },
+            errors: [{ messageId: "unexpected", type: "Identifier" }]
+        },
+        {
+            code: "(a,) => (a)",
+            output: "(a) => (a)",
+            options: ["never"],
+            parserOptions: { ecmaVersion: 8 },
+            errors: [{ messageId: "unexpected", type: "Identifier" }]
+        },
+        {
+            code: "({foo(a,) {}})",
+            output: "({foo(a) {}})",
+            options: ["never"],
+            parserOptions: { ecmaVersion: 8 },
+            errors: [{ messageId: "unexpected", type: "Identifier" }]
+        },
+        {
+            code: "class A {foo(a,) {}}",
+            output: "class A {foo(a) {}}",
+            options: ["never"],
+            parserOptions: { ecmaVersion: 8 },
+            errors: [{ messageId: "unexpected", type: "Identifier" }]
+        },
+        {
+            code: "foo(a,)",
+            output: "foo(a)",
+            options: ["never"],
+            parserOptions: { ecmaVersion: 8 },
+            errors: [{ messageId: "unexpected", type: "Identifier" }]
+        },
+        {
+            code: "foo(...a,)",
+            output: "foo(...a)",
+            options: ["never"],
+            parserOptions: { ecmaVersion: 8 },
+            errors: [{ messageId: "unexpected", type: "SpreadElement" }]
+        },
+
+        {
+            code: "function foo(a) {}",
+            output: "function foo(a,) {}",
+            options: ["always"],
+            parserOptions: { ecmaVersion: 8 },
+            errors: [{ messageId: "missing", type: "Identifier" }]
+        },
+        {
+            code: "(function foo(a) {})",
+            output: "(function foo(a,) {})",
+            options: ["always"],
+            parserOptions: { ecmaVersion: 8 },
+            errors: [{ messageId: "missing", type: "Identifier" }]
+        },
+        {
+            code: "(a) => a",
+            output: "(a,) => a",
+            options: ["always"],
+            parserOptions: { ecmaVersion: 8 },
+            errors: [{ messageId: "missing", type: "Identifier" }]
+        },
+        {
+            code: "(a) => (a)",
+            output: "(a,) => (a)",
+            options: ["always"],
+            parserOptions: { ecmaVersion: 8 },
+            errors: [{ messageId: "missing", type: "Identifier" }]
+        },
+        {
+            code: "({foo(a) {}})",
+            output: "({foo(a,) {},})",
+            options: ["always"],
+            parserOptions: { ecmaVersion: 8 },
+            errors: [
+                { messageId: "missing", type: "Identifier" },
+                { messageId: "missing", type: "Property" }
+            ]
+        },
+        {
+            code: "class A {foo(a) {}}",
+            output: "class A {foo(a,) {}}",
+            options: ["always"],
+            parserOptions: { ecmaVersion: 8 },
+            errors: [{ messageId: "missing", type: "Identifier" }]
+        },
+        {
+            code: "foo(a)",
+            output: "foo(a,)",
+            options: ["always"],
+            parserOptions: { ecmaVersion: 8 },
+            errors: [{ messageId: "missing", type: "Identifier" }]
+        },
+        {
+            code: "foo(...a)",
+            output: "foo(...a,)",
+            options: ["always"],
+            parserOptions: { ecmaVersion: 8 },
+            errors: [{ messageId: "missing", type: "SpreadElement" }]
+        },
+
+        {
+            code: "function foo(a,) {}",
+            output: "function foo(a) {}",
+            options: ["always-multiline"],
+            parserOptions: { ecmaVersion: 8 },
+            errors: [{ messageId: "unexpected", type: "Identifier" }]
+        },
+        {
+            code: "(function foo(a,) {})",
+            output: "(function foo(a) {})",
+            options: ["always-multiline"],
+            parserOptions: { ecmaVersion: 8 },
+            errors: [{ messageId: "unexpected", type: "Identifier" }]
+        },
+        {
+            code: "foo(a,)",
+            output: "foo(a)",
+            options: ["always-multiline"],
+            parserOptions: { ecmaVersion: 8 },
+            errors: [{ messageId: "unexpected", type: "Identifier" }]
+        },
+        {
+            code: "foo(...a,)",
+            output: "foo(...a)",
+            options: ["always-multiline"],
+            parserOptions: { ecmaVersion: 8 },
+            errors: [{ messageId: "unexpected", type: "SpreadElement" }]
+        },
+        {
+            code: "function foo(\na,\nb\n) {}",
+            output: "function foo(\na,\nb,\n) {}",
+            options: ["always-multiline"],
+            parserOptions: { ecmaVersion: 8 },
+            errors: [{ messageId: "missing", type: "Identifier" }]
+        },
+        {
+            code: "foo(\na,\nb\n)",
+            output: "foo(\na,\nb,\n)",
+            options: ["always-multiline"],
+            parserOptions: { ecmaVersion: 8 },
+            errors: [{ messageId: "missing", type: "Identifier" }]
+        },
+        {
+            code: "foo(\n...a,\n...b\n)",
+            output: "foo(\n...a,\n...b,\n)",
+            options: ["always-multiline"],
+            parserOptions: { ecmaVersion: 8 },
+            errors: [{ messageId: "missing", type: "SpreadElement" }]
+        },
+
+        {
+            code: "function foo(a,) {}",
+            output: "function foo(a) {}",
+            options: ["only-multiline"],
+            parserOptions: { ecmaVersion: 8 },
+            errors: [{ messageId: "unexpected", type: "Identifier" }]
+        },
+        {
+            code: "(function foo(a,) {})",
+            output: "(function foo(a) {})",
+            options: ["only-multiline"],
+            parserOptions: { ecmaVersion: 8 },
+            errors: [{ messageId: "unexpected", type: "Identifier" }]
+        },
+        {
+            code: "foo(a,)",
+            output: "foo(a)",
+            options: ["only-multiline"],
+            parserOptions: { ecmaVersion: 8 },
+            errors: [{ messageId: "unexpected", type: "Identifier" }]
+        },
+        {
+            code: "foo(...a,)",
+            output: "foo(...a)",
+            options: ["only-multiline"],
+            parserOptions: { ecmaVersion: 8 },
+            errors: [{ messageId: "unexpected", type: "SpreadElement" }]
+        },
+        {
+            code: "function foo(a) {}",
+            output: "function foo(a,) {}",
+            options: ["always"],
+            parserOptions: { ecmaVersion: 9 },
+            errors: [{ messageId: "missing", type: "Identifier" }]
+        },
 
         // separated options
         {
diff --git a/tests/lib/rules/no-tabs.js b/tests/lib/rules/no-tabs.js
index ac0ad9e74..637f49051 100644
--- a/tests/lib/rules/no-tabs.js
+++ b/tests/lib/rules/no-tabs.js
@@ -40,7 +40,9 @@ ruleTester.run("no-tabs", rule, {
             errors: [{
                 message: ERROR_MESSAGE,
                 line: 1,
-                column: 17
+                column: 17,
+                endLine: 1,
+                endColumn: 18
             }]
         },
         {
@@ -48,7 +50,9 @@ ruleTester.run("no-tabs", rule, {
             errors: [{
                 message: ERROR_MESSAGE,
                 line: 1,
-                column: 5
+                column: 5,
+                endLine: 1,
+                endColumn: 6
             }]
         },
         {
@@ -59,7 +63,9 @@ ruleTester.run("no-tabs", rule, {
             errors: [{
                 message: ERROR_MESSAGE,
                 line: 2,
-                column: 5
+                column: 5,
+                endLine: 2,
+                endColumn: 6
             }]
         },
         {
@@ -70,7 +76,9 @@ ruleTester.run("no-tabs", rule, {
             errors: [{
                 message: ERROR_MESSAGE,
                 line: 1,
-                column: 9
+                column: 9,
+                endLine: 1,
+                endColumn: 10
             }]
         },
         {
@@ -82,12 +90,16 @@ ruleTester.run("no-tabs", rule, {
                 {
                     message: ERROR_MESSAGE,
                     line: 2,
-                    column: 5
+                    column: 5,
+                    endLine: 2,
+                    endColumn: 6
                 },
                 {
                     message: ERROR_MESSAGE,
                     line: 3,
-                    column: 1
+                    column: 1,
+                    endLine: 3,
+                    endColumn: 2
                 }
             ]
         },
@@ -97,8 +109,50 @@ ruleTester.run("no-tabs", rule, {
             errors: [{
                 message: ERROR_MESSAGE,
                 line: 1,
-                column: 30
+                column: 30,
+                endLine: 1,
+                endColumn: 31
             }]
+        },
+        {
+            code: "\t\ta =\t\t\tb +\tc\t\t;\t\t",
+            errors: [
+                {
+                    message: ERROR_MESSAGE,
+                    line: 1,
+                    column: 1,
+                    endLine: 1,
+                    endColumn: 3
+                },
+                {
+                    message: ERROR_MESSAGE,
+                    line: 1,
+                    column: 6,
+                    endLine: 1,
+                    endColumn: 9
+                },
+                {
+                    message: ERROR_MESSAGE,
+                    line: 1,
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
+                },
+                {
+                    message: ERROR_MESSAGE,
+                    line: 1,
+                    column: 14,
+                    endLine: 1,
+                    endColumn: 16
+                },
+                {
+                    message: ERROR_MESSAGE,
+                    line: 1,
+                    column: 17,
+                    endLine: 1,
+                    endColumn: 19
+                }
+            ]
         }
     ]
 });
diff --git a/tests/lib/rules/no-unneeded-ternary.js b/tests/lib/rules/no-unneeded-ternary.js
index 243526c22..a297b211b 100644
--- a/tests/lib/rules/no-unneeded-ternary.js
+++ b/tests/lib/rules/no-unneeded-ternary.js
@@ -27,6 +27,12 @@ ruleTester.run("no-unneeded-ternary", rule, {
         "var a = x === 2 ? 'true' : 'false';",
         "var a = foo ? foo : bar;",
         "var value = 'a';var canSet = true;var result = value || (canSet ? 'unset' : 'can not set')",
+        "var a = foo ? bar : foo;",
+        "foo ? bar : foo;",
+        "var a = f(x ? x : 1)",
+        "f(x ? x : 1);",
+        "foo ? foo : bar;",
+        "var a = foo ? 'Yes' : foo;",
         {
             code: "var a = foo ? 'Yes' : foo;",
             options: [{ defaultAssignment: false }]
@@ -34,6 +40,10 @@ ruleTester.run("no-unneeded-ternary", rule, {
         {
             code: "var a = foo ? bar : foo;",
             options: [{ defaultAssignment: false }]
+        },
+        {
+            code: "foo ? bar : foo;",
+            options: [{ defaultAssignment: false }]
         }
     ],
     invalid: [
@@ -314,6 +324,39 @@ ruleTester.run("no-unneeded-ternary", rule, {
                 line: 1,
                 column: 13
             }]
+        },
+        {
+            code: "f(x ? x : 1);",
+            output: "f(x || 1);",
+            options: [{ defaultAssignment: false }],
+            errors: [{
+                message: "Unnecessary use of conditional expression for default assignment.",
+                type: "ConditionalExpression",
+                line: 1,
+                column: 7
+            }]
+        },
+        {
+            code: "x ? x : 1;",
+            output: "x || 1;",
+            options: [{ defaultAssignment: false }],
+            errors: [{
+                message: "Unnecessary use of conditional expression for default assignment.",
+                type: "ConditionalExpression",
+                line: 1,
+                column: 5
+            }]
+        },
+        {
+            code: "var a = foo ? foo : bar;",
+            output: "var a = foo || bar;",
+            options: [{ defaultAssignment: false }],
+            errors: [{
+                message: "Unnecessary use of conditional expression for default assignment.",
+                type: "ConditionalExpression",
+                line: 1,
+                column: 15
+            }]
         }
     ]
 });