Repository: eslint/eslint (js)

Issue:
object-curly-newline counts default export in minProperties
**Tell us about your environment**

Ubuntu 17.10

* **ESLint Version:** 4.19.0
* **Node Version:** 9.6.1
* **npm Version:** 5.7.1

(Also validated on OSX, Node 7.10.0, npm 4.2.0)

**What parser (default, Babel-ESLint, etc.) are you using?**

Default, I believe(?), with sourceType: module. Full configuration:

<details>
<summary>Configuration</summary>

`.eslintrc`
```json
{
	"root": true,
	"env": { "es6": true },
	"extends": [
		"eslint:recommended"
	],
	"parserOptions": {
		"sourceType": "module"
	},
	"rules": {
		"object-curly-newline": [ "error", {
			"minProperties": 2,
			"consistent": true
		} ]
	}
}
```

</details>

**What did you do? Please include the actual source code causing the issue, as well as the command that you used to run ESLint.**

[This gist](https://gist.github.com/kadamwhite/f0098c63df2f9edf5d79b8b8b8b446f5) contains the `package.json`, `.eslintrc` and `test.js` as described here; downloading that gist, running `npm install` and then `npm test` replicates the issue on every environment I can access.

<!-- Paste the source code below: -->
`test.js`
```js
import DefaultExport, { NamedExport } from 'some-module';
import { NamedExportWithoutDefaultImport } from 'some-other-module';

export default {
  DefaultExport,
  NamedExport,
  NamedExportWithoutDefaultImport,
};
```
`package.json`
```json
{
  "name": "test-object-curly-newline",
  "scripts": {
    "test": "eslint ./test.js"
  },
  "devDependencies": {
    "eslint": "^4.19.0"
  }
}
```
<!-- Paste the command you used to run ESLint: -->
```bash
npm test # runs `eslint ./test.js`
```

**What did you expect to happen?**

I expected no `object-curly-newline` issue to be reported for either of these imports, as they both have only a single named export within curly brackets:
```js
import DefaultExport, { NamedExport } from 'some-module';
import { NamedExportWithoutDefaultImport } from 'some-other-module';
```
however the default export on the first line is being counted as an object property, meaning that the rule matches the `minProperties` and I get errors for each curly bracket on Line 1, but not Line 2

**What actually happened? Please include the actual, raw output from ESLint.**

```
$ npm test

> test-object-curly-newline@ test /hm/gh/coding-standards/packages/eslint-config-humanmade/test
> eslint ./test.js


/hm/gh/coding-standards/packages/eslint-config-humanmade/test/test.js
  1:23  error  Expected a line break after this opening brace   object-curly-newline
  1:37  error  Expected a line break before this closing brace  object-curly-newline

✖ 2 problems (2 errors, 0 warnings)
  2 errors, 0 warnings potentially fixable with the `--fix` option.

npm ERR! Test failed.  See above for more details.
```

Pull request:
Fix: object-curly-newline minProperties w/default export (fixes #10101)
minProperties only tracks ImportSpecifier and ExportSpecifier nodes

<!--
    ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
-->

**What is the purpose of this pull request? (put an "X" next to item)**

[ ] Documentation update
[x] Bug fix ([template](https://raw.githubusercontent.com/eslint/eslint/master/templates/bug-report.md))
[ ] New rule ([template](https://raw.githubusercontent.com/eslint/eslint/master/templates/rule-proposal.md))
[ ] Changes an existing rule ([template](https://raw.githubusercontent.com/eslint/eslint/master/templates/rule-change-proposal.md))
[ ] Add autofixing to a rule
[ ] Add a CLI option
[ ] Add something to the core
[ ] Other, please explain:

<!--
    If the item you've checked above has a template, please paste the template questions below and answer them. (If this pull request is addressing an issue, you can just paste a link to the issue here instead.)
-->

See #10101.

<!--
    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)**

The `object-curly-newline` rule used to count all `specifiers` under an `ImportDeclaration` or `ExportDeclaration` node when determining if there are enough specifiers to require line breaks. However, ImportDefaultSpecifier and ImportNamespaceSpecifier nodes are not actually part of the "object" (i.e., nodes surrounded by curly brace tokens), so they should be ignored by this rule. This change fixes the logic to only check for the count of `ImportSpecifier` or `ExportSpecifier` nodes associated with the `ImportDeclaration` or `ExportDeclaration` nodes.

**Is there anything you'd like reviewers to focus on?**

Any other unit tests I should add?

Patch:
diff --git a/Makefile.js b/Makefile.js
index 0f92dc121..d3e3ec811 100644
--- a/Makefile.js
+++ b/Makefile.js
@@ -569,6 +569,8 @@ target.test = function() {
     let errors = 0,
         lastReturn;
 
+    echo("Running unit tests");
+
     lastReturn = exec(`${getBinFile("istanbul")} cover ${MOCHA} -- -R progress -t ${MOCHA_TIMEOUT} -c ${TEST_FILES}`);
     if (lastReturn.code !== 0) {
         errors++;
diff --git a/docs/rules/guard-for-in.md b/docs/rules/guard-for-in.md
index ec7860b79..28dc1637f 100644
--- a/docs/rules/guard-for-in.md
+++ b/docs/rules/guard-for-in.md
@@ -33,6 +33,9 @@ for (key in foo) {
     if (Object.prototype.hasOwnProperty.call(foo, key)) {
         doSomething(key);
     }
+}
+
+for (key in foo) {
     if ({}.hasOwnProperty.call(foo, key)) {
         doSomething(key);
     }
diff --git a/lib/config/plugins.js b/lib/config/plugins.js
index c509c48fe..756f9ff21 100644
--- a/lib/config/plugins.js
+++ b/lib/config/plugins.js
@@ -120,6 +120,26 @@ class Plugins {
                 throw pluginLoadErr;
             }
 
+            // This step is costly, so skip if debug is disabled
+            if (debug.enabled) {
+                const resolvedPath = require.resolve(longName);
+
+                let version = null;
+
+                try {
+                    version = require(`${longName}/package.json`).version;
+                } catch (e) {
+
+                    // Do nothing
+                }
+
+                const loadedPluginAndVersion = version
+                    ? `${longName}@${version}`
+                    : `${longName}, version unknown`;
+
+                debug(`Loaded plugin ${pluginName} (${loadedPluginAndVersion}) (from ${resolvedPath})`);
+            }
+
             this.define(pluginName, plugin);
         }
     }
diff --git a/lib/rules/object-curly-newline.js b/lib/rules/object-curly-newline.js
index 14b5d06a7..39043a8b9 100644
--- a/lib/rules/object-curly-newline.js
+++ b/lib/rules/object-curly-newline.js
@@ -116,7 +116,8 @@ function areLineBreaksRequired(node, options, first, last) {
     } else {
 
         // is ImportDeclaration or ExportNamedDeclaration
-        objectProperties = node.specifiers;
+        objectProperties = node.specifiers
+            .filter(s => s.type === "ImportSpecifier" || s.type === "ExportSpecifier");
     }
 
     return objectProperties.length >= options.minProperties ||


Test patch:
diff --git a/tests/lib/rules/object-curly-newline.js b/tests/lib/rules/object-curly-newline.js
index 73d9a233a..a3235a91a 100644
--- a/tests/lib/rules/object-curly-newline.js
+++ b/tests/lib/rules/object-curly-newline.js
@@ -493,6 +493,10 @@ ruleTester.run("object-curly-newline", rule, {
             ].join("\n"),
             options: [{ ImportDeclaration: { minProperties: 3 } }]
         },
+        {
+            code: "import DefaultExport, {a} from 'module';",
+            options: [{ ImportDeclaration: { minProperties: 2 } }]
+        },
 
         // "ExportDeclaration" ---------------------------------------------
         {
@@ -1590,6 +1594,19 @@ ruleTester.run("object-curly-newline", rule, {
                 { line: 3, column: 1, message: "Unexpected line break before this closing brace." }
             ]
         },
+        {
+            code: "import DefaultExport, {a, b} from 'module';",
+            output: [
+                "import DefaultExport, {",
+                "a, b",
+                "} from 'module';"
+            ].join("\n"),
+            options: [{ ImportDeclaration: { minProperties: 2 } }],
+            errors: [
+                { line: 1, column: 23, message: "Expected a line break after this opening brace." },
+                { line: 1, column: 28, message: "Expected a line break before this closing brace." }
+            ]
+        },
 
         // "ExportDeclaration" ---------------------------------------------
         {