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..bbd5958ecf8 100644 --- a/lib/common/connection.js +++ b/lib/common/connection.js @@ -14,13 +14,19 @@ * limitations under the License. */ -var GAPIToken = require('gapitoken'), - async = require('async'), - req = require('request'), - pkg = require('../../package.json'); +/*jshint camelcase:false */ -var USER_AGENT = 'gcloud-node/' + pkg.version, - METADATA_TOKEN_URL = 'http://metadata/computeMetadata/v1/instance/service-accounts/default/token'; +'use strict'; + +var GAPIToken = require('gapitoken'); +var req = require('request'); +var pkg = require('../../package.json'); +var util = require('./util'); + +var METADATA_TOKEN_URL = + 'http://metadata/computeMetadata/v1/instance/service-accounts/default/' + + 'token'; +var USER_AGENT = 'gcloud-node/' + pkg.version; /** * Token represents an access token @@ -48,8 +54,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 +92,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 +120,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,41 +134,52 @@ 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 || {}; - reqOpts.headers['User-Agent'] = reqOpts.headers['User-Agent'] ? - reqOpts.headers['User-Agent'] + '; ' + USER_AGENT : USER_AGENT; + + if (reqOpts.headers['User-Agent']) { + reqOpts.headers['User-Agent'] += '; ' + USER_AGENT; + } else { + reqOpts.headers['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 +207,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..11a71d82b1e 100644 --- a/lib/datastore/entity.js +++ b/lib/datastore/entity.js @@ -14,9 +14,12 @@ * limitations under the License. */ -var entityMeta = {}; +'use strict'; -var namespaceRegex = kindRegex = fieldNameRegex = new RegExp(/^[A-Za-z]*$/); +var entityMeta = {}; +var fieldNameRegex = /^[A-Za-z]*$/; +var kindRegex = /^[A-Za-z]*$/; +var namespaceRegex = /^[A-Za-z]*$/; /** * Conversion dict for query operation to operation proto value. @@ -46,7 +49,7 @@ function Int(val) { Int.prototype.get = function() { return this.val; -} +}; module.exports.Int = Int; @@ -56,10 +59,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,21 +93,26 @@ 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) { + var namespace = null; + var start = 0; + if (key.length % 2 === 1) { // the first item is the namespace namespace = key[0]; start = 1; } var path = []; for (var i = start; i < (key.length - start); i += 2) { - var p = { kind: key[i] }, val = key[i+1]; + var p = { kind: key[i] }; + var val = key[i+1]; if (val) { // if not numeric, set key name. - if (isNaN(val)) { p.name = val; } - else { p.id = val; } + if (isNaN(val)) { + p.name = val; + } else { + p.id = val; + } } path.push(p); } @@ -111,7 +133,7 @@ var keyToKeyProto = function(datasetId, key) { module.exports.keyToKeyProto = keyToKeyProto; module.exports.formatArray = function(results) { - return results.map(function (result) { + return results.map(function(result) { return { key: keyFromKeyProto(result.entity.key), data: entityFromEntityProto(result.entity) @@ -159,7 +181,7 @@ function propertyToValue(property) { } return l; } -}; +} function propertiesToObject(properties) { properties = properties || []; @@ -168,21 +190,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 +245,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 +393,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 +414,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..f88d7b2f273 100644 --- a/lib/datastore/index.js +++ b/lib/datastore/index.js @@ -14,17 +14,21 @@ * limitations under the License. */ -var conn = require('../common/connection.js'), - entity = require('./entity.js'), - Query = require('./query.js').Query, - util = require('../common/util.js'); +'use strict'; -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'], - MODE_NON_TRANSACTIONAL = 'NON_TRANSACTIONAL', - MODE_TRANSACTIONAL = 'TRANSACTIONAL'; +var conn = require('../common/connection.js'); +var entity = require('./entity.js'); +var Query = require('./query.js').Query; +var util = require('../common/util.js'); + +var DATASTORE_BASE_URL = + 'https://www.googleapis.com/datastore/v1beta2/datasets'; +var MODE_NON_TRANSACTIONAL = 'NON_TRANSACTIONAL'; +var MODE_TRANSACTIONAL = 'TRANSACTIONAL'; +var SCOPES = [ + 'https://www.googleapis.com/auth/datastore', + 'https://www.googleapis.com/auth/userinfo.email' +]; /** * Transaction represents a Datastore transaction. @@ -43,12 +47,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 +62,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 +78,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 +151,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 +205,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 +222,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) { + 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 +264,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 +322,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 +332,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..0743bc6ede3 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) { @@ -36,8 +38,8 @@ Query.prototype.filter = function(filter, value) { // TODO(jbd): Add filter validation. var q = util.extend(this, new Query()); filter = filter.trim(); - var fieldName = filter.replace(/[>|<|=|>=|<=]*$/, '').trim(), - op = filter.substr(fieldName.length, filter.length).trim(); + var fieldName = filter.replace(/[>|<|=|>=|<=]*$/, '').trim(); + var op = filter.substr(fieldName.length, filter.length).trim(); q.filters = q.filters || []; q.filters.push({ name: fieldName, op: op, val: value }); return q; @@ -51,10 +53,11 @@ Query.prototype.hasAncestor = function(key) { 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".') + var sign = order[0]; + var fieldName = order.substr(1); + 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..21b15280549 100644 --- a/lib/index.js +++ b/lib/index.js @@ -14,8 +14,10 @@ * limitations under the License. */ -var datastore = require('./datastore'), - entity = require('./datastore/entity.js'); +'use strict'; + +var datastore = require('./datastore'); +var entity = require('./datastore/entity.js'); datastore.Int = function(val) { return new entity.Int(val); @@ -27,6 +29,6 @@ datastore.Double = function(val) { module.exports = { datastore: datastore, - storage: require('./storage'), - pubsub: require('./pubsub') + storage: require('./storage'), + pubsub: require('./pubsub') }; diff --git a/lib/pubsub/index.js b/lib/pubsub/index.js index 504876d9486..2df6d23329f 100644 --- a/lib/pubsub/index.js +++ b/lib/pubsub/index.js @@ -14,17 +14,20 @@ * limitations under the License. */ -var events = require('events'), - nodeutil = require('util'); +'use strict'; -var conn = require('../common/connection.js'), - util = require('../common/util.js'); +var events = require('events'); +var nodeutil = require('util'); + +var conn = require('../common/connection.js'); +var util = require('../common/util.js'); /** * Base URL for Pub/Sub API. * @type {String} */ var PUBSUB_BASE_URL = 'https://www.googleapis.com/pubsub/v1beta1'; + /** * Required scopes for Pub/Sub API. * @type {Array} @@ -35,7 +38,6 @@ var SCOPES = [ ]; function Subscription(conn, name) { - var that = this; this.conn = conn; this.name = name; @@ -62,9 +64,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 +78,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 +121,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 +181,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 +247,14 @@ 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,12 +363,12 @@ 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, - fullName = this.fullTopicName_(name); + var cb = callback || util.noop; + var fullName = this.fullTopicName_(name); this.makeReq('GET', 'topics/' + fullName, null, true, function(err) { if (err) { return cb(err); @@ -367,12 +380,12 @@ 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, - fullName = this.fullTopicName_(name); + var cb = callback || util.noop; + var 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..5903af25e5d 100644 --- a/lib/storage/index.js +++ b/lib/storage/index.js @@ -14,23 +14,25 @@ * limitations under the License. */ -var conn = require('../common/connection.js'), - nodeutil = require('util'), - events = require('events'), - stream = require('stream'), - fs = require('fs'), - util = require('../common/util.js'), - uuid = require('node-uuid'); +'use strict'; + +var events = require('events'); +var fs = require('fs'); +var nodeutil = require('util'); +var stream = require('stream'); +var uuid = require('node-uuid'); + +var conn = require('../common/connection.js'); +var util = require('../common/util.js'); /** * Required scopes for Google Cloud Storage API. * @type {Array} */ -var SCOPES = [ - 'https://www.googleapis.com/auth/devstorage.full_control']; +var SCOPES = ['https://www.googleapis.com/auth/devstorage.full_control']; var STORAGE_BASE_URL = 'https://www.googleapis.com/storage/v1/b'; - STORAGE_UPLOAD_BASE_URL = 'https://www.googleapis.com/upload/storage/v1/b'; +var STORAGE_UPLOAD_BASE_URL = 'https://www.googleapis.com/upload/storage/v1/b'; var reqStreamToCallback = function(st, callback) { st.callback = util.noop; @@ -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,44 +254,48 @@ 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', { base: STORAGE_UPLOAD_BASE_URL, bucket: this.bucketName }), - qs: { name: name, uploadType: 'multipart' }, + qs: { + name: name, uploadType: 'multipart' + }, headers: { 'Content-Type': 'multipart/related; boundary="' + boundary + '"' } }, function(err, req) { if (err) { - callback && callback(err); + callback(err); return; } - var remoteStream = that.conn.requester(req), - oldEndFn = remoteStream.end; + var remoteStream = that.conn.requester(req); + var oldEndFn = remoteStream.end; remoteStream.end = function(data, encoding, callback) { data = data || ''; data += '\n--' + boundary + '--\n'; @@ -331,4 +339,3 @@ Bucket.prototype.makeReq = function(method, path, q, body, callback) { }; module.exports.Bucket = Bucket; - diff --git a/package.json b/package.json index 04ee6cf2ad4..3b39376371d 100644 --- a/package.json +++ b/package.json @@ -7,13 +7,22 @@ { "name": "Burcu Dogan", "email": "jbd@google.com" + }, + { + "name": "Johan Euphrosine", + "email": "proppy@google.com" + }, + { + "name": "Silvano Luciani", + "email": "silvano@google.com" + }, + { + "name": "Stephen Sawchuk", + "email": "sawchuk@gmail.com" } ], "main": "./lib/index", - "repository": { - "type": "git", - "url": "https://github.com/googlecloudplatform/gcloud-nodejs.git" - }, + "repository": "googlecloudplatform/gcloud-nodejs", "keywords": [ "google", "api", @@ -25,20 +34,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 regression/*.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..2a2212f0d92 100644 --- a/regression/datastore.js +++ b/regression/datastore.js @@ -14,36 +14,39 @@ * limitations under the License. */ +/*global describe, it, after, before */ + +'use strict'; + var env = require('./env.js'); -var assert = require('assert'), - datastore = require('../lib/datastore'), - ds = new datastore.Dataset(env); +var assert = require('assert'); +var datastore = require('../lib/datastore'); +var ds = new datastore.Dataset(env); 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 +54,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 +87,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]]; + var firstKey = ['Post', keys[0][1]]; + var 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(); }); }); - }) + }); }); }); @@ -198,33 +174,31 @@ describe('datastore', function() { }]; before(function(done) { - ds.save(keys.map(function(key, index) { return { key: key, data: characters[index] }; - }), function(err, keys) { - if (err) return done(err); + }), function(err) { + assert.ifError(err); done(); }); - }); 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(); }); @@ -233,10 +207,9 @@ 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); + var q = ds.createQuery('Character').filter('appearances >=', 20); + ds.runQuery(q, function(err, entities) { + assert.ifError(err); assert.equal(entities.length, 6); done(); }); @@ -244,10 +217,10 @@ describe('datastore', function() { it('should filter queries with defined indexes', function(done) { var q = ds.createQuery('Character') - .filter('family =', 'Stark') - .filter('appearances >=', 20); - ds.runQuery(q, function(err, entities, nextQuery) { - if (err) return done(err); + .filter('family =', 'Stark') + .filter('appearances >=', 20); + ds.runQuery(q, function(err, entities) { + assert.ifError(err); assert.equal(entities.length, 6); done(); }); @@ -255,8 +228,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 +238,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 +247,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(); @@ -283,10 +256,9 @@ 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); + var q = ds.createQuery('Character').select(['name', 'family']); + ds.runQuery(q, function(err, entities) { + assert.ifError(err); assert.deepEqual(entities[0].data, { name: 'Arya', family: 'Stark' @@ -301,15 +273,15 @@ describe('datastore', function() { it('should paginate with offset and limit', function(done) { var q = ds.createQuery('Character') - .offset(2) - .limit(3) - .order('+appearances'); + .offset(2) + .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'); @@ -320,17 +292,18 @@ describe('datastore', function() { it('should resume from a start cursor', function(done) { var q = ds.createQuery('Character') - .offset(2) - .limit(2) - .order('+appearances'); + .offset(2) + .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); + var cursorQuery = + ds.createQuery('Character') + .order('+appearances') + .start(startCursor); + 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'); @@ -340,60 +313,54 @@ 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); + var q = ds.createQuery('Character').groupBy('alive'); + 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(); }); - }); - }); describe('transactions', function() { it('should run in a transaction', function(done) { - var key = ['Company', 'Google'], - obj = { - 'url': 'www.google.com' - }; + var key = ['Company', 'Google']; + var obj = { + url: 'www.google.com' + }; 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); + ds.save({ key: key, data: obj }, function(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..503e6018b61 100644 --- a/regression/pubsub.js +++ b/regression/pubsub.js @@ -14,20 +14,27 @@ * limitations under the License. */ -var assert = require('assert'), - async = require('async'); +/*global describe, it, before */ -var env = require('./env.js'), - gcloud = require('../lib'); +'use strict'; + +var assert = require('assert'); +var async = require('async'); + +var env = require('./env.js'); +var gcloud = require('../lib'); var topicNames = ['topic1', 'topic2', 'topic3']; -var subscriptions = [{ - name: 'sub1', - ackDeadlineSeconds: 30 -}, { - name: 'sub2', - ackDeadlineSeconds: 60 -}]; +var subscriptions = [ + { + name: 'sub1', + ackDeadlineSeconds: 30 + }, + { + name: 'sub2', + ackDeadlineSeconds: 60 + } +]; var conn = new gcloud.pubsub.Connection(env); @@ -37,21 +44,20 @@ 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() { - it('should be listed', function(done) { conn.listTopics(function(err, topics) { assert(topics.length, 3); @@ -66,7 +72,7 @@ describe('Topic', function() { assert(!!next.pageToken, true); done(err); }); - }) + }); it('should be created', function(done) { conn.createTopic('topic-new', done); @@ -87,11 +93,9 @@ describe('Topic', function() { topic.del(done); }); }); - }); describe('Subscription', function() { - before(function(done) { var createFn = function(item, callback) { conn.createSubscription({ @@ -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,22 +149,17 @@ 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); }); sub.pull({}, done); }); }); - }); diff --git a/regression/storage.js b/regression/storage.js index 44800cfd29d..4a2c988c52d 100644 --- a/regression/storage.js +++ b/regression/storage.js @@ -14,26 +14,29 @@ * limitations under the License. */ -var assert = require('assert'), - async = require('async'), - crypto = require('crypto'), - fs = require('fs'), - tmp = require('tmp'); +/*global describe, it, before, after */ -var env = require('./env.js'), - gcloud = require('../lib'), - bucket = new gcloud.storage.Bucket(env); +'use strict'; -var pathToLogoFile = 'regression/data/CloudPlatform_128px_Retina.png', - logoFileMd5Hash; +var assert = require('assert'); +var async = require('async'); +var crypto = require('crypto'); +var fs = require('fs'); +var tmp = require('tmp'); -describe('storage', function() { +var env = require('./env.js'); +var gcloud = require('../lib'); - describe('write, read and remove files', function() { +var bucket = new gcloud.storage.Bucket(env); + +var pathToLogoFile = 'regression/data/CloudPlatform_128px_Retina.png'; +var logoFileMd5Hash; +describe('storage', function() { + describe('write, read and remove files', function() { before(function(done) { var md5sum = crypto.createHash('md5'); - s = fs.ReadStream(pathToLogoFile); + var s = fs.ReadStream(pathToLogoFile); s.on('data', function(d) { md5sum.update(d); }); @@ -46,8 +49,9 @@ describe('storage', function() { it('should write/remove from file', function(done) { var fileName = 'CloudLogo'; - bucket.write(fileName, { filename: pathToLogoFile }, function(err, fileObject, resp) { - if (err) { return done(err); } + var fileConfig = { filename: pathToLogoFile }; + bucket.write(fileName, fileConfig, function(err, fileObject) { + assert.ifError(err); assert.equal(fileObject.md5Hash, logoFileMd5Hash); bucket.remove(fileName, done); }); @@ -55,33 +59,33 @@ describe('storage', function() { it('should write/remove from stream', function(done) { var fileName = 'CloudLogo'; - bucket.write(fileName, { data: fs.createReadStream(pathToLogoFile) }, - function(err, fileObject) { - if (err) { return done(err); } + var fileConfig = { data: fs.createReadStream(pathToLogoFile) }; + bucket.write(fileName, fileConfig, function(err, fileObject) { + assert.ifError(err); assert.equal(fileObject.md5Hash, logoFileMd5Hash); bucket.remove(fileName, function(err) { - if (err) { return done(err); } + assert.ifError(err); done(); }); }); }); it('should write/read/remove from a buffer', function(done) { - var fileName = 'MyBuffer', - fileContent = 'Hello World'; + var fileName = 'MyBuffer'; + var fileContent = 'Hello World'; tmp.setGracefulCleanup(); - tmp.file(function _tempFileCreated(err, path, fd) { - if (err) {return done(err)}; - bucket.write(fileName, { data: fileContent }, function(err, fileObject) { - if (err) { return done(err); } + tmp.file(function _tempFileCreated(err, path) { + assert.ifError(err); + bucket.write( + fileName, { data: fileContent }, function(err, fileObject) { + assert.ifError(err); assert(fileObject); - var content = ''; bucket.createReadStream(fileName) .pipe(fs.createWriteStream(path)) .on('error', done) - .on('complete', function(content) { + .on('complete', function() { bucket.remove(fileName, function(err) { - if (err) { return done(err); } + assert.ifError(err); fs.readFile(path, function(err, data) { assert.equal(data, fileContent); done(); @@ -93,16 +97,16 @@ describe('storage', function() { }); it('should write and read metadata', function(done) { - var fileName = 'CloudLogo', - myMetadata = { contentType: 'image/png'}; - bucket.write(fileName, { filename: pathToLogoFile, metadata: myMetadata }, - function(err, fileObject) { - if (err) { return done(err); } + var fileName = 'CloudLogo'; + var myMetadata = { contentType: 'image/png' }; + var fileConfig = { filename: pathToLogoFile, metadata: myMetadata }; + bucket.write(fileName, fileConfig, function(err) { + assert.ifError(err); bucket.stat(fileName, function(err, metadata) { - if (err) { return done(err); } - assert.equal(metadata['contentType'], myMetadata['contentType']); + assert.ifError(err); + assert.equal(metadata.contentType, myMetadata.contentType); bucket.remove(fileName, function(err) { - if (err) { return done(err); } + assert.ifError(err); done(); }); }); @@ -110,38 +114,38 @@ describe('storage', function() { }); it('should copy an existing file', function(done) { - var fileName = 'CloudLogo', - copyName = 'CloudLogoCopy'; + var fileName = 'CloudLogo'; + var fileConfig = { filename: pathToLogoFile }; + var copyName = 'CloudLogoCopy'; // TODO(silvano): Use async.parallel. - bucket.write(fileName, { filename: pathToLogoFile }, function(err, fileObject) { - if (err) { return done(err); } - bucket.copy(fileName, { name: copyName }, function() { - if (err) { return done(err); } + bucket.write(fileName, fileConfig, function(err) { + assert.ifError(err); + bucket.copy(fileName, { name: copyName }, function() { + assert.ifError(err); bucket.remove(copyName, function(err) { - if (err) { return done(err); } + assert.ifError(err); bucket.remove(fileName, function(err) { - if (err) { return done(err); } + assert.ifError(err); done(); }); }); }); }); }); - }); describe('list files', function() { - var filenames = ['CloudLogo1', 'CloudLogo2', 'CloudLogo3']; + var fileConfig = { filename: pathToLogoFile }; before(function(done) { - bucket.write(filenames[0], { filename: pathToLogoFile }, function(err, fileObject) { - if (err) { return done(err); } - bucket.copy(filenames[0], { name: filenames[1] }, function() { - if (err) { return done(err); } - bucket.copy(filenames[0], { name: filenames[2] }, function() { - if (err) { return done(err); } + bucket.write(filenames[0], fileConfig, function(err) { + assert.ifError(err); + bucket.copy(filenames[0], { name: filenames[1] }, function() { + assert.ifError(err); + bucket.copy(filenames[0], { name: filenames[2] }, function() { + assert.ifError(err); done(); }); }); @@ -150,7 +154,7 @@ describe('storage', function() { it('should list files', function(done) { bucket.list(function(err, files, nextQuery) { - if (err) { return done(err); } + assert.ifError(err); assert.equal(files.length, 3); assert.equal(nextQuery, null); done(); @@ -159,11 +163,11 @@ describe('storage', function() { it('should paginate the list', function(done) { bucket.list({ maxResults: 2 }, function(err, files, nextQuery) { - if (err) { return done(err); } + assert.ifError(err); assert.equal(files.length, 2); assert(nextQuery); - bucket.list(nextQuery, function(err, files, nextQuery) { - if (err) { return done(err); } + bucket.list(nextQuery, function(err, files) { + assert.ifError(err); assert(files); done(); }); @@ -184,7 +188,5 @@ describe('storage', function() { } ], done); }); - }); - }); diff --git a/test/common.connection.js b/test/common.connection.js index ceaf44cc0eb..48025cbc8c6 100644 --- a/test/common.connection.js +++ b/test/common.connection.js @@ -14,9 +14,13 @@ * limitations under the License. */ -var assert = require('assert'), - async = require('async'), - conn = require('../lib/common/connection.js'); +/*global describe, it */ + +'use strict'; + +var assert = require('assert'); +var async = require('async'); +var conn = require('../lib/common/connection.js'); describe('Connection', function() { @@ -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..1b7a779ca1a 100644 --- a/test/common.util.js +++ b/test/common.util.js @@ -14,16 +14,18 @@ * limitations under the License. */ -var util = require('../lib/common/util.js'), - assert = require('assert'); +/*global describe, it */ -describe('extend', function() { +'use strict'; + +var assert = require('assert'); +var util = require('../lib/common/util.js'); +describe('extend', function() { it ('should return null for null input', function() { var copy = util.extend(null, {}); assert.strictEqual(copy, null); }); - }); describe('arrayize', function() { @@ -35,7 +37,6 @@ describe('arrayize', function() { }); describe('handleResp', function() { - it('should handle errors', function(done) { var defaultErr = new Error('new error'); util.handleResp(defaultErr, null, null, function(err) { @@ -49,7 +50,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,11 +67,10 @@ 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..847d7f7eea9 100644 --- a/test/datastore.entity.js +++ b/test/datastore.entity.js @@ -14,17 +14,101 @@ * limitations under the License. */ -var assert = require('assert'), - entity = require('../lib/datastore/entity.js'), - datastore = require('../lib/datastore'); +/*global describe, it */ + +'use strict'; + +var assert = require('assert'); +var entity = require('../lib/datastore/entity.js'); +var datastore = require('../lib/datastore'); var blogPostMetadata = { - title: { kind: String, indexed: true }, - tags: { kind: String, multi: true, indexed: true }, + title: { kind: String, indexed: true }, + tags: { kind: String, multi: true, indexed: true }, publishedAt: { kind: Date }, - author: { kind: Object, indexed: true }, - isDraft: { kind: Boolean, indexed: true } -} + 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/); @@ -50,17 +134,17 @@ describe('registerKind', function() { describe('keyFromKeyProto', function() { var proto = { partitionId: { namespace: '', datasetId: 'datasetId' }, - path: [{ kind: 'Kind', name: 'Name' }] + path: [{ kind: 'Kind', name: 'Name' }] }; var protoH = { partitionId: { namespace: 'Test', datasetId: 'datasetId' }, - path: [{ kind: 'Kind', id: '111' }, { kind: 'Kind2', name: 'name' }] + path: [{ kind: 'Kind', id: '111' }, { kind: 'Kind2', name: 'name' }] }; var protoHIncomplete = { partitionId: { namespace: 'Test', datasetId: 'datasetId' }, - path: [{ kind: 'Kind' }, { kind: 'Kind2' }] + path: [{ kind: 'Kind' }, { kind: 'Kind2' }] }; it('should handle keys hierarchically', function(done) { @@ -80,11 +164,9 @@ describe('keyFromKeyProto', function() { assert.deepEqual(key, ['Kind', 'Name']); done(); }); - }); describe('keyToKeyProto', function() { - it('should handle hierarchical key definitions', function(done) { var key = ['Kind1', 1, 'Kind2', 'name']; var proto = entity.keyToKeyProto('datasetId', key); @@ -113,7 +195,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]; @@ -139,26 +221,29 @@ describe('keyToKeyProto', function() { entity.keyToKeyProto('datasetId', ['Kind']); }); }); - }); 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 ret true if kind and an identifier have !0 vals', 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(); }); - }); 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); @@ -171,12 +256,12 @@ describe('entityFromEntityProto', function() { assert.strictEqual(obj.list[1], false); done(); }); - }); 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,31 +270,33 @@ 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(); }); }); describe('queryToQueryProto', function() { - it('should support filters and ancestory filtering', function(done) { var ds = new datastore.Dataset({ projectId: 'project-id' }); var q = ds.createQuery('Kind1') @@ -219,91 +306,4 @@ describe('queryToQueryProto', function() { assert.deepEqual(proto, queryFilterProto); done(); }); - }); - -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..9540b79f26f 100644 --- a/test/datastore.js +++ b/test/datastore.js @@ -14,12 +14,15 @@ * limitations under the License. */ -var assert = require('assert'), - datastore = require('../lib').datastore, - mockResp_get = require('./testdata/response_get.json'); +/*global describe, it, beforeEach */ -describe('Transaction', function() { +'use strict'; + +var assert = require('assert'); +var datastore = require('../lib').datastore; +var mockRespGet = require('./testdata/response_get.json'); +describe('Transaction', function() { it('should begin', function(done) { var t = new datastore.Transaction(null, 'test'); t.makeReq = function(method, proto, callback) { @@ -61,17 +64,15 @@ 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(); }; t.finalize(); }); - }); describe('Dataset', function() { - it('should append ~s if ~s or ~e are not presented', function(done) { var dsWithNoPrefix = new datastore.Dataset({ projectId: 'test' }); var dsWithSPrefix = new datastore.Dataset({ projectId: 's~name' }); @@ -87,7 +88,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,11 +107,9 @@ 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, entities) { + ds.get([['Kind', 123]], function(err, entities) { var entity = entities[0]; var properties = entity.data; assert.deepEqual(entity.key, ['Kind', 5732568548769792]); @@ -141,7 +140,8 @@ describe('Dataset', function() { callback(); }; ds.delete([ - ['Kind', 123], ['Kind', 345] + ['Kind', 123], + ['Kind', 345] ], done); }); @@ -180,7 +180,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 +207,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..651bbeffa79 100644 --- a/test/datastore.query.js +++ b/test/datastore.query.js @@ -14,13 +14,16 @@ * limitations under the License. */ -var assert = require('assert'), - datastore = require('../lib/datastore'), - entity = require('../lib/datastore/entity.js'), - queryProto = require('./testdata/proto_query.json'); +/*global describe, it */ -describe('Query', function() { +'use strict'; + +var assert = require('assert'); +var datastore = require('../lib/datastore'); +var entity = require('../lib/datastore/entity.js'); +var queryProto = require('./testdata/proto_query.json'); +describe('Query', function() { var ds = new datastore.Dataset({ projectId: 'my-project-id' }); it('should use default namespace if none is specified', function(done) { var q = ds.createQuery(['kind1']); @@ -94,7 +97,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(); }); @@ -107,16 +110,15 @@ describe('Query', function() { }); it('should allow page start and end tokens', function(done) { - var q = ds.createQuery(['kind1']) - .start('abc123') - .end('def987'); + var q = ds.createQuery(['kind1']).start('abc123').end('def987'); assert.strictEqual(q.startVal, 'abc123'); assert.strictEqual(q.endVal, 'def987'); done(); }); it('should be converted to a query proto successfully', function(done) { - var q = ds.createQuery(['Kind']) + var q = + ds.createQuery(['Kind']) .select(['name', 'count']) .filter('count >=', datastore.Int(5)) .filter('name =', 'Burcu') @@ -129,5 +131,4 @@ describe('Query', function() { assert.deepEqual(entity.queryToQueryProto(q), queryProto); done(); }); - -}); \ No newline at end of file +}); diff --git a/test/pubsub.js b/test/pubsub.js index e397582eb9e..10e90ef1b4c 100644 --- a/test/pubsub.js +++ b/test/pubsub.js @@ -14,16 +14,19 @@ * limitations under the License. */ -var assert = require('assert'), - pubsub = require('../lib/pubsub'); +/*global describe, it */ -describe('Subscription', function() { +'use strict'; + +var assert = require('assert'); +var pubsub = require('../lib/pubsub'); +describe('Subscription', function() { it('should ack messages if autoAck is set', function(done) { 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; } @@ -93,5 +96,4 @@ describe('Subscription', function() { doneCalled = true; }); }); - -}); \ No newline at end of file +}); diff --git a/test/storage.js b/test/storage.js index 8115237403e..fa398e9257c 100644 --- a/test/storage.js +++ b/test/storage.js @@ -14,8 +14,12 @@ * limitations under the License. */ -var assert = require('assert'), - storage = require('../lib').storage; +/*global describe, it */ + +'use strict'; + +var assert = require('assert'); +var storage = require('../lib').storage; var noop = function() {}; @@ -28,14 +32,13 @@ 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 +50,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 +63,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 +74,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 +83,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,33 +95,33 @@ 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); assert.deepEqual(body, { metadata: 'hello' }); done(); }; - bucket.copy('file-name', { - name: 'new-name', bucket: 'new-bucket', metadata: 'hello' }); + var copyObj = { name: 'new-name', bucket: 'new-bucket', metadata: 'hello' }; + bucket.copy('file-name', copyObj); }); 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); assert.deepEqual(body, { metadata: 'hello' }); done(); }; - bucket.copy('file-name', { - name: 'new-name', metadata: 'hello' }); + var copyObj = { name: 'new-name', metadata: 'hello' }; + bucket.copy('file-name', copyObj); }); 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); @@ -127,5 +130,4 @@ describe('Bucket', function() { }; bucket.remove('file-name'); }); - -}); \ No newline at end of file +});