diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000000..da0310f513b --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +# editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false \ No newline at end of file diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 00000000000..743037d6e2c --- /dev/null +++ b/.jshintrc @@ -0,0 +1,20 @@ +{ + "bitwise": true, + "camelcase": true, + "curly": true, + "eqeqeq": true, + "esnext": true, + "freeze": true, + "immed": true, + "indent": 2, + "latedef": "nofunc", + "maxlen": 80, + "newcap": true, + "node": true, + "noarg": true, + "quotmark": "single", + "strict": true, + "trailing": true, + "undef": true, + "unused": true +} diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 0cab2b7ee6b..285109c858d 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -13,4 +13,5 @@ Burcu Dogan Johan Euphrosine -Silvano Luciani \ No newline at end of file +Silvano Luciani +Stephen Sawchuk diff --git a/lib/common/connection.js b/lib/common/connection.js index 792db331b8b..dd003dc8f20 100644 --- a/lib/common/connection.js +++ b/lib/common/connection.js @@ -14,13 +14,18 @@ * limitations under the License. */ +/*jshint camelcase:false */ + +'use strict'; + var GAPIToken = require('gapitoken'), - async = require('async'), - req = require('request'), - pkg = require('../../package.json'); + req = require('request'), + pkg = require('../../package.json'), + util = require('./util'); var USER_AGENT = 'gcloud-node/' + pkg.version, - METADATA_TOKEN_URL = 'http://metadata/computeMetadata/v1/instance/service-accounts/default/token'; + METADATA_TOKEN_URL = 'http://metadata/computeMetadata/v1/instance/' + + 'service-accounts/default/token'; /** * Token represents an access token @@ -48,8 +53,10 @@ Token.prototype.isExpired = function() { */ function Connection(opts) { var credentials = opts.keyFilename && require(opts.keyFilename) || {}; - this.email = credentials['client_email']; // client email for the service account - this.privateKey = credentials['private_key']; // contains the contents of a pem file + // client email for the service account + this.email = credentials.client_email; + // contains the contents of a pem file + this.privateKey = credentials.private_key; this.scopes = opts.scopes || []; this.token = null; // existing access token, if exists @@ -84,7 +91,6 @@ Connection.prototype.connect = function(callback) { * @param {Function} callback Callback function. */ Connection.prototype.fetchToken = function(callback) { - var that = this; if (!this.email || !this.privateKey) { // We should be on GCE, try to retrieve token from // the metadata from server. @@ -113,7 +119,7 @@ Connection.prototype.fetchToken = function(callback) { if (err) { return callback(err); } - gapi.getToken(function(err, t) { + gapi.getToken(function(err) { if (err) { return callback(err); } @@ -127,20 +133,21 @@ Connection.prototype.fetchToken = function(callback) { * Makes an authorized request if the current connection token is * still valid. Tries to reconnect and makes a request otherwise. * @param {Object} Request options. - * @param {Function=} opt_callback + * @param {Function=} callback */ -Connection.prototype.req = function(reqOpts, opt_callback) { +Connection.prototype.req = function(reqOpts, callback) { var that = this; + callback = callback || util.noop; this.createAuthorizedReq(reqOpts, function(err, authorizedReq) { if (err) { - opt_callback && opt_callback(err); + callback(err); return; } - that.requester(authorizedReq, opt_callback); + that.requester(authorizedReq, callback); }); }; -Connection.prototype.createAuthorizedReq = function(reqOpts, opt_callback) { +Connection.prototype.createAuthorizedReq = function(reqOpts, callback) { var that = this; // Add user agent. reqOpts.headers = reqOpts.headers || {}; @@ -148,20 +155,26 @@ Connection.prototype.createAuthorizedReq = function(reqOpts, opt_callback) { reqOpts.headers['User-Agent'] + '; ' + USER_AGENT : USER_AGENT; if (this.isConnected()) { - return opt_callback && opt_callback(null, this.authorizeReq(reqOpts)); + return callback(null, this.authorizeReq(reqOpts)); } if (this.isConnecting) { this.waitQueue = this.waitQueue || []; - this.waitQueue.push({ req: reqOpts, cb: opt_callback }); + this.waitQueue.push({ req: reqOpts, cb: callback }); return; } this.connect(function(err) { - that.waitQueue.push({ req: reqOpts, cb: opt_callback }); + that.waitQueue.push({ req: reqOpts, cb: callback }); that.waitQueue.forEach(function(v) { + if (!v.cb) { + return; + } + if (err) { - return v.cb && v.cb(err); + v.cb(err); + return; } - v.cb && v.cb(null, that.authorizeReq(v.req)); + + v.cb(null, that.authorizeReq(v.req)); }); that.waitQueue = []; }); @@ -189,7 +202,7 @@ Connection.prototype.isConnected = function() { Connection.prototype.authorizeReq = function(reqOpts) { // TODO(jbd): Clone the request object. reqOpts.headers = reqOpts.headers || {}; - reqOpts.headers['Authorization'] = 'Bearer ' + this.token.accessToken; + reqOpts.headers.Authorization = 'Bearer ' + this.token.accessToken; return reqOpts; }; diff --git a/lib/common/util.js b/lib/common/util.js index 6cb1d46abb3..28636425d52 100644 --- a/lib/common/util.js +++ b/lib/common/util.js @@ -14,18 +14,20 @@ * limitations under the License. */ +/*jshint strict:false, noarg:false */ + var util = require('util'); -module.exports.extend = function(from, to) { - if (from == null || typeof from != "object") { +function extend(from, to) { + if (from === null || typeof from !== 'object') { return from; } - if (from.constructor != Object && from.constructor != Array) { + if (from.constructor !== Object && from.constructor !== Array) { return from; } - if (from.constructor == Date || from.constructor == Function || - from.constructor == String || from.constructor == Number || - from.constructor == Boolean) { + if (from.constructor === Date || from.constructor === Function || + from.constructor === String || from.constructor === Number || + from.constructor === Boolean) { return new from.constructor(from); } to = to || new from.constructor(); @@ -33,7 +35,9 @@ module.exports.extend = function(from, to) { to[name] = to[name] ? extend(from[name], null) : to[name]; } return to; -}; +} + +module.exports.extend = extend; module.exports.arrayize = function(input) { if (!Array.isArray(input)) { @@ -59,12 +63,12 @@ function ApiError (errorBody) { this.errors = errorBody.errors; this.code = errorBody.code; this.message = errorBody.message; -}; +} util.inherits(ApiError, Error); -module.exports.handleResp = function(err, resp, body, opt_callback) { - var callback = opt_callback || noop; +module.exports.handleResp = function(err, resp, body, callback) { + callback = callback || noop; if (err) { callback(err); return; diff --git a/lib/datastore/entity.js b/lib/datastore/entity.js index 614c269fd4f..515cbc89b46 100644 --- a/lib/datastore/entity.js +++ b/lib/datastore/entity.js @@ -14,9 +14,13 @@ * limitations under the License. */ +'use strict'; + var entityMeta = {}; -var namespaceRegex = kindRegex = fieldNameRegex = new RegExp(/^[A-Za-z]*$/); +var namespaceRegex = /^[A-Za-z]*$/, + kindRegex = /^[A-Za-z]*$/, + fieldNameRegex = /^[A-Za-z]*$/; /** * Conversion dict for query operation to operation proto value. @@ -46,7 +50,7 @@ function Int(val) { Int.prototype.get = function() { return this.val; -} +}; module.exports.Int = Int; @@ -56,10 +60,24 @@ function Double(val) { Double.prototype.get = function() { return this.val; -} +}; module.exports.Double = Double; +/** + * Converts any entity proto to a plain object. + */ +var entityFromEntityProto = function(proto) { + // TODO(jbd): Use registered metadata if provided. + return propertiesToObject(proto.properties); +}; + +/** + * Exports entityFromEntityProto. + * @type {Function} + */ +module.exports.entityFromEntityProto = entityFromEntityProto; + var keyFromKeyProto = function(proto) { var key = []; if (proto.partitionId.namespace) { @@ -76,10 +94,10 @@ module.exports.keyFromKeyProto = keyFromKeyProto; var keyToKeyProto = function(datasetId, key) { if (key.length < 2) { - throw new Error("A key should contain at least a kind and an identifier.") + throw new Error('A key should contain at least a kind and an identifier.'); } var namespace = null, start = 0; - if (key.length % 2 == 1) { + if (key.length % 2 === 1) { // the first item is the namespace namespace = key[0]; start = 1; @@ -159,7 +177,7 @@ function propertyToValue(property) { } return l; } -}; +} function propertiesToObject(properties) { properties = properties || []; @@ -168,21 +186,7 @@ function propertiesToObject(properties) { obj[name] = propertyToValue(properties[name]); } return obj; -}; - -/** - * Converts any entity proto to a plain object. - */ -var entityFromEntityProto = function(proto) { - // TODO(jbd): Use registered metadata if provided. - return propertiesToObject(proto.properties); -}; - -/** - * Exports entityFromEntityProto. - * @type {Function} - */ -module.exports.entityFromEntityProto = entityFromEntityProto; +} /** * Convert any object to property value. @@ -237,7 +241,7 @@ function valueToProperty(v) { p.entityValue = { properties: properties }; return p; } - throw new Error('Unsupported field value, ' + v + ', is provided.') + throw new Error('Unsupported field value, ' + v + ', is provided.'); } /** @@ -385,11 +389,11 @@ function validateField(name, field) { if (!field.kind) { throw new Error('Provide a kind for field ' + name); } - if (typeof field.kind != 'object' && - !primitiveKinds.indexOf(field.kind) < 0) { + if (typeof field.kind !== 'object' && + primitiveKinds.indexOf(field.kind) === -1) { throw new Error('Unknown kind for field ' + name); } - if (typeof field.kind == 'object') { + if (typeof field.kind === 'object') { Object.keys(field.key).forEach(function(key) { validateField(key, field.key[key]); }); @@ -406,4 +410,4 @@ module.exports.registerKind = registerKind; * Exports getKind. * @type {function} */ -module.exports.getKind = getKind +module.exports.getKind = getKind; diff --git a/lib/datastore/index.js b/lib/datastore/index.js index 46ab7ca3313..65188312335 100644 --- a/lib/datastore/index.js +++ b/lib/datastore/index.js @@ -14,12 +14,15 @@ * limitations under the License. */ +'use strict'; + var conn = require('../common/connection.js'), entity = require('./entity.js'), Query = require('./query.js').Query, util = require('../common/util.js'); -var DATASTORE_BASE_URL = 'https://www.googleapis.com/datastore/v1beta2/datasets', +var DATASTORE_BASE_URL = 'https://www.googleapis.com/datastore/v1beta2/' + + 'datasets', SCOPES = [ 'https://www.googleapis.com/auth/datastore', 'https://www.googleapis.com/auth/userinfo.email'], @@ -43,12 +46,13 @@ function Transaction(conn, datasetId) { * transaction instance with the remote transaction's ID. */ Transaction.prototype.begin = function(callback) { + callback = callback || util.noop; var that = this; this.makeReq('beginTransaction', null, function(err, resp) { if (!err) { that.id = resp.transaction; } - callback && callback(err); + callback(err); }); }; @@ -57,13 +61,14 @@ Transaction.prototype.begin = function(callback) { * the current transaction instance. */ Transaction.prototype.rollback = function(callback) { + callback = callback || util.noop; var that = this; var req = { transaction: this.id }; - this.makeReq('rollback', req, function(err, resp) { + this.makeReq('rollback', req, function(err) { if (!err) { that.isFinalized = true; } - callback && callback(err); + callback(err); }); }; @@ -72,13 +77,14 @@ Transaction.prototype.rollback = function(callback) { * current transaction instance. */ Transaction.prototype.commit = function(callback) { + callback = callback || util.noop; var that = this; var req = { transaction: this.id }; - this.makeReq('commit', req, function(err, resp) { + this.makeReq('commit', req, function(err) { if (!err) { that.isFinalized = true; } - callback && callback(err); + callback(err); }); }; @@ -144,7 +150,7 @@ Transaction.prototype.save = function(entities, callback) { acc.insertAutoId.push(ent); } return acc; - }, { upsert: [], insertAutoId: [] }) + }.bind(this), { upsert: [], insertAutoId: [] }) }; if (this.id) { req.transaction = this.id; @@ -198,10 +204,10 @@ Transaction.prototype.delete = function(keys, callback) { * } * }); * @param {Query} q - * @param {Function} opt_callback + * @param {Function} callback */ -Transaction.prototype.runQuery = function(q, opt_callback) { - opt_callback = opt_callback || util.noop; +Transaction.prototype.runQuery = function(q, callback) { + callback = callback || util.noop; var req = { readOptions: { transaction: this.id @@ -215,17 +221,17 @@ Transaction.prototype.runQuery = function(q, opt_callback) { } this.makeReq('runQuery', req, function(err, resp) { if (err || !resp.batch || !resp.batch.entityResults) { - return opt_callback(err); + return callback(err); } var nextQuery = null; if (resp.batch.endCursor && resp.batch.endCursor != q.startVal) { nextQuery = q.start(resp.batch.endCursor).offset(0); } - opt_callback(null, entity.formatArray(resp.batch.entityResults), nextQuery); + callback(null, entity.formatArray(resp.batch.entityResults), nextQuery); }); }; -Transaction.prototype.mapQuery = function(q, mapperFn, opt_callback) { +Transaction.prototype.mapQuery = function() { throw new Error('not yet implemented'); }; @@ -257,8 +263,8 @@ function Dataset(opts) { opts = opts || {}; var id = opts.projectId || ''; - if (id.indexOf("s~") < 0 && id.indexOf("e~") < 0) { - id = "s~" + id; + if (id.indexOf('s~') === -1 && id.indexOf('e~') === -1) { + id = 's~' + id; } this.id = id; @@ -315,7 +321,7 @@ Dataset.prototype.runInTransaction = function(fn, callback) { var done = function() { t.finalize(callback); }; - t.begin(function(err, id) { + t.begin(function(err) { if (err) { return callback(err); } @@ -325,7 +331,7 @@ Dataset.prototype.runInTransaction = function(fn, callback) { Dataset.prototype.allocateIds = function(incompleteKey, n, callback) { if (entity.isKeyComplete(incompleteKey)) { - throw new Error('An incomplete key should be provided.') + throw new Error('An incomplete key should be provided.'); } var incompleteKeys = []; for (var i = 0; i < n; i++) { diff --git a/lib/datastore/query.js b/lib/datastore/query.js index 393b4187936..15388f571f9 100644 --- a/lib/datastore/query.js +++ b/lib/datastore/query.js @@ -14,6 +14,8 @@ * limitations under the License. */ +'use strict'; + var util = require('../common/util.js'); function Query(namespace, kinds) { @@ -53,8 +55,9 @@ Query.prototype.order = function(order) { var q = util.extend(this, new Query()); var sign = order[0], fieldName = order.substr(1); - if (sign != '-' && sign != '+' ) { - throw new Error('Invalid order pattern, either should be "+fieldName" or "-fieldName".') + if (sign !== '-' && sign !== '+' ) { + throw new Error('Invalid order pattern. Expected "+fieldName" or ' + + '"-fieldName".'); } q.orders = q.orders || []; q.orders.push({ name: fieldName, sign: sign }); @@ -78,7 +81,7 @@ Query.prototype.start = function(start) { var q = util.extend(this, new Query()); q.startVal = start; return q; -} +}; Query.prototype.end = function(end) { var q = util.extend(this, new Query()); @@ -101,4 +104,4 @@ Query.prototype.offset = function(n) { /** * Exports Query. */ -module.exports.Query = Query; \ No newline at end of file +module.exports.Query = Query; diff --git a/lib/index.js b/lib/index.js index 359f1ae4f17..fa23327a004 100644 --- a/lib/index.js +++ b/lib/index.js @@ -14,6 +14,8 @@ * limitations under the License. */ +'use strict'; + var datastore = require('./datastore'), entity = require('./datastore/entity.js'); diff --git a/lib/pubsub/index.js b/lib/pubsub/index.js index 504876d9486..d49337b1b92 100644 --- a/lib/pubsub/index.js +++ b/lib/pubsub/index.js @@ -14,6 +14,8 @@ * limitations under the License. */ +'use strict'; + var events = require('events'), nodeutil = require('util'); @@ -35,7 +37,6 @@ var SCOPES = [ ]; function Subscription(conn, name) { - var that = this; this.conn = conn; this.name = name; @@ -62,9 +63,10 @@ Subscription.prototype.ack = function(ids, callback) { /** * Pulls from the subscribed topic. - * @param {Boolean} opts.returnImmediately If set, the system will respond immediately. - * Otherwise, wait until new messages are - * available. Returns if timeout is reached. + * @param {Boolean} opts.returnImmediately If set, the system will respond + * immediately. Otherwise, wait + * until new messages are available. + * Returns if timeout is reached. * @param {Function} callback Callback. */ Subscription.prototype.pull = function(opts, callback) { @@ -75,7 +77,8 @@ Subscription.prototype.pull = function(opts, callback) { subscription: this.name, returnImmediately: !!opts.returnImmediately }; - this.conn.makeReq('POST', 'subscriptions/pull', null, body, function(err, message) { + this.conn.makeReq('POST', 'subscriptions/pull', null, body, + function(err, message) { // TODO(jbd): Fix API to return a list of messages. if (err) { callback(err); @@ -117,23 +120,25 @@ Subscription.prototype.startPulling_ = function() { }); }; pullFn(); -} +}; /** * Deletes the current subscription. Pull requests from the current * subscription will be errored once unsubscription is done. - * @param {Function} opt_callback Optional callback. + * @param {Function} callback Optional callback. */ -Subscription.prototype.del = function(opt_callback) { +Subscription.prototype.del = function(callback) { + callback = callback || util.noop; var that = this; - cb = opt_callback || util.noop; var path = util.format('subscriptions/{fullName}', { fullName: this.name }); this.conn.makeReq('DELETE', path, null, true, function(err) { - if (err) return cb(err); + if (err) { + return callback(err); + } that.closed = true; - cb(err); + callback(err); }); }; @@ -175,35 +180,37 @@ function Topic(conn, name) { /** * Publishes the provided string message. * @param {string} data String message to publish. - * @param {Function} opt_callback Optional callback. + * @param {Function} callback Optional callback. */ -Topic.prototype.publish = function(data, opt_callback) { +Topic.prototype.publish = function(data, callback) { + callback = callback || util.noop; this.publishMessage({ topic: this.name, message: { data: new Buffer(data).toString('base64') } - }, opt_callback); + }, callback); }; /** * Publishes a raw message. * @param {message} message Raw message to publish. - * @param {Function} opt_callback Optional callback. + * @param {Function} callback Optional callback. */ -Topic.prototype.publishMessage = function(message, opt_callback) { - cb = opt_callback || util.noop; +Topic.prototype.publishMessage = function(message, callback) { + callback = callback || util.noop; message.topic = this.name; - this.conn.makeReq('POST', 'topics/publish', null, message, cb); + this.conn.makeReq('POST', 'topics/publish', null, message, callback); }; /** * Deletes a topic. - * @param {Function} opt_callback Optional callback. + * @param {Function} callback Optional callback. */ -Topic.prototype.del = function(opt_callback) { +Topic.prototype.del = function(callback) { + callback = callback || util.noop; var path = 'topics/' + this.name; - this.conn.makeReq('DELETE', path, null, true, opt_callback); + this.conn.makeReq('DELETE', path, null, true, callback); }; /** @@ -239,9 +246,13 @@ Connection.prototype.listSubscriptions = function(query, callback) { query = {}; } var q = util.extend({}, query); - q.query = q.filterByTopic - ? 'pubsub.googleapis.com/topic in (' + this.fullTopicName_(q.filterByTopic) + ')' - : 'cloud.googleapis.com/project in (' + this.fullProjectName_() + ')'; + if (q.filterByTopic) { + q.query = 'pubsub.googleapis.com/topic in (' + + this.fullTopicName_(q.filterByTopic) + ')'; + } else { + q.query = 'cloud.googleapis.com/project in (' + this.fullProjectName_() + + ')'; + } delete q.filterByTopic; this.makeReq('GET', 'subscriptions', q, true, function(err, result) { @@ -350,11 +361,11 @@ Connection.prototype.listTopics = function(query, callback) { /** * Gets a topic. * @param {string} name Name of the topic to get. - * @param {Function} opt_callback Optional callback. + * @param {Function} callback Optional callback. */ -Connection.prototype.getTopic = function(name, opt_callback) { +Connection.prototype.getTopic = function(name, callback) { var that = this; - var cb = opt_callback || util.noop, + var cb = callback || util.noop, fullName = this.fullTopicName_(name); this.makeReq('GET', 'topics/' + fullName, null, true, function(err) { if (err) { @@ -367,11 +378,11 @@ Connection.prototype.getTopic = function(name, opt_callback) { /** * Creates a topic with the given name. * @param {string} name Name of the topic. - * @param {Function} opt_callback Optional callback. + * @param {Function} callback Optional callback. */ -Connection.prototype.createTopic = function(name, opt_callback) { +Connection.prototype.createTopic = function(name, callback) { var that = this; - var cb = opt_callback || util.noop, + var cb = callback || util.noop, fullName = this.fullTopicName_(name); this.makeReq('POST', 'topics', null, { name: fullName }, function(err) { cb(err, new Topic(that, fullName)); diff --git a/lib/storage/index.js b/lib/storage/index.js index 856e2f33f74..38887965f7f 100644 --- a/lib/storage/index.js +++ b/lib/storage/index.js @@ -14,6 +14,8 @@ * limitations under the License. */ +'use strict'; + var conn = require('../common/connection.js'), nodeutil = require('util'), events = require('events'), @@ -29,7 +31,7 @@ var conn = require('../common/connection.js'), var SCOPES = [ 'https://www.googleapis.com/auth/devstorage.full_control']; -var STORAGE_BASE_URL = 'https://www.googleapis.com/storage/v1/b'; +var STORAGE_BASE_URL = 'https://www.googleapis.com/storage/v1/b', STORAGE_UPLOAD_BASE_URL = 'https://www.googleapis.com/upload/storage/v1/b'; var reqStreamToCallback = function(st, callback) { @@ -63,7 +65,7 @@ nodeutil.inherits(BufferStream, stream.Readable); BufferStream.prototype._read = function() { this.push(this.data); this.push(null); -} +}; /** * Read stream is a readable stream that streams the @@ -72,7 +74,6 @@ BufferStream.prototype._read = function() { * @param {String} name Name of the file to read from. */ function ReadStream(bucket, name) { - var that = this; events.EventEmitter.call(this); this.bucket = bucket; @@ -164,13 +165,15 @@ function Bucket(opts) { * are omitted. * @param {String} query.prefix Filters results to objects whose names * begin with this prefix. - * @param {Number} query.maxResults Maximum number of items plus prefixes to return. - * @param {String} query.pageToken A previously-returned page token representing part - * of the larger set of results to view. + * @param {Number} query.maxResults Maximum number of items plus prefixes + * to return. + * @param {String} query.pageToken A previously-returned page token + * representing part of the larger set of + * results to view. * @param {Function} callback Callback function. */ Bucket.prototype.list = function(query, callback) { - if (arguments.length == 1) { + if (arguments.length === 1) { callback = query; query = {}; } @@ -206,9 +209,10 @@ Bucket.prototype.stat = function(name, callback) { * @param {String?} metadata.bucket Optional destination bucket for * the file. If none is provided, * source's bucket name is used. - * @param {Function=} opt_callback Optional callback. + * @param {Function=} callback Optional callback. */ -Bucket.prototype.copy = function(name, metadata, opt_callback) { +Bucket.prototype.copy = function(name, metadata, callback) { + callback = callback || util.noop; if (!metadata.name) { throw new Error('Destination file should have a name.'); } @@ -220,9 +224,9 @@ Bucket.prototype.copy = function(name, metadata, opt_callback) { destBucket: metadata.bucket, destName: metadata.name }); - delete metadata['name']; - delete metadata['bucket']; - this.makeReq('POST', path, null, metadata, opt_callback); + delete metadata.name; + delete metadata.bucket; + this.makeReq('POST', path, null, metadata, callback); }; /** @@ -250,27 +254,29 @@ Bucket.prototype.createReadStream = function(name) { /** * Writes the provided stream to the destination * with optional metadata. - * @param {String} name Name of the remote file. + * @param {String} name Name of the remote file. * @param {Object=} opts.data A string, buffer or readable stream. * @param {string=} opts.filename Path of the source file. * @param {Object=} opts.metadata Optional metadata. - * @param {Function} callback Callback function. + * @param {Function} callback Callback function. */ Bucket.prototype.write = function(name, opts, callback) { + callback = callback || util.noop; // TODO(jbd): Support metadata only requests. var that = this; var metadata = opts.metadata || {}; var stream = opts.data; + var isStringOrBuffer = typeof stream === 'string' || stream instanceof Buffer; if (opts.filename) { stream = fs.createReadStream(opts.filename); - } else if (opts.data && (typeof opts.data === 'string' || opts.data instanceof Buffer)) { - stream = new BufferStream(opts.data); + } else if (stream && isStringOrBuffer) { + stream = new BufferStream(stream); } var boundary = uuid.v4(); - metadata.contentType = metadata.contentType || 'text/plain' + metadata.contentType = metadata.contentType || 'text/plain'; this.conn.createAuthorizedReq({ method: 'POST', uri: util.format('{base}/{bucket}/o', { @@ -283,7 +289,7 @@ Bucket.prototype.write = function(name, opts, callback) { } }, function(err, req) { if (err) { - callback && callback(err); + callback(err); return; } var remoteStream = that.conn.requester(req), diff --git a/package.json b/package.json index 04ee6cf2ad4..3dd453771db 100644 --- a/package.json +++ b/package.json @@ -10,10 +10,7 @@ } ], "main": "./lib/index", - "repository": { - "type": "git", - "url": "https://github.com/googlecloudplatform/gcloud-nodejs.git" - }, + "repository": "googlecloudplatform/gcloud-nodejs", "keywords": [ "google", "api", @@ -25,20 +22,21 @@ "google storage" ], "dependencies": { - "gapitoken": "*", - "async": "*", - "request": "*", - "node-uuid": "*" + "async": "^0.9.0", + "gapitoken": "^0.1.3", + "node-uuid": "^1.4.1", + "request": "^2.39.0" }, "devDependencies": { - "mocha": "*", - "istanbul": "*", - "tmp": "*" + "istanbul": "^0.3.0", + "jshint": "^2.5.2", + "mocha": "^1.21.3", + "tmp": "0.0.24" }, "scripts": { - "test": "node_modules/mocha/bin/_mocha --reporter spec", - "regression-test": "node_modules/mocha/bin/_mocha --reporter spec --timeout 10000 regression/*", - "cover": "node_modules/istanbul/lib/cli.js cover node_modules/mocha/bin/_mocha -- --timeout 10000 test/* regression/*" + "test": "jshint lib/**/*.js test/*.js && mocha --reporter spec", + "regression-test": "mocha --reporter spec --timeout 10000 regression/*", + "cover": "istanbul cover mocha -- --timeout 10000 test/* regression/*" }, "license": "Apache 2" } diff --git a/regression/datastore.js b/regression/datastore.js index 8173e60d9b9..13d5bef1b90 100644 --- a/regression/datastore.js +++ b/regression/datastore.js @@ -14,6 +14,10 @@ * limitations under the License. */ +/*global describe, it, after, before */ + +'use strict'; + var env = require('./env.js'); var assert = require('assert'), @@ -22,28 +26,28 @@ var assert = require('assert'), describe('datastore', function() { - describe('create, retrieve and delete using the datastore service', function() { + describe('create, retrieve and delete', function() { + var post = { + title: 'How to make the perfect pizza in your grill', + tags: ['pizza', 'grill'], + publishedAt: Date('2001-01-01T00:00:00.000Z'), + author: 'Silvano', + isDraft: false, + wordCount: 400, + rating: 5.0, + }; it('should save/get/delete with a key name', function(done) { - var post = { - title: "How to make the perfect pizza in your grill", - tags: ['pizza', 'grill'], - publishedAt: Date("2001-01-01T00:00:00.000Z"), - author: "Silvano", - isDraft: false, - wordCount: 400, - rating: 5.0, - }; var postKeyName = 'post1'; ds.save({ key: ['Post', postKeyName], data: post }, function(err, key) { - if (err) return done(err); + assert.ifError(err); assert.equal(key[1], postKeyName); ds.get(['Post', postKeyName], function(err, entity) { - if (err) return done(err); + assert.ifError(err); assert.deepEqual(entity.data, post); ds.delete(['Post', postKeyName], function(err) { - if (err) return done(err); + assert.ifError(err); done(); }); }); @@ -51,50 +55,32 @@ describe('datastore', function() { }); it('should save/get/delete with a numeric key id', function(done) { - var post = { - title: "How to make the perfect pizza in your grill", - tags: ['pizza', 'grill'], - publishedAt: Date("2001-01-01T00:00:00.000Z"), - author: "Silvano", - isDraft: false, - wordCount: 400, - rating: 5.0, - }; var postKeyId = '123456789'; ds.save({ key: ['Post', postKeyId], data: post }, function(err, key) { - if (err) return done(err); + assert.ifError(err); assert.equal(key[1], postKeyId); ds.get(['Post', postKeyId], function(err, entity) { - if (err) return done(err); + assert.ifError(err); assert.deepEqual(entity.data, post); ds.delete(['Post', postKeyId], function(err) { - if (err) return done(err); + assert.ifError(err); done(); }); }); }); }); - it('should save/get/delete with an automatically generated key id', function(done) { - var post = { - title: "How to make the perfect pizza in your grill", - tags: ['pizza', 'grill'], - publishedAt: Date("2001-01-01T00:00:00.000Z"), - author: "Silvano", - isDraft: false, - wordCount: 400, - rating: 5.0, - }; + it('should save/get/delete with a generated key id', function(done) { ds.save({ key: ['Post', null], data: post }, function(err, key) { - if (err) return done(err); + assert.ifError(err); assert(key[1]); var assignedId = key[1]; ds.get(['Post', assignedId], function(err, entity) { - if (err) return done(err); + assert.ifError(err); assert.deepEqual(entity.data, post); ds.delete(['Post', assignedId], function(err) { - if (err) return done(err); + assert.ifError(err); done(); }); }); @@ -102,42 +88,33 @@ describe('datastore', function() { }); it('should save/get/delete multiple entities at once', function(done) { - var post1 = { - title: "How to make the perfect pizza in your grill", - tags: ['pizza', 'grill'], - publishedAt: Date("2001-01-01T00:00:00.000Z"), - author: "Silvano", - isDraft: false, - wordCount: 400, - rating: 5.0, - }; var post2 = { - title: "How to make the perfect homemade pasta", + title: 'How to make the perfect homemade pasta', tags: ['pasta', 'homemade'], - publishedAt: Date("2001-01-01T00:00:00.000Z"), - author: "Silvano", + publishedAt: Date('2001-01-01T00:00:00.000Z'), + author: 'Silvano', isDraft: false, wordCount: 450, rating: 4.5, }; var key = ['Post', null]; ds.save([ - { key: key, data: post1 }, + { key: key, data: post }, { key: key, data: post2 } ], function(err, keys) { - if (err) return done(err); + assert.ifError(err); assert.equal(keys.length,2); var firstKey = ['Post', keys[0][1]], secondKey = ['Post', keys[1][1]]; ds.get([firstKey, secondKey], function(err, entities) { - if (err) return done(err); + assert.ifError(err); assert.equal(entities.length, 2); ds.delete([firstKey, secondKey], function(err) { - if (err) return done(err); + assert.ifError(err); done(); }); }); - }) + }); }); }); @@ -205,7 +182,7 @@ describe('datastore', function() { data: characters[index] }; }), function(err, keys) { - if (err) return done(err); + assert.ifError(err); done(); }); @@ -214,17 +191,17 @@ describe('datastore', function() { it('should limit queries', function(done) { var q = ds.createQuery('Character').limit(5); ds.runQuery(q, function(err, firstEntities, secondQuery) { - if (err) return done(err); + assert.ifError(err); assert.equal(firstEntities.length, 5); assert(secondQuery); ds.runQuery(secondQuery, function(err, secondEntities, thirdQuery) { - if (err) return done(err); + assert.ifError(err); assert.equal(secondEntities.length, 3); - // TODO(silvano): it currently requires an additional request that brings - // an empty page and a null query + // TODO(silvano): it currently requires an additional request that + // brings an empty page and a null query //assert.equal(thirdQuery, null) ds.runQuery(thirdQuery, function(err, thirdEntities, fourthQuery) { - if (err) return done(err); + assert.ifError(err); assert.equal(fourthQuery, null); done(); }); @@ -235,8 +212,8 @@ describe('datastore', function() { it('should filter queries with simple indexes', function(done) { var q = ds.createQuery('Character') .filter('appearances >=', 20); - ds.runQuery(q, function(err, entities, nextQuery) { - if (err) return done(err); + ds.runQuery(q, function(err, entities) { + assert.ifError(err); assert.equal(entities.length, 6); done(); }); @@ -246,8 +223,8 @@ describe('datastore', function() { var q = ds.createQuery('Character') .filter('family =', 'Stark') .filter('appearances >=', 20); - ds.runQuery(q, function(err, entities, nextQuery) { - if (err) return done(err); + ds.runQuery(q, function(err, entities) { + assert.ifError(err); assert.equal(entities.length, 6); done(); }); @@ -255,8 +232,8 @@ describe('datastore', function() { it('should filter by ancestor', function(done) { var q = ds.createQuery('Character').hasAncestor(['Character', 'Eddard']); - ds.runQuery(q, function(err, entities, nextQuery) { - if (err) return done(err); + ds.runQuery(q, function(err, entities) { + assert.ifError(err); assert.equal(entities.length, 5); done(); }); @@ -265,8 +242,8 @@ describe('datastore', function() { it('should filter by key', function(done) { var q = ds.createQuery('Character') .filter('__key__ =', ['Character', 'Rickard']); - ds.runQuery(q, function(err, entities, nextQuery) { - if (err) return done(err); + ds.runQuery(q, function(err, entities) { + assert.ifError(err); assert.equal(entities.length, 1); done(); }); @@ -274,8 +251,8 @@ describe('datastore', function() { it('should order queries', function(done) { var q = ds.createQuery('Character').order('+appearances'); - ds.runQuery(q, function(err, entities, nextQuery) { - if (err) return done(err); + ds.runQuery(q, function(err, entities) { + assert.ifError(err); assert.equal(entities[0].data.name, characters[0].name); assert.equal(entities[7].data.name, characters[3].name); done(); @@ -285,8 +262,8 @@ describe('datastore', function() { it('should select projections', function(done) { var q = ds.createQuery('Character') .select(['name', 'family']); - ds.runQuery(q, function(err, entities, nextQuery) { - if (err) return done(err); + ds.runQuery(q, function(err, entities) { + assert.ifError(err); assert.deepEqual(entities[0].data, { name: 'Arya', family: 'Stark' @@ -305,11 +282,11 @@ describe('datastore', function() { .limit(3) .order('+appearances'); ds.runQuery(q, function(err, entities, secondQuery) { - if (err) return done(err); + assert.ifError(err); assert.equal(entities.length, 3); assert.equal(entities[0].data.name, 'Robb'); assert.equal(entities[2].data.name, 'Catelyn'); - ds.runQuery(secondQuery, function(err, secondEntities, thirdQuery) { + ds.runQuery(secondQuery, function(err, secondEntities) { assert.equal(secondEntities.length, 3); assert.equal(secondEntities[0].data.name, 'Sansa'); assert.equal(secondEntities[2].data.name, 'Arya'); @@ -324,13 +301,13 @@ describe('datastore', function() { .limit(2) .order('+appearances'); ds.runQuery(q, function(err, entities, nextQuery) { - if (err) return done(err); + assert.ifError(err); var startCursor = nextQuery.startVal; var cursorQuery = ds.createQuery('Character') .order('+appearances') .start(startCursor); - ds.runQuery(cursorQuery, function(err, secondEntities, nextQuery) { - if (err) return done(err); + ds.runQuery(cursorQuery, function(err, secondEntities) { + assert.ifError(err); assert.equal(secondEntities.length, 4); assert.equal(secondEntities[0].data.name, 'Catelyn'); assert.equal(secondEntities[3].data.name, 'Arya'); @@ -342,17 +319,17 @@ describe('datastore', function() { it('should group queries', function(done) { var q = ds.createQuery('Character') .groupBy('alive'); - ds.runQuery(q, function(err, entities, nextQuery) { - if (err) return done(err); + ds.runQuery(q, function(err, entities) { + assert.ifError(err); assert.equal(entities.length, 2); done(); }); - }) + }); after(function(done) { ds.delete(keys, function(err) { - if (err) return done(err); + assert.ifError(err); done(); }); @@ -369,27 +346,27 @@ describe('datastore', function() { }; ds.runInTransaction(function(t, tDone) { ds.get(key, function(err, entity) { - if (err) return done(err); + assert.ifError(err); if (entity) { tDone(); return; } else { ds.save({ key: key, data: obj }, function(err, keyRes) { - if (err) console.log(err); + assert.ifError(err); tDone(); return; }); } }); }, function(err) { - if (err) throw (err); + assert.ifError(err); ds.get(key, function(err, entity) { - if (err) return done(err); + assert.ifError(err); assert.deepEqual(entity.data, obj); ds.delete(entity.key, function(err) { - if (err) return done(err); + assert.ifError(err); done(); - }) + }); }); }); }); diff --git a/regression/env.js b/regression/env.js index afc024952cb..f6b75f5ace9 100644 --- a/regression/env.js +++ b/regression/env.js @@ -14,11 +14,14 @@ * limitations under the License. */ +'use strict'; + if (!process.env.GCLOUD_TESTS_PROJECT_ID && !process.env.GCLOUD_TESTS_BUCKET_NAME && !process.env.GCLOUD_TESTS_KEY) { - var error = ['To run the regression tests, you need to set the value of some environment variables.', - 'Please check the README for instructions.' + var error = [ + 'To run the regression tests, you need to set some environment variables.', + 'Please check the Contributing guide for instructions.' ].join('\n'); throw error; } diff --git a/regression/pubsub.js b/regression/pubsub.js index add137e583f..e2e12c5a8a7 100644 --- a/regression/pubsub.js +++ b/regression/pubsub.js @@ -14,6 +14,10 @@ * limitations under the License. */ +/*global describe, it, before */ + +'use strict'; + var assert = require('assert'), async = require('async'); @@ -37,17 +41,17 @@ before(function(done) { conn.createTopic(name, callback); }; conn.listTopics(function(err, topics) { - if (err) { return done(err); } + assert.ifError(err); var fns = topics.map(function(t) { return function(cb) { t.del(cb); }; }); async.parallel(fns, function(err) { - if (err) { return done(err); } + assert.ifError(err); async.map(topicNames, createFn, done); }); - }) + }); }); describe('Topic', function() { @@ -66,7 +70,7 @@ describe('Topic', function() { assert(!!next.pageToken, true); done(err); }); - }) + }); it('should be created', function(done) { conn.createTopic('topic-new', done); @@ -101,21 +105,17 @@ describe('Subscription', function() { }, callback); }; conn.listSubscriptions(function(err, subs) { - if (err) { - done(err); return; - } + assert.ifError(err); var fns = subs.map(function(sub) { return function(cb) { sub.del(cb); }; }); async.series(fns, function(err) { - if (err) { - done(err); return; - } + assert.ifError(err); async.map(subscriptions, createFn, done); }); - }) + }); }); it('should be listed', function(done) { @@ -127,16 +127,14 @@ describe('Subscription', function() { it('should be gettable', function(done) { conn.getSubscription('sub1', function(err, sub) { - if (err) { - done(err); return; - } + assert.ifError(err); assert.strictEqual(sub.name, '/subscriptions/' + env.projectId + '/sub1'); done(); }); }); it('should error while getting a non-existent subscription', function(done){ - conn.getSubscription('sub-nothing-is-here', function(err, sub) { + conn.getSubscription('sub-nothing-is-here', function(err) { assert.strictEqual(err.code, 404); done(); }); @@ -151,17 +149,13 @@ describe('Subscription', function() { it('should be able to pull and ack', function(done) { conn.getTopic('topic1', function(err, topic) { - if (err) { - done(err); return; - } + assert.ifError(err); topic.publish('hello', function(err) { - if(err) done(err); return; + assert.ifError(err); }); }); conn.getSubscription('sub1', function(err, sub) { - if (err) { - done(err); return; - } + assert.ifError(err); sub.on('message', function(msg) { sub.ack(msg.ackId, done); }); diff --git a/test/common.connection.js b/test/common.connection.js index ceaf44cc0eb..43578d57641 100644 --- a/test/common.connection.js +++ b/test/common.connection.js @@ -14,6 +14,10 @@ * limitations under the License. */ +/*global describe, it */ + +'use strict'; + var assert = require('assert'), async = require('async'), conn = require('../lib/common/connection.js'); @@ -29,7 +33,7 @@ describe('Connection', function() { scopes: ['scope1', 'scope2'] }); c.token = tokenExpired; - c.fetchToken = function(cb) { + c.fetchToken = function() { done(); }; c.requester = function(opts, callback) { @@ -38,7 +42,7 @@ describe('Connection', function() { c.req({ uri: 'https://someuri' }, function(){}); }); - it('should be able to make other requests wait while connecting', function(done) { + it('should make other requests wait while connecting', function(done) { var numTokenFetches = 0; var c = new conn.Connection({ email: 'x@provider', @@ -74,7 +78,7 @@ describe('Connection', function() { scopes: ['scope1', 'scope2'] }); c.token = new conn.Token(); - c.fetchToken = function(cb) { + c.fetchToken = function() { done(); }; c.requester = function(opts, callback) { @@ -83,4 +87,4 @@ describe('Connection', function() { c.req({ uri: 'https://someuri' }, function(){}); }); -}); \ No newline at end of file +}); diff --git a/test/common.util.js b/test/common.util.js index 73af4c68b7e..ff07ff76d09 100644 --- a/test/common.util.js +++ b/test/common.util.js @@ -14,6 +14,10 @@ * limitations under the License. */ +/*global describe, it */ + +'use strict'; + var util = require('../lib/common/util.js'), assert = require('assert'); @@ -49,7 +53,7 @@ describe('handleResp', function() { errors: [{ foo: 'bar' }], code: 400, message: 'an error occurred' - } + }; util.handleResp(null, {}, { error: apiErr }, function(err) { assert.deepEqual(err.errors, apiErr.errors); assert.strictEqual(err.code, apiErr.code); @@ -66,7 +70,7 @@ describe('handleResp', function() { }); }); - it('should return status code as an error if there are not other errors', function(done) { + it('should return error code if there are not other errors', function(done) { util.handleResp(null, { statusCode: 400 }, null, function(err) { assert.strictEqual(err.message, 'error during request, statusCode: 400'); done(); diff --git a/test/datastore.entity.js b/test/datastore.entity.js index 6986cb83e2d..6444b82cf2d 100644 --- a/test/datastore.entity.js +++ b/test/datastore.entity.js @@ -14,6 +14,10 @@ * limitations under the License. */ +/*global describe, it */ + +'use strict'; + var assert = require('assert'), entity = require('../lib/datastore/entity.js'), datastore = require('../lib/datastore'); @@ -24,7 +28,87 @@ var blogPostMetadata = { publishedAt: { kind: Date }, author: { kind: Object, indexed: true }, isDraft: { kind: Boolean, indexed: true } -} +}; + +var keyProto = { + partitionId: { + datasetId: 's~bamboo-shift-xxx', + namespace: '' + }, + path: [ + { + kind: 'Kind', + id: '4790047639339008' + } + ] +}; + +var entityProto = { + properties: { + createdAt: { + dateTimeValue: '2001-01-01T00:00:00.000Z' + }, + linkedTo: { + keyValue: keyProto + }, + name: { + stringValue: 'Name' + }, + flagged: { + booleanValue: true + }, + count: { + integerValue: '5' + }, + total: { + doubleValue: '5.42' + }, + author: { + entityValue: { + properties: { + name: { stringValue: 'Burcu Dogan' } + } + } + }, + list: { + listValue: [{ integerValue: '6' }, { booleanValue: false }] + } + } +}; + +var queryFilterProto = { + projection: [], + kinds: [{ + name: 'Kind1' + }], + filter: { + compositeFilter: { + filters: [ + { + propertyFilter: { + property: { name: 'name' }, + operator: 'EQUAL', + value: { stringValue: 'John' } + } + }, + { + propertyFilter: { + property: { name: '__key__' }, + operator: 'HAS_ANCESTOR', + value: { + keyValue: { + path: [{ kind: 'Kind2', name: 'somename' }] + } + } + } + } + ], + operator: 'AND' + } + }, + order: [], + groupBy: [] +}; describe('registerKind', function() { it('should be able to register valid field metadata', function(done) { @@ -32,14 +116,14 @@ describe('registerKind', function() { done(); }); - it('should set the namespace to be "" if zero value or null is provided', function(done) { + it('should set the namespace to "" if zero value or null', function(done) { entity.registerKind(null, 'kind', blogPostMetadata); var meta = entity.getKind('', 'kind'); assert.strictEqual(meta, blogPostMetadata); done(); }); - it('should throw an exception if an invalid kind is provided', function(done) { + it('should throw an exception if an invalid kind', function(done) { assert.throws(function() { entity.registerKind(null, '000', blogPostMetadata); }, /Kinds should match/); @@ -113,7 +197,7 @@ describe('keyToKeyProto', function() { done(); }); - it('should handle incomplete keys with and without namespaces', function(done) { + it('should handle incomplete keys with & without namespaces', function(done) { var key = ['Kind1', null]; var keyWithNS = ['Namespace', 'Kind1', null]; @@ -144,11 +228,16 @@ describe('keyToKeyProto', function() { describe('isKeyComplete', function() { - it('should return true if kind and one of the identifiers have non-zero values', function(done) { - assert.strictEqual(entity.isKeyComplete(['Kind1', null]), false); - assert.strictEqual(entity.isKeyComplete(['Kind1', 3]), true); - assert.strictEqual(entity.isKeyComplete(['Namespace', 'Kind1', null]), false); - assert.strictEqual(entity.isKeyComplete(['Namespace', 'Kind1', 'name']), true); + it('should return true if kind and an identifier have non-zero values', + function(done) { + [ + { key: ['Kind1', null], expected: false }, + { key: ['Kind1', 3], expected: true }, + { key: ['Namespace', 'Kind1', null], expected: false }, + { key: ['Namespace', 'Kind1', 'name'], expected: true } + ].forEach(function(test) { + assert.strictEqual(entity.isKeyComplete(test.key), test.expected); + }); done(); }); @@ -156,9 +245,11 @@ describe('isKeyComplete', function() { describe('entityFromEntityProto', function() { - it('should support boolean, integer, double, string, entity and list values', function(done) { + it('should support boolean, integer, double, string, entity and list values', + function(done) { var obj = entity.entityFromEntityProto(entityProto); - assert.strictEqual(obj.createdAt.getTime(), new Date('2001-01-01').getTime()); + assert.strictEqual(obj.createdAt.getTime(), + new Date('2001-01-01').getTime()); assert.strictEqual(obj.linkedTo.ns, undefined); assert.strictEqual(obj.linkedTo[0], 'Kind'); assert.strictEqual(obj.linkedTo[1], 4790047639339008); @@ -176,7 +267,8 @@ describe('entityFromEntityProto', function() { describe('entityToEntityProto', function() { - it('should support boolean, integer, double, string, entity and list values', function(done) { + it('should support boolean, integer, double, string, entity and list values', + function(done) { var now = new Date(); var proto = entity.entityToEntityProto({ name: 'Burcu', @@ -185,24 +277,27 @@ describe('entityToEntityProto', function() { primitiveCount: 6, legit: true, date : now, - bytes: new Buffer("Hello"), + bytes: new Buffer('Hello'), list: ['a', new entity.Double(54.7)], metadata: { key1: 'value1', key2: 'value2' } }); - assert.equal(proto.properties.name.stringValue, 'Burcu'); - assert.equal(proto.properties.desc.stringValue, 'Description'); - assert.equal(proto.properties.count.integerValue, 6); - assert.equal(proto.properties.primitiveCount.integerValue, 6); - assert.equal(proto.properties.legit.booleanValue, true); - assert.equal(proto.properties.date.dateTimeValue, now); - assert.equal(proto.properties.bytes.blobValue, 'SGVsbG8='); - assert.equal(proto.properties.list.listValue[0].stringValue, 'a'); - assert.equal(proto.properties.list.listValue[1].doubleValue, 54.7); - assert.equal(proto.properties.metadata.entityValue.properties.key1.stringValue, 'value1'); - assert.equal(proto.properties.metadata.entityValue.properties.key2.stringValue, 'value2'); + var properties = proto.properties; + assert.equal(properties.name.stringValue, 'Burcu'); + assert.equal(properties.desc.stringValue, 'Description'); + assert.equal(properties.count.integerValue, 6); + assert.equal(properties.primitiveCount.integerValue, 6); + assert.equal(properties.legit.booleanValue, true); + assert.equal(properties.date.dateTimeValue, now); + assert.equal(properties.bytes.blobValue, 'SGVsbG8='); + assert.equal(properties.list.listValue[0].stringValue, 'a'); + assert.equal(properties.list.listValue[1].doubleValue, 54.7); + assert.equal(properties.metadata.entityValue.properties.key1.stringValue, + 'value1'); + assert.equal(properties.metadata.entityValue.properties.key2.stringValue, + 'value2'); done(); }); @@ -221,89 +316,3 @@ describe('queryToQueryProto', function() { }); }); - -var keyProto = { - "partitionId":{ - "datasetId":"s~bamboo-shift-xxx", - "namespace":"" - }, - "path":[ - { - "kind":"Kind", - "id":"4790047639339008" - } - ] -}; - -var entityProto = { - "properties":{ - "createdAt":{ - "dateTimeValue":"2001-01-01T00:00:00.000Z" - }, - "linkedTo": { - "keyValue": keyProto - }, - "name":{ - "stringValue":"Name" - }, - "flagged":{ - "booleanValue":true - }, - "count":{ - "integerValue":"5" - }, - "total":{ - "doubleValue": "5.42" - }, - "author": { - "entityValue": { - "properties": { - "name": { "stringValue": "Burcu Dogan" } - } - } - }, - "list": { - "listValue": [{ "integerValue": "6" }, { "booleanValue": false }] - } - } -}; - -var queryFilterProto = { - "projection": [], - "kinds": [{ - "name": "Kind1" - }], - "filter": { - "compositeFilter": { - "filters": [{ - "propertyFilter": { - "property": { - "name": "name" - }, - "operator": "EQUAL", - "value": { - "stringValue": "John" - } - } - }, { - "propertyFilter": { - "property": { - "name": "__key__" - }, - "operator": "HAS_ANCESTOR", - "value": { - "keyValue": { - "path": [{ - "kind": "Kind2", - "name": "somename" - }] - } - } - } - }], - "operator": "AND" - } - }, - "order": [], - "groupBy": [] -}; diff --git a/test/datastore.js b/test/datastore.js index 798e1134a8c..45eeac380bd 100644 --- a/test/datastore.js +++ b/test/datastore.js @@ -14,9 +14,13 @@ * limitations under the License. */ +/*global describe, it, beforeEach */ + +'use strict'; + var assert = require('assert'), datastore = require('../lib').datastore, - mockResp_get = require('./testdata/response_get.json'); + mockRespGet = require('./testdata/response_get.json'); describe('Transaction', function() { @@ -61,7 +65,7 @@ describe('Transaction', function() { it('should be committed if not rolled back', function(done) { var t = new datastore.Transaction(null, 'test'); t.isFinalized = false; - t.makeReq = function(method, proto, callback) { + t.makeReq = function(method) { assert.equal(method, 'commit'); done(); }; @@ -87,7 +91,7 @@ describe('Dataset', function() { ds.transaction.makeReq = function(method, proto, callback) { assert.equal(method, 'lookup'); assert.equal(proto.keys.length, 1); - callback(null, mockResp_get); + callback(null, mockRespGet); }; ds.get(['Kind', 123], function(err, entity) { var properties = entity.data; @@ -106,7 +110,7 @@ describe('Dataset', function() { ds.transaction.makeReq = function(method, proto, callback) { assert.equal(method, 'lookup'); assert.equal(proto.keys.length, 1); - callback(null, mockResp_get); + callback(null, mockRespGet); }; ds.get([ ['Kind', 123] @@ -180,7 +184,14 @@ describe('Dataset', function() { }, path :[{kind:'Kind'}] }); - callback(null, { keys: [{ partitionId: { datasetId: 's~test', namespace: '' }, path :[{kind:'Kind', id: '123'}]}]}); + callback(null, { + keys: [ + { + partitionId: { datasetId: 's~test', namespace: '' }, + path: [{ kind: 'Kind', id: '123' }] + } + ] + }); }; ds.allocateIds(['Kind', null], 1, function(err, ids) { assert.deepEqual(ids[0], ['Kind', 123]); @@ -200,12 +211,12 @@ describe('Dataset', function() { var query; var mockResponse = { withResults: { - batch: { entityResults: mockResp_get.found } + batch: { entityResults: mockRespGet.found } }, withResultsAndEndCursor: { - batch: { entityResults: mockResp_get.found, endCursor: 'cursor' } + batch: { entityResults: mockRespGet.found, endCursor: 'cursor' } }, - withoutResults: mockResp_get + withoutResults: mockRespGet }; beforeEach(function () { diff --git a/test/datastore.query.js b/test/datastore.query.js index 5cb11c19843..16eed3e4499 100644 --- a/test/datastore.query.js +++ b/test/datastore.query.js @@ -14,6 +14,10 @@ * limitations under the License. */ +/*global describe, it */ + +'use strict'; + var assert = require('assert'), datastore = require('../lib/datastore'), entity = require('../lib/datastore/entity.js'), @@ -94,7 +98,7 @@ describe('Query', function() { it('should throw error is invalid sort sign is provided', function(done) { assert.throws(function() { - var q = ds.createQuery(['kind1']).order('*name'); + ds.createQuery(['kind1']).order('*name'); }, /Invalid order pattern/); done(); }); @@ -130,4 +134,4 @@ describe('Query', function() { done(); }); -}); \ No newline at end of file +}); diff --git a/test/pubsub.js b/test/pubsub.js index e397582eb9e..32f421e5e88 100644 --- a/test/pubsub.js +++ b/test/pubsub.js @@ -14,6 +14,10 @@ * limitations under the License. */ +/*global describe, it */ + +'use strict'; + var assert = require('assert'), pubsub = require('../lib/pubsub'); @@ -23,7 +27,7 @@ describe('Subscription', function() { var sub = new pubsub.Subscription({}, 'sub1'); sub.autoAck = true; sub.conn.makeReq = function(method, path, qs, body, callback) { - if (path == 'subscriptions/pull') { + if (path === 'subscriptions/pull') { callback(null, { ackId: 'ackd-id' }); return; } @@ -94,4 +98,4 @@ describe('Subscription', function() { }); }); -}); \ No newline at end of file +}); diff --git a/test/storage.js b/test/storage.js index 8115237403e..2e98f37a5e0 100644 --- a/test/storage.js +++ b/test/storage.js @@ -14,6 +14,10 @@ * limitations under the License. */ +/*global describe, it */ + +'use strict'; + var assert = require('assert'), storage = require('../lib').storage; @@ -30,12 +34,12 @@ function createBucket() { describe('Bucket', function() { it('should throw if a bucket name is not passed', function() { - assert.throws(function() { var bucket = new storage.Bucket(); }, Error); - }) + assert.throws(function() { new storage.Bucket(); }, Error); + }); it('should list without a query', function(done) { var bucket = createBucket(); - bucket.makeReq = function(method, path, q, body, callback) { + bucket.makeReq = function(method, path, q, body) { assert.strictEqual(method, 'GET'); assert.strictEqual(path, 'o'); assert.deepEqual(q, {}); @@ -47,7 +51,7 @@ describe('Bucket', function() { it('should list with a query', function(done) { var bucket = createBucket(); - bucket.makeReq = function(method, path, q, body, callback) { + bucket.makeReq = function(method, path, q, body) { assert.strictEqual(method, 'GET'); assert.strictEqual(path, 'o'); assert.deepEqual(q, { maxResults: 5, pageToken: 'token' }); @@ -60,7 +64,7 @@ describe('Bucket', function() { it('should return nextQuery if more results', function() { var bucket = createBucket(); bucket.makeReq = function(method, path, q, body, callback) { - callback(null, { nextPageToken: 'next-page-token', items: [] }) + callback(null, { nextPageToken: 'next-page-token', items: [] }); }; bucket.list({ maxResults: 5}, function(err, results, nextQuery) { assert.strictEqual(nextQuery.pageToken, 'next-page-token'); @@ -71,7 +75,7 @@ describe('Bucket', function() { it('should return no nextQuery if no more results', function() { var bucket = createBucket(); bucket.makeReq = function(method, path, q, body, callback) { - callback(null, { items: [] }) + callback(null, { items: [] }); }; bucket.list({ maxResults: 5}, function(err, results, nextQuery) { assert.strictEqual(nextQuery, null); @@ -80,7 +84,7 @@ describe('Bucket', function() { it('should stat a file', function(done) { var bucket = createBucket(); - bucket.makeReq = function(method, path, q, body, callback) { + bucket.makeReq = function(method, path, q, body) { assert.strictEqual(method, 'GET'); assert.strictEqual(path, 'o/file-name'); assert.strictEqual(q, null); @@ -92,7 +96,7 @@ describe('Bucket', function() { it('should copy a file', function(done) { var bucket = createBucket(); - bucket.makeReq = function(method, path, q, body, callback) { + bucket.makeReq = function(method, path, q, body) { assert.strictEqual(method, 'POST'); assert.strictEqual(path, 'o/file-name/copyTo/b/new-bucket/o/new-name'); assert.strictEqual(q, null); @@ -105,7 +109,7 @@ describe('Bucket', function() { it('should use the same bucket if nothing else is provided', function(done) { var bucket = createBucket(); - bucket.makeReq = function(method, path, q, body, callback) { + bucket.makeReq = function(method, path, q, body) { assert.strictEqual(method, 'POST'); assert.strictEqual(path, 'o/file-name/copyTo/b/bucket-name/o/new-name'); assert.strictEqual(q, null); @@ -118,7 +122,7 @@ describe('Bucket', function() { it('should remove a file', function(done) { var bucket = createBucket(); - bucket.makeReq = function(method, path, q, body, callback) { + bucket.makeReq = function(method, path, q, body) { assert.strictEqual(method, 'DELETE'); assert.strictEqual(path, 'o/file-name'); assert.strictEqual(q, null); @@ -128,4 +132,4 @@ describe('Bucket', function() { bucket.remove('file-name'); }); -}); \ No newline at end of file +});