From 4b70323babe878bbe143a351062df996b3b89981 Mon Sep 17 00:00:00 2001 From: Jason Dobry Date: Wed, 4 Jan 2017 21:11:15 -0800 Subject: [PATCH 1/2] Switch from Mocha to Ava --- appengine/analytics/test/app.test.js | 80 +- appengine/bower/package.json | 2 +- appengine/bower/test/server.test.js | 34 +- appengine/cloudsql/package.json | 2 +- appengine/cloudsql/test/createTables.test.js | 115 +- appengine/cloudsql/test/server.test.js | 98 +- appengine/datastore/app.js | 51 +- appengine/datastore/package.json | 2 +- appengine/datastore/test/app.test.js | 74 +- appengine/disk/app.js | 62 +- appengine/disk/package.json | 2 +- appengine/disk/test/app.test.js | 90 +- appengine/endpoints/package.json | 2 +- appengine/endpoints/test/app.test.js | 96 +- appengine/errorreporting/package.json | 2 +- appengine/errorreporting/test/app.test.js | 44 +- .../express-memcached-session/package.json | 2 +- .../test/server.test.js | 38 +- appengine/express/package.json | 2 +- appengine/express/test/app.test.js | 72 +- appengine/system-test/all.test.js | 48 +- bigquery/package.json | 3 +- bigquery/system-test/datasets.test.js | 71 +- bigquery/system-test/queries.test.js | 34 +- bigquery/system-test/quickstart.test.js | 50 +- bigquery/system-test/tables.test.js | 250 ++-- bigquery/test/datasets.test.js | 27 - bigquery/test/queries.test.js | 26 - bigquery/test/quickstart.test.js | 41 - bigquery/test/tables.test.js | 33 - computeengine/package.json | 7 +- computeengine/system-test/mailjet.test.js | 18 - computeengine/system-test/sendgrid.test.js | 18 - computeengine/system-test/vms.test.js | 21 +- computeengine/system-test/vms_api.test.js | 19 +- computeengine/test/mailjet.test.js | 69 +- computeengine/test/sendgrid.test.js | 65 +- computeengine/test/vms.test.js | 18 - computeengine/test/vms_api.test.js | 18 - datastore/concepts.js | 45 +- datastore/system-test/concepts.test.js | 212 ++- datastore/system-test/error.test.js | 20 +- datastore/system-test/quickstart.test.js | 74 +- datastore/system-test/tasks.test.js | 78 +- debugger/package.json | 6 +- debugger/test/app.test.js | 18 - dns/package.json | 3 +- dns/quickstart.js | 14 +- dns/system-test/quickstart.test.js | 77 +- dns/system-test/zones.test.js | 45 +- dns/test/quickstart.test.js | 43 - dns/test/zones.test.js | 37 - dns/zones.js | 30 +- endpoints/getting-started/package.json | 5 +- endpoints/getting-started/test/app.test.js | 87 +- functions/background/package.json | 3 - functions/background/test/index.test.js | 105 +- functions/datastore/index.js | 3 + functions/datastore/test/index.test.js | 373 +++--- functions/errorreporting/package.json | 3 - functions/errorreporting/test/index.test.js | 20 - functions/gcs/test/index.test.js | 98 +- functions/helloworld/test/index.test.js | 277 ++-- functions/http/test/index.test.js | 252 ++-- functions/log/test/index.test.js | 52 +- functions/ocr/app/package.json | 2 +- functions/ocr/app/test/index.test.js | 300 ++--- functions/pubsub/index.js | 1 + functions/pubsub/test/index.test.js | 158 ++- functions/sendgrid/index.js | 4 +- functions/sendgrid/test/index.test.js | 605 +++++---- functions/slack/index.js | 1 + functions/slack/test/index.test.js | 294 ++--- functions/uuid/test/index.test.js | 18 +- language/slackbot/demo_bot.js | 1 + language/slackbot/demo_bot.test.js | 156 --- language/slackbot/package.json | 2 +- .../slackbot/system-test/controller.test.js | 83 ++ .../slackbot/system-test/demo_bot.test.js | 126 ++ language/system-test/analyze.test.js | 90 +- language/system-test/quickstart.test.js | 60 +- logging/quickstart.js | 12 +- logging/system-test/fluent.test.js | 18 - logging/system-test/logs.test.js | 90 +- logging/system-test/quickstart.test.js | 79 +- logging/system-test/sinks.test.js | 185 +-- logging/test/fluent.test.js | 62 +- logging/test/logs.test.js | 249 ---- logging/test/quickstart.test.js | 54 - logging/test/sinks.test.js | 266 ---- monitoring/package.json | 3 +- .../system-test/create_custom_metric.test.js | 57 +- monitoring/system-test/list_resources.test.js | 40 +- monitoring/test/create_custom_metric.test.js | 18 - monitoring/test/list_resources.test.js | 18 - package.json | 27 +- prediction/hostedmodels.js | 6 +- prediction/package.json | 3 +- prediction/system-test/hostedmodels.test.js | 20 +- prediction/test/hostedmodels.test.js | 18 - pubsub/package.json | 5 +- pubsub/system-test/quickstart.test.js | 63 +- pubsub/system-test/subscriptions.test.js | 275 ++-- pubsub/system-test/topics.test.js | 190 ++- resource/package.json | 7 +- resource/projects.js | 24 +- resource/quickstart.js | 14 +- resource/system-test/projects.test.js | 13 +- resource/system-test/quickstart.test.js | 54 +- resource/test/projects.test.js | 37 - resource/test/quickstart.test.js | 43 - scripts/run | 2 + speech/package.json | 4 +- speech/system-test/quickstart.test.js | 64 +- speech/system-test/recognize.test.js | 24 +- storage/system-test/acl.test.js | 149 +-- storage/system-test/buckets.test.js | 62 +- storage/system-test/encryption.test.js | 91 +- storage/system-test/files.test.js | 191 ++- storage/system-test/quickstart.test.js | 58 +- storage/system-test/transfer.test.js | 202 ++- storage/test/transfer.test.js | 1167 ++++++++--------- system-test/_setup.js | 155 ++- test/_setup.js | 87 +- test/utils.test.js | 111 +- trace/test/app.test.js | 6 +- translate/system-test/quickstart.test.js | 66 +- translate/system-test/translate.test.js | 111 +- vision/package.json | 3 +- vision/quickstart.js | 14 +- vision/system-test/faceDetection.test.js | 77 +- vision/system-test/labelDetection.test.js | 29 +- vision/system-test/landmarkDetection.test.js | 23 +- vision/system-test/quickstart.test.js | 63 +- vision/system-test/textDetection.test.js | 29 +- vision/test/faceDetection.test.js | 20 - vision/test/labelDetection.test.js | 20 - vision/test/landmarkDetection.test.js | 20 - vision/test/quickstart.test.js | 44 - vision/test/textDetection.test.js | 20 - 140 files changed, 4621 insertions(+), 5828 deletions(-) delete mode 100644 bigquery/test/datasets.test.js delete mode 100644 bigquery/test/queries.test.js delete mode 100644 bigquery/test/quickstart.test.js delete mode 100644 bigquery/test/tables.test.js delete mode 100644 computeengine/system-test/mailjet.test.js delete mode 100644 computeengine/system-test/sendgrid.test.js delete mode 100644 computeengine/test/vms.test.js delete mode 100644 computeengine/test/vms_api.test.js delete mode 100644 debugger/test/app.test.js delete mode 100644 dns/test/quickstart.test.js delete mode 100644 dns/test/zones.test.js delete mode 100644 functions/errorreporting/test/index.test.js delete mode 100644 language/slackbot/demo_bot.test.js create mode 100644 language/slackbot/system-test/controller.test.js create mode 100644 language/slackbot/system-test/demo_bot.test.js delete mode 100644 logging/system-test/fluent.test.js delete mode 100644 logging/test/logs.test.js delete mode 100644 logging/test/quickstart.test.js delete mode 100644 logging/test/sinks.test.js delete mode 100644 monitoring/test/create_custom_metric.test.js delete mode 100644 monitoring/test/list_resources.test.js delete mode 100644 prediction/test/hostedmodels.test.js delete mode 100644 resource/test/projects.test.js delete mode 100644 resource/test/quickstart.test.js delete mode 100644 vision/test/faceDetection.test.js delete mode 100644 vision/test/labelDetection.test.js delete mode 100644 vision/test/landmarkDetection.test.js delete mode 100644 vision/test/quickstart.test.js delete mode 100644 vision/test/textDetection.test.js diff --git a/appengine/analytics/test/app.test.js b/appengine/analytics/test/app.test.js index af747d177e..c889694527 100644 --- a/appengine/analytics/test/app.test.js +++ b/appengine/analytics/test/app.test.js @@ -15,6 +15,8 @@ 'use strict'; +require(`../../../test/_setup`); + const express = require(`express`); const path = require(`path`); const proxyquire = require(`proxyquire`).noPreserveCache(); @@ -50,54 +52,48 @@ function getSample () { }; } -describe(`appengine/analytics/app.js`, () => { - let sample; +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); - beforeEach(() => { - sample = getSample(); +test.cb(`should record a visit`, (t) => { + const sample = getSample(); + const expectedResult = `Event tracked.`; - assert(sample.mocks.express.calledOnce); - assert(sample.app.listen.calledOnce); - assert.equal(sample.app.listen.firstCall.args[0], process.env.PORT || 8080); - }); + request(sample.app) + .get(`/`) + .expect(200) + .expect((response) => { + t.is(response.text, expectedResult); + }) + .end(t.end); +}); - it(`should record a visit`, (done) => { - const expectedResult = `Event tracked.`; +test.cb(`should handle request error`, (t) => { + const sample = getSample(); + const expectedResult = `request_error`; - request(sample.app) - .get(`/`) - .expect(200) - .expect((response) => { - assert.equal(response.text, expectedResult); - }) - .end(done); - }); + sample.mocks.request.post.onFirstCall().callsArgWith(2, expectedResult); - it(`should handle request error`, (done) => { - const expectedResult = `request_error`; - - sample.mocks.request.post.onFirstCall().callsArgWith(2, expectedResult); + request(sample.app) + .get(`/`) + .expect(500) + .expect((response) => { + t.is(response.text, `${expectedResult}\n`); + }) + .end(t.end); +}); - request(sample.app) - .get(`/`) - .expect(500) - .expect((response) => { - assert.equal(response.text, expectedResult + `\n`); - }) - .end(done); +test.cb(`should handle track error`, (t) => { + const sample = getSample(); + sample.mocks.request.post.onFirstCall().callsArgWith(2, null, { + statusCode: 400 }); - it(`should handle track error`, (done) => { - sample.mocks.request.post.onFirstCall().callsArgWith(2, null, { - statusCode: 400 - }); - - request(sample.app) - .get('/') - .expect(500) - .expect((response) => { - assert.notEqual(response.text.indexOf('Error: Tracking failed'), -1); - }) - .end(done); - }); + request(sample.app) + .get('/') + .expect(500) + .expect((response) => { + t.true(response.text.includes('Error: Tracking failed')); + }) + .end(t.end); }); diff --git a/appengine/bower/package.json b/appengine/bower/package.json index 22385970fe..a7ce8d21d5 100644 --- a/appengine/bower/package.json +++ b/appengine/bower/package.json @@ -10,7 +10,7 @@ }, "scripts": { "postinstall": "bower install --config.interactive=false", - "test": "cd ..; npm run t -- appengine/analytics/test/*.test.js" + "test": "cd ..; npm run t -- appengine/bower/test/*.test.js" }, "dependencies": { "bower": "1.8.0", diff --git a/appengine/bower/test/server.test.js b/appengine/bower/test/server.test.js index b13fe5dfb8..34b8e67575 100644 --- a/appengine/bower/test/server.test.js +++ b/appengine/bower/test/server.test.js @@ -15,6 +15,8 @@ 'use strict'; +require(`../../../test/_setup`); + const express = require(`express`); const path = require(`path`); const proxyquire = require(`proxyquire`).noPreserveCache(); @@ -38,26 +40,18 @@ function getSample () { }; } -describe(`appengine/bower/server.js`, () => { - let sample; - - beforeEach(() => { - sample = getSample(); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); - assert(sample.mocks.express.calledOnce); - assert(sample.app.listen.calledOnce); - assert.equal(sample.app.listen.firstCall.args[0], process.env.PORT || 8080); - }); +test.cb(`should render a page`, (t) => { + const sample = getSample(); + const expectedResult = `

Hello World!

Express.js + Bower on Google App Engine.

`; - it(`should render a page`, (done) => { - const expectedResult = `

Hello World!

Express.js + Bower on Google App Engine.

`; - - request(sample.app) - .get(`/`) - .expect(200) - .expect((response) => { - assert.notEqual(response.text.indexOf(expectedResult), -1); - }) - .end(done); - }); + request(sample.app) + .get(`/`) + .expect(200) + .expect((response) => { + t.true(response.text.includes(expectedResult)); + }) + .end(t.end); }); diff --git a/appengine/cloudsql/package.json b/appengine/cloudsql/package.json index d3f430bece..f8f64c2b0f 100644 --- a/appengine/cloudsql/package.json +++ b/appengine/cloudsql/package.json @@ -9,7 +9,7 @@ "node": ">=4.3.2" }, "scripts": { - "test": "cd ..; npm run t -- appengine/analytics/test/*.test.js" + "test": "cd ..; npm run t -- appengine/cloudsql/test/*.test.js" }, "dependencies": { "express": "4.14.0", diff --git a/appengine/cloudsql/test/createTables.test.js b/appengine/cloudsql/test/createTables.test.js index 7b8462af01..7b8ba6a02b 100644 --- a/appengine/cloudsql/test/createTables.test.js +++ b/appengine/cloudsql/test/createTables.test.js @@ -15,6 +15,8 @@ 'use strict'; +require(`../../../test/_setup`); + const path = require(`path`); const proxyquire = require(`proxyquire`).noPreserveCache(); @@ -54,64 +56,65 @@ function getSample () { }; } -describe(`appengine/cloudsql/createTables.js`, () => { - it(`should record a visit`, (done) => { - const sample = getSample(); - const expectedResult = `created visits table!`; - - assert(sample.mocks.prompt.start.calledOnce); - assert(sample.mocks.prompt.get.calledOnce); - assert.deepEqual(sample.mocks.prompt.get.firstCall.args[0], [ - `user`, - `password`, - `database` - ]); - - setTimeout(() => { - const uri = `mysql://${sample.mocks.config.user}:${sample.mocks.config.password}@127.0.0.1:3306/${sample.mocks.config.database}`; - assert.deepEqual(sample.mocks.mysql.createConnection.firstCall.args, [uri]); - assert(console.log.calledWith(expectedResult)); - done(); - }, 10); - }); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); + +test.cb.serial(`should record a visit`, (t) => { + const sample = getSample(); + const expectedResult = `created visits table!`; + + t.true(sample.mocks.prompt.start.calledOnce); + t.true(sample.mocks.prompt.get.calledOnce); + t.deepEqual(sample.mocks.prompt.get.firstCall.args[0], [ + `user`, + `password`, + `database` + ]); + + setTimeout(() => { + const uri = `mysql://${sample.mocks.config.user}:${sample.mocks.config.password}@127.0.0.1:3306/${sample.mocks.config.database}`; + t.deepEqual(sample.mocks.mysql.createConnection.firstCall.args, [uri]); + t.true(console.log.calledWith(expectedResult)); + t.end(); + }, 10); +}); + +test.cb.serial(`should handle prompt error`, (t) => { + const error = new Error(`error`); + const sample = getSample(); - it(`should handle prompt error`, (done) => { - const expectedResult = `createTables_prompt_error`; - const sample = getSample(); - - proxyquire(SAMPLE_PATH, { - mysql: sample.mocks.mysql, - prompt: { - start: sinon.stub(), - get: sinon.stub().callsArgWith(1, expectedResult) - } - }); - - setTimeout(() => { - assert(console.error.calledWith(expectedResult)); - done(); - }, 10); + proxyquire(SAMPLE_PATH, { + mysql: sample.mocks.mysql, + prompt: { + start: sinon.stub(), + get: sinon.stub().yields(error) + } }); - it(`should handle insert error`, (done) => { - const expectedResult = `createTables_insert_error`; - const sample = getSample(); - - const connectionMock = { - query: sinon.stub().callsArgWith(1, expectedResult), - end: sinon.stub() - }; - - proxyquire(SAMPLE_PATH, { - mysql: { - createConnection: sinon.stub().returns(connectionMock) - }, - prompt: sample.mocks.prompt - }); - - setTimeout(() => { - assert(console.error.calledWith(expectedResult)); - done(); - }, 10); + setTimeout(() => { + t.true(console.error.calledWith(error)); + t.end(); + }, 10); +}); + +test.cb.serial(`should handle insert error`, (t) => { + const error = new Error(`error`); + const sample = getSample(); + + const connectionMock = { + query: sinon.stub().yields(error), + end: sinon.stub() + }; + + proxyquire(SAMPLE_PATH, { + mysql: { + createConnection: sinon.stub().returns(connectionMock) + }, + prompt: sample.mocks.prompt }); + + setTimeout(() => { + t.true(console.error.calledWith(error)); + t.end(); + }, 10); }); diff --git a/appengine/cloudsql/test/server.test.js b/appengine/cloudsql/test/server.test.js index 0e4b32dfd3..db4e6c02c6 100644 --- a/appengine/cloudsql/test/server.test.js +++ b/appengine/cloudsql/test/server.test.js @@ -15,6 +15,8 @@ 'use strict'; +require(`../../../test/_setup`); + const express = require(`express`); const path = require(`path`); const proxyquire = require(`proxyquire`).noPreserveCache(); @@ -57,60 +59,62 @@ function getSample () { }; } -describe(`appengine/cloudsql/server.js`, () => { - let sample; - - beforeEach(() => { - sample = getSample(); - - assert(sample.mocks.express.calledOnce); - assert(sample.mocks.mysql.createConnection.calledOnce); - assert.deepEqual(sample.mocks.mysql.createConnection.firstCall.args[0], { - user: process.env.MYSQL_USER, - password: process.env.MYSQL_PASSWORD, - database: process.env.MYSQL_DATABASE - }); - assert(sample.app.listen.calledOnce); - assert.equal(sample.app.listen.firstCall.args[0], process.env.PORT || 8080); - }); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); - it(`should record a visit`, (done) => { - const expectedResult = `Last 10 visits:\nTime: 1234, AddrHash: abcd`; +test(`sets up sample`, (t) => { + const sample = getSample(); - request(sample.app) - .get(`/`) - .expect(200) - .expect((response) => { - assert.equal(response.text, expectedResult); - }) - .end(done); + t.true(sample.mocks.express.calledOnce); + t.true(sample.mocks.mysql.createConnection.calledOnce); + t.deepEqual(sample.mocks.mysql.createConnection.firstCall.args[0], { + user: process.env.MYSQL_USER, + password: process.env.MYSQL_PASSWORD, + database: process.env.MYSQL_DATABASE }); + t.true(sample.app.listen.calledOnce); + t.is(sample.app.listen.firstCall.args[0], process.env.PORT || 8080); +}); + +test.cb(`should record a visit`, (t) => { + const sample = getSample(); + const expectedResult = `Last 10 visits:\nTime: 1234, AddrHash: abcd`; + + request(sample.app) + .get(`/`) + .expect(200) + .expect((response) => { + t.is(response.text, expectedResult); + }) + .end(t.end); +}); - it(`should handle insert error`, (done) => { - const expectedResult = `insert_error`; +test.cb(`should handle insert error`, (t) => { + const sample = getSample(); + const expectedResult = `insert_error`; - sample.mocks.connection.query.onFirstCall().yields(expectedResult); + sample.mocks.connection.query.onFirstCall().yields(expectedResult); - request(sample.app) - .get(`/`) - .expect(500) - .expect((response) => { - assert.equal(response.text, `${expectedResult}\n`); - }) - .end(done); - }); + request(sample.app) + .get(`/`) + .expect(500) + .expect((response) => { + t.is(response.text, `${expectedResult}\n`); + }) + .end(t.end); +}); - it(`should handle read error`, (done) => { - const expectedResult = `read_error`; +test.cb(`should handle read error`, (t) => { + const sample = getSample(); + const expectedResult = `read_error`; - sample.mocks.connection.query.onSecondCall().yields(expectedResult); + sample.mocks.connection.query.onSecondCall().yields(expectedResult); - request(sample.app) - .get(`/`) - .expect(500) - .expect((response) => { - assert.equal(response.text, `${expectedResult}\n`); - }) - .end(done); - }); + request(sample.app) + .get(`/`) + .expect(500) + .expect((response) => { + t.is(response.text, `${expectedResult}\n`); + }) + .end(t.end); }); diff --git a/appengine/datastore/app.js b/appengine/datastore/app.js index 7f779d178b..c89ec349c0 100644 --- a/appengine/datastore/app.js +++ b/appengine/datastore/app.js @@ -39,18 +39,11 @@ const datastore = Datastore(); * Insert a visit record into the database. * * @param {object} visit The visit record to insert. - * @param {function} callback The callback function. */ -function insertVisit (visit, callback) { - datastore.save({ +function insertVisit (visit) { + return datastore.save({ key: datastore.key('visit'), data: visit - }, (err) => { - if (err) { - callback(err); - return; - } - callback(); }); } // [END insertVisit] @@ -58,21 +51,17 @@ function insertVisit (visit, callback) { // [START getVisits] /** * Retrieve the latest 10 visit records from the database. - * - * @param {function} callback The callback function. */ -function getVisits (callback) { +function getVisits () { const query = datastore.createQuery('visit') .order('timestamp', { descending: true }) .limit(10); - datastore.runQuery(query, (err, entities) => { - if (err) { - callback(err); - return; - } - callback(null, entities.map((entity) => `Time: ${entity.timestamp}, AddrHash: ${entity.userIp}`)); - }); + return datastore.runQuery(query) + .then((results) => { + const entities = results[0]; + return entities.map((entity) => `Time: ${entity.timestamp}, AddrHash: ${entity.userIp}`); + }); } // [END getVisits] @@ -84,25 +73,17 @@ app.get('/', (req, res, next) => { userIp: crypto.createHash('sha256').update(req.ip).digest('hex').substr(0, 7) }; - insertVisit(visit, (err) => { - if (err) { - next(err); - return; - } - - // Query the last 10 visits from the datastore. - getVisits((err, visits) => { - if (err) { - next(err); - return; - } - + insertVisit(visit) + // Query the last 10 visits from Datastore. + .then(() => getVisits()) + .then((visits) => { res .status(200) .set('Content-Type', 'text/plain') - .send(`Last 10 visits:\n${visits.join('\n')}`); - }); - }); + .send(`Last 10 visits:\n${visits.join('\n')}`) + .end(); + }) + .catch(next); }); // [START listen] diff --git a/appengine/datastore/package.json b/appengine/datastore/package.json index e9f4d069dd..2903ee0bee 100644 --- a/appengine/datastore/package.json +++ b/appengine/datastore/package.json @@ -10,7 +10,7 @@ }, "scripts": { "start": "node app.js", - "test": "cd ..; npm run t -- appengine/analytics/test/*.test.js" + "test": "cd ..; npm run t -- appengine/datastore/test/*.test.js" }, "dependencies": { "@google-cloud/datastore": "0.6.0", diff --git a/appengine/datastore/test/app.test.js b/appengine/datastore/test/app.test.js index b89f11a26b..cbf30538b1 100644 --- a/appengine/datastore/test/app.test.js +++ b/appengine/datastore/test/app.test.js @@ -15,6 +15,8 @@ 'use strict'; +require(`../../../test/_setup`); + const express = require(`express`); const path = require(`path`); const proxyquire = require(`proxyquire`).noCallThru(); @@ -30,7 +32,6 @@ function getSample () { }; const testApp = express(); sinon.stub(testApp, `listen`, (port, callback) => { - assert.equal(port, 8080); setTimeout(() => { callback(); }); @@ -51,9 +52,9 @@ function getSample () { queryMock.limit.returns(queryMock); const datasetMock = { - save: sinon.stub().callsArg(1), + save: sinon.stub().returns(Promise.resolve()), createQuery: sinon.stub().returns(queryMock), - runQuery: sinon.stub().callsArgWith(1, null, resultsMock), + runQuery: sinon.stub().returns(Promise.resolve([resultsMock])), key: sinon.stub().returns({}) }; const DatastoreMock = sinon.stub().returns(datasetMock); @@ -74,56 +75,27 @@ function getSample () { }; } -describe(`appengine/datastore/app.js`, () => { - let sample; - - beforeEach(() => { - sample = getSample(); - - assert(sample.mocks.express.calledOnce); - assert(sample.mocks.Datastore.calledOnce); - assert(sample.app.listen.calledOnce); - assert.equal(sample.app.listen.firstCall.args[0], process.env.PORT || 8080); - }); - - it(`should record a visit`, (done) => { - const expectedResult = `Last 10 visits:\nTime: 1234, AddrHash: abcd`; - - request(sample.app) - .get(`/`) - .expect(200) - .expect((response) => { - console.log(response.body); - assert.equal(response.text, expectedResult); - }) - .end(done); - }); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); - it(`should handle insert error`, (done) => { - const expectedResult = `insert_error`; +test(`sets up sample`, (t) => { + const sample = getSample(); - sample.mocks.dataset.save.callsArgWith(1, expectedResult); - - request(sample.app) - .get(`/`) - .expect(500) - .expect((response) => { - assert.equal(response.text, expectedResult + `\n`); - }) - .end(done); - }); - - it(`should handle read error`, (done) => { - const expectedResult = `read_error`; + t.true(sample.mocks.express.calledOnce); + t.true(sample.mocks.Datastore.calledOnce); + t.true(sample.app.listen.calledOnce); + t.is(sample.app.listen.firstCall.args[0], process.env.PORT || 8080); +}); - sample.mocks.dataset.runQuery.callsArgWith(1, expectedResult); +test.cb(`should record a visit`, (t) => { + const sample = getSample(); + const expectedResult = `Last 10 visits:\nTime: 1234, AddrHash: abcd`; - request(sample.app) - .get(`/`) - .expect(500) - .expect((response) => { - assert.equal(response.text, `${expectedResult}\n`); - }) - .end(done); - }); + request(sample.app) + .get(`/`) + .expect(200) + .expect((response) => { + t.is(response.text, expectedResult); + }) + .end(t.end); }); diff --git a/appengine/disk/app.js b/appengine/disk/app.js index 96295477d6..9985329335 100644 --- a/appengine/disk/app.js +++ b/appengine/disk/app.js @@ -33,15 +33,16 @@ const FILENAME = path.join(__dirname, 'seen.txt'); * Store a visit record on disk. * * @param {object} visit The visit record to insert. - * @param {function} callback The callback function. */ -function insertVisit (visit, callback) { - fs.appendFile(FILENAME, `${JSON.stringify(visit)}\n`, (err) => { - if (err) { - callback(err); - return; - } - callback(); +function insertVisit (visit) { + return new Promise((resolve, reject) => { + fs.appendFile(FILENAME, `${JSON.stringify(visit)}\n`, (err) => { + if (err) { + reject(err); + return; + } + resolve(); + }); }); } // [END insertVisit] @@ -49,22 +50,22 @@ function insertVisit (visit, callback) { // [START getVisits] /** * Retrieve the latest 10 visit records from disk. - * - * @param {function} callback The callback function. */ -function getVisits (callback) { - fs.readFile(FILENAME, { encoding: 'utf8' }, (err, data) => { - if (err) { - callback(err); - return; - } +function getVisits () { + return new Promise((resolve, reject) => { + fs.readFile(FILENAME, { encoding: 'utf8' }, (err, data) => { + if (err) { + reject(err); + return; + } - const visits = data.split('\n') - .filter((line) => line) - .map(JSON.parse) - .map((visit) => `Time: ${visit.timestamp}, AddrHash: ${visit.userIp}`); + const visits = data.split('\n') + .filter((line) => line) + .map(JSON.parse) + .map((visit) => `Time: ${visit.timestamp}, AddrHash: ${visit.userIp}`); - callback(null, visits); + resolve(visits); + }); }); } // [END getVisits] @@ -77,25 +78,16 @@ app.get('/', (req, res, next) => { userIp: crypto.createHash('sha256').update(req.ip).digest('hex').substr(0, 7) }; - insertVisit(visit, (err) => { - if (err) { - next(err); - return; - } - + insertVisit(visit) // Query the last 10 visits from disk. - getVisits((err, visits) => { - if (err) { - next(err); - return; - } - + .then(() => getVisits()) + .then((visits) => { res .status(200) .set('Content-Type', 'text/plain') .send(`Last 10 visits:\n${visits.join('\n')}`); - }); - }); + }) + .catch(next); }); // [START listen] diff --git a/appengine/disk/package.json b/appengine/disk/package.json index 0bdb044696..1b136c0625 100644 --- a/appengine/disk/package.json +++ b/appengine/disk/package.json @@ -10,7 +10,7 @@ }, "scripts": { "start": "node app.js", - "test": "cd ..; npm run t -- appengine/analytics/test/*.test.js" + "test": "cd ..; npm run t -- appengine/disk/test/*.test.js" }, "dependencies": { "express": "4.14.0" diff --git a/appengine/disk/test/app.test.js b/appengine/disk/test/app.test.js index 1e1ce8fdb3..2604b5be5f 100644 --- a/appengine/disk/test/app.test.js +++ b/appengine/disk/test/app.test.js @@ -15,6 +15,8 @@ 'use strict'; +require(`../../../test/_setup`); + const express = require(`express`); const path = require(`path`); const proxyquire = require(`proxyquire`).noPreserveCache(); @@ -31,8 +33,8 @@ function getSample () { userIp: `abcd` }) + `\n`; const fsMock = { - appendFile: sinon.stub().callsArg(2), - readFile: sinon.stub().callsArgWith(2, null, resultsMock) + appendFile: sinon.stub().yields(), + readFile: sinon.stub().yields(null, resultsMock) }; const app = proxyquire(SAMPLE_PATH, { @@ -49,54 +51,56 @@ function getSample () { }; } -describe(`appengine/disk/app.js`, () => { - let sample; - - beforeEach(() => { - sample = getSample(); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); - assert(sample.mocks.express.calledOnce); - assert(sample.app.listen.calledOnce); - assert.equal(sample.app.listen.firstCall.args[0], process.env.PORT || 8080); - }); +test(`sets up the sample`, (t) => { + const sample = getSample(); - it(`should record a visit`, (done) => { - const expectedResult = `Last 10 visits:\nTime: 1234, AddrHash: abcd`; + t.true(sample.mocks.express.calledOnce); + t.true(sample.app.listen.calledOnce); + t.is(sample.app.listen.firstCall.args[0], process.env.PORT || 8080); +}); - request(sample.app) - .get(`/`) - .expect(200) - .expect((response) => { - assert.equal(response.text, expectedResult); - }) - .end(done); - }); +test.cb(`should record a visit`, (t) => { + const sample = getSample(); + const expectedResult = `Last 10 visits:\nTime: 1234, AddrHash: abcd`; + + request(sample.app) + .get(`/`) + .expect(200) + .expect((response) => { + t.is(response.text, expectedResult); + }) + .end(t.end); +}); - it(`should handle insert error`, (done) => { - const expectedResult = `insert_error`; +test.cb(`should handle insert error`, (t) => { + const sample = getSample(); + const error = new Error(`error`); - sample.mocks.fs.appendFile.callsArgWith(2, expectedResult); + sample.mocks.fs.appendFile.yields(error); - request(sample.app) - .get(`/`) - .expect(500) - .expect((response) => { - assert.equal(response.text, expectedResult + `\n`); - }) - .end(done); - }); + request(sample.app) + .get(`/`) + .expect(500) + .expect((response) => { + t.true(response.text.includes(error.message)); + }) + .end(t.end); +}); - it(`should handle read error`, (done) => { - const expectedResult = `read_error`; +test.cb(`should handle read error`, (t) => { + const sample = getSample(); + const error = new Error(`error`); - sample.mocks.fs.readFile.callsArgWith(2, expectedResult); + sample.mocks.fs.readFile.yields(error); - request(sample.app) - .get(`/`) - .expect(500) - .expect((response) => { - assert.equal(response.text, `${expectedResult}\n`); - }) - .end(done); - }); + request(sample.app) + .get(`/`) + .expect(500) + .expect((response) => { + t.true(response.text.includes(error.message)); + }) + .end(t.end); }); diff --git a/appengine/endpoints/package.json b/appengine/endpoints/package.json index b36946318f..17ddb1577f 100644 --- a/appengine/endpoints/package.json +++ b/appengine/endpoints/package.json @@ -10,7 +10,7 @@ }, "scripts": { "start": "node app.js", - "test": "cd ..; npm run t -- appengine/analytics/test/*.test.js" + "test": "cd ..; npm run t -- appengine/endpoints/test/*.test.js" }, "dependencies": { "express": "4.14.0", diff --git a/appengine/endpoints/test/app.test.js b/appengine/endpoints/test/app.test.js index ec4d464c46..3a858df58b 100644 --- a/appengine/endpoints/test/app.test.js +++ b/appengine/endpoints/test/app.test.js @@ -15,21 +15,23 @@ 'use strict'; -var express = require('express'); -var path = require('path'); -var proxyquire = require('proxyquire').noPreserveCache(); -var request = require('supertest'); +require(`../../../test/_setup`); -var SAMPLE_PATH = path.join(__dirname, '../app.js'); +const express = require('express'); +const path = require('path'); +const proxyquire = require('proxyquire').noPreserveCache(); +const request = require('supertest'); + +const SAMPLE_PATH = path.join(__dirname, '../app.js'); function getSample () { - var testApp = express(); + const testApp = express(); sinon.stub(testApp, 'listen').callsArg(1); - var expressMock = sinon.stub().returns(testApp); - - var app = proxyquire(SAMPLE_PATH, { + const expressMock = sinon.stub().returns(testApp); + const app = proxyquire(SAMPLE_PATH, { express: expressMock }); + return { app: app, mocks: { @@ -38,46 +40,48 @@ function getSample () { }; } -describe('appengine/endpoints/app.js', function () { - var sample; +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); - beforeEach(function () { - sample = getSample(); +test(`sets up the sample`, (t) => { + const sample = getSample(); - assert(sample.mocks.express.calledOnce); - assert(sample.app.listen.calledOnce); - assert.equal(sample.app.listen.firstCall.args[0], process.env.PORT || 8080); - }); + t.true(sample.mocks.express.calledOnce); + t.true(sample.app.listen.calledOnce); + t.is(sample.app.listen.firstCall.args[0], process.env.PORT || 8080); +}); - it('should echo a message', function (done) { - request(sample.app) - .post('/echo') - .send({ message: 'foo' }) - .expect(200) - .expect(function (response) { - assert.equal(response.body.message, 'foo'); - }) - .end(done); - }); +test.cb(`should echo a message`, (t) => { + const sample = getSample(); + request(sample.app) + .post('/echo') + .send({ message: 'foo' }) + .expect(200) + .expect((response) => { + t.is(response.body.message, 'foo'); + }) + .end(t.end); +}); - it('should try to parse encoded info', function (done) { - request(sample.app) - .get('/auth/info/googlejwt') - .expect(200) - .expect(function (response) { - assert.deepEqual(response.body, { id: 'anonymous' }); - }) - .end(done); - }); +test.cb(`should try to parse encoded info`, (t) => { + const sample = getSample(); + request(sample.app) + .get('/auth/info/googlejwt') + .expect(200) + .expect((response) => { + t.deepEqual(response.body, { id: 'anonymous' }); + }) + .end(t.end); +}); - it('should successfully parse encoded info', function (done) { - request(sample.app) - .get('/auth/info/googlejwt') - .set('X-Endpoint-API-UserInfo', new Buffer(JSON.stringify({ id: 'foo' })).toString('base64')) - .expect(200) - .expect(function (response) { - assert.deepEqual(response.body, { id: 'foo' }); - }) - .end(done); - }); +test.cb(`should successfully parse encoded info`, (t) => { + const sample = getSample(); + request(sample.app) + .get('/auth/info/googlejwt') + .set('X-Endpoint-API-UserInfo', new Buffer(JSON.stringify({ id: 'foo' })).toString('base64')) + .expect(200) + .expect((response) => { + t.deepEqual(response.body, { id: 'foo' }); + }) + .end(t.end); }); diff --git a/appengine/errorreporting/package.json b/appengine/errorreporting/package.json index f16afef5b4..3b67bccbf3 100644 --- a/appengine/errorreporting/package.json +++ b/appengine/errorreporting/package.json @@ -10,7 +10,7 @@ }, "scripts": { "start": "node app.js", - "test": "cd ..; npm run t -- appengine/analytics/test/*.test.js" + "test": "cd ..; npm run t -- appengine/errorreporting/test/*.test.js" }, "dependencies": { "express": "4.14.0", diff --git a/appengine/errorreporting/test/app.test.js b/appengine/errorreporting/test/app.test.js index 52e99da01a..608adf69e6 100644 --- a/appengine/errorreporting/test/app.test.js +++ b/appengine/errorreporting/test/app.test.js @@ -15,6 +15,8 @@ 'use strict'; +require(`../../../test/_setup`); + const express = require(`express`); const winston = require(`winston`); const path = require(`path`); @@ -50,29 +52,29 @@ function getSample () { }; } -describe(`appengine/errorreporting/app.js`, () => { - let sample; +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); - beforeEach(() => { - sample = getSample(); +test(`sets up the sample`, (t) => { + const sample = getSample(); - assert(sample.mocks.express.calledOnce); - assert(sample.mocks.winston.add.calledOnce); - assert.strictEqual(sample.mocks.winston.add.firstCall.args[0], winston.transports.File); - assert(sample.app.listen.calledOnce); - assert.equal(sample.app.listen.firstCall.args[0], process.env.PORT || 8080); - }); + t.true(sample.mocks.express.calledOnce); + t.true(sample.mocks.winston.add.calledOnce); + t.true(sample.mocks.winston.add.firstCall.args[0] === winston.transports.File); + t.true(sample.app.listen.calledOnce); + t.is(sample.app.listen.firstCall.args[0], process.env.PORT || 8080); +}); - it(`should throw an error`, (done) => { - const expectedResult = `something is wrong!`; +test.cb(`should throw an error`, (t) => { + const sample = getSample(); + const expectedResult = `something is wrong!`; - request(sample.app) - .get(`/`) - .expect(500) - .expect((response) => { - assert(sample.mocks.winston.error.calledOnce); - assert.equal(response.text, expectedResult); - }) - .end(done); - }); + request(sample.app) + .get(`/`) + .expect(500) + .expect((response) => { + t.true(sample.mocks.winston.error.calledOnce); + t.is(response.text, expectedResult); + }) + .end(t.end); }); diff --git a/appengine/express-memcached-session/package.json b/appengine/express-memcached-session/package.json index 70a85cb5e6..79999869fe 100644 --- a/appengine/express-memcached-session/package.json +++ b/appengine/express-memcached-session/package.json @@ -10,7 +10,7 @@ }, "scripts": { "start": "node server.js", - "test": "cd ..; npm run t -- appengine/analytics/test/*.test.js" + "test": "cd ..; npm run t -- appengine/express-memcached-session/test/*.test.js" }, "dependencies": { "connect-memjs": "0.1.0", diff --git a/appengine/express-memcached-session/test/server.test.js b/appengine/express-memcached-session/test/server.test.js index 93c1f1e8ec..6a69819bc5 100644 --- a/appengine/express-memcached-session/test/server.test.js +++ b/appengine/express-memcached-session/test/server.test.js @@ -15,6 +15,8 @@ 'use strict'; +require(`../../../test/_setup`); + const express = require(`express`); const session = require(`express-session`); const path = require(`path`); @@ -49,26 +51,26 @@ function getSample () { }; } -describe(`appengine/express-memcached-session/app.js`, () => { - let sample; +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); - beforeEach(() => { - sample = getSample(); +test(`sets up the sample`, (t) => { + const sample = getSample(); - assert(sample.mocks.express.calledOnce); - assert(sample.app.listen.calledOnce); - assert.equal(sample.app.listen.firstCall.args[0], process.env.PORT || 8080); - }); + t.true(sample.mocks.express.calledOnce); + t.true(sample.app.listen.calledOnce); + t.is(sample.app.listen.firstCall.args[0], process.env.PORT || 8080); +}); - it(`should respond with visit count`, (done) => { - const expectedResult = `Viewed 1 times.`; +test.cb(`should respond with visit count`, (t) => { + const sample = getSample(); + const expectedResult = `Viewed 1 times.`; - request(sample.app) - .get(`/`) - .expect(200) - .expect((response) => { - assert(response.text.indexOf(expectedResult) !== -1); - }) - .end(done); - }); + request(sample.app) + .get(`/`) + .expect(200) + .expect((response) => { + t.true(response.text.includes(expectedResult)); + }) + .end(t.end); }); diff --git a/appengine/express/package.json b/appengine/express/package.json index 0f104d01c7..bddb44d34a 100644 --- a/appengine/express/package.json +++ b/appengine/express/package.json @@ -10,7 +10,7 @@ }, "scripts": { "start": "node ./bin/www", - "test": "cd ..; npm run t -- appengine/analytics/test/*.test.js" + "test": "cd ..; npm run t -- appengine/express/test/*.test.js" }, "dependencies": { "body-parser": "1.15.2", diff --git a/appengine/express/test/app.test.js b/appengine/express/test/app.test.js index bbf2f9d8c0..ef47341a41 100644 --- a/appengine/express/test/app.test.js +++ b/appengine/express/test/app.test.js @@ -15,6 +15,8 @@ 'use strict'; +require(`../../../test/_setup`); + const path = require(`path`); const proxyquire = require(`proxyquire`).noPreserveCache(); const request = require(`supertest`); @@ -29,46 +31,44 @@ function getSample () { }; } -describe(`appengine/express/app.js`, () => { - let sample; - - beforeEach(() => { - sample = getSample(); - }); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); - it(`should render index page`, (done) => { - const expectedResult = `Hello World! Express.js on Google App Engine.`; +test.cb(`should render index page`, (t) => { + const sample = getSample(); + const expectedResult = `Hello World! Express.js on Google App Engine.`; - request(sample.app) - .get(`/`) - .expect(200) - .expect((response) => { - assert(response.text.indexOf(expectedResult) !== -1); - }) - .end(done); - }); + request(sample.app) + .get(`/`) + .expect(200) + .expect((response) => { + t.true(response.text.includes(expectedResult)); + }) + .end(t.end); +}); - it(`should render users page`, (done) => { - const expectedResult = `respond with a resource`; +test.cb(`should render users page`, (t) => { + const sample = getSample(); + const expectedResult = `respond with a resource`; - request(sample.app) - .get(`/users`) - .expect(200) - .expect((response) => { - assert(response.text.indexOf(expectedResult) !== -1); - }) - .end(done); - }); + request(sample.app) + .get(`/users`) + .expect(200) + .expect((response) => { + t.true(response.text.includes(expectedResult)); + }) + .end(t.end); +}); - it(`should catch 404`, (done) => { - const expectedResult = `Error: Not Found`; +test.cb(`should catch 404`, (t) => { + const sample = getSample(); + const expectedResult = `Error: Not Found`; - request(sample.app) - .get(`/doesnotexist`) - .expect(404) - .expect((response) => { - assert(response.text.indexOf(expectedResult) !== -1); - }) - .end(done); - }); + request(sample.app) + .get(`/doesnotexist`) + .expect(404) + .expect((response) => { + t.true(response.text.includes(expectedResult)); + }) + .end(t.end); }); diff --git a/appengine/system-test/all.test.js b/appengine/system-test/all.test.js index 080654f8b9..08def9efc4 100644 --- a/appengine/system-test/all.test.js +++ b/appengine/system-test/all.test.js @@ -13,6 +13,8 @@ 'use strict'; +require(`../../system-test/_setup`); + var spawn = require('child_process').spawn; var request = require('request'); var fs = require('fs'); @@ -296,8 +298,8 @@ function makeRequest (url, numTry, maxTries, cb) { // Send a request to the given url and test that the response body has the // expected value function testRequest (url, sample, cb) { - // Try up to 8 times - makeRequest(url, 1, 8, function (err, res, body) { + // Try up to 10 times + makeRequest(url, 1, 10, function (err, res, body) { if (err) { // Request error return cb(err); @@ -319,31 +321,29 @@ function testRequest (url, sample, cb) { }); } -var port = 8080; -sampleTests.forEach(function (sample) { - describe(sample.dir, function () { - sample.env = sample.env || {}; - sample.env.PORT = port; - if (sample.dir === 'appengine/parse-server') { - sample.env.SERVER_URL = sample.env.SERVER_URL + port + '/parse'; - } - port++; - it.skip('should install dependencies', function (done) { - testInstallation(sample, done); - }); +let port = 8080; +sampleTests.forEach((sample) => { + sample.env = sample.env || {}; + sample.env.PORT = port; + if (sample.dir === 'appengine/parse-server') { + sample.env.SERVER_URL = `${sample.env.SERVER_URL}${port}/parse`; + } + port++; + test.cb.skip(`${sample.dir}: should install dependencies`, (t) => { + testInstallation(sample, t.end); + }); - if (sample.TRAVIS && !process.env.TRAVIS) { - return; - } + if (sample.TRAVIS && !process.env.TRAVIS) { + return; + } - if (sample.TRAVIS_NODE_VERSION && process.env.TRAVIS && - process.env.TRAVIS_NODE_VERSION !== sample.TRAVIS_NODE_VERSION) { - return; - } + if (sample.TRAVIS_NODE_VERSION && process.env.TRAVIS && + process.env.TRAVIS_NODE_VERSION !== sample.TRAVIS_NODE_VERSION) { + return; + } - it('should return 200 and Hello World', function (done) { - testLocalApp(sample, done); - }); + test.cb(`${sample.dir}: should return 200 and Hello World`, (t) => { + testLocalApp(sample, t.end); }); }); diff --git a/bigquery/package.json b/bigquery/package.json index e3b74f185f..628a64d204 100644 --- a/bigquery/package.json +++ b/bigquery/package.json @@ -5,8 +5,7 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "scripts": { - "test": "cd ..; npm run t -- bigquery/test/*.test.js", - "system-test": "cd ..; npm run st -- bigquery/system-test/*.test.js" + "test": "cd ..; npm run st -- bigquery/system-test/*.test.js" }, "dependencies": { "@google-cloud/bigquery": "0.6.0", diff --git a/bigquery/system-test/datasets.test.js b/bigquery/system-test/datasets.test.js index 16822ea3b8..73f435eb8c 100644 --- a/bigquery/system-test/datasets.test.js +++ b/bigquery/system-test/datasets.test.js @@ -15,52 +15,51 @@ 'use strict'; +require(`../../system-test/_setup`); + const bigquery = require(`@google-cloud/bigquery`)(); const uuid = require(`uuid`); const path = require(`path`); -const run = require(`../../utils`).run; const cwd = path.join(__dirname, `..`); const cmd = `node datasets.js`; const datasetId = (`nodejs-docs-samples-test-${uuid.v4()}`).replace(/-/gi, '_'); -describe(`bigquery:datasets`, function () { - after(() => { - return bigquery - .dataset(datasetId) - .delete({ force: true }) - .catch(() => undefined); - }); +test.after(async () => { + try { + await bigquery.dataset(datasetId).delete({ force: true }); + } catch (err) {} // ignore error +}); + +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); - it(`should create a dataset`, () => { - const output = run(`${cmd} create ${datasetId}`, cwd); - assert.equal(output, `Dataset ${datasetId} created.`); - return bigquery.dataset(datasetId).exists() - .then((results) => assert.equal(results[0], true)); - }); +test.serial(`should create a dataset`, async (t) => { + const output = await runAsync(`${cmd} create ${datasetId}`, cwd); + t.is(output, `Dataset ${datasetId} created.`); + const [exists] = await bigquery.dataset(datasetId).exists(); + t.true(exists); +}); - it(`should list datasets`, (done) => { - // Listing is eventually consistent. Give the indexes time to update. - setTimeout(() => { - const output = run(`${cmd} list`, cwd); - assert.equal(output.includes(`Datasets:`), true); - assert.equal(output.includes(datasetId), true); - done(); - }, 5000); - }); +test.serial(`should list datasets`, async (t) => { + await tryTest(async () => { + const output = await runAsync(`${cmd} list`, cwd); + t.true(output.includes(`Datasets:`)); + t.true(output.includes(datasetId)); + }).start(); +}); - it(`should return the size of a dataset`, function () { - let output = run(`${cmd} size hacker_news bigquery-public-data`, cwd); - assert.equal(output.includes(`Size of hacker_news`), true); - assert.equal(output.includes(`MB`), true); - output = run(`${cmd} size ${datasetId}`, cwd); - assert.equal(output.includes(`Size of ${datasetId}: 0 MB`), true); - }); +test.serial(`should return the size of a dataset`, async (t) => { + let output = await runAsync(`${cmd} size hacker_news bigquery-public-data`, cwd); + t.true(output.includes(`Size of hacker_news`)); + t.true(output.includes(`MB`)); + output = await runAsync(`${cmd} size ${datasetId}`, cwd); + t.true(output.includes(`Size of ${datasetId}: 0 MB`)); +}); - it(`should delete a dataset`, () => { - const output = run(`${cmd} delete ${datasetId}`, cwd); - assert.equal(output, `Dataset ${datasetId} deleted.`); - return bigquery.dataset(datasetId).exists() - .then((results) => assert.equal(results[0], false)); - }); +test.serial(`should delete a dataset`, async (t) => { + const output = await runAsync(`${cmd} delete ${datasetId}`, cwd); + t.is(output, `Dataset ${datasetId} deleted.`); + const [exists] = await bigquery.dataset(datasetId).exists(); + t.false(exists); }); diff --git a/bigquery/system-test/queries.test.js b/bigquery/system-test/queries.test.js index 61ce533325..204c093c32 100644 --- a/bigquery/system-test/queries.test.js +++ b/bigquery/system-test/queries.test.js @@ -15,8 +15,9 @@ 'use strict'; +require(`../../system-test/_setup`); + const path = require(`path`); -const run = require(`../../utils`).run; const cwd = path.join(__dirname, `..`); const cmd = `node queries.js`; @@ -45,21 +46,22 @@ unique_words: 4582`; const sqlQuery = `SELECT * FROM publicdata.samples.natality LIMIT 5;`; -describe(`bigquery:queries`, function () { - it(`should query shakespeare`, () => { - const output = run(`${cmd} shakespeare`, cwd); - assert.equal(output, expectedShakespeareResult); - }); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); + +test(`should query shakespeare`, async (t) => { + const output = await runAsync(`${cmd} shakespeare`, cwd); + t.is(output, expectedShakespeareResult); +}); - it(`should run a sync query`, () => { - const output = run(`${cmd} sync "${sqlQuery}"`, cwd); - assert.equal(output.includes(`Rows:`), true); - assert.equal(output.includes(`source_year`), true); - }); +test(`should run a sync query`, async (t) => { + const output = await runAsync(`${cmd} sync "${sqlQuery}"`, cwd); + t.true(output.includes(`Rows:`)); + t.true(output.includes(`source_year`)); +}); - it(`should run an async query`, () => { - const output = run(`${cmd} async "${sqlQuery}"`, cwd); - assert.equal(output.includes(`Rows:`), true); - assert.equal(output.includes(`source_year`), true); - }); +test(`should run an async query`, async (t) => { + const output = await runAsync(`${cmd} async "${sqlQuery}"`, cwd); + t.true(output.includes(`Rows:`)); + t.true(output.includes(`source_year`)); }); diff --git a/bigquery/system-test/quickstart.test.js b/bigquery/system-test/quickstart.test.js index 85e5b0edac..6099008721 100644 --- a/bigquery/system-test/quickstart.test.js +++ b/bigquery/system-test/quickstart.test.js @@ -15,6 +15,8 @@ 'use strict'; +require(`../../system-test/_setup`); + const proxyquire = require(`proxyquire`).noPreserveCache(); const bigquery = proxyquire(`@google-cloud/bigquery`, {})(); const uuid = require(`uuid`); @@ -23,38 +25,42 @@ const expectedDatasetId = `my_new_dataset`; let datasetId = `nodejs-docs-samples-test-${uuid.v4()}`; datasetId = datasetId.replace(/-/gi, `_`); -describe(`bigquery:quickstart`, () => { - let bigqueryMock, BigqueryMock; +test.after(async () => { + try { + bigquery.dataset(datasetId).delete({ force: true }); + } catch (err) {} // ignore error +}); - after((done) => { - bigquery.dataset(datasetId).delete(() => { - // Ignore any error, the dataset might not have been created - done(); - }); - }); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); - it(`quickstart should create a dataset`, (done) => { - bigqueryMock = { +test(`quickstart should create a dataset`, async (t) => { + await new Promise((resolve, reject) => { + const bigqueryMock = { createDataset: (_datasetId) => { - assert.equal(_datasetId, expectedDatasetId); + t.is(_datasetId, expectedDatasetId); return bigquery.createDataset(datasetId) - .then((results) => { - const dataset = results[0]; - assert.notEqual(dataset, undefined); + .then(([dataset]) => { + t.not(dataset, undefined); + setTimeout(() => { - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, [`Dataset ${dataset.id} created.`]); - done(); - }, 500); - return results; - }).catch(done); + try { + t.true(console.log.calledOnce); + t.deepEqual(console.log.firstCall.args, [`Dataset ${dataset.id} created.`]); + resolve(); + } catch (err) { + reject(err); + } + }, 200); + + return [dataset]; + }).catch(reject); } }; - BigqueryMock = sinon.stub().returns(bigqueryMock); proxyquire(`../quickstart`, { - '@google-cloud/bigquery': BigqueryMock + '@google-cloud/bigquery': sinon.stub().returns(bigqueryMock) }); }); }); diff --git a/bigquery/system-test/tables.test.js b/bigquery/system-test/tables.test.js index 982b6b2d63..886242f951 100644 --- a/bigquery/system-test/tables.test.js +++ b/bigquery/system-test/tables.test.js @@ -15,13 +15,12 @@ 'use strict'; +require(`../../system-test/_setup`); + const bigquery = require(`@google-cloud/bigquery`)(); const storage = require(`@google-cloud/storage`)(); const uuid = require(`uuid`); const path = require(`path`); -const utils = require(`../../utils`); -const run = utils.run; -const noop = utils.noop; const cwd = path.join(__dirname, `..`); const cmd = `node tables.js`; @@ -39,139 +38,118 @@ const exportFileName = `data.json`; const importFileName = `data.csv`; const localFilePath = path.join(__dirname, `../resources/${importFileName}`); const rows = [ - { Name: 'foo', Age: 27, Weight: 80.3, IsMagic: true }, - { Name: 'bar', Age: 13, Weight: 54.6, IsMagic: false } + { Name: `foo`, Age: 27, Weight: 80.3, IsMagic: true }, + { Name: `bar`, Age: 13, Weight: 54.6, IsMagic: false } ]; -describe('bigquery:tables', () => { - before(() => { - return storage.createBucket(bucketName) - .then((results) => results[0].upload(localFilePath)) - .then(() => bigquery.createDataset(srcDatasetId)) - .then(() => bigquery.createDataset(destDatasetId)); - }); - - after(() => { - return bigquery.dataset(srcDatasetId).delete({ force: true }) - .then(() => bigquery.dataset(destDatasetId).delete({ force: true }), noop) - .then(() => storage.bucket(bucketName).deleteFiles({ force: true }), noop) - .then(() => { - return new Promise((resolve, reject) => { - setTimeout(() => { - storage.bucket(bucketName).delete().then(resolve, reject); - }, 2000); - }); - }, noop); - }); - - it(`should create a table`, () => { - const output = run(`${cmd} create ${datasetId} ${tableId} "${schema}"`, cwd); - assert.equal(output, `Table ${tableId} created.`); - return bigquery.dataset(datasetId).table(tableId).exists() - .then((results) => assert.equal(results[0], true)); - }); - - it(`should list tables`, (done) => { - // Listing is eventually consistent. Give the indexes time to update. - setTimeout(() => { - const output = run(`${cmd} list ${datasetId}`, cwd); - assert.equal(output.includes(`Tables:`), true); - assert.equal(output.includes(tableId), true); - done(); - }, 5000); - }); - - it(`should import a local file`, () => { - const output = run(`${cmd} import ${datasetId} ${tableId} ${localFilePath}`, cwd); - assert.equal(output.includes(`started.`), true); - assert.equal(output.includes(`completed.`), true); - return new Promise((resolve, reject) => { - setTimeout(() => { - return bigquery.dataset(datasetId).table(tableId).getRows() - .then((results) => { - assert.equal(results[0].length, 1); - resolve(); - }) - .catch(reject); - }, 2000); - }); - }).timeout(120000); - - it(`should browse table rows`, () => { - const output = run(`${cmd} browse ${datasetId} ${tableId}`, cwd); - assert.equal(output, `Rows:\n{ Name: 'Gandalf', Age: 2000, Weight: 140, IsMagic: true }`); - }); - - it(`should export a table to GCS`, () => { - const output = run(`${cmd} export ${datasetId} ${tableId} ${bucketName} ${exportFileName}`, cwd); - assert.equal(output.includes(`started.`), true); - assert.equal(output.includes(`completed.`), true); - return new Promise((resolve, reject) => { - setTimeout(() => { - storage.bucket(bucketName).file(exportFileName).exists() - .then((results) => { - assert.equal(results[0], true); - resolve(); - }) - .catch(reject); - }, 10000); - }); - }).timeout(120000); - - it(`should import a GCS file`, () => { - const output = run(`${cmd} import-gcs ${datasetId} ${tableId} ${bucketName} ${importFileName}`, cwd); - assert.equal(output.includes(`started.`), true); - assert.equal(output.includes(`completed.`), true); - return new Promise((resolve, reject) => { - setTimeout(() => { - return bigquery.dataset(datasetId).table(tableId).getRows() - .then((results) => { - assert.equal(results[0].length, 2); - resolve(); - }) - .catch(reject); - }, 2000); - }); - }).timeout(120000); - - it(`should copy a table`, () => { - const output = run(`${cmd} copy ${srcDatasetId} ${srcTableId} ${destDatasetId} ${destTableId}`, cwd); - assert.equal(output.includes(`started.`), true); - assert.equal(output.includes(`completed.`), true); - return new Promise((resolve, reject) => { - setTimeout(() => { - bigquery.dataset(destDatasetId).table(destTableId).getRows() - .then((results) => { - assert.equal(results[0].length, 2); - resolve(); - }) - .catch(reject); - }, 2000); - }); - }).timeout(120000); - - it(`should insert rows`, () => { - assert.throws(() => { - run(`${cmd} insert ${datasetId} ${tableId} 'foo.bar'`, cwd); - }, Error, `"json_or_file" (or the file it points to) is not a valid JSON array.`); - const output = run(`${cmd} insert ${datasetId} ${tableId} '${JSON.stringify(rows)}'`, cwd); - assert.equal(output, `Inserted:\n{ Name: 'foo', Age: 27, Weight: 80.3, IsMagic: true }\n{ Name: 'bar', Age: 13, Weight: 54.6, IsMagic: false }`); - return new Promise((resolve, reject) => { - setTimeout(() => { - bigquery.dataset(datasetId).table(tableId).getRows() - .then((results) => { - assert.equal(results[0].length, 4); - resolve(); - }) - .catch(reject); - }, 2000); - }); - }).timeout(120000); - - it(`should delete a table`, () => { - const output = run(`${cmd} delete ${datasetId} ${tableId}`, cwd); - assert.equal(output, `Table ${tableId} deleted.`); - return bigquery.dataset(datasetId).table(tableId).exists() - .then((results) => assert.equal(results[0], false)); - }); +test.before(async () => { + const [bucket] = await storage.createBucket(bucketName); + await Promise.all([ + bucket.upload(localFilePath), + bigquery.createDataset(srcDatasetId), + bigquery.createDataset(destDatasetId) + ]); +}); + +test.after(async () => { + try { + await bigquery.dataset(srcDatasetId).delete({ force: true }); + } catch (err) {} // ignore error + try { + await bigquery.dataset(destDatasetId).delete({ force: true }); + } catch (err) {} // ignore error + try { + await storage.bucket(bucketName).deleteFiles({ force: true }); + } catch (err) {} // ignore error + try { + // Try deleting files a second time + await storage.bucket(bucketName).deleteFiles({ force: true }); + } catch (err) {} // ignore error + try { + await bigquery.dataset(srcDatasetId).delete({ force: true }); + } catch (err) {} // ignore error + try { + await storage.bucket(bucketName).delete(); + } catch (err) {} // ignore error +}); + +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); + +test.serial(`should create a table`, async (t) => { + const output = await runAsync(`${cmd} create ${datasetId} ${tableId} "${schema}"`, cwd); + t.is(output, `Table ${tableId} created.`); + const [exists] = await bigquery.dataset(datasetId).table(tableId).exists(); + t.true(exists); +}); + +test.serial(`should list tables`, async (t) => { + await tryTest(async () => { + const output = await runAsync(`${cmd} list ${datasetId}`, cwd); + t.true(output.includes(`Tables:`)); + t.true(output.includes(tableId)); + }).start(); +}); + +test.serial(`should import a local file`, async (t) => { + const output = await runAsync(`${cmd} import ${datasetId} ${tableId} ${localFilePath}`, cwd); + t.true(output.includes(`started.`)); + t.true(output.includes(`completed.`)); + await tryTest(async () => { + const [rows] = await bigquery.dataset(datasetId).table(tableId).getRows(); + t.is(rows.length, 1); + }).start(); +}); + +test.serial(`should browse table rows`, async (t) => { + const output = await runAsync(`${cmd} browse ${datasetId} ${tableId}`, cwd); + t.is(output, `Rows:\n{ Name: 'Gandalf', Age: 2000, Weight: 140, IsMagic: true }`); +}); + +test.serial(`should export a table to GCS`, async (t) => { + const output = await runAsync(`${cmd} export ${datasetId} ${tableId} ${bucketName} ${exportFileName}`, cwd); + t.true(output.includes(`started.`)); + t.true(output.includes(`completed.`)); + await tryTest(async () => { + const [exists] = await storage.bucket(bucketName).file(exportFileName).exists(); + t.true(exists); + }).start(); +}); + +test.serial(`should import a GCS file`, async (t) => { + const output = await runAsync(`${cmd} import-gcs ${datasetId} ${tableId} ${bucketName} ${importFileName}`, cwd); + t.true(output.includes(`started.`)); + t.true(output.includes(`completed.`)); + await tryTest(async () => { + const [rows] = await bigquery.dataset(datasetId).table(tableId).getRows(); + t.is(rows.length, 2); + }).start(); +}); + +test.serial(`should copy a table`, async (t) => { + const output = await runAsync(`${cmd} copy ${srcDatasetId} ${srcTableId} ${destDatasetId} ${destTableId}`, cwd); + t.true(output.includes(`started.`)); + t.true(output.includes(`completed.`)); + await tryTest(async () => { + const [rows] = await bigquery.dataset(destDatasetId).table(destTableId).getRows(); + t.is(rows.length, 2); + }).start(); +}); + +test.serial(`should insert rows`, async (t) => { + const err = await t.throws(runAsync(`${cmd} insert ${datasetId} ${tableId} 'foo.bar'`, cwd)); + t.true(err.message.includes(`"json_or_file" (or the file it points to) is not a valid JSON array.`)); + const output = await runAsync(`${cmd} insert ${datasetId} ${tableId} '${JSON.stringify(rows)}'`, cwd); + t.is(output, `Inserted:\n{ Name: 'foo', Age: 27, Weight: 80.3, IsMagic: true }\n{ Name: 'bar', Age: 13, Weight: 54.6, IsMagic: false }`); + await tryTest(async () => { + const [rows] = await bigquery.dataset(datasetId).table(tableId).getRows(); + t.is(rows.length, 4); + }).start(); +}); + +test.serial(`should delete a table`, async (t) => { + const output = await runAsync(`${cmd} delete ${datasetId} ${tableId}`, cwd); + t.is(output, `Table ${tableId} deleted.`); + const [exists] = await bigquery.dataset(datasetId).table(tableId).exists(); + t.false(exists); }); diff --git a/bigquery/test/datasets.test.js b/bigquery/test/datasets.test.js deleted file mode 100644 index 5af24bfd5d..0000000000 --- a/bigquery/test/datasets.test.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright 2016, Google, Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -const program = require(`../datasets`); - -describe(`bigquery:datasets`, () => { - it(`should have expected exports`, () => { - assert.equal(typeof program.createDataset, `function`); - assert.equal(typeof program.deleteDataset, `function`); - assert.equal(typeof program.listDatasets, `function`); - assert.equal(typeof program.getDatasetSize, `function`); - }); -}); diff --git a/bigquery/test/queries.test.js b/bigquery/test/queries.test.js deleted file mode 100644 index 468456546d..0000000000 --- a/bigquery/test/queries.test.js +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright 2016, Google, Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -const program = require(`../queries`); - -describe(`bigquery:queries`, () => { - it(`should have expected exports`, () => { - assert.equal(typeof program.queryShakespeare, `function`); - assert.equal(typeof program.syncQuery, `function`); - assert.equal(typeof program.asyncQuery, `function`); - }); -}); diff --git a/bigquery/test/quickstart.test.js b/bigquery/test/quickstart.test.js deleted file mode 100644 index d862dceed1..0000000000 --- a/bigquery/test/quickstart.test.js +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright 2016, Google, Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -const proxyquire = require(`proxyquire`).noCallThru(); - -describe(`bigquery:quickstart`, () => { - let bigqueryMock, BigqueryMock; - const error = new Error(`error`); - - before(() => { - bigqueryMock = { - createDataset: sinon.stub().returns(Promise.reject(error)) - }; - BigqueryMock = sinon.stub().returns(bigqueryMock); - }); - - it(`should handle error`, () => { - proxyquire(`../quickstart`, { - '@google-cloud/bigquery': BigqueryMock - }); - - assert.equal(BigqueryMock.calledOnce, true); - assert.deepEqual(BigqueryMock.firstCall.args, [{ projectId: 'YOUR_PROJECT_ID' }]); - assert.equal(bigqueryMock.createDataset.calledOnce, true); - assert.deepEqual(bigqueryMock.createDataset.firstCall.args, ['my_new_dataset']); - }); -}); diff --git a/bigquery/test/tables.test.js b/bigquery/test/tables.test.js deleted file mode 100644 index f39404cf94..0000000000 --- a/bigquery/test/tables.test.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright 2016, Google, Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -const program = require(`../tables`); - -describe(`bigquery:tables`, () => { - it(`should have expected exports`, () => { - assert.equal(typeof program.createTable, `function`); - assert.equal(typeof program.deleteTable, `function`); - assert.equal(typeof program.listTables, `function`); - assert.equal(typeof program.browseRows, `function`); - assert.equal(typeof program.browseRows, `function`); - assert.equal(typeof program.importLocalFile, `function`); - assert.equal(typeof program.importFileFromGCS, `function`); - assert.equal(typeof program.exportTableToGCS, `function`); - assert.equal(typeof program.insertRowsAsStream, `function`); - assert.equal(typeof program.copyTable, `function`); - }); -}); diff --git a/computeengine/package.json b/computeengine/package.json index f568ba5229..31ef0205c3 100644 --- a/computeengine/package.json +++ b/computeengine/package.json @@ -5,8 +5,8 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "scripts": { - "test": "mocha -R spec -t 120000 --require intelli-espower-loader ../test/_setup.js test/*.test.js", - "system-test": "mocha -R spec -t 120000 --require intelli-espower-loader ../system-test/_setup.js system-test/*.test.js" + "test": "cd ..; npm run t -- computeengine/test/*.test.js", + "system-test": "cd ..; npm run t -- computeengine/system-test/*.test.js" }, "dependencies": { "@google-cloud/compute": "0.4.0", @@ -14,8 +14,5 @@ "nodemailer": "^2.4.1", "nodemailer-smtp-transport": "^2.5.0", "sendgrid": "^4.0.1" - }, - "devDependencies": { - "mocha": "^3.0.2" } } diff --git a/computeengine/system-test/mailjet.test.js b/computeengine/system-test/mailjet.test.js deleted file mode 100644 index 1887d6a08f..0000000000 --- a/computeengine/system-test/mailjet.test.js +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -'use strict'; - -describe('computeengine:mailjet', function () { - it('should be tested'); -}); diff --git a/computeengine/system-test/sendgrid.test.js b/computeengine/system-test/sendgrid.test.js deleted file mode 100644 index 15347ecd4e..0000000000 --- a/computeengine/system-test/sendgrid.test.js +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -'use strict'; - -describe('computeengine:sendgrid', function () { - it('should be tested'); -}); diff --git a/computeengine/system-test/vms.test.js b/computeengine/system-test/vms.test.js index 4d1888b163..5a2c6b39ec 100644 --- a/computeengine/system-test/vms.test.js +++ b/computeengine/system-test/vms.test.js @@ -13,15 +13,18 @@ 'use strict'; -var vmsExample = require('../vms'); +require(`../../system-test/_setup`); -describe('computeengine:vms', function () { - it('should retrieve vms', function (done) { - vmsExample.main(function (err, result) { - assert.ifError(err); - assert(result); - assert(Array.isArray(result)); - done(); - }); +const vmsExample = require(`../vms`); + +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); + +test.cb(`should retrieve vms`, (t) => { + vmsExample.main((err, result) => { + t.ifError(err); + t.truthy(result); + t.true(Array.isArray(result)); + t.end(); }); }); diff --git a/computeengine/system-test/vms_api.test.js b/computeengine/system-test/vms_api.test.js index d7749bb569..ad641461ec 100644 --- a/computeengine/system-test/vms_api.test.js +++ b/computeengine/system-test/vms_api.test.js @@ -13,14 +13,17 @@ 'use strict'; -var vmsExample = require('../vms_api'); +require(`../../system-test/_setup`); -describe('computeengine:vms_api', function () { - it('should retrieve vms', function (done) { - vmsExample.main(function (err, result) { - assert.ifError(err); - assert(result); - done(); - }); +const vmsExample = require(`../vms_api`); + +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); + +test.cb('should retrieve vms', (t) => { + vmsExample.main((err, result) => { + t.ifError(err); + t.truthy(result); + t.end(); }); }); diff --git a/computeengine/test/mailjet.test.js b/computeengine/test/mailjet.test.js index 1e9989b97f..2e42a3f5fd 100644 --- a/computeengine/test/mailjet.test.js +++ b/computeengine/test/mailjet.test.js @@ -13,41 +13,44 @@ 'use strict'; -var proxyquire = require('proxyquire').noPreserveCache(); -process.env.MAILJET_API_KEY = 'foo'; -process.env.MAILJET_API_SECRET = 'bar'; +require(`../../test/_setup`); -describe('computeengine:mailjet', function () { - it('should send an email', function (done) { - proxyquire('../mailjet', { - nodemailer: { - createTransport: function (arg) { - assert.equal(arg, 'test'); - return { - sendMail: function (payload, cb) { - assert.deepEqual(payload, { - from: 'ANOTHER_EMAIL@ANOTHER_EXAMPLE.COM', - to: 'EMAIL@EXAMPLE.COM', - subject: 'test email from Node.js on Google Cloud Platform', - text: 'Hello!\n\nThis a test email from Node.js.' - }); - cb('done'); - done(); - } - }; - } - }, - 'nodemailer-smtp-transport': function (options) { - assert.deepEqual(options, { - host: 'in.mailjet.com', - port: 2525, - auth: { - user: 'foo', - pass: 'bar' +const proxyquire = require(`proxyquire`).noPreserveCache(); +process.env.MAILJET_API_KEY = `foo`; +process.env.MAILJET_API_SECRET = `bar`; + +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); + +test.cb(`should send an email`, (t) => { + proxyquire(`../mailjet`, { + nodemailer: { + createTransport: (arg) => { + t.is(arg, `test`); + return { + sendMail: (payload, cb) => { + t.deepEqual(payload, { + from: `ANOTHER_EMAIL@ANOTHER_EXAMPLE.COM`, + to: `EMAIL@EXAMPLE.COM`, + subject: `test email from Node.js on Google Cloud Platform`, + text: `Hello!\n\nThis a test email from Node.js.` + }); + cb(`done`); + t.end(); } - }); - return 'test'; + }; } - }); + }, + 'nodemailer-smtp-transport': (options) => { + t.deepEqual(options, { + host: `in.mailjet.com`, + port: 2525, + auth: { + user: `foo`, + pass: `bar` + } + }); + return `test`; + } }); }); diff --git a/computeengine/test/sendgrid.test.js b/computeengine/test/sendgrid.test.js index 1cf8d676af..124539ae06 100644 --- a/computeengine/test/sendgrid.test.js +++ b/computeengine/test/sendgrid.test.js @@ -13,38 +13,39 @@ 'use strict'; -var proxyquire = require('proxyquire').noPreserveCache(); -process.env.SENDGRID_API_KEY = 'foo'; +require(`../../test/_setup`); -describe('computeengine:sendgrid', function () { - it('should send an email', function (done) { - proxyquire('../sendgrid', { - sendgrid: function (key) { - assert.equal(key, 'foo'); - return { - emptyRequest: function (x) { - return x; - }, - API: function (request, cb) { - assert.deepEqual(request, { - method: 'POST', - path: '/v3/mail/send', - body: { - personalizations: [{ - to: [{ email: 'to_email@example.com' }], - subject: 'Sendgrid test email from Node.js on Google Cloud Platform' - }], - from: { email: 'from_email@example.com' }, - content: [{ - type: 'text/plain', - value: 'Hello!\n\nThis a Sendgrid test email from Node.js on Google Cloud Platform.' - }] - } - }); - done(); - } - }; - } - }); +const proxyquire = require(`proxyquire`).noPreserveCache(); +process.env.SENDGRID_API_KEY = `foo`; + +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); + +test.cb(`should send an email`, (t) => { + proxyquire(`../sendgrid`, { + sendgrid: (key) => { + t.is(key, `foo`); + return { + emptyRequest: (x) => x, + API: (request, cb) => { + t.deepEqual(request, { + method: `POST`, + path: `/v3/mail/send`, + body: { + personalizations: [{ + to: [{ email: `to_email@example.com` }], + subject: `Sendgrid test email from Node.js on Google Cloud Platform` + }], + from: { email: `from_email@example.com` }, + content: [{ + type: `text/plain`, + value: `Hello!\n\nThis a Sendgrid test email from Node.js on Google Cloud Platform.` + }] + } + }); + t.end(); + } + }; + } }); }); diff --git a/computeengine/test/vms.test.js b/computeengine/test/vms.test.js deleted file mode 100644 index 1374d33def..0000000000 --- a/computeengine/test/vms.test.js +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -'use strict'; - -describe('computeengine:vms', function () { - it('should be tested'); -}); diff --git a/computeengine/test/vms_api.test.js b/computeengine/test/vms_api.test.js deleted file mode 100644 index ca47b156f9..0000000000 --- a/computeengine/test/vms_api.test.js +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -'use strict'; - -describe('computeengine:vms_api', function () { - it('should be tested'); -}); diff --git a/datastore/concepts.js b/datastore/concepts.js index ccf1f79a06..31d6236cac 100644 --- a/datastore/concepts.js +++ b/datastore/concepts.js @@ -15,7 +15,6 @@ 'use strict'; -const assert = require('power-assert'); // By default, the client will authenticate using the service account file // specified by the GOOGLE_APPLICATION_CREDENTIALS environment variable and use // the project specified by the GCLOUD_PROJECT environment variable. See @@ -436,7 +435,7 @@ class Index extends TestHelper { return this.datastore.runQuery(query); } - testExplodingProperties () { + testExplodingProperties (t) { const original = datastore.key; datastore.key = this.datastore.key; @@ -464,14 +463,14 @@ class Index extends TestHelper { return this.datastore.save(task) .then(() => { - assert(task.key); - assert(task.key.id); + t.truthy(task.key); + t.truthy(task.key.id); }); } } class Metadata extends TestHelper { - testNamespaceRunQuery () { + testNamespaceRunQuery (t) { const datastore = this.datastore; const startNamespace = 'Animals'; @@ -511,11 +510,11 @@ class Metadata extends TestHelper { return runNamespaceQuery(startNamespace, endNamespace); }) .then((namespaces) => { - assert.deepEqual(namespaces, ['Animals']); + t.deepEqual(namespaces, ['Animals']); }); } - testKindRunQuery () { + testKindRunQuery (t) { const datastore = this.datastore; // [START kind_run_query] @@ -538,11 +537,11 @@ class Metadata extends TestHelper { return runKindQuery() .then((kinds) => { - assert.equal(kinds.includes('Account'), true); + t.true(kinds.includes('Account')); }); } - testPropertyRunQuery () { + testPropertyRunQuery (t) { const datastore = this.datastore; // [START property_run_query] @@ -576,11 +575,11 @@ class Metadata extends TestHelper { return runPropertyQuery() .then((propertiesByKind) => { - assert.deepEqual(propertiesByKind.Account, ['balance']); + t.deepEqual(propertiesByKind.Account, ['balance']); }); } - testPropertyByKindRunQuery () { + testPropertyByKindRunQuery (t) { const datastore = this.datastore; // [START property_by_kind_run_query] @@ -616,7 +615,7 @@ class Metadata extends TestHelper { return runPropertyByKindQuery() .then((propertiesByKind) => { - assert.deepEqual(propertiesByKind, { + t.deepEqual(propertiesByKind, { balance: ['INT64'] }); }); @@ -951,7 +950,7 @@ class Query extends TestHelper { return this.datastore.runQuery(query); } - testCursorPaging () { + testCursorPaging (t) { const datastore = this.datastore; const pageSize = 1; @@ -992,7 +991,7 @@ class Query extends TestHelper { return runPageQuery() .then((results) => { const entities = results[0]; - assert.equal(Array.isArray(entities), true); + t.true(Array.isArray(entities)); const info = results[1]; if (!info || !info.endCursor) { throw new Error('An `info` with an `endCursor` is not present.'); @@ -1060,7 +1059,7 @@ class Transaction extends TestHelper { return this.datastore.save(entities); } - testTransactionalUpdate () { + testTransactionalUpdate (t) { const fromKey = this.fromKey; const toKey = this.toKey; const originalBalance = this.originalBalance; @@ -1080,8 +1079,8 @@ class Transaction extends TestHelper { const accounts = results.map((result) => result[0]); // Restore `datastore` to the mock API. datastore = datastoreMock; - assert.equal(accounts[0].balance, originalBalance - amountToTransfer); - assert.equal(accounts[1].balance, originalBalance + amountToTransfer); + t.is(accounts[0].balance, originalBalance - amountToTransfer); + t.is(accounts[1].balance, originalBalance + amountToTransfer); }) .catch((err) => { // Restore `datastore` to the mock API. @@ -1141,7 +1140,7 @@ class Transaction extends TestHelper { }); } - testTransactionalGetOrCreate () { + testTransactionalGetOrCreate (t) { const taskKey = this.datastore.key(['Task', Date.now()]); // Overwrite so the real Datastore instance is used in `transferFunds`. @@ -1177,11 +1176,11 @@ class Transaction extends TestHelper { return getOrCreate(taskKey, {}) .then((task) => { - assert(task, 'Should have a task.'); + t.truthy(task, 'Should have a task.'); return getOrCreate(taskKey, {}); }) .then((task) => { - assert(task, 'Should have a task.'); + t.truthy(task, 'Should have a task.'); // Restore `datastore` to the mock API. datastore = datastoreMock; }) @@ -1192,7 +1191,7 @@ class Transaction extends TestHelper { }); } - testSingleEntityGroupReadOnly () { + testSingleEntityGroupReadOnly (t) { // Overwrite so the real Datastore instance is used in `transferFunds`. const datastoreMock = datastore; datastore = this.datastore; @@ -1225,8 +1224,8 @@ class Transaction extends TestHelper { .then((results) => { // Restore `datastore` to the mock API. datastore = datastoreMock; - assert.equal(results.length, 2); - assert.equal(Array.isArray(results[1]), true); + t.is(results.length, 2); + t.true(Array.isArray(results[1])); }, (err) => { // Restore `datastore` to the mock API. datastore = datastoreMock; diff --git a/datastore/system-test/concepts.test.js b/datastore/system-test/concepts.test.js index 2365dae13c..411c74ff56 100644 --- a/datastore/system-test/concepts.test.js +++ b/datastore/system-test/concepts.test.js @@ -13,10 +13,10 @@ * limitations under the License. */ - 'use strict'; -const assert = require(`power-assert`); +require(`../../system-test/_setup`); + const concepts = require(`../concepts`); let transaction; @@ -31,119 +31,111 @@ const Index = concepts.Index; const Entity = concepts.Entity; const Query = concepts.Query; -describe(`datastore:concepts`, () => { - before(() => { - const projectId = process.env.GCLOUD_PROJECT; - assert.equal(!!projectId, true, `You must set the GCLOUD_PROJECT env var!`); - transaction = new Transaction(projectId); - metadata = new Metadata(projectId); - index = new Index(projectId); - entity = new Entity(projectId); - query = new Query(projectId); - }); +test.before((t) => { + const projectId = process.env.GCLOUD_PROJECT; + t.truthy(projectId, `You must set the GCLOUD_PROJECT env var!`); + transaction = new Transaction(projectId); + metadata = new Metadata(projectId); + index = new Index(projectId); + entity = new Entity(projectId); + query = new Query(projectId); +}); - after(() => { - const datastore = transaction.datastore; - const query = datastore.createQuery(`Task`).select(`__key__`); - return datastore.runQuery(query) - .then((results) => datastore.delete(results[0].map((entity) => entity[datastore.KEY]))); - }); +test.after(async () => { + const datastore = transaction.datastore; + const query = datastore.createQuery(`Task`).select(`__key__`); + const [entities] = await datastore.runQuery(query); + await datastore.delete(entities.map((entity) => entity[datastore.KEY])); +}); - describe(`Transactions`, () => { - it(`performs a transactional update`, () => transaction.testTransactionalUpdate()); - it(`performs retries if necessary`, () => transaction.testTransactionalRetry()); - it(`performs a get or create`, () => transaction.testTransactionalGetOrCreate()); - it(`gets a snapshot of task list entities`, () => transaction.testSingleEntityGroupReadOnly()); - }); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); - describe(`Metadata`, () => { - it(`performs a namespace query`, () => metadata.testNamespaceRunQuery()); - it(`performs a kind query`, () => metadata.testKindRunQuery()); - it(`performs a property query`, () => metadata.testPropertyRunQuery()); - it(`performs a property by kind query`, () => metadata.testPropertyByKindRunQuery()); - }); +// Transactions +test.serial(`performs a transactional update`, (t) => transaction.testTransactionalUpdate(t)); +test.serial(`performs retries if necessary`, (t) => transaction.testTransactionalRetry(t)); +test.serial(`performs a get or create`, (t) => transaction.testTransactionalGetOrCreate(t)); +test.serial(`gets a snapshot of task list entities`, (t) => transaction.testSingleEntityGroupReadOnly(t)); - describe(`Indexes`, () => { - it(`performs a query with a filter on an unindexed property`, () => index.testUnindexedPropertyQuery()); - it(`inserts arrays of data`, () => index.testExplodingProperties()); - }); +// Metadata +test.serial(`performs a namespace query`, (t) => metadata.testNamespaceRunQuery(t)); +test.serial(`performs a kind query`, (t) => metadata.testKindRunQuery(t)); +test.serial(`performs a property query`, (t) => metadata.testPropertyRunQuery(t)); +test.serial(`performs a property by kind query`, (t) => metadata.testPropertyByKindRunQuery(t)); - describe(`Queries`, () => { - it(`performs a basic query`, () => query.testRunQuery()); - it(`performs a query with a property filter`, () => query.testPropertyFilter()); - it(`performs a query with a composite filter`, () => query.testCompositeFilter()); - it(`performs a query with a key filter`, () => query.testKeyFilter()); - it(`performs a query with ascending sort`, () => query.testAscendingSort()); - it(`performs a query with descending sort`, () => query.testDescendingSort()); - it(`performs a query with multi sort`, () => query.testMultiSort()); - it(`performs a kindless query`, () => query.testKindlessQuery()); - it('performs a projection query', () => { - return entity.testProperties() - .then(() => { - return new Promise((resolve, reject) => { - setTimeout(function () { - query.testRunQueryProjection().then(resolve, reject); - }, 1000); - }); - }) - .then((results) => { - assert.deepEqual(results, { - priorities: [4], - percentCompletes: [10] - }); - }); - }); - it(`performs a keys only query`, () => query.testKeysOnlyQuery()); - it(`performs a distinct query`, () => query.testDistinctQuery()); - it(`performs a distinct on query`, () => query.testDistinctOnQuery()); - it(`performs an array value inequality query`, () => query.testArrayValueInequalityRange()); - it(`performs an array value equality query`, () => query.testArrayValueEquality()); - it(`performs an inequality range query`, () => query.testInequalityRange()); - it(`returns an error from an invalid query`, () => { - return query.testInequalityInvalid() - .then(() => assert.fail(), (err) => assert(err)); - }); - it(`performs an equal and inequality range query`, () => query.testEqualAndInequalityRange()); - it(`performs an equality sort query`, () => query.testInequalitySort()); - it(`returns an error when not sorted on filtered property`, () => { - return query.testInequalitySortInvalidNotSame() - .then(() => assert.fail(), (err) => assert(err)); - }); - it(`returns an error when not sorted on first filter prop`, () => { - return query.testInequalitySortInvalidNotFirst() - .then(() => assert.fail(), (err) => assert(err)); +// Indexes +test.serial(`performs a query with a filter on an unindexed property`, (t) => index.testUnindexedPropertyQuery(t)); +test.serial(`inserts arrays of data`, (t) => index.testExplodingProperties(t)); + +// Queries +test.serial(`performs a basic query`, (t) => query.testRunQuery(t)); +test.serial(`performs a query with a property filter`, (t) => query.testPropertyFilter(t)); +test.serial(`performs a query with a composite filter`, (t) => query.testCompositeFilter(t)); +test.serial(`performs a query with a key filter`, (t) => query.testKeyFilter(t)); +test.serial(`performs a query with ascending sort`, (t) => query.testAscendingSort(t)); +test.serial(`performs a query with descending sort`, (t) => query.testDescendingSort(t)); +test.serial(`performs a query with multi sort`, (t) => query.testMultiSort(t)); +test.serial(`performs a kindless query`, (t) => query.testKindlessQuery(t)); +test.serial('performs a projection query', (t) => { + return entity.testProperties(t) + .then(() => { + return new Promise((resolve, reject) => { + setTimeout(() => { + query.testRunQueryProjection(t).then(resolve, reject); + }, 1000); + }); + }) + .then((results) => { + t.deepEqual(results, { + priorities: [4], + percentCompletes: [10] + }); }); - it(`performs a query with a limit`, () => query.testLimit()); - it(`allows manual pagination through results`, () => { - return entity.testBatchUpsert() - .then(() => { - return new Promise((resolve, reject) => { - setTimeout(() => { - query.testCursorPaging() - .then(resolve, reject); - }, 1000); - }); - }); +}); +test.serial(`performs a keys only query`, (t) => query.testKeysOnlyQuery(t)); +test.serial(`performs a distinct query`, (t) => query.testDistinctQuery(t)); +test.serial(`performs a distinct on query`, (t) => query.testDistinctOnQuery(t)); +test.serial(`performs an array value inequality query`, (t) => query.testArrayValueInequalityRange(t)); +test.serial(`performs an array value equality query`, (t) => query.testArrayValueEquality(t)); +test.serial(`performs an inequality range query`, (t) => query.testInequalityRange(t)); +test.serial(`returns an error from an invalid query`, async (t) => { + await t.throws(query.testInequalityInvalid(t)); +}); +test.serial(`performs an equal and inequality range query`, (t) => query.testEqualAndInequalityRange(t)); +test.serial(`performs an equality sort query`, (t) => query.testInequalitySort(t)); +test.serial(`returns an error when not sorted on filtered property`, async (t) => { + await t.throws(query.testInequalitySortInvalidNotSame(t)); +}); +test.serial(`returns an error when not sorted on first filter prop`, async (t) => { + await t.throws(query.testInequalitySortInvalidNotFirst(t)); +}); +test.serial(`performs a query with a limit`, (t) => query.testLimit(t)); +test.serial(`allows manual pagination through results`, (t) => { + return entity.testBatchUpsert(t) + .then(() => { + return new Promise((resolve, reject) => { + setTimeout(() => { + query.testCursorPaging(t).then(resolve, reject); + }, 1000); + }); }); - it(`performs an ancestor query`, () => query.testEventualConsistentQuery()); - }); - - describe(`Entities`, () => { - it(`saves with an incomplete key`, () => entity.testIncompleteKey()); - it(`saves with a named key`, () => entity.testNamedKey()); - it(`saves a key with a parent`, () => entity.testKeyWithParent()); - it(`saves a key with multiple parents`, () => entity.testKeyWithMultiLevelParent()); - it(`saves an entity with a parent`, () => entity.testEntityWithParent()); - it(`saves an entity with properties`, () => entity.testProperties()); - it(`saves an entity with arrays`, () => entity.testArrayValue()); - it(`saves a basic entity`, () => entity.testBasicEntity()); - it(`saves with an upsert`, () => entity.testUpsert()); - it(`saves with an insert`, () => entity.testInsert()); - it(`performs a lookup`, () => entity.testLookup()); - it(`saves with an update`, () => entity.testUpdate()); - it(`deletes an entity`, () => entity.testDelete()); - it(`performs a batch upsert`, () => entity.testBatchUpsert()); - it(`performs a batch lookup`, () => entity.testBatchLookup()); - it(`performs a batch delete`, () => entity.testBatchDelete()); - }); }); +test.serial(`performs an ancestor query`, (t) => query.testEventualConsistentQuery(t)); + +// Entities +test.serial(`saves with an incomplete key`, (t) => entity.testIncompleteKey(t)); +test.serial(`saves with a named key`, (t) => entity.testNamedKey(t)); +test.serial(`saves a key with a parent`, (t) => entity.testKeyWithParent(t)); +test.serial(`saves a key with multiple parents`, (t) => entity.testKeyWithMultiLevelParent(t)); +test.serial(`saves an entity with a parent`, (t) => entity.testEntityWithParent(t)); +test.serial(`saves an entity with properties`, (t) => entity.testProperties(t)); +test.serial(`saves an entity with arrays`, (t) => entity.testArrayValue(t)); +test.serial(`saves a basic entity`, (t) => entity.testBasicEntity(t)); +test.serial(`saves with an upsert`, (t) => entity.testUpsert(t)); +test.serial(`saves with an insert`, (t) => entity.testInsert(t)); +test.serial(`performs a lookup`, (t) => entity.testLookup(t)); +test.serial(`saves with an update`, (t) => entity.testUpdate(t)); +test.serial(`deletes an entity`, (t) => entity.testDelete(t)); +test.serial(`performs a batch upsert`, (t) => entity.testBatchUpsert(t)); +test.serial(`performs a batch lookup`, (t) => entity.testBatchLookup(t)); +test.serial(`performs a batch delete`, (t) => entity.testBatchDelete(t)); diff --git a/datastore/system-test/error.test.js b/datastore/system-test/error.test.js index 578ec64c87..cab26d40ef 100644 --- a/datastore/system-test/error.test.js +++ b/datastore/system-test/error.test.js @@ -15,17 +15,15 @@ 'use strict'; +require(`../../system-test/_setup`); + const error = require('../error'); -describe(`datastore:error`, () => { - it(`should have an error`, () => { - return error.runQuery() - .then(() => { - assert.fail(`should have failed!`); - }) - .catch((err) => { - assert(err); - assert.equal(err.code, 400); - }); - }); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); + +test(`should have an error`, async (t) => { + const err = await t.throws(error.runQuery()); + t.truthy(err); + t.is(err.code, 400); }); diff --git a/datastore/system-test/quickstart.test.js b/datastore/system-test/quickstart.test.js index 38522bb4ea..4ad5cc9a8d 100644 --- a/datastore/system-test/quickstart.test.js +++ b/datastore/system-test/quickstart.test.js @@ -15,6 +15,8 @@ 'use strict'; +require(`../../system-test/_setup`); + const proxyquire = require(`proxyquire`).noPreserveCache(); const datastore = proxyquire(`@google-cloud/datastore`, {})(); const entity = { description: `Buy milk` }; @@ -22,37 +24,45 @@ const kind = `Task`; const name = `sampletask1`; const key = datastore.key([kind, name]); -describe(`datastore:quickstart`, () => { - before(() => datastore.delete(key).catch(() => {})); - after(() => datastore.delete(key).catch(() => {})); - - it(`should get a task from Datastore`, (done) => { - const datastoreMock = { - key: (...args) => datastore.key(...args), - - save: (_task) => { - assert.equal(_task.key.kind, kind); - assert.equal(_task.key.name, name); - assert.deepEqual(_task.data, entity); - - return datastore.save(_task) - .then(() => { - setTimeout(() => { - datastore.get(key) - .then((results) => { - const task = results[0]; - assert.deepEqual(task, entity); - assert.equal(console.log.calledWith(`Saved ${name}: ${entity.description}`), true); - done(); - }) - .catch(done); - }, 200); - }, done); - } - }; - - proxyquire(`../quickstart`, { - '@google-cloud/datastore': sinon.stub().returns(datastoreMock) - }); +test.before(async () => { + try { + await datastore.delete(key); + } catch (err) {} // ignore error +}); +test.after(async () => { + try { + await datastore.delete(key); + } catch (err) {} // ignore error +}); + +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); + +test.cb(`should get a task from Datastore`, (t) => { + const datastoreMock = { + key: (...args) => datastore.key(...args), + + save: (_task) => { + t.is(_task.key.kind, kind); + t.is(_task.key.name, name); + t.deepEqual(_task.data, entity); + + return datastore.save(_task) + .then(() => { + setTimeout(() => { + datastore.get(key) + .then(([task]) => { + t.deepEqual(task, entity); + t.true(console.log.calledWith(`Saved ${name}: ${entity.description}`)); + t.end(); + }) + .catch(t.end); + }, 200); + }, t.end); + } + }; + + proxyquire(`../quickstart`, { + '@google-cloud/datastore': sinon.stub().returns(datastoreMock) }); }); diff --git a/datastore/system-test/tasks.test.js b/datastore/system-test/tasks.test.js index 1d4913a999..3da66a11d5 100644 --- a/datastore/system-test/tasks.test.js +++ b/datastore/system-test/tasks.test.js @@ -15,54 +15,54 @@ 'use strict'; +require(`../../system-test/_setup`); + const path = require(`path`); const datastore = require(`@google-cloud/datastore`)(); -const run = require(`../../utils`).run; const cmd = `node tasks.js`; const cwd = path.join(__dirname, `..`); -describe(`datastore:tasks`, () => { - const description = `description`; - let key; +const description = `description`; +let key; + +test.after(async () => { + try { + await datastore.delete(key); + } catch (err) {} // ignore error +}); - after(() => datastore.delete(key).catch(() => {})); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); - it(`should add a task`, () => { - const expected = /^Task (\d+) created successfully.$/; - const parts = run(`${cmd} new "${description}"`, cwd).match(expected); - assert.equal(expected.test(parts[0]), true); - return datastore.get(datastore.key([`Task`, parseInt(parts[1], 10)])) - .then((results) => { - const task = results[0]; - key = task[datastore.KEY]; - assert.equal(task.description, description); - }); - }); +test.serial(`should add a task`, async (t) => { + const expected = /^Task (\d+) created successfully.$/; + const parts = run(`${cmd} new "${description}"`, cwd).match(expected); + t.true(expected.test(parts[0])); + const [task] = await datastore.get(datastore.key([`Task`, parseInt(parts[1], 10)])); + key = task[datastore.KEY]; + t.is(task.description, description); +}); - it(`should mark a task as done`, () => { - const expected = `Task ${key.id} updated successfully.`; - assert.equal(run(`${cmd} done ${key.id}`, cwd), expected); - return datastore.get(key) - .then((results) => { - assert.equal(results[0].done, true); - }); - }); +test.serial(`should mark a task as done`, async (t) => { + const expected = `Task ${key.id} updated successfully.`; + const output = await runAsync(`${cmd} done ${key.id}`, cwd); + t.is(output, expected); + const [task] = await datastore.get(key); + t.true(task.done); +}); - it(`should list tasks`, (done) => { - setTimeout(() => { - const output = run(`${cmd} list`, cwd); - assert.equal(output.includes(key.id), true); - done(); - }, 5000); - }); +test.serial(`should list tasks`, async (t) => { + await tryTest(async () => { + const output = await runAsync(`${cmd} list`, cwd); + t.true(output.includes(key.id)); + }).start(); +}); - it(`should delete a task`, () => { - const expected = `Task ${key.id} deleted successfully.`; - assert.equal(run(`${cmd} delete ${key.id}`, cwd), expected); - return datastore.get(key) - .then((results) => { - assert.equal(results[0], undefined); - }); - }); +test.serial(`should delete a task`, async (t) => { + const expected = `Task ${key.id} deleted successfully.`; + const output = await runAsync(`${cmd} delete ${key.id}`, cwd); + t.is(output, expected); + const [task] = await datastore.get(key); + t.is(task, undefined); }); diff --git a/debugger/package.json b/debugger/package.json index 32246bed4d..12516ae8a5 100644 --- a/debugger/package.json +++ b/debugger/package.json @@ -8,14 +8,10 @@ "node": ">=4.3.2" }, "scripts": { - "start": "node app.js", - "test": "mocha -R spec -t 120000 --require intelli-espower-loader ../test/_setup.js test/*.test.js" + "start": "node app.js" }, "dependencies": { "@google/cloud-debug": "^0.8.3", "express": "^4.13.4" - }, - "devDependencies": { - "mocha": "^2.5.3" } } diff --git a/debugger/test/app.test.js b/debugger/test/app.test.js deleted file mode 100644 index 0bbbd70d41..0000000000 --- a/debugger/test/app.test.js +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -'use strict'; - -describe('debugger', function () { - it('should be tested'); -}); diff --git a/dns/package.json b/dns/package.json index 4162b5bbbe..ab1c527722 100644 --- a/dns/package.json +++ b/dns/package.json @@ -5,8 +5,7 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "scripts": { - "test": "cd ..; npm run t -- dns/test/*.test.js", - "system-test": "cd ..; npm run st -- dns/system-test/*.test.js" + "test": "cd ..; npm run st -- dns/system-test/*.test.js" }, "dependencies": { "@google-cloud/dns": "0.4.0", diff --git a/dns/quickstart.js b/dns/quickstart.js index fd657ba3fc..f686c389dd 100644 --- a/dns/quickstart.js +++ b/dns/quickstart.js @@ -28,13 +28,11 @@ const dnsClient = DNS({ }); // Lists all zones in the current project -dnsClient.getZones((err, zones) => { - if (err) { - console.error(err); - return; - } +dnsClient.getZones() + .then((results) => { + const zones = results[0]; - console.log('Zones:'); - zones.forEach((zone) => console.log(zone.name)); -}); + console.log('Zones:'); + zones.forEach((zone) => console.log(zone.name)); + }); // [END dns_quickstart] diff --git a/dns/system-test/quickstart.test.js b/dns/system-test/quickstart.test.js index 897728dad7..cab7253d9f 100644 --- a/dns/system-test/quickstart.test.js +++ b/dns/system-test/quickstart.test.js @@ -15,53 +15,58 @@ 'use strict'; +require(`../../system-test/_setup`); + const proxyquire = require(`proxyquire`).noPreserveCache(); const dns = proxyquire(`@google-cloud/dns`, {})(); const uuid = require(`uuid`); const zoneName = `test-${uuid().substring(0, 13)}`; -describe(`dns:quickstart`, () => { - let dnsMock, DNSMock; - - before((done) => { - dns.createZone(zoneName, { - dnsName: `${process.env.GCLOUD_PROJECT}.appspot.com.` - }, done); +test.before(async () => { + await dns.createZone(zoneName, { + dnsName: `${process.env.GCLOUD_PROJECT}.appspot.com.` }); +}); - after((done) => { - dns.zone(zoneName).delete(() => { - // Ignore error - done(); - }); - }); +test.after(async () => { + try { + await dns.zone(zoneName).delete(); + } catch (err) {} // ignore error +}); + +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); - it(`should list zones`, (done) => { - dnsMock = { - getZones: (_callback) => { - assert.equal(typeof _callback, 'function'); +test.cb(`should list zones`, (t) => { + const dnsMock = { + getZones: () => { + return dns.getZones() + .then(([zones]) => { + t.true(Array.isArray(zones)); - // Listing is eventually consistent, give the indexes time to update - setTimeout(() => { - dns.getZones((err, zones) => { - _callback(err, zones); - assert.ifError(err); - assert.equal(Array.isArray(zones), true); - assert.equal(console.log.called, true); - assert.deepEqual(console.log.firstCall.args, [`Zones:`]); - zones.forEach((zone, i) => { - assert.deepEqual(console.log.getCall(i + 1).args, [zone.name]); - }); - done(); - }); - }, 5000); - } - }; - DNSMock = sinon.stub().returns(dnsMock); + // Listing is eventually consistent, give the indexes time to update + setTimeout(() => { + try { + t.true(console.log.called); + t.deepEqual(console.log.getCall(0).args, [`Zones:`]); + zones.forEach((zone, i) => { + t.deepEqual(console.log.getCall(i + 1).args, [zone.name]); + }); + t.end(); + } catch (err) { + t.end(err); + } + }, 200); + return [zones]; + }); + } + }; + + setTimeout(() => { proxyquire(`../quickstart`, { - '@google-cloud/dns': DNSMock + '@google-cloud/dns': sinon.stub().returns(dnsMock) }); - }); + }, 5000); }); diff --git a/dns/system-test/zones.test.js b/dns/system-test/zones.test.js index 3041dadaad..a13057e1b5 100644 --- a/dns/system-test/zones.test.js +++ b/dns/system-test/zones.test.js @@ -15,8 +15,9 @@ 'use strict'; +require(`../../system-test/_setup`); + const path = require(`path`); -const run = require(`../../utils`).run; const dns = require(`@google-cloud/dns`)(); const uuid = require(`uuid`); @@ -24,27 +25,29 @@ const zoneName = `test-${uuid().substr(0, 13)}`; const cwd = path.join(__dirname, `..`); const cmd = `node zones.js`; -describe(`dns:zones`, () => { - before((done) => { - dns.createZone(zoneName, { - dnsName: `${process.env.GCLOUD_PROJECT}.appspot.com.` - }, done); +test.before(async () => { + await dns.createZone(zoneName, { + dnsName: `${process.env.GCLOUD_PROJECT}.appspot.com.` }); +}); - after((done) => { - dns.zone(zoneName).delete(() => { - // Ignore error - done(); - }); - }); +test.after(async () => { + try { + await dns.zone(zoneName).delete(); + } catch (err) {} // ignore error +}); - it(`should list zones`, (done) => { - // Listing is eventually consistent, give the indexes time to update - setTimeout(() => { - const output = run(`${cmd} list`, cwd); - assert.notEqual(output.indexOf(`Zones:`), -1); - assert.notEqual(output.indexOf(zoneName), -1); - done(); - }, 5000); - }); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); + +test.cb(`should list zones`, (t) => { + // Listing is eventually consistent, give the indexes time to update + setTimeout(() => { + runAsync(`${cmd} list`, cwd) + .then((output) => { + t.true(output.includes(`Zones:`)); + t.true(output.includes(zoneName)); + t.end(); + }).catch(t.end); + }, 5000); }); diff --git a/dns/test/quickstart.test.js b/dns/test/quickstart.test.js deleted file mode 100644 index cbceb9ecb2..0000000000 --- a/dns/test/quickstart.test.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright 2016, Google, Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -const proxyquire = require(`proxyquire`).noCallThru(); - -describe(`dns:quickstart`, () => { - let dnsMock, DNSMock; - const error = new Error(`error`); - - before(() => { - dnsMock = { - getZones: sinon.stub().yields(error) - }; - DNSMock = sinon.stub().returns(dnsMock); - }); - - it(`should handle error`, () => { - proxyquire(`../quickstart`, { - '@google-cloud/dns': DNSMock - }); - - assert.equal(DNSMock.calledOnce, true); - assert.deepEqual(DNSMock.firstCall.args, [{ projectId: 'YOUR_PROJECT_ID' }]); - assert.equal(dnsMock.getZones.calledOnce, true); - assert.deepEqual(dnsMock.getZones.firstCall.args.slice(0, -1), []); - assert.equal(console.error.calledOnce, true); - assert.deepEqual(console.error.firstCall.args, [error]); - }); -}); diff --git a/dns/test/zones.test.js b/dns/test/zones.test.js deleted file mode 100644 index 0ac1e8a149..0000000000 --- a/dns/test/zones.test.js +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright 2016, Google, Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -const proxyquire = require(`proxyquire`).noCallThru(); - -describe(`dns:zones`, () => { - it(`should handle errors`, () => { - const error = new Error(`error`); - const callback = sinon.spy(); - const dnsMock = { - getZones: sinon.stub().yields(error) - }; - const DNSMock = sinon.stub().returns(dnsMock); - const program = proxyquire(`../zones`, { - '@google-cloud/dns': DNSMock - }); - - program.listZones(callback); - - assert.equal(callback.callCount, 1); - assert.equal(callback.alwaysCalledWithExactly(error), true); - }); -}); diff --git a/dns/zones.js b/dns/zones.js index f36e3514b9..399af7e1e2 100644 --- a/dns/zones.js +++ b/dns/zones.js @@ -18,27 +18,23 @@ const DNS = require('@google-cloud/dns'); // [START dns_list_zones] -function listZones (callback) { +function listZones () { // Instantiates a client const dns = DNS(); // Lists all zones in the current project - dns.getZones((err, zones) => { - if (err) { - callback(err); - return; - } - - console.log('Zones:'); - zones.forEach((zone) => console.log(zone.name)); - callback(); - }); + return dns.getZones() + .then((results) => { + const zones = results[0]; + console.log('Zones:'); + zones.forEach((zone) => console.log(zone.name)); + return zones; + }); } // [END dns_list_zones] // The command-line program -const cli = require('yargs'); -const makeHandler = require('../utils').makeHandler; +const cli = require(`yargs`); const program = module.exports = { listZones: listZones, @@ -50,13 +46,11 @@ const program = module.exports = { cli .demand(1) - .command('list', 'Lists all zones in the current project.', {}, () => { - program.listZones(makeHandler(false)); - }) - .example('node $0 list', 'Lists all zones in the current project.') + .command(`list`, `Lists all zones in the current project.`, {}, program.listZones) + .example(`node $0 list`, `Lists all zones in the current project.`) .wrap(120) .recommendCommands() - .epilogue('For more information, see https://cloud.google.com/dns/docs'); + .epilogue(`For more information, see https://cloud.google.com/dns/docs`); if (module === require.main) { program.main(process.argv.slice(2)); diff --git a/endpoints/getting-started/package.json b/endpoints/getting-started/package.json index 90b02a156f..8bfed46491 100644 --- a/endpoints/getting-started/package.json +++ b/endpoints/getting-started/package.json @@ -10,13 +10,10 @@ }, "scripts": { "start": "node app.js", - "test": "mocha -R spec -t 120000 --require intelli-espower-loader ../../test/_setup.js test/*.test.js" + "test": "cd ..; npm run t -- endpoints/getting-started/test/*.test.js" }, "dependencies": { "express": "^4.13.4", "body-parser": "^1.15.0" - }, - "devDependencies": { - "mocha": "^2.5.3" } } diff --git a/endpoints/getting-started/test/app.test.js b/endpoints/getting-started/test/app.test.js index 1d88c55917..26c423a127 100644 --- a/endpoints/getting-started/test/app.test.js +++ b/endpoints/getting-started/test/app.test.js @@ -13,19 +13,21 @@ 'use strict'; -var express = require('express'); -var path = require('path'); -var proxyquire = require('proxyquire').noPreserveCache(); -var request = require('supertest'); +require(`../../../test/_setup`); -var SAMPLE_PATH = path.join(__dirname, '../app.js'); +const express = require('express'); +const path = require('path'); +const proxyquire = require('proxyquire').noPreserveCache(); +const request = require('supertest'); + +const SAMPLE_PATH = path.join(__dirname, '../app.js'); function getSample () { - var testApp = express(); + const testApp = express(); sinon.stub(testApp, 'listen').callsArg(1); - var expressMock = sinon.stub().returns(testApp); + const expressMock = sinon.stub().returns(testApp); - var app = proxyquire(SAMPLE_PATH, { + const app = proxyquire(SAMPLE_PATH, { express: expressMock }); return { @@ -36,46 +38,37 @@ function getSample () { }; } -describe('appengine/endpoints/app.js', function () { - var sample; - - beforeEach(function () { - sample = getSample(); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); - assert(sample.mocks.express.calledOnce); - assert(sample.app.listen.calledOnce); - assert.equal(sample.app.listen.firstCall.args[0], process.env.PORT || 8080); - }); - - it('should echo a message', function (done) { - request(sample.app) - .post('/echo') - .send({ message: 'foo' }) - .expect(200) - .expect(function (response) { - assert.equal(response.body.message, 'foo'); - }) - .end(done); - }); +test.cb('should echo a message', (t) => { + request(getSample().app) + .post('/echo') + .send({ message: 'foo' }) + .expect(200) + .expect((response) => { + t.is(response.body.message, 'foo'); + }) + .end(t.end); +}); - it('should try to parse encoded info', function (done) { - request(sample.app) - .get('/auth/info/googlejwt') - .expect(200) - .expect(function (response) { - assert.deepEqual(response.body, { id: 'anonymous' }); - }) - .end(done); - }); +test.cb('should try to parse encoded info', (t) => { + request(getSample().app) + .get('/auth/info/googlejwt') + .expect(200) + .expect((response) => { + t.deepEqual(response.body, { id: 'anonymous' }); + }) + .end(t.end); +}); - it('should successfully parse encoded info', function (done) { - request(sample.app) - .get('/auth/info/googlejwt') - .set('X-Endpoint-API-UserInfo', new Buffer(JSON.stringify({ id: 'foo' })).toString('base64')) - .expect(200) - .expect(function (response) { - assert.deepEqual(response.body, { id: 'foo' }); - }) - .end(done); - }); +test.cb('should successfully parse encoded info', (t) => { + request(getSample().app) + .get('/auth/info/googlejwt') + .set('X-Endpoint-API-UserInfo', new Buffer(JSON.stringify({ id: 'foo' })).toString('base64')) + .expect(200) + .expect((response) => { + t.deepEqual(response.body, { id: 'foo' }); + }) + .end(t.end); }); diff --git a/functions/background/package.json b/functions/background/package.json index e9efbd14c6..4404bf98ed 100644 --- a/functions/background/package.json +++ b/functions/background/package.json @@ -11,8 +11,5 @@ "dependencies": { "request": "^2.78.0", "request-promise": "^4.1.1" - }, - "devDependencies": { - "mocha": "^3.1.2" } } diff --git a/functions/background/test/index.test.js b/functions/background/test/index.test.js index aab59f565d..e3324c75af 100644 --- a/functions/background/test/index.test.js +++ b/functions/background/test/index.test.js @@ -15,6 +15,8 @@ 'use strict'; +require(`../../../test/_setup`); + const proxyquire = require(`proxyquire`).noCallThru(); function getSample () { @@ -30,64 +32,65 @@ function getSample () { }; } -describe(`functions:background`, () => { - it(`should echo message`, () => { - const event = { - data: { - myMessage: `hi` - } - }; - const sample = getSample(); - const callback = sinon.stub(); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); - sample.program.helloWorld(event, callback); +test.serial(`should echo message`, (t) => { + const event = { + data: { + myMessage: `hi` + } + }; + const sample = getSample(); + const callback = sinon.stub(); - assert.equal(console.log.callCount, 1); - assert.deepEqual(console.log.firstCall.args, [event.data.myMessage]); - assert.equal(callback.callCount, 1); - assert.deepEqual(callback.firstCall.args, []); - }); + sample.program.helloWorld(event, callback); - it(`should say no message was provided`, () => { - const error = new Error(`No message defined!`); - const callback = sinon.stub(); - const sample = getSample(); - sample.program.helloWorld({ data: {} }, callback); + t.is(console.log.callCount, 1); + t.deepEqual(console.log.firstCall.args, [event.data.myMessage]); + t.is(callback.callCount, 1); + t.deepEqual(callback.firstCall.args, []); +}); - assert.equal(callback.callCount, 1); - assert.deepEqual(callback.firstCall.args, [error]); - }); +test.serial(`should say no message was provided`, (t) => { + const error = new Error(`No message defined!`); + const callback = sinon.stub(); + const sample = getSample(); + sample.program.helloWorld({ data: {} }, callback); - it(`should make a promise request`, () => { - const sample = getSample(); - const event = { - data: { - endpoint: `foo.com` - } - }; + t.is(callback.callCount, 1); + t.deepEqual(callback.firstCall.args, [error]); +}); - return sample.program.helloPromise(event) - .then((result) => { - assert.deepEqual(sample.mocks.requestPromise.firstCall.args, [{ uri: `foo.com` }]); - assert.equal(result, `test`); - }); - }); +test.serial(`should make a promise request`, (t) => { + const sample = getSample(); + const event = { + data: { + endpoint: `foo.com` + } + }; + + return sample.program.helloPromise(event) + .then((result) => { + t.deepEqual(sample.mocks.requestPromise.firstCall.args, [{ uri: `foo.com` }]); + t.is(result, `test`); + }); +}); - it(`should return synchronously`, () => { - assert.equal(getSample().program.helloSynchronous({ +test.serial(`should return synchronously`, (t) => { + t.is(getSample().program.helloSynchronous({ + data: { + something: true + } + }), `Something is true!`); +}); + +test.serial(`should throw an error`, (t) => { + t.throws(() => { + getSample().program.helloSynchronous({ data: { - something: true + something: false } - }), `Something is true!`); - }); - - it(`should throw an error`, () => { - assert.throws(() => { - getSample().program.helloSynchronous({ - data: { - something: false - } - }); - }, Error, `Something was not true!`); - }); + }); + }, Error, `Something was not true!`); }); diff --git a/functions/datastore/index.js b/functions/datastore/index.js index 11dff82e17..48b7a04d18 100644 --- a/functions/datastore/index.js +++ b/functions/datastore/index.js @@ -70,6 +70,7 @@ exports.set = function set (req, res) { .catch((err) => { console.error(err); res.status(500).send(err); + return Promise.reject(err); }); }; @@ -101,6 +102,7 @@ exports.get = function get (req, res) { .catch((err) => { console.error(err); res.status(500).send(err); + return Promise.reject(err); }); }; @@ -125,5 +127,6 @@ exports.del = function del (req, res) { .catch((err) => { console.error(err); res.status(500).send(err); + return Promise.reject(err); }); }; diff --git a/functions/datastore/test/index.test.js b/functions/datastore/test/index.test.js index 76894828cc..11ad0dcd5a 100644 --- a/functions/datastore/test/index.test.js +++ b/functions/datastore/test/index.test.js @@ -15,6 +15,8 @@ 'use strict'; +require(`../../../test/_setup`); + const proxyquire = require(`proxyquire`).noCallThru(); const NAME = `sampletask1`; @@ -65,202 +67,177 @@ function getSample () { }; } -describe(`functions:datastore`, () => { - it(`set: Set fails without a value`, () => { - const expectedMsg = `Value not provided. Make sure you have a "value" property in your request`; - const sample = getSample(); - - assert.throws(() => { - sample.mocks.req.body.value = undefined; - sample.program.set(sample.mocks.req, sample.mocks.res); - }, Error, expectedMsg); - }); - - it(`set: Set fails without a key`, () => { - const expectedMsg = `Key not provided. Make sure you have a "key" property in your request`; - const sample = getSample(); - - assert.throws(() => { - sample.mocks.req.body.key = undefined; - sample.program.set(sample.mocks.req, sample.mocks.res); - }, Error, expectedMsg); - }); - - it(`set: Set fails without a kind`, () => { - const expectedMsg = `Kind not provided. Make sure you have a "kind" property in your request`; - const sample = getSample(); - - assert.throws(() => { - sample.mocks.req.body.kind = undefined; - sample.program.set(sample.mocks.req, sample.mocks.res); - }, Error, expectedMsg); - }); - - it(`set: Handles save error`, () => { - const error = new Error(`error`); - const sample = getSample(); - - sample.mocks.datastore.save.returns(Promise.reject(error)); - - return sample.program.set(sample.mocks.req, sample.mocks.res) - .then(() => { - throw new Error(`Should have failed!`); - }) - .catch((err) => { - assert.deepEqual(err, error); - assert.deepEqual(console.error.callCount, 1); - assert.deepEqual(console.error.firstCall.args, [error]); - assert.deepEqual(sample.mocks.res.status.callCount, 1); - assert.deepEqual(sample.mocks.res.status.firstCall.args, [500]); - assert.deepEqual(sample.mocks.res.send.callCount, 1); - assert.deepEqual(sample.mocks.res.send.firstCall.args, [error]); - }); - }); - - it(`set: Set saves an entity`, () => { - const expectedMsg = `Entity ${KIND}/${NAME} saved.`; - const sample = getSample(); - - return sample.program.set(sample.mocks.req, sample.mocks.res) - .then(() => { - assert.deepEqual(sample.mocks.datastore.save.callCount, 1); - assert.deepEqual(sample.mocks.datastore.save.firstCall.args, [sample.mocks.entity]); - assert.deepEqual(sample.mocks.res.status.callCount, 1); - assert.deepEqual(sample.mocks.res.status.firstCall.args, [200]); - assert.deepEqual(sample.mocks.res.send.callCount, 1); - assert.deepEqual(sample.mocks.res.send.firstCall.args, [expectedMsg]); - }); - }); - - it(`get: Get fails without a key`, () => { - const expectedMsg = `Key not provided. Make sure you have a "key" property in your request`; - const sample = getSample(); - - assert.throws(() => { - sample.mocks.req.body.key = undefined; - sample.program.get(sample.mocks.req, sample.mocks.res); - }, Error, expectedMsg); - }); - - it(`get: Get fails without a kind`, () => { - const expectedMsg = `Kind not provided. Make sure you have a "kind" property in your request`; - const sample = getSample(); - - assert.throws(() => { - sample.mocks.req.body.kind = undefined; - sample.program.get(sample.mocks.req, sample.mocks.res); - }, Error, expectedMsg); - }); - - it(`get: Handles get error`, () => { - const error = new Error(`error`); - const sample = getSample(); - - sample.mocks.datastore.get.returns(Promise.reject(error)); - - return sample.program.get(sample.mocks.req, sample.mocks.res) - .then(() => { - throw new Error(`Should have failed!`); - }) - .catch((err) => { - assert.deepEqual(err, error); - assert.deepEqual(console.error.callCount, 1); - assert.deepEqual(console.error.firstCall.args, [error]); - assert.deepEqual(sample.mocks.res.status.callCount, 1); - assert.deepEqual(sample.mocks.res.status.firstCall.args, [500]); - assert.deepEqual(sample.mocks.res.send.callCount, 1); - assert.deepEqual(sample.mocks.res.send.firstCall.args, [error]); - }); - }); - - it(`get: Fails when entity does not exist`, () => { - const sample = getSample(); - const error = new Error(`No entity found for key ${sample.mocks.key.path.join('/')}.`); - - sample.mocks.datastore.get.returns(Promise.resolve([])); - - return sample.program.get(sample.mocks.req, sample.mocks.res) - .then(() => { - throw new Error(`Should have failed!`); - }) - .catch((err) => { - assert.deepEqual(err, error); - assert.deepEqual(console.error.callCount, 1); - assert.deepEqual(console.error.firstCall.args, [error]); - assert.deepEqual(sample.mocks.res.status.callCount, 1); - assert.deepEqual(sample.mocks.res.status.firstCall.args, [500]); - assert.deepEqual(sample.mocks.res.send.callCount, 1); - assert.deepEqual(sample.mocks.res.send.firstCall.args, [error]); - }); - }); - - it(`get: Finds an entity`, () => { - const sample = getSample(); - - return sample.program.get(sample.mocks.req, sample.mocks.res) - .then(() => { - assert.deepEqual(sample.mocks.datastore.get.callCount, 1); - assert.deepEqual(sample.mocks.datastore.get.firstCall.args, [sample.mocks.key]); - assert.deepEqual(sample.mocks.res.status.callCount, 1); - assert.deepEqual(sample.mocks.res.status.firstCall.args, [200]); - assert.deepEqual(sample.mocks.res.send.callCount, 1); - assert.deepEqual(sample.mocks.res.send.firstCall.args, [sample.mocks.entity]); - }); - }); - - it(`del: Delete fails without a key`, () => { - const expectedMsg = `Key not provided. Make sure you have a "key" property in your request`; - const sample = getSample(); - - assert.throws(() => { - sample.mocks.req.body.key = undefined; - sample.program.del(sample.mocks.req, sample.mocks.res); - }, Error, expectedMsg); - }); - - it(`del: Delete fails without a kind`, () => { - const expectedMsg = `Kind not provided. Make sure you have a "kind" property in your request`; - const sample = getSample(); - - assert.throws(() => { - sample.mocks.req.body.kind = undefined; - sample.program.del(sample.mocks.req, sample.mocks.res); - }, Error, expectedMsg); - }); - - it(`del: Handles delete error`, () => { - const error = new Error(`error`); - const sample = getSample(); - - sample.mocks.datastore.delete.returns(Promise.reject(error)); - - return sample.program.del(sample.mocks.req, sample.mocks.res) - .then(() => { - throw new Error(`Should have failed!`); - }) - .catch((err) => { - assert.deepEqual(err, error); - assert.deepEqual(console.error.callCount, 1); - assert.deepEqual(console.error.firstCall.args, [error]); - assert.deepEqual(sample.mocks.res.status.callCount, 1); - assert.deepEqual(sample.mocks.res.status.firstCall.args, [500]); - assert.deepEqual(sample.mocks.res.send.callCount, 1); - assert.deepEqual(sample.mocks.res.send.firstCall.args, [error]); - }); - }); - - it(`del: Deletes an entity`, () => { - const expectedMsg = `Entity ${KIND}/${NAME} deleted.`; - const sample = getSample(); - - return sample.program.del(sample.mocks.req, sample.mocks.res) - .then(() => { - assert.deepEqual(sample.mocks.datastore.delete.callCount, 1); - assert.deepEqual(sample.mocks.datastore.delete.firstCall.args, [sample.mocks.key]); - assert.deepEqual(sample.mocks.res.status.callCount, 1); - assert.deepEqual(sample.mocks.res.status.firstCall.args, [200]); - assert.deepEqual(sample.mocks.res.send.callCount, 1); - assert.deepEqual(sample.mocks.res.send.firstCall.args, [expectedMsg]); - }); - }); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); + +test.serial(`set: Set fails without a value`, (t) => { + const expectedMsg = `Value not provided. Make sure you have a "value" property in your request`; + const sample = getSample(); + + t.throws(() => { + sample.mocks.req.body.value = undefined; + sample.program.set(sample.mocks.req, sample.mocks.res); + }, Error, expectedMsg); +}); + +test.serial(`set: Set fails without a key`, (t) => { + const expectedMsg = `Key not provided. Make sure you have a "key" property in your request`; + const sample = getSample(); + + t.throws(() => { + sample.mocks.req.body.key = undefined; + sample.program.set(sample.mocks.req, sample.mocks.res); + }, Error, expectedMsg); +}); + +test.serial(`set: Set fails without a kind`, (t) => { + const expectedMsg = `Kind not provided. Make sure you have a "kind" property in your request`; + const sample = getSample(); + + t.throws(() => { + sample.mocks.req.body.kind = undefined; + sample.program.set(sample.mocks.req, sample.mocks.res); + }, Error, expectedMsg); +}); + +test.serial(`set: Handles save error`, async (t) => { + const error = new Error(`error`); + const sample = getSample(); + + sample.mocks.datastore.save.returns(Promise.reject(error)); + + const err = await t.throws(sample.program.set(sample.mocks.req, sample.mocks.res)); + t.deepEqual(err, error); + t.deepEqual(console.error.callCount, 1); + t.deepEqual(console.error.firstCall.args, [error]); + t.deepEqual(sample.mocks.res.status.callCount, 1); + t.deepEqual(sample.mocks.res.status.firstCall.args, [500]); + t.deepEqual(sample.mocks.res.send.callCount, 1); + t.deepEqual(sample.mocks.res.send.firstCall.args, [error]); +}); + +test.serial(`set: Set saves an entity`, async (t) => { + const expectedMsg = `Entity ${KIND}/${NAME} saved.`; + const sample = getSample(); + + await sample.program.set(sample.mocks.req, sample.mocks.res); + t.deepEqual(sample.mocks.datastore.save.callCount, 1); + t.deepEqual(sample.mocks.datastore.save.firstCall.args, [sample.mocks.entity]); + t.deepEqual(sample.mocks.res.status.callCount, 1); + t.deepEqual(sample.mocks.res.status.firstCall.args, [200]); + t.deepEqual(sample.mocks.res.send.callCount, 1); + t.deepEqual(sample.mocks.res.send.firstCall.args, [expectedMsg]); +}); + +test.serial(`get: Get fails without a key`, (t) => { + const expectedMsg = `Key not provided. Make sure you have a "key" property in your request`; + const sample = getSample(); + + t.throws(() => { + sample.mocks.req.body.key = undefined; + sample.program.get(sample.mocks.req, sample.mocks.res); + }, Error, expectedMsg); +}); + +test.serial(`get: Get fails without a kind`, (t) => { + const expectedMsg = `Kind not provided. Make sure you have a "kind" property in your request`; + const sample = getSample(); + + t.throws(() => { + sample.mocks.req.body.kind = undefined; + sample.program.get(sample.mocks.req, sample.mocks.res); + }, Error, expectedMsg); +}); + +test.serial(`get: Handles get error`, async (t) => { + const error = new Error(`error`); + const sample = getSample(); + + sample.mocks.datastore.get.returns(Promise.reject(error)); + + const err = await t.throws(sample.program.get(sample.mocks.req, sample.mocks.res)); + t.deepEqual(err, error); + t.deepEqual(console.error.callCount, 1); + t.deepEqual(console.error.firstCall.args, [error]); + t.deepEqual(sample.mocks.res.status.callCount, 1); + t.deepEqual(sample.mocks.res.status.firstCall.args, [500]); + t.deepEqual(sample.mocks.res.send.callCount, 1); + t.deepEqual(sample.mocks.res.send.firstCall.args, [error]); +}); + +test.serial(`get: Fails when entity does not exist`, async (t) => { + const sample = getSample(); + const error = new Error(`No entity found for key ${sample.mocks.key.path.join('/')}.`); + + sample.mocks.datastore.get.returns(Promise.resolve([])); + + const err = await t.throws(sample.program.get(sample.mocks.req, sample.mocks.res)); + t.deepEqual(err, error); + t.deepEqual(console.error.callCount, 1); + t.deepEqual(console.error.firstCall.args, [error]); + t.deepEqual(sample.mocks.res.status.callCount, 1); + t.deepEqual(sample.mocks.res.status.firstCall.args, [500]); + t.deepEqual(sample.mocks.res.send.callCount, 1); + t.deepEqual(sample.mocks.res.send.firstCall.args, [error]); +}); + +test.serial(`get: Finds an entity`, async (t) => { + const sample = getSample(); + + await sample.program.get(sample.mocks.req, sample.mocks.res); + t.deepEqual(sample.mocks.datastore.get.callCount, 1); + t.deepEqual(sample.mocks.datastore.get.firstCall.args, [sample.mocks.key]); + t.deepEqual(sample.mocks.res.status.callCount, 1); + t.deepEqual(sample.mocks.res.status.firstCall.args, [200]); + t.deepEqual(sample.mocks.res.send.callCount, 1); + t.deepEqual(sample.mocks.res.send.firstCall.args, [sample.mocks.entity]); +}); + +test.serial(`del: Delete fails without a key`, (t) => { + const expectedMsg = `Key not provided. Make sure you have a "key" property in your request`; + const sample = getSample(); + + t.throws(() => { + sample.mocks.req.body.key = undefined; + sample.program.del(sample.mocks.req, sample.mocks.res); + }, Error, expectedMsg); +}); + +test.serial(`del: Delete fails without a kind`, (t) => { + const expectedMsg = `Kind not provided. Make sure you have a "kind" property in your request`; + const sample = getSample(); + + t.throws(() => { + sample.mocks.req.body.kind = undefined; + sample.program.del(sample.mocks.req, sample.mocks.res); + }, Error, expectedMsg); +}); + +test.serial(`del: Handles delete error`, async (t) => { + const error = new Error(`error`); + const sample = getSample(); + + sample.mocks.datastore.delete.returns(Promise.reject(error)); + + const err = await t.throws(sample.program.del(sample.mocks.req, sample.mocks.res)); + t.deepEqual(err, error); + t.deepEqual(console.error.callCount, 1); + t.deepEqual(console.error.firstCall.args, [error]); + t.deepEqual(sample.mocks.res.status.callCount, 1); + t.deepEqual(sample.mocks.res.status.firstCall.args, [500]); + t.deepEqual(sample.mocks.res.send.callCount, 1); + t.deepEqual(sample.mocks.res.send.firstCall.args, [error]); +}); + +test.serial(`del: Deletes an entity`, async (t) => { + const expectedMsg = `Entity ${KIND}/${NAME} deleted.`; + const sample = getSample(); + + await sample.program.del(sample.mocks.req, sample.mocks.res); + t.deepEqual(sample.mocks.datastore.delete.callCount, 1); + t.deepEqual(sample.mocks.datastore.delete.firstCall.args, [sample.mocks.key]); + t.deepEqual(sample.mocks.res.status.callCount, 1); + t.deepEqual(sample.mocks.res.status.firstCall.args, [200]); + t.deepEqual(sample.mocks.res.send.callCount, 1); + t.deepEqual(sample.mocks.res.send.firstCall.args, [expectedMsg]); }); diff --git a/functions/errorreporting/package.json b/functions/errorreporting/package.json index e7572f3dc7..0c45f96fc3 100644 --- a/functions/errorreporting/package.json +++ b/functions/errorreporting/package.json @@ -5,9 +5,6 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "main": "./index.js", - "scripts": { - "test": "cd ..; npm run t -- functions/errorreporting/test/*.test.js" - }, "dependencies": { "@google-cloud/logging": "0.6.0" } diff --git a/functions/errorreporting/test/index.test.js b/functions/errorreporting/test/index.test.js deleted file mode 100644 index d82087a3db..0000000000 --- a/functions/errorreporting/test/index.test.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright 2016, Google, Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -describe(`functions:errorreporting`, () => { - it(`should have tests`); -}); diff --git a/functions/gcs/test/index.test.js b/functions/gcs/test/index.test.js index 49a2ca18b7..7df0d1b5f7 100644 --- a/functions/gcs/test/index.test.js +++ b/functions/gcs/test/index.test.js @@ -15,6 +15,8 @@ 'use strict'; +require(`../../../test/_setup`); + const fs = require(`fs`); const path = require(`path`); const proxyquire = require(`proxyquire`).noCallThru(); @@ -46,62 +48,60 @@ function getSample () { }; } -describe(`functions:gcs`, () => { - it(`Fails without a bucket`, () => { - const expectedMsg = `Bucket not provided. Make sure you have a "bucket" property in your request`; +test.serial(`Fails without a bucket`, (t) => { + const expectedMsg = `Bucket not provided. Make sure you have a "bucket" property in your request`; - assert.throws( - () => getSample().program.wordCount({ data: { name: `file` } }), - Error, - expectedMsg - ); - }); + t.throws( + () => getSample().program.wordCount({ data: { name: `file` } }), + Error, + expectedMsg + ); +}); - it(`Fails without a file`, () => { - const expectedMsg = `Filename not provided. Make sure you have a "file" property in your request`; +test.serial(`Fails without a file`, (t) => { + const expectedMsg = `Filename not provided. Make sure you have a "file" property in your request`; - assert.throws( - () => getSample().program.wordCount({ data: { bucket: `bucket` } }), - Error, - expectedMsg - ); - }); + t.throws( + () => getSample().program.wordCount({ data: { bucket: `bucket` } }), + Error, + expectedMsg + ); +}); - it(`Does nothing for deleted files`, (done) => { - const event = { - data: { - resourceState: `not_exists` - } - }; - const sample = getSample(); +test.cb.serial(`Does nothing for deleted files`, (t) => { + const event = { + data: { + resourceState: `not_exists` + } + }; + const sample = getSample(); - sample.program.wordCount(event, (err, message) => { - assert.ifError(err); - assert.equal(message, undefined); - assert.deepEqual(sample.mocks.storage.bucket.callCount, 0); - assert.deepEqual(sample.mocks.bucket.file.callCount, 0); - done(); - }); + sample.program.wordCount(event, (err, message) => { + t.ifError(err); + t.is(message, undefined); + t.deepEqual(sample.mocks.storage.bucket.callCount, 0); + t.deepEqual(sample.mocks.bucket.file.callCount, 0); + t.end(); }); +}); - it(`Reads the file line by line`, (done) => { - const expectedMsg = `File ${filename} has 114 words`; - const event = { - data: { - bucket: `bucket`, - name: `sample.txt` - } - }; +test.cb.serial(`Reads the file line by line`, (t) => { + const expectedMsg = `File ${filename} has 114 words`; + const event = { + data: { + bucket: `bucket`, + name: `sample.txt` + } + }; - const sample = getSample(); - sample.program.wordCount(event, (err, message) => { - assert.ifError(err); - assert.deepEqual(message, expectedMsg); - assert.deepEqual(sample.mocks.storage.bucket.calledOnce, true); - assert.deepEqual(sample.mocks.storage.bucket.firstCall.args, [event.data.bucket]); - assert.deepEqual(sample.mocks.bucket.file.calledOnce, true); - assert.deepEqual(sample.mocks.bucket.file.firstCall.args, [event.data.name]); - done(); - }); + const sample = getSample(); + sample.program.wordCount(event, (err, message) => { + t.ifError(err); + t.deepEqual(message, expectedMsg); + t.deepEqual(sample.mocks.storage.bucket.calledOnce, true); + t.deepEqual(sample.mocks.storage.bucket.firstCall.args, [event.data.bucket]); + t.deepEqual(sample.mocks.bucket.file.calledOnce, true); + t.deepEqual(sample.mocks.bucket.file.firstCall.args, [event.data.name]); + t.end(); }); }); diff --git a/functions/helloworld/test/index.test.js b/functions/helloworld/test/index.test.js index 130d2f3dbe..8f777dde5c 100644 --- a/functions/helloworld/test/index.test.js +++ b/functions/helloworld/test/index.test.js @@ -15,173 +15,176 @@ 'use strict'; +require(`../../../test/_setup`); + const proxyquire = require('proxyquire').noCallThru(); const program = proxyquire(`../`, {}); -describe(`functions:helloworld`, () => { - it(`helloworld: should log a message`, () => { - const expectedMsg = `My Cloud Function: hi`; - const callback = sinon.stub(); - - program.helloWorld({ - data: { - message: `hi` - } - }, callback); - - assert.deepEqual(console.log.callCount, 1); - assert.deepEqual(console.log.firstCall.args, [expectedMsg]); - assert.deepEqual(callback.callCount, 1); - assert.deepEqual(callback.firstCall.args, []); - }); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); - it(`helloGET: should print hello world`, (done) => { - const expectedMsg = `Hello World!`; +test.serial(`helloworld: should log a message`, (t) => { + const expectedMsg = `My Cloud Function: hi`; + const callback = sinon.stub(); - program.helloGET({}, { - send: (message) => { - assert.equal(message, expectedMsg); - done(); - } - }); + program.helloWorld({ + data: { + message: `hi` + } + }, callback); + + t.deepEqual(console.log.callCount, 1); + t.deepEqual(console.log.firstCall.args, [expectedMsg]); + t.deepEqual(callback.callCount, 1); + t.deepEqual(callback.firstCall.args, []); +}); + +test.cb.serial(`helloGET: should print hello world`, (t) => { + const expectedMsg = `Hello World!`; + + program.helloGET({}, { + send: (message) => { + t.is(message, expectedMsg); + t.end(); + } }); +}); - it(`helloHttp: should print a name`, (done) => { - const expectedMsg = `Hello John!`; - - program.helloHttp({ - body: { - name: `John` - } - }, { - send: (message) => { - assert.equal(message, expectedMsg); - done(); - } - }); +test.cb.serial(`helloHttp: should print a name`, (t) => { + const expectedMsg = `Hello John!`; + + program.helloHttp({ + body: { + name: `John` + } + }, { + send: (message) => { + t.is(message, expectedMsg); + t.end(); + } }); +}); + +test.cb.serial(`helloHttp: should print hello world`, (t) => { + const expectedMsg = `Hello World!`; - it(`helloHttp: should print hello world`, (done) => { - const expectedMsg = `Hello World!`; - - program.helloHttp({ - body: {} - }, { - send: (message) => { - assert.equal(message, expectedMsg); - done(); - } - }); + program.helloHttp({ + body: {} + }, { + send: (message) => { + t.is(message, expectedMsg); + t.end(); + } }); +}); - it(`helloBackground: should print a name`, () => { - const expectedMsg = `Hello John!`; - const callback = sinon.stub(); +test.serial(`helloBackground: should print a name`, (t) => { + const expectedMsg = `Hello John!`; + const callback = sinon.stub(); - program.helloBackground({ - data: { - name: `John` - } - }, callback); + program.helloBackground({ + data: { + name: `John` + } + }, callback); - assert.deepEqual(callback.callCount, 1); - assert.deepEqual(callback.firstCall.args, [null, expectedMsg]); - }); + t.deepEqual(callback.callCount, 1); + t.deepEqual(callback.firstCall.args, [null, expectedMsg]); +}); - it(`helloBackground: should print hello world`, () => { - const expectedMsg = `Hello World!`; - const callback = sinon.stub(); +test.serial(`helloBackground: should print hello world`, (t) => { + const expectedMsg = `Hello World!`; + const callback = sinon.stub(); - program.helloBackground({ data: {} }, callback); + program.helloBackground({ data: {} }, callback); - assert.deepEqual(callback.callCount, 1); - assert.deepEqual(callback.firstCall.args, [null, expectedMsg]); - }); + t.deepEqual(callback.callCount, 1); + t.deepEqual(callback.firstCall.args, [null, expectedMsg]); +}); - it(`helloPubSub: should print a name`, () => { - const expectedMsg = `Hello Bob!`; - const callback = sinon.stub(); +test.serial(`helloPubSub: should print a name`, (t) => { + const expectedMsg = `Hello Bob!`; + const callback = sinon.stub(); - program.helloPubSub({ - data: { - data: new Buffer(`Bob`).toString(`base64`) - } - }, callback); + program.helloPubSub({ + data: { + data: new Buffer(`Bob`).toString(`base64`) + } + }, callback); - assert.deepEqual(console.log.callCount, 1); - assert.deepEqual(console.log.firstCall.args, [expectedMsg]); - assert.deepEqual(callback.callCount, 1); - assert.deepEqual(callback.firstCall.args, []); - }); + t.deepEqual(console.log.callCount, 1); + t.deepEqual(console.log.firstCall.args, [expectedMsg]); + t.deepEqual(callback.callCount, 1); + t.deepEqual(callback.firstCall.args, []); +}); - it(`helloPubSub: should print hello world`, () => { - const expectedMsg = `Hello World!`; - const callback = sinon.stub(); +test.serial(`helloPubSub: should print hello world`, (t) => { + const expectedMsg = `Hello World!`; + const callback = sinon.stub(); - program.helloPubSub({ data: {} }, callback); + program.helloPubSub({ data: {} }, callback); - assert.deepEqual(console.log.callCount, 1); - assert.deepEqual(console.log.firstCall.args, [expectedMsg]); - assert.deepEqual(callback.callCount, 1); - assert.deepEqual(callback.firstCall.args, []); - }); + t.deepEqual(console.log.callCount, 1); + t.deepEqual(console.log.firstCall.args, [expectedMsg]); + t.deepEqual(callback.callCount, 1); + t.deepEqual(callback.firstCall.args, []); +}); - it(`helloGCS: should print uploaded message`, () => { - const expectedMsg = `File foo uploaded.`; - const callback = sinon.stub(); - - program.helloGCS({ - data: { - name: `foo`, - resourceState: `exists` - } - }, callback); - - assert.deepEqual(console.log.callCount, 1); - assert.deepEqual(console.log.firstCall.args, [expectedMsg]); - assert.deepEqual(callback.callCount, 1); - assert.deepEqual(callback.firstCall.args, []); - }); +test.serial(`helloGCS: should print uploaded message`, (t) => { + const expectedMsg = `File foo uploaded.`; + const callback = sinon.stub(); + + program.helloGCS({ + data: { + name: `foo`, + resourceState: `exists` + } + }, callback); + + t.deepEqual(console.log.callCount, 1); + t.deepEqual(console.log.firstCall.args, [expectedMsg]); + t.deepEqual(callback.callCount, 1); + t.deepEqual(callback.firstCall.args, []); +}); - it(`helloGCS: should print deleted message`, () => { - const expectedMsg = `File foo deleted.`; - const callback = sinon.stub(); - - program.helloGCS({ - data: { - name: `foo`, - resourceState: `not_exists` - } - }, callback); - - assert.deepEqual(console.log.callCount, 1); - assert.deepEqual(console.log.firstCall.args, [expectedMsg]); - assert.deepEqual(callback.callCount, 1); - assert.deepEqual(callback.firstCall.args, []); - }); +test.serial(`helloGCS: should print deleted message`, (t) => { + const expectedMsg = `File foo deleted.`; + const callback = sinon.stub(); + + program.helloGCS({ + data: { + name: `foo`, + resourceState: `not_exists` + } + }, callback); + + t.deepEqual(console.log.callCount, 1); + t.deepEqual(console.log.firstCall.args, [expectedMsg]); + t.deepEqual(callback.callCount, 1); + t.deepEqual(callback.firstCall.args, []); +}); - it(`helloError: should throw an error`, () => { - const expectedMsg = `I failed you`; +test.serial(`helloError: should throw an error`, (t) => { + const expectedMsg = `I failed you`; - assert.throws(() => { - program.helloError(); - }, Error, expectedMsg); - }); + t.throws(() => { + program.helloError(); + }, Error, expectedMsg); +}); - it(`helloError2: should throw a value`, () => { - assert.throws(() => { - program.helloError2(); - }); +test.serial(`helloError2: should throw a value`, (t) => { + t.throws(() => { + program.helloError2(); }); +}); - it(`helloError3: callback shoud return an errback value`, () => { - const expectedMsg = `I failed you`; - const callback = sinon.stub(); +test.serial(`helloError3: callback shoud return an errback value`, (t) => { + const expectedMsg = `I failed you`; + const callback = sinon.stub(); - program.helloError3({}, callback); + program.helloError3({}, callback); - assert.deepEqual(callback.callCount, 1); - assert.deepEqual(callback.firstCall.args, [expectedMsg]); - }); + t.deepEqual(callback.callCount, 1); + t.deepEqual(callback.firstCall.args, [expectedMsg]); }); diff --git a/functions/http/test/index.test.js b/functions/http/test/index.test.js index 59ba79ae1b..baedea4abd 100644 --- a/functions/http/test/index.test.js +++ b/functions/http/test/index.test.js @@ -15,6 +15,8 @@ 'use strict'; +require(`../../../test/_setup`); + const proxyquire = require('proxyquire').noCallThru(); function getSample () { @@ -50,130 +52,130 @@ function getMocks () { }; } -describe(`functions:http`, () => { - it(`http:helloworld: should error with no message`, () => { - const mocks = getMocks(); - const httpSample = getSample(); - mocks.req.body = {}; - httpSample.sample.helloWorld(mocks.req, mocks.res); - - assert.equal(mocks.res.status.calledOnce, true); - assert.equal(mocks.res.status.firstCall.args[0], 400); - assert.equal(mocks.res.send.calledOnce, true); - assert.equal(mocks.res.send.firstCall.args[0], `No message defined!`); - }); - - it(`http:helloworld: should log message`, () => { - const mocks = getMocks(); - const httpSample = getSample(); - mocks.req.body = { - message: `hi` - }; - httpSample.sample.helloWorld(mocks.req, mocks.res); - - assert.equal(mocks.res.status.calledOnce, true); - assert.equal(mocks.res.status.firstCall.args[0], 200); - assert.equal(mocks.res.end.calledOnce, true); - assert.equal(console.log.calledWith(`hi`), true); - }); - - it(`http:helloHttp: should handle GET`, () => { - const mocks = getMocks(); - const httpSample = getSample(); - mocks.req.method = `GET`; - httpSample.sample.helloHttp(mocks.req, mocks.res); - - assert.equal(mocks.res.status.calledOnce, true); - assert.equal(mocks.res.status.firstCall.args[0], 200); - assert.equal(mocks.res.send.calledOnce, true); - assert.equal(mocks.res.send.firstCall.args[0], `Hello World!`); - }); - - it(`http:helloHttp: should handle PUT`, () => { - const mocks = getMocks(); - const httpSample = getSample(); - mocks.req.method = `PUT`; - httpSample.sample.helloHttp(mocks.req, mocks.res); - - assert.equal(mocks.res.status.calledOnce, true); - assert.equal(mocks.res.status.firstCall.args[0], 403); - assert.equal(mocks.res.send.calledOnce, true); - assert.equal(mocks.res.send.firstCall.args[0], `Forbidden!`); - }); - - it(`http:helloHttp: should handle other methods`, () => { - const mocks = getMocks(); - const httpSample = getSample(); - mocks.req.method = `POST`; - httpSample.sample.helloHttp(mocks.req, mocks.res); - - assert.equal(mocks.res.status.calledOnce, true); - assert.equal(mocks.res.status.firstCall.args[0], 500); - assert.equal(mocks.res.send.calledOnce, true); - assert.deepEqual(mocks.res.send.firstCall.args[0], { error: `Something blew up!` }); - }); - - it(`http:helloContent: should handle application/json`, () => { - const mocks = getMocks(); - const httpSample = getSample(); - mocks.req.headers[`content-type`] = `application/json`; - mocks.req.body = { name: `John` }; - httpSample.sample.helloContent(mocks.req, mocks.res); - - assert.equal(mocks.res.status.calledOnce, true); - assert.equal(mocks.res.status.firstCall.args[0], 200); - assert.equal(mocks.res.send.calledOnce, true); - assert.deepEqual(mocks.res.send.firstCall.args[0], `Hello John!`); - }); - - it(`http:helloContent: should handle application/octet-stream`, () => { - const mocks = getMocks(); - const httpSample = getSample(); - mocks.req.headers[`content-type`] = `application/octet-stream`; - mocks.req.body = new Buffer(`John`); - httpSample.sample.helloContent(mocks.req, mocks.res); - - assert.equal(mocks.res.status.calledOnce, true); - assert.equal(mocks.res.status.firstCall.args[0], 200); - assert.equal(mocks.res.send.calledOnce, true); - assert.deepEqual(mocks.res.send.firstCall.args[0], `Hello John!`); - }); - - it(`http:helloContent: should handle text/plain`, () => { - const mocks = getMocks(); - const httpSample = getSample(); - mocks.req.headers[`content-type`] = `text/plain`; - mocks.req.body = `John`; - httpSample.sample.helloContent(mocks.req, mocks.res); - - assert.equal(mocks.res.status.calledOnce, true); - assert.equal(mocks.res.status.firstCall.args[0], 200); - assert.equal(mocks.res.send.calledOnce, true); - assert.deepEqual(mocks.res.send.firstCall.args[0], `Hello John!`); - }); - - it(`http:helloContent: should handle application/x-www-form-urlencoded`, () => { - const mocks = getMocks(); - const httpSample = getSample(); - mocks.req.headers[`content-type`] = `application/x-www-form-urlencoded`; - mocks.req.body = { name: `John` }; - httpSample.sample.helloContent(mocks.req, mocks.res); - - assert.equal(mocks.res.status.calledOnce, true); - assert.equal(mocks.res.status.firstCall.args[0], 200); - assert.equal(mocks.res.send.calledOnce, true); - assert.deepEqual(mocks.res.send.firstCall.args[0], `Hello John!`); - }); - - it(`http:helloContent: should handle other`, () => { - const mocks = getMocks(); - const httpSample = getSample(); - httpSample.sample.helloContent(mocks.req, mocks.res); - - assert.equal(mocks.res.status.calledOnce, true); - assert.equal(mocks.res.status.firstCall.args[0], 200); - assert.equal(mocks.res.send.calledOnce, true); - assert.deepEqual(mocks.res.send.firstCall.args[0], `Hello World!`); - }); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); + +test.serial(`http:helloworld: should error with no message`, (t) => { + const mocks = getMocks(); + const httpSample = getSample(); + mocks.req.body = {}; + httpSample.sample.helloWorld(mocks.req, mocks.res); + + t.true(mocks.res.status.calledOnce); + t.is(mocks.res.status.firstCall.args[0], 400); + t.true(mocks.res.send.calledOnce); + t.is(mocks.res.send.firstCall.args[0], `No message defined!`); +}); + +test.serial(`http:helloworld: should log message`, (t) => { + const mocks = getMocks(); + const httpSample = getSample(); + mocks.req.body = { + message: `hi` + }; + httpSample.sample.helloWorld(mocks.req, mocks.res); + + t.true(mocks.res.status.calledOnce); + t.is(mocks.res.status.firstCall.args[0], 200); + t.true(mocks.res.end.calledOnce); + t.true(console.log.calledWith(`hi`)); +}); + +test.serial(`http:helloHttp: should handle GET`, (t) => { + const mocks = getMocks(); + const httpSample = getSample(); + mocks.req.method = `GET`; + httpSample.sample.helloHttp(mocks.req, mocks.res); + + t.true(mocks.res.status.calledOnce); + t.is(mocks.res.status.firstCall.args[0], 200); + t.true(mocks.res.send.calledOnce); + t.is(mocks.res.send.firstCall.args[0], `Hello World!`); +}); + +test.serial(`http:helloHttp: should handle PUT`, (t) => { + const mocks = getMocks(); + const httpSample = getSample(); + mocks.req.method = `PUT`; + httpSample.sample.helloHttp(mocks.req, mocks.res); + + t.true(mocks.res.status.calledOnce); + t.is(mocks.res.status.firstCall.args[0], 403); + t.true(mocks.res.send.calledOnce); + t.is(mocks.res.send.firstCall.args[0], `Forbidden!`); }); +test.serial(`http:helloHttp: should handle other methods`, (t) => { + const mocks = getMocks(); + const httpSample = getSample(); + mocks.req.method = `POST`; + httpSample.sample.helloHttp(mocks.req, mocks.res); + + t.true(mocks.res.status.calledOnce); + t.is(mocks.res.status.firstCall.args[0], 500); + t.true(mocks.res.send.calledOnce); + t.deepEqual(mocks.res.send.firstCall.args[0], { error: `Something blew up!` }); +}); + +test.serial(`http:helloContent: should handle application/json`, (t) => { + const mocks = getMocks(); + const httpSample = getSample(); + mocks.req.headers[`content-type`] = `application/json`; + mocks.req.body = { name: `John` }; + httpSample.sample.helloContent(mocks.req, mocks.res); + + t.true(mocks.res.status.calledOnce); + t.is(mocks.res.status.firstCall.args[0], 200); + t.true(mocks.res.send.calledOnce); + t.deepEqual(mocks.res.send.firstCall.args[0], `Hello John!`); +}); + +test.serial(`http:helloContent: should handle application/octet-stream`, (t) => { + const mocks = getMocks(); + const httpSample = getSample(); + mocks.req.headers[`content-type`] = `application/octet-stream`; + mocks.req.body = new Buffer(`John`); + httpSample.sample.helloContent(mocks.req, mocks.res); + + t.true(mocks.res.status.calledOnce); + t.is(mocks.res.status.firstCall.args[0], 200); + t.true(mocks.res.send.calledOnce); + t.deepEqual(mocks.res.send.firstCall.args[0], `Hello John!`); +}); + +test.serial(`http:helloContent: should handle text/plain`, (t) => { + const mocks = getMocks(); + const httpSample = getSample(); + mocks.req.headers[`content-type`] = `text/plain`; + mocks.req.body = `John`; + httpSample.sample.helloContent(mocks.req, mocks.res); + + t.true(mocks.res.status.calledOnce); + t.is(mocks.res.status.firstCall.args[0], 200); + t.true(mocks.res.send.calledOnce); + t.deepEqual(mocks.res.send.firstCall.args[0], `Hello John!`); +}); + +test.serial(`http:helloContent: should handle application/x-www-form-urlencoded`, (t) => { + const mocks = getMocks(); + const httpSample = getSample(); + mocks.req.headers[`content-type`] = `application/x-www-form-urlencoded`; + mocks.req.body = { name: `John` }; + httpSample.sample.helloContent(mocks.req, mocks.res); + + t.true(mocks.res.status.calledOnce); + t.is(mocks.res.status.firstCall.args[0], 200); + t.true(mocks.res.send.calledOnce); + t.deepEqual(mocks.res.send.firstCall.args[0], `Hello John!`); +}); + +test.serial(`http:helloContent: should handle other`, (t) => { + const mocks = getMocks(); + const httpSample = getSample(); + httpSample.sample.helloContent(mocks.req, mocks.res); + + t.true(mocks.res.status.calledOnce); + t.is(mocks.res.status.firstCall.args[0], 200); + t.true(mocks.res.send.calledOnce); + t.deepEqual(mocks.res.send.firstCall.args[0], `Hello World!`); +}); diff --git a/functions/log/test/index.test.js b/functions/log/test/index.test.js index 9e77e5e3f9..52a865b328 100644 --- a/functions/log/test/index.test.js +++ b/functions/log/test/index.test.js @@ -15,6 +15,8 @@ 'use strict'; +require(`../../../test/_setup`); + const proxyquire = require(`proxyquire`).noCallThru(); function getSample () { @@ -49,36 +51,36 @@ function getSample () { }; } -describe(`functions:log`, () => { - it(`should write to log`, () => { - const expectedMsg = `I am a log entry!`; - const callback = sinon.stub(); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); - getSample().program.helloWorld({}, callback); +test.serial(`should write to log`, (t) => { + const expectedMsg = `I am a log entry!`; + const callback = sinon.stub(); - assert.equal(console.log.callCount, 1); - assert.deepEqual(console.log.firstCall.args, [expectedMsg]); - assert.equal(callback.callCount, 1); - assert.deepEqual(callback.firstCall.args, []); - }); + getSample().program.helloWorld({}, callback); - it(`getLogEntries: should retrieve logs`, () => { - const sample = getSample(); + t.is(console.log.callCount, 1); + t.deepEqual(console.log.firstCall.args, [expectedMsg]); + t.is(callback.callCount, 1); + t.deepEqual(callback.firstCall.args, []); +}); - return sample.program.getLogEntries() - .then((entries) => { - assert.equal(console.log.calledWith(`Entries:`), true); - assert.strictEqual(entries, sample.mocks.results[0]); - }); - }); +test.serial(`getLogEntries: should retrieve logs`, (t) => { + const sample = getSample(); - it(`getMetrics: should retrieve metrics`, () => { - const sample = getSample(); - const callback = sinon.stub(); + return sample.program.getLogEntries() + .then((entries) => { + t.true(console.log.calledWith(`Entries:`)); + t.true(entries === sample.mocks.results[0]); + }); +}); - sample.program.getMetrics(callback); +test.serial(`getMetrics: should retrieve metrics`, (t) => { + const sample = getSample(); + const callback = sinon.stub(); - assert.equal(callback.callCount, 1); - }); -}); + sample.program.getMetrics(callback); + t.is(callback.callCount, 1); +}); diff --git a/functions/ocr/app/package.json b/functions/ocr/app/package.json index 1e5ffe15c7..66b1a00b69 100644 --- a/functions/ocr/app/package.json +++ b/functions/ocr/app/package.json @@ -6,7 +6,7 @@ "author": "Google Inc.", "main": "./index.js", "scripts": { - "test": "cd ..; npm run t -- functions/ocr/app/test/*.test.js" + "test": "cd ../..; npm run t -- functions/ocr/app/test/*.test.js" }, "dependencies": { "@google-cloud/pubsub": "0.7.0", diff --git a/functions/ocr/app/test/index.test.js b/functions/ocr/app/test/index.test.js index 32e0ff2123..9f5ef37e59 100644 --- a/functions/ocr/app/test/index.test.js +++ b/functions/ocr/app/test/index.test.js @@ -15,6 +15,8 @@ 'use strict'; +require(`../../../../test/_setup`); + const proxyquire = require(`proxyquire`).noCallThru(); const bucketName = `my-bucket`; @@ -82,188 +84,160 @@ function getSample () { }; } -describe(`functions:ocr`, () => { - it(`processImage does nothing on delete`, () => { - return getSample().program.processImage({ data: { resourceState: `not_exists` } }); - }); - - it(`processImage fails without a bucket`, () => { - const error = new Error(`Bucket not provided. Make sure you have a "bucket" property in your request`); - - return getSample().program.processImage({ data: {} }) - .catch((err) => { - assert.deepEqual(err, error); - }); - }); - - it(`processImage fails without a name`, () => { - const error = new Error(`Filename not provided. Make sure you have a "name" property in your request`); - - return getSample().program.processImage({ data: { bucket: bucketName } }) - .catch((err) => { - assert.deepEqual(err, error); - }); - }); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); - it(`processImage processes an image`, () => { - const event = { - data: { - bucket: bucketName, - name: filename - } - }; - const sample = getSample(); +test.serial(`processImage does nothing on delete`, async (t) => { + await getSample().program.processImage({ data: { resourceState: `not_exists` } }); +}); - return sample.program.processImage(event) - .then(() => { - assert.equal(console.log.callCount, 4); - assert.deepEqual(console.log.getCall(0).args, [`Looking for text in image ${filename}`]); - assert.deepEqual(console.log.getCall(1).args, [`Extracted text from image (${text.length} chars)`]); - assert.deepEqual(console.log.getCall(2).args, [`Detected language "ja" for ${filename}`]); - assert.deepEqual(console.log.getCall(3).args, [`File ${event.data.name} processed.`]); - }); - }); +test.serial(`processImage fails without a bucket`, async (t) => { + const error = new Error(`Bucket not provided. Make sure you have a "bucket" property in your request`); + const err = await t.throws(getSample().program.processImage({ data: {} })); + t.deepEqual(err, error); +}); - it(`translateText fails without text`, () => { - const error = new Error(`Text not provided. Make sure you have a "text" property in your request`); - const event = { - data: { - data: Buffer.from(JSON.stringify({})).toString(`base64`) - } - }; +test.serial(`processImage fails without a name`, async (t) => { + const error = new Error(`Filename not provided. Make sure you have a "name" property in your request`); + const err = await t.throws(getSample().program.processImage({ data: { bucket: bucketName } })); + t.deepEqual(err, error); +}); - return getSample().program.translateText(event) - .catch((err) => { - assert.deepEqual(err, error); - }); - }); +test.serial(`processImage processes an image`, async (t) => { + const event = { + data: { + bucket: bucketName, + name: filename + } + }; + const sample = getSample(); + + await sample.program.processImage(event); + t.is(console.log.callCount, 4); + t.deepEqual(console.log.getCall(0).args, [`Looking for text in image ${filename}`]); + t.deepEqual(console.log.getCall(1).args, [`Extracted text from image (${text.length} chars)`]); + t.deepEqual(console.log.getCall(2).args, [`Detected language "ja" for ${filename}`]); + t.deepEqual(console.log.getCall(3).args, [`File ${event.data.name} processed.`]); +}); - it(`translateText fails without a filename`, () => { - const error = new Error(`Filename not provided. Make sure you have a "filename" property in your request`); - const event = { - data: { - data: Buffer.from(JSON.stringify({ text })).toString(`base64`) - } - }; +test.serial(`translateText fails without text`, async (t) => { + const error = new Error(`Text not provided. Make sure you have a "text" property in your request`); + const event = { + data: { + data: Buffer.from(JSON.stringify({})).toString(`base64`) + } + }; + const err = await t.throws(getSample().program.translateText(event)); + t.deepEqual(err, error); +}); - return getSample().program.translateText(event) - .catch((err) => { - assert.deepEqual(err, error); - }); - }); +test.serial(`translateText fails without a filename`, async (t) => { + const error = new Error(`Filename not provided. Make sure you have a "filename" property in your request`); + const event = { + data: { + data: Buffer.from(JSON.stringify({ text })).toString(`base64`) + } + }; + const err = await t.throws(getSample().program.translateText(event)); + t.deepEqual(err, error); +}); - it(`translateText fails without a lang`, () => { - const error = new Error(`Language not provided. Make sure you have a "lang" property in your request`); - const event = { - data: { - data: Buffer.from(JSON.stringify({ text, filename })).toString(`base64`) - } - }; +test.serial(`translateText fails without a lang`, async (t) => { + const error = new Error(`Language not provided. Make sure you have a "lang" property in your request`); + const event = { + data: { + data: Buffer.from(JSON.stringify({ text, filename })).toString(`base64`) + } + }; - return getSample().program.translateText(event) - .catch((err) => { - assert.deepEqual(err, error); - }); - }); + const err = await t.throws(getSample().program.translateText(event)); + t.deepEqual(err, error); +}); - it(`translateText translates and publishes text`, () => { - const event = { - data: { - data: Buffer.from( - JSON.stringify({ - text, - filename, - lang - }) - ).toString(`base64`) - } - }; - const sample = getSample(); +test.serial(`translateText translates and publishes text`, async (t) => { + const event = { + data: { + data: Buffer.from( + JSON.stringify({ + text, + filename, + lang + }) + ).toString(`base64`) + } + }; + const sample = getSample(); - sample.mocks.translate.translate.returns(Promise.resolve([translation])); + sample.mocks.translate.translate.returns(Promise.resolve([translation])); - return sample.program.translateText(event) - .then(() => { - assert.equal(console.log.callCount, 2); - assert.deepEqual(console.log.firstCall.args, [`Translating text into ${lang}`]); - assert.deepEqual(console.log.secondCall.args, [`Text translated to ${lang}`]); - }); - }); + await sample.program.translateText(event); + t.is(console.log.callCount, 2); + t.deepEqual(console.log.firstCall.args, [`Translating text into ${lang}`]); + t.deepEqual(console.log.secondCall.args, [`Text translated to ${lang}`]); +}); - it(`saveResult fails without text`, () => { - const error = new Error(`Text not provided. Make sure you have a "text" property in your request`); - const event = { - data: { - data: Buffer.from(JSON.stringify({})).toString(`base64`) - } - }; +test.serial(`saveResult fails without text`, async (t) => { + const error = new Error(`Text not provided. Make sure you have a "text" property in your request`); + const event = { + data: { + data: Buffer.from(JSON.stringify({})).toString(`base64`) + } + }; - return getSample().program.saveResult(event) - .catch((err) => { - assert.deepEqual(err, error); - }); - }); + const err = await t.throws(getSample().program.saveResult(event)); + t.deepEqual(err, error); +}); - it(`saveResult fails without a filename`, () => { - const error = new Error(`Filename not provided. Make sure you have a "filename" property in your request`); - const event = { - data: { - data: Buffer.from(JSON.stringify({ text })).toString(`base64`) - } - }; +test.serial(`saveResult fails without a filename`, async (t) => { + const error = new Error(`Filename not provided. Make sure you have a "filename" property in your request`); + const event = { + data: { + data: Buffer.from(JSON.stringify({ text })).toString(`base64`) + } + }; - return getSample().program.saveResult(event) - .catch((err) => { - assert.deepEqual(err, error); - }); - }); + const err = await t.throws(getSample().program.saveResult(event)); + t.deepEqual(err, error); +}); - it(`saveResult fails without a lang`, () => { - const error = new Error(`Language not provided. Make sure you have a "lang" property in your request`); - const event = { - data: { - data: Buffer.from(JSON.stringify({ text, filename })).toString(`base64`) - } - }; +test.serial(`saveResult fails without a lang`, async (t) => { + const error = new Error(`Language not provided. Make sure you have a "lang" property in your request`); + const event = { + data: { + data: Buffer.from(JSON.stringify({ text, filename })).toString(`base64`) + } + }; - return getSample().program.saveResult(event) - .catch((err) => { - assert.deepEqual(err, error); - }); - }); + const err = await t.throws(getSample().program.saveResult(event)); + t.deepEqual(err, error); +}); - it(`saveResult translates and publishes text`, () => { - const event = { - data: { - data: Buffer.from(JSON.stringify({ text, filename, lang })).toString(`base64`) - } - }; - const sample = getSample(); +test.serial(`saveResult translates and publishes text`, async (t) => { + const event = { + data: { + data: Buffer.from(JSON.stringify({ text, filename, lang })).toString(`base64`) + } + }; + const sample = getSample(); - return sample.program.saveResult(event) - .then(() => { - assert.equal(console.log.callCount, 3); - assert.deepEqual(console.log.getCall(0).args, [`Received request to save file ${filename}`]); - assert.deepEqual(console.log.getCall(1).args, [`Saving result to ${filename}_to_${lang}.txt in bucket ${sample.mocks.config.RESULT_BUCKET}`]); - assert.deepEqual(console.log.getCall(2).args, [`File saved.`]); - }); - }); + await sample.program.saveResult(event); + t.is(console.log.callCount, 3); + t.deepEqual(console.log.getCall(0).args, [`Received request to save file ${filename}`]); + t.deepEqual(console.log.getCall(1).args, [`Saving result to ${filename}_to_${lang}.txt in bucket ${sample.mocks.config.RESULT_BUCKET}`]); + t.deepEqual(console.log.getCall(2).args, [`File saved.`]); +}); - it(`saveResult translates and publishes text with dot in filename`, () => { - const event = { - data: { - data: Buffer.from(JSON.stringify({ text, filename: `${filename}.jpg`, lang })).toString(`base64`) - } - }; - const sample = getSample(); +test.serial(`saveResult translates and publishes text with dot in filename`, async (t) => { + const event = { + data: { + data: Buffer.from(JSON.stringify({ text, filename: `${filename}.jpg`, lang })).toString(`base64`) + } + }; + const sample = getSample(); - return sample.program.saveResult(event) - .then(() => { - assert.equal(console.log.callCount, 3); - assert.deepEqual(console.log.getCall(0).args, [`Received request to save file ${filename}.jpg`]); - assert.deepEqual(console.log.getCall(1).args, [`Saving result to ${filename}.jpg_to_${lang}.txt in bucket ${sample.mocks.config.RESULT_BUCKET}`]); - assert.deepEqual(console.log.getCall(2).args, [`File saved.`]); - }); - }); + await sample.program.saveResult(event); + t.is(console.log.callCount, 3); + t.deepEqual(console.log.getCall(0).args, [`Received request to save file ${filename}.jpg`]); + t.deepEqual(console.log.getCall(1).args, [`Saving result to ${filename}.jpg_to_${lang}.txt in bucket ${sample.mocks.config.RESULT_BUCKET}`]); + t.deepEqual(console.log.getCall(2).args, [`File saved.`]); }); - diff --git a/functions/pubsub/index.js b/functions/pubsub/index.js index aeee11a7d6..5d51152ab2 100644 --- a/functions/pubsub/index.js +++ b/functions/pubsub/index.js @@ -63,6 +63,7 @@ exports.publish = function publish (req, res) { .catch((err) => { console.error(err); res.status(500).send(err); + return Promise.reject(err); }); }; // [END functions_pubsub_publish] diff --git a/functions/pubsub/test/index.test.js b/functions/pubsub/test/index.test.js index 6dd81a4ed9..27bd46ea17 100644 --- a/functions/pubsub/test/index.test.js +++ b/functions/pubsub/test/index.test.js @@ -15,6 +15,8 @@ 'use strict'; +require(`../../../test/_setup`); + const proxyquire = require(`proxyquire`).noCallThru(); const TOPIC = `topic`; @@ -51,87 +53,81 @@ function getSample () { }; } -describe(`functions:pubsub`, () => { - it(`Publish fails without a topic`, () => { - const expectedMsg = `Topic not provided. Make sure you have a "topic" property in your request`; - const sample = getSample(); - - delete sample.mocks.req.body.topic; - sample.program.publish(sample.mocks.req, sample.mocks.res); - - assert.deepEqual(sample.mocks.res.status.callCount, 1); - assert.deepEqual(sample.mocks.res.status.firstCall.args, [500]); - assert.deepEqual(sample.mocks.res.send.callCount, 1); - assert.equal(sample.mocks.res.send.firstCall.args[0].message, expectedMsg); - }); - - it(`Publish fails without a message`, () => { - const expectedMsg = `Message not provided. Make sure you have a "message" property in your request`; - const sample = getSample(); - - delete sample.mocks.req.body.message; - sample.program.publish(sample.mocks.req, sample.mocks.res); - - assert.deepEqual(sample.mocks.res.status.callCount, 1); - assert.deepEqual(sample.mocks.res.status.firstCall.args, [500]); - assert.deepEqual(sample.mocks.res.send.callCount, 1); - assert.equal(sample.mocks.res.send.firstCall.args[0].message, expectedMsg); - }); - - it(`Publishes the message to the topic and calls success`, () => { - const expectedMsg = `Message published.`; - const sample = getSample(); - - return sample.program.publish(sample.mocks.req, sample.mocks.res) - .then(() => { - assert.deepEqual(sample.mocks.topic.publish.callCount, 1); - assert.deepEqual(sample.mocks.topic.publish.firstCall.args, [{ - data: { - message: MESSAGE - } - }]); - assert.deepEqual(sample.mocks.res.status.callCount, 1); - assert.deepEqual(sample.mocks.res.status.firstCall.args, [200]); - assert.deepEqual(sample.mocks.res.send.callCount, 1); - assert.deepEqual(sample.mocks.res.send.firstCall.args, [expectedMsg]); - }); - }); - - it(`Fails to publish the message and calls failure`, () => { - const error = new Error(`error`); - const sample = getSample(); - sample.mocks.topic.publish.returns(Promise.reject(error)); - - return sample.program.publish(sample.mocks.req, sample.mocks.res) - .then(() => { - throw new Error(`Should have failed!`); - }) - .catch((err) => { - assert.deepEqual(err, error); - assert.deepEqual(console.error.callCount, 1); - assert.deepEqual(console.error.firstCall.args, [error]); - assert.deepEqual(sample.mocks.res.status.callCount, 1); - assert.deepEqual(sample.mocks.res.status.firstCall.args, [500]); - assert.deepEqual(sample.mocks.res.send.callCount, 1); - assert.deepEqual(sample.mocks.res.send.firstCall.args, [error]); - }); - }); - - it(`Subscribes to a message`, () => { - const callback = sinon.stub(); - const json = JSON.stringify({ data: MESSAGE }); - const event = { - data: { - data: Buffer.from(json).toString('base64') - } - }; +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); + +test.serial(`Publish fails without a topic`, (t) => { + const expectedMsg = `Topic not provided. Make sure you have a "topic" property in your request`; + const sample = getSample(); + + delete sample.mocks.req.body.topic; + sample.program.publish(sample.mocks.req, sample.mocks.res); + + t.deepEqual(sample.mocks.res.status.callCount, 1); + t.deepEqual(sample.mocks.res.status.firstCall.args, [500]); + t.deepEqual(sample.mocks.res.send.callCount, 1); + t.is(sample.mocks.res.send.firstCall.args[0].message, expectedMsg); +}); + +test.serial(`Publish fails without a message`, (t) => { + const expectedMsg = `Message not provided. Make sure you have a "message" property in your request`; + const sample = getSample(); + + delete sample.mocks.req.body.message; + sample.program.publish(sample.mocks.req, sample.mocks.res); + + t.deepEqual(sample.mocks.res.status.callCount, 1); + t.deepEqual(sample.mocks.res.status.firstCall.args, [500]); + t.deepEqual(sample.mocks.res.send.callCount, 1); + t.is(sample.mocks.res.send.firstCall.args[0].message, expectedMsg); +}); + +test.serial(`Publishes the message to the topic and calls success`, async (t) => { + const expectedMsg = `Message published.`; + const sample = getSample(); + + await sample.program.publish(sample.mocks.req, sample.mocks.res); + t.deepEqual(sample.mocks.topic.publish.callCount, 1); + t.deepEqual(sample.mocks.topic.publish.firstCall.args, [{ + data: { + message: MESSAGE + } + }]); + t.deepEqual(sample.mocks.res.status.callCount, 1); + t.deepEqual(sample.mocks.res.status.firstCall.args, [200]); + t.deepEqual(sample.mocks.res.send.callCount, 1); + t.deepEqual(sample.mocks.res.send.firstCall.args, [expectedMsg]); +}); + +test.serial(`Fails to publish the message and calls failure`, async (t) => { + const error = new Error(`error`); + const sample = getSample(); + sample.mocks.topic.publish.returns(Promise.reject(error)); + + const err = await t.throws(sample.program.publish(sample.mocks.req, sample.mocks.res)); + t.deepEqual(err, error); + t.deepEqual(console.error.callCount, 1); + t.deepEqual(console.error.firstCall.args, [error]); + t.deepEqual(sample.mocks.res.status.callCount, 1); + t.deepEqual(sample.mocks.res.status.firstCall.args, [500]); + t.deepEqual(sample.mocks.res.send.callCount, 1); + t.deepEqual(sample.mocks.res.send.firstCall.args, [error]); +}); + +test.serial(`Subscribes to a message`, (t) => { + const callback = sinon.stub(); + const json = JSON.stringify({ data: MESSAGE }); + const event = { + data: { + data: Buffer.from(json).toString('base64') + } + }; - const sample = getSample(); - sample.program.subscribe(event, callback); + const sample = getSample(); + sample.program.subscribe(event, callback); - assert.deepEqual(console.log.callCount, 1); - assert.deepEqual(console.log.firstCall.args, [json]); - assert.deepEqual(callback.callCount, 1); - assert.deepEqual(callback.firstCall.args, []); - }); + t.deepEqual(console.log.callCount, 1); + t.deepEqual(console.log.firstCall.args, [json]); + t.deepEqual(callback.callCount, 1); + t.deepEqual(callback.firstCall.args, []); }); diff --git a/functions/sendgrid/index.js b/functions/sendgrid/index.js index 7f51720608..4e792406f9 100644 --- a/functions/sendgrid/index.js +++ b/functions/sendgrid/index.js @@ -169,6 +169,7 @@ exports.sendgridEmail = function sendgridEmail (req, res) { console.error(err); const code = err.code || (err.response ? err.response.statusCode : 500) || 500; res.status(code).send(err); + return Promise.reject(err); }); }; // [END functions_sendgrid_email] @@ -260,6 +261,7 @@ exports.sendgridWebhook = function sendgridWebhook (req, res) { .catch((err) => { console.error(err); res.status(err.code || 500).send(err); + return Promise.reject(err); }); }; // [END functions_sendgrid_webhook] @@ -319,7 +321,7 @@ exports.sendgridLoad = function sendgridLoad (event) { .then(() => console.log(`Job complete for ${file.name}`)) .catch((err) => { console.log(`Job failed for ${file.name}`); - throw err; + return Promise.reject(err); }); }; // [END functions_sendgrid_load] diff --git a/functions/sendgrid/test/index.test.js b/functions/sendgrid/test/index.test.js index 804c5c5935..3f6d6f5f46 100644 --- a/functions/sendgrid/test/index.test.js +++ b/functions/sendgrid/test/index.test.js @@ -15,6 +15,8 @@ 'use strict'; +require(`../../../test/_setup`); + const proxyquire = require(`proxyquire`).noCallThru(); const method = `POST`; @@ -141,341 +143,318 @@ function getMocks () { }; } -describe(`functions:sendgrid`, () => { - it(`Send fails if not a POST request`, () => { - const error = new Error(`Only POST requests are accepted`); - error.code = 405; - const sample = getSample(); - const mocks = getMocks(); - - return sample.program.sendgridEmail(mocks.req, mocks.res) - .then(() => { - assert.equal(mocks.res.status.callCount, 1); - assert.deepEqual(mocks.res.status.firstCall.args, [error.code]); - assert.equal(mocks.res.send.callCount, 1); - assert.deepEqual(mocks.res.send.firstCall.args, [error]); - assert.equal(console.error.callCount, 1); - assert.deepEqual(console.error.firstCall.args, [error]); - }); - }); - - it(`Send fails without an API key`, () => { - const error = new Error(`SendGrid API key not provided. Make sure you have a "sg_key" property in your request querystring`); - error.code = 401; - const mocks = getMocks(); - - mocks.req.method = method; - - return getSample().program.sendgridEmail(mocks.req, mocks.res) - .then(() => { - assert.equal(mocks.res.status.callCount, 1); - assert.deepEqual(mocks.res.status.firstCall.args, [error.code]); - assert.equal(mocks.res.send.callCount, 1); - assert.deepEqual(mocks.res.send.firstCall.args, [error]); - assert.equal(console.error.callCount, 1); - assert.deepEqual(console.error.firstCall.args, [error]); - }); - }); - - it(`Send fails without a "to"`, () => { - const error = new Error(`To email address not provided. Make sure you have a "to" property in your request`); - error.code = 400; - const mocks = getMocks(); - - mocks.req.method = method; - mocks.req.query.sg_key = key; - return getSample().program.sendgridEmail(mocks.req, mocks.res) - .then(() => { - assert.equal(mocks.res.status.callCount, 1); - assert.deepEqual(mocks.res.status.firstCall.args, [error.code]); - assert.equal(mocks.res.send.callCount, 1); - assert.deepEqual(mocks.res.send.firstCall.args, [error]); - assert.equal(console.error.callCount, 1); - assert.deepEqual(console.error.firstCall.args, [error]); - }); - }); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); + +test.serial(`Send fails if not a POST request`, async (t) => { + const error = new Error(`Only POST requests are accepted`); + error.code = 405; + const sample = getSample(); + const mocks = getMocks(); + + const err = await t.throws(sample.program.sendgridEmail(mocks.req, mocks.res)); + t.deepEqual(err, error); + t.is(mocks.res.status.callCount, 1); + t.deepEqual(mocks.res.status.firstCall.args, [error.code]); + t.is(mocks.res.send.callCount, 1); + t.deepEqual(mocks.res.send.firstCall.args, [error]); + t.is(console.error.callCount, 1); + t.deepEqual(console.error.firstCall.args, [error]); +}); - it(`Send fails without a "from"`, () => { - const error = new Error(`From email address not provided. Make sure you have a "from" property in your request`); - error.code = 400; - const mocks = getMocks(); - - mocks.req.method = method; - mocks.req.query.sg_key = key; - mocks.req.body.to = to; - - return getSample().program.sendgridEmail(mocks.req, mocks.res) - .then(() => { - assert.equal(mocks.res.status.callCount, 1); - assert.deepEqual(mocks.res.status.firstCall.args, [error.code]); - assert.equal(mocks.res.send.callCount, 1); - assert.deepEqual(mocks.res.send.firstCall.args, [error]); - assert.equal(console.error.callCount, 1); - assert.deepEqual(console.error.firstCall.args, [error]); - }); - }); +test.serial(`Send fails without an API key`, async (t) => { + const error = new Error(`SendGrid API key not provided. Make sure you have a "sg_key" property in your request querystring`); + error.code = 401; + const mocks = getMocks(); + + mocks.req.method = method; + + const err = await t.throws(getSample().program.sendgridEmail(mocks.req, mocks.res)); + t.deepEqual(err, error); + t.is(mocks.res.status.callCount, 1); + t.deepEqual(mocks.res.status.firstCall.args, [error.code]); + t.is(mocks.res.send.callCount, 1); + t.deepEqual(mocks.res.send.firstCall.args, [error]); + t.is(console.error.callCount, 1); + t.deepEqual(console.error.firstCall.args, [error]); +}); - it(`Send fails without a "subject"`, () => { - const error = new Error(`Email subject line not provided. Make sure you have a "subject" property in your request`); - error.code = 400; - const mocks = getMocks(); - - mocks.req.method = method; - mocks.req.query.sg_key = key; - mocks.req.body.to = to; - mocks.req.body.from = from; - - return getSample().program.sendgridEmail(mocks.req, mocks.res) - .then(() => { - assert.equal(mocks.res.status.callCount, 1); - assert.deepEqual(mocks.res.status.firstCall.args, [error.code]); - assert.equal(mocks.res.send.callCount, 1); - assert.deepEqual(mocks.res.send.firstCall.args, [error]); - assert.equal(console.error.callCount, 1); - assert.deepEqual(console.error.firstCall.args, [error]); - }); - }); +test.serial(`Send fails without a "to"`, async (t) => { + const error = new Error(`To email address not provided. Make sure you have a "to" property in your request`); + error.code = 400; + const mocks = getMocks(); + + mocks.req.method = method; + mocks.req.query.sg_key = key; + const err = await t.throws(getSample().program.sendgridEmail(mocks.req, mocks.res)); + t.deepEqual(err, error); + t.is(mocks.res.status.callCount, 1); + t.deepEqual(mocks.res.status.firstCall.args, [error.code]); + t.is(mocks.res.send.callCount, 1); + t.deepEqual(mocks.res.send.firstCall.args, [error]); + t.is(console.error.callCount, 1); + t.deepEqual(console.error.firstCall.args, [error]); +}); - it(`Send fails without a "body"`, () => { - const error = new Error(`Email body not provided. Make sure you have a "body" property in your request`); - error.code = 400; - const mocks = getMocks(); - - mocks.req.method = method; - mocks.req.query.sg_key = key; - mocks.req.body.to = to; - mocks.req.body.from = from; - mocks.req.body.subject = subject; - - return getSample().program.sendgridEmail(mocks.req, mocks.res) - .then(() => { - assert.equal(mocks.res.status.callCount, 1); - assert.deepEqual(mocks.res.status.firstCall.args, [error.code]); - assert.equal(mocks.res.send.callCount, 1); - assert.deepEqual(mocks.res.send.firstCall.args, [error]); - assert.equal(console.error.callCount, 1); - assert.deepEqual(console.error.firstCall.args, [error]); - }); - }); +test.serial(`Send fails without a "from"`, async (t) => { + const error = new Error(`From email address not provided. Make sure you have a "from" property in your request`); + error.code = 400; + const mocks = getMocks(); + + mocks.req.method = method; + mocks.req.query.sg_key = key; + mocks.req.body.to = to; + + const err = await t.throws(getSample().program.sendgridEmail(mocks.req, mocks.res)); + t.deepEqual(err, error); + t.is(mocks.res.status.callCount, 1); + t.deepEqual(mocks.res.status.firstCall.args, [error.code]); + t.is(mocks.res.send.callCount, 1); + t.deepEqual(mocks.res.send.firstCall.args, [error]); + t.is(console.error.callCount, 1); + t.deepEqual(console.error.firstCall.args, [error]); +}); - it(`Handles response error`, () => { - const mocks = getMocks(); - const sample = getSample(); - - mocks.req.method = method; - mocks.req.query.sg_key = key; - mocks.req.body.to = to; - mocks.req.body.from = from; - mocks.req.body.subject = subject; - mocks.req.body.body = body; - sample.mocks.client.API.returns(Promise.resolve({ - statusCode: 500, - body: `error` - })); - - return sample.program.sendgridEmail(mocks.req, mocks.res) - .then(() => { - assert.equal(mocks.res.status.callCount, 1); - assert.deepEqual(mocks.res.status.firstCall.args, [500]); - assert.equal(mocks.res.send.callCount, 1); - assert.deepEqual(mocks.res.send.firstCall.args[0].message, `error`); - }); - }); +test.serial(`Send fails without a "subject"`, async (t) => { + const error = new Error(`Email subject line not provided. Make sure you have a "subject" property in your request`); + error.code = 400; + const mocks = getMocks(); + + mocks.req.method = method; + mocks.req.query.sg_key = key; + mocks.req.body.to = to; + mocks.req.body.from = from; + + const err = await t.throws(getSample().program.sendgridEmail(mocks.req, mocks.res)); + t.deepEqual(err, error); + t.is(mocks.res.status.callCount, 1); + t.deepEqual(mocks.res.status.firstCall.args, [error.code]); + t.is(mocks.res.send.callCount, 1); + t.deepEqual(mocks.res.send.firstCall.args, [error]); + t.is(console.error.callCount, 1); + t.deepEqual(console.error.firstCall.args, [error]); +}); - it(`Sends the email and successfully responds`, () => { - const mocks = getMocks(); - - mocks.req.method = method; - mocks.req.query.sg_key = key; - mocks.req.body.to = to; - mocks.req.body.from = from; - mocks.req.body.subject = subject; - mocks.req.body.body = body; - - return getSample().program.sendgridEmail(mocks.req, mocks.res) - .then(() => { - assert.equal(mocks.res.status.callCount, 1); - assert.deepEqual(mocks.res.status.firstCall.args, [200]); - assert.equal(mocks.res.send.callCount, 1); - assert.deepEqual(mocks.res.send.firstCall.args, [`success`]); - }); - }); +test.serial(`Send fails without a "body"`, async (t) => { + const error = new Error(`Email content not provided. Make sure you have a "body" property in your request`); + error.code = 400; + const mocks = getMocks(); + + mocks.req.method = method; + mocks.req.query.sg_key = key; + mocks.req.body.to = to; + mocks.req.body.from = from; + mocks.req.body.subject = subject; + + const err = await t.throws(getSample().program.sendgridEmail(mocks.req, mocks.res)); + t.deepEqual(err, error); + t.is(mocks.res.status.callCount, 1); + t.deepEqual(mocks.res.status.firstCall.args, [error.code]); + t.is(mocks.res.send.callCount, 1); + t.deepEqual(mocks.res.send.firstCall.args, [error]); + t.is(console.error.callCount, 1); + t.deepEqual(console.error.firstCall.args, [error]); +}); - it(`Handles empty response body`, () => { - const sample = getSample(); - const mocks = getMocks(); +test.serial(`Handles response error`, async (t) => { + const mocks = getMocks(); + const sample = getSample(); + + mocks.req.method = method; + mocks.req.query.sg_key = key; + mocks.req.body.to = to; + mocks.req.body.from = from; + mocks.req.body.subject = subject; + mocks.req.body.body = body; + sample.mocks.client.API.returns(Promise.resolve({ + statusCode: 500, + body: `error` + })); + + await t.throws(sample.program.sendgridEmail(mocks.req, mocks.res)); + t.is(mocks.res.status.callCount, 1); + t.deepEqual(mocks.res.status.firstCall.args, [500]); + t.is(mocks.res.send.callCount, 1); + t.deepEqual(mocks.res.send.firstCall.args[0].message, `error`); +}); - mocks.req.method = method; - mocks.req.query.sg_key = key; - mocks.req.body.to = to; - mocks.req.body.from = from; - mocks.req.body.subject = subject; - mocks.req.body.body = body; +test.serial(`Sends the email and successfully responds`, async (t) => { + const mocks = getMocks(); + + mocks.req.method = method; + mocks.req.query.sg_key = key; + mocks.req.body.to = to; + mocks.req.body.from = from; + mocks.req.body.subject = subject; + mocks.req.body.body = body; + + await getSample().program.sendgridEmail(mocks.req, mocks.res); + t.is(mocks.res.status.callCount, 1); + t.deepEqual(mocks.res.status.firstCall.args, [200]); + t.is(mocks.res.send.callCount, 1); + t.deepEqual(mocks.res.send.firstCall.args, [`success`]); +}); - sample.mocks.client.API.returns(Promise.resolve({ - statusCode: 200, - headers: {} - })); - - return sample.program.sendgridEmail(mocks.req, mocks.res) - .then(() => { - assert.equal(mocks.res.status.callCount, 1); - assert.deepEqual(mocks.res.status.firstCall.args, [200]); - assert.equal(mocks.res.end.callCount, 1); - assert.deepEqual(mocks.res.end.firstCall.args, []); - }); - }); +test.serial(`Handles empty response body`, async (t) => { + const sample = getSample(); + const mocks = getMocks(); + + mocks.req.method = method; + mocks.req.query.sg_key = key; + mocks.req.body.to = to; + mocks.req.body.from = from; + mocks.req.body.subject = subject; + mocks.req.body.body = body; + + sample.mocks.client.API.returns(Promise.resolve({ + statusCode: 200, + headers: {} + })); + + await sample.program.sendgridEmail(mocks.req, mocks.res); + t.is(mocks.res.status.callCount, 1); + t.deepEqual(mocks.res.status.firstCall.args, [200]); + t.is(mocks.res.end.callCount, 1); + t.deepEqual(mocks.res.end.firstCall.args, []); +}); - it(`Send fails if not a POST request`, () => { - const error = new Error(`Only POST requests are accepted`); - error.code = 405; - const sample = getSample(); - const mocks = getMocks(); - - return sample.program.sendgridWebhook(mocks.req, mocks.res) - .then(() => { - assert.equal(mocks.res.send.callCount, 1); - assert.deepEqual(mocks.res.send.firstCall.args, [error]); - assert.equal(console.error.callCount, 1); - assert.deepEqual(console.error.firstCall.args, [error]); - }); - }); +test.serial(`Send fails if not a POST request`, async (t) => { + const error = new Error(`Only POST requests are accepted`); + error.code = 405; + const sample = getSample(); + const mocks = getMocks(); + + const err = await t.throws(sample.program.sendgridWebhook(mocks.req, mocks.res)); + t.deepEqual(err, error); + t.is(mocks.res.send.callCount, 1); + t.deepEqual(mocks.res.send.firstCall.args, [error]); + t.is(console.error.callCount, 1); + t.deepEqual(console.error.firstCall.args, [error]); +}); - it(`Throws if no basic auth`, () => { - const error = new Error(`Invalid credentials`); - error.code = 401; - const sample = getSample(); - const mocks = getMocks(); - - mocks.req.method = method; - mocks.req.headers.authorization = ``; - - return sample.program.sendgridWebhook(mocks.req, mocks.res) - .then(() => { - assert.equal(mocks.res.send.callCount, 1); - assert.deepEqual(mocks.res.send.firstCall.args, [error]); - assert.equal(console.error.callCount, 1); - assert.deepEqual(console.error.firstCall.args, [error]); - }); - }); +test.serial(`Throws if no basic auth`, async (t) => { + const error = new Error(`Invalid credentials`); + error.code = 401; + const sample = getSample(); + const mocks = getMocks(); + + mocks.req.method = method; + mocks.req.headers.authorization = ``; + + const err = await t.throws(sample.program.sendgridWebhook(mocks.req, mocks.res)); + t.deepEqual(err, error); + t.is(mocks.res.send.callCount, 1); + t.deepEqual(mocks.res.send.firstCall.args, [error]); + t.is(console.error.callCount, 1); + t.deepEqual(console.error.firstCall.args, [error]); +}); - it(`Throws if invalid username`, () => { - const error = new Error(`Invalid credentials`); - error.code = 401; - const sample = getSample(); - const mocks = getMocks(); - - mocks.req.method = method; - mocks.req.headers.authorization = `Basic d3Jvbmc6YmFy`; - - return sample.program.sendgridWebhook(mocks.req, mocks.res) - .then(() => { - assert.equal(mocks.res.send.callCount, 1); - assert.deepEqual(mocks.res.send.firstCall.args, [error]); - assert.equal(console.error.callCount, 1); - assert.deepEqual(console.error.firstCall.args, [error]); - }); - }); +test.serial(`Throws if invalid username`, async (t) => { + const error = new Error(`Invalid credentials`); + error.code = 401; + const sample = getSample(); + const mocks = getMocks(); + + mocks.req.method = method; + mocks.req.headers.authorization = `Basic d3Jvbmc6YmFy`; + + const err = await t.throws(sample.program.sendgridWebhook(mocks.req, mocks.res)); + t.deepEqual(err, error); + t.is(mocks.res.send.callCount, 1); + t.deepEqual(mocks.res.send.firstCall.args, [error]); + t.is(console.error.callCount, 1); + t.deepEqual(console.error.firstCall.args, [error]); +}); - it(`Throws if invalid password`, () => { - const error = new Error(`Invalid credentials`); - error.code = 401; - const sample = getSample(); - const mocks = getMocks(); - - mocks.req.method = method; - mocks.req.headers.authorization = `Basic Zm9vOndyb25n`; - - return sample.program.sendgridWebhook(mocks.req, mocks.res) - .then(() => { - assert.equal(mocks.res.send.callCount, 1); - assert.deepEqual(mocks.res.send.firstCall.args, [error]); - assert.equal(console.error.callCount, 1); - assert.deepEqual(console.error.firstCall.args, [error]); - }); - }); +test.serial(`Throws if invalid password`, async (t) => { + const error = new Error(`Invalid credentials`); + error.code = 401; + const sample = getSample(); + const mocks = getMocks(); + + mocks.req.method = method; + mocks.req.headers.authorization = `Basic Zm9vOndyb25n`; + + const err = await t.throws(sample.program.sendgridWebhook(mocks.req, mocks.res)); + t.deepEqual(err, error); + t.is(mocks.res.send.callCount, 1); + t.deepEqual(mocks.res.send.firstCall.args, [error]); + t.is(console.error.callCount, 1); + t.deepEqual(console.error.firstCall.args, [error]); +}); - it(`Calls "end" if no events`, () => { - const sample = getSample(); - const mocks = getMocks(); +test.serial(`Calls "end" if no events`, async (t) => { + const sample = getSample(); + const mocks = getMocks(); - mocks.req.method = method; - mocks.req.headers.authorization = auth; - mocks.req.body = undefined; + mocks.req.method = method; + mocks.req.headers.authorization = auth; + mocks.req.body = undefined; - return sample.program.sendgridWebhook(mocks.req, mocks.res) - .then(() => { - assert.equal(mocks.res.end.callCount, 1); - assert.deepEqual(mocks.res.end.firstCall.args, []); - }); - }); + await sample.program.sendgridWebhook(mocks.req, mocks.res); + t.is(mocks.res.end.callCount, 1); + t.deepEqual(mocks.res.end.firstCall.args, []); +}); - it(`Saves files`, () => { - const sample = getSample(); - const mocks = getMocks(); - - mocks.req.method = `POST`; - mocks.req.headers.authorization = auth; - mocks.req.body = events; - sample.mocks.uuid.v4 = sinon.stub().returns(`1357`); - - return sample.program.sendgridWebhook(mocks.req, mocks.res) - .then(() => { - const filename = sample.mocks.bucket.file.firstCall.args[0]; - assert.equal(mocks.res.status.callCount, 1); - assert.deepEqual(mocks.res.status.firstCall.args, [200]); - assert.equal(mocks.res.end.callCount, 1); - assert.deepEqual(console.log.getCall(0).args, [`Saving events to ${filename} in bucket ${sample.mocks.config.EVENT_BUCKET}`]); - assert.deepEqual(console.log.getCall(1).args, [`JSON written to ${filename}`]); - }); - }); +test.serial(`Saves files`, async (t) => { + const sample = getSample(); + const mocks = getMocks(); + + mocks.req.method = `POST`; + mocks.req.headers.authorization = auth; + mocks.req.body = events; + sample.mocks.uuid.v4 = sinon.stub().returns(`1357`); + + await sample.program.sendgridWebhook(mocks.req, mocks.res); + const filename = sample.mocks.bucket.file.firstCall.args[0]; + t.is(mocks.res.status.callCount, 1); + t.deepEqual(mocks.res.status.firstCall.args, [200]); + t.is(mocks.res.end.callCount, 1); + t.deepEqual(console.log.getCall(0).args, [`Saving events to ${filename} in bucket ${sample.mocks.config.EVENT_BUCKET}`]); + t.deepEqual(console.log.getCall(1).args, [`JSON written to ${filename}`]); +}); - it(`sendgridLoad does nothing on delete`, () => { - return getSample().program.sendgridLoad({ - data: { - resourceState: `not_exists` - } - }); +test.serial(`sendgridLoad does nothing on delete`, (t) => { + return getSample().program.sendgridLoad({ + data: { + resourceState: `not_exists` + } }); +}); - it(`sendgridLoad fails without a bucket`, () => { - const error = new Error(`Bucket not provided. Make sure you have a "bucket" property in your request`); - const event = { - data: {} - }; +test.serial(`sendgridLoad fails without a bucket`, async (t) => { + const error = new Error(`Bucket not provided. Make sure you have a "bucket" property in your request`); + const event = { + data: {} + }; - return getSample().program.sendgridLoad(event) - .then(() => assert.fail(`Should have failed!`)) - .catch((err) => assert.deepEqual(err, error)); - }); + const err = await t.throws(getSample().program.sendgridLoad(event)); + t.deepEqual(err, error); +}); - it(`sendgridLoad fails without a name`, () => { - const error = new Error(`Filename not provided. Make sure you have a "name" property in your request`); - const event = { - data: { - bucket: `event-bucket` - } - }; +test.serial(`sendgridLoad fails without a name`, async (t) => { + const error = new Error(`Filename not provided. Make sure you have a "name" property in your request`); + const event = { + data: { + bucket: `event-bucket` + } + }; - return getSample().program.sendgridLoad(event) - .then(() => assert.fail(`Should have failed!`)) - .catch((err) => assert.deepEqual(err, error)); - }); + const err = await t.throws(getSample().program.sendgridLoad(event)); + t.deepEqual(err, error); +}); - it(`starts a load job`, () => { - const sample = getSample(); - const name = `1234.json`; - const event = { - data: { - bucket: `event-bucket`, - name: name - } - }; +test.serial(`starts a load job`, async (t) => { + const sample = getSample(); + const name = `1234.json`; + const event = { + data: { + bucket: `event-bucket`, + name: name + } + }; - return sample.program.sendgridLoad(event) - .then(() => { - assert.deepEqual(console.log.getCall(0).args, [`Starting job for ${name}`]); - assert.deepEqual(console.log.getCall(1).args, [`Job complete for ${name}`]); - }); - }); + await sample.program.sendgridLoad(event); + t.deepEqual(console.log.getCall(0).args, [`Starting job for ${name}`]); + t.deepEqual(console.log.getCall(1).args, [`Job complete for ${name}`]); }); diff --git a/functions/slack/index.js b/functions/slack/index.js index 2a86e56a93..a06180c4fb 100644 --- a/functions/slack/index.js +++ b/functions/slack/index.js @@ -159,6 +159,7 @@ exports.kgSearch = function kgSearch (req, res) { .catch((err) => { console.error(err); res.status(err.code || 500).send(err); + return Promise.reject(err); }); }; // [END functions_slack_search] diff --git a/functions/slack/test/index.test.js b/functions/slack/test/index.test.js index a011955426..411c5bdfd7 100644 --- a/functions/slack/test/index.test.js +++ b/functions/slack/test/index.test.js @@ -15,6 +15,8 @@ 'use strict'; +require(`../../../test/_setup`); + const proxyquire = require(`proxyquire`).noCallThru(); const method = `POST`; @@ -81,164 +83,156 @@ function getMocks () { }; } -describe(`functions:slack`, () => { - it(`Send fails if not a POST request`, () => { - const error = new Error(`Only POST requests are accepted`); - error.code = 405; - const mocks = getMocks(); - const sample = getSample(); - - return sample.program.kgSearch(mocks.req, mocks.res) - .then(() => { - assert.equal(mocks.res.status.callCount, 1); - assert.deepEqual(mocks.res.status.firstCall.args, [error.code]); - assert.equal(mocks.res.send.callCount, 1); - assert.deepEqual(mocks.res.send.firstCall.args, [error]); - assert.equal(console.error.callCount, 1); - assert.deepEqual(console.error.firstCall.args, [error]); - }); - }); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); + +test.serial(`Send fails if not a POST request`, async (t) => { + const error = new Error(`Only POST requests are accepted`); + error.code = 405; + const mocks = getMocks(); + const sample = getSample(); + + const err = await t.throws(sample.program.kgSearch(mocks.req, mocks.res)); + t.deepEqual(err, error); + t.is(mocks.res.status.callCount, 1); + t.deepEqual(mocks.res.status.firstCall.args, [error.code]); + t.is(mocks.res.send.callCount, 1); + t.deepEqual(mocks.res.send.firstCall.args, [error]); + t.is(console.error.callCount, 1); + t.deepEqual(console.error.firstCall.args, [error]); +}); - it(`Throws if invalid slack token`, () => { - const error = new Error(`Invalid credentials`); - error.code = 401; - const mocks = getMocks(); - const sample = getSample(); - - mocks.req.method = method; - mocks.req.body.token = 'wrong'; - return sample.program.kgSearch(mocks.req, mocks.res) - .then(() => { - assert.equal(mocks.res.status.callCount, 1); - assert.deepEqual(mocks.res.status.firstCall.args, [error.code]); - assert.equal(mocks.res.send.callCount, 1); - assert.deepEqual(mocks.res.send.firstCall.args, [error]); - assert.equal(console.error.callCount, 1); - assert.deepEqual(console.error.firstCall.args, [error]); - }); - }); +test.serial(`Throws if invalid slack token`, async (t) => { + const error = new Error(`Invalid credentials`); + error.code = 401; + const mocks = getMocks(); + const sample = getSample(); + + mocks.req.method = method; + mocks.req.body.token = 'wrong'; + const err = await t.throws(sample.program.kgSearch(mocks.req, mocks.res)); + t.deepEqual(err, error); + t.is(mocks.res.status.callCount, 1); + t.deepEqual(mocks.res.status.firstCall.args, [error.code]); + t.is(mocks.res.send.callCount, 1); + t.deepEqual(mocks.res.send.firstCall.args, [error]); + t.is(console.error.callCount, 1); + t.deepEqual(console.error.firstCall.args, [error]); +}); - it(`Handles search error`, () => { - const error = new Error(`error`); - const mocks = getMocks(); - const sample = getSample(); - - mocks.req.method = method; - mocks.req.body.token = SLACK_TOKEN; - mocks.req.body.text = query; - sample.mocks.kgsearch.entities.search.yields(error); - - return sample.program.kgSearch(mocks.req, mocks.res) - .then(() => { - assert.equal(mocks.res.status.callCount, 1); - assert.deepEqual(mocks.res.status.firstCall.args, [500]); - assert.equal(mocks.res.send.callCount, 1); - assert.deepEqual(mocks.res.send.firstCall.args, [error]); - assert.equal(console.error.callCount, 1); - assert.deepEqual(console.error.firstCall.args, [error]); - }); - }); +test.serial(`Handles search error`, async (t) => { + const error = new Error(`error`); + const mocks = getMocks(); + const sample = getSample(); + + mocks.req.method = method; + mocks.req.body.token = SLACK_TOKEN; + mocks.req.body.text = query; + sample.mocks.kgsearch.entities.search.yields(error); + + const err = await t.throws(sample.program.kgSearch(mocks.req, mocks.res)); + t.deepEqual(err, error); + t.is(mocks.res.status.callCount, 1); + t.deepEqual(mocks.res.status.firstCall.args, [500]); + t.is(mocks.res.send.callCount, 1); + t.deepEqual(mocks.res.send.firstCall.args, [error]); + t.is(console.error.callCount, 1); + t.deepEqual(console.error.firstCall.args, [error]); +}); - it(`Makes search request, receives empty results`, () => { - const mocks = getMocks(); - const sample = getSample(); - - mocks.req.method = method; - mocks.req.body.token = SLACK_TOKEN; - mocks.req.body.text = query; - sample.mocks.kgsearch.entities.search.yields(null, { itemListElement: [] }); - - return sample.program.kgSearch(mocks.req, mocks.res) - .then(() => { - assert.equal(mocks.res.json.callCount, 1); - assert.deepEqual(mocks.res.json.firstCall.args, [{ - text: `Query: ${query}`, - response_type: `in_channel`, - attachments: [ - { - text: `No results match your query...` - } - ] - }]); - }); - }); +test.serial(`Makes search request, receives empty results`, async (t) => { + const mocks = getMocks(); + const sample = getSample(); + + mocks.req.method = method; + mocks.req.body.token = SLACK_TOKEN; + mocks.req.body.text = query; + sample.mocks.kgsearch.entities.search.yields(null, { itemListElement: [] }); + + await sample.program.kgSearch(mocks.req, mocks.res); + t.is(mocks.res.json.callCount, 1); + t.deepEqual(mocks.res.json.firstCall.args, [{ + text: `Query: ${query}`, + response_type: `in_channel`, + attachments: [ + { + text: `No results match your query...` + } + ] + }]); +}); - it(`Makes search request, receives non-empty results`, () => { - const mocks = getMocks(); - const sample = getSample(); - - mocks.req.method = method; - mocks.req.body.token = SLACK_TOKEN; - mocks.req.body.text = query; - sample.mocks.kgsearch.entities.search.yields(null, { - itemListElement: [ - { - result: { - name: `Giraffe`, - description: `Animal`, - detailedDescription: { - url: `http://domain.com/giraffe`, - articleBody: `giraffe is a tall animal` - }, - image: { - contentUrl: `http://domain.com/image.jpg` - } +test.serial(`Makes search request, receives non-empty results`, async (t) => { + const mocks = getMocks(); + const sample = getSample(); + + mocks.req.method = method; + mocks.req.body.token = SLACK_TOKEN; + mocks.req.body.text = query; + sample.mocks.kgsearch.entities.search.yields(null, { + itemListElement: [ + { + result: { + name: `Giraffe`, + description: `Animal`, + detailedDescription: { + url: `http://domain.com/giraffe`, + articleBody: `giraffe is a tall animal` + }, + image: { + contentUrl: `http://domain.com/image.jpg` } } - ] - }); - - return sample.program.kgSearch(mocks.req, mocks.res) - .then(() => { - assert.equal(mocks.res.json.callCount, 1); - assert.deepEqual(mocks.res.json.firstCall.args, [{ - text: `Query: ${query}`, - response_type: `in_channel`, - attachments: [ - { - color: `#3367d6`, - title: `Giraffe: Animal`, - title_link: `http://domain.com/giraffe`, - text: `giraffe is a tall animal`, - image_url: `http://domain.com/image.jpg` - } - ] - }]); - }); + } + ] }); - it(`Makes search request, receives non-empty results but partial data`, () => { - const mocks = getMocks(); - const sample = getSample(); - - mocks.req.method = method; - mocks.req.body.token = SLACK_TOKEN; - mocks.req.body.text = query; - sample.mocks.kgsearch.entities.search.yields(null, { - itemListElement: [ - { - result: { - name: `Giraffe`, - detailedDescription: {}, - image: {} - } + await sample.program.kgSearch(mocks.req, mocks.res); + t.is(mocks.res.json.callCount, 1); + t.deepEqual(mocks.res.json.firstCall.args, [{ + text: `Query: ${query}`, + response_type: `in_channel`, + attachments: [ + { + color: `#3367d6`, + title: `Giraffe: Animal`, + title_link: `http://domain.com/giraffe`, + text: `giraffe is a tall animal`, + image_url: `http://domain.com/image.jpg` + } + ] + }]); +}); + +test.serial(`Makes search request, receives non-empty results but partial data`, async (t) => { + const mocks = getMocks(); + const sample = getSample(); + + mocks.req.method = method; + mocks.req.body.token = SLACK_TOKEN; + mocks.req.body.text = query; + sample.mocks.kgsearch.entities.search.yields(null, { + itemListElement: [ + { + result: { + name: `Giraffe`, + detailedDescription: {}, + image: {} } - ] - }); - - return sample.program.kgSearch(mocks.req, mocks.res) - .then(() => { - assert.equal(mocks.res.json.callCount, 1); - assert.deepEqual(mocks.res.json.firstCall.args, [{ - text: `Query: ${query}`, - response_type: `in_channel`, - attachments: [ - { - color: `#3367d6`, - title: `Giraffe` - } - ] - }]); - }); + } + ] }); + + await sample.program.kgSearch(mocks.req, mocks.res); + t.is(mocks.res.json.callCount, 1); + t.deepEqual(mocks.res.json.firstCall.args, [{ + text: `Query: ${query}`, + response_type: `in_channel`, + attachments: [ + { + color: `#3367d6`, + title: `Giraffe` + } + ] + }]); }); diff --git a/functions/uuid/test/index.test.js b/functions/uuid/test/index.test.js index 6079441d80..2c3400814f 100644 --- a/functions/uuid/test/index.test.js +++ b/functions/uuid/test/index.test.js @@ -15,17 +15,17 @@ 'use strict'; +require(`../../../test/_setup`); + const uuidSample = require('../'); -describe(`functions:uuid`, () => { - it(`should generate a uuid`, () => { - const callback = sinon.stub(); +test(`should generate a uuid`, (t) => { + const callback = sinon.stub(); - uuidSample.uuid({}, callback); + uuidSample.uuid({}, callback); - assert.equal(callback.callCount, 1); - assert.strictEqual(callback.firstCall.args[0], null); - assert.equal(typeof callback.firstCall.args[1], `string`); - assert.equal(callback.firstCall.args[1].length, 36); - }); + t.is(callback.callCount, 1); + t.is(callback.firstCall.args[0], null); + t.is(typeof callback.firstCall.args[1], `string`); + t.is(callback.firstCall.args[1].length, 36); }); diff --git a/language/slackbot/demo_bot.js b/language/slackbot/demo_bot.js index c59fa0d5f6..59e20e3940 100755 --- a/language/slackbot/demo_bot.js +++ b/language/slackbot/demo_bot.js @@ -146,6 +146,7 @@ function handleEntitiesReply (bot, message) { // Query the database for the top N entities in the past week const queryTs = Math.floor(Date.now() / 1000) - SEVEN_DAYS_AGO; + // const entitiesWeekSql = `select * from entities`; const entitiesWeekSql = `${ENTITIES_BASE_SQL} WHERE ts > ${queryTs}${ENTITIES_SQL}`; db.all(entitiesWeekSql, (err, topEntities) => { if (err) { diff --git a/language/slackbot/demo_bot.test.js b/language/slackbot/demo_bot.test.js deleted file mode 100644 index 1c9fde810c..0000000000 --- a/language/slackbot/demo_bot.test.js +++ /dev/null @@ -1,156 +0,0 @@ -/** - * Copyright 2016, Google, Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -const fs = require(`fs`); -const path = require(`path`); -const proxyquire = require(`proxyquire`).noCallThru(); -const sqlite3 = require(`sqlite3`).verbose(); - -const DB_PATH = path.join(__dirname, `./slackDB.db`); -const SLACK_TOKEN_PATH = path.join(__dirname, `./.token`); -const text = `President Obama is speaking at the White House.`; - -describe(`demo_bot`, () => { - let db, controllerMock, botkitMock, botMock, program; - - before((done) => { - fs.unlink(DB_PATH, (err) => { - if (err && err.code !== `ENOENT`) { - done(err); - return; - } - - db = new sqlite3.cached.Database(DB_PATH); - controllerMock = { - spawn: sinon.stub().returnsThis(), - startRTM: sinon.stub().returnsThis(), - hears: sinon.stub().returnsThis(), - on: sinon.stub().returnsThis() - }; - - botkitMock = { - slackbot: sinon.stub().returns(controllerMock) - }; - - botMock = { - reply: sinon.stub() - }; - - program = proxyquire(`./demo_bot`, { - botkit: botkitMock - }); - - db.run(program.TABLE_SQL, done); - }); - }); - - after((done) => { - fs.unlink(DB_PATH, (err) => { - if (err) { - done(err); - return; - } - fs.unlink(SLACK_TOKEN_PATH, done); - }); - }); - - it(`should analyze sentiment in text`, () => { - return program.analyzeSentiment(text) - .then((sentiment) => { - assert.equal(sentiment > 0, true); - }); - }); - - it(`should analyze entities in text`, () => { - return program.analyzeEntities(text, 1234) - .then((entities) => { - assert.equal(entities.some((entity) => entity.name === `Obama`), true); - assert.equal(entities.some((entity) => entity.name === `White House`), true); - - return new Promise((resolve, reject) => { - setTimeout(() => { - db.all(program.ENTITIES_SQL, (err, entities) => { - if (err) { - reject(err); - return; - } - assert.equal(entities.some((entity) => entity.name === `Obama`), true); - assert.equal(entities.some((entity) => entity.name === `White House`), true); - resolve(); - }); - }, 1000); - }); - }); - }); - - it(`should reply to simple hello message`, () => { - const message = {}; - - program.handleSimpleReply(botMock, message); - - assert.equal(botMock.reply.callCount, 1); - assert.deepEqual(botMock.reply.getCall(0).args, [message, `Hello.`]); - }); - - it(`should reply to entities message`, (done) => { - const message = {}; - - program.handleEntitiesReply(botMock, message); - - setTimeout(() => { - assert.equal(botMock.reply.callCount, 3); - assert.deepEqual(botMock.reply.getCall(1).args, [message, `Top entities: `]); - assert.deepEqual(botMock.reply.getCall(2).args, [message, `entity: *Obama*, type: PERSON, count: 1\nentity: *White House*, type: LOCATION, count: 1\n`]); - done(); - }, 1000); - }); - - describe(`startController`, () => { - let originalToken; - - before(() => { - originalToken = process.env.SLACK_TOKEN_PATH; - }); - - after(() => { - process.env.SLACK_TOKEN_PATH = originalToken; - }); - - it(`should check SLACK_TOKEN_PATH`, () => { - process.env.SLACK_TOKEN_PATH = ``; - - assert.throws(() => { - program.startController(); - }, Error, `Please set the SLACK_TOKEN_PATH environment variable!`); - }); - - it(`should start the controller`, () => { - let controller; - - fs.writeFileSync(SLACK_TOKEN_PATH, `test`, { encoding: `utf8` }); - process.env.SLACK_TOKEN_PATH = SLACK_TOKEN_PATH; - - controller = program.startController(); - - assert.strictEqual(controller, controllerMock); - assert.equal(controllerMock.spawn.callCount, 1); - assert.equal(controllerMock.startRTM.callCount, 1); - assert.equal(controllerMock.hears.callCount, 2); - assert.equal(controllerMock.on.callCount, 1); - }); - }); -}); diff --git a/language/slackbot/package.json b/language/slackbot/package.json index b3f51eccfb..d32c30804a 100644 --- a/language/slackbot/package.json +++ b/language/slackbot/package.json @@ -12,7 +12,7 @@ "sqlite3": "^3.1.8" }, "scripts": { - "test": "cd ../..; npm run st -- language/slackbot/*.test.js" + "test": "cd ../..; npm run st -- language/slackbot/system-test/*.test.js" }, "engines": { "node": ">=4.3.2" diff --git a/language/slackbot/system-test/controller.test.js b/language/slackbot/system-test/controller.test.js new file mode 100644 index 0000000000..267bf27ae3 --- /dev/null +++ b/language/slackbot/system-test/controller.test.js @@ -0,0 +1,83 @@ +/** + * Copyright 2016, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +require(`../../../system-test/_setup`); + +const fs = require(`fs`); +const path = require(`path`); +const proxyquire = require(`proxyquire`).noCallThru(); + +const SLACK_TOKEN_PATH = path.join(__dirname, `../.token`); + +let controllerMock, botkitMock, program, originalToken; + +test.before((t) => { + originalToken = process.env.SLACK_TOKEN_PATH; + controllerMock = { + spawn: sinon.stub().returnsThis(), + startRTM: sinon.stub().returnsThis(), + hears: sinon.stub().returnsThis(), + on: sinon.stub().returnsThis() + }; + botkitMock = { + slackbot: sinon.stub().returns(controllerMock) + }; + program = proxyquire(`../demo_bot`, { + botkit: botkitMock, + sqlite3: { + verbose: sinon.stub().returns({ + cached: { + Database: sinon.stub().returns({ + run: sinon.stub() + }) + } + }) + } + }); +}); + +test.after((t) => { + process.env.SLACK_TOKEN_PATH = originalToken; + try { + fs.unlinkSync(SLACK_TOKEN_PATH); + } catch (err) { + // Ignore error + } +}); + +test(`should check SLACK_TOKEN_PATH`, (t) => { + process.env.SLACK_TOKEN_PATH = ``; + + t.throws(() => { + program.startController(); + }, Error, `Please set the SLACK_TOKEN_PATH environment variable!`); +}); + +test(`should start the controller`, (t) => { + let controller; + + fs.writeFileSync(SLACK_TOKEN_PATH, `test`, { encoding: `utf8` }); + process.env.SLACK_TOKEN_PATH = SLACK_TOKEN_PATH; + + controller = program.startController(); + + t.is(controller === controllerMock, true); + t.is(controllerMock.spawn.callCount, 1); + t.is(controllerMock.startRTM.callCount, 1); + t.is(controllerMock.hears.callCount, 2); + t.is(controllerMock.on.callCount, 2); +}); diff --git a/language/slackbot/system-test/demo_bot.test.js b/language/slackbot/system-test/demo_bot.test.js new file mode 100644 index 0000000000..7c08120592 --- /dev/null +++ b/language/slackbot/system-test/demo_bot.test.js @@ -0,0 +1,126 @@ +/** + * Copyright 2016, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +require(`../../../system-test/_setup`); + +const fs = require(`fs`); +const path = require(`path`); +const proxyquire = require(`proxyquire`).noCallThru(); +const sqlite3 = require(`sqlite3`).verbose(); + +const DB_PATH = path.join(__dirname, `../slackDB.db`); +const SLACK_TOKEN_PATH = path.join(__dirname, `../.token`); +const text = `President Obama is speaking at the White House.`; + +let db, controllerMock, botkitMock, botMock, program; + +test.before.cb((t) => { + fs.unlink(DB_PATH, (err) => { + if (err && err.code !== `ENOENT`) { + t.end(err); + return; + } + + db = new sqlite3.cached.Database(DB_PATH); + controllerMock = { + spawn: sinon.stub().returnsThis(), + startRTM: sinon.stub().returnsThis(), + hears: sinon.stub().returnsThis(), + on: sinon.stub().returnsThis() + }; + + botkitMock = { + slackbot: sinon.stub().returns(controllerMock) + }; + + botMock = { + reply: sinon.stub() + }; + + program = proxyquire(`../demo_bot`, { + botkit: botkitMock + }); + + db.run(program.TABLE_SQL, t.end); + }); +}); + +test.after.cb((t) => { + fs.unlink(DB_PATH, (err) => { + if (err) { + t.end(err); + return; + } + try { + fs.unlinkSync(SLACK_TOKEN_PATH); + } catch (err) { + // Ignore error + } + t.end(); + }); +}); + +test.serial(`should analyze sentiment in text`, async (t) => { + const sentiment = await program.analyzeSentiment(text); + t.is(sentiment > 0, true); +}); + +test.serial(`should analyze entities in text`, async (t) => { + const entities = await program.analyzeEntities(text, Date.now()); + t.is(entities.some((entity) => entity.name === `Obama`), true); + t.is(entities.some((entity) => entity.name === `White House`), true); + + await new Promise((resolve, reject) => { + setTimeout(() => { + db.all(`select * from entities`, (err, entities) => { + if (err) { + reject(err); + return; + } + t.is(entities.some((entity) => entity.name === `Obama`), true); + t.is(entities.some((entity) => entity.name === `White House`), true); + resolve(); + }); + }, 1000); + }); +}); + +test.serial(`should reply to simple hello message`, (t) => { + const message = {}; + + program.handleSimpleReply(botMock, message); + + t.is(botMock.reply.callCount, 1); + t.deepEqual(botMock.reply.getCall(0).args, [message, `Hello.`]); +}); + +test.cb.serial(`should reply to entities message`, (t) => { + const message = {}; + + program.handleEntitiesReply(botMock, message); + + setTimeout(() => { + try { + t.is(botMock.reply.callCount, 3); + t.deepEqual(botMock.reply.getCall(1).args, [message, `Top entities: `]); + t.deepEqual(botMock.reply.getCall(2).args, [message, `entity: *Obama*, type: PERSON, count: 1\nentity: *White House*, type: LOCATION, count: 1\n`]); + t.end(); + } catch (err) { + t.end(err); + } + }, 1000); +}); diff --git a/language/system-test/analyze.test.js b/language/system-test/analyze.test.js index f400799a28..16560e87c5 100644 --- a/language/system-test/analyze.test.js +++ b/language/system-test/analyze.test.js @@ -15,10 +15,11 @@ 'use strict'; +require(`../../system-test/_setup`); + const uuid = require(`uuid`); const path = require(`path`); const storage = require(`@google-cloud/storage`)(); -const run = require(`../../utils`).run; const cmd = `node analyze.js`; const cwd = path.join(__dirname, `..`); @@ -27,52 +28,57 @@ const fileName = `text.txt`; const localFilePath = path.join(__dirname, `../resources/text.txt`); const text = `President Obama is speaking at the White House.`; -describe(`language:analyze`, () => { - before(() => { - return storage.createBucket(bucketName) - .then((results) => results[0].upload(localFilePath)); - }); +test.before(async () => { + const [bucket] = await storage.createBucket(bucketName); + await bucket.upload(localFilePath); +}); - after(() => { - return storage.bucket(bucketName).deleteFiles({ force: true }) - .then(() => storage.bucket(bucketName).delete()); - }); +test.after(async () => { + const bucket = storage.bucket(bucketName); + await bucket.deleteFiles({ force: true }); + await bucket.deleteFiles({ force: true }); // Try a second time... + await bucket.delete(); +}); - it(`should analyze sentiment in text`, () => { - assert.equal(run(`${cmd} sentiment-text "${text}"`, cwd), `Sentiment: positive.`); - }); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); - it(`should analyze sentiment in a file`, () => { - assert.equal(run(`${cmd} sentiment-file ${bucketName} ${fileName}`, cwd), `Sentiment: positive.`); - }); +test(`should run sync recognize`, async (t) => { + const output = await runAsync(`${cmd} sentiment-text "${text}"`, cwd); + t.true(output.includes(`Sentiment: positive.`)); +}); - it(`should analyze entities in text`, () => { - const output = run(`${cmd} entities-text "${text}"`, cwd); - assert.equal(output.includes(`Entities:`), true); - assert.equal(output.includes(`people:`), true); - assert.equal(output.includes(`places:`), true); - }); +test(`should analyze sentiment in a file`, async (t) => { + const output = await runAsync(`${cmd} sentiment-file ${bucketName} ${fileName}`, cwd); + t.true(output.includes(`Sentiment: positive.`)); +}); - it('should analyze entities in a file', () => { - const output = run(`${cmd} entities-file ${bucketName} ${fileName}`, cwd); - assert.equal(output.includes(`Entities:`), true); - assert.equal(output.includes(`people:`), true); - assert.equal(output.includes(`places:`), true); - }); +test(`should analyze entities in text`, async (t) => { + const output = await runAsync(`${cmd} entities-text "${text}"`, cwd); + t.true(output.includes(`Entities:`)); + t.true(output.includes(`people:`)); + t.true(output.includes(`places:`)); +}); + +test('should analyze entities in a file', async (t) => { + const output = await runAsync(`${cmd} entities-file ${bucketName} ${fileName}`, cwd); + t.true(output.includes(`Entities:`)); + t.true(output.includes(`people:`)); + t.true(output.includes(`places:`)); +}); - it(`should analyze syntax in text`, () => { - const output = run(`${cmd} syntax-text "${text}"`, cwd); - assert.equal(output.includes(`Tags:`), true); - assert.equal(output.includes(`NOUN`), true); - assert.equal(output.includes(`VERB`), true); - assert.equal(output.includes(`PUNCT`), true); - }); +test(`should analyze syntax in text`, async (t) => { + const output = await runAsync(`${cmd} syntax-text "${text}"`, cwd); + t.true(output.includes(`Tags:`)); + t.true(output.includes(`NOUN`)); + t.true(output.includes(`VERB`)); + t.true(output.includes(`PUNCT`)); +}); - it('should analyze syntax in a file', () => { - const output = run(`${cmd} syntax-file ${bucketName} ${fileName}`, cwd); - assert.equal(output.includes(`Tags:`), true); - assert.equal(output.includes(`NOUN`), true); - assert.equal(output.includes(`VERB`), true); - assert.equal(output.includes(`PUNCT`), true); - }); +test('should analyze syntax in a file', async (t) => { + const output = await runAsync(`${cmd} syntax-file ${bucketName} ${fileName}`, cwd); + t.true(output.includes(`Tags:`)); + t.true(output.includes(`NOUN`)); + t.true(output.includes(`VERB`)); + t.true(output.includes(`PUNCT`)); }); diff --git a/language/system-test/quickstart.test.js b/language/system-test/quickstart.test.js index 6b02ea0357..41cfb414d3 100644 --- a/language/system-test/quickstart.test.js +++ b/language/system-test/quickstart.test.js @@ -15,35 +15,41 @@ 'use strict'; +require(`../../system-test/_setup`); + const proxyquire = require(`proxyquire`).noPreserveCache(); const language = proxyquire(`@google-cloud/language`, {})(); -describe(`language:quickstart`, () => { - it(`should detect sentiment`, (done) => { - const expectedText = `Hello, world!`; - const languageMock = { - detectSentiment: (_text) => { - assert.equal(_text, expectedText); - - return language.detectSentiment(_text) - .then((results) => { - const sentiment = results[0]; - assert.equal(typeof sentiment, `number`); - - setTimeout(() => { - assert.equal(console.log.callCount, 2); - assert.deepEqual(console.log.getCall(0).args, [`Text: ${expectedText}`]); - assert.deepEqual(console.log.getCall(1).args, [`Sentiment: ${sentiment}`]); - done(); - }, 200); - - return results; - }); - } - }; - - proxyquire(`../quickstart`, { - '@google-cloud/language': sinon.stub().returns(languageMock) - }); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); + +test.cb(`should detect sentiment`, (t) => { + const expectedText = `Hello, world!`; + const languageMock = { + detectSentiment: (_text) => { + t.is(_text, expectedText); + + return language.detectSentiment(_text) + .then(([sentiment]) => { + t.is(typeof sentiment, `number`); + + setTimeout(() => { + try { + t.is(console.log.callCount, 2); + t.deepEqual(console.log.getCall(0).args, [`Text: ${expectedText}`]); + t.deepEqual(console.log.getCall(1).args, [`Sentiment: ${sentiment}`]); + t.end(); + } catch (err) { + t.end(err); + } + }, 200); + + return [sentiment]; + }); + } + }; + + proxyquire(`../quickstart`, { + '@google-cloud/language': sinon.stub().returns(languageMock) }); }); diff --git a/logging/quickstart.js b/logging/quickstart.js index c87353a607..88ba21c914 100644 --- a/logging/quickstart.js +++ b/logging/quickstart.js @@ -40,12 +40,8 @@ const metadata = { resource: { type: 'global' } }; const entry = log.entry(metadata, text); // Writes the log entry -log.write(entry, (err) => { - if (err) { - console.error(err); - return; - } - - console.log(`Logged: ${text}`); -}); +log.write(entry) + .then(() => { + console.log(`Logged: ${text}`); + }); // [END logging_quickstart] diff --git a/logging/system-test/fluent.test.js b/logging/system-test/fluent.test.js deleted file mode 100644 index 9ce35c1a57..0000000000 --- a/logging/system-test/fluent.test.js +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -'use strict'; - -describe('logging:fluent', function () { - it('should be tested'); -}); diff --git a/logging/system-test/logs.test.js b/logging/system-test/logs.test.js index b9669cfe1f..eee7e44148 100644 --- a/logging/system-test/logs.test.js +++ b/logging/system-test/logs.test.js @@ -13,60 +13,60 @@ 'use strict'; -var uuid = require('uuid'); -var program = require('../logs'); +require(`../../system-test/_setup`); -var logName = 'nodejs-docs-samples-test-' + uuid.v4(); -var projectId = process.env.GCLOUD_PROJECT; -var filter = 'resource.type="global" AND logName="projects/' + projectId + '/logs/' + logName + '"'; -var message = 'Hello world!'; +const uuid = require(`uuid`); +const program = require(`../logs`); -describe('logging:logs', function () { - describe('writeLogEntryAdvanced', function () { - it('should write a log entry', function (done) { - var options = { - resource: { - type: 'global' - }, - entry: { - message: message - } - }; +const logName = `nodejs-docs-samples-test-${uuid.v4()}`; +const projectId = process.env.GCLOUD_PROJECT; +const filter = `resource.type="global" AND logName="projects/${projectId}/logs/${logName}"`; +const message = `Hello world!`; - program.writeLogEntryAdvanced(logName, options, function (err, apiResponse) { - assert.ifError(err); - assert.notEqual(apiResponse, undefined); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); - // Logs are eventually consistent - setTimeout(done, 5000); - }); - }); - }); +test.cb.serial(`should write a log entry`, (t) => { + const options = { + resource: { + type: `global` + }, + entry: { + message: message + } + }; - describe('listLogEntriesAdvanced', function () { - it('should list log entries', function (done) { - program.listLogEntriesAdvanced(filter, 5, null, function (err, entries) { - assert.ifError(err); - assert(Array.isArray(entries), '"entries" should be an array.'); - var matchingEntries = entries.filter(function (entry) { - return entry.data && entry.data.message === message; - }); - assert.equal(matchingEntries.length, 1, 'Newly written entry should be in list.'); - done(); - }); - }); + program.writeLogEntryAdvanced(logName, options, (err, apiResponse) => { + t.ifError(err); + t.not(apiResponse, undefined); + t.end(); }); +}); - describe('deleteLog', function () { - it('should delete a log', function (done) { - program.deleteLog(logName, function (err, apiResponse) { - // Ignore "Not Found" error - if (err && err.code !== 404) { - assert.ifError(err); - assert.notEqual(apiResponse, undefined); +test.serial(`should list log entries`, async (t) => { + await tryTest(async () => { + await new Promise((resolve, reject) => { + program.listLogEntriesAdvanced(filter, 5, null, (err, entries) => { + try { + t.ifError(err); + t.true(Array.isArray(entries)); + t.true(entries.some((entry) => entry.data && entry.data.message === message)); + resolve(); + } catch (err) { + reject(err); } - done(); }); }); + }).start(); +}); + +test.cb.serial(`should delete a log`, (t) => { + program.deleteLog(logName, (err, apiResponse) => { + // Ignore "Not Found" error + if (err && err.code !== 404) { + t.ifError(err); + t.not(apiResponse, undefined); + } + t.end(); }); }); diff --git a/logging/system-test/quickstart.test.js b/logging/system-test/quickstart.test.js index 0c47367e65..fb864435d9 100644 --- a/logging/system-test/quickstart.test.js +++ b/logging/system-test/quickstart.test.js @@ -15,54 +15,59 @@ 'use strict'; +require(`../../system-test/_setup`); + const proxyquire = require(`proxyquire`).noPreserveCache(); const logging = proxyquire(`@google-cloud/logging`, {})(); const uuid = require(`uuid`); const logName = `nodejs-docs-samples-test-${uuid.v4()}`; -describe(`logging:quickstart`, () => { - let logMock, loggingMock, LoggingMock; +test.after(async () => { + try { + await logging.log(logName).delete(); + } catch (err) {} // ignore error +}); - after((done) => { - logging.log(logName).delete(() => { - // Ignore any error, the topic might not have been created - done(); - }); - }); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); + +test.cb(`should log an entry`, (t) => { + const expectedlogName = `my-log`; + + const logMock = { + entry: sinon.stub().returns({}), + write: (_entry) => { + t.deepEqual(_entry, {}); - it(`should log an entry`, (done) => { - const expectedlogName = `my-log`; + const log = logging.log(logName); + const text = `Hello, world!`; + const entry = log.entry({ resource: { type: `global` } }, text); - logMock = { - entry: sinon.stub().returns({}), - write: (_entry, _callback) => { - assert.deepEqual(_entry, {}); - assert.equal(typeof _callback, 'function'); + return log.write(entry) + .then((results) => { + setTimeout(() => { + try { + t.true(console.log.calledOnce); + t.deepEqual(console.log.firstCall.args, [`Logged: ${text}`]); + t.end(); + } catch (err) { + t.end(err); + } + }, 200); - const log = logging.log(logName); - const text = `Hello, world!`; - const entry = log.entry({ resource: { type: `global` } }, text); - log.write(entry, (err, apiResponse) => { - _callback(err, apiResponse); - assert.ifError(err); - assert.notEqual(apiResponse, undefined); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, [`Logged: ${text}`]); - done(); + return results; }); - } - }; - loggingMock = { - log: (_logName) => { - assert.equal(_logName, expectedlogName); - return logMock; - } - }; - LoggingMock = sinon.stub().returns(loggingMock); + } + }; + const loggingMock = { + log: (_logName) => { + t.is(_logName, expectedlogName); + return logMock; + } + }; - proxyquire(`../quickstart`, { - '@google-cloud/logging': LoggingMock - }); + proxyquire(`../quickstart`, { + '@google-cloud/logging': sinon.stub().returns(loggingMock) }); }); diff --git a/logging/system-test/sinks.test.js b/logging/system-test/sinks.test.js index a36915e249..04114f9c34 100644 --- a/logging/system-test/sinks.test.js +++ b/logging/system-test/sinks.test.js @@ -13,113 +13,114 @@ 'use strict'; -var Logging = require('@google-cloud/logging'); -var Storage = require('@google-cloud/storage'); -var uuid = require('uuid'); -var program = require('../sinks'); +require(`../../system-test/_setup`); -var logging = Logging(); -var storage = Storage(); +const Logging = require(`@google-cloud/logging`); +const Storage = require(`@google-cloud/storage`); +const uuid = require(`uuid`); +const program = require(`../sinks`); -var bucketName = 'nodejs-docs-samples-test-' + uuid.v4(); -var sinkName = 'nodejs-docs-samples-test-' + uuid.v4(); -var filter = 'severity > WARNING'; +const logging = Logging(); +const storage = Storage(); -describe('logging:sinks', function () { - before(function (done) { - storage.createBucket(bucketName, done); - }); +const bucketName = `nodejs-docs-samples-test-${uuid.v4()}`; +const sinkName = `nodejs-docs-samples-test-${uuid.v4()}`; +const filter = `severity > WARNING`; - after(function (done) { - logging.sink(sinkName).delete(function () { - // Don't check for error, the sink might already have been deleted - storage.bucket(bucketName).delete(function () { - // Don't check for error, the bucket might already have been deleted - done(); - }); - }); - }); +test.before(async (t) => { + await storage.createBucket(bucketName); +}); - describe('createSink', function () { - it('should create a new sink', function (done) { - program.createSink(sinkName, bucketName, filter, function (err, sink, apiResponse) { - assert.ifError(err); - assert(sink, 'sink should be defined'); - assert.equal(sink.name, sinkName, 'should have received the new sink'); - assert.notEqual(apiResponse, undefined); - done(); - }); - }); +test.after(async (t) => { + try { + await logging.sink(sinkName).delete(); + } catch (err) {} // ignore error + try { + await storage.bucket(bucketName).delete(); + } catch (err) {} // ignore error +}); + +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); + +test.cb.serial(`should create a new sink`, (t) => { + program.createSink(sinkName, bucketName, filter, (err, sink, apiResponse) => { + t.ifError(err); + t.truthy(sink); + t.is(sink.name, sinkName); + t.not(apiResponse, undefined); + t.end(); }); +}); - describe('getSink', function () { - it('should get the metadata for a sink', function (done) { - var expected = { - name: sinkName, - destination: 'storage.googleapis.com/' + bucketName, - filter: filter, - outputVersionFormat: 'V2', - writerIdentity: 'serviceAccount:cloud-logs@system.gserviceaccount.com' - }; - - program.getSinkMetadata(sinkName, function (err, metadata) { - assert.ifError(err); - assert.deepEqual(metadata, expected, 'should have received sink metadata'); - done(); - }); - }); +test.cb.serial(`should get the metadata for a sink`, (t) => { + const expected = { + name: sinkName, + destination: `storage.googleapis.com/${bucketName}`, + filter: filter, + outputVersionFormat: `V2`, + writerIdentity: `serviceAccount:cloud-logs@system.gserviceaccount.com` + }; + + program.getSinkMetadata(sinkName, (err, metadata) => { + t.ifError(err); + for (let key in expected) { + t.is(metadata[key], expected[key]); + } + t.end(); }); +}); - describe('listSinks', function () { - it('should list sinks', function (done) { - program.listSinks(function (err, sinks) { - assert.ifError(err); - assert(Array.isArray(sinks), '"sinks" should be an array.'); - var matchingSinks = sinks.map(function (sink) { - return sink.name === sinkName; - }); - assert.equal(matchingSinks.length, 1, 'Newly created sink should be in list.'); - done(); +test.serial(`should list sinks`, async (t) => { + await tryTest(async () => { + await new Promise((resolve, reject) => { + program.listSinks((err, sinks) => { + try { + t.ifError(err); + t.true(Array.isArray(sinks)); + t.true(sinks.some((sink) => sink.name === sinkName)); + resolve(); + } catch (err) { + reject(err); + } }); }); - }); + }).start(); +}); - describe('updateSink', function () { - it('should update metdata for a sink', function (done) { - var newFilter = 'severity > ALERT'; - var expected = { - name: sinkName, - destination: 'storage.googleapis.com/' + bucketName, - filter: newFilter, - outputVersionFormat: 'V2', - writerIdentity: 'serviceAccount:cloud-logs@system.gserviceaccount.com' - }; - - program.updateSink(sinkName, newFilter, function (err, apiResponse) { - assert.ifError(err); - assert.notEqual(apiResponse, undefined); - - program.getSinkMetadata(sinkName, function (err, metadata) { - assert.ifError(err); - assert.deepEqual(metadata, expected, 'Sink should have new metadata.'); - done(); - }); - }); +test.cb.serial(`should update metdata for a sink`, (t) => { + const newFilter = `severity > ALERT`; + const expected = { + name: sinkName, + destination: `storage.googleapis.com/${bucketName}`, + filter: newFilter, + outputVersionFormat: `V2`, + writerIdentity: `serviceAccount:cloud-logs@system.gserviceaccount.com` + }; + + program.updateSink(sinkName, newFilter, (err, apiResponse) => { + t.ifError(err); + t.not(apiResponse, undefined); + + program.getSinkMetadata(sinkName, (err, metadata) => { + t.ifError(err); + for (let key in expected) { + t.is(metadata[key], expected[key]); + } + t.end(); }); }); +}); - describe('deleteSink', function () { - it('should delete a sink', function (done) { - program.deleteSink(sinkName, function (err, apiResponse) { - assert.ifError(err); - assert.notEqual(apiResponse, undefined); - - program.getSinkMetadata(sinkName, function (err) { - assert(err, 'Should be an error.'); - assert.equal(err.code, 404, 'Should be a "not found" error.'); - done(); - }); - }); +test.cb.serial(`should delete a sink`, (t) => { + program.deleteSink(sinkName, (err, apiResponse) => { + t.ifError(err); + t.not(apiResponse, undefined); + + program.getSinkMetadata(sinkName, (err) => { + t.truthy(err); + t.is(err.code, 404); + t.end(); }); }); }); diff --git a/logging/test/fluent.test.js b/logging/test/fluent.test.js index c15c344764..5084190368 100644 --- a/logging/test/fluent.test.js +++ b/logging/test/fluent.test.js @@ -13,40 +13,40 @@ 'use strict'; -var proxyquire = require('proxyquire').noPreserveCache(); -var request = require('supertest'); +require(`../../test/_setup`); -describe('logging:fluent', function () { - it('should log error', function (done) { - var loggerCalled = false; +const proxyquire = require(`proxyquire`).noPreserveCache(); +const request = require(`supertest`); - var structuredLogger = { - emit: function (name) { - loggerCalled = true; - assert(name === 'errors'); - } - }; +test.cb(`should log error`, (t) => { + let loggerCalled = false; - var app = proxyquire('../fluent', { - 'fluent-logger': { - createFluentSender: function (name, options) { - assert(name === 'myapp'); - assert.deepEqual(options, { - host: 'localhost', - port: 24224, - timeout: 3.0 - }); - return structuredLogger; - } - } - }); + const structuredLogger = { + emit: (name) => { + loggerCalled = true; + t.is(name, `errors`); + } + }; - request(app) - .get('/') - .expect(500) - .expect(function () { - assert(loggerCalled, 'structuredLogger.emit should have been called'); - }) - .end(done); + const app = proxyquire(`../fluent`, { + 'fluent-logger': { + createFluentSender: (name, options) => { + t.is(name, `myapp`); + t.deepEqual(options, { + host: `localhost`, + port: 24224, + timeout: 3.0 + }); + return structuredLogger; + } + } }); + + request(app) + .get(`/`) + .expect(500) + .expect(() => { + t.true(loggerCalled, `structuredLogger.emit should have been called`); + }) + .end(t.end); }); diff --git a/logging/test/logs.test.js b/logging/test/logs.test.js deleted file mode 100644 index 15b32a3ada..0000000000 --- a/logging/test/logs.test.js +++ /dev/null @@ -1,249 +0,0 @@ -// Copyright 2015-2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -'use strict'; - -var proxyquire = require('proxyquire').noCallThru(); -var filter = 'severity > ALERT'; -var logName = 'bar'; -var sort = 'field'; -var limit = 1; -var resource = { - type: 'global' -}; - -function getSample () { - var apiResponseMock = {}; - var entriesMock = [{}]; - var entryMock = {}; - var logMock = { - entry: sinon.stub().returns(entryMock), - write: sinon.stub().yields(null, apiResponseMock), - delete: sinon.stub().yields(null, apiResponseMock), - getEntries: sinon.stub().yields(null, entriesMock) - }; - var loggingMock = { - log: sinon.stub().returns(logMock), - getEntries: sinon.stub().yields(null, entriesMock) - }; - var LoggingMock = sinon.stub().returns(loggingMock); - - return { - program: proxyquire('../logs', { - '@google-cloud/logging': LoggingMock, - yargs: proxyquire('yargs', {}) - }), - mocks: { - Logging: LoggingMock, - logging: loggingMock, - log: logMock, - entries: entriesMock, - entry: entryMock, - apiResponse: apiResponseMock - } - }; -} - -describe('logging:entries', function () { - describe('listLogEntries', function () { - it('should list log entries', function () { - var sample = getSample(); - var callback = sinon.stub(); - - sample.program.listLogEntries(logName, callback); - - assert.equal(sample.mocks.log.getEntries.calledOnce, true); - assert.deepEqual(sample.mocks.log.getEntries.firstCall.args.slice(0, -1), []); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.entries]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Found %d entries!', sample.mocks.entries.length]); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.log.getEntries = sinon.stub().yields(error); - - sample.program.listLogEntries(logName, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('listLogEntriesAdvanced', function () { - it('should list log entries', function () { - var sample = getSample(); - var callback = sinon.stub(); - - sample.program.listLogEntriesAdvanced(filter, limit, sort, callback); - - assert.equal(sample.mocks.logging.getEntries.calledOnce, true); - assert.deepEqual(sample.mocks.logging.getEntries.firstCall.args.slice(0, -1), [{ - pageSize: limit, - filter: filter, - orderBy: sort - }]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.entries]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Found %d entries!', sample.mocks.entries.length]); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.logging.getEntries = sinon.stub().yields(error); - - sample.program.listLogEntriesAdvanced(null, null, null, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('writeLogEntry', function () { - it('should write log entries', function () { - var sample = getSample(); - var callback = sinon.stub(); - - sample.program.writeLogEntry(logName, callback); - - assert.equal(sample.mocks.log.write.calledOnce, true); - assert.deepEqual(sample.mocks.log.write.firstCall.args.slice(0, -1), [[sample.mocks.log.entry(), sample.mocks.log.entry()]]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.apiResponse]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Wrote to %s', logName]); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.log.write = sinon.stub().yields(error); - - sample.program.writeLogEntry(logName, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('writeLogEntryAdvanced', function () { - it('should write a log entry', function () { - var sample = getSample(); - var callback = sinon.stub(); - - sample.program.writeLogEntryAdvanced(logName, { - resource: resource, - entry: 'Hello, world!' - }, callback); - - assert(sample.mocks.log.write.calledOnce, 'method called once'); - assert.equal(sample.mocks.log.write.firstCall.args.length, 2, 'method received 2 arguments'); - assert.strictEqual(sample.mocks.log.write.firstCall.args[0], sample.mocks.entry, 'method received options'); - assert(callback.calledOnce, 'callback called once'); - assert.equal(callback.firstCall.args.length, 2, 'callback received 2 arguments'); - assert.ifError(callback.firstCall.args[0], 'callback did not receive error'); - assert.strictEqual(callback.firstCall.args[1], sample.mocks.apiResponse, 'callback received result'); - assert(console.log.calledWith('Wrote entry to log: %s', logName)); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.log.write = sinon.stub().yields(error); - - sample.program.writeLogEntryAdvanced(logName, {}, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('deleteLog', function () { - it('should delete a log', function () { - var sample = getSample(); - var callback = sinon.stub(); - - sample.program.deleteLog(logName, callback); - - assert(sample.mocks.log.delete.calledOnce, 'method called once'); - assert.equal(sample.mocks.log.delete.firstCall.args.length, 1, 'method received 1 argument'); - assert(callback.calledOnce, 'callback called once'); - assert.equal(callback.firstCall.args.length, 2, 'callback received 2 arguments'); - assert.ifError(callback.firstCall.args[0], 'callback did not receive error'); - assert.strictEqual(callback.firstCall.args[1], sample.mocks.apiResponse, 'callback received result'); - assert(console.log.calledWith('Deleted log: %s', logName)); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.log.delete = sinon.stub().yields(error); - - sample.program.deleteLog(logName, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('main', function () { - it('should call listLogEntriesAdvanced', function () { - var program = getSample().program; - - sinon.stub(program, 'listLogEntriesAdvanced'); - program.main(['list', '-f', filter, '-l', limit, '-s', sort]); - assert.equal(program.listLogEntriesAdvanced.calledOnce, true); - assert.deepEqual(program.listLogEntriesAdvanced.firstCall.args.slice(0, -1), [filter, limit, sort]); - }); - - it('should call writeLogEntryAdvanced', function () { - var program = getSample().program; - - sinon.stub(program, 'writeLogEntryAdvanced'); - program.main(['write', logName, '{}', '{}']); - assert.equal(program.writeLogEntryAdvanced.calledOnce, true); - assert.deepEqual(program.writeLogEntryAdvanced.firstCall.args.slice(0, -1), [logName, { - resource: {}, - entry: {} - }]); - }); - - it('should validate args and call writeLogEntryAdvanced', function () { - var program = getSample().program; - - sinon.stub(program, 'writeLogEntryAdvanced'); - program.main(['write', logName, '"{"invalid', '"{"invalid']); - assert.equal(program.writeLogEntryAdvanced.called, false, 'writeLogEntryAdvanced should not have been called'); - assert.equal(console.error.calledOnce, true); - assert.deepEqual(console.error.firstCall.args, ['"resource" must be a valid JSON string!']); - }); - - it('should call deleteLog', function () { - var program = getSample().program; - - sinon.stub(program, 'deleteLog'); - program.main(['delete', logName]); - assert.equal(program.deleteLog.calledOnce, true); - assert.deepEqual(program.deleteLog.firstCall.args.slice(0, -1), [logName]); - }); - }); -}); diff --git a/logging/test/quickstart.test.js b/logging/test/quickstart.test.js deleted file mode 100644 index a087300303..0000000000 --- a/logging/test/quickstart.test.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Copyright 2016, Google, Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -const proxyquire = require(`proxyquire`).noCallThru(); - -describe(`logging:quickstart`, () => { - let logMock, loggingMock, LoggingMock; - const error = new Error(`error`); - const expectedLogName = `my-log`; - const expectedResource = { resource: { type: `global` } }; - const expectedMessage = `Hello, world!`; - - before(() => { - logMock = { - entry: sinon.stub().returns({}), - write: sinon.stub().yields(error) - }; - loggingMock = { - log: sinon.stub().returns(logMock) - }; - LoggingMock = sinon.stub().returns(loggingMock); - }); - - it(`should log an entry`, () => { - proxyquire(`../quickstart`, { - '@google-cloud/logging': LoggingMock - }); - - assert.equal(LoggingMock.calledOnce, true); - assert.deepEqual(LoggingMock.firstCall.args, [{ projectId: 'YOUR_PROJECT_ID' }]); - assert.equal(loggingMock.log.calledOnce, true); - assert.deepEqual(loggingMock.log.firstCall.args, [expectedLogName]); - assert.equal(logMock.entry.calledOnce, true); - assert.deepEqual(logMock.entry.firstCall.args, [expectedResource, expectedMessage]); - assert.equal(logMock.write.calledOnce, true); - assert.deepEqual(logMock.write.firstCall.args.slice(0, -1), [{}]); - assert.equal(console.error.calledOnce, true); - assert.deepEqual(console.error.firstCall.args, [error]); - }); -}); diff --git a/logging/test/sinks.test.js b/logging/test/sinks.test.js deleted file mode 100644 index 508d5c4826..0000000000 --- a/logging/test/sinks.test.js +++ /dev/null @@ -1,266 +0,0 @@ -// Copyright 2015-2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -'use strict'; - -var proxyquire = require('proxyquire').noCallThru(); -var bucketName = 'foo'; -var filter = 'severity > ALERT'; -var sinkName = 'bar'; - -function getSample () { - var apiResponseMock = {}; - var bucketMock = {}; - var metadataMock = {}; - var sinksMock = [ - { - name: sinkName - } - ]; - var sinkMock = { - create: sinon.stub().callsArgWith(1, null, sinksMock[0], apiResponseMock), - delete: sinon.stub().callsArgWith(0, null, apiResponseMock), - getMetadata: sinon.stub().callsArgWith(0, null, metadataMock), - setMetadata: sinon.stub().callsArgWith(1, null, apiResponseMock) - }; - var loggingMock = { - sink: sinon.stub().returns(sinkMock), - getSinks: sinon.stub().callsArgWith(0, null, sinksMock) - }; - var storageMock = { - bucket: sinon.stub().returns(bucketMock) - }; - var LoggingMock = sinon.stub().returns(loggingMock); - var StorageMock = sinon.stub().returns(storageMock); - - return { - program: proxyquire('../sinks', { - '@google-cloud/logging': LoggingMock, - '@google-cloud/storage': StorageMock, - yargs: proxyquire('yargs', {}) - }), - mocks: { - Logging: LoggingMock, - Storage: StorageMock, - logging: loggingMock, - storage: storageMock, - bucket: bucketMock, - metadata: metadataMock, - sink: sinkMock, - sinks: sinksMock, - apiResponse: apiResponseMock - } - }; -} - -describe('logging:sinks', function () { - describe('createSink', function () { - it('should create a new sink to a bucket', function () { - var sample = getSample(); - var callback = sinon.stub(); - - sample.program.createSink(sinkName, bucketName, filter, callback); - - assert(sample.mocks.sink.create.calledOnce, 'method called once'); - assert.equal(sample.mocks.sink.create.firstCall.args.length, 2, 'method received 2 arguments'); - assert.deepEqual(sample.mocks.sink.create.firstCall.args[0], { - filter: filter, - destination: sample.mocks.bucket - }, 'method received options'); - assert(callback.calledOnce, 'callback called once'); - assert.equal(callback.firstCall.args.length, 3, 'callback received 3 arguments'); - assert.ifError(callback.firstCall.args[0], 'callback did not receive error'); - assert.strictEqual(callback.firstCall.args[1], sample.mocks.sinks[0], 'callback received result'); - assert.strictEqual(callback.firstCall.args[2], sample.mocks.apiResponse, 'callback received result'); - assert(console.log.calledWith('Created sink %s to %s', sinkName, bucketName)); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.sink.create = sinon.stub().callsArgWith(1, error); - - sample.program.createSink(sinkName, bucketName, filter, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('getSinkMetadata', function () { - it('should get metadata for a sink', function () { - var sample = getSample(); - var callback = sinon.stub(); - - sample.program.getSinkMetadata(sinkName, callback); - - assert(sample.mocks.sink.getMetadata.calledOnce, 'method called once'); - assert.equal(sample.mocks.sink.getMetadata.firstCall.args.length, 1, 'method received 1 argument'); - assert(callback.calledOnce, 'callback called once'); - assert.equal(callback.firstCall.args.length, 2, 'callback received 2 arguments'); - assert.ifError(callback.firstCall.args[0], 'callback did not receive error'); - assert.strictEqual(callback.firstCall.args[1], sample.mocks.metadata, 'callback received result'); - assert(console.log.calledWith('Got metadata for sink: %s', sinkName)); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.sink.getMetadata = sinon.stub().callsArgWith(0, error); - - sample.program.getSinkMetadata(sinkName, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('listSinks', function () { - it('should list sinks', function () { - var sample = getSample(); - var callback = sinon.stub(); - - sample.program.listSinks(callback); - - assert(sample.mocks.logging.getSinks.calledOnce, 'method called once'); - assert.equal(sample.mocks.logging.getSinks.firstCall.args.length, 1, 'method received 1 argument'); - assert(callback.calledOnce, 'callback called once'); - assert.equal(callback.firstCall.args.length, 2, 'callback received 2 arguments'); - assert.ifError(callback.firstCall.args[0], 'callback did not receive error'); - assert.strictEqual(callback.firstCall.args[1], sample.mocks.sinks, 'callback received result'); - assert(console.log.calledWith('Found %d sink(s)!', sample.mocks.sinks.length)); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.logging.getSinks = sinon.stub().callsArgWith(0, error); - - sample.program.listSinks(callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('updateSink', function () { - it('should update metadata for a sink', function () { - var sample = getSample(); - var callback = sinon.stub(); - - sample.program.updateSink(sinkName, filter, callback); - - assert(sample.mocks.sink.setMetadata.calledOnce, 'method called once'); - assert.equal(sample.mocks.sink.setMetadata.firstCall.args.length, 2, 'method received 2 arguments'); - assert.deepEqual(sample.mocks.sink.setMetadata.firstCall.args[0], { - filter: filter - }, 'method received options'); - assert(callback.calledOnce, 'callback called once'); - assert.equal(callback.firstCall.args.length, 2, 'callback received 2 arguments'); - assert.ifError(callback.firstCall.args[0], 'callback did not receive error'); - assert.strictEqual(callback.firstCall.args[1], sample.mocks.apiResponse, 'callback received result'); - assert(console.log.calledWith('Updated sink: %s', sinkName)); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.sink.setMetadata = sinon.stub().callsArgWith(1, error); - - sample.program.updateSink(sinkName, filter, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('deleteSink', function () { - it('should delete a sink', function () { - var sample = getSample(); - var callback = sinon.stub(); - - sample.program.deleteSink(sinkName, callback); - - assert(sample.mocks.sink.delete.calledOnce, 'method called once'); - assert.equal(sample.mocks.sink.delete.firstCall.args.length, 1, 'method received 1 argument'); - assert(callback.calledOnce, 'callback called once'); - assert.equal(callback.firstCall.args.length, 2, 'callback received 2 arguments'); - assert.ifError(callback.firstCall.args[0], 'callback did not receive error'); - assert.strictEqual(callback.firstCall.args[1], sample.mocks.apiResponse, 'callback received result'); - assert(console.log.calledWith('Deleted sink: %s', sinkName)); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.sink.delete = sinon.stub().callsArgWith(0, error); - - sample.program.deleteSink(sinkName, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('main', function () { - it('should call createSink', function () { - var program = getSample().program; - - sinon.stub(program, 'createSink'); - program.main(['create', sinkName, bucketName, filter]); - assert.equal(program.createSink.calledOnce, true); - assert.deepEqual(program.createSink.firstCall.args.slice(0, -1), [sinkName, bucketName, filter]); - }); - - it('should call getSinkMetadata', function () { - var program = getSample().program; - - sinon.stub(program, 'getSinkMetadata'); - program.main(['get', sinkName]); - assert.equal(program.getSinkMetadata.calledOnce, true); - assert.deepEqual(program.getSinkMetadata.firstCall.args.slice(0, -1), [sinkName]); - }); - - it('should call listSinks', function () { - var program = getSample().program; - - sinon.stub(program, 'listSinks'); - program.main(['list']); - assert.equal(program.listSinks.calledOnce, true); - assert.deepEqual(program.listSinks.firstCall.args.slice(0, -1), []); - }); - - it('should call updateSink', function () { - var program = getSample().program; - - sinon.stub(program, 'updateSink'); - program.main(['update', sinkName, filter]); - assert.equal(program.updateSink.calledOnce, true); - assert.deepEqual(program.updateSink.firstCall.args.slice(0, -1), [sinkName, filter]); - }); - - it('should call deleteSink', function () { - var program = getSample().program; - - sinon.stub(program, 'deleteSink'); - program.main(['delete', sinkName]); - assert.equal(program.deleteSink.calledOnce, true); - assert.deepEqual(program.deleteSink.firstCall.args.slice(0, -1), [sinkName]); - }); - }); -}); diff --git a/monitoring/package.json b/monitoring/package.json index b682bbbf98..2969e485ea 100644 --- a/monitoring/package.json +++ b/monitoring/package.json @@ -5,8 +5,7 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "scripts": { - "test": "cd ..; npm run t -- monitoring/test/*.test.js", - "system-test": "cd ..; npm run st -- monitoring/system-test/*.test.js" + "test": "cd ..; npm run st -- monitoring/system-test/*.test.js" }, "dependencies": { "async":"2.1.2", diff --git a/monitoring/system-test/create_custom_metric.test.js b/monitoring/system-test/create_custom_metric.test.js index 5fcfbc64db..acd608a323 100644 --- a/monitoring/system-test/create_custom_metric.test.js +++ b/monitoring/system-test/create_custom_metric.test.js @@ -13,37 +13,40 @@ 'use strict'; -var customMetricsExample = require('../create_custom_metric'); +require(`../../system-test/_setup`); + +const customMetricsExample = require('../create_custom_metric'); /** Refactored out to keep lines shorter */ function getPointValue (timeSeries) { return timeSeries.timeSeries[0].points[0].value.int64Value; } -describe('monitoring:create_custom_metric', function () { - it('should create and read back a custom metric', function (done) { - customMetricsExample.main( - process.env.GCLOUD_PROJECT, - Math.random().toString(36).substring(7), - function (err, results) { - assert.ifError(err); - assert(results.length === 4); - // Result of creating metric - assert(typeof results[0].name === 'string'); - // Result of writing time series - assert.deepEqual(results[1], {}); - // Result of reading time series - assert(typeof getPointValue(results[2]) === 'string'); - assert(!isNaN(parseInt(getPointValue(results[2]), 10))); - // Result of deleting metric - assert.deepEqual(results[3], {}); - assert(console.log.calledWith('Created custom metric')); - assert(console.log.calledWith('Wrote time series')); - assert(console.log.calledWith('Reading metric type')); - assert(console.log.calledWith('Time series')); - assert(console.log.calledWith('Deleted metric')); - done(); - } - ); - }); +test.before(stubConsole); +test.after(restoreConsole); + +test.cb('should create and read back a custom metric', (t) => { + customMetricsExample.main( + process.env.GCLOUD_PROJECT, + Math.random().toString(36).substring(7), + (err, results) => { + t.ifError(err); + t.is(results.length, 4); + // Result of creating metric + t.is(typeof results[0].name, 'string'); + // Result of writing time series + t.deepEqual(results[1], {}); + // Result of reading time series + t.is(typeof getPointValue(results[2]), 'string'); + t.false(isNaN(parseInt(getPointValue(results[2]), 10))); + // Result of deleting metric + t.deepEqual(results[3], {}); + t.true(console.log.calledWith('Created custom metric')); + t.true(console.log.calledWith('Wrote time series')); + t.true(console.log.calledWith('Reading metric type')); + t.true(console.log.calledWith('Time series')); + t.true(console.log.calledWith('Deleted metric')); + t.end(); + } + ); }); diff --git a/monitoring/system-test/list_resources.test.js b/monitoring/system-test/list_resources.test.js index 49e64ad97b..caccc16a04 100644 --- a/monitoring/system-test/list_resources.test.js +++ b/monitoring/system-test/list_resources.test.js @@ -13,26 +13,26 @@ 'use strict'; -var listResourcesExample = require('../list_resources'); +require(`../../system-test/_setup`); -describe('monitoring:list_resources', function () { - it('should list a bunch of stuff', function (done) { - listResourcesExample.main( - process.env.GCLOUD_PROJECT, - function (err, results) { - assert.ifError(err); - assert(results.length === 3); - // Monitored resources - assert(Array.isArray(results[0].resourceDescriptors)); - // Metric descriptors - assert(Array.isArray(results[1].metricDescriptors)); - // Time series - assert(Array.isArray(results[2].timeSeries)); - assert(console.log.calledWith('Monitored resources')); - assert(console.log.calledWith('Metric descriptors')); - assert(console.log.calledWith('Time series')); - done(); - } - ); +const listResourcesExample = require(`../list_resources`); + +test.before(stubConsole); +test.after(restoreConsole); + +test.cb(`should list a bunch of stuff`, (t) => { + listResourcesExample.main(process.env.GCLOUD_PROJECT, (err, results) => { + t.ifError(err); + t.is(results.length, 3); + // Monitored resources + t.true(Array.isArray(results[0].resourceDescriptors)); + // Metric descriptors + t.true(Array.isArray(results[1].metricDescriptors)); + // Time series + t.true(Array.isArray(results[2].timeSeries)); + t.true(console.log.calledWith('Monitored resources')); + t.true(console.log.calledWith('Metric descriptors')); + t.true(console.log.calledWith('Time series')); + t.end(); }); }); diff --git a/monitoring/test/create_custom_metric.test.js b/monitoring/test/create_custom_metric.test.js deleted file mode 100644 index 18843c626c..0000000000 --- a/monitoring/test/create_custom_metric.test.js +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -'use strict'; - -describe('monitoring:create_custom_metric', function () { - it('should be tested'); -}); diff --git a/monitoring/test/list_resources.test.js b/monitoring/test/list_resources.test.js deleted file mode 100644 index 03e0d0b22b..0000000000 --- a/monitoring/test/list_resources.test.js +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -'use strict'; - -describe('monitoring:list_resources', function () { - it('should be tested'); -}); diff --git a/package.json b/package.json index 7143d95e35..34f128e122 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,13 @@ "describe", "it", "assert", + "restoreConsole", + "run", + "runAsync", "sinon", + "stubConsole", + "test", + "tryTest", "uuid" ], "ignore": [ @@ -54,28 +60,25 @@ "scripts": { "lint": "semistandard", "pretest": "npm run lint && ./scripts/clean", - "t": "mocha -R spec -t 2000 --require intelli-espower-loader test/_setup.js", - "st": "mocha -R spec -t 120000 --require intelli-espower-loader system-test/_setup.js", - "mocha": "npm run t -- ./test/_setup.js ./test/*.test.js '{*,appengine/*,functions/*,functions/ocr/*}/test/*.test.js'", - "test": "npm run mocha", + "t": "ava --verbose -c 10 -T 30s", + "st": "ava --verbose -c 10 -T 180s", + "test": "npm run t -- test/**/*.test.js **/test/**/*.test.js", "cover": "nyc --cache npm test && nyc report --reporter=html && nyc report --reporter=lcov", - "system-test": "mocha -R spec -t 120000 --require intelli-espower-loader ./system-test/_setup.js '{*,appengine/*}/system-test/*.test.js'", + "system-test": "npm run st -- system-test/**/*.test.js **/system-test/**/*.test.js", "system-cover": "npm run pretest && nyc --cache npm run system-test && nyc report --reporter=html && nyc report --reporter=lcov", - "all-test": "mocha -R spec -t 120000 --require intelli-espower-loader ./system-test/_setup.js '{*,appengine/*}/system-test/*.test.js' ./test/*.test.js '{*,appengine/*,functions/*}/test/*.test.js'", + "all-test": "npm run st -- test/**/*.test.js **/test/**/*.test.js system-test/**/*.test.js **/system-test/**/*.test.js", "all-cover": "npm run pretest && nyc --cache npm run all-test && nyc report --reporter=html && nyc report --reporter=lcov" }, "devDependencies": { "async": "2.1.4", - "intelli-espower-loader": "1.0.1", - "mocha": "3.1.2", + "ava": "0.17.0", "nodejs-repo-tools": "git+https://github.com/GoogleCloudPlatform/nodejs-repo-tools.git#bbbb6035d77671eb053dbe6b6f0e3ff983f79639", - "nyc": "9.0.1", - "power-assert": "1.4.2", + "nyc": "10.0.0", "proxyquire": "1.7.10", "request": "2.79.0", - "semistandard": "9.1.0", + "semistandard": "9.2.1", "shelljs": "0.7.5", - "sinon": "1.17.6", + "sinon": "1.17.7", "supertest": "2.0.1" } } diff --git a/prediction/hostedmodels.js b/prediction/hostedmodels.js index 35f7e549fa..f9dbab81b7 100644 --- a/prediction/hostedmodels.js +++ b/prediction/hostedmodels.js @@ -15,7 +15,6 @@ // [START predict] var google = require('googleapis'); -var hostedmodels = google.prediction('v1.6').hostedmodels; function auth (callback) { google.auth.getApplicationDefault(function (err, authClient) { @@ -50,9 +49,12 @@ function predict (phrase, callback) { if (err) { return callback(err); } + var hostedmodels = google.prediction({ + version: 'v1.6', + auth: authClient + }).hostedmodels; // Predict the sentiment for the provided phrase hostedmodels.predict({ - auth: authClient, // Project id used for this sample project: '414649711441', hostedModelName: 'sample.sentiment', diff --git a/prediction/package.json b/prediction/package.json index 20c984fad8..fd2f98a117 100644 --- a/prediction/package.json +++ b/prediction/package.json @@ -5,8 +5,7 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "scripts": { - "test": "cd ..; npm run t -- prediction/test/*.test.js", - "system-test": "cd ..; npm run st -- prediction/system-test/*.test.js" + "test": "cd ..; npm run st -- prediction/system-test/*.test.js" }, "dependencies": { "googleapis": "15.0.0" diff --git a/prediction/system-test/hostedmodels.test.js b/prediction/system-test/hostedmodels.test.js index e4cad834a7..98f7b16c17 100644 --- a/prediction/system-test/hostedmodels.test.js +++ b/prediction/system-test/hostedmodels.test.js @@ -13,15 +13,15 @@ 'use strict'; -var hostedmodels = require('../../prediction/hostedmodels'); +require(`../../system-test/_setup`); -describe('prediction:hostedmodels', function () { - it('should predict', function (done) { - hostedmodels.main('good night', function (err, result) { - assert.ifError(err); - assert(result); - assert(console.log.calledWith('Sentiment for "good night": positive')); - done(); - }); - }); +const path = require(`path`); + +const cmd = `node hostedmodels.js`; +const cwd = path.join(__dirname, `..`); +const text = `good night`; + +test(`should predict`, async (t) => { + const output = await runAsync(`${cmd} "${text}"`, cwd); + t.true(output.includes(`Sentiment for "${text}": positive`)); }); diff --git a/prediction/test/hostedmodels.test.js b/prediction/test/hostedmodels.test.js deleted file mode 100644 index d9a237541f..0000000000 --- a/prediction/test/hostedmodels.test.js +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -'use strict'; - -describe('prediction:hostedmodels', function () { - it('should be tested'); -}); diff --git a/pubsub/package.json b/pubsub/package.json index 19f1faff64..c1f677288b 100644 --- a/pubsub/package.json +++ b/pubsub/package.json @@ -9,10 +9,7 @@ }, "dependencies": { "@google-cloud/pubsub": "0.7.0", - "yargs": "6.5.0" - }, - "devDependencies": { - "uuid": "3.0.1" + "yargs": "6.6.0" }, "engines": { "node": ">=4.3.2" diff --git a/pubsub/system-test/quickstart.test.js b/pubsub/system-test/quickstart.test.js index 6f08e9e959..620cbda253 100644 --- a/pubsub/system-test/quickstart.test.js +++ b/pubsub/system-test/quickstart.test.js @@ -15,6 +15,8 @@ 'use strict'; +require(`../../system-test/_setup`); + const proxyquire = require(`proxyquire`).noPreserveCache(); const pubsub = proxyquire(`@google-cloud/pubsub`, {})(); const uuid = require(`uuid`); @@ -23,33 +25,38 @@ const topicName = `nodejs-docs-samples-test-${uuid.v4()}`; const projectId = process.env.GCLOUD_PROJECT; const fullTopicName = `projects/${projectId}/topics/${topicName}`; -describe(`pubsub:quickstart`, () => { - after(() => pubsub.topic(topicName).delete().catch(() => {})); - - it(`should create a topic`, (done) => { - const expectedTopicName = `my-new-topic`; - const pubsubMock = { - createTopic: (_topicName) => { - assert.equal(_topicName, expectedTopicName); - - return pubsub.createTopic(topicName) - .then((results) => { - const topic = results[0]; - assert.equal(topic.name, fullTopicName); - - setTimeout(() => { - assert.equal(console.log.callCount, 1); - assert.deepEqual(console.log.getCall(0).args, [`Topic ${topic.name} created.`]); - done(); - }, 200); - - return results; - }); - } - }; - - proxyquire(`../quickstart`, { - '@google-cloud/pubsub': sinon.stub().returns(pubsubMock) - }); +test.before(stubConsole); +test.after(() => { + restoreConsole(); + return pubsub.topic(topicName).delete().catch(() => {}); +}); + +test.cb(`should create a topic`, (t) => { + const expectedTopicName = `my-new-topic`; + const pubsubMock = { + createTopic: (_topicName) => { + t.is(_topicName, expectedTopicName); + + return pubsub.createTopic(topicName) + .then(([topic]) => { + t.is(topic.name, fullTopicName); + + setTimeout(() => { + try { + t.is(console.log.callCount, 1); + t.deepEqual(console.log.getCall(0).args, [`Topic ${topic.name} created.`]); + t.end(); + } catch (err) { + t.end(err); + } + }, 200); + + return [topic]; + }); + } + }; + + proxyquire(`../quickstart`, { + '@google-cloud/pubsub': sinon.stub().returns(pubsubMock) }); }); diff --git a/pubsub/system-test/subscriptions.test.js b/pubsub/system-test/subscriptions.test.js index 6aa9711202..38a362ba8c 100644 --- a/pubsub/system-test/subscriptions.test.js +++ b/pubsub/system-test/subscriptions.test.js @@ -15,10 +15,11 @@ 'use strict'; +require(`../../system-test/_setup`); + const pubsub = require(`@google-cloud/pubsub`)(); const uuid = require(`uuid`); const path = require(`path`); -const run = require(`../../utils`).run; const cwd = path.join(__dirname, `..`); const topicName = `nodejs-docs-samples-test-${uuid.v4()}`; @@ -30,154 +31,126 @@ const fullSubscriptionNameOne = `projects/${projectId}/subscriptions/${subscript const fullSubscriptionNameTwo = `projects/${projectId}/subscriptions/${subscriptionNameTwo}`; const cmd = `node subscriptions.js`; -describe(`pubsub:subscriptions`, () => { - before(() => pubsub.createTopic(topicName)); - - after(() => { - return pubsub.subscription(subscriptionNameOne).delete() - .then(() => pubsub.subscription(subscriptionNameTwo).delete(), () => {}) - .then(() => pubsub.topic(topicName).delete(), () => {}) - .catch(() => {}); - }); - - it(`should create a subscription`, () => { - const output = run(`${cmd} create ${topicName} ${subscriptionNameOne}`, cwd); - assert.equal(output, `Subscription ${fullSubscriptionNameOne} created.`); - return pubsub.subscription(subscriptionNameOne).exists() - .then((results) => { - const exists = results[0]; - assert.equal(exists, true); - }); - }); - - it(`should create a push subscription`, () => { - const output = run(`${cmd} create-push ${topicName} ${subscriptionNameTwo}`, cwd); - assert.equal(output, `Subscription ${fullSubscriptionNameTwo} created.`); - return pubsub.subscription(subscriptionNameTwo).exists() - .then((results) => { - const exists = results[0]; - assert.equal(exists, true); - }); - }); - - it(`should get metadata for a subscription`, () => { - const output = run(`${cmd} get ${subscriptionNameOne}`, cwd); - const expected = `Subscription: ${fullSubscriptionNameOne}` + - `\nTopic: ${fullTopicName}` + - `\nPush config: ` + - `\nAck deadline: 10s`; - assert.equal(output, expected); - }); - - it(`should list all subscriptions`, (done) => { - // Listing is eventually consistent. Give the indexes time to update. - setTimeout(() => { - const output = run(`${cmd} list`, cwd); - assert.equal(output.includes(`Subscriptions:`), true); - assert.equal(output.includes(fullSubscriptionNameOne), true); - assert.equal(output.includes(fullSubscriptionNameTwo), true); - done(); - }, 5000); - }); - - it(`should list subscriptions for a topic`, () => { - const output = run(`${cmd} list ${topicName}`, cwd); - assert.equal(output.includes(`Subscriptions for ${topicName}:`), true); - assert.equal(output.includes(fullSubscriptionNameOne), true); - assert.equal(output.includes(fullSubscriptionNameTwo), true); - }); - - it(`should pull messages`, () => { - const expected = `Hello, world!`; - return pubsub.topic(topicName).publish(expected) - .then((results) => { - const messageIds = results[0]; - const output = run(`${cmd} pull ${subscriptionNameOne}`, cwd); - const expectedOutput = `Received ${messageIds.length} messages.\n` + - `* ${messageIds[0]} "${expected}" {}`; - assert.equal(output, expectedOutput); - }); - }); - - it(`should pull ordered messages`, () => { - const subscriptions = require('../subscriptions'); - const expected = `Hello, world!`; - const publishedMessageIds = []; - - return pubsub.topic(topicName).publish({ data: expected, attributes: { counterId: '3' } }, { raw: true }) - .then((results) => { - const messageIds = results[0]; - publishedMessageIds.push(messageIds[0]); - return subscriptions.pullOrderedMessages(subscriptionNameOne); - }) - .then(() => { - assert.equal(console.log.callCount, 0); - return pubsub.topic(topicName).publish({ data: expected, attributes: { counterId: '1' } }, { raw: true }); - }) - .then((results) => { - const messageIds = results[0]; - publishedMessageIds.push(messageIds[0]); - return subscriptions.pullOrderedMessages(subscriptionNameOne); - }) - .then(() => { - assert.equal(console.log.callCount, 1); - assert.deepEqual(console.log.firstCall.args, [`* %d %j %j`, publishedMessageIds[1], expected, { counterId: '1' }]); - return pubsub.topic(topicName).publish({ data: expected, attributes: { counterId: '1' } }, { raw: true }); - }) - .then((results) => { - return pubsub.topic(topicName).publish({ data: expected, attributes: { counterId: '2' } }, { raw: true }); - }) - .then((results) => { - const messageIds = results[0]; - publishedMessageIds.push(messageIds[0]); - return subscriptions.pullOrderedMessages(subscriptionNameOne); - }) - .then(() => { - assert.equal(console.log.callCount, 3); - assert.deepEqual(console.log.secondCall.args, [`* %d %j %j`, publishedMessageIds[2], expected, { counterId: '2' }]); - assert.deepEqual(console.log.thirdCall.args, [`* %d %j %j`, publishedMessageIds[0], expected, { counterId: '3' }]); - }); - }); - - it(`should set the IAM policy for a subscription`, () => { - run(`${cmd} set-policy ${subscriptionNameOne}`, cwd); - return pubsub.subscription(subscriptionNameOne).iam.getPolicy() - .then((results) => { - const policy = results[0]; - assert.deepEqual(policy.bindings, [ - { - role: `roles/pubsub.editor`, - members: [`group:cloud-logs@google.com`] - }, - { - role: `roles/pubsub.viewer`, - members: [`allUsers`] - } - ]); - }); - }); - - it(`should get the IAM policy for a subscription`, () => { - pubsub.subscription(subscriptionNameOne).iam.getPolicy() - .then((results) => { - const policy = results[0]; - const output = run(`${cmd} get-policy ${subscriptionNameOne}`, cwd); - assert.equal(output, `Policy for subscription: ${JSON.stringify(policy.bindings)}.`); - }); - }); - - it(`should test permissions for a subscription`, () => { - const output = run(`${cmd} test-permissions ${subscriptionNameOne}`, cwd); - assert.equal(output.includes(`Tested permissions for subscription`), true); - }); - - it(`should delete a subscription`, () => { - const output = run(`${cmd} delete ${subscriptionNameOne}`, cwd); - assert.equal(output, `Subscription ${fullSubscriptionNameOne} deleted.`); - return pubsub.subscription(subscriptionNameOne).exists() - .then((results) => { - const exists = results[0]; - assert.equal(exists, false); - }); - }); +test.before(async () => { + await pubsub.createTopic(topicName); +}); + +test.after(async () => { + try { + await pubsub.subscription(subscriptionNameOne).delete(); + } catch (err) {} // ignore error + try { + await pubsub.subscription(subscriptionNameTwo).delete(); + } catch (err) {} // ignore error + try { + await pubsub.topic(topicName).delete(); + } catch (err) {} // ignore error +}); + +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); + +test.serial(`should create a subscription`, async (t) => { + const output = await runAsync(`${cmd} create ${topicName} ${subscriptionNameOne}`, cwd); + t.is(output, `Subscription ${fullSubscriptionNameOne} created.`); + const results = await pubsub.subscription(subscriptionNameOne).exists(); + t.true(results[0]); +}); + +test.serial(`should create a push subscription`, async (t) => { + const output = await runAsync(`${cmd} create-push ${topicName} ${subscriptionNameTwo}`, cwd); + t.is(output, `Subscription ${fullSubscriptionNameTwo} created.`); + const results = await pubsub.subscription(subscriptionNameTwo).exists(); + t.true(results[0]); +}); + +test.serial(`should get metadata for a subscription`, async (t) => { + const output = await runAsync(`${cmd} get ${subscriptionNameOne}`, cwd); + const expected = `Subscription: ${fullSubscriptionNameOne}` + + `\nTopic: ${fullTopicName}` + + `\nPush config: ` + + `\nAck deadline: 10s`; + t.is(output, expected); +}); + +test.serial(`should list all subscriptions`, async (t) => { + await tryTest(async () => { + const output = await runAsync(`${cmd} list`, cwd); + t.true(output.includes(`Subscriptions:`)); + t.true(output.includes(fullSubscriptionNameOne)); + t.true(output.includes(fullSubscriptionNameTwo)); + }).start(); +}); + +test.serial(`should list subscriptions for a topic`, async (t) => { + const output = await runAsync(`${cmd} list ${topicName}`, cwd); + t.true(output.includes(`Subscriptions for ${topicName}:`)); + t.true(output.includes(fullSubscriptionNameOne)); + t.true(output.includes(fullSubscriptionNameTwo)); +}); + +test.serial(`should pull messages`, async (t) => { + const expected = `Hello, world!`; + const results = await pubsub.topic(topicName).publish(expected); + const messageIds = results[0]; + const expectedOutput = `Received ${messageIds.length} messages.\n* ${messageIds[0]} "${expected}" {}`; + const output = await runAsync(`${cmd} pull ${subscriptionNameOne}`, cwd); + t.is(output, expectedOutput); +}); + +test.serial(`should pull ordered messages`, async (t) => { + const subscriptions = require('../subscriptions'); + const expected = `Hello, world!`; + const publishedMessageIds = []; + + let results = await pubsub.topic(topicName).publish({ data: expected, attributes: { counterId: '3' } }, { raw: true }); + publishedMessageIds.push(results[0][0]); + await subscriptions.pullOrderedMessages(subscriptionNameOne); + t.is(console.log.callCount, 0); + results = await pubsub.topic(topicName).publish({ data: expected, attributes: { counterId: '1' } }, { raw: true }); + publishedMessageIds.push(results[0][0]); + await subscriptions.pullOrderedMessages(subscriptionNameOne); + t.is(console.log.callCount, 1); + t.deepEqual(console.log.firstCall.args, [`* %d %j %j`, publishedMessageIds[1], expected, { counterId: '1' }]); + results = await pubsub.topic(topicName).publish({ data: expected, attributes: { counterId: '1' } }, { raw: true }); + results = await pubsub.topic(topicName).publish({ data: expected, attributes: { counterId: '2' } }, { raw: true }); + publishedMessageIds.push(results[0][0]); + await subscriptions.pullOrderedMessages(subscriptionNameOne); + t.is(console.log.callCount, 3); + t.deepEqual(console.log.secondCall.args, [`* %d %j %j`, publishedMessageIds[2], expected, { counterId: '2' }]); + t.deepEqual(console.log.thirdCall.args, [`* %d %j %j`, publishedMessageIds[0], expected, { counterId: '3' }]); +}); + +test.serial(`should set the IAM policy for a subscription`, async (t) => { + await runAsync(`${cmd} set-policy ${subscriptionNameOne}`, cwd); + const results = await pubsub.subscription(subscriptionNameOne).iam.getPolicy(); + const policy = results[0]; + t.deepEqual(policy.bindings, [ + { + role: `roles/pubsub.editor`, + members: [`group:cloud-logs@google.com`] + }, + { + role: `roles/pubsub.viewer`, + members: [`allUsers`] + } + ]); +}); + +test.serial(`should get the IAM policy for a subscription`, async (t) => { + const results = await pubsub.subscription(subscriptionNameOne).iam.getPolicy(); + const output = await runAsync(`${cmd} get-policy ${subscriptionNameOne}`, cwd); + t.is(output, `Policy for subscription: ${JSON.stringify(results[0].bindings)}.`); +}); + +test.serial(`should test permissions for a subscription`, async (t) => { + const output = await runAsync(`${cmd} test-permissions ${subscriptionNameOne}`, cwd); + t.true(output.includes(`Tested permissions for subscription`)); +}); + +test.serial(`should delete a subscription`, async (t) => { + const output = await runAsync(`${cmd} delete ${subscriptionNameOne}`, cwd); + t.is(output, `Subscription ${fullSubscriptionNameOne} deleted.`); + const results = await pubsub.subscription(subscriptionNameOne).exists(); + t.false(results[0], false); }); diff --git a/pubsub/system-test/topics.test.js b/pubsub/system-test/topics.test.js index 1c154f2939..5ee823d132 100644 --- a/pubsub/system-test/topics.test.js +++ b/pubsub/system-test/topics.test.js @@ -15,10 +15,11 @@ 'use strict'; +require(`../../system-test/_setup`); + const pubsub = require(`@google-cloud/pubsub`)(); const uuid = require(`uuid`); const path = require(`path`); -const run = require(`../../utils`).run; const cwd = path.join(__dirname, `..`); const topicName = `nodejs-docs-samples-test-${uuid.v4()}`; @@ -28,124 +29,91 @@ const fullTopicName = `projects/${projectId}/topics/${topicName}`; const message = { data: `Hello, world!` }; const cmd = `node topics.js`; -describe(`pubsub:topics`, () => { - after(() => { - return pubsub.subscription(subscriptionName).delete() - .then(() => pubsub.topic(topicName).delete(), () => {}) - .catch(() => {}); - }); - - it(`should create a topic`, () => { - const output = run(`${cmd} create ${topicName}`, cwd); - assert.equal(output, `Topic ${fullTopicName} created.`); - return pubsub.topic(topicName).exists() - .then((results) => { - const exists = results[0]; - assert.equal(exists, true); - }); - }); +test.after(async () => { + try { + await pubsub.subscription(subscriptionName).delete(); + } catch (err) {} // ignore error + try { + await pubsub.topic(topicName).delete(); + } catch (err) {} // ignore error +}); - it(`should list topics`, (done) => { - // Listing is eventually consistent. Give the indexes time to update. - setTimeout(() => { - const output = run(`${cmd} list`, cwd); - assert.equal(output.includes(`Topics:`), true); - assert.equal(output.includes(fullTopicName), true); - done(); - }, 5000); - }); +test.serial(`should create a topic`, async (t) => { + const output = await runAsync(`${cmd} create ${topicName}`, cwd); + t.is(output, `Topic ${fullTopicName} created.`); + const [exists] = await pubsub.topic(topicName).exists(); + t.true(exists); +}); - it(`should publish a simple message`, () => { - return pubsub.topic(topicName).subscribe(subscriptionName) - .then((results) => { - const subscription = results[0]; - run(`${cmd} publish ${topicName} "${message.data}"`, cwd); - return subscription.pull(); - }) - .then((results) => { - const messages = results[0]; - assert.equal(messages[0].data, message.data); - }); - }); +test.serial(`should list topics`, async (t) => { + await tryTest(async () => { + const output = await runAsync(`${cmd} list`, cwd); + t.true(output.includes(`Topics:`)); + t.true(output.includes(fullTopicName)); + }).start(); +}); - it(`should publish a JSON message`, () => { - return pubsub.topic(topicName).subscribe(subscriptionName) - .then((results) => { - const subscription = results[0]; - run(`${cmd} publish ${topicName} '${JSON.stringify(message)}'`, cwd); - return subscription.pull(); - }) - .then((results) => { - const messages = results[0]; - assert.deepEqual(messages[0].data, message); - }); - }); +test.serial(`should publish a simple message`, async (t) => { + const [subscription] = await pubsub.topic(topicName).subscribe(subscriptionName); + await runAsync(`${cmd} publish ${topicName} "${message.data}"`, cwd); + const [messages] = await subscription.pull(); + t.is(messages[0].data, message.data); +}); - it(`should publish ordered messages`, () => { - const topics = require(`../topics`); - let subscription; +test.serial(`should publish a JSON message`, async (t) => { + const [subscription] = await pubsub.topic(topicName).subscribe(subscriptionName); + await runAsync(`${cmd} publish ${topicName} '${JSON.stringify(message)}'`, cwd); + const [messages] = await subscription.pull(); + t.deepEqual(messages[0].data, message); +}); - return pubsub.topic(topicName).subscribe(subscriptionName) - .then((results) => { - subscription = results[0]; - return topics.publishOrderedMessage(topicName, message.data); - }) - .then(() => subscription.pull()) - .then((results) => { - const messages = results[0]; - assert.equal(messages[0].data, message.data); - assert.equal(messages[0].attributes.counterId, '1'); - return topics.publishOrderedMessage(topicName, message.data); - }) - .then(() => subscription.pull()) - .then((results) => { - const messages = results[0]; - assert.equal(messages[0].data, message.data); - assert.equal(messages[0].attributes.counterId, '2'); - return topics.publishOrderedMessage(topicName, message.data); - }); - }); +test.serial(`should publish ordered messages`, async (t) => { + const topics = require(`../topics`); - it(`should set the IAM policy for a topic`, () => { - run(`${cmd} set-policy ${topicName}`, cwd); + const [subscription] = await pubsub.topic(topicName).subscribe(subscriptionName); + let messageIds = await topics.publishOrderedMessage(topicName, message.data); + let [messages] = await subscription.pull(); + t.is(messages[0].id, messageIds[0]); + t.is(messages[0].data, message.data); + t.is(messages[0].attributes.counterId, '1'); + messageIds = await topics.publishOrderedMessage(topicName, message.data); + [messages] = await subscription.pull(); + t.is(messages[0].id, messageIds[0]); + t.is(messages[0].data, message.data); + t.is(messages[0].attributes.counterId, '2'); + await topics.publishOrderedMessage(topicName, message.data); +}); - return pubsub.topic(topicName).iam.getPolicy() - .then((results) => { - const policy = results[0]; - assert.deepEqual(policy.bindings, [ - { - role: `roles/pubsub.editor`, - members: [`group:cloud-logs@google.com`] - }, - { - role: `roles/pubsub.viewer`, - members: [`allUsers`] - } - ]); - }); - }); +test.serial(`should set the IAM policy for a topic`, async (t) => { + await runAsync(`${cmd} set-policy ${topicName}`, cwd); + const results = await pubsub.topic(topicName).iam.getPolicy(); + const policy = results[0]; + t.deepEqual(policy.bindings, [ + { + role: `roles/pubsub.editor`, + members: [`group:cloud-logs@google.com`] + }, + { + role: `roles/pubsub.viewer`, + members: [`allUsers`] + } + ]); +}); - it(`should get the IAM policy for a topic`, () => { - return pubsub.topic(topicName).iam.getPolicy() - .then((results) => { - const policy = results[0]; - const output = run(`${cmd} get-policy ${topicName}`, cwd); - assert.equal(output, `Policy for topic: ${JSON.stringify(policy.bindings)}.`); - }); - }); +test.serial(`should get the IAM policy for a topic`, async (t) => { + const [policy] = await pubsub.topic(topicName).iam.getPolicy(); + const output = await runAsync(`${cmd} get-policy ${topicName}`, cwd); + t.is(output, `Policy for topic: ${JSON.stringify(policy.bindings)}.`); +}); - it(`should test permissions for a topic`, () => { - const output = run(`${cmd} test-permissions ${topicName}`, cwd); - assert.equal(output.includes(`Tested permissions for topic`), true); - }); +test.serial(`should test permissions for a topic`, async (t) => { + const output = await runAsync(`${cmd} test-permissions ${topicName}`, cwd); + t.true(output.includes(`Tested permissions for topic`)); +}); - it(`should delete a topic`, () => { - const output = run(`${cmd} delete ${topicName}`, cwd); - assert.equal(output, `Topic ${fullTopicName} deleted.`); - return pubsub.topic(topicName).exists() - .then((results) => { - const exists = results[0]; - assert.equal(exists, false); - }); - }); +test.serial(`should delete a topic`, async (t) => { + const output = await runAsync(`${cmd} delete ${topicName}`, cwd); + t.is(output, `Topic ${fullTopicName} deleted.`); + const [exists] = await pubsub.topic(topicName).exists(); + t.false(exists); }); diff --git a/resource/package.json b/resource/package.json index 0d8b12f338..bf77e43ef7 100644 --- a/resource/package.json +++ b/resource/package.json @@ -5,12 +5,11 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "scripts": { - "test": "cd ..; npm run t -- resource/test/*.test.js", - "system-test": "cd ..; npm run st -- resource/system-test/*.test.js" + "test": "cd ..; npm run st -- resource/system-test/*.test.js" }, "dependencies": { - "@google-cloud/resource": "0.5.0", - "yargs": "6.5.0" + "@google-cloud/resource": "0.5.1", + "yargs": "6.6.0" }, "engines": { "node": ">=4.3.2" diff --git a/resource/projects.js b/resource/projects.js index 53c5e72761..606174ad71 100644 --- a/resource/projects.js +++ b/resource/projects.js @@ -18,27 +18,23 @@ const Resource = require('@google-cloud/resource'); // [START resource_list_projects] -function listProjects (callback) { +function listProjects () { // Instantiates a client const resource = Resource(); // Lists all current projects - resource.getProjects((err, projects) => { - if (err) { - callback(err); - return; - } - - console.log('Projects:'); - projects.forEach((project) => console.log(project.id)); - callback(); - }); + return resource.getProjects() + .then((results) => { + const projects = results[0]; + console.log('Projects:'); + projects.forEach((project) => console.log(project.id)); + return projects; + }); } // [END resource_list_projects] // The command-line program const cli = require(`yargs`); -const makeHandler = require(`../utils`).makeHandler; const program = module.exports = { listProjects: listProjects, @@ -50,9 +46,7 @@ const program = module.exports = { cli .demand(1) - .command(`list`, `List all current projects.`, {}, () => { - program.listProjects(makeHandler(false)); - }) + .command(`list`, `List all current projects.`, {}, program.listProjects) .example(`node $0 list`, `Lists all current projects.`) .wrap(120) .recommendCommands() diff --git a/resource/quickstart.js b/resource/quickstart.js index 85f06e5cda..ada6428551 100644 --- a/resource/quickstart.js +++ b/resource/quickstart.js @@ -28,13 +28,11 @@ const resourceClient = Resource({ }); // Lists current projects -resourceClient.getProjects((err, projects) => { - if (err) { - console.error(err); - return; - } +resourceClient.getProjects() + .then((results) => { + const projects = results[0]; - console.log('Projects:'); - projects.forEach((project) => console.log(project.id)); -}); + console.log('Projects:'); + projects.forEach((project) => console.log(project.id)); + }); // [END resource_quickstart] diff --git a/resource/system-test/projects.test.js b/resource/system-test/projects.test.js index 36bac853d1..a5071376d6 100644 --- a/resource/system-test/projects.test.js +++ b/resource/system-test/projects.test.js @@ -15,16 +15,15 @@ 'use strict'; +require(`../../system-test/_setup`); + const path = require(`path`); -const run = require(`../../utils`).run; const cwd = path.join(__dirname, `..`); const cmd = `node projects.js`; -describe(`resource:projects`, () => { - it(`should list projects`, () => { - const output = run(`${cmd} list`, cwd); - assert.notEqual(output.indexOf(`Projects:`), -1); - assert.notEqual(output.indexOf(`${process.env.GCLOUD_PROJECT}`), -1); - }); +test(`should list projects`, async (t) => { + const stdout = await runAsync(`${cmd} list`, cwd); + t.true(stdout.includes(`Projects:`)); + t.true(stdout.includes(`${process.env.GCLOUD_PROJECT}`)); }); diff --git a/resource/system-test/quickstart.test.js b/resource/system-test/quickstart.test.js index ccbea5ea0a..dbb2b0d83a 100644 --- a/resource/system-test/quickstart.test.js +++ b/resource/system-test/quickstart.test.js @@ -15,34 +15,40 @@ 'use strict'; +require(`../../system-test/_setup`); + const proxyquire = require(`proxyquire`).noPreserveCache(); const resource = proxyquire(`@google-cloud/resource`, {})(); -describe(`resource:quickstart`, () => { - let resourceMock, ResourceMock; - - it(`should list projects`, (done) => { - resourceMock = { - getProjects: (_callback) => { - assert.equal(typeof _callback, 'function'); - - resource.getProjects((err, projects) => { - _callback(err, projects); - assert.ifError(err); - assert.equal(Array.isArray(projects), true); - assert.equal(console.log.called, true); - assert.deepEqual(console.log.firstCall.args, [`Projects:`]); - projects.forEach((project, i) => { - assert.deepEqual(console.log.getCall(i + 1).args, [project.id]); - }); - done(); +test.before(stubConsole); +test.after(restoreConsole); + +test.cb(`should list projects`, (t) => { + const resourceMock = { + getProjects: () => { + return resource.getProjects() + .then(([projects]) => { + t.true(Array.isArray(projects)); + + setTimeout(() => { + try { + t.true(console.log.called); + t.deepEqual(console.log.firstCall.args, [`Projects:`]); + projects.forEach((project, i) => { + t.deepEqual(console.log.getCall(i + 1).args, [project.id]); + }); + t.end(); + } catch (err) { + t.end(err); + } + }, 200); + + return [projects]; }); - } - }; - ResourceMock = sinon.stub().returns(resourceMock); + } + }; - proxyquire(`../quickstart`, { - '@google-cloud/resource': ResourceMock - }); + proxyquire(`../quickstart`, { + '@google-cloud/resource': sinon.stub().returns(resourceMock) }); }); diff --git a/resource/test/projects.test.js b/resource/test/projects.test.js deleted file mode 100644 index f109f545ec..0000000000 --- a/resource/test/projects.test.js +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright 2016, Google, Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -const proxyquire = require(`proxyquire`).noCallThru(); - -describe(`resource:projects`, () => { - it(`should handle errors`, () => { - const error = new Error(`error`); - const callback = sinon.spy(); - const resourceMock = { - getProjects: sinon.stub().yields(error) - }; - const ResourceMock = sinon.stub().returns(resourceMock); - const program = proxyquire(`../projects`, { - '@google-cloud/resource': ResourceMock - }); - - program.listProjects(callback); - - assert.equal(callback.callCount, 1); - assert.equal(callback.alwaysCalledWithExactly(error), true); - }); -}); diff --git a/resource/test/quickstart.test.js b/resource/test/quickstart.test.js deleted file mode 100644 index 073572e4f5..0000000000 --- a/resource/test/quickstart.test.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright 2016, Google, Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -const proxyquire = require(`proxyquire`).noCallThru(); - -describe(`resource:quickstart`, () => { - let resourceMock, ResourceMock; - const error = new Error(`error`); - - before(() => { - resourceMock = { - getProjects: sinon.stub().yields(error) - }; - ResourceMock = sinon.stub().returns(resourceMock); - }); - - it(`should handle error`, () => { - proxyquire(`../quickstart`, { - '@google-cloud/resource': ResourceMock - }); - - assert.equal(ResourceMock.calledOnce, true); - assert.deepEqual(ResourceMock.firstCall.args, [{ projectId: 'YOUR_PROJECT_ID' }]); - assert.equal(resourceMock.getProjects.calledOnce, true); - assert.deepEqual(resourceMock.getProjects.firstCall.args.slice(0, -1), []); - assert.equal(console.error.calledOnce, true); - assert.deepEqual(console.error.firstCall.args, [error]); - }); -}); diff --git a/scripts/run b/scripts/run index 51f4d2a617..4883b35183 100644 --- a/scripts/run +++ b/scripts/run @@ -33,9 +33,11 @@ queue.push('computeengine'); queue.push('datastore'); queue.push('debugger'); queue.push('dns'); +queueDirectories('endpoints'); queueDirectories('functions'); queue.push('functions/ocr/app'); queue.push('language'); +queue.push('language/slackbot'); queue.push('logging'); queue.push('monitoring'); queue.push('prediction'); diff --git a/speech/package.json b/speech/package.json index 3ac2236a61..c98555538a 100644 --- a/speech/package.json +++ b/speech/package.json @@ -9,8 +9,8 @@ }, "dependencies": { "@google-cloud/speech": "0.5.0", - "node-record-lpcm16": "0.1.4", - "yargs": "6.5.0" + "node-record-lpcm16": "0.2.0", + "yargs": "6.6.0" }, "engines": { "node": ">=4.3.2" diff --git a/speech/system-test/quickstart.test.js b/speech/system-test/quickstart.test.js index 1b24b541f4..4a4b6f4ba9 100644 --- a/speech/system-test/quickstart.test.js +++ b/speech/system-test/quickstart.test.js @@ -15,6 +15,8 @@ 'use strict'; +require(`../../system-test/_setup`); + const path = require(`path`); const proxyquire = require(`proxyquire`).noPreserveCache(); const speech = proxyquire(`@google-cloud/speech`, {})(); @@ -25,34 +27,38 @@ const config = { sampleRate: 16000 }; -describe(`speech:quickstart`, () => { - it(`should detect speech`, (done) => { - const expectedFileName = `./resources/audio.raw`; - const expectedText = `how old is the Brooklyn Bridge`; - - const speechMock = { - recognize: (_fileName, _config) => { - assert.equal(_fileName, expectedFileName); - assert.deepEqual(_config, config); - - return speech.recognize(fileName, config) - .then((results) => { - const transcription = results[0]; - assert.equal(transcription, expectedText); - - setTimeout(() => { - assert.equal(console.log.callCount, 1); - assert.deepEqual(console.log.getCall(0).args, [`Transcription: ${expectedText}`]); - done(); - }, 200); - - return results; - }); - } - }; - - proxyquire(`../quickstart`, { - '@google-cloud/speech': sinon.stub().returns(speechMock) - }); +test.before(stubConsole); +test.after(restoreConsole); + +test.cb(`should detect speech`, (t) => { + const expectedFileName = `./resources/audio.raw`; + const expectedText = `how old is the Brooklyn Bridge`; + + const speechMock = { + recognize: (_fileName, _config) => { + t.is(_fileName, expectedFileName); + t.deepEqual(_config, config); + + return speech.recognize(fileName, config) + .then(([transcription]) => { + t.is(transcription, expectedText); + + setTimeout(() => { + try { + t.is(console.log.callCount, 1); + t.deepEqual(console.log.getCall(0).args, [`Transcription: ${expectedText}`]); + t.end(); + } catch (err) { + t.end(err); + } + }, 200); + + return [transcription]; + }); + } + }; + + proxyquire(`../quickstart`, { + '@google-cloud/speech': sinon.stub().returns(speechMock) }); }); diff --git a/speech/system-test/recognize.test.js b/speech/system-test/recognize.test.js index 8feb6e0167..d35f266f2a 100644 --- a/speech/system-test/recognize.test.js +++ b/speech/system-test/recognize.test.js @@ -15,24 +15,26 @@ 'use strict'; +require(`../../system-test/_setup`); + const path = require(`path`); -const run = require(`../../utils`).run; const cmd = `node recognize.js`; const cwd = path.join(__dirname, `..`); const filename = `./resources/audio.raw`; const text = `how old is the Brooklyn Bridge`; -describe(`speech:recognize`, () => { - it(`should run sync recognize`, () => { - assert.equal(run(`${cmd} sync ${filename}`, cwd).includes(text), true); - }); +test(`should run sync recognize`, async (t) => { + const output = await runAsync(`${cmd} sync ${filename}`, cwd); + t.true(output.includes(`Transcription: ${text}`)); +}); - it(`should run async recognize`, () => { - assert.equal(run(`${cmd} async ${filename}`, cwd).includes(text), true); - }); +test(`should run async recognize`, async (t) => { + const output = await runAsync(`${cmd} async ${filename}`, cwd); + t.true(output.includes(`Transcription: ${text}`)); +}); - it(`should run streaming recognize`, () => { - assert.equal(run(`${cmd} stream ${filename}`, cwd).includes(text), true); - }); +test(`should run streaming recognize`, async (t) => { + const output = await runAsync(`${cmd} stream ${filename}`, cwd); + t.true(output.includes(text)); }); diff --git a/storage/system-test/acl.test.js b/storage/system-test/acl.test.js index 89bd3de62e..1f6a7ba5de 100644 --- a/storage/system-test/acl.test.js +++ b/storage/system-test/acl.test.js @@ -15,10 +15,11 @@ 'use strict'; +require(`../../system-test/_setup`); + const storage = require(`@google-cloud/storage`)(); const uuid = require(`uuid`); const path = require(`path`); -const run = require(`../../utils`).run; const cwd = path.join(__dirname, `..`); const bucketName = `nodejs-docs-samples-test-${uuid.v4()}`; @@ -28,76 +29,78 @@ const fileName = `test.txt`; const filePath = path.join(__dirname, `../resources`, fileName); const cmd = `node acl.js`; -describe('storage:acl', () => { - before(() => bucket.create().then((results) => results[0].upload(filePath))); - - after(() => { - // Try deleting all files twice, just to make sure. Ignore any errors. - return bucket.deleteFiles({ force: true }) - .then(() => bucket.deleteFiles({ force: true }), () => {}) - .then(() => bucket.delete(), () => {}) - .catch(() => {}); - }); - - it(`should print acl for a bucket`, () => { - const output = run(`${cmd} print-bucket-acl ${bucketName}`, cwd); - assert.equal(output.includes(`OWNER: project-editors-`), true); - assert.equal(output.includes(`OWNER: project-owners-`), true); - assert.equal(output.includes(`READER: project-viewers-`), true); - }); - - it(`should print a user's acl for a bucket`, () => { - return bucket.acl.readers.addUser(userEmail) - .then(() => { - const output = run(`${cmd} print-bucket-acl-for-user ${bucketName} ${userEmail}`, cwd); - assert.equal(output, `READER: user-${userEmail}`); - return bucket.acl.readers.deleteUser(userEmail); - }); - }); - - it(`should add a user as an owner on a bucket`, () => { - const output = run(`${cmd} add-bucket-owner ${bucketName} ${userEmail}`, cwd); - assert.equal(output, `Added user ${userEmail} as an owner on bucket ${bucketName}.`); - }); - - it(`should remove a user from a bucket`, () => { - const output = run(`${cmd} remove-bucket-owner ${bucketName} ${userEmail}`, cwd); - assert.equal(output, `Removed user ${userEmail} from bucket ${bucketName}.`); - }); - - it(`should add a user as a default owner on a bucket`, () => { - const output = run(`${cmd} add-bucket-default-owner ${bucketName} ${userEmail}`, cwd); - assert.equal(output, `Added user ${userEmail} as an owner on bucket ${bucketName}.`); - }); - - it(`should remove a default user from a bucket`, () => { - const output = run(`${cmd} remove-bucket-default-owner ${bucketName} ${userEmail}`, cwd); - assert.equal(output, `Removed user ${userEmail} from bucket ${bucketName}.`); - }); - - it(`should print acl for a file`, () => { - const output = run(`${cmd} print-file-acl ${bucketName} ${fileName}`, cwd); - assert.equal(output.includes(`OWNER: project-editors-`), true); - assert.equal(output.includes(`OWNER: project-owners-`), true); - assert.equal(output.includes(`READER: project-viewers-`), true); - }); - - it(`should print a user's acl for a file`, () => { - return bucket.file(fileName).acl.readers.addUser(userEmail) - .then(() => { - const output = run(`${cmd} print-file-acl-for-user ${bucketName} ${fileName} ${userEmail}`, cwd); - assert.equal(output, `READER: user-${userEmail}`); - return bucket.file(fileName).acl.readers.deleteUser(userEmail); - }); - }); - - it(`should add a user as an owner on a bucket`, () => { - const output = run(`${cmd} add-file-owner ${bucketName} ${fileName} ${userEmail}`, cwd); - assert.equal(output, `Added user ${userEmail} as an owner on file ${fileName}.`); - }); - - it(`should remove a user from a bucket`, () => { - const output = run(`${cmd} remove-file-owner ${bucketName} ${fileName} ${userEmail}`, cwd); - assert.equal(output, `Removed user ${userEmail} from file ${fileName}.`); - }); +test.before(async (t) => { + await bucket.create(); + await bucket.upload(filePath); +}); + +test.after(async (t) => { + // Try deleting all files twice + try { + await bucket.deleteFiles({ force: true }); + } catch (err) {} // ignore error + try { + await bucket.deleteFiles({ force: true }); + } catch (err) {} // ignore error + try { + await bucket.delete(); + } catch (err) {} // ignore error +}); + +test(`should print acl for a bucket`, async (t) => { + const output = await runAsync(`${cmd} print-bucket-acl ${bucketName}`, cwd); + t.true(output.includes(`OWNER: project-editors-`)); + t.true(output.includes(`OWNER: project-owners-`)); + t.true(output.includes(`READER: project-viewers-`)); +}); + +test(`should print acl for a file`, async (t) => { + const output = await runAsync(`${cmd} print-file-acl ${bucketName} ${fileName}`, cwd); + t.true(output.includes(`OWNER: project-editors-`)); + t.true(output.includes(`OWNER: project-owners-`)); + t.true(output.includes(`READER: project-viewers-`)); +}); + +test.serial(`should print a user's acl for a bucket`, async (t) => { + await bucket.acl.readers.addUser(userEmail); + const output = await runAsync(`${cmd} print-bucket-acl-for-user ${bucketName} ${userEmail}`, cwd); + t.is(output, `READER: user-${userEmail}`); + await bucket.acl.readers.deleteUser(userEmail); +}); + +test.serial(`should add a user as an owner on a bucket`, async (t) => { + const output = await runAsync(`${cmd} add-bucket-owner ${bucketName} ${userEmail}`, cwd); + t.is(output, `Added user ${userEmail} as an owner on bucket ${bucketName}.`); +}); + +test.serial(`should remove a user from a bucket`, async (t) => { + const output = await runAsync(`${cmd} remove-bucket-owner ${bucketName} ${userEmail}`, cwd); + t.is(output, `Removed user ${userEmail} from bucket ${bucketName}.`); +}); + +test.serial(`should add a user as a default owner on a bucket`, async (t) => { + const output = await runAsync(`${cmd} add-bucket-default-owner ${bucketName} ${userEmail}`, cwd); + t.is(output, `Added user ${userEmail} as an owner on bucket ${bucketName}.`); +}); + +test.serial(`should remove a default user from a bucket`, async (t) => { + const output = await runAsync(`${cmd} remove-bucket-default-owner ${bucketName} ${userEmail}`, cwd); + t.is(output, `Removed user ${userEmail} from bucket ${bucketName}.`); +}); + +test.serial(`should print a user's acl for a file`, async (t) => { + await bucket.file(fileName).acl.readers.addUser(userEmail); + const output = await runAsync(`${cmd} print-file-acl-for-user ${bucketName} ${fileName} ${userEmail}`, cwd); + t.is(output, `READER: user-${userEmail}`); + await bucket.file(fileName).acl.readers.deleteUser(userEmail); +}); + +test.serial(`should add a user as an owner on a bucket`, async (t) => { + const output = await runAsync(`${cmd} add-file-owner ${bucketName} ${fileName} ${userEmail}`, cwd); + t.is(output, `Added user ${userEmail} as an owner on file ${fileName}.`); +}); + +test.serial(`should remove a user from a bucket`, async (t) => { + const output = await runAsync(`${cmd} remove-file-owner ${bucketName} ${fileName} ${userEmail}`, cwd); + t.is(output, `Removed user ${userEmail} from file ${fileName}.`); }); diff --git a/storage/system-test/buckets.test.js b/storage/system-test/buckets.test.js index a7a80254cb..6daa4bde77 100644 --- a/storage/system-test/buckets.test.js +++ b/storage/system-test/buckets.test.js @@ -15,44 +15,44 @@ 'use strict'; +require(`../../system-test/_setup`); + const storage = require(`@google-cloud/storage`)(); const uuid = require(`uuid`); const path = require(`path`); -const run = require(`../../utils`).run; const cwd = path.join(__dirname, `..`); const bucketName = `nodejs-docs-samples-test-${uuid.v4()}`; const bucket = storage.bucket(bucketName); const cmd = `node buckets.js`; -describe('storage:buckets', () => { - after(() => bucket.delete().catch(() => {})); - - it(`should create a bucket`, () => { - const output = run(`${cmd} create ${bucketName}`, cwd); - assert.equal(output, `Bucket ${bucketName} created.`); - return bucket.exists() - .then((results) => { - assert.equal(results[0], true); - }); - }); - - it(`should list buckets`, (done) => { - // Listing is eventually consistent. Give the indexes time to update. - setTimeout(() => { - const output = run(`${cmd} list`, cwd); - assert.equal(output.includes(`Buckets:`), true); - assert.equal(output.includes(bucketName), true); - done(); - }, 5000); - }); - - it(`should delete a bucket`, () => { - const output = run(`${cmd} delete ${bucketName}`, cwd); - assert.equal(output, `Bucket ${bucketName} deleted.`); - return bucket.exists() - .then((results) => { - assert.equal(results[0], false); - }); - }); +test.after(async () => { + try { + await bucket.delete(); + } catch (err) {} // ignore error +}); + +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); + +test.serial(`should create a bucket`, async (t) => { + const output = await runAsync(`${cmd} create ${bucketName}`, cwd); + t.is(output, `Bucket ${bucketName} created.`); + const [exists] = await bucket.exists(); + t.true(exists); +}); + +test.serial(`should list buckets`, async (t) => { + await tryTest(async () => { + const output = await runAsync(`${cmd} list`, cwd); + t.true(output.includes(`Buckets:`)); + t.true(output.includes(bucketName)); + }).start(); +}); + +test.serial(`should delete a bucket`, async (t) => { + const output = await runAsync(`${cmd} delete ${bucketName}`, cwd); + t.is(output, `Bucket ${bucketName} deleted.`); + const [exists] = await bucket.exists(); + t.false(exists); }); diff --git a/storage/system-test/encryption.test.js b/storage/system-test/encryption.test.js index 43162c7ed5..a603d70235 100644 --- a/storage/system-test/encryption.test.js +++ b/storage/system-test/encryption.test.js @@ -15,9 +15,10 @@ 'use strict'; +require(`../../system-test/_setup`); + const fs = require('fs'); const path = require('path'); -const run = require(`../../utils`).run; const storage = require('@google-cloud/storage')(); const uuid = require('uuid'); @@ -30,52 +31,58 @@ const fileName = `test.txt`; const filePath = path.join(__dirname, `../resources`, fileName); const downloadFilePath = path.join(__dirname, `../resources/downloaded.txt`); -describe('storage:encryption', () => { - let key; +let key; - before(() => bucket.create(bucketName)); +test.before(async () => { + await bucket.create(bucketName); +}); - after(() => { - try { - // Delete the downloaded file - fs.unlinkSync(downloadFilePath); - } catch (err) { - console.log(err); - } - // Try deleting all files twice, just to make sure. Ignore any errors. - return bucket.deleteFiles({ force: true }) - .then(() => bucket.deleteFiles({ force: true }), () => {}) - .then(() => bucket.delete(), () => {}) - .catch(() => {}); - }); +test.after(async () => { + try { + // Delete the downloaded file + fs.unlinkSync(downloadFilePath); + } catch (err) { + console.log(err); + } + // Try deleting all files twice, just to make sure + try { + await bucket.deleteFiles({ force: true }); + } catch (err) {} // ignore error + try { + await bucket.deleteFiles({ force: true }); + } catch (err) {} // ignore error + try { + await bucket.delete(); + } catch (err) {} // ignore error +}); - it(`should generate a key`, () => { - const output = run(`${cmd} generate-encryption-key`, cwd); - assert.equal(output.includes(`Base 64 encoded encryption key:`), true); - const test = /^Base 64 encoded encryption key: (.+)$/; - key = output.match(test)[1]; - }); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); - it(`should upload a file`, () => { - const output = run(`${cmd} upload ${bucketName} ${filePath} ${fileName} ${key}`, cwd); - assert.equal(output, `File ${filePath} uploaded to ${fileName}.`); - return bucket.file(fileName).exists() - .then((results) => { - assert.equal(results[0], true); - }); - }); +test.serial(`should generate a key`, async (t) => { + const output = await runAsync(`${cmd} generate-encryption-key`, cwd); + t.true(output.includes(`Base 64 encoded encryption key:`)); + const test = /^Base 64 encoded encryption key: (.+)$/; + key = output.match(test)[1]; +}); - it(`should download a file`, () => { - const output = run(`${cmd} download ${bucketName} ${fileName} ${downloadFilePath} ${key}`, cwd); - assert.equal(output, `File ${fileName} downloaded to ${downloadFilePath}.`); - assert.doesNotThrow(() => { - fs.statSync(downloadFilePath); - }); - }); +test.serial(`should upload a file`, async (t) => { + const output = await runAsync(`${cmd} upload ${bucketName} ${filePath} ${fileName} ${key}`, cwd); + t.is(output, `File ${filePath} uploaded to ${fileName}.`); + const [exists] = await bucket.file(fileName).exists(); + t.true(exists); +}); - it(`should rotate keys`, () => { - assert.throws(() => { - run(`${cmd} rotate ${bucketName} ${fileName} ${key} ${key}`, cwd); - }, Error, `This is currently not available using the Cloud Client Library.`); +test.serial(`should download a file`, async (t) => { + const output = await runAsync(`${cmd} download ${bucketName} ${fileName} ${downloadFilePath} ${key}`, cwd); + t.is(output, `File ${fileName} downloaded to ${downloadFilePath}.`); + t.notThrows(() => { + fs.statSync(downloadFilePath); }); }); + +test.serial(`should rotate keys`, (t) => { + t.throws(() => { + run(`${cmd} rotate ${bucketName} ${fileName} ${key} ${key}`, cwd); + }, Error, `This is currently not available using the Cloud Client Library.`); +}); diff --git a/storage/system-test/files.test.js b/storage/system-test/files.test.js index ecaecbd5b0..dfcd93107b 100644 --- a/storage/system-test/files.test.js +++ b/storage/system-test/files.test.js @@ -15,11 +15,12 @@ 'use strict'; +require(`../../system-test/_setup`); + const fs = require(`fs`); const storage = require(`@google-cloud/storage`)(); const uuid = require(`uuid`); const path = require(`path`); -const run = require(`../../utils`).run; const cwd = path.join(__dirname, `..`); const bucketName = `nodejs-docs-samples-test-${uuid.v4()}`; @@ -31,99 +32,97 @@ const filePath = path.join(__dirname, `../resources`, fileName); const downloadFilePath = path.join(__dirname, `../resources/downloaded.txt`); const cmd = `node files.js`; -describe('storage:files', () => { - before(() => bucket.create()); - - after(() => { - try { - fs.unlinkSync(downloadFilePath); - } catch (err) { - console.log(err); - } - // Try deleting all files twice, just to make sure. Ignore any errors. - return bucket.deleteFiles({ force: true }) - .then(() => bucket.deleteFiles({ force: true }), () => {}) - .then(() => bucket.delete(), () => {}) - .catch(() => {}); - }); - - it('should upload a file', () => { - const output = run(`${cmd} upload ${bucketName} ${filePath}`, cwd); - assert.equal(output, `File ${fileName} uploaded.`); - return bucket.file(fileName).exists() - .then((results) => { - assert.equal(results[0], true); - }); - }); - - it('should download a file', () => { - const output = run(`${cmd} download ${bucketName} ${fileName} ${downloadFilePath}`, cwd); - assert.equal(output, `File ${fileName} downloaded to ${downloadFilePath}.`); - assert.doesNotThrow(() => fs.statSync(downloadFilePath)); - }); - - it('should move a file', () => { - const output = run(`${cmd} move ${bucketName} ${fileName} ${movedFileName}`, cwd); - assert.equal(output, `File ${fileName} moved to ${movedFileName}.`); - return bucket.file(movedFileName).exists() - .then((results) => { - assert.equal(results[0], true); - }); - }); - - it('should copy a file', () => { - const output = run(`${cmd} copy ${bucketName} ${movedFileName} ${bucketName} ${copiedFileName}`, cwd); - assert.equal(output, `File ${movedFileName} copied to ${copiedFileName} in ${bucketName}.`); - return bucket.file(copiedFileName).exists() - .then((results) => { - assert.equal(results[0], true); - }); - }); - - it('should list files', (done) => { - // Listing is eventually consistent, give the indexes time to update - setTimeout(() => { - const output = run(`${cmd} list ${bucketName}`, cwd); - assert.equal(output.includes(`Files:`), true); - assert.equal(output.includes(movedFileName), true); - assert.equal(output.includes(copiedFileName), true); - done(); - }, 5000); - }); - - it('should list files by a prefix', () => { - let output = run(`${cmd} list ${bucketName} test "/"`, cwd); - assert.equal(output.includes(`Files:`), true); - assert.equal(output.includes(movedFileName), true); - assert.equal(output.includes(copiedFileName), true); - output = run(`${cmd} list ${bucketName} foo`, cwd); - assert.equal(output.includes(`Files:`), true); - assert.equal(output.indexOf(movedFileName), -1); - assert.equal(output.indexOf(copiedFileName), -1); - }); - - it('should make a file public', () => { - const output = run(`${cmd} make-public ${bucketName} ${copiedFileName}`, cwd); - assert.equal(output, `File ${copiedFileName} is now public.`); - }); - - it('should generate a signed URL for a file', () => { - const output = run(`${cmd} generate-signed-url ${bucketName} ${copiedFileName}`, cwd); - assert.equal(output.includes(`The signed url for ${copiedFileName} is `), true); - }); - - it('should get metadata for a file', () => { - const output = run(`${cmd} get-metadata ${bucketName} ${copiedFileName}`, cwd); - assert.equal(output.includes(`File: ${copiedFileName}`), true); - assert.equal(output.includes(`Bucket: ${bucketName}`), true); - }); - - it('should delete a file', () => { - const output = run(`${cmd} delete ${bucketName} ${copiedFileName}`, cwd); - assert.equal(output, `File ${copiedFileName} deleted.`); - return bucket.file(copiedFileName).exists() - .then((results) => { - assert.equal(results[0], false); - }); - }); +test.before(async () => { + await bucket.create(); +}); + +test.after(async () => { + try { + fs.unlinkSync(downloadFilePath); + } catch (err) { + console.log(err); + } + // Try deleting all files twice, just to make sure + try { + await bucket.deleteFiles({ force: true }); + } catch (err) {} // ignore error + try { + await bucket.deleteFiles({ force: true }); + } catch (err) {} // ignore error + try { + await bucket.delete(); + } catch (err) {} // ignore error +}); + +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); + +test.serial(`should upload a file`, async (t) => { + const output = await runAsync(`${cmd} upload ${bucketName} ${filePath}`, cwd); + t.is(output, `File ${fileName} uploaded.`); + const [exists] = await bucket.file(fileName).exists(); + t.true(exists); +}); + +test.serial(`should download a file`, async (t) => { + const output = await runAsync(`${cmd} download ${bucketName} ${fileName} ${downloadFilePath}`, cwd); + t.is(output, `File ${fileName} downloaded to ${downloadFilePath}.`); + t.notThrows(() => fs.statSync(downloadFilePath)); +}); + +test.serial(`should move a file`, async (t) => { + const output = await runAsync(`${cmd} move ${bucketName} ${fileName} ${movedFileName}`, cwd); + t.is(output, `File ${fileName} moved to ${movedFileName}.`); + const [exists] = await bucket.file(movedFileName).exists(); + t.true(exists); +}); + +test.serial(`should copy a file`, async (t) => { + const output = await runAsync(`${cmd} copy ${bucketName} ${movedFileName} ${bucketName} ${copiedFileName}`, cwd); + t.is(output, `File ${movedFileName} copied to ${copiedFileName} in ${bucketName}.`); + const [exists] = await bucket.file(copiedFileName).exists(); + t.true(exists); +}); + +test.serial(`should list files`, async (t) => { + await tryTest(async () => { + const output = await runAsync(`${cmd} list ${bucketName}`, cwd); + t.true(output.includes(`Files:`)); + t.true(output.includes(movedFileName)); + t.true(output.includes(copiedFileName)); + }).start(); +}); + +test.serial(`should list files by a prefix`, async (t) => { + let output = await runAsync(`${cmd} list ${bucketName} test "/"`, cwd); + t.true(output.includes(`Files:`)); + t.true(output.includes(movedFileName)); + t.true(output.includes(copiedFileName)); + output = await runAsync(`${cmd} list ${bucketName} foo`, cwd); + t.true(output.includes(`Files:`)); + t.false(output.includes(movedFileName)); + t.false(output.includes(copiedFileName)); +}); + +test.serial(`should make a file public`, async (t) => { + const output = await runAsync(`${cmd} make-public ${bucketName} ${copiedFileName}`, cwd); + t.is(output, `File ${copiedFileName} is now public.`); +}); + +test.serial(`should generate a signed URL for a file`, async (t) => { + const output = await runAsync(`${cmd} generate-signed-url ${bucketName} ${copiedFileName}`, cwd); + t.true(output.includes(`The signed url for ${copiedFileName} is `)); +}); + +test.serial(`should get metadata for a file`, async (t) => { + const output = await runAsync(`${cmd} get-metadata ${bucketName} ${copiedFileName}`, cwd); + t.true(output.includes(`File: ${copiedFileName}`)); + t.true(output.includes(`Bucket: ${bucketName}`)); +}); + +test.serial(`should delete a file`, async (t) => { + const output = await runAsync(`${cmd} delete ${bucketName} ${copiedFileName}`, cwd); + t.is(output, `File ${copiedFileName} deleted.`); + const [exists] = await bucket.file(copiedFileName).exists(); + t.false(exists); }); diff --git a/storage/system-test/quickstart.test.js b/storage/system-test/quickstart.test.js index 6f6e74168b..0c69e6015b 100644 --- a/storage/system-test/quickstart.test.js +++ b/storage/system-test/quickstart.test.js @@ -15,6 +15,8 @@ 'use strict'; +require(`../../system-test/_setup`); + const proxyquire = require(`proxyquire`).noPreserveCache(); const storage = proxyquire(`@google-cloud/storage`, {})(); const uuid = require(`uuid`); @@ -22,36 +24,42 @@ const uuid = require(`uuid`); const bucketName = `nodejs-docs-samples-test-${uuid.v4()}`; const bucket = storage.bucket(bucketName); -describe(`storage:quickstart`, () => { - after(() => bucket.delete().catch(() => {})); - - it(`should create a bucket`, (done) => { - const expectedBucketName = `my-new-bucket`; +test.before(stubConsole); +test.after(async () => { + restoreConsole(); + try { + await bucket.delete(); + } catch (err) {} // ignore error +}); - const storageMock = { - createBucket: (_bucketName) => { - assert.equal(_bucketName, expectedBucketName); +test.cb(`should create a bucket`, (t) => { + const expectedBucketName = `my-new-bucket`; - return bucket.create() - .then((results) => { - const bucket = results[0]; + const storageMock = { + createBucket: (_bucketName) => { + t.is(_bucketName, expectedBucketName); - assert.notEqual(bucket, undefined); - assert.equal(bucket.name, bucketName); + return bucket.create() + .then(([bucket]) => { + t.not(bucket, undefined); + t.is(bucket.name, bucketName); - setTimeout(() => { - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, [`Bucket ${bucket.name} created.`]); - done(); - }, 200); + setTimeout(() => { + try { + t.true(console.log.calledOnce); + t.deepEqual(console.log.firstCall.args, [`Bucket ${bucket.name} created.`]); + t.end(); + } catch (err) { + t.end(err); + } + }, 200); - return results; - }); - } - }; + return [bucket]; + }); + } + }; - proxyquire(`../quickstart`, { - '@google-cloud/storage': sinon.stub().returns(storageMock) - }); + proxyquire(`../quickstart`, { + '@google-cloud/storage': sinon.stub().returns(storageMock) }); }); diff --git a/storage/system-test/transfer.test.js b/storage/system-test/transfer.test.js index 2355ce14b1..1a5544ff18 100644 --- a/storage/system-test/transfer.test.js +++ b/storage/system-test/transfer.test.js @@ -15,127 +15,115 @@ 'use strict'; -var uuid = require('uuid'); -var program = require('../transfer'); -var Storage = require('@google-cloud/storage'); +require(`../../system-test/_setup`); -var storage = Storage(); -var firstBucketName = 'nodejs-docs-samples-test-' + uuid.v4(); -var secondBucketName = 'nodejs-docs-samples-test-' + uuid.v4(); +const uuid = require(`uuid`); +const program = require(`../transfer`); +const Storage = require(`@google-cloud/storage`); -describe('storage:transfer', function () { - var jobName; - var date = '2222/08/11'; - var time = '15:30'; - var description = 'this is a test'; - var status = 'DISABLED'; +const storage = Storage(); +const firstBucketName = `nodejs-docs-samples-test-${uuid.v4()}`; +const secondBucketName = `nodejs-docs-samples-test-${uuid.v4()}`; - before(function (done) { - storage.createBucket(firstBucketName, function (err) { - if (err) { - return done(err); - } - storage.createBucket(secondBucketName, done); - }); - }); +let jobName; +const date = `2222/08/11`; +const time = `15:30`; +const description = `this is a test`; +const status = `DISABLED`; - after(function (done) { - storage.bucket(firstBucketName).deleteFiles({ force: true }, function (err) { - if (err) { - return done(err); - } - storage.bucket(firstBucketName).delete(function (err) { - if (err) { - return done(err); - } - storage.bucket(secondBucketName).deleteFiles({ force: true }, function (err) { - if (err) { - return done(err); - } - storage.bucket(secondBucketName).delete(done); - }); - }); - }); - }); +test.before(async () => { + stubConsole(); + await storage.createBucket(firstBucketName); + await storage.createBucket(secondBucketName); +}); + +test.after(async () => { + restoreConsole(); + const bucketOne = storage.bucket(firstBucketName); + const bucketTwo = storage.bucket(secondBucketName); + try { + bucketOne.deleteFiles({ force: true }); + } catch (err) {} // ignore error + try { + bucketOne.deleteFiles({ force: true }); + } catch (err) {} // ignore error + try { + bucketOne.delete(); + } catch (err) {} // ignore error + try { + bucketTwo.deleteFiles({ force: true }); + } catch (err) {} // ignore error + try { + bucketTwo.deleteFiles({ force: true }); + } catch (err) {} // ignore error + try { + bucketTwo.delete(); + } catch (err) {} // ignore error +}); - describe('createTransferJob', function () { - it('should create a storage transfer job', function (done) { - var options = { - srcBucket: firstBucketName, - destBucket: secondBucketName, - date: date, - time: time, - description: description - }; +test.cb.serial(`should create a storage transfer job`, (t) => { + const options = { + srcBucket: firstBucketName, + destBucket: secondBucketName, + date: date, + time: time, + description: description + }; - program.createTransferJob(options, function (err, transferJob) { - assert.ifError(err); - jobName = transferJob.name; - assert.equal(transferJob.name.indexOf('transferJobs/'), 0); - assert.equal(transferJob.description, description); - assert.equal(transferJob.status, 'ENABLED'); - assert(console.log.calledWith('Created transfer job: %s', transferJob.name)); - setTimeout(done, 2000); - }); - }); + program.createTransferJob(options, (err, transferJob) => { + t.ifError(err); + jobName = transferJob.name; + t.is(transferJob.name.indexOf(`transferJobs/`), 0); + t.is(transferJob.description, description); + t.is(transferJob.status, `ENABLED`); + t.true(console.log.calledWith(`Created transfer job: %s`, transferJob.name)); + setTimeout(t.end, 2000); }); +}); - describe('getTransferJob', function () { - it('should get a transferJob', function (done) { - program.getTransferJob(jobName, function (err, transferJob) { - assert.ifError(err); - assert.equal(transferJob.name, jobName); - assert.equal(transferJob.description, description); - assert.equal(transferJob.status, 'ENABLED'); - assert(console.log.calledWith('Found transfer job: %s', transferJob.name)); - setTimeout(done, 2000); - }); - }); +test.cb.serial(`should get a transferJob`, (t) => { + program.getTransferJob(jobName, (err, transferJob) => { + t.ifError(err); + t.is(transferJob.name, jobName); + t.is(transferJob.description, description); + t.is(transferJob.status, `ENABLED`); + t.true(console.log.calledWith(`Found transfer job: %s`, transferJob.name)); + setTimeout(t.end, 2000); }); +}); - describe('updateTransferJob', function () { - it('should update a transferJob', function (done) { - var options = { - job: jobName, - field: 'status', - value: status - }; +test.cb.serial(`should update a transferJob`, (t) => { + var options = { + job: jobName, + field: `status`, + value: status + }; - program.updateTransferJob(options, function (err, transferJob) { - assert.ifError(err); - assert.equal(transferJob.name, jobName); - assert.equal(transferJob.description, description); - assert.equal(transferJob.status, status); - assert(console.log.calledWith('Updated transfer job: %s', transferJob.name)); - setTimeout(done, 2000); - }); - }); + program.updateTransferJob(options, (err, transferJob) => { + t.ifError(err); + t.is(transferJob.name, jobName); + t.is(transferJob.description, description); + t.is(transferJob.status, status); + t.true(console.log.calledWith(`Updated transfer job: %s`, transferJob.name)); + setTimeout(t.end, 2000); }); +}); - describe('listTransferJobs', function () { - it('should list transferJobs', function (done) { - program.listTransferJobs(function (err, transferJobs) { - assert.ifError(err); - var matchingTransferJobs = transferJobs.filter(function (transferJob) { - return transferJob.name === jobName; - }); - assert.equal(matchingTransferJobs.length, 1); - assert.equal(matchingTransferJobs[0].name, jobName); - assert.equal(matchingTransferJobs[0].description, description); - assert.equal(matchingTransferJobs[0].status, status); - assert(console.log.calledWith('Found %d jobs!', transferJobs.length)); - setTimeout(done, 2000); - }); - }); +test.cb.serial(`should list transferJobs`, (t) => { + program.listTransferJobs((err, transferJobs) => { + t.ifError(err); + t.true(transferJobs.some((transferJob) => transferJob.name === jobName)); + t.true(transferJobs.some((transferJob) => transferJob.description === description)); + t.true(transferJobs.some((transferJob) => transferJob.status === status)); + t.true(console.log.calledWith(`Found %d jobs!`, transferJobs.length)); + setTimeout(t.end, 2000); }); +}); - describe('listTransferOperations', function () { - it('should list transferJobs', function (done) { - program.listTransferOperations(jobName, function (err, operations) { - assert.ifError(err); - assert(Array.isArray(operations)); - done(); - }); - }); +test.cb.serial(`should list transferJobs`, (t) => { + program.listTransferOperations(jobName, (err, operations) => { + t.ifError(err); + t.true(Array.isArray(operations)); + t.end(); }); }); diff --git a/storage/test/transfer.test.js b/storage/test/transfer.test.js index baef195cd2..b32faa206c 100644 --- a/storage/test/transfer.test.js +++ b/storage/test/transfer.test.js @@ -15,18 +15,20 @@ 'use strict'; -var proxyquire = require('proxyquire').noCallThru(); -var srcBucketName = 'foo'; -var destBucketName = 'bar'; -var jobName = 'transferJobs/123456789012345678'; -var transferOperationName = 'transferOperations/123456789012345678'; +require(`../../test/_setup`); + +const proxyquire = require(`proxyquire`).noCallThru(); +const srcBucketName = `foo`; +const destBucketName = `bar`; +const jobName = `transferJobs/123456789012345678`; +const transferOperationName = `transferOperations/123456789012345678`; function getSample () { - var transferJobMock = { + const transferJobMock = { name: jobName }; - var transferOperationMock = {}; - var storagetransferMock = { + const transferOperationMock = {}; + const storagetransferMock = { transferJobs: { create: sinon.stub().yields(null, transferJobMock), get: sinon.stub().yields(null, transferJobMock), @@ -40,7 +42,7 @@ function getSample () { list: sinon.stub().yields(null, { operations: [transferOperationMock] }) } }; - var googleapisMock = { + const googleapisMock = { storagetransfer: sinon.stub().returns(storagetransferMock), auth: { getApplicationDefault: sinon.stub().yields(null, {}) @@ -48,9 +50,9 @@ function getSample () { }; return { - program: proxyquire('../transfer', { + program: proxyquire(`../transfer`, { googleapis: googleapisMock, - yargs: proxyquire('yargs', {}) + yargs: proxyquire(`yargs`, {}) }), mocks: { googleapis: googleapisMock, @@ -61,586 +63,565 @@ function getSample () { }; } -describe('storage:transfer', function () { - describe('jobs', function () { - describe('create', function () { - it('should create a transfer job', function () { - var description = 'description'; - var sample = getSample(); - var callback = sinon.stub(); - var date = '2016/08/11'; - var time = '15:30'; - var options = { - srcBucket: srcBucketName, - destBucket: destBucketName, - date: date, - time: time - }; - - sample.program.createTransferJob(options, callback); - - assert.equal(sample.mocks.storagetransfer.transferJobs.create.calledOnce, true); - assert.equal(sample.mocks.storagetransfer.transferJobs.create.firstCall.args[0].resource.description, undefined); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.transferJob]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Created transfer job: %s', sample.mocks.transferJob.name]); - - options.description = description; - sample.program.createTransferJob(options, callback); - - assert.equal(sample.mocks.storagetransfer.transferJobs.create.calledTwice, true); - assert.equal(sample.mocks.storagetransfer.transferJobs.create.secondCall.args[0].resource.description, description); - assert.equal(callback.calledTwice, true); - assert.deepEqual(callback.secondCall.args, [null, sample.mocks.transferJob]); - assert.equal(console.log.calledTwice, true); - assert.deepEqual(console.log.secondCall.args, ['Created transfer job: %s', sample.mocks.transferJob.name]); - }); - - it('should handle auth error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.googleapis.auth.getApplicationDefault.yields(error); - - sample.program.createTransferJob({}, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - - it('should handle create error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.storagetransfer.transferJobs.create.yields(error); - - sample.program.createTransferJob({}, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('get', function () { - it('should get a transfer job', function () { - var sample = getSample(); - var callback = sinon.stub(); - - sample.program.getTransferJob(jobName, callback); - - assert.equal(sample.mocks.storagetransfer.transferJobs.get.calledOnce, true); - assert.deepEqual(sample.mocks.storagetransfer.transferJobs.get.firstCall.args.slice(0, -1), [{ - auth: {}, - projectId: process.env.GCLOUD_PROJECT, - jobName: jobName - }]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.transferJob]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Found transfer job: %s', sample.mocks.transferJob.name]); - }); - - it('should handle auth error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.googleapis.auth.getApplicationDefault.yields(error); - - sample.program.getTransferJob(jobName, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - - it('should handle get error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.storagetransfer.transferJobs.get.yields(error); - - sample.program.getTransferJob(jobName, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('set', function () { - it('should update a transfer job', function () { - var sample = getSample(); - var callback = sinon.stub(); - var options = { - job: jobName, - field: 'status', - value: 'DISABLED' - }; - - sample.program.updateTransferJob(options, callback); - - assert.equal(sample.mocks.storagetransfer.transferJobs.patch.calledOnce, true); - assert.deepEqual(sample.mocks.storagetransfer.transferJobs.patch.firstCall.args.slice(0, -1), [{ - auth: {}, - jobName: jobName, - resource: { - projectId: process.env.GCLOUD_PROJECT, - transferJob: { - name: jobName, - status: options.value - }, - updateTransferJobFieldMask: options.field - } - }]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.transferJob]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Updated transfer job: %s', jobName]); - - options.field = 'description'; - options.value = 'description'; - - sample.program.updateTransferJob(options, callback); - - assert.equal(sample.mocks.storagetransfer.transferJobs.patch.calledTwice, true); - assert.deepEqual(sample.mocks.storagetransfer.transferJobs.patch.secondCall.args.slice(0, -1), [{ - auth: {}, - jobName: jobName, - resource: { - projectId: process.env.GCLOUD_PROJECT, - transferJob: { - name: jobName, - description: options.value - }, - updateTransferJobFieldMask: options.field - } - }]); - assert.equal(callback.calledTwice, true); - assert.deepEqual(callback.secondCall.args, [null, sample.mocks.transferJob]); - assert.equal(console.log.calledTwice, true); - assert.deepEqual(console.log.secondCall.args, ['Updated transfer job: %s', jobName]); - - options.field = 'transferSpec'; - options.value = '{"foo":"bar"}'; - - sample.program.updateTransferJob(options, callback); - - assert.equal(sample.mocks.storagetransfer.transferJobs.patch.calledThrice, true); - assert.deepEqual(sample.mocks.storagetransfer.transferJobs.patch.thirdCall.args.slice(0, -1), [{ - auth: {}, - jobName: jobName, - resource: { - projectId: process.env.GCLOUD_PROJECT, - transferJob: { - name: jobName, - transferSpec: JSON.parse(options.value) - }, - updateTransferJobFieldMask: options.field - } - }]); - assert.equal(callback.calledThrice, true); - assert.deepEqual(callback.thirdCall.args, [null, sample.mocks.transferJob]); - assert.equal(console.log.calledThrice, true); - assert.deepEqual(console.log.thirdCall.args, ['Updated transfer job: %s', jobName]); - }); - - it('should handle auth error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - var options = { - job: jobName, - field: 'status', - value: 'DISABLED' - }; - sample.mocks.googleapis.auth.getApplicationDefault.yields(error); - - sample.program.updateTransferJob(options, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - - it('should handle patch error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - var options = { - job: jobName, - field: 'status', - value: 'DISABLED' - }; - sample.mocks.storagetransfer.transferJobs.patch.yields(error); - - sample.program.updateTransferJob(options, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('list', function () { - it('should list transfer jobs', function () { - var sample = getSample(); - var callback = sinon.stub(); - - sample.program.listTransferJobs(callback); - - assert.equal(sample.mocks.storagetransfer.transferJobs.list.calledOnce, true); - assert.deepEqual(sample.mocks.storagetransfer.transferJobs.list.firstCall.args.slice(0, -1), [{ - auth: {}, - filter: JSON.stringify({ project_id: process.env.GCLOUD_PROJECT }) - }]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, [sample.mocks.transferJob]]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Found %d jobs!', 1]); - - sample.mocks.storagetransfer.transferJobs.list.yields(null, {}); - sample.program.listTransferJobs(callback); - - assert.equal(sample.mocks.storagetransfer.transferJobs.list.calledTwice, true); - assert.deepEqual(sample.mocks.storagetransfer.transferJobs.list.secondCall.args.slice(0, -1), [{ - auth: {}, - filter: JSON.stringify({ project_id: process.env.GCLOUD_PROJECT }) - }]); - assert.equal(callback.calledTwice, true); - assert.deepEqual(callback.secondCall.args, [null, []]); - assert.equal(console.log.calledOnce, true); - }); - - it('should handle auth error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.googleapis.auth.getApplicationDefault.yields(error); - - sample.program.listTransferJobs(callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - - it('should handle list error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.storagetransfer.transferJobs.list.yields(error); - - sample.program.listTransferJobs(callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - }); - - describe('operations', function () { - describe('list', function () { - it('should list transfer operations', function () { - var sample = getSample(); - var callback = sinon.stub(); - - // Test that all operations get listed - sample.program.listTransferOperations(undefined, callback); - - assert.equal(sample.mocks.storagetransfer.transferOperations.list.calledOnce, true); - assert.deepEqual(sample.mocks.storagetransfer.transferOperations.list.firstCall.args.slice(0, -1), [{ - name: 'transferOperations', - auth: {}, - filter: JSON.stringify({ project_id: process.env.GCLOUD_PROJECT }) - }]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, [sample.mocks.transferOperation]]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Found %d operations!', 1]); - - // Test that operations for a specific job get listed - sample.program.listTransferOperations(jobName, callback); - - assert.equal(sample.mocks.storagetransfer.transferOperations.list.calledTwice, true); - assert.deepEqual(sample.mocks.storagetransfer.transferOperations.list.secondCall.args.slice(0, -1), [{ - name: 'transferOperations', - auth: {}, - filter: JSON.stringify({ project_id: process.env.GCLOUD_PROJECT, job_names: [jobName] }) - }]); - assert.equal(callback.calledTwice, true); - assert.deepEqual(callback.secondCall.args, [null, [sample.mocks.transferOperation]]); - assert.equal(console.log.calledTwice, true); - assert.deepEqual(console.log.secondCall.args, ['Found %d operations!', 1]); - - // Test that operations for a specific job get listed when the API response with just an object - sample.mocks.storagetransfer.transferOperations.list.yields(null, {}); - sample.program.listTransferOperations(jobName, callback); - - assert.equal(sample.mocks.storagetransfer.transferOperations.list.calledThrice, true); - assert.deepEqual(sample.mocks.storagetransfer.transferOperations.list.thirdCall.args.slice(0, -1), [{ - name: 'transferOperations', - auth: {}, - filter: JSON.stringify({ project_id: process.env.GCLOUD_PROJECT, job_names: [jobName] }) - }]); - assert.equal(callback.calledThrice, true); - assert.deepEqual(callback.thirdCall.args, [null, []]); - assert.equal(console.log.calledTwice, true); - }); - - it('should handle auth error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.googleapis.auth.getApplicationDefault.yields(error); - - sample.program.listTransferOperations(undefined, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - - it('should handle list error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.storagetransfer.transferOperations.list.yields(error); - - sample.program.listTransferOperations(undefined, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('get', function () { - it('should get a transfer operation', function () { - var sample = getSample(); - var callback = sinon.stub(); - - sample.program.getTransferOperation(transferOperationName, callback); - - assert.equal(callback.calledOnce, true); - assert.equal(callback.firstCall.args.length, 2, 'callback received 2 arguments'); - assert.ifError(callback.firstCall.args[0], 'callback did not receive error'); - assert.strictEqual(callback.firstCall.args[1], sample.mocks.transferOperation, 'callback received transfer operation'); - - assert.equal(sample.mocks.storagetransfer.transferOperations.get.calledOnce, true); - assert.deepEqual(sample.mocks.storagetransfer.transferOperations.get.firstCall.args.slice(0, -1), [{ - name: transferOperationName, - auth: {} - }]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.transferOperation]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Found transfer operation: %s', sample.mocks.transferOperation]); - }); - - it('should handle auth error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.googleapis.auth.getApplicationDefault.yields(error); - - sample.program.getTransferOperation(jobName, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - - it('should handle get error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.storagetransfer.transferOperations.get.yields(error); - - sample.program.getTransferOperation(jobName, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('pause', function () { - it('should pause a transfer operation', function () { - var sample = getSample(); - var callback = sinon.stub(); - - sample.program.pauseTransferOperation(transferOperationName, callback); - - assert.equal(callback.calledOnce, true); - assert.equal(callback.firstCall.args.length, 1, 'callback received 1 argument'); - assert.ifError(callback.firstCall.args[0], 'callback did not receive error'); - - assert.equal(sample.mocks.storagetransfer.transferOperations.pause.calledOnce, true); - assert.deepEqual(sample.mocks.storagetransfer.transferOperations.pause.firstCall.args.slice(0, -1), [{ - name: transferOperationName, - auth: {} - }]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Paused transfer operation: %s', transferOperationName]); - }); - - it('should handle auth error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.googleapis.auth.getApplicationDefault.yields(error); - - sample.program.pauseTransferOperation(jobName, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - - it('should handle pause error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.storagetransfer.transferOperations.pause.yields(error); - - sample.program.pauseTransferOperation(jobName, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('resume', function () { - it('should resume a transfer operation', function () { - var sample = getSample(); - var callback = sinon.stub(); - - sample.program.resumeTransferOperation(transferOperationName, callback); - - assert.equal(callback.calledOnce, true); - assert.equal(callback.firstCall.args.length, 1, 'callback received 1 argument'); - assert.ifError(callback.firstCall.args[0], 'callback did not receive error'); - - assert.equal(sample.mocks.storagetransfer.transferOperations.resume.calledOnce, true); - assert.deepEqual(sample.mocks.storagetransfer.transferOperations.resume.firstCall.args.slice(0, -1), [{ - name: transferOperationName, - auth: {} - }]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Resumed transfer operation: %s', transferOperationName]); - }); - - it('should handle auth error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.googleapis.auth.getApplicationDefault.yields(error); - - sample.program.resumeTransferOperation(jobName, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - - it('should handle resume error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.storagetransfer.transferOperations.resume.yields(error); - - sample.program.resumeTransferOperation(jobName, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - }); - - describe('main', function () { - it('should call createTransferJob', function () { - var program = getSample().program; - - sinon.stub(program, 'createTransferJob'); - program.main(['jobs', 'create', srcBucketName, destBucketName, 'time', 'date']); - assert.equal(program.createTransferJob.calledOnce, true); - assert.deepEqual(program.createTransferJob.firstCall.args.slice(0, -1), [{ - srcBucket: srcBucketName, - destBucket: destBucketName, - time: 'time', - date: 'date', - description: undefined - }]); - }); - - it('should call getTransferJob', function () { - var program = getSample().program; - - sinon.stub(program, 'getTransferJob'); - program.main(['jobs', 'get', jobName]); - assert.equal(program.getTransferJob.calledOnce, true); - assert.deepEqual(program.getTransferJob.firstCall.args.slice(0, -1), [jobName]); - }); - - it('should call listTransferJobs', function () { - var program = getSample().program; - - sinon.stub(program, 'listTransferJobs'); - program.main(['jobs', 'list']); - assert.equal(program.listTransferJobs.calledOnce, true); - assert.deepEqual(program.listTransferJobs.firstCall.args.slice(0, -1), []); - }); - - it('should call updateTransferJob', function () { - var program = getSample().program; - - sinon.stub(program, 'updateTransferJob'); - program.main(['jobs', 'set', jobName, 'status', 'DISABLED']); - assert.equal(program.updateTransferJob.calledOnce, true); - assert.deepEqual(program.updateTransferJob.firstCall.args.slice(0, -1), [{ - job: jobName, - field: 'status', - value: 'DISABLED' - }]); - }); - - it('should call listTransferOperations', function () { - var program = getSample().program; - - sinon.stub(program, 'listTransferOperations'); - program.main(['operations', 'list']); - assert.equal(program.listTransferOperations.calledOnce, true); - assert.deepEqual(program.listTransferOperations.firstCall.args.slice(0, -1), [undefined]); - }); - - it('should call listTransferOperations and filter', function () { - var program = getSample().program; - - sinon.stub(program, 'listTransferOperations'); - program.main(['operations', 'list', jobName]); - assert.equal(program.listTransferOperations.calledOnce, true); - assert.deepEqual(program.listTransferOperations.firstCall.args.slice(0, -1), [jobName]); - }); - - it('should call getTransferOperation', function () { - var program = getSample().program; - - sinon.stub(program, 'getTransferOperation'); - program.main(['operations', 'get', transferOperationName]); - assert.equal(program.getTransferOperation.calledOnce, true); - assert.deepEqual(program.getTransferOperation.firstCall.args.slice(0, -1), [transferOperationName]); - }); - - it('should call pauseTransferOperation', function () { - var program = getSample().program; - - sinon.stub(program, 'pauseTransferOperation'); - program.main(['operations', 'pause', transferOperationName]); - assert.equal(program.pauseTransferOperation.calledOnce, true); - assert.deepEqual(program.pauseTransferOperation.firstCall.args.slice(0, -1), [transferOperationName]); - }); - - it('should call resumeTransferOperation', function () { - var program = getSample().program; - - sinon.stub(program, 'resumeTransferOperation'); - program.main(['operations', 'resume', transferOperationName]); - assert.equal(program.resumeTransferOperation.calledOnce, true); - assert.deepEqual(program.resumeTransferOperation.firstCall.args.slice(0, -1), [transferOperationName]); - }); - }); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); + +test.serial(`should create a transfer job`, (t) => { + const description = `description`; + const sample = getSample(); + const callback = sinon.stub(); + const date = `2016/08/11`; + const time = `15:30`; + const options = { + srcBucket: srcBucketName, + destBucket: destBucketName, + date: date, + time: time + }; + + sample.program.createTransferJob(options, callback); + + t.true(sample.mocks.storagetransfer.transferJobs.create.calledOnce); + t.is(sample.mocks.storagetransfer.transferJobs.create.firstCall.args[0].resource.description, undefined); + t.true(callback.calledOnce); + t.deepEqual(callback.firstCall.args, [null, sample.mocks.transferJob]); + t.true(console.log.calledOnce); + t.deepEqual(console.log.firstCall.args, [`Created transfer job: %s`, sample.mocks.transferJob.name]); + + options.description = description; + sample.program.createTransferJob(options, callback); + + t.true(sample.mocks.storagetransfer.transferJobs.create.calledTwice); + t.is(sample.mocks.storagetransfer.transferJobs.create.secondCall.args[0].resource.description, description); + t.true(callback.calledTwice); + t.deepEqual(callback.secondCall.args, [null, sample.mocks.transferJob]); + t.true(console.log.calledTwice); + t.deepEqual(console.log.secondCall.args, [`Created transfer job: %s`, sample.mocks.transferJob.name]); +}); + +test.serial(`should handle auth error`, (t) => { + const error = new Error(`error`); + const sample = getSample(); + const callback = sinon.stub(); + sample.mocks.googleapis.auth.getApplicationDefault.yields(error); + + sample.program.createTransferJob({}, callback); + + t.true(callback.calledOnce); + t.deepEqual(callback.firstCall.args, [error]); +}); + +test.serial(`should handle create error`, (t) => { + const error = new Error(`error`); + const sample = getSample(); + const callback = sinon.stub(); + sample.mocks.storagetransfer.transferJobs.create.yields(error); + + sample.program.createTransferJob({}, callback); + + t.true(callback.calledOnce); + t.deepEqual(callback.firstCall.args, [error]); +}); + +test.serial(`should get a transfer job`, (t) => { + const sample = getSample(); + const callback = sinon.stub(); + + sample.program.getTransferJob(jobName, callback); + + t.true(sample.mocks.storagetransfer.transferJobs.get.calledOnce); + t.deepEqual(sample.mocks.storagetransfer.transferJobs.get.firstCall.args.slice(0, -1), [{ + auth: {}, + projectId: process.env.GCLOUD_PROJECT, + jobName: jobName + }]); + t.true(callback.calledOnce); + t.deepEqual(callback.firstCall.args, [null, sample.mocks.transferJob]); + t.true(console.log.calledOnce); + t.deepEqual(console.log.firstCall.args, [`Found transfer job: %s`, sample.mocks.transferJob.name]); +}); + +test.serial(`should handle auth error`, (t) => { + const error = new Error(`error`); + const sample = getSample(); + const callback = sinon.stub(); + sample.mocks.googleapis.auth.getApplicationDefault.yields(error); + + sample.program.getTransferJob(jobName, callback); + + t.true(callback.calledOnce); + t.deepEqual(callback.firstCall.args, [error]); +}); + +test.serial(`should handle get error`, (t) => { + const error = new Error(`error`); + const sample = getSample(); + const callback = sinon.stub(); + sample.mocks.storagetransfer.transferJobs.get.yields(error); + + sample.program.getTransferJob(jobName, callback); + + t.true(callback.calledOnce); + t.deepEqual(callback.firstCall.args, [error]); +}); + +test.serial(`should update a transfer job`, (t) => { + const sample = getSample(); + const callback = sinon.stub(); + const options = { + job: jobName, + field: `status`, + value: `DISABLED` + }; + + sample.program.updateTransferJob(options, callback); + + t.true(sample.mocks.storagetransfer.transferJobs.patch.calledOnce); + t.deepEqual(sample.mocks.storagetransfer.transferJobs.patch.firstCall.args.slice(0, -1), [{ + auth: {}, + jobName: jobName, + resource: { + projectId: process.env.GCLOUD_PROJECT, + transferJob: { + name: jobName, + status: options.value + }, + updateTransferJobFieldMask: options.field + } + }]); + t.true(callback.calledOnce); + t.deepEqual(callback.firstCall.args, [null, sample.mocks.transferJob]); + t.true(console.log.calledOnce); + t.deepEqual(console.log.firstCall.args, [`Updated transfer job: %s`, jobName]); + + options.field = `description`; + options.value = `description`; + + sample.program.updateTransferJob(options, callback); + + t.true(sample.mocks.storagetransfer.transferJobs.patch.calledTwice); + t.deepEqual(sample.mocks.storagetransfer.transferJobs.patch.secondCall.args.slice(0, -1), [{ + auth: {}, + jobName: jobName, + resource: { + projectId: process.env.GCLOUD_PROJECT, + transferJob: { + name: jobName, + description: options.value + }, + updateTransferJobFieldMask: options.field + } + }]); + t.true(callback.calledTwice); + t.deepEqual(callback.secondCall.args, [null, sample.mocks.transferJob]); + t.true(console.log.calledTwice); + t.deepEqual(console.log.secondCall.args, [`Updated transfer job: %s`, jobName]); + + options.field = `transferSpec`; + options.value = `{"foo":"bar"}`; + + sample.program.updateTransferJob(options, callback); + + t.true(sample.mocks.storagetransfer.transferJobs.patch.calledThrice); + t.deepEqual(sample.mocks.storagetransfer.transferJobs.patch.thirdCall.args.slice(0, -1), [{ + auth: {}, + jobName: jobName, + resource: { + projectId: process.env.GCLOUD_PROJECT, + transferJob: { + name: jobName, + transferSpec: JSON.parse(options.value) + }, + updateTransferJobFieldMask: options.field + } + }]); + t.true(callback.calledThrice); + t.deepEqual(callback.thirdCall.args, [null, sample.mocks.transferJob]); + t.true(console.log.calledThrice); + t.deepEqual(console.log.thirdCall.args, [`Updated transfer job: %s`, jobName]); +}); + +test.serial(`should handle auth error`, (t) => { + const error = new Error(`error`); + const sample = getSample(); + const callback = sinon.stub(); + const options = { + job: jobName, + field: `status`, + value: `DISABLED` + }; + sample.mocks.googleapis.auth.getApplicationDefault.yields(error); + + sample.program.updateTransferJob(options, callback); + + t.true(callback.calledOnce); + t.deepEqual(callback.firstCall.args, [error]); +}); + +test.serial(`should handle patch error`, (t) => { + const error = new Error(`error`); + const sample = getSample(); + const callback = sinon.stub(); + const options = { + job: jobName, + field: `status`, + value: `DISABLED` + }; + sample.mocks.storagetransfer.transferJobs.patch.yields(error); + + sample.program.updateTransferJob(options, callback); + + t.true(callback.calledOnce); + t.deepEqual(callback.firstCall.args, [error]); +}); + +test.serial(`should list transfer jobs`, (t) => { + const sample = getSample(); + const callback = sinon.stub(); + + sample.program.listTransferJobs(callback); + + t.true(sample.mocks.storagetransfer.transferJobs.list.calledOnce); + t.deepEqual(sample.mocks.storagetransfer.transferJobs.list.firstCall.args.slice(0, -1), [{ + auth: {}, + filter: JSON.stringify({ project_id: process.env.GCLOUD_PROJECT }) + }]); + t.true(callback.calledOnce); + t.deepEqual(callback.firstCall.args, [null, [sample.mocks.transferJob]]); + t.true(console.log.calledOnce); + t.deepEqual(console.log.firstCall.args, [`Found %d jobs!`, 1]); + + sample.mocks.storagetransfer.transferJobs.list.yields(null, {}); + sample.program.listTransferJobs(callback); + + t.true(sample.mocks.storagetransfer.transferJobs.list.calledTwice); + t.deepEqual(sample.mocks.storagetransfer.transferJobs.list.secondCall.args.slice(0, -1), [{ + auth: {}, + filter: JSON.stringify({ project_id: process.env.GCLOUD_PROJECT }) + }]); + t.true(callback.calledTwice); + t.deepEqual(callback.secondCall.args, [null, []]); + t.true(console.log.calledOnce); +}); + +test.serial(`should handle auth error`, (t) => { + const error = new Error(`error`); + const sample = getSample(); + const callback = sinon.stub(); + sample.mocks.googleapis.auth.getApplicationDefault.yields(error); + + sample.program.listTransferJobs(callback); + + t.true(callback.calledOnce); + t.deepEqual(callback.firstCall.args, [error]); +}); + +test.serial(`should handle list error`, (t) => { + const error = new Error(`error`); + const sample = getSample(); + const callback = sinon.stub(); + sample.mocks.storagetransfer.transferJobs.list.yields(error); + + sample.program.listTransferJobs(callback); + + t.true(callback.calledOnce); + t.deepEqual(callback.firstCall.args, [error]); +}); + +test.serial(`should list transfer operations`, (t) => { + const sample = getSample(); + const callback = sinon.stub(); + + // Test that all operations get listed + sample.program.listTransferOperations(undefined, callback); + + t.true(sample.mocks.storagetransfer.transferOperations.list.calledOnce); + t.deepEqual(sample.mocks.storagetransfer.transferOperations.list.firstCall.args.slice(0, -1), [{ + name: `transferOperations`, + auth: {}, + filter: JSON.stringify({ project_id: process.env.GCLOUD_PROJECT }) + }]); + t.true(callback.calledOnce); + t.deepEqual(callback.firstCall.args, [null, [sample.mocks.transferOperation]]); + t.true(console.log.calledOnce); + t.deepEqual(console.log.firstCall.args, [`Found %d operations!`, 1]); + + // Test that operations for a specific job get listed + sample.program.listTransferOperations(jobName, callback); + + t.true(sample.mocks.storagetransfer.transferOperations.list.calledTwice); + t.deepEqual(sample.mocks.storagetransfer.transferOperations.list.secondCall.args.slice(0, -1), [{ + name: `transferOperations`, + auth: {}, + filter: JSON.stringify({ project_id: process.env.GCLOUD_PROJECT, job_names: [jobName] }) + }]); + t.true(callback.calledTwice); + t.deepEqual(callback.secondCall.args, [null, [sample.mocks.transferOperation]]); + t.true(console.log.calledTwice); + t.deepEqual(console.log.secondCall.args, [`Found %d operations!`, 1]); + + // Test that operations for a specific job get listed when the API response with just an object + sample.mocks.storagetransfer.transferOperations.list.yields(null, {}); + sample.program.listTransferOperations(jobName, callback); + + t.true(sample.mocks.storagetransfer.transferOperations.list.calledThrice); + t.deepEqual(sample.mocks.storagetransfer.transferOperations.list.thirdCall.args.slice(0, -1), [{ + name: `transferOperations`, + auth: {}, + filter: JSON.stringify({ project_id: process.env.GCLOUD_PROJECT, job_names: [jobName] }) + }]); + t.true(callback.calledThrice); + t.deepEqual(callback.thirdCall.args, [null, []]); + t.true(console.log.calledTwice); +}); + +test.serial(`should handle auth error`, (t) => { + const error = new Error(`error`); + const sample = getSample(); + const callback = sinon.stub(); + sample.mocks.googleapis.auth.getApplicationDefault.yields(error); + + sample.program.listTransferOperations(undefined, callback); + + t.true(callback.calledOnce); + t.deepEqual(callback.firstCall.args, [error]); +}); + +test.serial(`should handle list error`, (t) => { + const error = new Error(`error`); + const sample = getSample(); + const callback = sinon.stub(); + sample.mocks.storagetransfer.transferOperations.list.yields(error); + + sample.program.listTransferOperations(undefined, callback); + + t.true(callback.calledOnce); + t.deepEqual(callback.firstCall.args, [error]); +}); + +test.serial(`should get a transfer operation`, (t) => { + const sample = getSample(); + const callback = sinon.stub(); + + sample.program.getTransferOperation(transferOperationName, callback); + + t.true(callback.calledOnce); + t.is(callback.firstCall.args.length, 2, `callback received 2 arguments`); + t.ifError(callback.firstCall.args[0], `callback did not receive error`); + t.true(callback.firstCall.args[1] === sample.mocks.transferOperation); + + t.true(sample.mocks.storagetransfer.transferOperations.get.calledOnce); + t.deepEqual(sample.mocks.storagetransfer.transferOperations.get.firstCall.args.slice(0, -1), [{ + name: transferOperationName, + auth: {} + }]); + t.true(callback.calledOnce); + t.deepEqual(callback.firstCall.args, [null, sample.mocks.transferOperation]); + t.true(console.log.calledOnce); + t.deepEqual(console.log.firstCall.args, [`Found transfer operation: %s`, sample.mocks.transferOperation]); +}); + +test.serial(`should handle auth error`, (t) => { + const error = new Error(`error`); + const sample = getSample(); + const callback = sinon.stub(); + sample.mocks.googleapis.auth.getApplicationDefault.yields(error); + + sample.program.getTransferOperation(jobName, callback); + + t.true(callback.calledOnce); + t.deepEqual(callback.firstCall.args, [error]); +}); + +test.serial(`should handle get error`, (t) => { + const error = new Error(`error`); + const sample = getSample(); + const callback = sinon.stub(); + sample.mocks.storagetransfer.transferOperations.get.yields(error); + + sample.program.getTransferOperation(jobName, callback); + + t.true(callback.calledOnce); + t.deepEqual(callback.firstCall.args, [error]); +}); + +test.serial(`should pause a transfer operation`, (t) => { + const sample = getSample(); + const callback = sinon.stub(); + + sample.program.pauseTransferOperation(transferOperationName, callback); + + t.true(callback.calledOnce); + t.is(callback.firstCall.args.length, 1, `callback received 1 argument`); + t.ifError(callback.firstCall.args[0], `callback did not receive error`); + + t.true(sample.mocks.storagetransfer.transferOperations.pause.calledOnce); + t.deepEqual(sample.mocks.storagetransfer.transferOperations.pause.firstCall.args.slice(0, -1), [{ + name: transferOperationName, + auth: {} + }]); + t.true(callback.calledOnce); + t.deepEqual(callback.firstCall.args, [null]); + t.true(console.log.calledOnce); + t.deepEqual(console.log.firstCall.args, [`Paused transfer operation: %s`, transferOperationName]); +}); + +test.serial(`should handle auth error`, (t) => { + const error = new Error(`error`); + const sample = getSample(); + const callback = sinon.stub(); + sample.mocks.googleapis.auth.getApplicationDefault.yields(error); + + sample.program.pauseTransferOperation(jobName, callback); + + t.true(callback.calledOnce); + t.deepEqual(callback.firstCall.args, [error]); +}); + +test.serial(`should handle pause error`, (t) => { + const error = new Error(`error`); + const sample = getSample(); + const callback = sinon.stub(); + sample.mocks.storagetransfer.transferOperations.pause.yields(error); + + sample.program.pauseTransferOperation(jobName, callback); + + t.true(callback.calledOnce); + t.deepEqual(callback.firstCall.args, [error]); +}); + +test.serial(`should resume a transfer operation`, (t) => { + const sample = getSample(); + const callback = sinon.stub(); + + sample.program.resumeTransferOperation(transferOperationName, callback); + + t.true(callback.calledOnce); + t.is(callback.firstCall.args.length, 1, `callback received 1 argument`); + t.ifError(callback.firstCall.args[0], `callback did not receive error`); + + t.true(sample.mocks.storagetransfer.transferOperations.resume.calledOnce); + t.deepEqual(sample.mocks.storagetransfer.transferOperations.resume.firstCall.args.slice(0, -1), [{ + name: transferOperationName, + auth: {} + }]); + t.true(callback.calledOnce); + t.deepEqual(callback.firstCall.args, [null]); + t.true(console.log.calledOnce); + t.deepEqual(console.log.firstCall.args, [`Resumed transfer operation: %s`, transferOperationName]); +}); + +test.serial(`should handle auth error`, (t) => { + const error = new Error(`error`); + const sample = getSample(); + const callback = sinon.stub(); + sample.mocks.googleapis.auth.getApplicationDefault.yields(error); + + sample.program.resumeTransferOperation(jobName, callback); + + t.true(callback.calledOnce); + t.deepEqual(callback.firstCall.args, [error]); +}); + +test.serial(`should handle resume error`, (t) => { + const error = new Error(`error`); + const sample = getSample(); + const callback = sinon.stub(); + sample.mocks.storagetransfer.transferOperations.resume.yields(error); + + sample.program.resumeTransferOperation(jobName, callback); + + t.true(callback.calledOnce); + t.deepEqual(callback.firstCall.args, [error]); +}); + +test.serial(`should call createTransferJob`, (t) => { + const program = getSample().program; + + sinon.stub(program, `createTransferJob`); + program.main([`jobs`, `create`, srcBucketName, destBucketName, `time`, `date`]); + t.true(program.createTransferJob.calledOnce); + t.deepEqual(program.createTransferJob.firstCall.args.slice(0, -1), [{ + srcBucket: srcBucketName, + destBucket: destBucketName, + time: `time`, + date: `date`, + description: undefined + }]); +}); + +test.serial(`should call getTransferJob`, (t) => { + const program = getSample().program; + + sinon.stub(program, `getTransferJob`); + program.main([`jobs`, `get`, jobName]); + t.true(program.getTransferJob.calledOnce); + t.deepEqual(program.getTransferJob.firstCall.args.slice(0, -1), [jobName]); +}); + +test.serial(`should call listTransferJobs`, (t) => { + const program = getSample().program; + + sinon.stub(program, `listTransferJobs`); + program.main([`jobs`, `list`]); + t.true(program.listTransferJobs.calledOnce); + t.deepEqual(program.listTransferJobs.firstCall.args.slice(0, -1), []); +}); + +test.serial(`should call updateTransferJob`, (t) => { + const program = getSample().program; + + sinon.stub(program, `updateTransferJob`); + program.main([`jobs`, `set`, jobName, `status`, `DISABLED`]); + t.true(program.updateTransferJob.calledOnce); + t.deepEqual(program.updateTransferJob.firstCall.args.slice(0, -1), [{ + job: jobName, + field: `status`, + value: `DISABLED` + }]); +}); + +test.serial(`should call listTransferOperations`, (t) => { + const program = getSample().program; + + sinon.stub(program, `listTransferOperations`); + program.main([`operations`, `list`]); + t.true(program.listTransferOperations.calledOnce); + t.deepEqual(program.listTransferOperations.firstCall.args.slice(0, -1), [undefined]); +}); + +test.serial(`should call listTransferOperations and filter`, (t) => { + const program = getSample().program; + + sinon.stub(program, `listTransferOperations`); + program.main([`operations`, `list`, jobName]); + t.true(program.listTransferOperations.calledOnce); + t.deepEqual(program.listTransferOperations.firstCall.args.slice(0, -1), [jobName]); +}); + +test.serial(`should call getTransferOperation`, (t) => { + const program = getSample().program; + + sinon.stub(program, `getTransferOperation`); + program.main([`operations`, `get`, transferOperationName]); + t.true(program.getTransferOperation.calledOnce); + t.deepEqual(program.getTransferOperation.firstCall.args.slice(0, -1), [transferOperationName]); +}); + +test.serial(`should call pauseTransferOperation`, (t) => { + const program = getSample().program; + + sinon.stub(program, `pauseTransferOperation`); + program.main([`operations`, `pause`, transferOperationName]); + t.true(program.pauseTransferOperation.calledOnce); + t.deepEqual(program.pauseTransferOperation.firstCall.args.slice(0, -1), [transferOperationName]); +}); + +test.serial(`should call resumeTransferOperation`, (t) => { + const program = getSample().program; + + sinon.stub(program, `resumeTransferOperation`); + program.main([`operations`, `resume`, transferOperationName]); + t.true(program.resumeTransferOperation.calledOnce); + t.deepEqual(program.resumeTransferOperation.firstCall.args.slice(0, -1), [transferOperationName]); }); diff --git a/system-test/_setup.js b/system-test/_setup.js index 4cd3b2dd4b..09f2414459 100644 --- a/system-test/_setup.js +++ b/system-test/_setup.js @@ -1,47 +1,124 @@ -// Copyright 2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/** + * Copyright 2017, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ 'use strict'; -var assert = require('power-assert').customize({ - output: { - maxDepth: 2 - } -}); -var sinon = require('sinon'); - -global.assert = assert; -global.sinon = sinon; - -var log = console.log; - -beforeEach(function () { - if (process.env.DEBUG) { - sinon.spy(console, 'error'); - sinon.spy(console, 'log'); - } else { - sinon.stub(console, 'error'); - sinon.stub(console, 'log', function (a, b, c) { - if (typeof a === 'string' && a.indexOf('\u001b') !== -1 && typeof b === 'string') { - log.apply(console, arguments); +const childProcess = require(`child_process`); +const sinon = global.sinon = require(`sinon`); +const test = global.test = require(`ava`); + +global.run = (cmd, cwd) => { + return childProcess.execSync(cmd, { cwd: cwd }).toString().trim(); +}; + +global.runAsync = (cmd, cwd, cb) => { + return new Promise((resolve, reject) => { + childProcess.exec(cmd, { cwd: cwd }, (err, stdout, stderr) => { + if (err) { + reject(err); + return; + } + if (stdout) { + resolve(stdout.toString().trim()); + } else { + resolve(stdout); } }); + }); +}; + +class Try { + constructor (test) { + this._maxTries = 10; + this._maxDelay = 20000; + this._timeout = 60000; + this._iteration = 1; + this._multiplier = 1.3; + this._delay = 500; + this._test = test; } - assert(process.env.GCLOUD_PROJECT, 'Must set GCLOUD_PROJECT environment variable!'); - assert(process.env.GOOGLE_APPLICATION_CREDENTIALS, 'Must set GOOGLE_APPLICATION_CREDENTIALS environment variable!'); -}); -afterEach(function () { - console.error.restore(); - console.log.restore(); + execute () { + if (this._iteration >= this._maxTries) { + this.reject(this._error || new Error('Reached maximum number of tries')); + return; + } else if ((Date.now() - this._start) >= this._timeout) { + this.reject(this._error || new Error('Test timed out')); + return; + } + + try { + this._test(); + this.resolve(); + } catch (err) { + this._error = err; + this._iteration++; + this._delay = Math.min(this._delay * this._multiplier, this._maxDelay); + setTimeout(() => this.execute(), this._delay); + } + } + + timeout (timeout) { + this._timeout = timeout; + } + + tries (maxTries) { + this._maxTries = maxTries; + } + + start () { + this._start = Date.now(); + this.promise = new Promise((resolve, reject) => { + this.resolve = resolve; + this.reject = reject; + this.execute(); + }); + return this.promise; + } +} + +global.tryTest = (test) => { + return new Try(test); +}; + +global.stubConsole = () => { + if (typeof console.log.restore !== `function` && typeof console.error.restore !== `function`) { + if (process.env.DEBUG) { + sinon.spy(console, `error`); + sinon.spy(console, `log`); + } else { + sinon.stub(console, `error`); + sinon.stub(console, `log`, (a, b, c) => { + if (typeof a === `string` && a.indexOf(`\u001b`) !== -1 && typeof b === `string`) { + console.log.apply(console, arguments); + } + }); + } + } +}; + +global.restoreConsole = () => { + if (typeof console.log.restore === `function`) { + console.log.restore(); + } + if (typeof console.error.restore === `function`) { + console.error.restore(); + } +}; + +test.beforeEach((t) => { + t.truthy(process.env.GCLOUD_PROJECT, `Must set GCLOUD_PROJECT environment variable!`); + t.truthy(process.env.GOOGLE_APPLICATION_CREDENTIALS, `Must set GOOGLE_APPLICATION_CREDENTIALS environment variable!`); }); diff --git a/test/_setup.js b/test/_setup.js index 4cd3b2dd4b..4af2f19c47 100644 --- a/test/_setup.js +++ b/test/_setup.js @@ -1,47 +1,58 @@ -// Copyright 2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/** + * Copyright 2017, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ 'use strict'; -var assert = require('power-assert').customize({ - output: { - maxDepth: 2 - } -}); -var sinon = require('sinon'); +const childProcess = require(`child_process`); +const sinon = global.sinon = require(`sinon`); +const test = global.test = require(`ava`); -global.assert = assert; -global.sinon = sinon; +global.run = (cmd, cwd) => { + return childProcess.execSync(cmd, { cwd: cwd }).toString().trim(); +}; -var log = console.log; +global.runAsync = (cmd, cwd, cb) => { + childProcess.exec(cmd, { cwd: cwd }, cb); +}; -beforeEach(function () { - if (process.env.DEBUG) { - sinon.spy(console, 'error'); - sinon.spy(console, 'log'); - } else { - sinon.stub(console, 'error'); - sinon.stub(console, 'log', function (a, b, c) { - if (typeof a === 'string' && a.indexOf('\u001b') !== -1 && typeof b === 'string') { - log.apply(console, arguments); - } - }); +global.stubConsole = () => { + if (typeof console.log.restore !== `function` && typeof console.error.restore !== `function`) { + if (process.env.DEBUG) { + sinon.spy(console, `error`); + sinon.spy(console, `log`); + } else { + sinon.stub(console, `error`); + sinon.stub(console, `log`, (a, b, c) => { + if (typeof a === `string` && a.indexOf(`\u001b`) !== -1 && typeof b === `string`) { + console.log.apply(console, arguments); + } + }); + } } - assert(process.env.GCLOUD_PROJECT, 'Must set GCLOUD_PROJECT environment variable!'); - assert(process.env.GOOGLE_APPLICATION_CREDENTIALS, 'Must set GOOGLE_APPLICATION_CREDENTIALS environment variable!'); -}); +}; + +global.restoreConsole = () => { + if (typeof console.log.restore === `function`) { + console.log.restore(); + } + if (typeof console.error.restore === `function`) { + console.error.restore(); + } +}; -afterEach(function () { - console.error.restore(); - console.log.restore(); +test.beforeEach((t) => { + t.truthy(process.env.GCLOUD_PROJECT, `Must set GCLOUD_PROJECT environment variable!`); + t.truthy(process.env.GOOGLE_APPLICATION_CREDENTIALS, `Must set GOOGLE_APPLICATION_CREDENTIALS environment variable!`); }); diff --git a/test/utils.test.js b/test/utils.test.js index 9b27b2071a..8622f489be 100644 --- a/test/utils.test.js +++ b/test/utils.test.js @@ -13,67 +13,68 @@ 'use strict'; +require(`./_setup`); + var utils = require('../utils'); -describe('utils', function () { - describe('makeHandler', function () { - it('should throw error', function () { - var handler = utils.makeHandler(); - var error = new Error('error'); - assert.throws(function () { - handler(error); - }, Error, error.message); - }); +test.beforeEach(stubConsole); +test.afterEach(restoreConsole); + +test.serial('should throw error', (t) => { + var handler = utils.makeHandler(); + var error = new Error('error'); + t.throws(() => { + handler(error); + }, Error, error.message); +}); - it('should do nothing', function () { - var callCount = console.log.callCount; - var handler = utils.makeHandler(false); - handler(); - assert.equal(console.log.callCount, callCount, 'Console.log was not called'); - }); +test.serial('should do nothing', (t) => { + var callCount = console.log.callCount; + var handler = utils.makeHandler(false); + handler(); + t.is(console.log.callCount, callCount, 'Console.log was not called'); +}); - it('should pretty print an array', function () { - var handler = utils.makeHandler(true, 'foo'); - handler(null, [{ - foo: 'utils:bar' - }, { - foo: 'utils:bar2' - }]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['utils:bar\nutils:bar2']); - }); +test.serial('should pretty print an array', (t) => { + var handler = utils.makeHandler(true, 'foo'); + handler(null, [{ + foo: 'utils:bar' + }, { + foo: 'utils:bar2' + }]); + t.is(console.log.calledOnce, true); + t.deepEqual(console.log.firstCall.args, ['utils:bar\nutils:bar2']); +}); - it('should pretty print an array with multiple fields', function () { - var handler = utils.makeHandler(true, ['foo', 'bar']); - handler(null, [{ - foo: 'utils:bar', - bar: 'utils:foo' - }, { - foo: 'utils:bar2', - bar: 'utils:foo2' - }]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['{"foo":"utils:bar","bar":"utils:foo"}\n{"foo":"utils:bar2","bar":"utils:foo2"}']); - }); +test.serial('should pretty print an array with multiple fields', (t) => { + var handler = utils.makeHandler(true, ['foo', 'bar']); + handler(null, [{ + foo: 'utils:bar', + bar: 'utils:foo' + }, { + foo: 'utils:bar2', + bar: 'utils:foo2' + }]); + t.is(console.log.calledOnce, true); + t.deepEqual(console.log.firstCall.args, ['{"foo":"utils:bar","bar":"utils:foo"}\n{"foo":"utils:bar2","bar":"utils:foo2"}']); +}); - it('should pretty print a single field', function () { - var handler = utils.makeHandler(true, 'foo'); - handler(null, { - foo: 'utils:bar' - }); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['utils:bar']); - }); +test.serial('should pretty print a single field', (t) => { + var handler = utils.makeHandler(true, 'foo'); + handler(null, { + foo: 'utils:bar' + }); + t.is(console.log.calledOnce, true); + t.deepEqual(console.log.firstCall.args, ['utils:bar']); +}); - it('should just print', function () { - var handler = utils.makeHandler(); - handler(null, { - foo: 'utils:bar' - }); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, [{ - foo: 'utils:bar' - }]); - }); +test.serial('should just print', (t) => { + var handler = utils.makeHandler(); + handler(null, { + foo: 'utils:bar' }); + t.is(console.log.calledOnce, true); + t.deepEqual(console.log.firstCall.args, [{ + foo: 'utils:bar' + }]); }); diff --git a/trace/test/app.test.js b/trace/test/app.test.js index fb5de2bf60..b5a12ce435 100644 --- a/trace/test/app.test.js +++ b/trace/test/app.test.js @@ -15,6 +15,6 @@ 'use strict'; -describe(`trace`, () => { - it(`should be tested`); -}); +require(`../../test/_setup`); + +test.todo(`trace app should be tested`); diff --git a/translate/system-test/quickstart.test.js b/translate/system-test/quickstart.test.js index d41753da33..f056c2a286 100644 --- a/translate/system-test/quickstart.test.js +++ b/translate/system-test/quickstart.test.js @@ -15,38 +15,44 @@ 'use strict'; +require(`../../system-test/_setup`); + const proxyquire = require(`proxyquire`).noPreserveCache(); const translate = proxyquire(`@google-cloud/translate`, {})(); -describe(`translate:quickstart`, () => { - it(`should translate a string`, (done) => { - const string = `Hello, world!`; - const expectedTranslation = `Привет мир!`; - const targetLanguage = `ru`; - const translateMock = { - translate: (_string, _targetLanguage) => { - assert.equal(_string, string); - assert.equal(_targetLanguage, targetLanguage); - - return translate.translate(_string, _targetLanguage) - .then((results) => { - const translation = results[0]; - assert.equal(translation, expectedTranslation); - - setTimeout(() => { - assert.equal(console.log.callCount, 2); - assert.deepEqual(console.log.getCall(0).args, [`Text: ${string}`]); - assert.deepEqual(console.log.getCall(1).args, [`Translation: ${expectedTranslation}`]); - done(); - }, 200); - - return results; - }); - } - }; - - proxyquire(`../quickstart`, { - '@google-cloud/translate': sinon.stub().returns(translateMock) - }); +test.before(stubConsole); +test.after(restoreConsole); + +test.cb(`should translate a string`, (t) => { + const string = `Hello, world!`; + const expectedTranslation = `Привет мир!`; + const targetLanguage = `ru`; + const translateMock = { + translate: (_string, _targetLanguage) => { + t.is(_string, string); + t.is(_targetLanguage, targetLanguage); + + return translate.translate(_string, _targetLanguage) + .then(([translation]) => { + t.is(translation, expectedTranslation); + + setTimeout(() => { + try { + t.is(console.log.callCount, 2); + t.deepEqual(console.log.getCall(0).args, [`Text: ${string}`]); + t.deepEqual(console.log.getCall(1).args, [`Translation: ${expectedTranslation}`]); + t.end(); + } catch (err) { + t.end(err); + } + }, 200); + + return [translation]; + }); + } + }; + + proxyquire(`../quickstart`, { + '@google-cloud/translate': sinon.stub().returns(translateMock) }); }); diff --git a/translate/system-test/translate.test.js b/translate/system-test/translate.test.js index 30a75bffa0..294465a09e 100644 --- a/translate/system-test/translate.test.js +++ b/translate/system-test/translate.test.js @@ -15,9 +15,10 @@ 'use strict'; -const Translate = require(`@google-cloud/translate`); +require(`../../system-test/_setup`); + +const translate = require(`@google-cloud/translate`)(); const path = require(`path`); -const run = require(`../../utils`).run; const cwd = path.join(__dirname, `..`); const cmd = `node translate.js`; @@ -26,72 +27,56 @@ const text2 = `Goodbye!`; const model = `nmt`; const toLang = `ru`; -describe(`translate:translate`, () => { - const translate = Translate(); - - it(`should detect language of a single string`, () => { - const output = run(`${cmd} detect "${text}"`, cwd); - return translate.detect(text) - .then((results) => { - const expected = `Detections:\n${text} => ${results[0].language}`; - assert.equal(output, expected); - }); - }); +test(`should detect language of a single string`, async (t) => { + const output = await runAsync(`${cmd} detect "${text}"`, cwd); + const [detection] = await translate.detect(text); + const expected = `Detections:\n${text} => ${detection.language}`; + t.is(output, expected); +}); - it(`should detect language of multiple strings`, () => { - const output = run(`${cmd} detect "${text}" "${text2}"`, cwd); - return translate.detect([text, text2]) - .then((results) => { - const expected = `Detections:\n${text} => ${results[0][0].language}\n${text2} => ${results[0][1].language}`; - assert.equal(output, expected); - }); - }); +test(`should detect language of multiple strings`, async (t) => { + const output = await runAsync(`${cmd} detect "${text}" "${text2}"`, cwd); + const [detections] = await translate.detect([text, text2]); + const expected = `Detections:\n${text} => ${detections[0].language}\n${text2} => ${detections[1].language}`; + t.is(output, expected); +}); - it(`should list languages`, () => { - const output = run(`${cmd} list`, cwd); - assert.equal(output.includes(`Languages:`), true); - assert.equal(output.includes(`{ code: 'af', name: 'Afrikaans' }`), true); - }); +test(`should list languages`, async (t) => { + const output = await runAsync(`${cmd} list`, cwd); + t.true(output.includes(`Languages:`)); + t.true(output.includes(`{ code: 'af', name: 'Afrikaans' }`)); +}); - it(`should list languages with a target`, () => { - const output = run(`${cmd} list es`, cwd); - assert.equal(output.includes(`Languages:`), true); - assert.equal(output.includes(`{ code: 'af', name: 'afrikáans' }`), true); - }); +test(`should list languages with a target`, async (t) => { + const output = await runAsync(`${cmd} list es`, cwd); + t.true(output.includes(`Languages:`)); + t.true(output.includes(`{ code: 'af', name: 'afrikáans' }`)); +}); - it(`should translate a single string`, () => { - const output = run(`${cmd} translate ${toLang} "${text}"`, cwd); - return translate.translate(text, toLang) - .then((results) => { - const expected = `Translations:\n${text} => (${toLang}) ${results[0]}`; - assert.equal(output, expected); - }); - }); +test(`should translate a single string`, async (t) => { + const output = await runAsync(`${cmd} translate ${toLang} "${text}"`, cwd); + const [translation] = await translate.translate(text, toLang); + const expected = `Translations:\n${text} => (${toLang}) ${translation}`; + t.is(output, expected); +}); - it(`should translate multiple strings`, () => { - const output = run(`${cmd} translate ${toLang} "${text}" "${text2}"`, cwd); - return translate.translate([text, text2], toLang) - .then((results) => { - const expected = `Translations:\n${text} => (${toLang}) ${results[0][0]}\n${text2} => (${toLang}) ${results[0][1]}`; - assert.equal(output, expected); - }); - }); +test(`should translate multiple strings`, async (t) => { + const output = await runAsync(`${cmd} translate ${toLang} "${text}" "${text2}"`, cwd); + const [translations] = await translate.translate([text, text2], toLang); + const expected = `Translations:\n${text} => (${toLang}) ${translations[0]}\n${text2} => (${toLang}) ${translations[1]}`; + t.is(output, expected); +}); - it(`should translate a single string with a model`, () => { - const output = run(`${cmd} translate-with-model ${toLang} ${model} "${text}"`, cwd); - return translate.translate(text, toLang) - .then((results) => { - const expected = `Translations:\n${text} => (${toLang}) ${results[0]}`; - assert.equal(output, expected); - }); - }); +test(`should translate a single string with a model`, async (t) => { + const output = await runAsync(`${cmd} translate-with-model ${toLang} ${model} "${text}"`, cwd); + const [translation] = await translate.translate(text, toLang); + const expected = `Translations:\n${text} => (${toLang}) ${translation}`; + t.is(output, expected); +}); - it(`should translate multiple strings with a model`, () => { - const output = run(`${cmd} translate-with-model ${toLang} ${model} "${text}" "${text2}"`, cwd); - return translate.translate([text, text2], toLang) - .then((results) => { - const expected = `Translations:\n${text} => (${toLang}) ${results[0][0]}\n${text2} => (${toLang}) ${results[0][1]}`; - assert.equal(output, expected); - }); - }); +test(`should translate multiple strings with a model`, async (t) => { + const output = await runAsync(`${cmd} translate-with-model ${toLang} ${model} "${text}" "${text2}"`, cwd); + const [translations] = await translate.translate([text, text2], toLang); + const expected = `Translations:\n${text} => (${toLang}) ${translations[0]}\n${text2} => (${toLang}) ${translations[1]}`; + t.is(output, expected); }); diff --git a/vision/package.json b/vision/package.json index a3043b8145..28a99d7e50 100644 --- a/vision/package.json +++ b/vision/package.json @@ -5,8 +5,7 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "scripts": { - "test": "cd ..; npm run t -- vision/test/*.test.js", - "system-test": "cd ..; npm run st -- vision/system-test/*.test.js" + "test": "cd ..; npm run st -- vision/system-test/*.test.js" }, "dependencies": { "@google-cloud/vision": "0.7.0", diff --git a/vision/quickstart.js b/vision/quickstart.js index fafa46b1a2..e650314dbd 100644 --- a/vision/quickstart.js +++ b/vision/quickstart.js @@ -31,13 +31,11 @@ const visionClient = Vision({ const fileName = './resources/wakeupcat.jpg'; // Performs label detection on the image file -visionClient.detectLabels(fileName, (err, labels) => { - if (err) { - console.error(err); - return; - } +visionClient.detectLabels(fileName) + .then((results) => { + const labels = results[0]; - console.log('Labels:'); - labels.forEach((label) => console.log(label)); -}); + console.log('Labels:'); + labels.forEach((label) => console.log(label)); + }); // [END vision_quickstart] diff --git a/vision/system-test/faceDetection.test.js b/vision/system-test/faceDetection.test.js index 343d4b6b86..859fbf3ad2 100644 --- a/vision/system-test/faceDetection.test.js +++ b/vision/system-test/faceDetection.test.js @@ -15,57 +15,54 @@ 'use strict'; -var fs = require('fs'); -var path = require('path'); +require(`../../system-test/_setup`); -function MockCanvas () { - this.getContext = function () { +const fs = require(`fs`); +const path = require(`path`); + +class MockCanvas { + getContext () { return { - drawImage: function () {}, - beginPath: function () {}, - lineTo: function () {}, - stroke: function () {} + drawImage: () => {}, + beginPath: () => {}, + lineTo: () => {}, + stroke: () => {} }; - }; - this.pngStream = function () { + } + + pngStream () { return { - on: function (event, cb) { + on: (event, cb) => { if (event === 'end') { - setTimeout(function () { - cb(); - }, 1000); - } else if (event === 'data') { - cb('test'); - cb('foo'); - cb('bar'); + setTimeout(cb, 1000); + } else if (event === `data`) { + cb(`test`); + cb(`foo`); + cb(`bar`); } } }; - }; + } } -MockCanvas.Image = function () {}; +MockCanvas.Image = class Image {}; -var faceDetectionExample = require('../faceDetection'); -var inputFile = path.join(__dirname, '../resources', 'face.png'); -var outputFile = path.join(__dirname, '../../vision', 'out.png'); +const faceDetectionExample = require(`../faceDetection`); +const inputFile = path.join(__dirname, `../resources`, `face.png`); +const outputFile = path.join(__dirname, `../../vision`, `out.png`); -describe('vision:faceDetection', function () { - it('should detect faces', function (done) { - faceDetectionExample.main( - inputFile, - outputFile, - MockCanvas, - function (err, faces) { - assert.ifError(err); - assert(faces.length === 1); - var image = fs.readFileSync(outputFile); - assert(image.toString('utf8') === 'testfoobar'); - assert(console.log.calledWith('Found 1 face')); - assert(console.log.calledWith('Highlighting...')); - assert(console.log.calledWith('Finished!')); - done(); - } - ); +test.before(stubConsole); +test.after(restoreConsole); + +test.cb(`should detect faces`, (t) => { + faceDetectionExample.main(inputFile, outputFile, MockCanvas, (err, faces) => { + t.ifError(err); + t.is(faces.length, 1); + const image = fs.readFileSync(outputFile); + t.is(image.toString(`utf8`), `testfoobar`); + t.true(console.log.calledWith(`Found 1 face`)); + t.true(console.log.calledWith(`Highlighting...`)); + t.true(console.log.calledWith(`Finished!`)); + t.end(); }); }); diff --git a/vision/system-test/labelDetection.test.js b/vision/system-test/labelDetection.test.js index 5659191a69..f6a3c00d54 100644 --- a/vision/system-test/labelDetection.test.js +++ b/vision/system-test/labelDetection.test.js @@ -15,20 +15,21 @@ 'use strict'; -var path = require('path'); -var labelDetectionSample = require('../labelDetection'); -var inputFile = path.join(__dirname, '../resources', 'cat.jpg'); +require(`../../system-test/_setup`); -describe('vision:labelDetection', function () { - it('should detect labels', function (done) { - labelDetectionSample.main( - inputFile, - function (err, labels) { - assert.ifError(err); - assert(labels.length > 0); - assert(console.log.calledWith('Found label: cat for ' + inputFile)); - done(); - } - ); +const path = require(`path`); + +const labelDetectionSample = require(`../labelDetection`); +const inputFile = path.join(__dirname, `../resources`, `cat.jpg`); + +test.before(stubConsole); +test.after(restoreConsole); + +test.cb(`should detect labels`, (t) => { + labelDetectionSample.main(inputFile, (err, labels) => { + t.ifError(err); + t.true(labels.length > 0); + t.true(console.log.calledWith(`Found label: cat for ${inputFile}`)); + t.end(); }); }); diff --git a/vision/system-test/landmarkDetection.test.js b/vision/system-test/landmarkDetection.test.js index c43a7b7b9a..c0341f6b1c 100644 --- a/vision/system-test/landmarkDetection.test.js +++ b/vision/system-test/landmarkDetection.test.js @@ -15,16 +15,19 @@ 'use strict'; -var landmarkDetectionSample = require('../landmarkDetection'); -var inputFile = 'https://cloud-samples-tests.storage.googleapis.com/vision/water.jpg'; +require(`../../system-test/_setup`); -describe('vision:landmarkDetection', function () { - it('should detect landmarks', function (done) { - landmarkDetectionSample.main(inputFile, function (err, landmarks) { - assert.ifError(err); - assert(landmarks.length > 0); - assert(console.log.calledWith('Found landmark: Taitung, Famous Places "up the water flow" marker for ' + inputFile)); - done(); - }); +const landmarkDetectionSample = require(`../landmarkDetection`); +const inputFile = `https://cloud-samples-tests.storage.googleapis.com/vision/water.jpg`; + +test.before(stubConsole); +test.after(restoreConsole); + +test.cb(`should detect landmarks`, (t) => { + landmarkDetectionSample.main(inputFile, (err, landmarks) => { + t.ifError(err); + t.true(landmarks.length > 0); + t.true(console.log.calledWith(`Found landmark: Taitung, Famous Places "up the water flow" marker for ${inputFile}`)); + t.end(); }); }); diff --git a/vision/system-test/quickstart.test.js b/vision/system-test/quickstart.test.js index 0fb15353f1..209ba9ba4a 100644 --- a/vision/system-test/quickstart.test.js +++ b/vision/system-test/quickstart.test.js @@ -15,40 +15,45 @@ 'use strict'; +require(`../../system-test/_setup`); + const proxyquire = require(`proxyquire`).noPreserveCache(); const vision = proxyquire(`@google-cloud/vision`, {})(); const path = require(`path`); -describe(`vision:quickstart`, () => { - let visionMock, VisionMock; - - it(`should detect labels`, (done) => { - const filePath = path.join(__dirname, `../resources/wakeupcat.jpg`); - const expectedFileName = `./resources/wakeupcat.jpg`; - - visionMock = { - detectLabels: (_fileName, _callback) => { - assert.equal(_fileName, expectedFileName); - assert.equal(typeof _callback, 'function'); - - vision.detectLabels(filePath, (err, labels, apiResponse) => { - _callback(err, labels, apiResponse); - assert.ifError(err); - assert.equal(Array.isArray(labels), true); - assert.notEqual(apiResponse, undefined); - assert.equal(console.log.called, true); - assert.deepEqual(console.log.firstCall.args, [`Labels:`]); - labels.forEach((label, i) => { - assert.deepEqual(console.log.getCall(i + 1).args, [label]); - }); - done(); +test.before(stubConsole); +test.after(restoreConsole); + +test.cb(`should detect labels`, (t) => { + const filePath = path.join(__dirname, `../resources/wakeupcat.jpg`); + const expectedFileName = `./resources/wakeupcat.jpg`; + const visionMock = { + detectLabels: (_fileName) => { + t.is(_fileName, expectedFileName); + + return vision.detectLabels(filePath) + .then(([labels]) => { + t.true(Array.isArray(labels)); + + setTimeout(() => { + try { + t.is(console.log.callCount, 6); + t.deepEqual(console.log.getCall(0).args, [`Labels:`]); + labels.forEach((label, i) => { + t.deepEqual(console.log.getCall(i + 1).args, [label]); + }); + t.end(); + } catch (err) { + t.end(err); + } + }, 200); + + return [labels]; }); - } - }; - VisionMock = sinon.stub().returns(visionMock); + } + }; - proxyquire(`../quickstart`, { - '@google-cloud/vision': VisionMock - }); + proxyquire(`../quickstart`, { + '@google-cloud/vision': sinon.stub().returns(visionMock) }); }); diff --git a/vision/system-test/textDetection.test.js b/vision/system-test/textDetection.test.js index a67c04c471..ab9a0f6c1a 100644 --- a/vision/system-test/textDetection.test.js +++ b/vision/system-test/textDetection.test.js @@ -15,21 +15,22 @@ 'use strict'; -var path = require('path'); -var inputDir = path.join(__dirname, '../resources'); -var textDetectionSample = require('../textDetection'); +require(`../../system-test/_setup`); -describe('vision:textDetection', function () { - it('should detect texts', function (done) { - textDetectionSample.main(inputDir, function (err, textResponse) { - assert.ifError(err); - assert(Object.keys(textResponse).length > 0); - textDetectionSample.lookup(['the', 'sunbeams', 'in'], function (err, hits) { - assert.ifError(err); - assert(hits.length > 0); - assert(hits[0].length > 0); - done(); - }); +const path = require(`path`); + +const inputDir = path.join(__dirname, `../resources`); +const textDetectionSample = require(`../textDetection`); + +test.cb(`should detect texts`, (t) => { + textDetectionSample.main(inputDir, (err, textResponse) => { + t.ifError(err); + t.true(Object.keys(textResponse).length > 0); + textDetectionSample.lookup(['the', 'sunbeams', 'in'], (err, hits) => { + t.ifError(err); + t.true(hits.length > 0); + t.true(hits[0].length > 0); + t.end(); }); }); }); diff --git a/vision/test/faceDetection.test.js b/vision/test/faceDetection.test.js deleted file mode 100644 index e23de44c48..0000000000 --- a/vision/test/faceDetection.test.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright 2016, Google, Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -describe('vision:faceDetection', function () { - it('should be tested'); -}); diff --git a/vision/test/labelDetection.test.js b/vision/test/labelDetection.test.js deleted file mode 100644 index 565d24d277..0000000000 --- a/vision/test/labelDetection.test.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright 2016, Google, Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -describe('vision:labelDetection', function () { - it('should be tested'); -}); diff --git a/vision/test/landmarkDetection.test.js b/vision/test/landmarkDetection.test.js deleted file mode 100644 index 13c4a70d11..0000000000 --- a/vision/test/landmarkDetection.test.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright 2016, Google, Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -describe('vision:landmarkDetection', function () { - it('should be tested'); -}); diff --git a/vision/test/quickstart.test.js b/vision/test/quickstart.test.js deleted file mode 100644 index 9a75af8f17..0000000000 --- a/vision/test/quickstart.test.js +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Copyright 2016, Google, Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -const proxyquire = require(`proxyquire`).noCallThru(); - -describe(`vision:quickstart`, () => { - let visionMock, VisionMock; - const error = new Error(`error`); - const fileName = `./resources/wakeupcat.jpg`; - - before(() => { - visionMock = { - detectLabels: sinon.stub().yields(error) - }; - VisionMock = sinon.stub().returns(visionMock); - }); - - it(`should handle error`, () => { - proxyquire(`../quickstart`, { - '@google-cloud/vision': VisionMock - }); - - assert.equal(VisionMock.calledOnce, true); - assert.deepEqual(VisionMock.firstCall.args, [{ projectId: 'YOUR_PROJECT_ID' }]); - assert.equal(visionMock.detectLabels.calledOnce, true); - assert.deepEqual(visionMock.detectLabels.firstCall.args.slice(0, -1), [fileName]); - assert.equal(console.error.calledOnce, true); - assert.deepEqual(console.error.firstCall.args, [error]); - }); -}); diff --git a/vision/test/textDetection.test.js b/vision/test/textDetection.test.js deleted file mode 100644 index c4e7ac302e..0000000000 --- a/vision/test/textDetection.test.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright 2016, Google, Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -describe('vision:textDetection', function () { - it('should be tested'); -}); From 39af9f797d38fe74450013a277a3a9d6e46d2597 Mon Sep 17 00:00:00 2001 From: Jason Dobry Date: Fri, 6 Jan 2017 13:57:54 -0800 Subject: [PATCH 2/2] Concurrency: 5 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 34f128e122..88e74caa04 100644 --- a/package.json +++ b/package.json @@ -60,8 +60,8 @@ "scripts": { "lint": "semistandard", "pretest": "npm run lint && ./scripts/clean", - "t": "ava --verbose -c 10 -T 30s", - "st": "ava --verbose -c 10 -T 180s", + "t": "ava --verbose -c 5 -T 30s", + "st": "ava --verbose -c 5 -T 180s", "test": "npm run t -- test/**/*.test.js **/test/**/*.test.js", "cover": "nyc --cache npm test && nyc report --reporter=html && nyc report --reporter=lcov", "system-test": "npm run st -- system-test/**/*.test.js **/system-test/**/*.test.js",