Repository: eslint/eslint (js)

Issue:
"Expected NaN spaces" indent error with multiline string and arguments: 'off'
**Tell us about your environment**

* **ESLint Version:** 4.4.0
* **Node Version:** 6.10.3
* **npm Version:** 3.10.10

**What parser (default, Babel-ESLint, etc.) are you using?** default

**Please show your full configuration:**

<details>
<summary>Configuration</summary>

```js
module.exports = {
  env: {
    es6: true,
  },
  rules: {
    indent: ['error', 2, {
      CallExpression: {
        arguments: 'off',
      },
    }],
  },
};
```

</details>

**What did you do? Please include the actual source code causing the issue.**

This is a reduced test case showing the issue:
```js
a(`b
c`, function() {
  d;
});
```

**What did you expect to happen?**

Ideally no error, but if there is an error, it should be sensible.

**What actually happened? Please include the actual, raw output from ESLint.**
eslint gives this error:
```
3:1  error  Expected indentation of NaN spaces but found 2  indent
```

Running `eslint --fix` treats NaN as 0 and removes all indentation from all affected lines.

Changing the multiline string to a single-line string fixes the issue, and removing `arguments: 'off'` in the config also fixes the issue.

**Context:**
This type of code came up when converting multiline strings from CoffeeScript ([example](http://decaffeinate-project.org/repl/#?evaluate=true&stage=full&code=it%20'this%20is%20a%20multiline%0A%20%20%20%20test%20name'%2C%20-%3E%0A%20%20expect(1).eql%201%0A%20%20return)), and it appears a number of times in my codebase. A workaround is to rewrite the multiline strings as single-line strings, but certainly would be nice for this to be fixed within eslint.

Pull request description:
Update: avoid requiring NaN spaces of indentation (fixes #9083)
<!--
    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] Bug fix (https://github.com/eslint/eslint/issues/9083)

<!--
    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 (http://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)**

This fixes an issue where the `indent` rule would sometimes expect "NaN spaces" of indentation when an `"off"` option was used. The value `"off"` was incorrectly getting used as a numeric offset, so it was cast to a number, resulting in `NaN`.

**Is there anything you'd like reviewers to focus on?**

Nothing in particular


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9aa808d68..2ca850a96 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+v4.4.1 - August 7, 2017
+
+* ec93614 Fix: no-multi-spaces to avoid reporting consecutive tabs (fixes #9079) (#9087) (Teddy Katz)
+
 v4.4.0 - August 5, 2017
 
 * 89196fd Upgrade: Espree to 3.5.0 (#9074) (Gyandeep Singh)
diff --git a/lib/rules/indent.js b/lib/rules/indent.js
index 45332f447..429567ee5 100644
--- a/lib/rules/indent.js
+++ b/lib/rules/indent.js
@@ -783,7 +783,7 @@ module.exports = {
             offsets.setDesiredOffsets(
                 [startToken.range[1], endToken.range[0]],
                 startToken,
-                offset === "first" ? 1 : offset
+                typeof offset === "number" ? offset : 1
             );
             offsets.setDesiredOffset(endToken, startToken, 0);
 
diff --git a/lib/rules/no-multi-spaces.js b/lib/rules/no-multi-spaces.js
index 73e514335..84f1b5018 100644
--- a/lib/rules/no-multi-spaces.js
+++ b/lib/rules/no-multi-spaces.js
@@ -76,8 +76,11 @@ module.exports = {
                     }
                     const rightToken = tokensAndComments[leftIndex + 1];
 
-                    // Ignore tokens that have less than 2 spaces between them or are on different lines
-                    if (leftToken.range[1] + 2 > rightToken.range[0] || leftToken.loc.end.line < rightToken.loc.start.line) {
+                    // Ignore tokens that don't have 2 spaces between them or are on different lines
+                    if (
+                        !sourceCode.text.slice(leftToken.range[1], rightToken.range[0]).includes("  ") ||
+                        leftToken.loc.end.line < rightToken.loc.start.line
+                    ) {
                         return;
                     }
 
diff --git a/package.json b/package.json
index 3d4e1795c..541cb8d18 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "eslint",
-  "version": "4.4.0",
+  "version": "4.4.1",
   "author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
   "description": "An AST-based pattern checker for JavaScript.",
   "bin": {
diff --git a/templates/blogpost.md.ejs b/templates/blogpost.md.ejs
index b33f36199..0f0a2f752 100644
--- a/templates/blogpost.md.ejs
+++ b/templates/blogpost.md.ejs
@@ -7,7 +7,7 @@ tags:
 ---
 # ESLint v<%= version %> released
 
-We just pushed ESLint v<%- version %>, which is a <%- type %> release upgrade of ESLint. This release <% if (type !== "patch") { %>adds some new features and<% } %> fixes several bugs found in the previous release. <% if (type === "major") { %>This release also has some breaking changes, so please read the following closely. <% } %>
+We just pushed ESLint v<%- version %>, which is a <%- type %> release upgrade of ESLint. This release <% if (type !== "patch") { %>adds some new features and<% } %>fixes several bugs found in the previous release. <% if (type === "major") { %>This release also has some breaking changes, so please read the following closely. <% } %>
 
 <%
 const RULE_REGEX = new RegExp(`\`?\\b(${ruleList.join("|")})\\b\`?`, "g");


Test patch:
diff --git a/tests/lib/rules/indent.js b/tests/lib/rules/indent.js
index e2e843bce..be026fe51 100644
--- a/tests/lib/rules/indent.js
+++ b/tests/lib/rules/indent.js
@@ -4915,6 +4915,24 @@ ruleTester.run("indent", rule, {
                     );
                 }
             `
+        },
+        {
+            code: unIndent`
+                a(b
+                  , c
+                )
+            `,
+            options: [2, { CallExpression: { arguments: "off" } }]
+        },
+        {
+            code: unIndent`
+                a(
+                  new B({
+                    c,
+                  })
+                );
+            `,
+            options: [2, { CallExpression: { arguments: "off" } }]
         }
     ],
 
diff --git a/tests/lib/rules/no-multi-spaces.js b/tests/lib/rules/no-multi-spaces.js
index d3dcf61f5..ea726fbdd 100644
--- a/tests/lib/rules/no-multi-spaces.js
+++ b/tests/lib/rules/no-multi-spaces.js
@@ -101,7 +101,9 @@ ruleTester.run("no-multi-spaces", rule, {
         "foo\n \f  bar",
 
         // https://github.com/eslint/eslint/issues/9001
-        "a".repeat(2e5)
+        "a".repeat(2e5),
+
+        "foo\t\t+bar"
     ],
 
     invalid: [