Repository: eslint/eslint (js)

Issue:
no-constant-condition reported error range is too broad
**Tell us about your environment**

* **ESLint Version:** 4.8.0
* **Node Version:** 8.3.0
* **npm Version:** 5.3.0

**What parser (default, Babel-ESLint, etc.) are you using?** default

**Please show your full configuration:**

<details>
<summary>Configuration</summary>

<!-- Paste your configuration below: -->
```js
{
  "rules": {
    "no-constant-condition": "error"
  }
}
```

</details>

**What did you do? Please include the actual source code causing the issue.**

<!-- Paste the source code below: -->
```js
if (true) {
  something();
}

something(true ? 1 : 0);
```

**What did you expect to happen?**

The reported error ranges should only include the constant conditions themselves. In the above cases, the words "true".

**What actually happened? Please include the actual, raw output from ESLint.**

The reported error ranges include the entire statement/expression that the constant condition is part of.

```json
$ eslint test.js --format json | jq
[
  {
    "filePath": "/home/lydell/bugs/eslint/test.js",
    "messages": [
      {
        "ruleId": "no-constant-condition",
        "severity": 2,
        "message": "Unexpected constant condition.",
        "line": 1,
        "column": 1,
        "nodeType": "IfStatement",
        "source": "if (true) {",
        "endLine": 3,
        "endColumn": 2
      },
      {
        "ruleId": "no-constant-condition",
        "severity": 2,
        "message": "Unexpected constant condition.",
        "line": 5,
        "column": 11,
        "nodeType": "ConditionalExpression",
        "source": "something(true ? 1 : 0);",
        "endLine": 5,
        "endColumn": 23
      }
    ],
    "errorCount": 2,
    "warningCount": 0,
    "fixableErrorCount": 0,
    "fixableWarningCount": 0,
    "source": "if (true) {\n  something();\n}\n\nsomething(true ? 1 : 0);\n"
  }
]
```

Expected:

```diff
@@ -7,11 +7,11 @@
         "severity": 2,
         "message": "Unexpected constant condition.",
         "line": 1,
-        "column": 1,
+        "column": 5,
         "nodeType": "IfStatement",
         "source": "if (true) {",
-        "endLine": 3,
-        "endColumn": 2
+        "endLine": 1,
+        "endColumn": 9
       },
       {
         "ruleId": "no-constant-condition",
@@ -22,7 +22,7 @@
         "nodeType": "ConditionalExpression",
         "source": "something(true ? 1 : 0);",
         "endLine": 5,
-        "endColumn": 23
+        "endColumn": 15
       }
     ],
     "errorCount": 2,
```

**Note:** I don't know how the reported `"source"` properties are supposed to work, so I can't tell whether they are correct or not.

Visual representation of the problem:

![screenshot from 2017-10-07 14-53-15](https://user-images.githubusercontent.com/2142817/31308016-4e871674-ab6f-11e7-828b-e0f40ed697d5.png)

Notice how much more than the constant conditions are underlined.

See also: https://github.com/steelbrain/linter-ui-default/issues/398#issuecomment-331632791 and onwards.

Pull request description:
Fix: change err report in constant condition (fixes #9398)

**What is the purpose of this pull request? (put an "X" next to item)**
[X] Bug fix ([template](https://raw.githubusercontent.com/eslint/eslint/master/templates/bug-report.md))

**What did you do? Please include the actual source code causing the issue.**
To update the node in the report so that the error underlines in code editor linter is more accurate.

The node type in the report had to be updated as well.

**What did you expect to happen?**
For example, from the issue - with this fix, the linter looks like so
<img width="374" alt="screen shot 2017-10-13 at 11 14 49 pm" src="https://user-images.githubusercontent.com/3211873/31572120-8f161d64-b06c-11e7-81ec-2da71289dada.png">




Patch:
diff --git a/docs/developer-guide/contributing/pull-requests.md b/docs/developer-guide/contributing/pull-requests.md
index 3fb32146d..07a42b697 100644
--- a/docs/developer-guide/contributing/pull-requests.md
+++ b/docs/developer-guide/contributing/pull-requests.md
@@ -77,7 +77,7 @@ Here are some good commit message summary examples:
 ```
 Build: Update Travis to only test Node 0.10 (refs #734)
 Fix: Semi rule incorrectly flagging extra semicolon (fixes #840)
-Upgrade: Esprima to 1.2, switch to using Esprima comment attachment (fixes #730)
+Upgrade: Esprima to 1.2, switch to using comment attachment (fixes #730)
 ```
 
 The commit message format is important because these messages are used to create a changelog for each release. The tag and issue number help to create more consistent and useful changelogs.
diff --git a/docs/developer-guide/development-environment.md b/docs/developer-guide/development-environment.md
index afbab5641..0f56f15fa 100644
--- a/docs/developer-guide/development-environment.md
+++ b/docs/developer-guide/development-environment.md
@@ -21,8 +21,6 @@ $ npm install
 
 You must be connected to the Internet for this step to work. You'll see a lot of utilities being downloaded.
 
-If you have an ESLint configuration file in your home directory (such as `~/.eslintrc.js`), either delete or rename it. This will help ensure that all the tests in Step 5 pass. It will also prevent ESLint from running with an incorrect configuration in case the configuration file in your development environment becomes misnamed, moved, or deleted.
-
 ## Step 3: Add the upstream source
 
 The *upstream source* is the main ESLint repository that active development happens on. While you won't have push access to upstream, you will have pull access, allowing you to pull in the latest code whenever you want.
diff --git a/lib/rules/generator-star-spacing.js b/lib/rules/generator-star-spacing.js
index 5c6120224..a718b59af 100644
--- a/lib/rules/generator-star-spacing.js
+++ b/lib/rules/generator-star-spacing.js
@@ -68,7 +68,7 @@ module.exports = {
 
         /**
          * Returns resolved option definitions based on an option and defaults
-         * 
+         *
          * @param {any} option - The option object or string value
          * @param {Object} defaults - The defaults to use if options are not present
          * @returns {Object} the resolved object definition
@@ -121,7 +121,7 @@ module.exports = {
 
         /**
          * Checks the spacing between two tokens before or after the star token.
-         * 
+         *
          * @param {string} kind Either "named", "anonymous", or "method"
          * @param {string} side Either "before" or "after".
          * @param {Token} leftToken `function` keyword token if side is "before", or
@@ -161,7 +161,7 @@ module.exports = {
 
         /**
          * Enforces the spacing around the star if node is a generator function.
-         * 
+         *
          * @param {ASTNode} node A function expression or declaration node.
          * @returns {void}
          */
diff --git a/lib/rules/no-constant-condition.js b/lib/rules/no-constant-condition.js
index 31e5b372c..0cd445dfd 100644
--- a/lib/rules/no-constant-condition.js
+++ b/lib/rules/no-constant-condition.js
@@ -138,7 +138,7 @@ module.exports = {
         function checkConstantConditionLoopInSet(node) {
             if (loopsInCurrentScope.has(node)) {
                 loopsInCurrentScope.delete(node);
-                context.report({ node, message: "Unexpected constant condition." });
+                context.report({ node: node.test, message: "Unexpected constant condition." });
             }
         }
 
@@ -150,7 +150,7 @@ module.exports = {
          */
         function reportIfConstant(node) {
             if (node.test && isConstant(node.test, true)) {
-                context.report({ node, message: "Unexpected constant condition." });
+                context.report({ node: node.test, message: "Unexpected constant condition." });
             }
         }
 
diff --git a/lib/rules/no-trailing-spaces.js b/lib/rules/no-trailing-spaces.js
index b5d2f8d1b..598bbea4f 100644
--- a/lib/rules/no-trailing-spaces.js
+++ b/lib/rules/no-trailing-spaces.js
@@ -49,7 +49,7 @@ module.exports = {
 
         const options = context.options[0] || {},
             skipBlankLines = options.skipBlankLines || false,
-            ignoreComments = typeof options.ignoreComments === "undefined" || options.ignoreComments;
+            ignoreComments = typeof options.ignoreComments === "boolean" && options.ignoreComments;
 
         /**
          * Report the error message


Test patch:
diff --git a/tests/bench/bench.js b/tests/bench/bench.js
index ccae42fc6..be574cf33 100644
--- a/tests/bench/bench.js
+++ b/tests/bench/bench.js
@@ -33,7 +33,6 @@ function benchmark(grep, times) {
 
 function run(content, times) {
     while(times--) {
-        linter.reset();
         linter.verify(content, config);
     }
 }
diff --git a/tests/bench/xform-rules.js b/tests/bench/xform-rules.js
index fa13aa7f7..9456f3258 100644
--- a/tests/bench/xform-rules.js
+++ b/tests/bench/xform-rules.js
@@ -3,7 +3,7 @@ module.exports = transform;
 var fs = require("fs"),
     path = require("path"),
     through = require("through");
-    
+
 var target = path.resolve(__dirname, "..", "..", "lib", "load-rules.js");
 
 
@@ -23,10 +23,14 @@ function inject() {
     var output = "module.exports = function() {\n";
     output += "    var rules = Object.create(null);\n";
 
-    fs.readdirSync(path.resolve(__dirname, "..", "..", "lib", "rules")).forEach(function(filename) {
-        var basename = path.basename(filename, ".js");
-        output += "    rules[\"" + basename + "\"] = require(\"./rules/" + basename + "\");\n";
-    });
+    fs.readdirSync(path.resolve(__dirname, "..", "..", "lib", "rules"))
+        .filter(function(filename) {
+            return filename.endsWith(".js");
+        })
+        .forEach(function(filename) {
+            var basename = path.basename(filename, ".js");
+            output += "    rules[\"" + basename + "\"] = require(\"./rules/" + basename + "\");\n";
+        });
 
     output += "\n    return rules;\n};";
 
diff --git a/tests/bin/eslint.js b/tests/bin/eslint.js
index 6c7cd0990..7d6bbaf69 100644
--- a/tests/bin/eslint.js
+++ b/tests/bin/eslint.js
@@ -122,21 +122,35 @@ describe("bin/eslint.js", () => {
             return assertExitCode(child, 1);
         });
 
-        it("gives a detailed error message if no config file is found in / or in ~/", () => {
-
-            // Assumes the root and home directories have no .eslintrc file.
-            const child = runESLint(["--stdin"], { cwd: "/" });
-
-            const exitCodePromise = assertExitCode(child, 1);
-            const stdoutPromise = getOutput(child).then(output => {
-                assert.match(output.stderr, /ESLint couldn't find a configuration file/);
-            });
+        it(
+            "gives a detailed error message if no config file is found in /",
+            () => {
+                if (
+                    fs.readdirSync("/").some(
+                        fileName =>
+                            /^\.eslintrc(?:\.(?:js|yaml|yml|json))?$/
+                                .test(fileName)
+                    )
+                ) {
+                    return Promise.resolve(true);
+                }
+                const child = runESLint(
+                    ["--stdin"], { cwd: "/", env: { HOME: "/" } }
+                );
 
-            child.stdin.write("var foo = bar\n");
-            child.stdin.end();
+                const exitCodePromise = assertExitCode(child, 1);
+                const stderrPromise = getOutput(child).then(output => {
+                    assert.match(
+                        output.stderr,
+                        /ESLint couldn't find a configuration file/
+                    );
+                });
 
-            return Promise.all([exitCodePromise, stdoutPromise]);
-        });
+                child.stdin.write("1 < 3;\n");
+                child.stdin.end();
+                return Promise.all([exitCodePromise, stderrPromise]);
+            }
+        );
 
     });
 
diff --git a/tests/lib/rules/no-constant-condition.js b/tests/lib/rules/no-constant-condition.js
index b113ebb09..9f7bc4c0d 100644
--- a/tests/lib/rules/no-constant-condition.js
+++ b/tests/lib/rules/no-constant-condition.js
@@ -71,90 +71,90 @@ ruleTester.run("no-constant-condition", rule, {
         "function* foo() { for (let x = yield; ; x++) { yield; }}"
     ],
     invalid: [
-        { code: "for(;true;);", errors: [{ message: "Unexpected constant condition.", type: "ForStatement" }] },
-        { code: "do{}while(true)", errors: [{ message: "Unexpected constant condition.", type: "DoWhileStatement" }] },
-        { code: "do{}while(t = -2)", errors: [{ message: "Unexpected constant condition.", type: "DoWhileStatement" }] },
-        { code: "true ? 1 : 2;", errors: [{ message: "Unexpected constant condition.", type: "ConditionalExpression" }] },
-        { code: "q = 0 ? 1 : 2;", errors: [{ message: "Unexpected constant condition.", type: "ConditionalExpression" }] },
-        { code: "(q = 0) ? 1 : 2;", errors: [{ message: "Unexpected constant condition.", type: "ConditionalExpression" }] },
-        { code: "if(-2);", errors: [{ message: "Unexpected constant condition.", type: "IfStatement" }] },
-        { code: "if(true);", errors: [{ message: "Unexpected constant condition.", type: "IfStatement" }] },
-        { code: "if({});", errors: [{ message: "Unexpected constant condition.", type: "IfStatement" }] },
-        { code: "if(0 < 1);", errors: [{ message: "Unexpected constant condition.", type: "IfStatement" }] },
-        { code: "if(0 || 1);", errors: [{ message: "Unexpected constant condition.", type: "IfStatement" }] },
-        { code: "if(a, 1);", errors: [{ message: "Unexpected constant condition.", type: "IfStatement" }] },
-
-        { code: "while([]);", errors: [{ message: "Unexpected constant condition.", type: "WhileStatement" }] },
-        { code: "while(~!0);", errors: [{ message: "Unexpected constant condition.", type: "WhileStatement" }] },
-        { code: "while(x = 1);", errors: [{ message: "Unexpected constant condition.", type: "WhileStatement" }] },
-        { code: "while(function(){});", errors: [{ message: "Unexpected constant condition.", type: "WhileStatement" }] },
-        { code: "while(true);", errors: [{ message: "Unexpected constant condition.", type: "WhileStatement" }] },
-        { code: "while(() => {});", errors: [{ message: "Unexpected constant condition.", type: "WhileStatement" }] },
+        { code: "for(;true;);", errors: [{ message: "Unexpected constant condition.", type: "Literal" }] },
+        { code: "do{}while(true)", errors: [{ message: "Unexpected constant condition.", type: "Literal" }] },
+        { code: "do{}while(t = -2)", errors: [{ message: "Unexpected constant condition.", type: "AssignmentExpression" }] },
+        { code: "true ? 1 : 2;", errors: [{ message: "Unexpected constant condition.", type: "Literal" }] },
+        { code: "q = 0 ? 1 : 2;", errors: [{ message: "Unexpected constant condition.", type: "Literal" }] },
+        { code: "(q = 0) ? 1 : 2;", errors: [{ message: "Unexpected constant condition.", type: "AssignmentExpression" }] },
+        { code: "if(-2);", errors: [{ message: "Unexpected constant condition.", type: "UnaryExpression" }] },
+        { code: "if(true);", errors: [{ message: "Unexpected constant condition.", type: "Literal" }] },
+        { code: "if({});", errors: [{ message: "Unexpected constant condition.", type: "ObjectExpression" }] },
+        { code: "if(0 < 1);", errors: [{ message: "Unexpected constant condition.", type: "BinaryExpression" }] },
+        { code: "if(0 || 1);", errors: [{ message: "Unexpected constant condition.", type: "LogicalExpression" }] },
+        { code: "if(a, 1);", errors: [{ message: "Unexpected constant condition.", type: "SequenceExpression" }] },
+
+        { code: "while([]);", errors: [{ message: "Unexpected constant condition.", type: "ArrayExpression" }] },
+        { code: "while(~!0);", errors: [{ message: "Unexpected constant condition.", type: "UnaryExpression" }] },
+        { code: "while(x = 1);", errors: [{ message: "Unexpected constant condition.", type: "AssignmentExpression" }] },
+        { code: "while(function(){});", errors: [{ message: "Unexpected constant condition.", type: "FunctionExpression" }] },
+        { code: "while(true);", errors: [{ message: "Unexpected constant condition.", type: "Literal" }] },
+        { code: "while(() => {});", errors: [{ message: "Unexpected constant condition.", type: "ArrowFunctionExpression" }] },
 
         // #5228 , typeof conditions
-        { code: "if(typeof x){}", errors: [{ message: "Unexpected constant condition.", type: "IfStatement" }] },
-        { code: "if(typeof 'abc' === 'string'){}", errors: [{ message: "Unexpected constant condition.", type: "IfStatement" }] },
-        { code: "if(a = typeof b){}", errors: [{ message: "Unexpected constant condition.", type: "IfStatement" }] },
-        { code: "if(a, typeof b){}", errors: [{ message: "Unexpected constant condition.", type: "IfStatement" }] },
-        { code: "if(typeof 'a' == 'string' || typeof 'b' == 'string'){}", errors: [{ message: "Unexpected constant condition.", type: "IfStatement" }] },
-        { code: "while(typeof x){}", errors: [{ message: "Unexpected constant condition.", type: "WhileStatement" }] },
+        { code: "if(typeof x){}", errors: [{ message: "Unexpected constant condition.", type: "UnaryExpression" }] },
+        { code: "if(typeof 'abc' === 'string'){}", errors: [{ message: "Unexpected constant condition.", type: "BinaryExpression" }] },
+        { code: "if(a = typeof b){}", errors: [{ message: "Unexpected constant condition.", type: "AssignmentExpression" }] },
+        { code: "if(a, typeof b){}", errors: [{ message: "Unexpected constant condition.", type: "SequenceExpression" }] },
+        { code: "if(typeof 'a' == 'string' || typeof 'b' == 'string'){}", errors: [{ message: "Unexpected constant condition.", type: "LogicalExpression" }] },
+        { code: "while(typeof x){}", errors: [{ message: "Unexpected constant condition.", type: "UnaryExpression" }] },
 
         // #5726, void conditions
-        { code: "if(1 || void x);", errors: [{ message: "Unexpected constant condition.", type: "IfStatement" }] },
-        { code: "if(void x);", errors: [{ message: "Unexpected constant condition.", type: "IfStatement" }] },
-        { code: "if(y = void x);", errors: [{ message: "Unexpected constant condition.", type: "IfStatement" }] },
-        { code: "if(x, void x);", errors: [{ message: "Unexpected constant condition.", type: "IfStatement" }] },
-        { code: "if(void x === void y);", errors: [{ message: "Unexpected constant condition.", type: "IfStatement" }] },
-        { code: "if(void x && a);", errors: [{ message: "Unexpected constant condition.", type: "IfStatement" }] },
-        { code: "if(a && void x);", errors: [{ message: "Unexpected constant condition.", type: "IfStatement" }] },
+        { code: "if(1 || void x);", errors: [{ message: "Unexpected constant condition.", type: "LogicalExpression" }] },
+        { code: "if(void x);", errors: [{ message: "Unexpected constant condition.", type: "UnaryExpression" }] },
+        { code: "if(y = void x);", errors: [{ message: "Unexpected constant condition.", type: "AssignmentExpression" }] },
+        { code: "if(x, void x);", errors: [{ message: "Unexpected constant condition.", type: "SequenceExpression" }] },
+        { code: "if(void x === void y);", errors: [{ message: "Unexpected constant condition.", type: "BinaryExpression" }] },
+        { code: "if(void x && a);", errors: [{ message: "Unexpected constant condition.", type: "LogicalExpression" }] },
+        { code: "if(a && void x);", errors: [{ message: "Unexpected constant condition.", type: "LogicalExpression" }] },
 
         // #5693
-        { code: "if(false && abc==='str'){}", errors: [{ message: "Unexpected constant condition.", type: "IfStatement" }] },
-        { code: "if(true || abc==='str'){}", errors: [{ message: "Unexpected constant condition.", type: "IfStatement" }] },
-        { code: "if(abc==='str' || true){}", errors: [{ message: "Unexpected constant condition.", type: "IfStatement" }] },
-        { code: "if(abc==='str' || true || def ==='str'){}", errors: [{ message: "Unexpected constant condition.", type: "IfStatement" }] },
-        { code: "if(false || true){}", errors: [{ message: "Unexpected constant condition.", type: "IfStatement" }] },
-        { code: "if(typeof abc==='str' || true){}", errors: [{ message: "Unexpected constant condition.", type: "IfStatement" }] },
+        { code: "if(false && abc==='str'){}", errors: [{ message: "Unexpected constant condition.", type: "LogicalExpression" }] },
+        { code: "if(true || abc==='str'){}", errors: [{ message: "Unexpected constant condition.", type: "LogicalExpression" }] },
+        { code: "if(abc==='str' || true){}", errors: [{ message: "Unexpected constant condition.", type: "LogicalExpression" }] },
+        { code: "if(abc==='str' || true || def ==='str'){}", errors: [{ message: "Unexpected constant condition.", type: "LogicalExpression" }] },
+        { code: "if(false || true){}", errors: [{ message: "Unexpected constant condition.", type: "LogicalExpression" }] },
+        { code: "if(typeof abc==='str' || true){}", errors: [{ message: "Unexpected constant condition.", type: "LogicalExpression" }] },
 
         {
             code: "function* foo(){while(true){} yield 'foo';}",
-            errors: [{ message: "Unexpected constant condition.", type: "WhileStatement" }]
+            errors: [{ message: "Unexpected constant condition.", type: "Literal" }]
         },
         {
             code: "function* foo(){while(true){if (true) {yield 'foo';}}}",
-            errors: [{ message: "Unexpected constant condition.", type: "IfStatement" }]
+            errors: [{ message: "Unexpected constant condition.", type: "Literal" }]
         },
         {
             code: "function* foo(){while(true){yield 'foo';} while(true) {}}",
-            errors: [{ message: "Unexpected constant condition.", type: "WhileStatement" }]
+            errors: [{ message: "Unexpected constant condition.", type: "Literal" }]
         },
         {
             code: "var a = function* foo(){while(true){} yield 'foo';}",
-            errors: [{ message: "Unexpected constant condition.", type: "WhileStatement" }]
+            errors: [{ message: "Unexpected constant condition.", type: "Literal" }]
         },
         {
             code: "while (true) { function* foo() {yield;}}",
-            errors: [{ message: "Unexpected constant condition.", type: "WhileStatement" }]
+            errors: [{ message: "Unexpected constant condition.", type: "Literal" }]
         },
         {
             code: "function* foo(){if (true) {yield 'foo';}}",
-            errors: [{ message: "Unexpected constant condition.", type: "IfStatement" }]
+            errors: [{ message: "Unexpected constant condition.", type: "Literal" }]
         },
         {
             code: "function* foo() {for (let foo = yield; true;) {}}",
-            errors: [{ message: "Unexpected constant condition.", type: "ForStatement" }]
+            errors: [{ message: "Unexpected constant condition.", type: "Literal" }]
         },
         {
             code: "function* foo() {for (foo = yield; true;) {}}",
-            errors: [{ message: "Unexpected constant condition.", type: "ForStatement" }]
+            errors: [{ message: "Unexpected constant condition.", type: "Literal" }]
         },
         {
             code: "function foo() {while (true) {function* bar() {while (true) {yield;}}}}",
-            errors: [{ message: "Unexpected constant condition.", type: "WhileStatement" }]
+            errors: [{ message: "Unexpected constant condition.", type: "Literal" }]
         },
         {
             code: "function* foo() { for (let foo = 1 + 2 + 3 + (yield); true; baz) {}}",
-            errors: [{ message: "Unexpected constant condition.", type: "ForStatement" }]
+            errors: [{ message: "Unexpected constant condition.", type: "Literal" }]
         }
     ]
 });
diff --git a/tests/lib/rules/no-trailing-spaces.js b/tests/lib/rules/no-trailing-spaces.js
index d33af0c25..37c81f327 100644
--- a/tests/lib/rules/no-trailing-spaces.js
+++ b/tests/lib/rules/no-trailing-spaces.js
@@ -71,6 +71,14 @@ ruleTester.run("no-trailing-spaces", rule, {
             code: "// Trailing comment test. ",
             options: [{ ignoreComments: true }]
         },
+        {
+            code: "// Trailing comment test.",
+            options: [{ ignoreComments: false }]
+        },
+        {
+            code: "// Trailing comment test.",
+            options: []
+        },
         {
             code: "/* \nTrailing comments test. \n*/",
             options: [{ ignoreComments: true }]
@@ -484,6 +492,19 @@ ruleTester.run("no-trailing-spaces", rule, {
                     column: 20
                 }
             ]
+        },
+        {
+            code: "// Trailing comment default test. ",
+            output: "// Trailing comment default test.",
+            options: [],
+            errors: [
+                {
+                    message: "Trailing spaces not allowed.",
+                    type: "Program",
+                    line: 1,
+                    column: 34
+                }
+            ]
         }
     ]
 });