Skip to content

Commit

Permalink
fix(returns): should return rejected error when non Promise value
Browse files Browse the repository at this point in the history
Should promisified function return rejected promise when `done` is not called, but returns a non
Promise value. It can only return undefined or Promise, or call the callback

fixes #20
  • Loading branch information
tunnckoCore committed Apr 4, 2017
1 parent 05d8745 commit 67ae2b6
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 11 deletions.
11 changes: 9 additions & 2 deletions dist/redolent-testing.js
Expand Up @@ -118,10 +118,17 @@ function redolent (fn, opts) {

opts.args = isAsyncFn ? opts.args.concat(done) : opts.args;
var syncResult = fn.apply(opts.context, opts.args);
var xPromise = isAsyncFn && !called && isPromise(syncResult, opts.Promise);

if ((!isAsyncFn && !called) || xPromise) {
var xPromise = isPromise(syncResult, opts.Promise);
var hasPromiseReturn = isAsyncFn && !called && xPromise;

if ((!isAsyncFn && !called) || hasPromiseReturn) {
resolve(syncResult);
return
}
if (isAsyncFn && !xPromise && syncResult !== undefined) {
var msg = 'Asynchronous functions can only return a Promise or invoke a callback';
reject(new Error('redolent: ' + msg));
}
});

Expand Down
11 changes: 9 additions & 2 deletions dist/redolent.common.js
Expand Up @@ -392,10 +392,17 @@ function redolent (fn, opts) {

opts.args = isAsyncFn ? opts.args.concat(done) : opts.args;
var syncResult = fn.apply(opts.context, opts.args);
var xPromise = isAsyncFn && !called && isPromise(syncResult, opts.Promise);

if ((!isAsyncFn && !called) || xPromise) {
var xPromise = isPromise(syncResult, opts.Promise);
var hasPromiseReturn = isAsyncFn && !called && xPromise;

if ((!isAsyncFn && !called) || hasPromiseReturn) {
resolve(syncResult);
return
}
if (isAsyncFn && !xPromise && syncResult !== undefined) {
var msg = 'Asynchronous functions can only return a Promise or invoke a callback';
reject(new Error('redolent: ' + msg));
}
});

Expand Down
11 changes: 9 additions & 2 deletions dist/redolent.es.js
Expand Up @@ -388,10 +388,17 @@ function redolent (fn, opts) {

opts.args = isAsyncFn ? opts.args.concat(done) : opts.args;
var syncResult = fn.apply(opts.context, opts.args);
var xPromise = isAsyncFn && !called && isPromise(syncResult, opts.Promise);

if ((!isAsyncFn && !called) || xPromise) {
var xPromise = isPromise(syncResult, opts.Promise);
var hasPromiseReturn = isAsyncFn && !called && xPromise;

if ((!isAsyncFn && !called) || hasPromiseReturn) {
resolve(syncResult);
return
}
if (isAsyncFn && !xPromise && syncResult !== undefined) {
var msg = 'Asynchronous functions can only return a Promise or invoke a callback';
reject(new Error('redolent: ' + msg));
}
});

Expand Down
11 changes: 9 additions & 2 deletions index.js
Expand Up @@ -118,10 +118,17 @@ export default function redolent (fn, opts) {

opts.args = isAsyncFn ? opts.args.concat(done) : opts.args
var syncResult = fn.apply(opts.context, opts.args)
var xPromise = isAsyncFn && !called && isPromise(syncResult, opts.Promise)

if ((!isAsyncFn && !called) || xPromise) {
var xPromise = isPromise(syncResult, opts.Promise)
var hasPromiseReturn = isAsyncFn && !called && xPromise

if ((!isAsyncFn && !called) || hasPromiseReturn) {
resolve(syncResult)
return
}
if (isAsyncFn && !xPromise && syncResult !== undefined) {
var msg = 'Asynchronous functions can only return a Promise or invoke a callback'
reject(new Error('redolent: ' + msg))
}
})

Expand Down
19 changes: 16 additions & 3 deletions test.js
Expand Up @@ -66,10 +66,10 @@ function factory (promisify) {
var readFile = promisify(fs.readFile, {
Promise: Pinkie
})
var promise = readFile('package.json')
var promise = readFile('package.json', 'utf8')

promise.then(function (res) {
test.strictEqual(typeof res !== 'string', true)
test.strictEqual(typeof res, 'string')
if (semver.lt(process.version, '0.11.13')) {
test.strictEqual(promise.___customPromise, true)
}
Expand Down Expand Up @@ -160,7 +160,7 @@ function factory (promisify) {
})

test('should work if `done` is present, but return a promise', function (done) {
var fn = promisify(function (xxx, done) {
var fn = promisify(function (xxx, cb) {
return Pinkie.resolve(100 + xxx)
})

Expand All @@ -169,6 +169,19 @@ function factory (promisify) {
done()
}, done).catch(done)
})

test('should reject if async fn returns non Promise, nor call a callback', function (done) {
var func = promisify(function (cb) {
return 'foo bar'
})

func().catch(function (err) {
test.strictEqual(err instanceof Error, true)
test.strictEqual(/Asynchronous functions can only/.test(err.message), true)
test.strictEqual(/return a Promise or invoke a callback/.test(err.message), true)
done()
}).catch(done)
})
}

if (semver.lt(process.version, '0.12.0')) {
Expand Down

0 comments on commit 67ae2b6

Please sign in to comment.