Skip to content

Commit

Permalink
Add Translate API samples. Fixes #176. (#184)
Browse files Browse the repository at this point in the history
* Add Translate API samples. Fixes #176.

* Fix build.

* Add comment.

* Address comments
  • Loading branch information
jmdobry authored Aug 21, 2016
1 parent ffe2476 commit 47baf19
Show file tree
Hide file tree
Showing 10 changed files with 516 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ cache:
- speech/node_modules/
- storage/node_modules/
- trace/node_modules/
- translate/node_modules/
- vision/node_modules/

env:
Expand All @@ -85,6 +86,7 @@ env:

before_install:
- openssl aes-256-cbc -K $encrypted_fda0b707c7d5_key -iv $encrypted_fda0b707c7d5_iv -in key.json.enc -out key.json -d
- npm install -g npm
- npm set progress=false

before_script:
Expand Down
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ on Google Cloud Platform.
* [Google Cloud Pub/Sub](#google-cloud-pubsub)
* [Google Cloud Speech API (Beta)](#google-cloud-speech-api-beta)
* [Google Cloud Storage](#google-cloud-storage)
* [Google Translate API](#google-translate-api)
* [Google Cloud Vision API](#google-cloud-vision-api)
* [Stackdriver Debugger (Beta)](#stackdriver-debugger-beta)
* [Stackdriver Logging (Beta)](#stackdriver-logging-beta)
Expand Down Expand Up @@ -321,6 +322,16 @@ View the [Cloud Storage Node.js samples][storage_samples].
[storage_docs]: https://cloud.google.com/storage/docs/
[storage_samples]: storage

### Google Translate API

With the [Google Translate API][translate_docs], you can dynamically translate
text between thousands of language pairs.

View the [Translate API Node.js samples][translate_samples].

[translate_docs]: https://cloud.google.com/translate/docs/
[translate_samples]: translate

### Google Cloud Vision API

The [Cloud Vision API][vision_docs] allows developers to easily integrate vision
Expand Down
1 change: 1 addition & 0 deletions circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,5 @@ dependencies:
- speech/node_modules/
- storage/node_modules/
- trace/node_modules/
- translate/node_modules/
- vision/node_modules/
1 change: 1 addition & 0 deletions scripts/install
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ queue.push('pubsub');
queue.push('speech');
queue.push('storage');
queue.push('trace');
queue.push('translate');
queue.push('vision');

/**
Expand Down
1 change: 1 addition & 0 deletions scripts/uninstall
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ queue.push('pubsub');
queue.push('speech');
queue.push('storage');
queue.push('trace');
queue.push('translate');
queue.push('vision');

/**
Expand Down
57 changes: 57 additions & 0 deletions translate/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<img src="https://avatars2.githubusercontent.com/u/2810941?v=3&s=96" alt="Google Cloud Platform logo" title="Google Cloud Platform" align="right" height="96" width="96"/>

# Google Translate API Node.js Samples

With the [Google Translate API][translate_docs], you can dynamically translate
text between thousands of language pairs.

[translate_docs]: https://cloud.google.com/translate/docs/

## Table of Contents

* [Setup](#setup)
* [Samples](#samples)
* [Translate](#translate)

## Setup

1. Read [Prerequisites][prereq] and [How to run a sample][run] first.
1. Install dependencies:

npm install

[prereq]: ../README.md#prerequisities
[run]: ../README.md#how-to-run-a-sample

## Samples

### Translate

View the [documentation][translate_docs] or the [source code][translate_code].

__Usage:__ `node translate --help`

```
Commands:
detect <text> Detect the language of the provided text
list List available translation languages.
translate <text> Translate the provided text to the target language.
Options:
--apiKey, -k Your Translate API key. Defaults to the value of the TRANSLATE_API_KEY environment
variable. [string]
--help Show help [boolean]
Examples:
node translate detect -k your-key "Hello world!" Detect the language of "Hello world!".
node translate list -k your-key List available translation languages.
node translate translate -k your-key --to ru "Good Translate "Good morning!" to Russian,
morning!" auto-detecting English.
node translate translate -k your-key --to ru Translate "Good morning!" to Russian from
--from en "Good morning!" English.
For more information, see https://cloud.google.com/translate/docs
```

[translate_docs]: https://cloud.google.com/translate/docs
[translate_code]: translate.js
19 changes: 19 additions & 0 deletions translate/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "nodejs-docs-samples-translate",
"version": "0.0.1",
"private": true,
"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"
},
"dependencies": {
"@google-cloud/translate": "^0.1.1",
"iso-639-1": "^1.2.1",
"yargs": "^5.0.0"
},
"devDependencies": {
"mocha": "^3.0.2"
}
}
66 changes: 66 additions & 0 deletions translate/system-test/translate.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2015-2016, Google, Inc.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

'use strict';

var program = require('../translate');
var apiKey = process.env.TRANSLATE_API_KEY;
var text = 'Hello world!';

describe('translate:translate', function () {
if (!process.env.TRANSLATE_API_KEY) {
process.stdout.write('Skipping Translate API tests...\n');
return;
}
describe('detectLanguage', function () {
it('should detect language', function (done) {
program.detectLanguage(text, apiKey, function (err, result) {
assert.ifError(err);
assert(result, 'should have received a result');
assert.equal(result.language, 'en', 'should have detected english');
assert(console.log.calledWith('Detected %s with confidence %d', 'English', result.confidence));
done();
});
});
});

describe('listLanguages', function () {
it('should list languages', function (done) {
program.listLanguages(apiKey, function (err, languages) {
assert.ifError(err);
assert(Array.isArray(languages));
assert(languages.length > 0);
assert(console.log.calledWith('Found %d language(s)!', languages.length));
done();
});
});
});

describe('translateText', function () {
it('should translate text', function (done) {
var options = {
text: text,
apiKey: apiKey,
to: 'ru'
};
var expected = 'Привет мир!';

program.translateText(options, function (err, translation) {
assert.ifError(err);
assert.equal(translation, expected);
assert(console.log.calledWith('Translated text to %s', 'Russian'));
done();
});
});
});
});
188 changes: 188 additions & 0 deletions translate/test/translate.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
// 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 = 'Hello world!';
var apiKey = 'key';

function getSample () {
var languagesMock = [
'en',
'ru'
];
var resultMock = {
language: 'en',
confidence: 0.75,
input: text
};
var translationMock = 'Привет мир!';
var translateMock = {
getLanguages: sinon.stub().callsArgWith(0, null, languagesMock),
detect: sinon.stub().callsArgWith(1, null, resultMock),
translate: sinon.stub().callsArgWith(2, null, translationMock)
};
var TranslateMock = sinon.stub().returns(translateMock);

return {
program: proxyquire('../translate', {
'@google-cloud/translate': TranslateMock,
yargs: proxyquire('yargs', {})
}),
mocks: {
Translate: TranslateMock,
translate: translateMock,
languages: languagesMock,
result: resultMock,
translation: translationMock
}
};
}

describe('translate:translate', function () {
describe('detectLanguage', function () {
it('should detect language', function () {
var sample = getSample();
var callback = sinon.stub();

sample.program.detectLanguage(text, apiKey, callback);

assert(sample.mocks.translate.detect.calledOnce, 'method called once');
assert.equal(sample.mocks.translate.detect.firstCall.args.length, 2, 'method received 2 arguments');
assert.equal(sample.mocks.translate.detect.firstCall.args[0], text, 'method received correct argument');
assert(callback.calledOnce, 'callback called once');
assert.equal(callback.firstCall.args.length, 2, 'callback received 2 arguments');
assert.ifError(callback.firstCall.args[0], 'callback did not receive error');
assert.strictEqual(callback.firstCall.args[1], sample.mocks.result, 'callback received result');
assert(console.log.calledWith('Detected %s with confidence %d', 'English', sample.mocks.result.confidence));
});

it('should handle error', function () {
var error = 'error';
var sample = getSample();
var callback = sinon.stub();
sample.mocks.translate.detect = sinon.stub().callsArgWith(1, error);

sample.program.detectLanguage(text, apiKey, callback);

assert(callback.calledOnce, 'callback called once');
assert.equal(callback.firstCall.args.length, 1, 'callback received 1 argument');
assert(callback.firstCall.args[0], 'callback received error');
assert.equal(callback.firstCall.args[0].message, error.message, 'error has correct message');
});
});

describe('listLanguages', function () {
it('should list languages', function () {
var sample = getSample();
var callback = sinon.stub();

sample.program.listLanguages(apiKey, callback);

assert(sample.mocks.translate.getLanguages.calledOnce, 'method called once');
assert.equal(sample.mocks.translate.getLanguages.firstCall.args.length, 1, 'method received 1 argument');
assert(callback.calledOnce, 'callback called once');
assert.equal(callback.firstCall.args.length, 2, 'callback received 2 arguments');
assert.ifError(callback.firstCall.args[0], 'callback did not receive error');
assert.strictEqual(callback.firstCall.args[1], sample.mocks.languages, 'callback received result');
assert(console.log.calledWith('Found %d language(s)!', sample.mocks.languages.length));
});

it('should handle error', function () {
var error = 'error';
var sample = getSample();
var callback = sinon.stub();
sample.mocks.translate.getLanguages = sinon.stub().callsArgWith(0, error);

sample.program.listLanguages(apiKey, callback);

assert(callback.calledOnce, 'callback called once');
assert.equal(callback.firstCall.args.length, 1, 'callback received 1 argument');
assert(callback.firstCall.args[0], 'callback received error');
assert.equal(callback.firstCall.args[0].message, error.message, 'error has correct message');
});
});

describe('translateText', function () {
it('should translate text', function () {
var sample = getSample();
var callback = sinon.stub();
var options = {
text: text,
to: 'ru',
apiKey: apiKey
};

sample.program.translateText(options, callback);

assert(sample.mocks.translate.translate.calledOnce, 'method called once');
assert.equal(sample.mocks.translate.translate.firstCall.args.length, 3, 'method received 3 arguments');
assert.equal(sample.mocks.translate.translate.firstCall.args[0], text, 'method received correct first argument');
assert.deepEqual(sample.mocks.translate.translate.firstCall.args[1], {
to: 'ru',
from: undefined
}, 'method received correct second argument');
assert(callback.calledOnce, 'callback called once');
assert.equal(callback.firstCall.args.length, 2, 'callback received 2 arguments');
assert.ifError(callback.firstCall.args[0], 'callback did not receive error');
assert.strictEqual(callback.firstCall.args[1], sample.mocks.translation, 'callback received result');
assert(console.log.calledWith('Translated text to %s', 'Russian'));
});

it('should handle error', function () {
var error = 'error';
var sample = getSample();
var callback = sinon.stub();
var options = {
text: text,
to: 'ru',
apiKey: apiKey
};
sample.mocks.translate.translate = sinon.stub().callsArgWith(2, error);

sample.program.translateText(options, callback);

assert(callback.calledOnce, 'callback called once');
assert.equal(callback.firstCall.args.length, 1, 'callback received 1 argument');
assert(callback.firstCall.args[0], 'callback received error');
assert.equal(callback.firstCall.args[0].message, error.message, 'error has correct message');
});
});

describe('main', function () {
it('should call detectLanguage', function () {
var program = getSample().program;

sinon.stub(program, 'detectLanguage');
program.main(['detect', text, '-k', apiKey]);
assert(program.detectLanguage.calledOnce);
});

it('should call listLanguages', function () {
var program = getSample().program;

sinon.stub(program, 'listLanguages');
program.main(['list', '-k', apiKey]);
assert(program.listLanguages.calledOnce);
});

it('should call translateText', function () {
var program = getSample().program;

sinon.stub(program, 'translateText');
program.main(['translate', text, '-k', apiKey, '-t', 'ru']);
assert(program.translateText.calledOnce);
});
});
});
Loading

0 comments on commit 47baf19

Please sign in to comment.