Moves pkg/kubectl/util/i18n to staging
Kubernetes-commit: 70984d83858eef3c9c7d046f84d45c53aead673a
This commit is contained in:
parent
a3f4769375
commit
c1971f30ff
18
go.mod
18
go.mod
|
@ -7,6 +7,7 @@ go 1.12
|
||||||
require (
|
require (
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
|
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
|
||||||
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd
|
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd
|
||||||
|
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5
|
||||||
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0
|
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0
|
||||||
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d
|
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d
|
||||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de
|
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de
|
||||||
|
@ -19,10 +20,10 @@ require (
|
||||||
github.com/spf13/pflag v1.0.3
|
github.com/spf13/pflag v1.0.3
|
||||||
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f
|
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f
|
||||||
gotest.tools v2.2.0+incompatible // indirect
|
gotest.tools v2.2.0+incompatible // indirect
|
||||||
k8s.io/api v0.0.0-20190726022912-69e1bce1dad5
|
k8s.io/api v0.0.0
|
||||||
k8s.io/apimachinery v0.0.0-20190726022757-641a75999153
|
k8s.io/apimachinery v0.0.0
|
||||||
k8s.io/cli-runtime v0.0.0-20190726024606-74a61cd71909
|
k8s.io/cli-runtime v0.0.0
|
||||||
k8s.io/client-go v0.0.0-20190726023111-a9c895e7f2ac
|
k8s.io/client-go v0.0.0
|
||||||
k8s.io/klog v0.3.1
|
k8s.io/klog v0.3.1
|
||||||
k8s.io/utils v0.0.0-20190607212802-c55fbcfc754a
|
k8s.io/utils v0.0.0-20190607212802-c55fbcfc754a
|
||||||
)
|
)
|
||||||
|
@ -34,8 +35,9 @@ replace (
|
||||||
golang.org/x/sys => golang.org/x/sys v0.0.0-20190209173611-3b5209105503
|
golang.org/x/sys => golang.org/x/sys v0.0.0-20190209173611-3b5209105503
|
||||||
golang.org/x/text => golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db
|
golang.org/x/text => golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db
|
||||||
golang.org/x/tools => golang.org/x/tools v0.0.0-20190313210603-aa82965741a9
|
golang.org/x/tools => golang.org/x/tools v0.0.0-20190313210603-aa82965741a9
|
||||||
k8s.io/api => k8s.io/api v0.0.0-20190726022912-69e1bce1dad5
|
k8s.io/api => ../api
|
||||||
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20190726022757-641a75999153
|
k8s.io/apimachinery => ../apimachinery
|
||||||
k8s.io/cli-runtime => k8s.io/cli-runtime v0.0.0-20190726024606-74a61cd71909
|
k8s.io/cli-runtime => ../cli-runtime
|
||||||
k8s.io/client-go => k8s.io/client-go v0.0.0-20190725230141-579ad46bdcb9
|
k8s.io/client-go => ../client-go
|
||||||
|
k8s.io/kubectl => ../kubectl
|
||||||
)
|
)
|
||||||
|
|
6
go.sum
6
go.sum
|
@ -13,6 +13,8 @@ github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdko
|
||||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||||
|
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 h1:7aWHqerlJ41y6FOsEUvknqgXnGmJyJSbjhAWq5pO4F8=
|
||||||
|
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
|
||||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||||
|
@ -181,10 +183,6 @@ gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||||
k8s.io/api v0.0.0-20190726022912-69e1bce1dad5/go.mod h1:V6cpJ9D7WqSy0wqcE096gcbj+W//rshgQgmj1Shdwi8=
|
|
||||||
k8s.io/apimachinery v0.0.0-20190726022757-641a75999153/go.mod h1:eXR4ljjmbwK6Ng0PKsXRySPXnTUy/qBUa6kPDeckhQ0=
|
|
||||||
k8s.io/cli-runtime v0.0.0-20190726024606-74a61cd71909/go.mod h1:bk/fSEmINmKG2jHCCbqbXmwEJgE6kHVMkOC1U9dclzo=
|
|
||||||
k8s.io/client-go v0.0.0-20190725230141-579ad46bdcb9/go.mod h1:ncT9fCvHnM5BUiZs0RCf9vAEqRrRoJtR2sZ2evompEU=
|
|
||||||
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||||
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||||
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,149 @@
|
||||||
|
/*
|
||||||
|
Copyright 2016 The Kubernetes Authors.
|
||||||
|
|
||||||
|
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 i18n
|
||||||
|
|
||||||
|
import (
|
||||||
|
"archive/zip"
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"k8s.io/kubectl/pkg/generated"
|
||||||
|
|
||||||
|
"github.com/chai2010/gettext-go/gettext"
|
||||||
|
"k8s.io/klog"
|
||||||
|
)
|
||||||
|
|
||||||
|
var knownTranslations = map[string][]string{
|
||||||
|
"kubectl": {
|
||||||
|
"default",
|
||||||
|
"en_US",
|
||||||
|
"fr_FR",
|
||||||
|
"zh_CN",
|
||||||
|
"ja_JP",
|
||||||
|
"zh_TW",
|
||||||
|
"it_IT",
|
||||||
|
"de_DE",
|
||||||
|
"ko_KR",
|
||||||
|
},
|
||||||
|
// only used for unit tests.
|
||||||
|
"test": {
|
||||||
|
"default",
|
||||||
|
"en_US",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadSystemLanguage() string {
|
||||||
|
// Implements the following locale priority order: LC_ALL, LC_MESSAGES, LANG
|
||||||
|
// Similarly to: https://www.gnu.org/software/gettext/manual/html_node/Locale-Environment-Variables.html
|
||||||
|
langStr := os.Getenv("LC_ALL")
|
||||||
|
if langStr == "" {
|
||||||
|
langStr = os.Getenv("LC_MESSAGES")
|
||||||
|
}
|
||||||
|
if langStr == "" {
|
||||||
|
langStr = os.Getenv("LANG")
|
||||||
|
}
|
||||||
|
|
||||||
|
if langStr == "" {
|
||||||
|
klog.V(3).Infof("Couldn't find the LC_ALL, LC_MESSAGES or LANG environment variables, defaulting to en_US")
|
||||||
|
return "default"
|
||||||
|
}
|
||||||
|
pieces := strings.Split(langStr, ".")
|
||||||
|
if len(pieces) != 2 {
|
||||||
|
klog.V(3).Infof("Unexpected system language (%s), defaulting to en_US", langStr)
|
||||||
|
return "default"
|
||||||
|
}
|
||||||
|
return pieces[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
func findLanguage(root string, getLanguageFn func() string) string {
|
||||||
|
langStr := getLanguageFn()
|
||||||
|
|
||||||
|
translations := knownTranslations[root]
|
||||||
|
if translations != nil {
|
||||||
|
for ix := range translations {
|
||||||
|
if translations[ix] == langStr {
|
||||||
|
return langStr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
klog.V(3).Infof("Couldn't find translations for %s, using default", langStr)
|
||||||
|
return "default"
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadTranslations loads translation files. getLanguageFn should return a language
|
||||||
|
// string (e.g. 'en-US'). If getLanguageFn is nil, then the loadSystemLanguage function
|
||||||
|
// is used, which uses the 'LANG' environment variable.
|
||||||
|
func LoadTranslations(root string, getLanguageFn func() string) error {
|
||||||
|
if getLanguageFn == nil {
|
||||||
|
getLanguageFn = loadSystemLanguage
|
||||||
|
}
|
||||||
|
|
||||||
|
langStr := findLanguage(root, getLanguageFn)
|
||||||
|
translationFiles := []string{
|
||||||
|
fmt.Sprintf("%s/%s/LC_MESSAGES/k8s.po", root, langStr),
|
||||||
|
fmt.Sprintf("%s/%s/LC_MESSAGES/k8s.mo", root, langStr),
|
||||||
|
}
|
||||||
|
|
||||||
|
klog.V(3).Infof("Setting language to %s", langStr)
|
||||||
|
// TODO: list the directory and load all files.
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
w := zip.NewWriter(buf)
|
||||||
|
|
||||||
|
// Make sure to check the error on Close.
|
||||||
|
for _, file := range translationFiles {
|
||||||
|
filename := "translations/" + file
|
||||||
|
f, err := w.Create(file)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
data, err := generated.Asset(filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := f.Write(data); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := w.Close(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
gettext.BindTextdomain("k8s", root+".zip", buf.Bytes())
|
||||||
|
gettext.Textdomain("k8s")
|
||||||
|
gettext.SetLocale(langStr)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// T translates a string, possibly substituting arguments into it along
|
||||||
|
// the way. If len(args) is > 0, args1 is assumed to be the plural value
|
||||||
|
// and plural translation is used.
|
||||||
|
func T(defaultValue string, args ...int) string {
|
||||||
|
if len(args) == 0 {
|
||||||
|
return gettext.PGettext("", defaultValue)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf(gettext.PNGettext("", defaultValue, defaultValue+".plural", args[0]),
|
||||||
|
args[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Errorf produces an error with a translated error string.
|
||||||
|
// Substitution is performed via the `T` function above, following
|
||||||
|
// the same rules.
|
||||||
|
func Errorf(defaultValue string, args ...int) error {
|
||||||
|
return errors.New(T(defaultValue, args...))
|
||||||
|
}
|
|
@ -0,0 +1,157 @@
|
||||||
|
/*
|
||||||
|
Copyright 2016 The Kubernetes Authors.
|
||||||
|
|
||||||
|
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 i18n
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
var knownTestLocale = "en_US.UTF-8"
|
||||||
|
|
||||||
|
func TestTranslation(t *testing.T) {
|
||||||
|
err := LoadTranslations("test", func() string { return "default" })
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
result := T("test_string")
|
||||||
|
if result != "foo" {
|
||||||
|
t.Errorf("expected: %s, saw: %s", "foo", result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTranslationPlural(t *testing.T) {
|
||||||
|
err := LoadTranslations("test", func() string { return "default" })
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
result := T("test_plural", 3)
|
||||||
|
if result != "there were 3 items" {
|
||||||
|
t.Errorf("expected: %s, saw: %s", "there were 3 items", result)
|
||||||
|
}
|
||||||
|
|
||||||
|
result = T("test_plural", 1)
|
||||||
|
if result != "there was 1 item" {
|
||||||
|
t.Errorf("expected: %s, saw: %s", "there was 1 item", result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTranslationUsingEnvVar(t *testing.T) {
|
||||||
|
// We must backup and restore env vars before setting test values in tests
|
||||||
|
// othervise we are risking to break other tests/test cases
|
||||||
|
// which rely on the same env vars
|
||||||
|
envVarsToBackup := []string{"LC_MESSAGES", "LANG", "LC_ALL"}
|
||||||
|
expectedStrEnUSLocale := "baz"
|
||||||
|
expectedStrFallback := "foo"
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
setenvFn func()
|
||||||
|
expectedStr string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Only LC_ALL is set",
|
||||||
|
setenvFn: func() { os.Setenv("LC_ALL", knownTestLocale) },
|
||||||
|
expectedStr: expectedStrEnUSLocale,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Only LC_MESSAGES is set",
|
||||||
|
setenvFn: func() { os.Setenv("LC_MESSAGES", knownTestLocale) },
|
||||||
|
expectedStr: expectedStrEnUSLocale,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Only LANG",
|
||||||
|
setenvFn: func() { os.Setenv("LANG", knownTestLocale) },
|
||||||
|
expectedStr: expectedStrEnUSLocale,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "LC_MESSAGES overrides LANG",
|
||||||
|
setenvFn: func() {
|
||||||
|
os.Setenv("LANG", "be_BY.UTF-8") // Unknown locale
|
||||||
|
os.Setenv("LC_MESSAGES", knownTestLocale)
|
||||||
|
},
|
||||||
|
expectedStr: expectedStrEnUSLocale,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "LC_ALL overrides LANG",
|
||||||
|
setenvFn: func() {
|
||||||
|
os.Setenv("LANG", "be_BY.UTF-8") // Unknown locale
|
||||||
|
os.Setenv("LC_ALL", knownTestLocale)
|
||||||
|
},
|
||||||
|
expectedStr: expectedStrEnUSLocale,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "LC_ALL overrides LC_MESSAGES",
|
||||||
|
setenvFn: func() {
|
||||||
|
os.Setenv("LC_MESSAGES", "be_BY.UTF-8") // Unknown locale
|
||||||
|
os.Setenv("LC_ALL", knownTestLocale)
|
||||||
|
},
|
||||||
|
expectedStr: expectedStrEnUSLocale,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Unknown locale in LANG",
|
||||||
|
setenvFn: func() { os.Setenv("LANG", "be_BY.UTF-8") },
|
||||||
|
expectedStr: expectedStrFallback,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Unknown locale in LC_MESSAGES",
|
||||||
|
setenvFn: func() { os.Setenv("LC_MESSAGES", "be_BY.UTF-8") },
|
||||||
|
expectedStr: expectedStrFallback,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Unknown locale in LC_ALL",
|
||||||
|
setenvFn: func() { os.Setenv("LC_ALL", "be_BY.UTF-8") },
|
||||||
|
expectedStr: expectedStrFallback,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Invalid env var",
|
||||||
|
setenvFn: func() { os.Setenv("LC_MESSAGES", "fake.locale.UTF-8") },
|
||||||
|
expectedStr: expectedStrFallback,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "No env vars",
|
||||||
|
setenvFn: func() {},
|
||||||
|
expectedStr: expectedStrFallback,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
for _, envVar := range envVarsToBackup {
|
||||||
|
if envVarValue := os.Getenv(envVar); envVarValue != "" {
|
||||||
|
os.Unsetenv(envVar)
|
||||||
|
// Restore env var at the end
|
||||||
|
defer func() { os.Setenv(envVar, envVarValue) }()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test.setenvFn()
|
||||||
|
|
||||||
|
err := LoadTranslations("test", nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
result := T("test_string")
|
||||||
|
if result != test.expectedStr {
|
||||||
|
t.Errorf("expected: %s, saw: %s", test.expectedStr, result)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue