From 2b76870da209be012103e5d78dc5525812cfd039 Mon Sep 17 00:00:00 2001 From: Jason Dobry Date: Fri, 26 Aug 2016 16:06:18 -0700 Subject: [PATCH 1/2] Bring Language sample up to standard. --- language/README.md | 83 +++--- language/analyze.js | 387 ++++++++++++++++++--------- language/package.json | 4 +- language/resources/text.txt | 1 + language/system-test/analyze.test.js | 133 ++++++--- language/test/analyze.test.js | 368 ++++++++++++++++++++++++- 6 files changed, 753 insertions(+), 223 deletions(-) create mode 100644 language/resources/text.txt diff --git a/language/README.md b/language/README.md index 0d66231075..5bb8d32b0f 100644 --- a/language/README.md +++ b/language/README.md @@ -13,18 +13,15 @@ Learning API. * [Setup](#setup) * [Samples](#samples) - * [analyze.js](#analyze) + * [Analyze](#analyze) ## Setup -1. Please follow the [Set Up Your Project][quickstart] steps in the Quickstart -doc to create a project and enable the Cloud Natural Language API. 1. Read [Prerequisites][prereq] and [How to run a sample][run] first. 1. Install dependencies: npm install -[quickstart]: https://cloud.google.com/natural-language/docs/getting-started#set_up_your_project [prereq]: ../README.md#prerequisities [run]: ../README.md#how-to-run-a-sample @@ -32,54 +29,34 @@ doc to create a project and enable the Cloud Natural Language API. ### Analyze -View the [source code][analyze_code]. - -__Run the sample:__ - -Usage: `node analyze ` - -For example, the following command returns all entities found in the text: - -Example: - - node analyze entities "President Obama is speaking at the White House." - - { - "entities": [ - { - "name": "Obama", - "type": "PERSON", - "metadata": { - "wikipedia_url": "http://en.wikipedia.org/wiki/Barack_Obama" - }, - "salience": 0.84503114, - "mentions": [ - { - "text": { - "content": "Obama", - "beginOffset": 10 - } - } - ] - }, - { - "name": "White House", - "type": "LOCATION", - "metadata": { - "wikipedia_url": "http://en.wikipedia.org/wiki/White_House" - }, - "salience": 0.15496887, - "mentions": [ - { - "text": { - "content": "White House", - "beginOffset": 35 - } - } - ] - } - ], - "language": "en" - } +View the [documentation][analyze_docs] or the [source code][analyze_code]. +__Usage:__ `node analyze --help` + +``` +Commands: + sentiment Detect the sentiment of a block of text. + sentimentFromFile Detect the sentiment of text in a GCS file. + entities Detect the entities of a block of text. + entitiesFromFile Detect the entities of text in a GCS file. + syntax Detect the syntax of a block of text. + syntaxFromFile Detect the syntax of a block of text. + +Options: + --language, -l The language of the text. [string] + --type, -t Type of text. [string] [choices: "text", "html"] [default: "text"] + --help Show help [boolean] + +Examples: + node analyze sentiment "President Obama is speaking at the White House." + node analyze sentimentFromFile my-bucket file.txt + node analyze entities "

President Obama is speaking at the White House.

-t html" + node analyze entitiesFromFile my-bucket file.txt + node analyze syntax "President Obama is speaking at the White House." + node analyze syntaxFromFile my-bucket es_file.txt -l es + +For more information, see https://cloud.google.com/natural-language/docs +``` + +[analyze_docs]: https://cloud.google.com/natural-language/docs [analyze_code]: analyze.js diff --git a/language/analyze.js b/language/analyze.js index 245119d282..2253d2e78b 100644 --- a/language/analyze.js +++ b/language/analyze.js @@ -12,163 +12,294 @@ // 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] /** - * @fileoverview Command-line program to demonstrate how to call different - * methods in Cloud Natural Language API. - * - * To run this example, install npm: - * npm install + * Detect the sentiment of a block of text. * - * You must also set up to authenticate with the Cloud APIs using your - * project's service account credentials. See the README for details. - * - * To run: - * node analyze.js - * - * Here is an example: - * node analyze.js entities "President Obama is speaking at the White House." + * @param {string} text The text to analyze. + * @param {object} [options] Configuration options. + * @param {string} [options.type] "text" or "html". + * @param {string} [options.language] The language of the text, e.g. "en". + * @param {function} callback The callback function. */ -'use strict'; +function analyzeSentiment (text, options, callback) { + var document = language.document({ + content: text, + type: options.type, + language: options.language + }); -var google = require('googleapis'); + var config = { + // Get more detailed results + verbose: true + }; -var languageScopes = ['https://www.googleapis.com/auth/cloud-platform']; + // 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] + +// [START analyze_sentiment_from_file] /** - * Gets a client that is connected to the Google Cloud Natural Language API. + * Detect the sentiment 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] "text" or "html". + * @param {function} callback The callback function. */ -function getLanguageService (callback) { - google.auth.getApplicationDefault(function (err, authClient) { +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 + }; + + // See https://googlecloudplatform.github.io/google-cloud-node/#/docs/language/latest/language/document + document.detectSentiment(config, function (err, sentiment) { if (err) { return callback(err); } - // Depending on the environment that provides the default credentials - // (e.g. Compute Engine, App Engine), the credentials retrieved may - // require you to specify the scopes you need explicitly. - if (authClient.createScopedRequired && authClient.createScopedRequired()) { - authClient = authClient.createScoped(languageScopes); + console.log('Found %s sentiment', sentiment.polarity >= 0 ? 'positive' : 'negative'); + return callback(null, sentiment); + }); +} +// [END analyze_sentiment_from_file] + +// [START analyze_entities] +/** + * 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] "text" or "html". + * @param {function} callback The callback function. + */ +function analyzeEntities (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.detectEntities(config, function (err, entities) { + if (err) { + return callback(err); } - // Load the discovery document for the natural language api service, using - // the acquired credentials. - console.log('Loading language service...'); - google.discoverAPI({ - url: 'https://language.googleapis.com/$discovery/rest', - version: 'v1beta1', - auth: authClient - }, function (err, languageService) { - if (err) { - return callback(err); - } - callback(null, languageService, authClient); - }); + console.log('Found %d entity type(s)!', Object.keys(entities).length); + return callback(null, entities); }); } +// [END analyze_entities] -function analyzeSentiment (inputText, languageService, authClient, callback) { - languageService.documents.analyzeSentiment( - { - auth: authClient, - resource: { // Resource is used as the body for the API call. - document: { - content: inputText, - type: 'PLAIN_TEXT' - } - } - }, - function (err, result) { - if (err) { - return callback(err); - } - callback(null, result); - }); -} +// [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] "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 + }); -function analyzeEntities (inputText, languageService, authClient, callback) { - languageService.documents.analyzeEntities( - { - auth: authClient, - resource: { // Resource is used as the body for the API call. - document: { - content: inputText, - type: 'PLAIN_TEXT' - }, - encoding_type: 'UTF16' - } - }, - function (err, result) { - if (err) { - return callback(err); - } - callback(null, result); - }); -} + var config = { + // Get more detailed results + verbose: true + }; -function analyzeSyntax (inputText, languageService, authClient, callback) { - languageService.documents.annotateText( - { - auth: authClient, - resource: { // Resource is used as the body for the API call. - document: { - content: inputText, - type: 'PLAIN_TEXT' - }, - features: { - extract_syntax: 'TRUE' - }, - encoding_type: 'UTF16' - } - }, - function (err, result) { - if (err) { - return callback(err); - } - callback(null, result); - }); + // 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); + }); } +// [END analyze_entities_from_file] + +// [START analyze_syntax] +/** + * 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] "text" or "html". + * @param {function} callback The callback function. + */ +function analyzeSyntax (text, options, callback) { + var document = language.document({ + content: text, + type: options.type, + language: options.language + }); + + var config = { + syntax: true + }; -// Run the examples. -exports.main = function (command, inputText, callback) { - getLanguageService(function (err, languageService, authClient) { + // 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); } - var resultCallback = function (err, result) { - if (err) { - return callback(err); - } - callback(null, result); - }; - if (command === 'sentiment') { - analyzeSentiment(inputText, languageService, authClient, resultCallback); - } else if (command === 'entities') { - analyzeEntities(inputText, languageService, authClient, resultCallback); - } else if (command === 'syntax') { - analyzeSyntax(inputText, languageService, authClient, resultCallback); - } else { + console.log('Done analyzing syntax'); + return callback(null, apiResponse); + }); +} +// [END analyze_syntax] + +// [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] "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 + }); + + 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); }); -}; +} +// [END analyze_syntax_from_file] +// [END all] -if (require.main === module) { - var args = process.argv.slice(2); - if (args.length !== 2) { - console.log('Incorrect number of arguments. ' + - 'Usage: node analyze.js '); - process.exit(1); - } - if (['sentiment', 'entities', 'syntax'].indexOf(args[0]) === -1) { - console.log('Incorrect command. ' + - 'Usage: node analyze.js '); - process.exit(1); +// The command-line program +var cli = require('yargs'); +var utils = require('../utils'); + +var program = module.exports = { + analyzeSentiment: analyzeSentiment, + analyzeSentimentFromFile: analyzeSentimentFromFile, + analyzeEntities: analyzeEntities, + analyzeEntitiesFromFile: analyzeEntitiesFromFile, + analyzeSyntax: analyzeSyntax, + analyzeSyntaxFromFile: analyzeSyntaxFromFile, + main: function (args) { + // Run the command-line program + cli.help().strict().parse(args).argv; } - exports.main(args[0], args[1], function (err, result) { - if (err) { - console.error(err); +}; + +cli + .demand(1) + .command('sentiment ', 'Detect the sentiment of a block of text.', {}, function (options) { + program.analyzeSentiment(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('entities ', 'Detect the entities of a block of text.', {}, function (options) { + program.analyzeEntities(options.text, utils.pick(options, ['language', 'type']), utils.makeHandler()); + }) + .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('syntax ', 'Detect the syntax of a block of text.', {}, function (options) { + program.analyzeSyntax(options.text, utils.pick(options, ['language', 'type']), utils.makeHandler()); + }) + .command('syntaxFromFile ', 'Detect the syntax of a block of text.', {}, function (options) { + program.analyzeSyntaxFromFile(options.bucket, options.filename, utils.pick(options, ['language', 'type']), utils.makeHandler()); + }) + .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 } - console.log(JSON.stringify(result, null, ' ')); - }); + }) + .example('node $0 sentiment "President Obama is speaking at the White House."', '') + .example('node $0 sentimentFromFile my-bucket file.txt', '') + .example('node $0 entities "

President Obama is speaking at the White House.

-t html"', '') + .example('node $0 entitiesFromFile my-bucket file.txt', '') + .example('node $0 syntax "President Obama is speaking at the White House."', '') + .example('node $0 syntaxFromFile my-bucket es_file.txt -l es', '') + .wrap(200) + .recommendCommands() + .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 ba0b599c62..44e98c8e34 100644 --- a/language/package.json +++ b/language/package.json @@ -9,7 +9,9 @@ "system-test": "mocha -R spec -t 120000 --require intelli-espower-loader ../system-test/_setup.js system-test/*.test.js" }, "dependencies": { - "googleapis": "^12.0.0" + "@google-cloud/language": "^0.1.1", + "@google-cloud/storage": "^0.1.1", + "yargs": "^5.0.0" }, "devDependencies": { "mocha": "^2.5.3" diff --git a/language/resources/text.txt b/language/resources/text.txt new file mode 100644 index 0000000000..97a1cea02b --- /dev/null +++ b/language/resources/text.txt @@ -0,0 +1 @@ +President Obama is speaking at the White House. \ No newline at end of file diff --git a/language/system-test/analyze.test.js b/language/system-test/analyze.test.js index 813590fa35..959dbe13f8 100644 --- a/language/system-test/analyze.test.js +++ b/language/system-test/analyze.test.js @@ -13,50 +13,103 @@ 'use strict'; -var analyzeExample = require('../../language/analyze'); +var uuid = require('node-uuid'); +var path = require('path'); +var storage = require('@google-cloud/storage')(); +var program = require('../analyze'); + +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' +}; describe('language:analyze', function () { - it('should analyze sentiment in text', function (done) { - analyzeExample.main( - 'sentiment', - 'This gazinga pin is bad and it should feel bad', - function (err, result) { - assert.ifError(err); - assert(result); - assert(result.documentSentiment); - assert(result.documentSentiment.polarity < 0); + before(function (done) { + storage.createBucket(bucketName, function (err, bucket) { + assert.equal(err, null); + bucket.upload(localFilePath, done); + }); + }); + + after(function (done) { + storage.bucket(bucketName).deleteFiles({ force: true }, function (err) { + assert.equal(err, null); + storage.bucket(bucketName).delete(done); + }); + }); + + describe('analyzeSentiment', function () { + it('should analyze sentiment in text', function (done) { + program.analyzeSentiment(text, options, function (err, sentiment) { + assert.equal(null, err); + assert.equal(typeof sentiment, 'object'); + assert.equal(typeof sentiment.polarity, 'number'); + assert.equal(typeof sentiment.magnitude, 'number'); + done(); + }); + }); + }); + + describe('analyzeSentimentFromFile', function () { + it('should analyze sentiment in a file', function (done) { + program.analyzeSentimentFromFile(bucketName, fileName, options, function (err, sentiment) { + assert.equal(null, err); + assert.equal(typeof sentiment, 'object'); + assert.equal(typeof sentiment.polarity, 'number'); + assert.equal(typeof sentiment.magnitude, 'number'); + done(); + }); + }); + }); + + describe('analyzeEntities', function () { + it('should analyze entities in text', function (done) { + program.analyzeEntities(text, options, function (err, entities) { + assert.equal(null, err); + 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', function (done) { - analyzeExample.main( - 'entities', - 'Mark Twain is the author of a book called Tom Sawyer', - function (err, result) { - assert.ifError(err); - assert(result); - assert(result.entities && result.entities.length); - assert(result.entities[0].name === 'Mark Twain'); - assert(result.entities[0].type === 'PERSON'); + }); + }); + }); + + describe('analyzeEntitiesFromFile', function () { + it('should analyze entities in a file', function (done) { + program.analyzeEntitiesFromFile(bucketName, fileName, options, function (err, entities) { + assert.equal(null, err); + assert.equal(typeof entities, 'object'); + assert.equal(Array.isArray(entities.people), true); + assert.equal(Array.isArray(entities.places), true); done(); - } - ); - }); - it('should analyze syntax in text', function (done) { - analyzeExample.main( - 'syntax', - 'Betty bought a bit of bitter butter. But she said, "This butter\'s ' + - 'bitter! If I put it in my batter, it will make my batter bitter. If I ' + - 'buy some better butter - better than this bitter butter - it will ' + - 'make my batter better."', - function (err, result) { - assert.ifError(err); - assert(result); - assert(result.sentences && result.sentences.length); - assert(result.tokens && result.tokens.length > 5); + }); + }); + }); + + describe('analyzeSyntax', function () { + it('should analyze syntax in text', function (done) { + program.analyzeSyntax(text, options, function (err, syntax) { + assert.equal(null, err); + assert.equal(typeof syntax, 'object'); + assert.equal(Array.isArray(syntax.sentences), true); + assert.equal(Array.isArray(syntax.tokens), true); + done(); + }); + }); + }); + + describe('analyzeSyntaxFromFile', function () { + it('should analyze syntax in a file', function (done) { + program.analyzeSyntaxFromFile(bucketName, fileName, options, function (err, syntax) { + assert.equal(null, err); + assert.equal(typeof syntax, 'object'); + assert.equal(Array.isArray(syntax.sentences), true); + assert.equal(Array.isArray(syntax.tokens), true); done(); - } - ); + }); + }); }); }); diff --git a/language/test/analyze.test.js b/language/test/analyze.test.js index 500b91a2b4..166574b826 100644 --- a/language/test/analyze.test.js +++ b/language/test/analyze.test.js @@ -13,6 +13,372 @@ '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 () { - it('should be tested'); + describe('analyzeSentiment', function () { + it('should analyze sentiment in text', function () { + var sample = getSample(); + var callback = sinon.stub(); + + sample.program.analyzeSentiment(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.analyzeSentiment(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('analyzeEntities', function () { + it('should analyze entities in text', function () { + var sample = getSample(); + var callback = sinon.stub(); + + sample.program.analyzeEntities(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.analyzeEntities(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('analyzeSyntax', function () { + it('should analyze syntax in text', function () { + var sample = getSample(); + var callback = sinon.stub(); + + sample.program.analyzeSyntax(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.analyzeSyntax(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 () { + it('should call analyzeSentiment', function () { + var program = getSample().program; + + sinon.stub(program, 'analyzeSentiment'); + program.main(['sentiment', text]); + assert.equal(program.analyzeSentiment.calledOnce, true); + assert.deepEqual(program.analyzeSentiment.firstCall.args.slice(0, -1), [text, { + type: 'text', + language: undefined + }]); + }); + + 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, { + type: 'text', + language: undefined + }]); + }); + + it('should call analyzeEntities', function () { + var program = getSample().program; + + sinon.stub(program, 'analyzeEntities'); + program.main(['entities', text]); + assert.equal(program.analyzeEntities.calledOnce, true); + assert.deepEqual(program.analyzeEntities.firstCall.args.slice(0, -1), [text, { + type: 'text', + language: undefined + }]); + }); + + 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, { + type: 'text', + language: undefined + }]); + }); + + it('should call analyzeSyntax', function () { + var program = getSample().program; + + sinon.stub(program, 'analyzeSyntax'); + program.main(['syntax', text]); + assert.equal(program.analyzeSyntax.calledOnce, true); + assert.deepEqual(program.analyzeSyntax.firstCall.args.slice(0, -1), [text, { + type: 'text', + language: undefined + }]); + }); + + 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, { + type: 'text', + language: undefined + }]); + }); + }); }); From bc558afa3dffb7f5f695ec1aa1d3aadcf0957366 Mon Sep 17 00:00:00 2001 From: Jason Dobry Date: Sat, 27 Aug 2016 17:35:51 -0700 Subject: [PATCH 2/2] Address comments. --- language/README.md | 16 +++--- language/analyze.js | 58 +++++++++++----------- language/system-test/analyze.test.js | 24 ++++----- language/test/analyze.test.js | 74 +++++++++++----------------- 4 files changed, 78 insertions(+), 94 deletions(-) diff --git a/language/README.md b/language/README.md index 5bb8d32b0f..d7a0fddadd 100644 --- a/language/README.md +++ b/language/README.md @@ -35,24 +35,24 @@ __Usage:__ `node analyze --help` ``` Commands: - sentiment Detect the sentiment of a block of text. + sentimentFromString Detect the sentiment of a block of text. sentimentFromFile Detect the sentiment of text in a GCS file. - entities Detect the entities of a block of text. + entitiesFromString Detect the entities of a block of text. entitiesFromFile Detect the entities of text in a GCS file. - syntax Detect the syntax of a block of text. - syntaxFromFile Detect the syntax of a block of text. + syntaxFromString Detect the syntax of a block of text. + syntaxFromFile 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"] + --type, -t Type of text [string] [choices: "text", "html"] [default: "text"] --help Show help [boolean] Examples: - node analyze sentiment "President Obama is speaking at the White House." + node analyze sentimentFromString "President Obama is speaking at the White House." node analyze sentimentFromFile my-bucket file.txt - node analyze entities "

President Obama is speaking at the White House.

-t html" + node analyze entitiesFromString "

President Obama is speaking at the White House.

" -t html node analyze entitiesFromFile my-bucket file.txt - node analyze syntax "President Obama is speaking at the White House." + node analyze syntaxFromString "President Obama is speaking at the White House." node analyze syntaxFromFile my-bucket es_file.txt -l es For more information, see https://cloud.google.com/natural-language/docs diff --git a/language/analyze.js b/language/analyze.js index 2253d2e78b..93a6642f39 100644 --- a/language/analyze.js +++ b/language/analyze.js @@ -29,17 +29,17 @@ var language = Language(); var storage = Storage(); // [END setup] -// [START analyze_sentiment] +// [START analyze_sentiment_from_string] /** * Detect the sentiment of a block of text. * * @param {string} text The text to analyze. * @param {object} [options] Configuration options. - * @param {string} [options.type] "text" or "html". + * @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 analyzeSentiment (text, options, callback) { +function analyzeSentimentFromString (text, options, callback) { var document = language.document({ content: text, type: options.type, @@ -61,7 +61,7 @@ function analyzeSentiment (text, options, callback) { return callback(null, sentiment); }); } -// [END analyze_sentiment] +// [END analyze_sentiment_from_string] // [START analyze_sentiment_from_file] /** @@ -71,7 +71,7 @@ function analyzeSentiment (text, options, callback) { * @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] "text" or "html". + * @param {string} [options.type] The type of the text, either "text" or "html". * @param {function} callback The callback function. */ function analyzeSentimentFromFile (bucket, filename, options, callback) { @@ -98,17 +98,17 @@ function analyzeSentimentFromFile (bucket, filename, options, callback) { } // [END analyze_sentiment_from_file] -// [START analyze_entities] +// [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] "text" or "html". + * @param {string} [options.type] The type of the text, either "text" or "html". * @param {function} callback The callback function. */ -function analyzeEntities (text, options, callback) { +function analyzeEntitiesFromString (text, options, callback) { var document = language.document({ content: text, type: options.type, @@ -130,7 +130,7 @@ function analyzeEntities (text, options, callback) { return callback(null, entities); }); } -// [END analyze_entities] +// [END analyze_entities_from_string] // [START analyze_entities_from_file] /** @@ -140,7 +140,7 @@ function analyzeEntities (text, options, callback) { * @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] "text" or "html". + * @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) { @@ -167,17 +167,17 @@ function analyzeEntitiesFromFile (bucket, filename, options, callback) { } // [END analyze_entities_from_file] -// [START analyze_syntax] +// [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] "text" or "html". + * @param {string} [options.type] The type of the text, either "text" or "html". * @param {function} callback The callback function. */ -function analyzeSyntax (text, options, callback) { +function analyzeSyntaxFromString (text, options, callback) { var document = language.document({ content: text, type: options.type, @@ -198,7 +198,7 @@ function analyzeSyntax (text, options, callback) { return callback(null, apiResponse); }); } -// [END analyze_syntax] +// [END analyze_syntax_from_string] // [START analyze_syntax_from_file] /** @@ -208,7 +208,7 @@ function analyzeSyntax (text, options, callback) { * @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] "text" or "html". + * @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) { @@ -240,11 +240,11 @@ var cli = require('yargs'); var utils = require('../utils'); var program = module.exports = { - analyzeSentiment: analyzeSentiment, + analyzeSentimentFromString: analyzeSentimentFromString, analyzeSentimentFromFile: analyzeSentimentFromFile, - analyzeEntities: analyzeEntities, + analyzeEntitiesFromString: analyzeEntitiesFromString, analyzeEntitiesFromFile: analyzeEntitiesFromFile, - analyzeSyntax: analyzeSyntax, + analyzeSyntaxFromString: analyzeSyntaxFromString, analyzeSyntaxFromFile: analyzeSyntaxFromFile, main: function (args) { // Run the command-line program @@ -254,22 +254,22 @@ var program = module.exports = { cli .demand(1) - .command('sentiment ', 'Detect the sentiment of a block of text.', {}, function (options) { - program.analyzeSentiment(options.text, utils.pick(options, ['language', 'type']), utils.makeHandler()); + .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('entities ', 'Detect the entities of a block of text.', {}, function (options) { - program.analyzeEntities(options.text, utils.pick(options, ['language', 'type']), utils.makeHandler()); + .command('entitiesFromString ', 'Detect the entities of a block of text.', {}, function (options) { + program.analyzeEntitiesFromString(options.text, utils.pick(options, ['language', 'type']), utils.makeHandler()); }) .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('syntax ', 'Detect the syntax of a block of text.', {}, function (options) { - program.analyzeSyntax(options.text, utils.pick(options, ['language', 'type']), utils.makeHandler()); + .command('syntaxFromString ', 'Detect the syntax of a block of text.', {}, function (options) { + program.analyzeSyntaxFromString(options.text, utils.pick(options, ['language', 'type']), utils.makeHandler()); }) - .command('syntaxFromFile ', 'Detect the syntax of a block of text.', {}, function (options) { + .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()); }) .options({ @@ -290,13 +290,13 @@ cli global: true } }) - .example('node $0 sentiment "President Obama is speaking at the White House."', '') + .example('node $0 sentimentFromString "President Obama is speaking at the White House."', '') .example('node $0 sentimentFromFile my-bucket file.txt', '') - .example('node $0 entities "

President Obama is speaking at the White House.

-t html"', '') + .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 syntax "President Obama is speaking at the White House."', '') + .example('node $0 syntaxFromString "President Obama is speaking at the White House."', '') .example('node $0 syntaxFromFile my-bucket es_file.txt -l es', '') - .wrap(200) + .wrap(100) .recommendCommands() .epilogue('For more information, see https://cloud.google.com/natural-language/docs'); diff --git a/language/system-test/analyze.test.js b/language/system-test/analyze.test.js index 959dbe13f8..9e99299ff3 100644 --- a/language/system-test/analyze.test.js +++ b/language/system-test/analyze.test.js @@ -41,10 +41,10 @@ describe('language:analyze', function () { }); }); - describe('analyzeSentiment', function () { + describe('analyzeSentimentFromString', function () { it('should analyze sentiment in text', function (done) { - program.analyzeSentiment(text, options, function (err, sentiment) { - assert.equal(null, err); + 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'); @@ -56,7 +56,7 @@ describe('language:analyze', function () { describe('analyzeSentimentFromFile', function () { it('should analyze sentiment in a file', function (done) { program.analyzeSentimentFromFile(bucketName, fileName, options, function (err, sentiment) { - assert.equal(null, err); + assert.equal(err, null); assert.equal(typeof sentiment, 'object'); assert.equal(typeof sentiment.polarity, 'number'); assert.equal(typeof sentiment.magnitude, 'number'); @@ -65,10 +65,10 @@ describe('language:analyze', function () { }); }); - describe('analyzeEntities', function () { + describe('analyzeEntitiesFromString', function () { it('should analyze entities in text', function (done) { - program.analyzeEntities(text, options, function (err, entities) { - assert.equal(null, err); + 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); @@ -80,7 +80,7 @@ describe('language:analyze', function () { describe('analyzeEntitiesFromFile', function () { it('should analyze entities in a file', function (done) { program.analyzeEntitiesFromFile(bucketName, fileName, options, function (err, entities) { - assert.equal(null, err); + assert.equal(err, null); assert.equal(typeof entities, 'object'); assert.equal(Array.isArray(entities.people), true); assert.equal(Array.isArray(entities.places), true); @@ -89,10 +89,10 @@ describe('language:analyze', function () { }); }); - describe('analyzeSyntax', function () { + describe('analyzeSyntaxFromString', function () { it('should analyze syntax in text', function (done) { - program.analyzeSyntax(text, options, function (err, syntax) { - assert.equal(null, err); + 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); @@ -104,7 +104,7 @@ describe('language:analyze', function () { describe('analyzeSyntaxFromFile', function () { it('should analyze syntax in a file', function (done) { program.analyzeSyntaxFromFile(bucketName, fileName, options, function (err, syntax) { - assert.equal(null, err); + assert.equal(err, null); assert.equal(typeof syntax, 'object'); assert.equal(Array.isArray(syntax.sentences), true); assert.equal(Array.isArray(syntax.tokens), true); diff --git a/language/test/analyze.test.js b/language/test/analyze.test.js index 166574b826..0f037064ed 100644 --- a/language/test/analyze.test.js +++ b/language/test/analyze.test.js @@ -68,12 +68,12 @@ function getSample () { } describe('language:analyze', function () { - describe('analyzeSentiment', function () { + describe('analyzeSentimentFromString', function () { it('should analyze sentiment in text', function () { var sample = getSample(); var callback = sinon.stub(); - sample.program.analyzeSentiment(text, { + sample.program.analyzeSentimentFromString(text, { type: type, language: language }, callback); @@ -98,7 +98,7 @@ describe('language:analyze', function () { var callback = sinon.stub(); sample.mocks.document.detectSentiment.yields(error); - sample.program.analyzeSentiment(text, { + sample.program.analyzeSentimentFromString(text, { type: type, language: language }, callback); @@ -148,12 +148,12 @@ describe('language:analyze', function () { }); }); - describe('analyzeEntities', function () { + describe('analyzeEntitiesFromString', function () { it('should analyze entities in text', function () { var sample = getSample(); var callback = sinon.stub(); - sample.program.analyzeEntities(text, { + sample.program.analyzeEntitiesFromString(text, { type: type, language: language }, callback); @@ -178,7 +178,7 @@ describe('language:analyze', function () { var callback = sinon.stub(); sample.mocks.document.detectEntities.yields(error); - sample.program.analyzeEntities(text, { + sample.program.analyzeEntitiesFromString(text, { type: type, language: language }, callback); @@ -228,12 +228,12 @@ describe('language:analyze', function () { }); }); - describe('analyzeSyntax', function () { + describe('analyzeSyntaxFromString', function () { it('should analyze syntax in text', function () { var sample = getSample(); var callback = sinon.stub(); - sample.program.analyzeSyntax(text, { + sample.program.analyzeSyntaxFromString(text, { type: type, language: language }, callback); @@ -258,7 +258,7 @@ describe('language:analyze', function () { var callback = sinon.stub(); sample.mocks.document.annotate.yields(error); - sample.program.analyzeSyntax(text, { + sample.program.analyzeSyntaxFromString(text, { type: type, language: language }, callback); @@ -309,16 +309,15 @@ describe('language:analyze', function () { }); describe('main', function () { - it('should call analyzeSentiment', function () { + var options = { type: 'text', language: undefined }; + + it('should call analyzeSentimentFromString', function () { var program = getSample().program; - sinon.stub(program, 'analyzeSentiment'); - program.main(['sentiment', text]); - assert.equal(program.analyzeSentiment.calledOnce, true); - assert.deepEqual(program.analyzeSentiment.firstCall.args.slice(0, -1), [text, { - type: 'text', - language: undefined - }]); + 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 () { @@ -327,22 +326,16 @@ describe('language:analyze', function () { 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, { - type: 'text', - language: undefined - }]); + assert.deepEqual(program.analyzeSentimentFromFile.firstCall.args.slice(0, -1), [bucketName, fileName, options]); }); - it('should call analyzeEntities', function () { + it('should call analyzeEntitiesFromString', function () { var program = getSample().program; - sinon.stub(program, 'analyzeEntities'); - program.main(['entities', text]); - assert.equal(program.analyzeEntities.calledOnce, true); - assert.deepEqual(program.analyzeEntities.firstCall.args.slice(0, -1), [text, { - type: 'text', - language: undefined - }]); + 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 () { @@ -351,22 +344,16 @@ describe('language:analyze', function () { 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, { - type: 'text', - language: undefined - }]); + assert.deepEqual(program.analyzeEntitiesFromFile.firstCall.args.slice(0, -1), [bucketName, fileName, options]); }); - it('should call analyzeSyntax', function () { + it('should call analyzeSyntaxFromString', function () { var program = getSample().program; - sinon.stub(program, 'analyzeSyntax'); - program.main(['syntax', text]); - assert.equal(program.analyzeSyntax.calledOnce, true); - assert.deepEqual(program.analyzeSyntax.firstCall.args.slice(0, -1), [text, { - type: 'text', - language: undefined - }]); + 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 () { @@ -375,10 +362,7 @@ describe('language:analyze', function () { 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, { - type: 'text', - language: undefined - }]); + assert.deepEqual(program.analyzeSyntaxFromFile.firstCall.args.slice(0, -1), [bucketName, fileName, options]); }); }); });