Skip to content

Commit

Permalink
Add "Google" provider (#119)
Browse files Browse the repository at this point in the history
- Add "Google" provider.
- Fix "Unit Tests" workflow on main branch.
  • Loading branch information
fabasoad authored Feb 14, 2023
1 parent c3ad8c9 commit bf2338d
Show file tree
Hide file tree
Showing 18 changed files with 380 additions and 168 deletions.
6 changes: 6 additions & 0 deletions .codeclimate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
version: "2"
checks:
method-complexity:
config:
threshold: 6
5 changes: 5 additions & 0 deletions .github/workflows/functional-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ jobs:
source: 'Love'
expected: 'Любов'
api_key: 'DEEPL_API_KEY' # pragma: allowlist secret
- provider: 'google'
lang: 'en-hr'
source: 'Love'
expected: 'Ljubav'
api_key: 'N_A' # pragma: allowlist secret
- provider: 'linguatools'
lang: 'en-de'
source: 'Love'
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ jobs:
uses: paambaati/[email protected]
env:
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
DEEPL_API_KEY: ${{ secrets.DEEPL_API_KEY }}
MYMEMORY_API_KEY: ${{ secrets.MYMEMORY_API_KEY }}
with:
coverageCommand: yarn test
debug: true
Empty file added .yarn/versions/990a22e4.yml
Empty file.
57 changes: 47 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ more details for each provider below.
* [Outputs](#outputs)
* [Providers](#providers)
* [DeepL](#deepl)
* [Google](#google)
* [Linguatools](#linguatools)
* [Microsoft](#microsoft)
* [MyMemory](#mymemory)
Expand All @@ -31,13 +32,13 @@ more details for each provider below.

## Inputs

| Name | Required | Description | Default | Possible values |
|--------------------------|----------|--------------------------------------------------------------------------------------------------|---------|-----------------------------------------------------------------------------------------------------------------------------------|
| source | Yes | Can be text or path to the file for translation | | _<Path>_,_<String>_ |
| provider | Yes | Provider identifier | | [deepl](#deepl), [linguatools](#linguatools), [microsoft](#microsoft), [mymemory](#mymemory), [funtranslations](#funtranslations) |
| api_key | No | API key that should be used for chosen [provider](#providers) | | |
| api_additional_parameter | No | Additional parameter for the API. eg the region for Microsoft: `canadacentral` | `null` | _<String>_ |
| lang | Yes | The translation direction. Should be one of the option proposed by chosen [provider](#providers) | | _<String>_ |
| Name | Required | Description | Default | Possible values |
|--------------------------|----------|--------------------------------------------------------------------------------------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------|
| source | Yes | Can be text or path to the file for translation | | _<Path>_,_<String>_ |
| provider | Yes | Provider identifier | | [deepl](#deepl), [google](#google), [linguatools](#linguatools), [microsoft](#microsoft), [mymemory](#mymemory), [funtranslations](#funtranslations) |
| api_key | No | API key that should be used for chosen [provider](#providers) | `""` | _<String>_ |
| api_additional_parameter | No | Additional parameter for the API. eg the region for Microsoft: `canadacentral` | `""` | _<String>_ |
| lang | Yes | The translation direction. Should be one of the option proposed by chosen [provider](#providers) | | _<String>_ |

## Outputs

Expand All @@ -52,9 +53,9 @@ more details for each provider below.
* Identifier is `deepl`.
* Supported translation directions can be found [here](https://www.deepl.com/docs-api/general/get-languages/).
* Be aware that source and target languages should be separated by `-` (hyphen)
character while using them in `lang` input. For example, `en-pt` should be used
in case you want to translate text from English into Portugal. See example below
for more details.
character while using them in `lang` input. For example, `en-uk` should be used
in case you want to translate text from English into Ukrainian. See example
below for more details.
* How to get API key:
* Sign up to [DeepL](https://www.deepl.com) (free plan is fine).
* Go to `Account -> Account -> Authentication Key for DeepL API` section
Expand Down Expand Up @@ -87,6 +88,42 @@ Output is the following:
Translation is 'Любов'
```

### Google

* Identifier is `google`.
* Supported translation directions can be found [here](https://github.com/AidanWelch/google-translate-api/blob/master/index.d.ts#L67).
* Be aware that source and target languages should be separated by `-` (hyphen)
character while using them in `lang` input. For example, `ms-en` should be used
in case you want to translate text from Malay into English. See example below
for more details.

Example of translating "Victory" word from Malay into English:

```yaml
jobs:
google:
name: Google
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: fabasoad/translation-action@main
id: google-step
with:
provider: google
lang: ms-en
source: Kemenangan
- name: Print the result
run: echo "Translation is '${{ steps.google-step.outputs.text }}'"
shell: sh
```
Output is the following:
```text
> echo "Translation is 'Victory'"
Translation is 'Victory'
```

### Linguatools

* Identifier is `linguatools`. API Key is not needed for this provider.
Expand Down
4 changes: 2 additions & 2 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ inputs:
api_key:
description: 'API key that should be used for chosen provider.'
required: false
default: null
default: ''
api_additional_parameter:
description: 'Additional parameter for the API. eg the region for Microsoft: canadacentral.'
required: false
default: null
default: ''
lang:
description: 'The translation direction. Should be one of the option proposed by chosen provider.'
required: true
Expand Down
6 changes: 3 additions & 3 deletions dist/index.js

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "translation-action",
"version": "2.0.0",
"version": "2.1.0",
"description": "This GitHub action translates any text from any language to any language.",
"main": "dist/index.js",
"scripts": {
Expand All @@ -27,12 +27,14 @@
"dependencies": {
"@actions/core": "1.10.0",
"deepl-node": "1.8.0",
"google-translate-api-x": "10.5.4",
"node-fetch": "2.6.9",
"typed-rest-client": "1.8.9"
},
"devDependencies": {
"@types/jest": "29.4.0",
"@typescript-eslint/eslint-plugin": "5.51.0",
"@typescript-eslint/parser": "5.51.0",
"@typescript-eslint/eslint-plugin": "5.52.0",
"@typescript-eslint/parser": "5.52.0",
"@vercel/ncc": "0.36.1",
"dotenv": "16.0.3",
"eslint": "8.34.0",
Expand Down
32 changes: 15 additions & 17 deletions src/__tests__/providers/DeeplProvider.spec.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,25 @@
import ProviderBase from '../../providers/ProviderBase'
import DeeplProvider from '../../providers/DeeplProvider'
import { config } from 'dotenv'
import ProviderTester from './ProviderTester';

config()

describe('DeeplProvider', () => {
test('should get correct translation', async () => {
const provider: ProviderBase =
new DeeplProvider(process.env.DEEPL_API_KEY || '')
const translations = await provider.translate('Poem', 'en-uk')
expect(translations.length).toEqual(1)
expect(translations[0]).toEqual('Вірш')
})
let providerTester: ProviderTester

test('should fail because of invalid lang', async () => {
const provider: ProviderBase =
beforeAll(() => {
providerTester = new ProviderTester(
new DeeplProvider(process.env.DEEPL_API_KEY || '')
try {
await provider.translate('Evening', 'en-abc123')
} catch (e) {
expect(e).toBeTruthy()
return
}
throw new Error('Request should fail due to unknown target language')
)
})

test(
'should get correct translation',
async () => providerTester.positive()
)

test(
'should fail because of invalid lang',
async () => providerTester.negative()
)
})
43 changes: 18 additions & 25 deletions src/__tests__/providers/FunTranslationsProvider.spec.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,24 @@
import FunTranslationsProvider from '../../providers/FunTranslationsProvider'
import ProviderBase, { ProviderError } from '../../providers/ProviderBase'
import ProviderTester from './ProviderTester'

describe('FunTranslationsProvider', () => {
test('should get correct translation', async () => {
const provider: ProviderBase = new FunTranslationsProvider()
try {
const translations = await provider.translate('Evening', 'vulcan')
expect(translations.length).toEqual(1)
expect(translations[0]).toEqual('Khru')
} catch (e: unknown) {
if (!(e instanceof ProviderError)) {
const { statusCode } = e as never
if (statusCode !== 429) {
throw e
}
}
}
})
let providerTester: ProviderTester

test('should fail because of invalid lang', async () => {
const provider: ProviderBase = new FunTranslationsProvider()
try {
await provider.translate('Evening', 'abc123')
} catch (e) {
expect(e).toBeTruthy()
return
}
fail()
beforeAll(() => {
providerTester = new ProviderTester(
new FunTranslationsProvider()
)
})

test(
'should get correct translation',
async () => providerTester.positive({
text: 'Evening', lang: 'vulcan', expected: 'Khru'
})
)

test(
'should fail because of invalid lang',
async () => providerTester.negative()
)
})
22 changes: 22 additions & 0 deletions src/__tests__/providers/GoogleProvider.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import GoogleProvider from '../../providers/GoogleProvider'
import ProviderTester from './ProviderTester'

describe('GoogleProvider', () => {
let providerTester: ProviderTester

beforeAll(() => {
providerTester = new ProviderTester(
new GoogleProvider()
)
})

test(
'should get correct translation',
async () => providerTester.positive()
)

test(
'should fail because of invalid lang',
async () => providerTester.negative()
)
})
36 changes: 16 additions & 20 deletions src/__tests__/providers/LinguaToolsProvider.spec.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
import LinguaToolsProvider from '../../providers/LinguaToolsProvider'
import ProviderBase, { ProviderError } from '../../providers/ProviderBase'
import ProviderTester from './ProviderTester'

describe('LinguaToolsProvider', () => {
test.skip('should get correct translation', async () => {
const provider: ProviderBase = new LinguaToolsProvider()
const translations = await provider.translate('Evening', 'en-de')
expect(translations.length).toEqual(1)
expect(translations[0]).toEqual('Abend')
})
let providerTester: ProviderTester

test.skip('should fail because of invalid lang', async () => {
const provider: ProviderBase = new LinguaToolsProvider()
try {
await provider.translate('Evening', 'abc123')
} catch (e: unknown) {
const { status } = e as ProviderError
if (status === 404) {
throw e
}
expect(e).toBeTruthy()
return
}
throw new Error('Request should fail due to unknown lang')
beforeAll(() => {
providerTester = new ProviderTester(
new LinguaToolsProvider()
)
})

test.skip(
'should get correct translation',
async () => providerTester.positive()
)

test.skip(
'should fail because of invalid lang',
async () => providerTester.negative()
)
})
67 changes: 49 additions & 18 deletions src/__tests__/providers/MyMemoryProvider.spec.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,58 @@
import itParam from 'mocha-param'
import MyMemoryProvider from '../../providers/MyMemoryProvider'
import ProviderBase from '../../providers/ProviderBase'
import { config } from 'dotenv'
import ProviderTester from './ProviderTester'

config()

type ProviderTesterWrapper = {
providerTester: ProviderTester,
type: string
}

describe('MyMemoryProvider', () => {
itParam<string | undefined>('should get correct translation',
[undefined, process.env.MYMEMORY_API_KEY], async (apiKey) => {
const provider: ProviderBase = new MyMemoryProvider(apiKey)
const translations = await provider.translate('Evening', 'en|pt')
expect(translations.length).toBeGreaterThan(0)
expect(translations[0]).toEqual('NOITE')
})
const fixture: ProviderTesterWrapper[] = [{
providerTester: new ProviderTester(new MyMemoryProvider()),
type: 'Free'
}, {
providerTester: new ProviderTester(
new MyMemoryProvider(process.env.MYMEMORY_API_KEY)
),
type: 'Registered'
}]

itParam<ProviderTesterWrapper>(
'[${value.type}] should get correct translation',
fixture,
async ({ providerTester }: ProviderTesterWrapper) =>
providerTester.positive({
text: 'Evening', lang: 'en|pt', expected: 'NOITE'
})
)

itParam<ProviderTesterWrapper>(
'[${value.type}] should fail because of invalid lang',
fixture,
async ({ providerTester }: ProviderTesterWrapper) =>
providerTester.negative()
)

test('should fail because of invalid lang', async () => {
const provider: ProviderBase = new MyMemoryProvider()
try {
await provider.translate('Evening', 'abc123')
} catch (e) {
expect(e).toBeTruthy()
return
}
fail()
})
// itParam<string | undefined>('should get correct translation',
// [undefined, process.env.MYMEMORY_API_KEY], async (apiKey) => {
// const provider: ProviderBase = new MyMemoryProvider(apiKey)
// const translations = await provider.translate('Evening', 'en|pt')
// expect(translations.length).toBeGreaterThan(0)
// expect(translations[0]).toEqual('NOITE')
// })
//
// test('should fail because of invalid lang', async () => {
// const provider: ProviderBase = new MyMemoryProvider()
// try {
// await provider.translate('Evening', 'abc123')
// } catch (e) {
// expect(e).toBeTruthy()
// return
// }
// fail()
// })
})
Loading

0 comments on commit bf2338d

Please sign in to comment.