diff --git a/lib/callback_to_promise.js b/lib/callback_to_promise.js index 71eb52dd..40f6e20e 100644 --- a/lib/callback_to_promise.js +++ b/lib/callback_to_promise.js @@ -8,11 +8,13 @@ */ function callbackToPromise(fn, context, callbackArgIndex) { return function() { - // If callbackArgIndex isn't provided, use the last argument. + var thisCallbackArgIndex; if (callbackArgIndex === void 0) { - callbackArgIndex = arguments.length > 0 ? arguments.length - 1 : 0; + thisCallbackArgIndex = arguments.length > 0 ? arguments.length - 1 : 0; + } else { + thisCallbackArgIndex = callbackArgIndex; } - var callbackArg = arguments[callbackArgIndex]; + var callbackArg = arguments[thisCallbackArgIndex]; if (typeof callbackArg === 'function') { fn.apply(context, arguments); } else { @@ -20,7 +22,7 @@ function callbackToPromise(fn, context, callbackArgIndex) { // If an explicit callbackArgIndex is set, but the function is called // with too few arguments, we want to push undefined onto args so that // our constructed callback ends up at the right index. - var argLen = Math.max(arguments.length, callbackArgIndex); + var argLen = Math.max(arguments.length, thisCallbackArgIndex); for (var i = 0; i < argLen; i++) { args.push(arguments[i]); } diff --git a/test/callback_to_promise.test.js b/test/callback_to_promise.test.js new file mode 100644 index 00000000..4a5d2d6e --- /dev/null +++ b/test/callback_to_promise.test.js @@ -0,0 +1,50 @@ +'use strict'; + +var callbackToPromise = require('../lib/callback_to_promise'); + +describe('callbackToPromise', function () { + function returnThisPlusValue(value, callback) { + callback(null, this + value); // jshint ignore:line + } + + function sum() { + var callback = arguments[arguments.length - 1]; + var result = 0; + for (var i = 0; i < arguments.length - 1; i++) { + result += arguments[i]; + } + callback(null, result); + } + + it('lets a function return a promise', function () { + var wrapped = callbackToPromise(returnThisPlusValue, 1); + expect(wrapped(2)).resolves.toBe(3); + }); + + it('maintains the ability to call a function with a callback', function (done) { + var wrapped = callbackToPromise(returnThisPlusValue, 1); + wrapped(2, function (err, result) { + expect(err).toBeNull(); + expect(result).toBe(3); + done(); + }); + }); + + it('is resilient to changes in the number of arguments', function (done) { + var wrapped = callbackToPromise(sum, null); + + wrapped(1, 2, function (err1, result1) { + expect(err1).toBeNull(); + expect(result1).toBe(3); + wrapped(3, 4, 5, function (err2, result2) { + expect(err2).toBeNull(); + expect(result2).toBe(12); + wrapped(6, function (err3, result3) { + expect(err3).toBeNull(); + expect(result3).toBe(6); + done(); + }); + }); + }); + }); +});