Skip to content

Commit d053b20

Browse files
ofrobotslukesneeringer
authored andcommitted
common: promisify: deal with trailing undefined (googleapis#2130)
1 parent a596506 commit d053b20

File tree

2 files changed

+36
-6
lines changed

2 files changed

+36
-6
lines changed

packages/common/src/util.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -706,14 +706,18 @@ function promisify(originalMethod, options) {
706706
var slice = Array.prototype.slice;
707707

708708
var wrapper = function() {
709-
var args = slice.call(arguments);
710-
var hasCallback = is.fn(args[args.length - 1]);
711-
var context = this;
712-
713-
if (hasCallback) {
714-
return originalMethod.apply(context, args);
709+
var last;
710+
for (last = arguments.length - 1; last >= 0; last--) {
711+
var arg = arguments[last];
712+
if (arg === undefined) continue; // skip trailing undefined.
713+
if (!is.fn(arg)) break; // non-callback last argument found.
714+
return originalMethod.apply(this, arguments);
715715
}
716716

717+
// peel trailing undefined.
718+
var args = slice.call(arguments, 0, last + 1);
719+
var context = this;
720+
717721
var PromiseCtor = Promise;
718722

719723
// Because dedupe will likely create a single install of

packages/common/test/util.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1648,6 +1648,32 @@ describe('common/util', function() {
16481648

16491649
assert.strictEqual(FakeClass.prototype.methodName, method);
16501650
});
1651+
1652+
describe('trailing undefined arguments', function() {
1653+
it('should not return a promise in callback mode', function(done) {
1654+
var func = util.promisify(function(optional, callback) {
1655+
assert(is.fn(optional));
1656+
optional(null);
1657+
});
1658+
1659+
var returnVal = func(function() {
1660+
assert(!returnVal);
1661+
done();
1662+
});
1663+
});
1664+
1665+
it('should return a promise when callback omitted', function(done) {
1666+
var func = util.promisify(function(optional, callback) {
1667+
assert.strictEqual(arguments.length, 1);
1668+
assert(is.fn(optional));
1669+
optional(null);
1670+
});
1671+
1672+
var returnVal = func(undefined, undefined).then(function() {
1673+
done();
1674+
});
1675+
});
1676+
});
16511677
});
16521678

16531679
describe('promisify', function() {

0 commit comments

Comments
 (0)