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

Issue:
`prefer-node-append` fixer bug
<!-- Issuehunt Badges -->
[<img alt="Issuehunt badges" src="https://img.shields.io/badge/IssueHunt-%2430%20Rewarded-%237E24E3.svg" />](https://issuehunt.io/r/sindresorhus/eslint-plugin-unicorn/issues/319)
<!-- /Issuehunt Badges -->


```js
const canvas = document.body.appendChild(document.createElement('canvas'))
```

```js
const canvas = document.body.append(document.createElement('canvas'))
```

This can't be fixed, `ParentNode.append()` has no return value

https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/append


<!-- Issuehunt content -->

---

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

#
#
#
#
 
[
<
i
m
g
 
s
r
c
=
'
h
t
t
p
s
:
/
/
a
v
a
t
a
r
s
1
.
g
i
t
h
u
b
u
s
e
r
c
o
n
t
e
n
t
.
c
o
m
/
u
/
7
4
2
6
0
?
v
=
4
'
 
a
l
t
=
'
m
r
h
e
n
'
 
w
i
d
t
h
=
2
4
 
h
e
i
g
h
t
=
2
4
>
 
m
r
h
e
n
]
(
h
t
t
p
s
:
/
/
i
s
s
u
e
h
u
n
t
.
i
o
/
u
/
m
r
h
e
n
)
 
h
a
s
 
b
e
e
n
 
r
e
w
a
r
d
e
d
.

### Backers (Total: $30.00)

- [<img src='https://avatars3.githubusercontent.com/u/44827199?v=4' alt='issuehunt' width=24 height=24> issuehunt](https://issuehunt.io/u/issuehunt) ($30.00)
### Submitted pull Requests
- [#321 prefer-node-append: Only fix when expression is not used](https://issuehunt.io/r/sindresorhus/eslint-plugin-unicorn/pull/321)
---

### 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:
[@issuehunt](https://issuehunt.io/sponsors) has funded $30.00 to this issue.

---
- Submit pull request via [IssueHunt](https://issuehunt.io/repos/55832243/issues/319) to receive this reward.
- Want to contribute? Chip in to this issue via [IssueHunt](https://issuehunt.io/repos/55832243/issues/319).
- 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 I just noticed that this bounty was not awarded. Is there some followup I should do or did it just fall through the cracks?
@sindresorhus has rewarded $27.00 to @mrhen. [See it on IssueHunt](https://issuehunt.io/repos/55832243/issues/319)

- :moneybag: Total deposit: $30.00
- :tada: Repository reward(0%): $0.00
- :wrench: Service fee(10%): $3.00
Sorry, I sometimes (rarely) forget. If so, just let me know ;)



Patch:
diff --git a/rules/prefer-node-append.js b/rules/prefer-node-append.js
index a123042753..8426c1763e 100644
--- a/rules/prefer-node-append.js
+++ b/rules/prefer-node-append.js
@@ -3,16 +3,43 @@ const getDocsUrl = require('./utils/get-docs-url');
 
 const getMethodName = memberExpression => memberExpression.property.name;
 
+const ignoredParentTypes = [
+	'IfStatement',
+	'MemberExpression',
+	'VariableDeclarator'
+];
+
+const ignoredGrandparentTypes = [
+	'ExpressionStatement'
+];
+
 const create = context => {
 	return {
 		CallExpression(node) {
-			const {callee} = node;
+			const {
+				callee,
+				parent
+			} = node;
+
+			const {
+				parent: grandparent
+			} = (parent || {});
 
 			if (callee.type === 'MemberExpression' && getMethodName(callee) === 'appendChild') {
+				let fix = fixer => fixer.replaceText(callee.property, 'append');
+
+				if (parent && ignoredParentTypes.includes(parent.type)) {
+					fix = undefined;
+				}
+
+				if (grandparent && ignoredGrandparentTypes.includes(grandparent.type)) {
+					fix = undefined;
+				}
+
 				context.report({
 					node,
 					message: 'Prefer `Node#append()` over `Node#appendChild()`.',
-					fix: fixer => fixer.replaceText(callee.property, 'append')
+					fix
 				});
 			}
 		}


Test patch:
diff --git a/test/prefer-node-append.js b/test/prefer-node-append.js
index 3ee7f61f6d..b77169c94e 100644
--- a/test/prefer-node-append.js
+++ b/test/prefer-node-append.js
@@ -1,5 +1,6 @@
 import test from 'ava';
 import avaRuleTester from 'eslint-ava-rule-tester';
+import {outdent} from 'outdent';
 import rule from '../rules/prefer-node-append';
 
 const ruleTester = avaRuleTester(test, {
@@ -8,11 +9,9 @@ const ruleTester = avaRuleTester(test, {
 	}
 });
 
-const errors = [
-	{
-		message: 'Prefer `Node#append()` over `Node#appendChild()`.'
-	}
-];
+const error = {
+	message: 'Prefer `Node#append()` over `Node#appendChild()`.'
+};
 
 ruleTester.run('prefer-node-append', rule, {
 	valid: [
@@ -25,22 +24,80 @@ ruleTester.run('prefer-node-append', rule, {
 		{
 			code: 'node.appendChild(child);',
 			output: 'node.append(child);',
-			errors
+			errors: [error]
 		},
 		{
 			code: 'document.body.appendChild(child);',
 			output: 'document.body.append(child);',
-			errors
+			errors: [error]
 		},
 		{
 			code: 'node.appendChild()',
 			output: 'node.append()',
-			errors
+			errors: [error]
 		},
 		{
 			code: 'node.appendChild(null)',
 			output: 'node.append(null)',
-			errors
+			errors: [error]
+		},
+		{
+			code: outdent`
+				function foo() {
+					node.appendChild(null);
+				}
+			`,
+			output: outdent`
+				function foo() {
+					node.append(null);
+				}
+			`,
+			errors: [error]
+		},
+		{
+			code: 'const foo = node.appendChild(child);',
+			output: 'const foo = node.appendChild(child);',
+			errors: [error]
+		},
+		{
+			code: 'console.log(node.appendChild(child));',
+			output: 'console.log(node.appendChild(child));',
+			errors: [error]
+		},
+		{
+			code: 'node.appendChild(child).appendChild(grandchild);',
+			output: 'node.appendChild(child).append(grandchild);',
+			errors: [error, error]
+		},
+		{
+			code: 'node.appendChild(child) || "foo";',
+			output: 'node.appendChild(child) || "foo";',
+			errors: [error]
+		},
+		{
+			code: 'node.appendChild(child) + 0;',
+			output: 'node.appendChild(child) + 0;',
+			errors: [error]
+		},
+		{
+			code: 'node.appendChild(child) + 0;',
+			output: 'node.appendChild(child) + 0;',
+			errors: [error]
+		},
+		{
+			code: '+node.appendChild(child);',
+			output: '+node.appendChild(child);',
+			errors: [error]
+		},
+		{
+			code: 'node.appendChild(child) ? "foo" : "bar";',
+			output: 'node.appendChild(child) ? "foo" : "bar";',
+			errors: [error]
+		},
+		{
+			code: 'if (node.appendChild(child)) {}',
+			output: 'if (node.appendChild(child)) {}',
+			errors: [error]
 		}
 	]
 });