Repository: ember-template-lint/ember-template-lint
Pull request #613 (2019-01-17 04:59:48)

fix: avoid suggesting 'unless' with helpers in condition in 'no-negated-condition' rule.
We don't want to suggest turning this:
```hbs
<img class={{if (not (or c1 c2)) "some-class"}}>
```
into this:
```hbs
<img class={{unless (or c1 c2) "some-class"}}>
```
as the [simple-unless](https://github.com/ember-template-lint/ember-template-lint/blob/master/docs/rule/simple-unless.md) rule does not permit helpers to be used with `unless`.


Patch:
diff --git a/lib/rules/lint-no-negated-condition.js b/lib/rules/lint-no-negated-condition.js
index e9fcf7c3..5091b5cc 100644
--- a/lib/rules/lint-no-negated-condition.js
+++ b/lib/rules/lint-no-negated-condition.js
@@ -42,29 +42,37 @@ module.exports = class NoNegatedCondition extends Rule {
       }
 
       if (
-        node.params.length > 0 &&
-        AstNodeInfo.isSubExpression(node.params[0]) &&
-        AstNodeInfo.isPathExpression(node.params[0].path) &&
-        node.params[0].path.original === 'not'
+        node.params.length === 0 ||
+        !AstNodeInfo.isSubExpression(node.params[0]) ||
+        !AstNodeInfo.isPathExpression(node.params[0].path) ||
+        node.params[0].path.original !== 'not'
       ) {
-        // Determine what error message to show:
-        const isIfElseBlockStatement = AstNodeInfo.isBlockStatement(node) && node.inverse;
-        const isIfElseNonBlockStatement =
-          !AstNodeInfo.isBlockStatement(node) && node.params.length === 3;
-        const shouldFlipCondition = isIfElseBlockStatement || isIfElseNonBlockStatement;
-        const message = isUnless
-          ? ERROR_MESSAGE_USE_IF
-          : shouldFlipCondition
-          ? ERROR_MESSAGE_FLIP_IF
-          : ERROR_MESSAGE_USE_UNLESS;
+        return;
+      }
 
-        this.log({
-          message,
-          line: node.loc && node.loc.start.line,
-          column: node.loc && node.loc.start.column,
-          source: this.sourceForNode(node),
-        });
+      if (isIf && AstNodeInfo.isSubExpression(node.params[0].params[0])) {
+        // We don't want to suggest converting to `unless` when there are helpers
+        // in the condition, as the `simple-unless` rule does not permit that.
+        return;
       }
+
+      // Determine what error message to show:
+      const isIfElseBlockStatement = AstNodeInfo.isBlockStatement(node) && node.inverse;
+      const isIfElseNonBlockStatement =
+        !AstNodeInfo.isBlockStatement(node) && node.params.length === 3;
+      const shouldFlipCondition = isIfElseBlockStatement || isIfElseNonBlockStatement;
+      const message = isUnless
+        ? ERROR_MESSAGE_USE_IF
+        : shouldFlipCondition
+        ? ERROR_MESSAGE_FLIP_IF
+        : ERROR_MESSAGE_USE_UNLESS;
+
+      this.log({
+        message,
+        line: node.loc && node.loc.start.line,
+        column: node.loc && node.loc.start.column,
+        source: this.sourceForNode(node),
+      });
     }
 
     return {


Test patch:
diff --git a/test/unit/rules/lint-no-negated-condition.js b/test/unit/rules/lint-no-negated-condition.js
index da27179e..acaad51a 100644
--- a/test/unit/rules/lint-no-negated-condition.js
+++ b/test/unit/rules/lint-no-negated-condition.js
@@ -18,6 +18,7 @@ generateRuleTests({
     // if ...
     '{{#if condition}}<img>{{/if}}',
     '{{#if (or c1 c2)}}{{/if}}',
+    '{{#if (not (or c1 c2))}}{{/if}}', // Valid since we don't want to suggest `unless` with helpers in the condition.
 
     // if ... else ...
     '{{#if condition}}<img>{{else}}<img>{{/if}}',
@@ -67,6 +68,7 @@ generateRuleTests({
     // if ...
     '<img class={{if condition "some-class"}}>',
     '<img class={{if (or c1 c2) "some-class"}}>',
+    '<img class={{if (not (or c1 c2)) "some-class"}}>', // Valid since we don't want to suggest `unless` with helpers in the condition.
 
     // if ... else ...
     '<img class={{if condition "some-class" "other-class"}}>',
@@ -87,6 +89,7 @@ generateRuleTests({
     // if ...
     '{{input class=(if condition "some-class")}}',
     '{{input class=(if (or c1 c2) "some-class")}}',
+    '{{input class=(if (not (or c1 c2)) "some-class")}}', // Valid since we don't want to suggest `unless` with helpers in the condition.
 
     // if ... else ...
     '{{input class=(if condition "some-class" "other-class")}}',