Skip to content

Commit 3f2c61d

Browse files
authored
Merge pull request #136 from ota-meshi/fix/no-return-wrap
Fixed that `no-return-wrap` does not work if type is not "ExpressionStatement".
2 parents 0e00592 + 57267ca commit 3f2c61d

File tree

2 files changed

+128
-5
lines changed

2 files changed

+128
-5
lines changed

__tests__/no-return-wrap.js

Lines changed: 106 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,10 @@ ruleTester.run('no-return-wrap', rule, {
5151
{
5252
code: 'doThing().then(function() { return Promise.reject(4) })',
5353
options: [{ allowReject: true }]
54-
}
54+
},
55+
56+
// not function bind
57+
'doThing().then((function() { return Promise.resolve(4) }).toString())'
5558
],
5659

5760
invalid: [
@@ -105,11 +108,112 @@ ruleTester.run('no-return-wrap', rule, {
105108
code:
106109
'doThing().catch(function(x) {if (x) { return Promise.resolve(4) } else { return Promise.reject() } })',
107110
errors: [{ message: resolveMessage }, { message: rejectMessage }]
108-
}
111+
},
109112

110113
// should work someday
111114
// {code: 'doThing().catch(function(x) { return x && Promise.resolve(4) })', errors: [{message: resolveMessage}]},
112115
// {code: 'doThing().catch(function(x) { return true ? Promise.resolve(4) : Promise.reject(5) })', errors: [{message: rejectMessage }, {message: resolveMessage}]},
113116
// {code: 'doThing().catch(function(x) { return x && Promise.reject(4) })', errors: [{message: rejectMessage}]}
117+
118+
// mltiple "ExpressionStatement"
119+
{
120+
code: `
121+
fn(function() {
122+
doThing().then(function() {
123+
return Promise.resolve(4)
124+
})
125+
return
126+
})`,
127+
errors: [{ message: resolveMessage, line: 4 }]
128+
},
129+
{
130+
code: `
131+
fn(function() {
132+
doThing().then(function nm() {
133+
return Promise.resolve(4)
134+
})
135+
return
136+
})`,
137+
errors: [{ message: resolveMessage, line: 4 }]
138+
},
139+
{
140+
code: `
141+
fn(function() {
142+
fn2(function() {
143+
doThing().then(function() {
144+
return Promise.resolve(4)
145+
})
146+
})
147+
})`,
148+
errors: [{ message: resolveMessage, line: 5 }]
149+
},
150+
{
151+
code: `
152+
fn(function() {
153+
fn2(function() {
154+
doThing().then(function() {
155+
fn3(function() {
156+
return Promise.resolve(4)
157+
})
158+
return Promise.resolve(4)
159+
})
160+
})
161+
})`,
162+
errors: [{ message: resolveMessage, line: 8 }]
163+
},
164+
165+
// other than "ExpressionStatement"
166+
{
167+
code: `
168+
const o = {
169+
fn: function() {
170+
return doThing().then(function() {
171+
return Promise.resolve(5);
172+
});
173+
},
174+
}
175+
`,
176+
errors: [{ message: resolveMessage, line: 5 }]
177+
},
178+
{
179+
code: `
180+
fn(
181+
doThing().then(function() {
182+
return Promise.resolve(5);
183+
})
184+
);
185+
`,
186+
errors: [{ message: resolveMessage, line: 4 }]
187+
},
188+
189+
// function bind
190+
{
191+
code:
192+
'doThing().then((function() { return Promise.resolve(4) }).bind(this))',
193+
errors: [{ message: resolveMessage }]
194+
},
195+
{
196+
code:
197+
'doThing().then((function() { return Promise.resolve(4) }).bind(this).bind(this))',
198+
errors: [{ message: resolveMessage }]
199+
},
200+
201+
// arrow functions and other things
202+
{
203+
code: 'doThing().then(() => { return Promise.resolve(4) })',
204+
errors: [{ message: resolveMessage }]
205+
},
206+
207+
// issue #150
208+
{
209+
code: `
210+
function a () {
211+
return p.then(function(val) {
212+
return Promise.resolve(val * 4)
213+
})
214+
}
215+
`,
216+
errors: [{ message: resolveMessage }]
217+
}
114218
]
115219
})

rules/no-return-wrap.js

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,29 @@ const getDocsUrl = require('./lib/get-docs-url')
1010
const isPromise = require('./lib/is-promise')
1111

1212
function isInPromise(context) {
13-
const expression = context
13+
let functionNode = context
1414
.getAncestors()
15-
.filter(node => node.type === 'ExpressionStatement')[0]
16-
return expression && expression.expression && isPromise(expression.expression)
15+
.filter(node => {
16+
return (
17+
node.type === 'ArrowFunctionExpression' ||
18+
node.type === 'FunctionExpression'
19+
)
20+
})
21+
.reverse()[0]
22+
while (
23+
functionNode &&
24+
functionNode.parent &&
25+
functionNode.parent.type === 'MemberExpression' &&
26+
functionNode.parent.object === functionNode &&
27+
functionNode.parent.property.type === 'Identifier' &&
28+
functionNode.parent.property.name === 'bind' &&
29+
functionNode.parent.parent &&
30+
functionNode.parent.parent.type === 'CallExpression' &&
31+
functionNode.parent.parent.callee === functionNode.parent
32+
) {
33+
functionNode = functionNode.parent.parent
34+
}
35+
return functionNode && functionNode.parent && isPromise(functionNode.parent)
1736
}
1837

1938
module.exports = {

0 commit comments

Comments
 (0)