From 4bba4b86c52df30b4d4dc3b1635ac3715a36b1c2 Mon Sep 17 00:00:00 2001 From: Stephen Sawchuk Date: Wed, 12 Aug 2015 16:59:39 -0400 Subject: [PATCH 1/2] core: test index file --- lib/common/util.js | 6 +- lib/index.js | 24 +++-- package.json | 2 +- test/index.js | 227 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 251 insertions(+), 8 deletions(-) create mode 100644 test/index.js diff --git a/lib/common/util.js b/lib/common/util.js index c11c126b3c6..75072706d35 100644 --- a/lib/common/util.js +++ b/lib/common/util.js @@ -62,7 +62,7 @@ util.missingProjectIdError = missingProjectIdError; * latter is preferred. * * @param {object} globalConfig - The global configuration object. - * @param {object} overrides - The instantiation-time configuration object. + * @param {object=} overrides - The instantiation-time configuration object. * @return {object} * * @example @@ -83,11 +83,15 @@ util.missingProjectIdError = missingProjectIdError; function extendGlobalConfig(globalConfig, overrides) { var options = extend({}, globalConfig); var hasGlobalConnection = options.credentials || options.keyFilename; + + overrides = overrides || {}; var isOverridingConnection = overrides.credentials || overrides.keyFilename; + if (hasGlobalConnection && isOverridingConnection) { delete options.credentials; delete options.keyFilename; } + return extend(true, {}, options, overrides); } diff --git a/lib/index.js b/lib/index.js index 7dc4c2cf2c6..5dc42b19b5f 100644 --- a/lib/index.js +++ b/lib/index.js @@ -20,6 +20,8 @@ 'use strict'; +var extend = require('extend'); + /** * @type {module:bigquery} * @private @@ -122,29 +124,39 @@ var util = require('./common/util.js'); * //- */ function gcloud(config) { - return { + var api = { bigquery: function(options) { - options = options || {}; return new BigQuery(util.extendGlobalConfig(config, options)); }, + datastore: new Datastore(config), + dns: function(options) { - options = options || {}; return new DNS(util.extendGlobalConfig(config, options)); }, + pubsub: function(options) { - options = options || {}; return new PubSub(util.extendGlobalConfig(config, options)); }, + search: function(options) { - options = options || {}; return new Search(util.extendGlobalConfig(config, options)); }, + storage: function(options) { - options = options || {}; return new Storage(util.extendGlobalConfig(config, options)); } }; + + // Extend each API to pick up static members, e.g. Datastore.int & Storage.acl + extend(api.bigquery, BigQuery); + extend(api.datastore, Datastore); + extend(api.dns, DNS); + extend(api.pubsub, PubSub); + extend(api.search, Search); + extend(api.storage, Storage); + + return api; } /** diff --git a/package.json b/package.json index 29054ea9b4d..97b5442c94d 100644 --- a/package.json +++ b/package.json @@ -90,7 +90,7 @@ "scripts": { "docs": "./scripts/docs.sh", "lint": "jshint lib/ system-test/ test/ && jscs lib/ system-test/ test/", - "test": "npm run docs && mocha test/*/*.js test/docs.js", + "test": "npm run docs && mocha test/*/*.js test/index.js test/docs.js", "system-test": "mocha system-test/* --timeout 45000", "cover": "istanbul cover -x 'system-test/*' _mocha -- --timeout 45000 test/*/*.js test/docs.js system-test/*", "coveralls": "istanbul cover -x 'system-test/*' _mocha --report lcovonly -- --timeout 45000 test/*/*.js test/docs.js system-test/* -R spec && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage" diff --git a/test/index.js b/test/index.js new file mode 100644 index 00000000000..151e927bada --- /dev/null +++ b/test/index.js @@ -0,0 +1,227 @@ +/*! + * Copyright 2015 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +var assert = require('assert'); +var extend = require('extend'); +var mockery = require('mockery'); +var util = require('../lib/common/util.js'); + +var extendGlobalConfigOverride = null; +var fakeUtil = extend({}, util, { + extendGlobalConfig: function() { + var method = extendGlobalConfigOverride || util.extendGlobalConfig; + return method.apply(null, arguments); + } +}); + +function FakeBigQuery() { + this.calledWith_ = [].slice.call(arguments); +} +FakeBigQuery.static = true; + +function FakeDatastore() { + this.calledWith_ = [].slice.call(arguments); +} +FakeDatastore.static = true; + +function FakeDNS() { + this.calledWith_ = [].slice.call(arguments); +} +FakeDNS.static = true; + +function FakePubSub() { + this.calledWith_ = [].slice.call(arguments); +} +FakePubSub.static = true; + +function FakeSearch() { + this.calledWith_ = [].slice.call(arguments); +} +FakeSearch.static = true; + +function FakeStorage() { + this.calledWith_ = [].slice.call(arguments); +} +FakeStorage.static = true; + +describe('gcloud', function() { + var gcloud; + + before(function() { + mockery.registerMock('./bigquery', FakeBigQuery); + mockery.registerMock('./datastore', FakeDatastore); + mockery.registerMock('./dns', FakeDNS); + mockery.registerMock('./pubsub', FakePubSub); + mockery.registerMock('./search', FakeSearch); + mockery.registerMock('./storage', FakeStorage); + mockery.registerMock('./common/util.js', fakeUtil); + mockery.enable({ + useCleanCache: true, + warnOnUnregistered: false + }); + gcloud = require('../lib/index.js'); + }); + + beforeEach(function() { + extendGlobalConfigOverride = null; + }); + + after(function() { + mockery.deregisterAll(); + mockery.disable(); + }); + + it('should export a function', function() { + assert.strictEqual(typeof gcloud, 'function'); + }); + + it('should export static bigquery', function() { + assert.strictEqual(gcloud.bigquery, FakeBigQuery); + }); + + it('should export static datastore', function() { + assert.strictEqual(gcloud.datastore, FakeDatastore); + }); + + it('should export static dns', function() { + assert.strictEqual(gcloud.dns, FakeDNS); + }); + + it('should export static pubsub', function() { + assert.strictEqual(gcloud.pubsub, FakePubSub); + }); + + it('should export static search', function() { + assert.strictEqual(gcloud.search, FakeSearch); + }); + + it('should export static storage', function() { + assert.strictEqual(gcloud.storage, FakeStorage); + }); + + describe('localized auth', function() { + var localGcloud; + var config = { a: 'b', c: 'd' }; + var options = { e: 'f', g: 'h' }; + var extendedOptions = { a: 'b', c: 'd' }; + + beforeEach(function() { + localGcloud = gcloud(config); + }); + + describe('bigquery', function() { + it('should create new BigQuery with extended options', function() { + extendGlobalConfigOverride = function(config_, options_) { + assert.strictEqual(config_, config); + assert.strictEqual(options_, options); + return extendedOptions; + }; + + var bigquery = localGcloud.bigquery(options); + + assert.strictEqual(bigquery.calledWith_[0], extendedOptions); + }); + + it('should extend the original API', function() { + assert.strictEqual(localGcloud.bigquery.static, FakeBigQuery.static); + }); + }); + + describe('datastore', function() { + it('should create new Datastore from original config', function() { + assert.strictEqual(localGcloud.datastore.calledWith_[0], config); + }); + + it('should extend the original API', function() { + assert.strictEqual(localGcloud.datastore.static, FakeDatastore.static); + }); + }); + + describe('dns', function() { + it('should create new BigQuery with extended options', function() { + extendGlobalConfigOverride = function(config_, options_) { + assert.strictEqual(config_, config); + assert.strictEqual(options_, options); + return extendedOptions; + }; + + var dns = localGcloud.dns(options); + + assert.strictEqual(dns.calledWith_[0], extendedOptions); + }); + + it('should extend the original API', function() { + assert.strictEqual(localGcloud.dns.static, FakeDNS.static); + }); + }); + + describe('pubsub', function() { + it('should create new BigQuery with extended options', function() { + extendGlobalConfigOverride = function(config_, options_) { + assert.strictEqual(config_, config); + assert.strictEqual(options_, options); + return extendedOptions; + }; + + var pubsub = localGcloud.pubsub(options); + + assert.strictEqual(pubsub.calledWith_[0], extendedOptions); + }); + + it('should extend the original API', function() { + assert.strictEqual(localGcloud.pubsub.static, FakePubSub.static); + }); + }); + + describe('search', function() { + it('should create new BigQuery with extended options', function() { + extendGlobalConfigOverride = function(config_, options_) { + assert.strictEqual(config_, config); + assert.strictEqual(options_, options); + return extendedOptions; + }; + + var search = localGcloud.search(options); + + assert.strictEqual(search.calledWith_[0], extendedOptions); + }); + + it('should extend the original API', function() { + assert.strictEqual(localGcloud.search.static, FakeSearch.static); + }); + }); + + describe('storage', function() { + it('should create new BigQuery with extended options', function() { + extendGlobalConfigOverride = function(config_, options_) { + assert.strictEqual(config_, config); + assert.strictEqual(options_, options); + return extendedOptions; + }; + + var storage = localGcloud.storage(options); + + assert.strictEqual(storage.calledWith_[0], extendedOptions); + }); + + it('should extend the original API', function() { + assert.strictEqual(localGcloud.storage.static, FakeStorage.static); + }); + }); + }); +}); From 8b6489380d24bd2ee5af7da09fb4c23dfd2c58c5 Mon Sep 17 00:00:00 2001 From: Stephen Sawchuk Date: Wed, 12 Aug 2015 21:11:57 -0400 Subject: [PATCH 2/2] restructure index.js & correct doc sorting method --- docs/site/components/docs/docs.html | 4 +- docs/site/components/docs/docs.js | 10 +- lib/index.js | 331 +++++++++++++--------------- 3 files changed, 161 insertions(+), 184 deletions(-) diff --git a/docs/site/components/docs/docs.html b/docs/site/components/docs/docs.html index dfb6adc6629..efa2f809003 100644 --- a/docs/site/components/docs/docs.html +++ b/docs/site/components/docs/docs.html @@ -68,11 +68,11 @@

-
Available methods: - + {{method.name}}{{$last ? '' : ', '}} diff --git a/docs/site/components/docs/docs.js b/docs/site/components/docs/docs.js index 880edee35b1..b737ea9edb4 100644 --- a/docs/site/components/docs/docs.js +++ b/docs/site/components/docs/docs.js @@ -266,7 +266,15 @@ angular } function compareMethods(a, b) { - return a.constructor ? -1: a.name > b.name ? 1 : -1; + if (a.constructor) { + return -1; + } + + if (b.constructor) { + return 1; + } + + return a.name > b.name ? 1 : -1; } $routeProvider diff --git a/lib/index.js b/lib/index.js index 5dc42b19b5f..0c2e809316b 100644 --- a/lib/index.js +++ b/lib/index.js @@ -23,46 +23,151 @@ var extend = require('extend'); /** - * @type {module:bigquery} - * @private - */ -var BigQuery = require('./bigquery'); - -/** - * @type {module:datastore} - * @private - */ -var Datastore = require('./datastore'); - -/** - * @type {module:dns} - * @private - */ -var DNS = require('./dns'); - -/** - * @type {module:pubsub} - * @private - */ -var PubSub = require('./pubsub'); - -/** - * @type {module:search} + * @type {module:common/util} * @private */ -var Search = require('./search'); +var util = require('./common/util.js'); /** - * @type {module:storage} + * The APIs exposed to the user. + * + * @type {object} * @private */ -var Storage = require('./storage'); +var apis = { + /** + * Analyze Big Data in the cloud with + * [Google BigQuery](https://cloud.google.com/bigquery). Run fast, SQL-like + * queries against multi-terabyte datasets in seconds. Scalable and easy to + * use, BigQuery gives you real-time insights about your data. + * + * @type {module:bigquery} + * + * @return {module:bigquery} + * + * @example + * var gcloud = require('gcloud'); + * var bigquery = gcloud.bigquery({ + * projectId: 'grape-spaceship-123', + * keyFilename: '/path/to/keyfile.json' + * }); + */ + bigquery: require('./bigquery'), + + /** + * [Google Cloud Datastore](https://developers.google.com/datastore/) is a + * fully managed, schemaless database for storing non-relational data. Use + * this object to create a Dataset to interact with your data, an "Int", and a + * "Double" representation. + * + * @type {module:datastore} + * + * @return {module:datastore} + * + * @example + * var gcloud = require('gcloud'); + * var datastore = gcloud.datastore; + * var dataset = datastore.dataset({ + * projectId: 'grape-spaceship-123', + * keyFilename: '/path/to/keyfile.json' + * }); + */ + datastore: require('./datastore'), + + /** + * [Google Cloud DNS](https://cloud.google.com/dns/what-is-cloud-dns) is a + * high-performance, resilient, global DNS service that provides a cost- + * effective way to make your applications and services available to your + * users. This programmable, authoritative DNS service can be used to easily + * publish and manage DNS records using the same infrastructure relied upon by + * Google. + * + * @type {module:dns} + * + * @return {module:dns} + * + * @example + * var gcloud = require('gcloud'); + * var dns = gcloud.dns({ + * projectId: 'grape-spaceship-123', + * keyFilename: '/path/to/keyfile.json' + * }); + */ + dns: require('./dns'), + + /** + * [Google Cloud Pub/Sub](https://developers.google.com/pubsub/overview) is a + * reliable, many-to-many, asynchronous messaging service from Google Cloud + * Platform. + * + * @type {module:pubsub} + * + * @return {module:pubsub} + * + * @example + * var gcloud = require('gcloud'); + * var pubsub = gcloud.pubsub({ + * projectId: 'grape-spaceship-123', + * keyFilename: '/path/to/keyfile.json' + * }); + */ + pubsub: require('./pubsub'), + + /** + * [Google Cloud Search](https://cloud.google.com/search/) allows you to + * quickly perform full-text and geospatial searches against your data without + * having to spin up your own instances and without the hassle of managing and + * maintaining a search service. + * + *

+ * **This is an *Alpha* release of Google Cloud Search.** This feature is + * not covered by any SLA or deprecation policy and may be subject to + * backward-incompatible changes. + *

+ * + * @type {module:search} + * + * @return {module:search} + * + * @example + * var gcloud = require('gcloud'); + * var search = gcloud.search({ + * projectId: 'grape-spaceship-123', + * keyFilename: '/path/to/keyfile.json' + * }); + */ + search: require('./search'), + + /** + * Google Cloud Storage allows you to store data on Google infrastructure. + * Read [Google Cloud Storage API docs](https://developers.google.com/storage) + * for more information. + * + * @type {module:storage} + * + * @return {module:storage} + * + * @example + * var gcloud = require('gcloud'); + * var gcs = gcloud.storage({ + * projectId: 'grape-spaceship-123', + * keyFilename: '/path/to/keyfile.json' + * }); + */ + storage: require('./storage') +}; /** - * @type {module:common/util} + * Scoped APIs are "boxed in" APIs. The "outer" class (e.g. Datastore) is a + * container for sub-classes that can be given separate authentication and + * instantiation options. + * + * @type {object} * @private */ -var util = require('./common/util.js'); +var scopedApis = { + datastore: true +}; /** * There are two key ways to use the `gcloud` module. @@ -124,159 +229,23 @@ var util = require('./common/util.js'); * //- */ function gcloud(config) { - var api = { - bigquery: function(options) { - return new BigQuery(util.extendGlobalConfig(config, options)); - }, - - datastore: new Datastore(config), - - dns: function(options) { - return new DNS(util.extendGlobalConfig(config, options)); - }, - - pubsub: function(options) { - return new PubSub(util.extendGlobalConfig(config, options)); - }, - - search: function(options) { - return new Search(util.extendGlobalConfig(config, options)); - }, - - storage: function(options) { - return new Storage(util.extendGlobalConfig(config, options)); + return Object.keys(apis).reduce(function(gcloudExposedApi, apiName) { + var Class = apis[apiName]; + + if (scopedApis[apiName]) { + gcloudExposedApi[apiName] = new Class(config); + } else { + gcloudExposedApi[apiName] = function(options) { + return new Class(util.extendGlobalConfig(config, options)); + }; } - }; - // Extend each API to pick up static members, e.g. Datastore.int & Storage.acl - extend(api.bigquery, BigQuery); - extend(api.datastore, Datastore); - extend(api.dns, DNS); - extend(api.pubsub, PubSub); - extend(api.search, Search); - extend(api.storage, Storage); + // Extend each API to pick up static members, e.g. Datastore.int and + // Storage.acl. + extend(gcloudExposedApi[apiName], Class); - return api; + return gcloudExposedApi; + }, {}); } -/** - * Analyze Big Data in the cloud with - * [Google BigQuery](https://cloud.google.com/bigquery). Run fast, SQL-like - * queries against multi-terabyte datasets in seconds. Scalable and easy to use, - * BigQuery gives you real-time insights about your data. - * - * @type {module:bigquery} - * - * @return {module:bigquery} - * - * @example - * var gcloud = require('gcloud'); - * var bigquery = gcloud.bigquery({ - * projectId: 'grape-spaceship-123', - * keyFilename: '/path/to/keyfile.json' - * }); - */ -gcloud.bigquery = BigQuery; - -/** - * [Google Cloud Datastore](https://developers.google.com/datastore/) is a fully - * managed, schemaless database for storing non-relational data. Use this object - * to create a Dataset to interact with your data, an "Int", and a "Double" - * representation. - * - * @type {module:datastore} - * - * @return {module:datastore} - * - * @example - * var gcloud = require('gcloud'); - * var datastore = gcloud.datastore; - * var dataset = datastore.dataset({ - * projectId: 'grape-spaceship-123', - * keyFilename: '/path/to/keyfile.json' - * }); - */ -gcloud.datastore = Datastore; - -/** - * [Google Cloud DNS](https://cloud.google.com/dns/what-is-cloud-dns) is a high- - * performance, resilient, global DNS service that provides a cost-effective way - * to make your applications and services available to your users. This - * programmable, authoritative DNS service can be used to easily publish and - * manage DNS records using the same infrastructure relied upon by Google. - * - * @type {module:dns} - * - * @return {module:dns} - * - * @example - * var gcloud = require('gcloud'); - * var dns = gcloud.dns({ - * projectId: 'grape-spaceship-123', - * keyFilename: '/path/to/keyfile.json' - * }); - */ -gcloud.dns = DNS; - -/** - * [Google Cloud Pub/Sub](https://developers.google.com/pubsub/overview) is a - * reliable, many-to-many, asynchronous messaging service from Google Cloud - * Platform. - * - * @type {module:pubsub} - * - * @return {module:pubsub} - * - * @example - * var gcloud = require('gcloud'); - * var pubsub = gcloud.pubsub({ - * projectId: 'grape-spaceship-123', - * keyFilename: '/path/to/keyfile.json' - * }); - */ -gcloud.pubsub = PubSub; - -/** - * [Google Cloud Search](https://cloud.google.com/search/) allows you to quickly - * perform full-text and geospatial searches against your data without having to - * spin up your own instances and without the hassle of managing and maintaining - * a search service. - * - *

- * **This is an *Alpha* release of Google Cloud Search.** This feature is - * not covered by any SLA or deprecation policy and may be subject to - * backward-incompatible changes. - *

- * - * @type {module:search} - * - * @return {module:search} - * - * @example - * var gcloud = require('gcloud'); - * var search = gcloud.search({ - * projectId: 'grape-spaceship-123', - * keyFilename: '/path/to/keyfile.json' - * }); - */ -gcloud.search = Search; - -/** - * Google Cloud Storage allows you to store data on Google infrastructure. - * Read [Google Cloud Storage API docs](https://developers.google.com/storage/) - * for more information. - * - * @type {module:storage} - * - * @return {module:storage} - * - * @example - * var gcloud = require('gcloud'); - * var gcs = gcloud.storage({ - * projectId: 'grape-spaceship-123', - * keyFilename: '/path/to/keyfile.json' - * }); - */ -gcloud.storage = Storage; - -module.exports = gcloud; +module.exports = extend(gcloud, apis);