From 73a0764c07d2db9b9b75348ff8a37fc27c6ee7c5 Mon Sep 17 00:00:00 2001 From: Jason Dobry Date: Tue, 15 Nov 2016 11:17:26 -0800 Subject: [PATCH] Update Language samples. (#254) * Update Language samples. * Address comments. --- language/README.md | 31 +- language/analyze.js | 434 ++++++++++-------------- language/package.json | 13 +- language/quickstart.js | 14 +- language/system-test/analyze.test.js | 125 +++---- language/system-test/quickstart.test.js | 30 +- language/test/analyze.test.js | 368 -------------------- language/test/quickstart.test.js | 44 --- package.json | 4 +- 9 files changed, 263 insertions(+), 800 deletions(-) delete mode 100644 language/test/analyze.test.js delete mode 100644 language/test/quickstart.test.js diff --git a/language/README.md b/language/README.md index d7a0fddadd..fb7ec57303 100644 --- a/language/README.md +++ b/language/README.md @@ -35,25 +35,26 @@ __Usage:__ `node analyze --help` ``` Commands: - sentimentFromString Detect the sentiment of a block of text. - sentimentFromFile Detect the sentiment of text in a GCS file. - entitiesFromString Detect the entities of a block of text. - entitiesFromFile Detect the entities of text in a GCS file. - syntaxFromString Detect the syntax of a block of text. - syntaxFromFile Detect the syntax of text in a GCS file. + sentimentOfText Detect the sentiment of a block of text. + sentimentInFile Detect the sentiment of text in a GCS file. + entitiesOfText Detect the entities of a block of text. + entitiesInFile Detect the entities of text in a GCS file. + syntaxOfText Detect the syntax of a block of text. + syntaxInFile Detect the syntax of text in a GCS file. Options: - --language, -l The language of the text. [string] - --type, -t Type of text [string] [choices: "text", "html"] [default: "text"] - --help Show help [boolean] + --help Show help [boolean] Examples: - node analyze sentimentFromString "President Obama is speaking at the White House." - node analyze sentimentFromFile my-bucket file.txt - node analyze entitiesFromString "

President Obama is speaking at the White House.

" -t html - node analyze entitiesFromFile my-bucket file.txt - node analyze syntaxFromString "President Obama is speaking at the White House." - node analyze syntaxFromFile my-bucket es_file.txt -l es + node analyze sentimentOfText "President Obama is speaking at + the White House." + node analyze sentimentInFile my-bucket file.txt + node analyze entitiesOfText "President Obama is speaking at + the White House." + node analyze entitiesInFile my-bucket file.txt + node analyze syntaxOfText "President Obama is speaking at + the White House." + node analyze syntaxInFile my-bucket file.txt For more information, see https://cloud.google.com/natural-language/docs ``` diff --git a/language/analyze.js b/language/analyze.js index 93a6642f39..ffae71ffaa 100644 --- a/language/analyze.js +++ b/language/analyze.js @@ -1,252 +1,186 @@ -// 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'; - -// [START all] -// [START setup] -// 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 -// https://googlecloudplatform.github.io/gcloud-node/#/docs/google-cloud/latest/guides/authentication -var Language = require('@google-cloud/language'); -var Storage = require('@google-cloud/storage'); - -// Instantiate the language client -var language = Language(); -// Instantiate the storage client -var storage = Storage(); -// [END setup] - -// [START analyze_sentiment_from_string] /** - * Detect the sentiment of a block of text. + * 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 * - * @param {string} text The text to analyze. - * @param {object} [options] Configuration options. - * @param {string} [options.type] The type of the text, either "text" or "html". - * @param {string} [options.language] The language of the text, e.g. "en". - * @param {function} callback The callback function. - */ -function analyzeSentimentFromString (text, options, callback) { - var document = language.document({ - content: text, - type: options.type, - language: options.language - }); - - var config = { - // Get more detailed results - verbose: true - }; - - // See https://googlecloudplatform.github.io/google-cloud-node/#/docs/language/latest/language/document - document.detectSentiment(config, function (err, sentiment) { - if (err) { - return callback(err); - } - - console.log('Found %s sentiment', sentiment.polarity >= 0 ? 'positive' : 'negative'); - return callback(null, sentiment); - }); -} -// [END analyze_sentiment_from_string] - -// [START analyze_sentiment_from_file] -/** - * Detect the sentiment in a text file that resides in Google Cloud Storage. + * http://www.apache.org/licenses/LICENSE-2.0 * - * @param {string} bucket The bucket where the file resides. - * @param {string} filename The name of the file to be analyzed. - * @param {object} [options] Optional configuration. - * @param {string} [options.language] The language of the text, e.g. "en". - * @param {string} [options.type] The type of the text, either "text" or "html". - * @param {function} callback The callback function. + * 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. */ -function analyzeSentimentFromFile (bucket, filename, options, callback) { - var document = language.document({ - content: storage.bucket(bucket).file(filename), - type: options.type, - language: options.language - }); - var config = { - // Get more detailed results - verbose: true - }; +'use strict'; - // See https://googlecloudplatform.github.io/google-cloud-node/#/docs/language/latest/language/document - document.detectSentiment(config, function (err, sentiment) { - if (err) { - return callback(err); - } +const Language = require('@google-cloud/language'); +const Storage = require('@google-cloud/storage'); - console.log('Found %s sentiment', sentiment.polarity >= 0 ? 'positive' : 'negative'); - return callback(null, sentiment); - }); -} -// [END analyze_sentiment_from_file] +// [START language_sentiment_string] +function analyzeSentimentOfText (text) { + // Instantiates a client + const language = Language(); -// [START analyze_entities_from_string] -/** - * Detect the entities from a block of text. - * - * @param {string} text The text to analyze. - * @param {object} [options] Optional configuration. - * @param {string} [options.language] The language of the text, e.g. "en". - * @param {string} [options.type] The type of the text, either "text" or "html". - * @param {function} callback The callback function. - */ -function analyzeEntitiesFromString (text, options, callback) { - var document = language.document({ - content: text, - type: options.type, - language: options.language + // Instantiates a Document, representing the provided text + const document = language.document({ + // The document text, e.g. "Hello, world!" + content: text }); - var config = { - // Get more detailed results - verbose: true - }; - - // See https://googlecloudplatform.github.io/google-cloud-node/#/docs/language/latest/language/document - document.detectEntities(config, function (err, entities) { - if (err) { - return callback(err); - } - - console.log('Found %d entity type(s)!', Object.keys(entities).length); - return callback(null, entities); - }); + // Detects the sentiment of the document + return document.detectSentiment() + .then((results) => { + const sentiment = results[0]; + console.log(`Sentiment: ${sentiment >= 0 ? 'positive' : 'negative'}.`); + return sentiment; + }); } -// [END analyze_entities_from_string] - -// [START analyze_entities_from_file] -/** - * Detect the entities in a text file that resides in Google Cloud Storage. - * - * @param {string} bucket The bucket where the file resides. - * @param {string} filename The name of the file to be analyzed. - * @param {object} [options] Optional configuration. - * @param {string} [options.language] The language of the text, e.g. "en". - * @param {string} [options.type] The type of the text, either "text" or "html". - * @param {function} callback The callback function. - */ -function analyzeEntitiesFromFile (bucket, filename, options, callback) { - var document = language.document({ - content: storage.bucket(bucket).file(filename), - type: options.type, - language: options.language +// [END language_sentiment_string] + +// [START language_sentiment_file] +function analyzeSentimentInFile (bucketName, fileName) { + // Instantiates clients + const language = Language(); + const storage = Storage(); + + // The bucket where the file resides, e.g. "my-bucket" + const bucket = storage.bucket(bucketName); + // The text file to analyze, e.g. "file.txt" + const file = bucket.file(fileName); + + // Instantiates a Document, representing a text file in Cloud Storage + const document = language.document({ + // The GCS file + content: file }); - var config = { - // Get more detailed results - verbose: true - }; + // Detects the sentiment of the document + return document.detectSentiment() + .then((results) => { + const sentiment = results[0]; + console.log(`Sentiment: ${sentiment >= 0 ? 'positive' : 'negative'}.`); + return sentiment; + }); +} +// [END language_sentiment_file] - // See https://googlecloudplatform.github.io/google-cloud-node/#/docs/language/latest/language/document - document.detectEntities(config, function (err, entities) { - if (err) { - return callback(err); - } +// [START language_entities_string] +function analyzeEntitiesOfText (text) { + // Instantiates a client + const language = Language(); - console.log('Found %d entity type(s)!', Object.keys(entities).length); - return callback(null, entities); + // Instantiates a Document, representing the provided text + const document = language.document({ + // The document text, e.g. "Hello, world!" + content: text }); -} -// [END analyze_entities_from_file] -// [START analyze_syntax_from_string] -/** - * Detect the syntax in a block of text. - * - * @param {string} text The text to analyze. - * @param {object} [options] Optional configuration. - * @param {string} [options.language] The language of the text, e.g. "en". - * @param {string} [options.type] The type of the text, either "text" or "html". - * @param {function} callback The callback function. - */ -function analyzeSyntaxFromString (text, options, callback) { - var document = language.document({ - content: text, - type: options.type, - language: options.language + // Detects entities in the document + return document.detectEntities() + .then((results) => { + const entities = results[0]; + console.log('Entities:'); + for (let type in entities) { + console.log(`${type}:`, entities[type]); + } + return entities; + }); +} +// [END language_entities_string] + +// [START language_entities_file] +function analyzeEntitiesInFile (bucketName, fileName) { + // Instantiates clients + const language = Language(); + const storage = Storage(); + + // The bucket where the file resides, e.g. "my-bucket" + const bucket = storage.bucket(bucketName); + // The text file to analyze, e.g. "file.txt" + const file = bucket.file(fileName); + + // Instantiates a Document, representing a text file in Cloud Storage + const document = language.document({ + // The GCS file + content: file }); - var config = { - syntax: true - }; + // Detects entities in the document + return document.detectEntities() + .then((results) => { + const entities = results[0]; + console.log('Entities:'); + for (let type in entities) { + console.log(`${type}:`, entities[type]); + } + return entities; + }); +} +// [END language_entities_file] - // See https://googlecloudplatform.github.io/google-cloud-node/#/docs/language/latest/language/document - document.annotate(config, function (err, result, apiResponse) { - if (err) { - return callback(err); - } +// [START language_syntax_string] +function analyzeSyntaxOfText (text) { + // Instantiates a client + const language = Language(); - console.log('Done analyzing syntax'); - return callback(null, apiResponse); + // Instantiates a Document, representing the provided text + const document = language.document({ + // The document text, e.g. "Hello, world!" + content: text }); -} -// [END analyze_syntax_from_string] -// [START analyze_syntax_from_file] -/** - * Detect the syntax in a text file that resides in Google Cloud Storage. - * - * @param {string} bucket The bucket where the file resides. - * @param {string} filename The name of the file to be analyzed. - * @param {object} [options] Optional configuration. - * @param {string} [options.language] The language of the text, e.g. "en". - * @param {string} [options.type] The type of the text, either "text" or "html". - * @param {function} callback The callback function. - */ -function analyzeSyntaxFromFile (bucket, filename, options, callback) { - var document = language.document({ - content: storage.bucket(bucket).file(filename), - type: options.type, - language: options.language + // Detects syntax in the document + return document.detectSyntax() + .then((results) => { + const syntax = results[0]; + console.log('Tags:'); + syntax.forEach((part) => console.log(part.tag)); + return syntax; + }); +} +// [END language_syntax_string] + +// [START language_syntax_file] +function analyzeSyntaxInFile (bucketName, fileName) { + // Instantiates clients + const language = Language(); + const storage = Storage(); + + // The bucket where the file resides, e.g. "my-bucket" + const bucket = storage.bucket(bucketName); + // The text file to analyze, e.g. "file.txt" + const file = bucket.file(fileName); + + // Instantiates a Document, representing a text file in Cloud Storage + const document = language.document({ + // The GCS file + content: file }); - var config = { - syntax: true - }; - - // See https://googlecloudplatform.github.io/google-cloud-node/#/docs/language/latest/language/document - document.annotate(config, function (err, result, apiResponse) { - if (err) { - return callback(err); - } - - console.log('Done analyzing syntax'); - return callback(null, apiResponse); - }); + // Detects syntax in the document + return document.detectSyntax() + .then((results) => { + const syntax = results[0]; + console.log('Tags:'); + syntax.forEach((part) => console.log(part.tag)); + return syntax; + }); } -// [END analyze_syntax_from_file] -// [END all] +// [END language_syntax_file] // The command-line program -var cli = require('yargs'); -var utils = require('../utils'); - -var program = module.exports = { - analyzeSentimentFromString: analyzeSentimentFromString, - analyzeSentimentFromFile: analyzeSentimentFromFile, - analyzeEntitiesFromString: analyzeEntitiesFromString, - analyzeEntitiesFromFile: analyzeEntitiesFromFile, - analyzeSyntaxFromString: analyzeSyntaxFromString, - analyzeSyntaxFromFile: analyzeSyntaxFromFile, - main: function (args) { +const cli = require(`yargs`); + +const program = module.exports = { + analyzeSentimentOfText, + analyzeSentimentInFile, + analyzeEntitiesOfText, + analyzeEntitiesInFile, + analyzeSyntaxOfText, + analyzeSyntaxInFile, + main: (args) => { // Run the command-line program cli.help().strict().parse(args).argv; } @@ -254,51 +188,33 @@ var program = module.exports = { cli .demand(1) - .command('sentimentFromString ', 'Detect the sentiment of a block of text.', {}, function (options) { - program.analyzeSentimentFromString(options.text, utils.pick(options, ['language', 'type']), utils.makeHandler()); - }) - .command('sentimentFromFile ', 'Detect the sentiment of text in a GCS file.', {}, function (options) { - program.analyzeSentimentFromFile(options.bucket, options.filename, utils.pick(options, ['language', 'type']), utils.makeHandler()); + .command(`sentimentOfText `, `Detect the sentiment of a block of text.`, {}, (opts) => { + program.analyzeSentimentOfText(opts.text); }) - .command('entitiesFromString ', 'Detect the entities of a block of text.', {}, function (options) { - program.analyzeEntitiesFromString(options.text, utils.pick(options, ['language', 'type']), utils.makeHandler()); + .command(`sentimentInFile `, `Detect the sentiment of text in a GCS file.`, {}, (opts) => { + program.analyzeSentimentInFile(opts.bucket, opts.filename); }) - .command('entitiesFromFile ', 'Detect the entities of text in a GCS file.', {}, function (options) { - program.analyzeEntitiesFromFile(options.bucket, options.filename, utils.pick(options, ['language', 'type']), utils.makeHandler()); + .command(`entitiesOfText `, `Detect the entities of a block of text.`, {}, (opts) => { + program.analyzeEntitiesOfText(opts.text); }) - .command('syntaxFromString ', 'Detect the syntax of a block of text.', {}, function (options) { - program.analyzeSyntaxFromString(options.text, utils.pick(options, ['language', 'type']), utils.makeHandler()); + .command(`entitiesInFile `, `Detect the entities of text in a GCS file.`, {}, (opts) => { + program.analyzeEntitiesInFile(opts.bucket, opts.filename); }) - .command('syntaxFromFile ', 'Detect the syntax of text in a GCS file.', {}, function (options) { - program.analyzeSyntaxFromFile(options.bucket, options.filename, utils.pick(options, ['language', 'type']), utils.makeHandler()); + .command(`syntaxOfText `, `Detect the syntax of a block of text.`, {}, (opts) => { + program.analyzeSyntaxOfText(opts.text); }) - .options({ - language: { - alias: 'l', - type: 'string', - requiresArg: true, - description: 'The language of the text.', - global: true - }, - type: { - alias: 't', - type: 'string', - choices: ['text', 'html'], - default: 'text', - requiresArg: true, - description: 'Type of text.', - global: true - } + .command(`syntaxInFile `, `Detect the syntax of text in a GCS file.`, {}, (opts) => { + program.analyzeSyntaxInFile(opts.bucket, opts.filename); }) - .example('node $0 sentimentFromString "President Obama is speaking at the White House."', '') - .example('node $0 sentimentFromFile my-bucket file.txt', '') - .example('node $0 entitiesFromString "

President Obama is speaking at the White House.

" -t html', '') - .example('node $0 entitiesFromFile my-bucket file.txt', '') - .example('node $0 syntaxFromString "President Obama is speaking at the White House."', '') - .example('node $0 syntaxFromFile my-bucket es_file.txt -l es', '') - .wrap(100) + .example(`node $0 sentimentOfText "President Obama is speaking at the White House."`, ``) + .example(`node $0 sentimentInFile my-bucket file.txt`, ``) + .example(`node $0 entitiesOfText "President Obama is speaking at the White House."`, ``) + .example(`node $0 entitiesInFile my-bucket file.txt`, ``) + .example(`node $0 syntaxOfText "President Obama is speaking at the White House."`, ``) + .example(`node $0 syntaxInFile my-bucket file.txt`, ``) + .wrap(120) .recommendCommands() - .epilogue('For more information, see https://cloud.google.com/natural-language/docs'); + .epilogue(`For more information, see https://cloud.google.com/natural-language/docs`); if (module === require.main) { program.main(process.argv.slice(2)); diff --git a/language/package.json b/language/package.json index c5ac342fd0..f95e29b9fd 100644 --- a/language/package.json +++ b/language/package.json @@ -5,17 +5,12 @@ "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 st -- language/system-test/*" }, "dependencies": { - "@google-cloud/language": "^0.1.2", - "@google-cloud/storage": "^0.1.1", - "yargs": "^5.0.0" - }, - "devDependencies": { - "mocha": "^3.0.2", - "node-uuid": "^1.4.7" + "@google-cloud/language": "^0.6.0", + "@google-cloud/storage": "^0.4.0", + "yargs": "^6.4.0" }, "engines": { "node": ">=4.3.2" diff --git a/language/quickstart.js b/language/quickstart.js index ac595aa563..fd40ed8a2b 100644 --- a/language/quickstart.js +++ b/language/quickstart.js @@ -31,13 +31,11 @@ const languageClient = Language({ const text = 'Hello, world!'; // Detects the sentiment of the text -languageClient.detectSentiment(text, { verbose: true }, (err, sentiment) => { - if (err) { - console.error(err); - return; - } +languageClient.detectSentiment(text) + .then((results) => { + const sentiment = results[0]; - console.log('Text: %s', text); - console.log('Sentiment: %j', sentiment); -}); + console.log(`Text: ${text}`); + console.log(`Sentiment: ${sentiment}`); + }); // [END language_quickstart] diff --git a/language/system-test/analyze.test.js b/language/system-test/analyze.test.js index 9e99299ff3..7030f9a425 100644 --- a/language/system-test/analyze.test.js +++ b/language/system-test/analyze.test.js @@ -13,103 +13,64 @@ 'use strict'; -var uuid = require('node-uuid'); -var path = require('path'); -var storage = require('@google-cloud/storage')(); -var program = require('../analyze'); +const uuid = require(`node-uuid`); +const path = require(`path`); +const storage = require(`@google-cloud/storage`)(); +const run = require(`../../utils`).run; -var bucketName = 'nodejs-docs-samples-test-' + uuid.v4(); -var fileName = 'text.txt'; -var localFilePath = path.join(__dirname, '../resources/text.txt'); -var text = 'President Obama is speaking at the White House.'; -var options = { - type: 'text' -}; +const cmd = `node analyze.js`; +const cwd = path.join(__dirname, `..`); +const bucketName = `nodejs-docs-samples-test-${uuid.v4()}`; +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', function () { - before(function (done) { - storage.createBucket(bucketName, function (err, bucket) { - assert.equal(err, null); - bucket.upload(localFilePath, done); - }); +describe(`language:analyze`, () => { + before(() => { + return storage.createBucket(bucketName) + .then((results) => results[0].upload(localFilePath)); }); - after(function (done) { - storage.bucket(bucketName).deleteFiles({ force: true }, function (err) { - assert.equal(err, null); - storage.bucket(bucketName).delete(done); - }); + after(() => { + return storage.bucket(bucketName).deleteFiles({ force: true }) + .then(() => storage.bucket(bucketName).delete()); }); - describe('analyzeSentimentFromString', function () { - it('should analyze sentiment in text', function (done) { - program.analyzeSentimentFromString(text, options, function (err, sentiment) { - assert.equal(err, null); - assert.equal(typeof sentiment, 'object'); - assert.equal(typeof sentiment.polarity, 'number'); - assert.equal(typeof sentiment.magnitude, 'number'); - done(); - }); - }); + it(`should analyze sentiment in text`, () => { + assert.equal(run(`${cmd} sentimentOfText "${text}"`, cwd), `Sentiment: positive.`); }); - describe('analyzeSentimentFromFile', function () { - it('should analyze sentiment in a file', function (done) { - program.analyzeSentimentFromFile(bucketName, fileName, options, function (err, sentiment) { - assert.equal(err, null); - assert.equal(typeof sentiment, 'object'); - assert.equal(typeof sentiment.polarity, 'number'); - assert.equal(typeof sentiment.magnitude, 'number'); - done(); - }); - }); + it(`should analyze sentiment in a file`, () => { + assert.equal(run(`${cmd} sentimentInFile ${bucketName} ${fileName}`, cwd), `Sentiment: positive.`); }); - describe('analyzeEntitiesFromString', function () { - it('should analyze entities in text', function (done) { - program.analyzeEntitiesFromString(text, options, function (err, entities) { - assert.equal(err, null); - assert.equal(typeof entities, 'object'); - assert.equal(Array.isArray(entities.people), true); - assert.equal(Array.isArray(entities.places), true); - done(); - }); - }); + it(`should analyze entities in text`, () => { + const output = run(`${cmd} entitiesOfText "${text}"`, cwd); + assert.equal(output.includes(`Entities:`), true); + assert.equal(output.includes(`people:`), true); + assert.equal(output.includes(`places:`), true); }); - describe('analyzeEntitiesFromFile', function () { - it('should analyze entities in a file', function (done) { - program.analyzeEntitiesFromFile(bucketName, fileName, options, function (err, entities) { - assert.equal(err, null); - assert.equal(typeof entities, 'object'); - assert.equal(Array.isArray(entities.people), true); - assert.equal(Array.isArray(entities.places), true); - done(); - }); - }); + it('should analyze entities in a file', () => { + const output = run(`${cmd} entitiesInFile ${bucketName} ${fileName}`, cwd); + assert.equal(output.includes(`Entities:`), true); + assert.equal(output.includes(`people:`), true); + assert.equal(output.includes(`places:`), true); }); - describe('analyzeSyntaxFromString', function () { - it('should analyze syntax in text', function (done) { - program.analyzeSyntaxFromString(text, options, function (err, syntax) { - assert.equal(err, null); - assert.equal(typeof syntax, 'object'); - assert.equal(Array.isArray(syntax.sentences), true); - assert.equal(Array.isArray(syntax.tokens), true); - done(); - }); - }); + it(`should analyze syntax in text`, () => { + const output = run(`${cmd} syntaxOfText "${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); }); - describe('analyzeSyntaxFromFile', function () { - it('should analyze syntax in a file', function (done) { - program.analyzeSyntaxFromFile(bucketName, fileName, options, function (err, syntax) { - assert.equal(err, null); - assert.equal(typeof syntax, 'object'); - assert.equal(Array.isArray(syntax.sentences), true); - assert.equal(Array.isArray(syntax.tokens), true); - done(); - }); - }); + it('should analyze syntax in a file', () => { + const output = run(`${cmd} syntaxInFile ${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); }); }); diff --git a/language/system-test/quickstart.test.js b/language/system-test/quickstart.test.js index 6c68b79400..85214485c5 100644 --- a/language/system-test/quickstart.test.js +++ b/language/system-test/quickstart.test.js @@ -25,21 +25,23 @@ describe(`language:quickstart`, () => { const expectedText = `Hello, world!`; languageMock = { - detectSentiment: (_text, _config, _callback) => { + detectSentiment: (_text) => { assert.equal(_text, expectedText); - assert.deepEqual(_config, { verbose: true }); - assert.equal(typeof _callback, 'function'); - - language.detectSentiment(_text, _config, (err, sentiment, apiResponse) => { - _callback(err, sentiment, apiResponse); - assert.ifError(err); - assert.equal(typeof sentiment, 'object'); - assert.notEqual(apiResponse, undefined); - assert.equal(console.log.calledTwice, true); - assert.deepEqual(console.log.firstCall.args, [`Text: %s`, expectedText]); - assert.deepEqual(console.log.secondCall.args, [`Sentiment: %j`, sentiment]); - done(); - }); + + return language.detectSentiment(_text) + .then((results) => { + const sentiment = results[0]; + assert.equal(typeof sentiment, `number`); + + setTimeout(() => { + assert.equal(console.log.calledTwice, true); + assert.deepEqual(console.log.firstCall.args, [`Text: ${expectedText}`]); + assert.deepEqual(console.log.secondCall.args, [`Sentiment: ${sentiment}`]); + done(); + }, 200); + + return results; + }); } }; LanguageMock = sinon.stub().returns(languageMock); diff --git a/language/test/analyze.test.js b/language/test/analyze.test.js deleted file mode 100644 index 0f037064ed..0000000000 --- a/language/test/analyze.test.js +++ /dev/null @@ -1,368 +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'; - -var proxyquire = require('proxyquire').noCallThru(); -var text = 'President Obama is speaking at the White House.'; -var bucketName = 'foo'; -var fileName = 'file.txt'; -var language = 'en'; -var type = 'text'; - -function getSample () { - var sentimentMock = { - polarity: -10, - magnitude: 2 - }; - var entitiesMock = { - foo: [] - }; - var syntaxMock = {}; - var fileMock = {}; - var documentMock = { - detectSentiment: sinon.stub().yields(null, sentimentMock), - detectEntities: sinon.stub().yields(null, entitiesMock), - annotate: sinon.stub().yields(null, undefined, syntaxMock) - }; - var languageMock = { - document: sinon.stub().returns(documentMock) - }; - var bucketMock = { - file: sinon.stub().returns(fileMock) - }; - var storageMock = { - bucket: sinon.stub().returns(bucketMock) - }; - var LanguageMock = sinon.stub().returns(languageMock); - var StorageMock = sinon.stub().returns(storageMock); - - return { - program: proxyquire('../analyze', { - '@google-cloud/language': LanguageMock, - '@google-cloud/storage': StorageMock - }), - mocks: { - Language: LanguageMock, - language: languageMock, - Storage: StorageMock, - storage: storageMock, - document: documentMock, - sentiment: sentimentMock, - file: fileMock, - bucket: bucketMock, - entities: entitiesMock, - syntax: syntaxMock - } - }; -} - -describe('language:analyze', function () { - describe('analyzeSentimentFromString', function () { - it('should analyze sentiment in text', function () { - var sample = getSample(); - var callback = sinon.stub(); - - sample.program.analyzeSentimentFromString(text, { - type: type, - language: language - }, callback); - - assert.equal(sample.mocks.language.document.calledOnce, true); - assert.deepEqual(sample.mocks.language.document.firstCall.args, [{ - content: text, - type: type, - language: language - }]); - assert.equal(sample.mocks.document.detectSentiment.calledOnce, true); - assert.deepEqual(sample.mocks.document.detectSentiment.firstCall.args.slice(0, -1), [{ verbose: true }]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.sentiment]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Found %s sentiment', sample.mocks.sentiment.polarity >= 0 ? 'positive' : 'negative']); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.document.detectSentiment.yields(error); - - sample.program.analyzeSentimentFromString(text, { - type: type, - language: language - }, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('analyzeSentimentFromFile', function () { - it('should analyze sentiment in text', function () { - var sample = getSample(); - var callback = sinon.stub(); - - sample.program.analyzeSentimentFromFile(bucketName, fileName, { - type: type, - language: language - }, callback); - - assert.equal(sample.mocks.language.document.calledOnce, true); - assert.deepEqual(sample.mocks.language.document.firstCall.args, [{ - content: sample.mocks.file, - type: type, - language: language - }]); - assert.equal(sample.mocks.document.detectSentiment.calledOnce, true); - assert.deepEqual(sample.mocks.document.detectSentiment.firstCall.args.slice(0, -1), [{ verbose: true }]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.sentiment]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Found %s sentiment', sample.mocks.sentiment.polarity >= 0 ? 'positive' : 'negative']); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.document.detectSentiment.yields(error); - - sample.program.analyzeSentimentFromFile(bucketName, fileName, { - type: type, - language: language - }, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('analyzeEntitiesFromString', function () { - it('should analyze entities in text', function () { - var sample = getSample(); - var callback = sinon.stub(); - - sample.program.analyzeEntitiesFromString(text, { - type: type, - language: language - }, callback); - - assert.equal(sample.mocks.language.document.calledOnce, true); - assert.deepEqual(sample.mocks.language.document.firstCall.args, [{ - content: text, - type: type, - language: language - }]); - assert.equal(sample.mocks.document.detectEntities.calledOnce, true); - assert.deepEqual(sample.mocks.document.detectEntities.firstCall.args.slice(0, -1), [{ verbose: true }]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.entities]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Found %d entity type(s)!', Object.keys(sample.mocks.entities).length]); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.document.detectEntities.yields(error); - - sample.program.analyzeEntitiesFromString(text, { - type: type, - language: language - }, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('analyzeEntitiesFromFile', function () { - it('should analyze sentiment in text', function () { - var sample = getSample(); - var callback = sinon.stub(); - - sample.program.analyzeEntitiesFromFile(bucketName, fileName, { - type: type, - language: language - }, callback); - - assert.equal(sample.mocks.language.document.calledOnce, true); - assert.deepEqual(sample.mocks.language.document.firstCall.args, [{ - content: sample.mocks.file, - type: type, - language: language - }]); - assert.equal(sample.mocks.document.detectEntities.calledOnce, true); - assert.deepEqual(sample.mocks.document.detectEntities.firstCall.args.slice(0, -1), [{ verbose: true }]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.entities]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Found %d entity type(s)!', Object.keys(sample.mocks.entities).length]); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.document.detectEntities.yields(error); - - sample.program.analyzeEntitiesFromFile(bucketName, fileName, { - type: type, - language: language - }, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('analyzeSyntaxFromString', function () { - it('should analyze syntax in text', function () { - var sample = getSample(); - var callback = sinon.stub(); - - sample.program.analyzeSyntaxFromString(text, { - type: type, - language: language - }, callback); - - assert.equal(sample.mocks.language.document.calledOnce, true); - assert.deepEqual(sample.mocks.language.document.firstCall.args, [{ - content: text, - type: type, - language: language - }]); - assert.equal(sample.mocks.document.annotate.calledOnce, true); - assert.deepEqual(sample.mocks.document.annotate.firstCall.args.slice(0, -1), [{ syntax: true }]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.syntax]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Done analyzing syntax']); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.document.annotate.yields(error); - - sample.program.analyzeSyntaxFromString(text, { - type: type, - language: language - }, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('analyzeSyntaxFromFile', function () { - it('should analyze syntax in text', function () { - var sample = getSample(); - var callback = sinon.stub(); - - sample.program.analyzeSyntaxFromFile(bucketName, fileName, { - type: type, - language: language - }, callback); - - assert.equal(sample.mocks.language.document.calledOnce, true); - assert.deepEqual(sample.mocks.language.document.firstCall.args, [{ - content: sample.mocks.file, - type: type, - language: language - }]); - assert.equal(sample.mocks.document.annotate.calledOnce, true); - assert.deepEqual(sample.mocks.document.annotate.firstCall.args.slice(0, -1), [{ syntax: true }]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.syntax]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Done analyzing syntax']); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.document.annotate.yields(error); - - sample.program.analyzeSyntaxFromFile(bucketName, fileName, { - type: type, - language: language - }, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('main', function () { - var options = { type: 'text', language: undefined }; - - it('should call analyzeSentimentFromString', function () { - var program = getSample().program; - - sinon.stub(program, 'analyzeSentimentFromString'); - program.main(['sentimentFromString', text]); - assert.equal(program.analyzeSentimentFromString.calledOnce, true); - assert.deepEqual(program.analyzeSentimentFromString.firstCall.args.slice(0, -1), [text, options]); - }); - - it('should call analyzeSentimentFromFile', function () { - var program = getSample().program; - - sinon.stub(program, 'analyzeSentimentFromFile'); - program.main(['sentimentFromFile', bucketName, fileName]); - assert.equal(program.analyzeSentimentFromFile.calledOnce, true); - assert.deepEqual(program.analyzeSentimentFromFile.firstCall.args.slice(0, -1), [bucketName, fileName, options]); - }); - - it('should call analyzeEntitiesFromString', function () { - var program = getSample().program; - - sinon.stub(program, 'analyzeEntitiesFromString'); - program.main(['entitiesFromString', text]); - assert.equal(program.analyzeEntitiesFromString.calledOnce, true); - assert.deepEqual(program.analyzeEntitiesFromString.firstCall.args.slice(0, -1), [text, options]); - }); - - it('should call analyzeEntitiesFromFile', function () { - var program = getSample().program; - - sinon.stub(program, 'analyzeEntitiesFromFile'); - program.main(['entitiesFromFile', bucketName, fileName]); - assert.equal(program.analyzeEntitiesFromFile.calledOnce, true); - assert.deepEqual(program.analyzeEntitiesFromFile.firstCall.args.slice(0, -1), [bucketName, fileName, options]); - }); - - it('should call analyzeSyntaxFromString', function () { - var program = getSample().program; - - sinon.stub(program, 'analyzeSyntaxFromString'); - program.main(['syntaxFromString', text]); - assert.equal(program.analyzeSyntaxFromString.calledOnce, true); - assert.deepEqual(program.analyzeSyntaxFromString.firstCall.args.slice(0, -1), [text, options]); - }); - - it('should call analyzeSyntaxFromFile', function () { - var program = getSample().program; - - sinon.stub(program, 'analyzeSyntaxFromFile'); - program.main(['syntaxFromFile', bucketName, fileName]); - assert.equal(program.analyzeSyntaxFromFile.calledOnce, true); - assert.deepEqual(program.analyzeSyntaxFromFile.firstCall.args.slice(0, -1), [bucketName, fileName, options]); - }); - }); -}); diff --git a/language/test/quickstart.test.js b/language/test/quickstart.test.js deleted file mode 100644 index df0519c73c..0000000000 --- a/language/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(`language:quickstart`, () => { - let languageMock, LanguageMock; - const error = new Error(`error`); - const text = 'Hello, world!'; - - before(() => { - languageMock = { - detectSentiment: sinon.stub().yields(error) - }; - LanguageMock = sinon.stub().returns(languageMock); - }); - - it(`should handle error`, () => { - proxyquire(`../quickstart`, { - '@google-cloud/language': LanguageMock - }); - - assert.equal(LanguageMock.calledOnce, true); - assert.deepEqual(LanguageMock.firstCall.args, [{ projectId: 'YOUR_PROJECT_ID' }]); - assert.equal(languageMock.detectSentiment.calledOnce, true); - assert.deepEqual(languageMock.detectSentiment.firstCall.args.slice(0, -1), [text, { verbose: true }]); - assert.equal(console.error.calledOnce, true); - assert.deepEqual(console.error.firstCall.args, [error]); - }); -}); diff --git a/package.json b/package.json index ea2df57c56..5e75cabfe9 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,9 @@ "scripts": { "lint": "semistandard", "pretest": "npm run lint && ./scripts/clean", - "mocha": "mocha -R spec -t 120000 --require intelli-espower-loader ./test/_setup.js ./test/*.test.js '{*,appengine/*,functions/*}/test/*.test.js'", + "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/*}/test/*.test.js'", "test": "npm run mocha", "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'",