summaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/text/message/catalog/catalog_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/text/message/catalog/catalog_test.go')
-rw-r--r--vendor/golang.org/x/text/message/catalog/catalog_test.go296
1 files changed, 296 insertions, 0 deletions
diff --git a/vendor/golang.org/x/text/message/catalog/catalog_test.go b/vendor/golang.org/x/text/message/catalog/catalog_test.go
new file mode 100644
index 0000000..08bfdc7
--- /dev/null
+++ b/vendor/golang.org/x/text/message/catalog/catalog_test.go
@@ -0,0 +1,296 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package catalog
+
+import (
+ "bytes"
+ "path"
+ "reflect"
+ "strings"
+ "testing"
+
+ "golang.org/x/text/internal/catmsg"
+ "golang.org/x/text/language"
+)
+
+type entry struct {
+ tag, key string
+ msg interface{}
+}
+
+func langs(s string) []language.Tag {
+ t, _, _ := language.ParseAcceptLanguage(s)
+ return t
+}
+
+type testCase struct {
+ desc string
+ cat []entry
+ lookup []entry
+ fallback string
+ match []string
+ tags []language.Tag
+}
+
+var testCases = []testCase{{
+ desc: "empty catalog",
+ lookup: []entry{
+ {"en", "key", ""},
+ {"en", "", ""},
+ {"nl", "", ""},
+ },
+ match: []string{
+ "gr -> und",
+ "en-US -> und",
+ "af -> und",
+ },
+ tags: nil, // not an empty list.
+}, {
+ desc: "one entry",
+ cat: []entry{
+ {"en", "hello", "Hello!"},
+ },
+ lookup: []entry{
+ {"und", "hello", ""},
+ {"nl", "hello", ""},
+ {"en", "hello", "Hello!"},
+ {"en-US", "hello", "Hello!"},
+ {"en-GB", "hello", "Hello!"},
+ {"en-oxendict", "hello", "Hello!"},
+ {"en-oxendict-u-ms-metric", "hello", "Hello!"},
+ },
+ match: []string{
+ "gr -> en",
+ "en-US -> en",
+ },
+ tags: langs("en"),
+}, {
+ desc: "hierarchical languages",
+ cat: []entry{
+ {"en", "hello", "Hello!"},
+ {"en-GB", "hello", "Hellø!"},
+ {"en-US", "hello", "Howdy!"},
+ {"en", "greetings", "Greetings!"},
+ {"gsw", "hello", "Grüetzi!"},
+ },
+ lookup: []entry{
+ {"und", "hello", ""},
+ {"nl", "hello", ""},
+ {"en", "hello", "Hello!"},
+ {"en-US", "hello", "Howdy!"},
+ {"en-GB", "hello", "Hellø!"},
+ {"en-oxendict", "hello", "Hello!"},
+ {"en-US-oxendict-u-ms-metric", "hello", "Howdy!"},
+
+ {"und", "greetings", ""},
+ {"nl", "greetings", ""},
+ {"en", "greetings", "Greetings!"},
+ {"en-US", "greetings", "Greetings!"},
+ {"en-GB", "greetings", "Greetings!"},
+ {"en-oxendict", "greetings", "Greetings!"},
+ {"en-US-oxendict-u-ms-metric", "greetings", "Greetings!"},
+ },
+ fallback: "gsw",
+ match: []string{
+ "gr -> gsw",
+ "en-US -> en-US",
+ },
+ tags: langs("gsw, en, en-GB, en-US"),
+}, {
+ desc: "variables",
+ cat: []entry{
+ {"en", "hello %s", []Message{
+ Var("person", String("Jane")),
+ String("Hello ${person}!"),
+ }},
+ {"en", "hello error", []Message{
+ Var("person", String("Jane")),
+ noMatchMessage{}, // trigger sequence path.
+ String("Hello ${person."),
+ }},
+ {"en", "fallback to var value", []Message{
+ Var("you", noMatchMessage{}, noMatchMessage{}),
+ String("Hello ${you}."),
+ }},
+ {"en", "scopes", []Message{
+ Var("person1", String("Mark")),
+ Var("person2", String("Jane")),
+ Var("couple",
+ Var("person1", String("Joe")),
+ String("${person1} and ${person2}")),
+ String("Hello ${couple}."),
+ }},
+ {"en", "missing var", String("Hello ${missing}.")},
+ },
+ lookup: []entry{
+ {"en", "hello %s", "Hello Jane!"},
+ {"en", "hello error", "Hello $!(MISSINGBRACE)"},
+ {"en", "fallback to var value", "Hello you."},
+ {"en", "scopes", "Hello Joe and Jane."},
+ {"en", "missing var", "Hello missing."},
+ },
+ tags: langs("en"),
+}, {
+ desc: "macros",
+ cat: []entry{
+ {"en", "macro1", String("Hello ${macro1(1)}.")},
+ {"en", "macro2", String("Hello ${ macro1(2) }!")},
+ {"en", "macroWS", String("Hello ${ macro1( 2 ) }!")},
+ {"en", "missing", String("Hello ${ missing(1 }.")},
+ {"en", "badnum", String("Hello ${ badnum(1b) }.")},
+ {"en", "undefined", String("Hello ${ undefined(1) }.")},
+ {"en", "macroU", String("Hello ${ macroU(2) }!")},
+ },
+ lookup: []entry{
+ {"en", "macro1", "Hello Joe."},
+ {"en", "macro2", "Hello Joe!"},
+ {"en-US", "macroWS", "Hello Joe!"},
+ {"en-NL", "missing", "Hello $!(MISSINGPAREN)."},
+ {"en", "badnum", "Hello $!(BADNUM)."},
+ {"en", "undefined", "Hello undefined."},
+ {"en", "macroU", "Hello macroU!"},
+ },
+ tags: langs("en"),
+}}
+
+func setMacros(b *Builder) {
+ b.SetMacro(language.English, "macro1", String("Joe"))
+ b.SetMacro(language.Und, "macro2", String("${macro1(1)}"))
+ b.SetMacro(language.English, "macroU", noMatchMessage{})
+}
+
+type buildFunc func(t *testing.T, tc testCase) Catalog
+
+func initBuilder(t *testing.T, tc testCase) Catalog {
+ options := []Option{}
+ if tc.fallback != "" {
+ options = append(options, Fallback(language.MustParse(tc.fallback)))
+ }
+ cat := NewBuilder(options...)
+ for _, e := range tc.cat {
+ tag := language.MustParse(e.tag)
+ switch msg := e.msg.(type) {
+ case string:
+
+ cat.SetString(tag, e.key, msg)
+ case Message:
+ cat.Set(tag, e.key, msg)
+ case []Message:
+ cat.Set(tag, e.key, msg...)
+ }
+ }
+ setMacros(cat)
+ return cat
+}
+
+type dictionary map[string]string
+
+func (d dictionary) Lookup(key string) (data string, ok bool) {
+ data, ok = d[key]
+ return data, ok
+}
+
+func initCatalog(t *testing.T, tc testCase) Catalog {
+ m := map[string]Dictionary{}
+ for _, e := range tc.cat {
+ m[e.tag] = dictionary{}
+ }
+ for _, e := range tc.cat {
+ var msg Message
+ switch x := e.msg.(type) {
+ case string:
+ msg = String(x)
+ case Message:
+ msg = x
+ case []Message:
+ msg = firstInSequence(x)
+ }
+ data, _ := catmsg.Compile(language.MustParse(e.tag), nil, msg)
+ m[e.tag].(dictionary)[e.key] = data
+ }
+ options := []Option{}
+ if tc.fallback != "" {
+ options = append(options, Fallback(language.MustParse(tc.fallback)))
+ }
+ c, err := NewFromMap(m, options...)
+ if err != nil {
+ t.Fatal(err)
+ }
+ // TODO: implement macros for fixed catalogs.
+ b := NewBuilder()
+ setMacros(b)
+ c.(*catalog).macros.index = b.macros.index
+ return c
+}
+
+func TestMatcher(t *testing.T) {
+ test := func(t *testing.T, init buildFunc) {
+ for _, tc := range testCases {
+ for _, s := range tc.match {
+ a := strings.Split(s, "->")
+ t.Run(path.Join(tc.desc, a[0]), func(t *testing.T) {
+ cat := init(t, tc)
+ got, _ := language.MatchStrings(cat.Matcher(), a[0])
+ want := language.MustParse(strings.TrimSpace(a[1]))
+ if got != want {
+ t.Errorf("got %q; want %q", got, want)
+ }
+ })
+ }
+ }
+ }
+ t.Run("Builder", func(t *testing.T) { test(t, initBuilder) })
+ t.Run("Catalog", func(t *testing.T) { test(t, initCatalog) })
+}
+
+func TestCatalog(t *testing.T) {
+ test := func(t *testing.T, init buildFunc) {
+ for _, tc := range testCases {
+ cat := init(t, tc)
+ wantTags := tc.tags
+ if got := cat.Languages(); !reflect.DeepEqual(got, wantTags) {
+ t.Errorf("%s:Languages: got %v; want %v", tc.desc, got, wantTags)
+ }
+
+ for _, e := range tc.lookup {
+ t.Run(path.Join(tc.desc, e.tag, e.key), func(t *testing.T) {
+ tag := language.MustParse(e.tag)
+ buf := testRenderer{}
+ ctx := cat.Context(tag, &buf)
+ want := e.msg.(string)
+ err := ctx.Execute(e.key)
+ gotFound := err != ErrNotFound
+ wantFound := want != ""
+ if gotFound != wantFound {
+ t.Fatalf("err: got %v (%v); want %v", gotFound, err, wantFound)
+ }
+ if got := buf.buf.String(); got != want {
+ t.Errorf("Lookup:\ngot %q\nwant %q", got, want)
+ }
+ })
+ }
+ }
+ }
+ t.Run("Builder", func(t *testing.T) { test(t, initBuilder) })
+ t.Run("Catalog", func(t *testing.T) { test(t, initCatalog) })
+}
+
+type testRenderer struct {
+ buf bytes.Buffer
+}
+
+func (f *testRenderer) Arg(i int) interface{} { return nil }
+func (f *testRenderer) Render(s string) { f.buf.WriteString(s) }
+
+var msgNoMatch = catmsg.Register("no match", func(d *catmsg.Decoder) bool {
+ return false // no match
+})
+
+type noMatchMessage struct{}
+
+func (noMatchMessage) Compile(e *catmsg.Encoder) error {
+ e.EncodeMessageType(msgNoMatch)
+ return catmsg.ErrIncomplete
+}