summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/nicksnyder/go-i18n/i18n/translation
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/nicksnyder/go-i18n/i18n/translation')
-rw-r--r--vendor/github.com/nicksnyder/go-i18n/i18n/translation/plural_translation.go78
-rw-r--r--vendor/github.com/nicksnyder/go-i18n/i18n/translation/plural_translation_test.go308
-rw-r--r--vendor/github.com/nicksnyder/go-i18n/i18n/translation/single_translation.go57
-rw-r--r--vendor/github.com/nicksnyder/go-i18n/i18n/translation/template.go61
-rw-r--r--vendor/github.com/nicksnyder/go-i18n/i18n/translation/template_test.go146
-rw-r--r--vendor/github.com/nicksnyder/go-i18n/i18n/translation/translation.go83
-rw-r--r--vendor/github.com/nicksnyder/go-i18n/i18n/translation/translation_test.go17
7 files changed, 750 insertions, 0 deletions
diff --git a/vendor/github.com/nicksnyder/go-i18n/i18n/translation/plural_translation.go b/vendor/github.com/nicksnyder/go-i18n/i18n/translation/plural_translation.go
new file mode 100644
index 000000000..4f579d16a
--- /dev/null
+++ b/vendor/github.com/nicksnyder/go-i18n/i18n/translation/plural_translation.go
@@ -0,0 +1,78 @@
+package translation
+
+import (
+ "github.com/nicksnyder/go-i18n/i18n/language"
+)
+
+type pluralTranslation struct {
+ id string
+ templates map[language.Plural]*template
+}
+
+func (pt *pluralTranslation) MarshalInterface() interface{} {
+ return map[string]interface{}{
+ "id": pt.id,
+ "translation": pt.templates,
+ }
+}
+
+func (pt *pluralTranslation) ID() string {
+ return pt.id
+}
+
+func (pt *pluralTranslation) Template(pc language.Plural) *template {
+ return pt.templates[pc]
+}
+
+func (pt *pluralTranslation) UntranslatedCopy() Translation {
+ return &pluralTranslation{pt.id, make(map[language.Plural]*template)}
+}
+
+func (pt *pluralTranslation) Normalize(l *language.Language) Translation {
+ // Delete plural categories that don't belong to this language.
+ for pc := range pt.templates {
+ if _, ok := l.Plurals[pc]; !ok {
+ delete(pt.templates, pc)
+ }
+ }
+ // Create map entries for missing valid categories.
+ for pc := range l.Plurals {
+ if _, ok := pt.templates[pc]; !ok {
+ pt.templates[pc] = mustNewTemplate("")
+ }
+ }
+ return pt
+}
+
+func (pt *pluralTranslation) Backfill(src Translation) Translation {
+ for pc, t := range pt.templates {
+ if t == nil || t.src == "" {
+ pt.templates[pc] = src.Template(language.Other)
+ }
+ }
+ return pt
+}
+
+func (pt *pluralTranslation) Merge(t Translation) Translation {
+ other, ok := t.(*pluralTranslation)
+ if !ok || pt.ID() != t.ID() {
+ return t
+ }
+ for pluralCategory, template := range other.templates {
+ if template != nil && template.src != "" {
+ pt.templates[pluralCategory] = template
+ }
+ }
+ return pt
+}
+
+func (pt *pluralTranslation) Incomplete(l *language.Language) bool {
+ for pc := range l.Plurals {
+ if t := pt.templates[pc]; t == nil || t.src == "" {
+ return true
+ }
+ }
+ return false
+}
+
+var _ = Translation(&pluralTranslation{})
diff --git a/vendor/github.com/nicksnyder/go-i18n/i18n/translation/plural_translation_test.go b/vendor/github.com/nicksnyder/go-i18n/i18n/translation/plural_translation_test.go
new file mode 100644
index 000000000..ea7de7fd9
--- /dev/null
+++ b/vendor/github.com/nicksnyder/go-i18n/i18n/translation/plural_translation_test.go
@@ -0,0 +1,308 @@
+package translation
+
+import (
+ "reflect"
+ "testing"
+
+ "github.com/nicksnyder/go-i18n/i18n/language"
+)
+
+func mustTemplate(t *testing.T, src string) *template {
+ tmpl, err := newTemplate(src)
+ if err != nil {
+ t.Fatal(err)
+ }
+ return tmpl
+}
+
+func pluralTranslationFixture(t *testing.T, id string, pluralCategories ...language.Plural) *pluralTranslation {
+ templates := make(map[language.Plural]*template, len(pluralCategories))
+ for _, pc := range pluralCategories {
+ templates[pc] = mustTemplate(t, string(pc))
+ }
+ return &pluralTranslation{id, templates}
+}
+
+func verifyDeepEqual(t *testing.T, actual, expected interface{}) {
+ if !reflect.DeepEqual(actual, expected) {
+ t.Fatalf("\n%#v\nnot equal to expected value\n%#v", actual, expected)
+ }
+}
+
+func TestPluralTranslationMerge(t *testing.T) {
+ pt := pluralTranslationFixture(t, "id", language.One, language.Other)
+ oneTemplate, otherTemplate := pt.templates[language.One], pt.templates[language.Other]
+
+ pt.Merge(pluralTranslationFixture(t, "id"))
+ verifyDeepEqual(t, pt.templates, map[language.Plural]*template{
+ language.One: oneTemplate,
+ language.Other: otherTemplate,
+ })
+
+ pt2 := pluralTranslationFixture(t, "id", language.One, language.Two)
+ pt.Merge(pt2)
+ verifyDeepEqual(t, pt.templates, map[language.Plural]*template{
+ language.One: pt2.templates[language.One],
+ language.Two: pt2.templates[language.Two],
+ language.Other: otherTemplate,
+ })
+}
+
+/* Test implementations from old idea
+
+func TestCopy(t *testing.T) {
+ ls := &LocalizedString{
+ ID: "id",
+ Translation: testingTemplate(t, "translation {{.Hello}}"),
+ Translations: map[language.Plural]*template{
+ language.One: testingTemplate(t, "plural {{.One}}"),
+ language.Other: testingTemplate(t, "plural {{.Other}}"),
+ },
+ }
+
+ c := ls.Copy()
+ delete(c.Translations, language.One)
+ if _, ok := ls.Translations[language.One]; !ok {
+ t.Errorf("deleting plural translation from copy deleted it from the original")
+ }
+ c.Translations[language.Two] = testingTemplate(t, "plural {{.Two}}")
+ if _, ok := ls.Translations[language.Two]; ok {
+ t.Errorf("adding plural translation to copy added it to the original")
+ }
+}
+
+func TestNormalize(t *testing.T) {
+ oneTemplate := testingTemplate(t, "one {{.One}}")
+ ls := &LocalizedString{
+ Translation: testingTemplate(t, "single {{.Single}}"),
+ Translations: map[language.Plural]*template{
+ language.One: oneTemplate,
+ language.Two: testingTemplate(t, "two {{.Two}}"),
+ },
+ }
+ ls.Normalize(LanguageWithCode("en"))
+ if ls.Translation != nil {
+ t.Errorf("ls.Translation is %#v; expected nil", ls.Translation)
+ }
+ if actual := ls.Translations[language.Two]; actual != nil {
+ t.Errorf("ls.Translation[language.Two] is %#v; expected nil", actual)
+ }
+ if actual := ls.Translations[language.One]; actual != oneTemplate {
+ t.Errorf("ls.Translations[language.One] is %#v; expected %#v", actual, oneTemplate)
+ }
+ if _, ok := ls.Translations[language.Other]; !ok {
+ t.Errorf("ls.Translations[language.Other] shouldn't be empty")
+ }
+}
+
+func TestMergeTranslation(t *testing.T) {
+ ls := &LocalizedString{}
+
+ translation := testingTemplate(t, "one {{.Hello}}")
+ ls.Merge(&LocalizedString{
+ Translation: translation,
+ })
+ if ls.Translation != translation {
+ t.Errorf("expected %#v; got %#v", translation, ls.Translation)
+ }
+
+ ls.Merge(&LocalizedString{})
+ if ls.Translation != translation {
+ t.Errorf("expected %#v; got %#v", translation, ls.Translation)
+ }
+
+ translation = testingTemplate(t, "two {{.Hello}}")
+ ls.Merge(&LocalizedString{
+ Translation: translation,
+ })
+ if ls.Translation != translation {
+ t.Errorf("expected %#v; got %#v", translation, ls.Translation)
+ }
+}
+
+func TestMergeTranslations(t *testing.T) {
+ ls := &LocalizedString{}
+
+ oneTemplate := testingTemplate(t, "one {{.One}}")
+ otherTemplate := testingTemplate(t, "other {{.Other}}")
+ ls.Merge(&LocalizedString{
+ Translations: map[language.Plural]*template{
+ language.One: oneTemplate,
+ language.Other: otherTemplate,
+ },
+ })
+ if actual := ls.Translations[language.One]; actual != oneTemplate {
+ t.Errorf("ls.Translations[language.One] expected %#v; got %#v", oneTemplate, actual)
+ }
+ if actual := ls.Translations[language.Other]; actual != otherTemplate {
+ t.Errorf("ls.Translations[language.Other] expected %#v; got %#v", otherTemplate, actual)
+ }
+
+ ls.Merge(&LocalizedString{
+ Translations: map[language.Plural]*template{},
+ })
+ if actual := ls.Translations[language.One]; actual != oneTemplate {
+ t.Errorf("ls.Translations[language.One] expected %#v; got %#v", oneTemplate, actual)
+ }
+ if actual := ls.Translations[language.Other]; actual != otherTemplate {
+ t.Errorf("ls.Translations[language.Other] expected %#v; got %#v", otherTemplate, actual)
+ }
+
+ twoTemplate := testingTemplate(t, "two {{.Two}}")
+ otherTemplate = testingTemplate(t, "second other {{.Other}}")
+ ls.Merge(&LocalizedString{
+ Translations: map[language.Plural]*template{
+ language.Two: twoTemplate,
+ language.Other: otherTemplate,
+ },
+ })
+ if actual := ls.Translations[language.One]; actual != oneTemplate {
+ t.Errorf("ls.Translations[language.One] expected %#v; got %#v", oneTemplate, actual)
+ }
+ if actual := ls.Translations[language.Two]; actual != twoTemplate {
+ t.Errorf("ls.Translations[language.Two] expected %#v; got %#v", twoTemplate, actual)
+ }
+ if actual := ls.Translations[language.Other]; actual != otherTemplate {
+ t.Errorf("ls.Translations[language.Other] expected %#v; got %#v", otherTemplate, actual)
+ }
+}
+
+func TestMissingTranslations(t *testing.T) {
+ en := LanguageWithCode("en")
+
+ tests := []struct {
+ localizedString *LocalizedString
+ language *Language
+ expected bool
+ }{
+ {
+ &LocalizedString{},
+ en,
+ true,
+ },
+ {
+ &LocalizedString{Translation: testingTemplate(t, "single {{.Single}}")},
+ en,
+ false,
+ },
+ {
+ &LocalizedString{
+ Translation: testingTemplate(t, "single {{.Single}}"),
+ Translations: map[language.Plural]*template{
+ language.One: testingTemplate(t, "one {{.One}}"),
+ }},
+ en,
+ true,
+ },
+ {
+ &LocalizedString{Translations: map[language.Plural]*template{
+ language.One: testingTemplate(t, "one {{.One}}"),
+ }},
+ en,
+ true,
+ },
+ {
+ &LocalizedString{Translations: map[language.Plural]*template{
+ language.One: nil,
+ language.Other: nil,
+ }},
+ en,
+ true,
+ },
+ {
+ &LocalizedString{Translations: map[language.Plural]*template{
+ language.One: testingTemplate(t, ""),
+ language.Other: testingTemplate(t, ""),
+ }},
+ en,
+ true,
+ },
+ {
+ &LocalizedString{Translations: map[language.Plural]*template{
+ language.One: testingTemplate(t, "one {{.One}}"),
+ language.Other: testingTemplate(t, "other {{.Other}}"),
+ }},
+ en,
+ false,
+ },
+ }
+
+ for _, tt := range tests {
+ if actual := tt.localizedString.MissingTranslations(tt.language); actual != tt.expected {
+ t.Errorf("expected %t got %t for %s, %#v",
+ tt.expected, actual, tt.language.code, tt.localizedString)
+ }
+ }
+}
+
+func TestHasTranslations(t *testing.T) {
+ en := LanguageWithCode("en")
+
+ tests := []struct {
+ localizedString *LocalizedString
+ language *Language
+ expected bool
+ }{
+ {
+ &LocalizedString{},
+ en,
+ false,
+ },
+ {
+ &LocalizedString{Translation: testingTemplate(t, "single {{.Single}}")},
+ en,
+ true,
+ },
+ {
+ &LocalizedString{
+ Translation: testingTemplate(t, "single {{.Single}}"),
+ Translations: map[language.Plural]*template{}},
+ en,
+ false,
+ },
+ {
+ &LocalizedString{Translations: map[language.Plural]*template{
+ language.One: testingTemplate(t, "one {{.One}}"),
+ }},
+ en,
+ true,
+ },
+ {
+ &LocalizedString{Translations: map[language.Plural]*template{
+ language.Two: testingTemplate(t, "two {{.Two}}"),
+ }},
+ en,
+ false,
+ },
+ {
+ &LocalizedString{Translations: map[language.Plural]*template{
+ language.One: nil,
+ }},
+ en,
+ false,
+ },
+ {
+ &LocalizedString{Translations: map[language.Plural]*template{
+ language.One: testingTemplate(t, ""),
+ }},
+ en,
+ false,
+ },
+ }
+
+ for _, tt := range tests {
+ if actual := tt.localizedString.HasTranslations(tt.language); actual != tt.expected {
+ t.Errorf("expected %t got %t for %s, %#v",
+ tt.expected, actual, tt.language.code, tt.localizedString)
+ }
+ }
+}
+
+func testingTemplate(t *testing.T, src string) *template {
+ tmpl, err := newTemplate(src)
+ if err != nil {
+ t.Fatal(err)
+ }
+ return tmpl
+}
+*/
diff --git a/vendor/github.com/nicksnyder/go-i18n/i18n/translation/single_translation.go b/vendor/github.com/nicksnyder/go-i18n/i18n/translation/single_translation.go
new file mode 100644
index 000000000..1010e5947
--- /dev/null
+++ b/vendor/github.com/nicksnyder/go-i18n/i18n/translation/single_translation.go
@@ -0,0 +1,57 @@
+package translation
+
+import (
+ "github.com/nicksnyder/go-i18n/i18n/language"
+)
+
+type singleTranslation struct {
+ id string
+ template *template
+}
+
+func (st *singleTranslation) MarshalInterface() interface{} {
+ return map[string]interface{}{
+ "id": st.id,
+ "translation": st.template,
+ }
+}
+
+func (st *singleTranslation) ID() string {
+ return st.id
+}
+
+func (st *singleTranslation) Template(pc language.Plural) *template {
+ return st.template
+}
+
+func (st *singleTranslation) UntranslatedCopy() Translation {
+ return &singleTranslation{st.id, mustNewTemplate("")}
+}
+
+func (st *singleTranslation) Normalize(language *language.Language) Translation {
+ return st
+}
+
+func (st *singleTranslation) Backfill(src Translation) Translation {
+ if st.template == nil || st.template.src == "" {
+ st.template = src.Template(language.Other)
+ }
+ return st
+}
+
+func (st *singleTranslation) Merge(t Translation) Translation {
+ other, ok := t.(*singleTranslation)
+ if !ok || st.ID() != t.ID() {
+ return t
+ }
+ if other.template != nil && other.template.src != "" {
+ st.template = other.template
+ }
+ return st
+}
+
+func (st *singleTranslation) Incomplete(l *language.Language) bool {
+ return st.template == nil || st.template.src == ""
+}
+
+var _ = Translation(&singleTranslation{})
diff --git a/vendor/github.com/nicksnyder/go-i18n/i18n/translation/template.go b/vendor/github.com/nicksnyder/go-i18n/i18n/translation/template.go
new file mode 100644
index 000000000..c8756fa4e
--- /dev/null
+++ b/vendor/github.com/nicksnyder/go-i18n/i18n/translation/template.go
@@ -0,0 +1,61 @@
+package translation
+
+import (
+ "bytes"
+ "encoding"
+ "strings"
+ gotemplate "text/template"
+)
+
+type template struct {
+ tmpl *gotemplate.Template
+ src string
+}
+
+func newTemplate(src string) (*template, error) {
+ var tmpl template
+ err := tmpl.parseTemplate(src)
+ return &tmpl, err
+}
+
+func mustNewTemplate(src string) *template {
+ t, err := newTemplate(src)
+ if err != nil {
+ panic(err)
+ }
+ return t
+}
+
+func (t *template) String() string {
+ return t.src
+}
+
+func (t *template) Execute(args interface{}) string {
+ if t.tmpl == nil {
+ return t.src
+ }
+ var buf bytes.Buffer
+ if err := t.tmpl.Execute(&buf, args); err != nil {
+ return err.Error()
+ }
+ return buf.String()
+}
+
+func (t *template) MarshalText() ([]byte, error) {
+ return []byte(t.src), nil
+}
+
+func (t *template) UnmarshalText(src []byte) error {
+ return t.parseTemplate(string(src))
+}
+
+func (t *template) parseTemplate(src string) (err error) {
+ t.src = src
+ if strings.Contains(src, "{{") {
+ t.tmpl, err = gotemplate.New(src).Parse(src)
+ }
+ return
+}
+
+var _ = encoding.TextMarshaler(&template{})
+var _ = encoding.TextUnmarshaler(&template{})
diff --git a/vendor/github.com/nicksnyder/go-i18n/i18n/translation/template_test.go b/vendor/github.com/nicksnyder/go-i18n/i18n/translation/template_test.go
new file mode 100644
index 000000000..73a923404
--- /dev/null
+++ b/vendor/github.com/nicksnyder/go-i18n/i18n/translation/template_test.go
@@ -0,0 +1,146 @@
+package translation
+
+import (
+ "bytes"
+ "fmt"
+ //"launchpad.net/goyaml"
+ "testing"
+ gotemplate "text/template"
+)
+
+func TestNilTemplate(t *testing.T) {
+ expected := "hello"
+ tmpl := &template{
+ tmpl: nil,
+ src: expected,
+ }
+ if actual := tmpl.Execute(nil); actual != expected {
+ t.Errorf("Execute(nil) returned %s; expected %s", actual, expected)
+ }
+}
+
+func TestMarshalText(t *testing.T) {
+ tmpl := &template{
+ tmpl: gotemplate.Must(gotemplate.New("id").Parse("this is a {{.foo}} template")),
+ src: "boom",
+ }
+ expectedBuf := []byte(tmpl.src)
+ if buf, err := tmpl.MarshalText(); !bytes.Equal(buf, expectedBuf) || err != nil {
+ t.Errorf("MarshalText() returned %#v, %#v; expected %#v, nil", buf, err, expectedBuf)
+ }
+}
+
+func TestUnmarshalText(t *testing.T) {
+ tmpl := &template{}
+ tmpl.UnmarshalText([]byte("hello {{.World}}"))
+ result := tmpl.Execute(map[string]string{
+ "World": "world!",
+ })
+ expected := "hello world!"
+ if result != expected {
+ t.Errorf("expected %#v; got %#v", expected, result)
+ }
+}
+
+/*
+func TestYAMLMarshal(t *testing.T) {
+ src := "hello {{.World}}"
+ tmpl, err := newTemplate(src)
+ if err != nil {
+ t.Fatal(err)
+ }
+ buf, err := goyaml.Marshal(tmpl)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !bytes.Equal(buf, []byte(src)) {
+ t.Fatalf(`expected "%s"; got "%s"`, src, buf)
+ }
+}
+
+func TestYAMLUnmarshal(t *testing.T) {
+ buf := []byte(`Tmpl: "hello"`)
+
+ var out struct {
+ Tmpl *template
+ }
+ var foo map[string]string
+ if err := goyaml.Unmarshal(buf, &foo); err != nil {
+ t.Fatal(err)
+ }
+ if out.Tmpl == nil {
+ t.Fatalf("out.Tmpl was nil")
+ }
+ if out.Tmpl.tmpl == nil {
+ t.Fatalf("out.Tmpl.tmpl was nil")
+ }
+ if expected := "hello {{.World}}"; out.Tmpl.src != expected {
+ t.Fatalf("expected %s; got %s", expected, out.Tmpl.src)
+ }
+}
+
+func TestGetYAML(t *testing.T) {
+ src := "hello"
+ tmpl := &template{
+ tmpl: nil,
+ src: src,
+ }
+ if tag, value := tmpl.GetYAML(); tag != "" || value != src {
+ t.Errorf("GetYAML() returned (%#v, %#v); expected (%#v, %#v)", tag, value, "", src)
+ }
+}
+
+func TestSetYAML(t *testing.T) {
+ tmpl := &template{}
+ tmpl.SetYAML("tagDoesntMatter", "hello {{.World}}")
+ result := tmpl.Execute(map[string]string{
+ "World": "world!",
+ })
+ expected := "hello world!"
+ if result != expected {
+ t.Errorf("expected %#v; got %#v", expected, result)
+ }
+}
+*/
+
+func BenchmarkExecuteNilTemplate(b *testing.B) {
+ template := &template{src: "hello world"}
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ template.Execute(nil)
+ }
+}
+
+func BenchmarkExecuteHelloWorldTemplate(b *testing.B) {
+ template, err := newTemplate("hello world")
+ if err != nil {
+ b.Fatal(err)
+ }
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ template.Execute(nil)
+ }
+}
+
+// Executing a simple template like this is ~6x slower than Sprintf
+// but it is still only a few microseconds which should be sufficiently fast.
+// The benefit is that we have nice semantic tags in the translation.
+func BenchmarkExecuteHelloNameTemplate(b *testing.B) {
+ template, err := newTemplate("hello {{.Name}}")
+ if err != nil {
+ b.Fatal(err)
+ }
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ template.Execute(map[string]string{
+ "Name": "Nick",
+ })
+ }
+}
+
+func BenchmarkSprintf(b *testing.B) {
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ fmt.Sprintf("hello %s", "nick")
+ }
+}
diff --git a/vendor/github.com/nicksnyder/go-i18n/i18n/translation/translation.go b/vendor/github.com/nicksnyder/go-i18n/i18n/translation/translation.go
new file mode 100644
index 000000000..fa93180b8
--- /dev/null
+++ b/vendor/github.com/nicksnyder/go-i18n/i18n/translation/translation.go
@@ -0,0 +1,83 @@
+// Package translation defines the interface for a translation.
+package translation
+
+import (
+ "fmt"
+
+ "github.com/nicksnyder/go-i18n/i18n/language"
+)
+
+// Translation is the interface that represents a translated string.
+type Translation interface {
+ // MarshalInterface returns the object that should be used
+ // to serialize the translation.
+ MarshalInterface() interface{}
+ ID() string
+ Template(language.Plural) *template
+ UntranslatedCopy() Translation
+ Normalize(language *language.Language) Translation
+ Backfill(src Translation) Translation
+ Merge(Translation) Translation
+ Incomplete(l *language.Language) bool
+}
+
+// SortableByID implements sort.Interface for a slice of translations.
+type SortableByID []Translation
+
+func (a SortableByID) Len() int { return len(a) }
+func (a SortableByID) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+func (a SortableByID) Less(i, j int) bool { return a[i].ID() < a[j].ID() }
+
+// NewTranslation reflects on data to create a new Translation.
+//
+// data["id"] must be a string and data["translation"] must be either a string
+// for a non-plural translation or a map[string]interface{} for a plural translation.
+func NewTranslation(data map[string]interface{}) (Translation, error) {
+ id, ok := data["id"].(string)
+ if !ok {
+ return nil, fmt.Errorf(`missing "id" key`)
+ }
+ var pluralObject map[string]interface{}
+ switch translation := data["translation"].(type) {
+ case string:
+ tmpl, err := newTemplate(translation)
+ if err != nil {
+ return nil, err
+ }
+ return &singleTranslation{id, tmpl}, nil
+ case map[interface{}]interface{}:
+ // The YAML parser uses interface{} keys so we first convert them to string keys.
+ pluralObject = make(map[string]interface{})
+ for k, v := range translation {
+ kStr, ok := k.(string)
+ if !ok {
+ return nil, fmt.Errorf(`invalid plural category type %T; expected string`, k)
+ }
+ pluralObject[kStr] = v
+ }
+ case map[string]interface{}:
+ pluralObject = translation
+ case nil:
+ return nil, fmt.Errorf(`missing "translation" key`)
+ default:
+ return nil, fmt.Errorf(`unsupported type for "translation" key %T`, translation)
+ }
+
+ templates := make(map[language.Plural]*template, len(pluralObject))
+ for k, v := range pluralObject {
+ pc, err := language.NewPlural(k)
+ if err != nil {
+ return nil, err
+ }
+ str, ok := v.(string)
+ if !ok {
+ return nil, fmt.Errorf(`plural category "%s" has value of type %T; expected string`, pc, v)
+ }
+ tmpl, err := newTemplate(str)
+ if err != nil {
+ return nil, err
+ }
+ templates[pc] = tmpl
+ }
+ return &pluralTranslation{id, templates}, nil
+}
diff --git a/vendor/github.com/nicksnyder/go-i18n/i18n/translation/translation_test.go b/vendor/github.com/nicksnyder/go-i18n/i18n/translation/translation_test.go
new file mode 100644
index 000000000..7380d5a6f
--- /dev/null
+++ b/vendor/github.com/nicksnyder/go-i18n/i18n/translation/translation_test.go
@@ -0,0 +1,17 @@
+package translation
+
+import (
+ "sort"
+ "testing"
+)
+
+// Check this here to avoid unnecessary import of sort package.
+var _ = sort.Interface(make(SortableByID, 0, 0))
+
+func TestNewSingleTranslation(t *testing.T) {
+ t.Skipf("not implemented")
+}
+
+func TestNewPluralTranslation(t *testing.T) {
+ t.Skipf("not implemented")
+}