Repository: xjamundx/eslint-plugin-promise
Pull request #56 (2017-01-27 20:27:33)

Potential fix for #31
Potential fix for #31. I'm not sure what side effects this would have, but it seems like it works. I've tested it on some other projects. Thoughts?


Patch:
diff --git a/rules/always-return.js b/rules/always-return.js
index d56edf6..b30c551 100644
--- a/rules/always-return.js
+++ b/rules/always-return.js
@@ -32,6 +32,22 @@ function isInlineThenFunctionExpression (node) {
   )
 }
 
+function hasParentReturnStatement (node) {
+  if (node && node.parent && node.parent.type) {
+    // if the parent is a then, and we haven't returned anything, fail
+    if (isThenCallExpression(node.parent)) {
+      return false
+    }
+
+    if (node.parent.type === 'ReturnStatement') {
+      return true
+    }
+    return hasParentReturnStatement(node.parent)
+  }
+
+  return false
+}
+
 function peek (arr) {
   return arr[arr.length - 1]
 }
@@ -111,6 +127,10 @@ module.exports = {
           var id = segment.id
           var branch = funcInfo.branchInfoMap[id]
           if (!branch.good) {
+            if (hasParentReturnStatement(branch.node)) {
+              return
+            }
+
             // check shortcircuit syntax like `x && x()` and `y || x()``
             var prevSegments = segment.prevSegments
             for (var ii = prevSegments.length - 1; ii >= 0; --ii) {


Test patch:
diff --git a/test/always-return.test.js b/test/always-return.test.js
index 97b22fc..9f47252 100644
--- a/test/always-return.test.js
+++ b/test/always-return.test.js
@@ -10,6 +10,7 @@ ruleTester.run('always-return', rule, {
     { code: 'hey.then(x => x)', parserOptions: parserOptions },
     { code: 'hey.then(x => ({}))', parserOptions: parserOptions },
     { code: 'hey.then(x => { return; })', parserOptions: parserOptions },
+    { code: 'hey.then(x => { return x ? x.id : null })', parserOptions: parserOptions },
     { code: 'hey.then(x => { return x * 10 })', parserOptions: parserOptions },
     { code: 'hey.then(function() { return 42; })', parserOptions: parserOptions },
     { code: 'hey.then(function() { return new Promise(); })', parserOptions: parserOptions },
@@ -27,7 +28,18 @@ ruleTester.run('always-return', rule, {
     { code: 'hey.then(x => { return x; return "unreachable"; })', parserOptions: parserOptions },
     { code: 'hey.then(x => { return; }, err=>{ log(err); })', parserOptions: parserOptions },
     { code: 'hey.then(x => { return x && x(); }, err=>{ log(err); })', parserOptions: parserOptions },
-    { code: 'hey.then(x => { return x.y || x(); }, err=>{ log(err); })', parserOptions: parserOptions }
+    { code: 'hey.then(x => { return x.y || x(); }, err=>{ log(err); })', parserOptions: parserOptions },
+    {
+      code: `hey.then(x => { 
+        return anotherFunc({
+          nested: {
+            one: x === 1 ? 1 : 0,
+            two: x === 2 ? 1 : 0
+          }
+        })
+      })`,
+      parserOptions: parserOptions
+    }
   ],
 
   invalid: [
@@ -71,6 +83,29 @@ ruleTester.run('always-return', rule, {
     {
       code: 'hey.then(function() { if (x) { return you.then(function() { return x; }); } })',
       errors: [ { message: message } ]
+    },
+    {
+      code: 'hey.then( x => { x ? x.id : null })',
+      parserOptions: parserOptions,
+      errors: [ { message: message } ]
+    },
+    {
+      code: 'hey.then(function(x) { x ? x.id : null })',
+      errors: [ { message: message } ]
+    },
+    {
+      code: `(function() {
+        return hey.then(x => { 
+          anotherFunc({
+            nested: {
+              one: x === 1 ? 1 : 0,
+              two: x === 2 ? 1 : 0
+            }
+          })
+        })
+      })()`,
+      parserOptions: parserOptions,
+      errors: [ { message: message } ]
     }
   ]
 })