From c8a593e3e991db33daf6698c13bd244ee968f14d Mon Sep 17 00:00:00 2001 From: Stephen Sawchuk Date: Tue, 14 Apr 2015 12:49:55 -0400 Subject: [PATCH] datastore: support local devserver automatically - fixes #104 --- lib/datastore/dataset.js | 36 +++++++++++---- test/datastore/dataset.js | 93 +++++++++++++++++++++++++++++---------- 2 files changed, 98 insertions(+), 31 deletions(-) diff --git a/lib/datastore/dataset.js b/lib/datastore/dataset.js index 4ed176c659f..62173f961e5 100644 --- a/lib/datastore/dataset.js +++ b/lib/datastore/dataset.js @@ -110,20 +110,40 @@ function Dataset(options) { email: options.email }); - if (options.apiEndpoint && options.apiEndpoint.indexOf('http') !== 0) { - options.apiEndpoint = 'http://' + options.apiEndpoint; - } - - var trailingSlashes = new RegExp('/*$'); - this.apiEndpoint = options.apiEndpoint || 'https://www.googleapis.com'; - this.apiEndpoint = this.apiEndpoint.replace(trailingSlashes, ''); - + this.apiEndpoint = Dataset.determineApiEndpoint_(options); this.namespace = options.namespace; this.projectId = options.projectId; } nodeutil.inherits(Dataset, DatastoreRequest); +/** + * Determine the appropriate endpoint to use for API requests. If not explicitly + * defined, check for the "DATASTORE_HOST" environment variable, used to connect + * to a local Datastore server. + * + * @private + * + * @param {object} options - Configuration object. + * @param {string=} options.apiEndpoint - Custom API endpoint. + */ +Dataset.determineApiEndpoint_ = function(options) { + var apiEndpoint = 'https://www.googleapis.com'; + var trailingSlashes = new RegExp('/*$'); + + if (options.apiEndpoint) { + apiEndpoint = options.apiEndpoint; + } else if (process.env.DATASTORE_HOST) { + apiEndpoint = process.env.DATASTORE_HOST; + } + + if (apiEndpoint.indexOf('http') !== 0) { + apiEndpoint = 'http://' + apiEndpoint; + } + + return apiEndpoint.replace(trailingSlashes, ''); +}; + /** * Helper to create a Key object, scoped to the dataset's namespace by default. * diff --git a/test/datastore/dataset.js b/test/datastore/dataset.js index 274a129e068..30b49a3715d 100644 --- a/test/datastore/dataset.js +++ b/test/datastore/dataset.js @@ -14,39 +14,31 @@ * limitations under the License. */ -/*global describe, it, beforeEach */ - 'use strict'; var assert = require('assert'); -var Dataset = require('../../lib/datastore/dataset'); var util = require('../../lib/common/util.js'); describe('Dataset', function() { - describe('instantiation', function() { - it('should set default API connection details', function() { - var ds = new Dataset(); - assert.equal(ds.apiEndpoint, 'https://www.googleapis.com'); - }); + var Dataset; - it('should set API connection details', function() { - var ds = new Dataset({ apiEndpoint: 'http://localhost:8080' }); - assert.equal(ds.apiEndpoint, 'http://localhost:8080'); - }); + beforeEach(function() { + delete require.cache[require.resolve('../../lib/datastore/dataset')]; + Dataset = require('../../lib/datastore/dataset'); + }); - it('should remove slashes from the apiEndpoint', function() { - var ds1 = new Dataset({ apiEndpoint: 'http://localhost:8080' }); - var ds2 = new Dataset({ apiEndpoint: 'http://localhost:8080/' }); - var ds3 = new Dataset({ apiEndpoint: 'http://localhost:8080//' }); + describe('instantiation', function() { + it('should set default API connection details', function() { + var options = { a: 'b', c: 'd' }; + var mockApiEndpoint = 'http://localhost:8080'; - assert.equal(ds1.apiEndpoint, 'http://localhost:8080'); - assert.equal(ds2.apiEndpoint, 'http://localhost:8080'); - assert.equal(ds3.apiEndpoint, 'http://localhost:8080'); - }); + Dataset.determineApiEndpoint_ = function (opts) { + assert.deepEqual(opts, options); + return mockApiEndpoint; + }; - it('should default to http if protocol is unspecified', function() { - var ds = new Dataset({ apiEndpoint: 'localhost:8080' }); - assert.equal(ds.apiEndpoint, 'http://localhost:8080'); + var ds = new Dataset(options); + assert.equal(ds.apiEndpoint, mockApiEndpoint); }); }); @@ -175,4 +167,59 @@ describe('Dataset', function() { assert.strictEqual(query.namespace, null); }); }); + + describe('determineApiEndpoint_', function() { + it('should default to googleapis.com', function() { + delete process.env.DATASTORE_HOST; + var expectedApiEndpoint = 'https://www.googleapis.com'; + assert.equal(Dataset.determineApiEndpoint_({}), expectedApiEndpoint); + }); + + it('should remove slashes from the apiEndpoint', function() { + var expectedApiEndpoint = 'http://localhost:8080'; + + assert.equal(Dataset.determineApiEndpoint_({ + apiEndpoint: expectedApiEndpoint + }), expectedApiEndpoint); + + assert.equal(Dataset.determineApiEndpoint_({ + apiEndpoint: 'http://localhost:8080/' + }), expectedApiEndpoint); + + assert.equal(Dataset.determineApiEndpoint_({ + apiEndpoint: 'http://localhost:8080//' + }), expectedApiEndpoint); + }); + + it('should default to http if protocol is unspecified', function() { + var apiEndpoint = Dataset.determineApiEndpoint_({ + apiEndpoint: 'localhost:8080' + }); + assert.equal(apiEndpoint, 'http://localhost:8080'); + }); + + describe('with DATASTORE_HOST environment variable', function() { + var DATASTORE_HOST = 'http://localhost:8080'; + + before(function() { + process.env.DATASTORE_HOST = DATASTORE_HOST; + }); + + after(function() { + delete process.env.DATASTORE_HOST; + }); + + it('should use the DATASTORE_HOST env var', function() { + assert.equal(Dataset.determineApiEndpoint_({}), DATASTORE_HOST); + }); + + it('should favor an explicit apiEndpoint option', function() { + var expectedApiEndpoint = 'http://apiendpointoverride'; + + assert.equal(Dataset.determineApiEndpoint_({ + apiEndpoint: expectedApiEndpoint + }), expectedApiEndpoint); + }); + }); + }); });