From d58879abd5f7f787583c739bc8eb840e9c27a431 Mon Sep 17 00:00:00 2001 From: Dave Gramlich Date: Mon, 17 Oct 2016 19:14:18 -0400 Subject: [PATCH] resource: add promise support (#1709) --- .../google-cloud-resourcemanager/README.md | 10 +++ .../google-cloud-resourcemanager/package.json | 2 +- .../google-cloud-resourcemanager/src/index.js | 73 +++++++++++++------ .../src/project.js | 59 +++++++++++++++ .../system-test/resource.js | 2 +- .../test/index.js | 26 ++++++- .../test/project.js | 16 +++- 7 files changed, 161 insertions(+), 27 deletions(-) diff --git a/packages/google-cloud-resourcemanager/README.md b/packages/google-cloud-resourcemanager/README.md index fb737c303c9..ce7acc8b11c 100644 --- a/packages/google-cloud-resourcemanager/README.md +++ b/packages/google-cloud-resourcemanager/README.md @@ -31,6 +31,16 @@ var project = resource.project(); project.getMetadata(function(err, metadata) { // `metadata` describes your project. }); + +// Promises are also supported by omitting callbacks. +project.getMetadata().then(function(data) { + var metadata = data[0]; +}); + +// It's also possible to integrate with third-party Promise libraries. +var resource = require('@google-cloud/resource')({ + promise: require('bluebird') +}); ``` diff --git a/packages/google-cloud-resourcemanager/package.json b/packages/google-cloud-resourcemanager/package.json index 63547fed637..29fa7c43e99 100644 --- a/packages/google-cloud-resourcemanager/package.json +++ b/packages/google-cloud-resourcemanager/package.json @@ -50,7 +50,7 @@ "resource" ], "dependencies": { - "@google-cloud/common": "^0.6.0", + "@google-cloud/common": "^0.7.0", "extend": "^3.0.0", "is": "^3.0.1" }, diff --git a/packages/google-cloud-resourcemanager/src/index.js b/packages/google-cloud-resourcemanager/src/index.js index 0a9df2fdd31..56e3c2c287a 100644 --- a/packages/google-cloud-resourcemanager/src/index.js +++ b/packages/google-cloud-resourcemanager/src/index.js @@ -101,6 +101,14 @@ util.inherits(Resource, common.Service); * // `project` is a new Project instance. * } * }); + * + * //- + * // If the callback is omitted, we'll return a Promise. + * //- + * resource.createProject('new project name').then(function(data) { + * var project = data[0]; + * var apiResponse = data[1]; + * }); */ Resource.prototype.createProject = function(id, options, callback) { var self = this; @@ -171,25 +179,11 @@ Resource.prototype.createProject = function(id, options, callback) { * }, callback); * * //- - * // Get the projects from your account as a readable object stream. + * // If the callback is omitted, we'll return a Promise. * //- - * resource.getProjects() - * .on('error', console.error) - * .on('data', function(project) { - * // `project` is a `Project` object. - * }) - * .on('end', function() { - * // All projects retrieved. - * }); - * - * //- - * // If you anticipate many results, you can end a stream early to prevent - * // unnecessary processing and API requests. - * //- - * resource.getProjects() - * .on('data', function(project) { - * this.end(); - * }); + * resource.getProjects().then(function(data) { + * var projects = data[0]; + * }); */ Resource.prototype.getProjects = function(options, callback) { var self = this; @@ -228,6 +222,35 @@ Resource.prototype.getProjects = function(options, callback) { }); }; +/** + * Get a list of {module:resource/project} objects as a readable object stream. + * + * @param {object=} query - Configuration object. See + * {module:resource#getProjects} for a complete list of options. + * @return {stream} + * + * @example + * resource.getProjectsStream() + * .on('error', console.error) + * .on('data', function(project) { + * // `project` is a `Project` object. + * }) + * .on('end', function() { + * // All projects retrieved. + * }); + * + * //- + * // If you anticipate many results, you can end a stream early to prevent + * // unnecessary processing and API requests. + * //- + * resource.getProjectsStream() + * .on('data', function(project) { + * this.end(); + * }); + */ +Resource.prototype.getProjectsStream = + common.paginator.streamify('getProjects'); + /** * Create a Project object. See {module:resoucemanager/createProject} to create * a project. @@ -252,10 +275,18 @@ Resource.prototype.project = function(id) { /*! Developer Documentation * - * These methods can be used with either a callback or as a readable object - * stream. `streamRouter` is used to add this dual behavior. + * These methods can be auto-paginated. + */ +common.paginator.extend(Resource, ['getProjects']); + +/*! Developer Documentation + * + * All async methods (except for streams) will return a Promise in the event + * that a callback is omitted. */ -common.streamRouter.extend(Resource, ['getProjects']); +common.util.promisifyAll(Resource, { + exclude: ['project'] +}); Resource.Project = Project; diff --git a/packages/google-cloud-resourcemanager/src/project.js b/packages/google-cloud-resourcemanager/src/project.js index 26508bbe135..94dbac30fcd 100644 --- a/packages/google-cloud-resourcemanager/src/project.js +++ b/packages/google-cloud-resourcemanager/src/project.js @@ -53,6 +53,14 @@ function Project(resource, id) { * // The zone was created successfully. * } * }); + * + * //- + * // If the callback is omitted, we'll return a Promise. + * //- + * project.create().then(function(data) { + * var zone = data[0]; + * var apiResponse = data[0]; + * }); */ create: true, @@ -75,6 +83,13 @@ function Project(resource, id) { * // The project was deleted! * } * }); + * + * //- + * // If the callback is omitted, we'll return a Promise. + * //- + * project.delete().then(function(data) { + * var apiResponse = data[0]; + * }); */ delete: true, @@ -88,6 +103,13 @@ function Project(resource, id) { * * @example * project.exists(function(err, exists) {}); + * + * //- + * // If the callback is omitted, we'll return a Promise. + * //- + * project.exists().then(function(data) { + * var exists = data[0]; + * }); */ exists: true, @@ -107,6 +129,14 @@ function Project(resource, id) { * project.get(function(err, project, apiResponse) { * // `project.metadata` has been populated. * }); + * + * //- + * // If the callback is omitted, we'll return a Promise. + * //- + * project.get().then(function(data) { + * var project = data[0]; + * var apiResponse = data[1]; + * }); */ get: true, @@ -124,6 +154,14 @@ function Project(resource, id) { * * @example * project.getMetadata(function(err, metadata, apiResponse) {}); + * + * //- + * // If the callback is omitted, we'll return a Promise. + * //- + * project.getMetadata().then(function(data) { + * var metadata = data[0]; + * var apiResponse = data[1]; + * }); */ getMetadata: true, @@ -153,6 +191,13 @@ function Project(resource, id) { * // The project has been successfully updated. * } * }); + * + * //- + * // If the callback is omitted, we'll return a Promise. + * //- + * project.setMetadata(metadata).then(function(data) { + * var apiResponse = data[0]; + * }); */ setMetadata: { reqOpts: { @@ -190,6 +235,13 @@ util.inherits(Project, common.ServiceObject); * // Project restored. * } * }); + * + * //- + * // If the callback is omitted, we'll return a Promise. + * //- + * project.restore().then(function(data) { + * var apiResponse = data[0]; + * }); */ Project.prototype.restore = function(callback) { callback = callback || common.util.noop; @@ -202,4 +254,11 @@ Project.prototype.restore = function(callback) { }); }; +/*! Developer Documentation + * + * All async methods (except for streams) will return a Promise in the event + * that a callback is omitted. + */ +common.util.promisifyAll(Project); + module.exports = Project; diff --git a/packages/google-cloud-resourcemanager/system-test/resource.js b/packages/google-cloud-resourcemanager/system-test/resource.js index 50d633fdef3..025827b07b1 100644 --- a/packages/google-cloud-resourcemanager/system-test/resource.js +++ b/packages/google-cloud-resourcemanager/system-test/resource.js @@ -38,7 +38,7 @@ describe('Resource', function() { it('should get a list of projects in stream mode', function(done) { var resultsMatched = 0; - resource.getProjects() + resource.getProjectsStream() .on('error', done) .on('data', function() { resultsMatched++; diff --git a/packages/google-cloud-resourcemanager/test/index.js b/packages/google-cloud-resourcemanager/test/index.js index 07a39e6adf5..771ad307fda 100644 --- a/packages/google-cloud-resourcemanager/test/index.js +++ b/packages/google-cloud-resourcemanager/test/index.js @@ -36,7 +36,7 @@ function FakeService() { nodeutil.inherits(FakeService, Service); var extended = false; -var fakeStreamRouter = { +var fakePaginator = { extend: function(Class, methods) { if (Class.name !== 'Resource') { return; @@ -46,9 +46,13 @@ var fakeStreamRouter = { assert.equal(Class.name, 'Resource'); assert.deepEqual(methods, ['getProjects']); extended = true; + }, + streamify: function(methodName) { + return methodName; } }; +var promisified = true; var makeAuthenticatedRequestFactoryOverride; var fakeUtil = extend({}, util, { makeAuthenticatedRequestFactory: function() { @@ -57,6 +61,14 @@ var fakeUtil = extend({}, util, { } return util.makeAuthenticatedRequestFactory.apply(null, arguments); + }, + promisifyAll: function(Class, options) { + if (Class.name !== 'Resource') { + return; + } + + promisified = true; + assert.deepEqual(options.exclude, ['project']); } }); @@ -70,7 +82,7 @@ describe('Resource', function() { Resource = proxyquire('../', { '@google-cloud/common': { Service: FakeService, - streamRouter: fakeStreamRouter, + paginator: fakePaginator, util: fakeUtil }, './project.js': FakeProject @@ -87,7 +99,15 @@ describe('Resource', function() { describe('instantiation', function() { it('should extend the correct methods', function() { - assert(extended); // See `fakeStreamRouter.extend` + assert(extended); // See `fakePaginator.extend` + }); + + it('should streamify the correct methods', function() { + assert.strictEqual(resource.getProjectsStream, 'getProjects'); + }); + + it('should promisify all tlhe things', function() { + assert(promisified); }); it('should normalize the arguments', function() { diff --git a/packages/google-cloud-resourcemanager/test/project.js b/packages/google-cloud-resourcemanager/test/project.js index 9413224ee30..dbf3efd0215 100644 --- a/packages/google-cloud-resourcemanager/test/project.js +++ b/packages/google-cloud-resourcemanager/test/project.js @@ -23,6 +23,15 @@ var proxyquire = require('proxyquire'); var ServiceObject = require('@google-cloud/common').ServiceObject; var util = require('@google-cloud/common').util; +var promisified = false; +var fakeUtil = extend({}, util, { + promisifyAll: function(Class) { + if (Class.name === 'Project') { + promisified = true; + } + } +}); + function FakeServiceObject() { this.calledWith_ = arguments; ServiceObject.apply(this, arguments); @@ -42,7 +51,8 @@ describe('Project', function() { before(function() { Project = proxyquire('../src/project.js', { '@google-cloud/common': { - ServiceObject: FakeServiceObject + ServiceObject: FakeServiceObject, + util: fakeUtil } }); }); @@ -83,6 +93,10 @@ describe('Project', function() { } }); }); + + it('should promisify all tlhe things', function() { + assert(promisified); + }); }); describe('restore', function() {