Repository: sindresorhus/eslint-plugin-unicorn (JavaScript)

Issue:
False-positives in `no-fn-reference-in-iterator` rule
<!-- Issuehunt Badges -->
[<img alt="Issuehunt badges" src="https://img.shields.io/badge/IssueHunt-%2440%20Rewarded-%237E24E3.svg" />](https://issuehunt.io/r/sindresorhus/eslint-plugin-unicorn/issues/121)
<!-- /Issuehunt Badges -->


the `unicorn/no-fn-reference-in-iterator` matched all of these pieces of (valid) code and the fix applied broke every one. not sure the best way forward for this..

https://reactjs.org/docs/react-api.html#reactchildrenforeach
```
React.Children.forEach(children, (p) => {
})
```

https://github.com/airbnb/enzyme/blob/master/docs/api/ReactWrapper/find.md
```
const wrapper = shallow(<Foo />)
wrapper.find(Panel).first().childAt(1)
```

https://caolan.github.io/async/docs.html#filter
```
    async.filter(
      Object.keys(manifest),
      (f, callback) => {
        callback(null, f.match(/\.js$/))
      },
      (err, results) => {
        async.each(results, (f, callback) => {
```

https://lodash.com/docs/4.17.4#forEach
```
      _.forEach(api, (op, m) => {
```

https://github.com/react-bootstrap/react-bootstrap/blob/master/src/utils/ValidComponentChildren.js

```
import ValidComponentChildren from 'react-bootstrap/lib/utils/ValidComponentChildren'
ValidComponentChildren.map(children, child => (
```


<!-- Issuehunt content -->

---

<details>
<summary>
<b>IssueHunt Summary</b>
</summary>

#### [<img src='https://avatars3.githubusercontent.com/u/93752?v=4' alt='alexzherdev' width=24 height=24> alexzherdev](https://issuehunt.io/u/alexzherdev) has been rewarded.

### Backers (Total: $40.00)

- [<img src='https://avatars3.githubusercontent.com/u/44827199?v=4' alt='issuehunt' width=24 height=24> issuehunt](https://issuehunt.io/u/issuehunt) ($40.00)
### Submitted pull Requests
- [#281 Check for argument count in iterators](https://issuehunt.io/r/sindresorhus/eslint-plugin-unicorn/pull/281)
---

### Tips

- Checkout the [Issuehunt explorer](https://issuehunt.io/r/sindresorhus/eslint-plugin-unicorn/) to discover more funded issues.
- Need some help from other developers? [Add your repositories](https://issuehunt.io/r/new) on IssueHunt to raise funds.
---
IssueHunt has been backed by the following sponsors. [Become a sponsor](https://issuehunt.io/membership/members)
</details>
<!-- /Issuehunt content-->


Discussion:
Getting the same thing. 
The auto fix results in 
```diff
-    return Async.map(stages, (stage, callback) => {
+    return Async.map((x) => stages(x), (stage, callback) => {
```

I turned it off by adding `'unicorn/no-fn-reference-in-iterator': 'off'` to my config
Unfortunately, there's really no way to know the actual type of the variable. So this rule is destined to have some false positives. We should more clearly mention this in the docs.

Like we did with https://github.com/sindresorhus/eslint-plugin-unicorn/commit/53dc7c11c187e656d2e832e2b02ce830bf417934, we could add some overrides for known globals, like `React.Children`, `async`, `Async`, `_`. We could also only report when there's just one argument to the method.
Should this really be in the recommended config if it's prone to false positives?
The "one argument" heuristic seems like a great idea…
For dealing with these false-positives, I can implement what @sindresorhus suggested. I can add configuration rules to this rule so that the user has the ability to exclude identifiers from this rule. Also, I can add a configuration rule where we can report methods with one argument, which will ignore the errors for `React.Children` and `Async `. How does that sound?
> I can add configuration rules to this rule so that the user has the ability to exclude identifiers from this rule.

👍

> Also, I can add a configuration rule where we can report methods with one argument

👍, but it should not be configurable. We should always ignore methods with more than 1 argument.

FWIW, [lodash/prefer-lodash-method](https://github.com/wix/eslint-plugin-lodash/blob/master/docs/rules/prefer-lodash-method.md#rule-details) had to solve this problem too and they chose to do it by adding `ignoreMethods` and `ignoreObjects` configs to the rule.
Reopening as this is not completely fixed.
Someone still needs to handle https://github.com/sindresorhus/eslint-plugin-unicorn/pull/172#issuecomment-383017266.
@issuehunt has funded $40.00 to this issue.

---
- Submit pull request via [IssueHunt](https://issuehunt.io/repos/55832243/issues/121) to receive this reward.
- Want to contribute? Chip in to this issue via [IssueHunt](https://issuehunt.io/repos/55832243/issues/121).
- Checkout the [IssueHunt Issue Explorer](https://issuehunt.io/issues) to see more funded issues.
- Need help from developers? [Add your repository](https://issuehunt.io/r/new) on IssueHunt to raise funds.
@sindresorhus has rewarded $36.00 to @alexzherdev. [See it on IssueHunt](https://issuehunt.io/repos/55832243/issues/121)

- :moneybag: Total deposit: $40.00
- :tada: Repository reward(0%): $0.00
- :wrench: Service fee(10%): $4.00



Patch:
diff --git a/rules/no-fn-reference-in-iterator.js b/rules/no-fn-reference-in-iterator.js
index 8f23daf365..936ed23905 100644
--- a/rules/no-fn-reference-in-iterator.js
+++ b/rules/no-fn-reference-in-iterator.js
@@ -49,7 +49,7 @@ const selector = `CallExpression${calleeBlacklist.map(toSelector).join('')}`;
 
 const create = context => ({
 	[selector]: node => {
-		if (isIteratorMethod(node) && hasFunctionArgument(node)) {
+		if (isIteratorMethod(node) && hasFunctionArgument(node) && node.arguments.length <= getNumberOfArguments(node)) {
 			const [arg] = node.arguments;
 
 			context.report({


Test patch:
diff --git a/test/no-fn-reference-in-iterator.js b/test/no-fn-reference-in-iterator.js
index 9c2581b6e5..2393f5942e 100644
--- a/test/no-fn-reference-in-iterator.js
+++ b/test/no-fn-reference-in-iterator.js
@@ -18,6 +18,7 @@ const errors = [
 ruleTester.run('no-fn-reference-in-iterator', rule, {
 	valid: [
 		'foo.map(x => fn(x))',
+		'foo.map(fn, x)',
 		'foo.forEach(x => fn(x))',
 		'foo.every(x => fn(x))',
 		'foo.filter(x => fn(x))',
@@ -29,6 +30,7 @@ ruleTester.run('no-fn-reference-in-iterator', rule, {
 		'foo.map(x => parseInt(x, 10))',
 		'foo.map(x => m({foo: true})(x))',
 		'foo.reduce((a, b) => a + b, 0)',
+		'foo.reduce(fn, x, y)',
 		'foo.reduceRight((a, b) => a.concat(b), [])',
 		'Promise.map(fn)',
 		'Promise.forEach(fn)',