|
- // Copyright 2016 Google LLC
- //
- // 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.
-
- package translate
-
- import (
- "fmt"
- "io/ioutil"
- "log"
- "net/http"
- "net/url"
- "os"
- "strings"
- "sync"
- "testing"
-
- "cloud.google.com/go/internal/testutil"
-
- "golang.org/x/net/context"
- "golang.org/x/text/language"
- "google.golang.org/api/option"
- )
-
- var (
- once sync.Once
- authOpt option.ClientOption
- )
-
- func initTest(ctx context.Context, t *testing.T) *Client {
- if testing.Short() {
- t.Skip("integration tests skipped in short mode")
- }
- once.Do(func() { authOpt = authOption() })
- if authOpt == nil {
- t.Skip("Integration tests skipped. See CONTRIBUTING.md for details")
- }
- client, err := NewClient(ctx, authOpt)
- if err != nil {
- t.Fatalf("NewClient: %v", err)
- }
- return client
- }
-
- func authOption() option.ClientOption {
- ts := testutil.TokenSource(context.Background(), Scope)
- if ts != nil {
- log.Println("authenticating via OAuth2")
- return option.WithTokenSource(ts)
- }
- apiKey := os.Getenv("GCLOUD_TESTS_API_KEY")
- if apiKey != "" {
- log.Println("authenticating with API key")
- return option.WithAPIKey(apiKey)
- }
- return nil
- }
-
- type fakeTransport struct {
- req *http.Request
- }
-
- func (t *fakeTransport) RoundTrip(req *http.Request) (*http.Response, error) {
- t.req = req
- return &http.Response{
- Status: fmt.Sprintf("%d OK", http.StatusOK),
- StatusCode: http.StatusOK,
- Body: ioutil.NopCloser(strings.NewReader("{}")),
- }, nil
- }
-
- func TestTranslateURL(t *testing.T) {
- // The translate API has all inputs in the URL.
- // Make sure we generate the right one.
- ctx := context.Background()
- ft := &fakeTransport{}
- c, err := NewClient(ctx, option.WithHTTPClient(&http.Client{Transport: ft}))
- if err != nil {
- t.Fatal(err)
- }
- for _, test := range []struct {
- target language.Tag
- inputs []string
- opts *Options
- want url.Values
- }{
- {language.Spanish, []string{"text"}, nil, url.Values{
- "q": []string{"text"},
- "target": []string{"es"},
- }},
- {language.English, []string{"text"}, &Options{}, url.Values{
- "q": []string{"text"},
- "target": []string{"en"},
- }},
- {language.Turkish, []string{"t1", "t2"}, nil, url.Values{
- "q": []string{"t1", "t2"},
- "target": []string{"tr"},
- }},
- {language.English, []string{"text"}, &Options{Source: language.French},
- url.Values{
- "q": []string{"text"},
- "source": []string{"fr"},
- "target": []string{"en"},
- },
- },
- {language.English, []string{"text"}, &Options{Source: language.French, Format: HTML}, url.Values{
- "q": []string{"text"},
- "source": []string{"fr"},
- "format": []string{"html"},
- "target": []string{"en"},
- }},
- } {
- _, err = c.Translate(ctx, test.inputs, test.target, test.opts)
- if err != nil {
- t.Fatal(err)
- }
- got := ft.req.URL.Query()
- test.want.Add("alt", "json")
- if !testutil.Equal(got, test.want) {
- t.Errorf("Translate(%s, %v, %+v):\ngot %s\nwant %s",
- test.target, test.inputs, test.opts, got, test.want)
- }
- }
- }
-
- func TestTranslateOneInput(t *testing.T) {
- ctx := context.Background()
- c := initTest(ctx, t)
- defer c.Close()
-
- translate := func(input string, target language.Tag, opts *Options) Translation {
- ts, err := c.Translate(ctx, []string{input}, target, opts)
- if err != nil {
- t.Fatal(err)
- }
- if len(ts) != 1 {
- t.Fatalf("wanted one Translation, got %d", len(ts))
- }
- return ts[0]
- }
-
- for _, test := range []struct {
- input string
- source language.Tag
- output string
- target language.Tag
- }{
- // https://www.youtube.com/watch?v=x1sQkEfAdfY
- {"Le singe est sur la branche", language.French,
- "The monkey is on the branch", language.English},
- {"The cat is on the chair", language.English,
- "Le chat est sur la chaise", language.French},
- } {
- // Provide source and format.
- tr := translate(test.input, test.target, &Options{Source: test.source, Format: Text})
- if got, want := tr.Source, language.Und; got != want {
- t.Errorf("source: got %q, wanted %q", got, want)
- continue
- }
- if got, want := tr.Text, test.output; got != want {
- t.Errorf("text: got %q, want %q", got, want)
- }
- // Omit source; it should be detected.
- tr = translate(test.input, test.target, &Options{Format: Text})
- if got, want := tr.Source, test.source; got != want {
- t.Errorf("source: got %q, wanted %q", got, want)
- continue
- }
- if got, want := tr.Text, test.output; got != want {
- t.Errorf("text: got %q, want %q", got, want)
- }
-
- // Omit format. Defaults to HTML. Still works with plain text.
- tr = translate(test.input, test.target, nil)
- if got, want := tr.Source, test.source; got != want {
- t.Errorf("source: got %q, wanted %q", got, want)
- continue
- }
- if got, want := tr.Text, test.output; got != want {
- t.Errorf("text: got %q, want %q", got, want)
- }
-
- // Add HTML tags to input. They should be in output.
- htmlify := func(s string) string {
- return "<b><i>" + s + "</i></b>"
- }
- tr = translate(htmlify(test.input), test.target, nil)
- if got, want := tr.Text, htmlify(test.output); got != want {
- t.Errorf("html: got %q, want %q", got, want)
- }
- // Using the HTML format behaves the same.
- tr = translate(htmlify(test.input), test.target, &Options{Format: HTML})
- if got, want := tr.Text, htmlify(test.output); got != want {
- t.Errorf("html: got %q, want %q", got, want)
- }
- }
- }
-
- // This tests the beta "nmt" model.
- func TestTranslateModel(t *testing.T) {
- ctx := context.Background()
- c := initTest(ctx, t)
- defer c.Close()
-
- trs, err := c.Translate(ctx, []string{"Hello"}, language.French, &Options{Model: "nmt"})
- if err != nil {
- t.Fatal(err)
- }
- if len(trs) != 1 {
- t.Fatalf("wanted one Translation, got %d", len(trs))
- }
- tr := trs[0]
- if got, want := tr.Text, "Bonjour"; got != want {
- t.Errorf("text: got %q, want %q", got, want)
- }
- if got, want := tr.Model, "nmt"; got != want {
- t.Errorf("model: got %q, want %q", got, want)
- }
- }
-
- func TestTranslateMultipleInputs(t *testing.T) {
- ctx := context.Background()
- c := initTest(ctx, t)
- defer c.Close()
-
- inputs := []string{
- "When you're a Jet, you're a Jet all the way",
- "From your first cigarette to your last dying day",
- "When you're a Jet if the spit hits the fan",
- "You got brothers around, you're a family man",
- }
- ts, err := c.Translate(ctx, inputs, language.French, nil)
- if err != nil {
- t.Fatal(err)
- }
- if got, want := len(ts), len(inputs); got != want {
- t.Fatalf("got %d Translations, wanted %d", got, want)
- }
- }
-
- func TestTranslateErrors(t *testing.T) {
- ctx := context.Background()
- c := initTest(ctx, t)
- defer c.Close()
-
- for _, test := range []struct {
- ctx context.Context
- target language.Tag
- inputs []string
- opts *Options
- }{
- {ctx, language.English, nil, nil},
- {ctx, language.Und, []string{"input"}, nil},
- {ctx, language.English, []string{}, nil},
- {ctx, language.English, []string{"input"}, &Options{Format: "random"}},
- } {
- _, err := c.Translate(test.ctx, test.inputs, test.target, test.opts)
- if err == nil {
- t.Errorf("%+v: got nil, want error", test)
- }
- }
- }
-
- func TestDetectLanguage(t *testing.T) {
- ctx := context.Background()
- c := initTest(ctx, t)
- defer c.Close()
- ds, err := c.DetectLanguage(ctx, []string{
- "Today is Monday",
- "Aujourd'hui est lundi",
- })
- if err != nil {
- t.Fatal(err)
- }
- if len(ds) != 2 {
- t.Fatalf("got %d detection lists, want 2", len(ds))
- }
- checkDetections(t, ds[0], language.English)
- checkDetections(t, ds[1], language.French)
- }
-
- func checkDetections(t *testing.T, ds []Detection, want language.Tag) {
- for _, d := range ds {
- if d.Language == want {
- return
- }
- }
- t.Errorf("%v: missing %s", ds, want)
- }
-
- // A small subset of the supported languages.
- var supportedLangs = []Language{
- {Name: "Danish", Tag: language.Danish},
- {Name: "English", Tag: language.English},
- {Name: "French", Tag: language.French},
- {Name: "German", Tag: language.German},
- {Name: "Greek", Tag: language.Greek},
- {Name: "Hindi", Tag: language.Hindi},
- {Name: "Hungarian", Tag: language.Hungarian},
- {Name: "Italian", Tag: language.Italian},
- {Name: "Russian", Tag: language.Russian},
- {Name: "Turkish", Tag: language.Turkish},
- }
-
- func TestSupportedLanguages(t *testing.T) {
- ctx := context.Background()
- c := initTest(ctx, t)
- defer c.Close()
- got, err := c.SupportedLanguages(ctx, language.English)
- if err != nil {
- t.Fatal(err)
- }
- want := map[language.Tag]Language{}
- for _, sl := range supportedLangs {
- want[sl.Tag] = sl
- }
- for _, g := range got {
- w, ok := want[g.Tag]
- if !ok {
- continue
- }
- if g != w {
- t.Errorf("got %+v, want %+v", g, w)
- }
- delete(want, g.Tag)
- }
- if len(want) > 0 {
- t.Errorf("missing: %+v", want)
- }
- }
|