diff --git a/lib/utils.js b/lib/utils.js index 51f49e075a..8cb6d95947 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -70,7 +70,11 @@ var utils = module.exports = { return OPTIONS_KEYS.indexOf(key) > -1; }); - if (optionKeysInArgs.length > 0) { + // In some cases options may be the provided as the first argument. + // Here we're detecting a case where there are two distinct arguments + // (the first being args and the second options) and with known + // option keys in the first so that we can warn the user about it. + if (optionKeysInArgs.length > 0 && optionKeysInArgs.length !== argKeys.length) { console.warn( 'Stripe: Options found in arguments (' + optionKeysInArgs.join(', ') + '). Did you mean to pass an options ' + 'object? See https://github.com/stripe/stripe-node/wiki/Passing-Options.' diff --git a/test/utils.spec.js b/test/utils.spec.js index 91aad771e8..10d701fc60 100644 --- a/test/utils.spec.js +++ b/test/utils.spec.js @@ -101,32 +101,32 @@ describe('utils', function() { it('handles an empty list', function() { expect(utils.getDataFromArgs([])).to.deep.equal({}); }); - it('handles an list with no object', function() { + it('handles a list with no object', function() { var args = [1, 3]; expect(utils.getDataFromArgs(args)).to.deep.equal({}); expect(args.length).to.equal(2); }); it('ignores a hash with only options', function() { var args = [{api_key: 'foo'}]; - expect(utils.getDataFromArgs(args)).to.deep.equal({}); - expect(args.length).to.equal(1); + + handleConsoleWarns(function() { + expect(utils.getDataFromArgs(args)).to.deep.equal({}); + expect(args.length).to.equal(1); + }, function(message) { + throw new Error('Should not have warned, but did: ' + message); + }); }); - it('throws an error if the hash contains both data and options', function() { + it('warns if the hash contains both data and options', function() { var args = [{foo: 'bar', api_key: 'foo', idempotency_key: 'baz'}]; - // Hack to make sure we're logging to console.warn here: - var _warn = console.warn; - - console.warn = function(message) { + handleConsoleWarns(function() { + utils.getDataFromArgs(args); + }, function(message) { expect(message).to.equal( 'Stripe: Options found in arguments (api_key, idempotency_key).' + ' Did you mean to pass an options object? See https://github.com/stripe/stripe-node/wiki/Passing-Options.' ); - }; - - utils.getDataFromArgs(args); - - console.warn = _warn; + }); }); it('finds the data', function() { var args = [{foo: 'bar'}, {api_key: 'foo'}]; @@ -260,3 +260,15 @@ describe('utils', function() { }); }); }); + +function handleConsoleWarns(doWithShimmedConsoleWarn, onWarn) { + // Shim `console.warn` + var _warn = console.warn; + + console.warn = onWarn; + + doWithShimmedConsoleWarn(); + + // Un-shim `console.warn` + console.warn = _warn; +}