Repository: eslint/eslint (js)

Issue:
Enhance padding-line-between-statements with "iife" statement type
**What rule do you want to change?**

padding-line-between-statements

**Does this change cause the rule to produce more or fewer warnings?**

Either way, depending on configuration. Does not produce more warnings by default as it is a new option.

**How will the change be implemented? (New option, new default behavior, etc.)?**

New statement type option: "iife".

**Please provide some example code that this change will affect:**

```js
/* eslint padding-line-between-statements: [error, [{ blankLine: "always", prev: "iife", next: "*" }]] */

// IIFE example:

(function() {
}());
foo();

// Other block-like:

if (true) {
}
foo();
```

**What does the rule currently do for this code?**

Nothing (well, schema error).

Currently, it is possible to use the "block-like" statement type, but that will also cover IfStatement, WhileStatement, DoWhileStatement, ForStatement, other function declarations, etc., meaning the second example would also be enforced. It is not possible to target just IIFEs.

**What will the rule do after it's changed?**

Users can target IIFEs as previous or next statements in the rule.

N.B. The rule already detects IIFEs as part of "block-like", so this addition will be pretty trivial-- the new statement type's "test" would simply be to call the internal IIFE checker.

----------

Inspired by #10843.

I'll champion this.

Pull request:
Update: iife statement type for padding-line-between-statements (fixes #10853)
<!--
    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
[ ] 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))
[x] 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.)
-->

See #10853.

<!--
    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)**

Added "iife" statement type to `padding-line-between-statements` rule.

**Is there anything you'd like reviewers to focus on?**

* Any issues with the documentation changes I've added?
* Are there any more tests I should add?


Patch:
diff --git a/docs/developer-guide/README.md b/docs/developer-guide/README.md
index 2070b2da1..ea1943099 100644
--- a/docs/developer-guide/README.md
+++ b/docs/developer-guide/README.md
@@ -34,7 +34,7 @@ You're finally ready to start working with rules. You may want to fix an existin
 
 You've developed library-specific rules for ESLint and you want to share it with the community. You can publish an ESLint plugin on npm.
 
-## Section 6: [Working with Parsers](working-with-parsers.md)
+## Section 6: [Working with Custom Parsers](working-with-custom-parsers.md)
 
 If you aren't going to use the default parser of ESLint, this section explains about using custom parsers.
 
diff --git a/docs/rules/no-tabs.md b/docs/rules/no-tabs.md
index 691b2f2af..4e02d9a04 100644
--- a/docs/rules/no-tabs.md
+++ b/docs/rules/no-tabs.md
@@ -9,14 +9,14 @@ This rule looks for tabs anywhere inside a file: code, comments or anything else
 Examples of **incorrect** code for this rule:
 
 ```js
-var a /t= 2;
+var a \t= 2;
 
 /**
-* /t/t it's a test function
+* \t\t it's a test function
 */
 function test(){}
 
-var x = 1; // /t test
+var x = 1; // \t test
 ```
 
 Examples of **correct** code for this rule:
@@ -32,9 +32,29 @@ function test(){}
 var x = 1; // test
 ```
 
+### Options
+
+This rule has an optional object option with the following properties:
+
+* `allowIndentationTabs` (default: false): If this is set to true, then the rule will not report tabs used for indentation.
+
+#### allowIndentationTabs
+
+Examples of **correct** code for this rule with the `allowIndentationTabs: true` option:
+
+```js
+/* eslint no-tabs: ["error", { allowIndentationTabs: true }] */
+
+function test() {
+\tdoSomething();
+}
+
+\t// comment with leading indentation tab
+```
+
 ## When Not To Use It
 
-If you have established a standard where having tabs is fine.
+If you have established a standard where having tabs is fine, then you can disable this rule.
 
 ## Compatibility
 
diff --git a/docs/rules/no-unsafe-finally.md b/docs/rules/no-unsafe-finally.md
index 1783e501f..fb3bb1ea5 100644
--- a/docs/rules/no-unsafe-finally.md
+++ b/docs/rules/no-unsafe-finally.md
@@ -49,7 +49,7 @@ JavaScript suspends the control flow statements of `try` and `catch` blocks unti
 // We expect this function to return 0 from try block.
 (() => {
   label: try {
-    return 0; // 1 is returned but suspended until finally block ends
+    return 0; // 0 is returned but suspended until finally block ends
   } finally {
     break label; // It breaks out the try-finally block, before 0 is returned.
   }
diff --git a/docs/rules/padding-line-between-statements.md b/docs/rules/padding-line-between-statements.md
index c56259734..390dada29 100644
--- a/docs/rules/padding-line-between-statements.md
+++ b/docs/rules/padding-line-between-statements.md
@@ -20,9 +20,9 @@ function foo() {
 
 ## Rule Details
 
-This rule does nothing if no configuration.
+This rule does nothing if no configurations are provided.
 
-A configuration is an object which has 3 properties; `blankLine`, `prev` and `next`. For example, `{ blankLine: "always", prev: "var", next: "return" }` means "it requires one or more blank lines between a variable declaration and a `return` statement."
+A configuration is an object which has 3 properties; `blankLine`, `prev` and `next`. For example, `{ blankLine: "always", prev: "var", next: "return" }` means "one or more blank lines are required between a variable declaration and a `return` statement."
 You can supply any number of configurations. If a statement pair matches multiple configurations, the last matched configuration will be used.
 
 ```json
@@ -46,11 +46,11 @@ You can supply any number of configurations. If a statement pair matches multipl
 - `STATEMENT_TYPE` is one of the following, or an array of the following.
     - `"*"` is wildcard. This matches any statements.
     - `"block"` is lonely blocks.
-    - `"block-like"` is block like statements. This matches statements that the last token is the closing brace of blocks; e.g. `{ }`, `if (a) { }`, and `while (a) { }`.
+    - `"block-like"` is block like statements. This matches statements that the last token is the closing brace of blocks; e.g. `{ }`, `if (a) { }`, and `while (a) { }`. Also matches immediately invoked function expression statements.
     - `"break"` is `break` statements.
     - `"case"` is `case` labels.
-    - `"cjs-export"` is `export` statements of CommonJS; e.g. `module.exports = 0`, `module.exports.foo = 1`, and `exports.foo = 2`. This is the special cases of assignment.
-    - `"cjs-import"` is `import` statements of CommonJS; e.g. `const foo = require("foo")`. This is the special cases of variable declarations.
+    - `"cjs-export"` is `export` statements of CommonJS; e.g. `module.exports = 0`, `module.exports.foo = 1`, and `exports.foo = 2`. This is a special case of assignment.
+    - `"cjs-import"` is `import` statements of CommonJS; e.g. `const foo = require("foo")`. This is a special case of variable declarations.
     - `"class"` is `class` declarations.
     - `"const"` is `const` variable declarations.
     - `"continue"` is `continue` statements.
@@ -64,6 +64,7 @@ You can supply any number of configurations. If a statement pair matches multipl
     - `"for"` is `for` loop families. This matches all statements that the first token is `for` keyword.
     - `"function"` is function declarations.
     - `"if"` is `if` statements.
+    - `"iife"` is immediately invoked function expression statements. This matches calls on a function expression, optionally prefixed with a unary operator.
     - `"import"` is `import` declarations.
     - `"let"` is `let` variable declarations.
     - `"multiline-block-like"` is block like statements. This is the same as `block-like` type, but only if the block is multiline.
diff --git a/docs/rules/space-infix-ops.md b/docs/rules/space-infix-ops.md
index f0381877d..406e2030c 100644
--- a/docs/rules/space-infix-ops.md
+++ b/docs/rules/space-infix-ops.md
@@ -73,3 +73,7 @@ var {a = 0} = bar;
 
 function foo(a = 0) { }
 ```
+
+## When Not To Use It
+
+You can turn this rule off if you are not concerned with the consistency of spacing around infix operators.
diff --git a/docs/user-guide/command-line-interface.md b/docs/user-guide/command-line-interface.md
index 7de5a50a1..62ecd3c20 100644
--- a/docs/user-guide/command-line-interface.md
+++ b/docs/user-guide/command-line-interface.md
@@ -401,7 +401,7 @@ Store the info about processed files in order to only operate on the changed one
 
 **Note:** If you run ESLint with `--cache` and then run ESLint without `--cache`, the `.eslintcache` file will be deleted. This is necessary because the results of the lint might change and make `.eslintcache` invalid. If you want to control when the cache file is deleted, then use `--cache-location` to specify an alternate location for the cache file.
 
-**Note:**: As of now, only the results for successfully linted files are stored in the cache. Files which fail linting are not stored in the cache, so they will be linted every time.
+**Note:**: Autofixed files are not placed in the cache. Subsequent linting that does not trigger an autofix will place it in the cache.
 
 #### `--cache-file`
 
diff --git a/lib/rules/no-extra-bind.js b/lib/rules/no-extra-bind.js
index b8376adfc..6d6cad13e 100644
--- a/lib/rules/no-extra-bind.js
+++ b/lib/rules/no-extra-bind.js
@@ -10,6 +10,12 @@
 
 const astUtils = require("../util/ast-utils");
 
+//------------------------------------------------------------------------------
+// Helpers
+//------------------------------------------------------------------------------
+
+const SIDE_EFFECT_FREE_NODE_TYPES = new Set(["Literal", "Identifier", "ThisExpression", "FunctionExpression"]);
+
 //------------------------------------------------------------------------------
 // Rule Definition
 //------------------------------------------------------------------------------
@@ -35,6 +41,18 @@ module.exports = {
     create(context) {
         let scopeInfo = null;
 
+        /**
+         * Checks if a node is free of side effects.
+         *
+         * This check is stricter than it needs to be, in order to keep the implementation simple.
+         *
+         * @param {ASTNode} node A node to check.
+         * @returns {boolean} True if the node is known to be side-effect free, false otherwise.
+         */
+        function isSideEffectFree(node) {
+            return SIDE_EFFECT_FREE_NODE_TYPES.has(node.type);
+        }
+
         /**
          * Reports a given function node.
          *
@@ -48,6 +66,10 @@ module.exports = {
                 messageId: "unexpected",
                 loc: node.parent.property.loc.start,
                 fix(fixer) {
+                    if (node.parent.parent.arguments.length && !isSideEffectFree(node.parent.parent.arguments[0])) {
+                        return null;
+                    }
+
                     const firstTokenToRemove = context.getSourceCode()
                         .getFirstTokenBetween(node.parent.object, node.parent.property, astUtils.isNotClosingParenToken);
 
diff --git a/lib/rules/no-tabs.js b/lib/rules/no-tabs.js
index 08a8fa5b7..c22a94da3 100644
--- a/lib/rules/no-tabs.js
+++ b/lib/rules/no-tabs.js
@@ -8,7 +8,9 @@
 //------------------------------------------------------------------------------
 // Helpers
 //------------------------------------------------------------------------------
-const regex = /\t/;
+
+const tabRegex = /\t+/g;
+const anyNonWhitespaceRegex = /\S/;
 
 //------------------------------------------------------------------------------
 // Public Interface
@@ -22,21 +24,36 @@ module.exports = {
             recommended: false,
             url: "https://eslint.org/docs/rules/no-tabs"
         },
-        schema: []
+        schema: [{
+            type: "object",
+            properties: {
+                allowIndentationTabs: {
+                    type: "boolean"
+                }
+            },
+            additionalProperties: false
+        }]
     },
 
     create(context) {
+        const sourceCode = context.getSourceCode();
+        const allowIndentationTabs = context.options && context.options[0] && context.options[0].allowIndentationTabs;
+
         return {
             Program(node) {
-                context.getSourceCode().getLines().forEach((line, index) => {
-                    const match = regex.exec(line);
+                sourceCode.getLines().forEach((line, index) => {
+                    let match;
+
+                    while ((match = tabRegex.exec(line)) !== null) {
+                        if (allowIndentationTabs && !anyNonWhitespaceRegex.test(line.slice(0, match.index))) {
+                            continue;
+                        }
 
-                    if (match) {
                         context.report({
                             node,
                             loc: {
                                 line: index + 1,
-                                column: match.index + 1
+                                column: match.index
                             },
                             message: "Unexpected tab character."
                         });
diff --git a/lib/rules/no-unused-vars.js b/lib/rules/no-unused-vars.js
index fff3e33d9..6f36813ac 100644
--- a/lib/rules/no-unused-vars.js
+++ b/lib/rules/no-unused-vars.js
@@ -469,7 +469,7 @@ module.exports = {
             const posteriorParams = params.slice(params.indexOf(variable) + 1);
 
             // If any used parameters occur after this parameter, do not report.
-            return !posteriorParams.some(v => v.references.length > 0);
+            return !posteriorParams.some(v => v.references.length > 0 || v.eslintUsed);
         }
 
         /**
diff --git a/lib/rules/one-var.js b/lib/rules/one-var.js
index 15b664d77..3efd0f27f 100644
--- a/lib/rules/one-var.js
+++ b/lib/rules/one-var.js
@@ -314,6 +314,11 @@ module.exports = {
         function splitDeclarations(declaration) {
             return fixer => declaration.declarations.map(declarator => {
                 const tokenAfterDeclarator = sourceCode.getTokenAfter(declarator);
+
+                if (tokenAfterDeclarator === null) {
+                    return null;
+                }
+
                 const afterComma = sourceCode.getTokenAfter(tokenAfterDeclarator, { includeComments: true });
 
                 if (tokenAfterDeclarator.value !== ",") {
diff --git a/lib/rules/padding-line-between-statements.js b/lib/rules/padding-line-between-statements.js
index f571e1e2e..4af85fef0 100644
--- a/lib/rules/padding-line-between-statements.js
+++ b/lib/rules/padding-line-between-statements.js
@@ -353,6 +353,9 @@ const StatementTypes = {
             node.type === "ExpressionStatement" &&
             !isDirectivePrologue(node, sourceCode)
     },
+    iife: {
+        test: isIIFEStatement
+    },
     "multiline-block-like": {
         test: (node, sourceCode) =>
             node.loc.start.line !== node.loc.end.line &&
diff --git a/lib/rules/space-infix-ops.js b/lib/rules/space-infix-ops.js
index 49b64658d..17b49cc11 100644
--- a/lib/rules/space-infix-ops.js
+++ b/lib/rules/space-infix-ops.js
@@ -34,37 +34,25 @@ module.exports = {
 
     create(context) {
         const int32Hint = context.options[0] ? context.options[0].int32Hint === true : false;
-
-        const OPERATORS = [
-            "*", "/", "%", "+", "-", "<<", ">>", ">>>", "<", "<=", ">", ">=", "in",
-            "instanceof", "==", "!=", "===", "!==", "&", "^", "|", "&&", "||", "=",
-            "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=", "&=", "^=", "|=",
-            "?", ":", ",", "**"
-        ];
-
         const sourceCode = context.getSourceCode();
 
         /**
          * Returns the first token which violates the rule
          * @param {ASTNode} left - The left node of the main node
          * @param {ASTNode} right - The right node of the main node
+         * @param {string} op - The operator of the main node
          * @returns {Object} The violator token or null
          * @private
          */
-        function getFirstNonSpacedToken(left, right) {
-            const tokens = sourceCode.getTokensBetween(left, right, 1);
-
-            for (let i = 1, l = tokens.length - 1; i < l; ++i) {
-                const op = tokens[i];
-
-                if (
-                    (op.type === "Punctuator" || op.type === "Keyword") &&
-                    OPERATORS.indexOf(op.value) >= 0 &&
-                    (tokens[i - 1].range[1] >= op.range[0] || op.range[1] >= tokens[i + 1].range[0])
-                ) {
-                    return op;
-                }
+        function getFirstNonSpacedToken(left, right, op) {
+            const operator = sourceCode.getFirstTokenBetween(left, right, token => token.value === op);
+            const prev = sourceCode.getTokenBefore(operator);
+            const next = sourceCode.getTokenAfter(operator);
+
+            if (!sourceCode.isSpaceBetweenTokens(prev, operator) || !sourceCode.isSpaceBetweenTokens(operator, next)) {
+                return operator;
             }
+
             return null;
         }
 
@@ -110,7 +98,10 @@ module.exports = {
             const leftNode = (node.left.typeAnnotation) ? node.left.typeAnnotation : node.left;
             const rightNode = node.right;
 
-            const nonSpacedNode = getFirstNonSpacedToken(leftNode, rightNode);
+            // search for = in AssignmentPattern nodes
+            const operator = node.operator || "=";
+
+            const nonSpacedNode = getFirstNonSpacedToken(leftNode, rightNode, operator);
 
             if (nonSpacedNode) {
                 if (!(int32Hint && sourceCode.getText(node).endsWith("|0"))) {
@@ -126,8 +117,8 @@ module.exports = {
          * @private
          */
         function checkConditional(node) {
-            const nonSpacedConsequesntNode = getFirstNonSpacedToken(node.test, node.consequent);
-            const nonSpacedAlternateNode = getFirstNonSpacedToken(node.consequent, node.alternate);
+            const nonSpacedConsequesntNode = getFirstNonSpacedToken(node.test, node.consequent, "?");
+            const nonSpacedAlternateNode = getFirstNonSpacedToken(node.consequent, node.alternate, ":");
 
             if (nonSpacedConsequesntNode) {
                 report(node, nonSpacedConsequesntNode);
@@ -147,7 +138,7 @@ module.exports = {
             const rightNode = node.init;
 
             if (rightNode) {
-                const nonSpacedNode = getFirstNonSpacedToken(leftNode, rightNode);
+                const nonSpacedNode = getFirstNonSpacedToken(leftNode, rightNode, "=");
 
                 if (nonSpacedNode) {
                     report(node, nonSpacedNode);
diff --git a/package.json b/package.json
index e970cf87c..cfc6b1b01 100644
--- a/package.json
+++ b/package.json
@@ -66,7 +66,7 @@
     "path-is-inside": "^1.0.2",
     "pluralize": "^7.0.0",
     "progress": "^2.0.0",
-    "regexpp": "^2.0.0",
+    "regexpp": "^2.0.1",
     "require-uncached": "^1.0.3",
     "semver": "^5.5.1",
     "strip-ansi": "^4.0.0",


Test patch:
diff --git a/tests/lib/rules/no-extra-bind.js b/tests/lib/rules/no-extra-bind.js
index 4dfec87ac..4e5a08f36 100644
--- a/tests/lib/rules/no-extra-bind.js
+++ b/tests/lib/rules/no-extra-bind.js
@@ -70,10 +70,32 @@ ruleTester.run("no-extra-bind", rule, {
             output: "var a = function() { function c(){ this.d } }",
             errors
         },
+        {
+            code: "var a = function() { return 1; }.bind(this)",
+            output: "var a = function() { return 1; }",
+            errors
+        },
         {
             code: "var a = function() { (function(){ (function(){ this.d }.bind(c)) }) }.bind(b)",
             output: "var a = function() { (function(){ (function(){ this.d }.bind(c)) }) }",
             errors: [{ messageId: "unexpected", type: "CallExpression", column: 71 }]
+        },
+
+        // Should not autofix if bind expression args have side effects
+        {
+            code: "var a = function() {}.bind(b++)",
+            output: null,
+            errors
+        },
+        {
+            code: "var a = function() {}.bind(b())",
+            output: null,
+            errors
+        },
+        {
+            code: "var a = function() {}.bind(b.c)",
+            output: null,
+            errors
         }
     ]
 });
diff --git a/tests/lib/rules/no-invalid-regexp.js b/tests/lib/rules/no-invalid-regexp.js
index 305f4e0d3..0062a5bbc 100644
--- a/tests/lib/rules/no-invalid-regexp.js
+++ b/tests/lib/rules/no-invalid-regexp.js
@@ -46,6 +46,12 @@ ruleTester.run("no-invalid-regexp", rule, {
     invalid: [
         { code: "RegExp('[');", errors: [{ message: "Invalid regular expression: /[/: Unterminated character class.", type: "CallExpression" }] },
         { code: "RegExp('.', 'z');", errors: [{ message: "Invalid flags supplied to RegExp constructor 'z'.", type: "CallExpression" }] },
-        { code: "new RegExp(')');", errors: [{ message: "Invalid regular expression: /)/: Unmatched ')'.", type: "NewExpression" }] }
+        { code: "new RegExp(')');", errors: [{ message: "Invalid regular expression: /)/: Unmatched ')'.", type: "NewExpression" }] },
+
+        // https://github.com/eslint/eslint/issues/10861
+        {
+            code: String.raw`new RegExp('\\');`,
+            errors: [{ message: "Invalid regular expression: /\\/: \\ at end of pattern.", type: "NewExpression" }]
+        }
     ]
 });
diff --git a/tests/lib/rules/no-tabs.js b/tests/lib/rules/no-tabs.js
index a01d9dc16..b4989037d 100644
--- a/tests/lib/rules/no-tabs.js
+++ b/tests/lib/rules/no-tabs.js
@@ -23,7 +23,16 @@ ruleTester.run("no-tabs", rule, {
         "function test(){\n}",
         "function test(){\n" +
         "  //   sdfdsf \n" +
-        "}"
+        "}",
+
+        {
+            code: "\tdoSomething();",
+            options: [{ allowIndentationTabs: true }]
+        },
+        {
+            code: "\t// comment",
+            options: [{ allowIndentationTabs: true }]
+        }
     ],
     invalid: [
         {
@@ -31,7 +40,7 @@ ruleTester.run("no-tabs", rule, {
             errors: [{
                 message: ERROR_MESSAGE,
                 line: 1,
-                column: 18
+                column: 17
             }]
         },
         {
@@ -39,7 +48,7 @@ ruleTester.run("no-tabs", rule, {
             errors: [{
                 message: ERROR_MESSAGE,
                 line: 1,
-                column: 6
+                column: 5
             }]
         },
         {
@@ -50,7 +59,7 @@ ruleTester.run("no-tabs", rule, {
             errors: [{
                 message: ERROR_MESSAGE,
                 line: 2,
-                column: 6
+                column: 5
             }]
         },
         {
@@ -61,7 +70,7 @@ ruleTester.run("no-tabs", rule, {
             errors: [{
                 message: ERROR_MESSAGE,
                 line: 1,
-                column: 10
+                column: 9
             }]
         },
         {
@@ -73,14 +82,23 @@ ruleTester.run("no-tabs", rule, {
                 {
                     message: ERROR_MESSAGE,
                     line: 2,
-                    column: 6
+                    column: 5
                 },
                 {
                     message: ERROR_MESSAGE,
                     line: 3,
-                    column: 2
+                    column: 1
                 }
             ]
+        },
+        {
+            code: "\t// Comment with leading tab \t and inline tab",
+            options: [{ allowIndentationTabs: true }],
+            errors: [{
+                message: ERROR_MESSAGE,
+                line: 1,
+                column: 30
+            }]
         }
     ]
 });
diff --git a/tests/lib/rules/no-unused-vars.js b/tests/lib/rules/no-unused-vars.js
index f188f8ce3..316df18e0 100644
--- a/tests/lib/rules/no-unused-vars.js
+++ b/tests/lib/rules/no-unused-vars.js
@@ -271,7 +271,11 @@ ruleTester.run("no-unused-vars", rule, {
             code: "(({a, ...rest}) => rest)",
             options: [{ args: "all", ignoreRestSiblings: true }],
             parserOptions: { ecmaVersion: 2018 }
-        }
+        },
+
+        // https://github.com/eslint/eslint/issues/10952
+        "/*eslint use-every-a:1*/ !function(b, a) { return 1 }"
+
     ],
     invalid: [
         { code: "function foox() { return foox(); }", errors: [definedError("foox")] },
diff --git a/tests/lib/rules/one-var.js b/tests/lib/rules/one-var.js
index b628f512a..e5470d2e9 100644
--- a/tests/lib/rules/one-var.js
+++ b/tests/lib/rules/one-var.js
@@ -949,6 +949,17 @@ ruleTester.run("one-var", rule, {
                 column: 1
             }]
         },
+        {
+            code: "var a = 1, b = 2",
+            output: "var a = 1; var b = 2",
+            options: ["never"],
+            errors: [{
+                message: "Split 'var' declarations into multiple statements.",
+                type: "VariableDeclaration",
+                line: 1,
+                column: 1
+            }]
+        },
         {
             code: "var foo = require('foo'), bar;",
             output: null,
diff --git a/tests/lib/rules/padding-line-between-statements.js b/tests/lib/rules/padding-line-between-statements.js
index 3f72f8ff2..82147d389 100644
--- a/tests/lib/rules/padding-line-between-statements.js
+++ b/tests/lib/rules/padding-line-between-statements.js
@@ -852,6 +852,35 @@ ruleTester.run("padding-line-between-statements", rule, {
             ]
         },
 
+        //----------------------------------------------------------------------
+        // iife
+        //----------------------------------------------------------------------
+
+        {
+            code: "(function(){\n})()\n\nvar a = 2;",
+            options: [
+                { blankLine: "always", prev: "iife", next: "*" }
+            ]
+        },
+        {
+            code: "+(function(){\n})()\n\nvar a = 2;",
+            options: [
+                { blankLine: "always", prev: "iife", next: "*" }
+            ]
+        },
+        {
+            code: "(function(){\n})()\nvar a = 2;",
+            options: [
+                { blankLine: "never", prev: "iife", next: "*" }
+            ]
+        },
+        {
+            code: "+(function(){\n})()\nvar a = 2;",
+            options: [
+                { blankLine: "never", prev: "iife", next: "*" }
+            ]
+        },
+
         //----------------------------------------------------------------------
         // import
         //----------------------------------------------------------------------
@@ -3371,6 +3400,43 @@ ruleTester.run("padding-line-between-statements", rule, {
             errors: [MESSAGE_ALWAYS]
         },
 
+        //----------------------------------------------------------------------
+        // iife
+        //----------------------------------------------------------------------
+
+        {
+            code: "(function(){\n})()\n\nvar a = 2;",
+            output: "(function(){\n})()\nvar a = 2;",
+            options: [
+                { blankLine: "never", prev: "iife", next: "*" }
+            ],
+            errors: [MESSAGE_NEVER]
+        },
+        {
+            code: "+(function(){\n})()\n\nvar a = 2;",
+            output: "+(function(){\n})()\nvar a = 2;",
+            options: [
+                { blankLine: "never", prev: "iife", next: "*" }
+            ],
+            errors: [MESSAGE_NEVER]
+        },
+        {
+            code: "(function(){\n})()\nvar a = 2;",
+            output: "(function(){\n})()\n\nvar a = 2;",
+            options: [
+                { blankLine: "always", prev: "iife", next: "*" }
+            ],
+            errors: [MESSAGE_ALWAYS]
+        },
+        {
+            code: "+(function(){\n})()\nvar a = 2;",
+            output: "+(function(){\n})()\n\nvar a = 2;",
+            options: [
+                { blankLine: "always", prev: "iife", next: "*" }
+            ],
+            errors: [MESSAGE_ALWAYS]
+        },
+
         //----------------------------------------------------------------------
         // import
         //----------------------------------------------------------------------
@@ -4247,6 +4313,14 @@ ruleTester.run("padding-line-between-statements", rule, {
             ],
             errors: [MESSAGE_NEVER]
         },
+        {
+            code: "+(function(){\n})()\n\nvar a = 2;",
+            output: "+(function(){\n})()\nvar a = 2;",
+            options: [
+                { blankLine: "never", prev: "block-like", next: "*" }
+            ],
+            errors: [MESSAGE_NEVER]
+        },
         {
             code: "var a = function() {};\n\nvar b = 2;",
             output: "var a = function() {};\nvar b = 2;",
diff --git a/tests/lib/rules/space-infix-ops.js b/tests/lib/rules/space-infix-ops.js
index 3f98c88d4..57e28addc 100644
--- a/tests/lib/rules/space-infix-ops.js
+++ b/tests/lib/rules/space-infix-ops.js
@@ -18,8 +18,14 @@ const ruleTester = new RuleTester();
 ruleTester.run("space-infix-ops", rule, {
     valid: [
         "a + b",
+        "a + ++b",
+        "a++ + b",
+        "a++ + ++b",
         "a     + b",
         "(a) + (b)",
+        "((a)) + ((b))",
+        "(((a))) + (((b)))",
+        "a + +b",
         "a + (b)",
         "a + +(b)",
         "a + (+(b))",