123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- // 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 plural
- import (
- "fmt"
- "strings"
- "testing"
- "golang.org/x/text/internal/catmsg"
- "golang.org/x/text/language"
- "golang.org/x/text/message/catalog"
- )
- func TestSelect(t *testing.T) {
- lang := language.English
- type test struct {
- arg interface{}
- result string
- err string
- }
- testCases := []struct {
- desc string
- msg catalog.Message
- err string
- tests []test
- }{{
- desc: "basic",
- msg: Selectf(1, "%d", "one", "foo", "other", "bar"),
- tests: []test{
- {arg: 0, result: "bar"},
- {arg: 1, result: "foo"},
- {arg: 2, result: "bar"},
- {arg: opposite(1), result: "bar"},
- {arg: opposite(2), result: "foo"},
- {arg: "unknown", result: "bar"}, // other
- },
- }, {
- desc: "comparisons",
- msg: Selectf(1, "%d",
- "=0", "zero",
- "=1", "one",
- "one", "cannot match", // never matches
- "<5", "<5", // never matches
- "=5", "=5",
- Other, "other"),
- tests: []test{
- {arg: 0, result: "zero"},
- {arg: 1, result: "one"},
- {arg: 2, result: "<5"},
- {arg: 4, result: "<5"},
- {arg: 5, result: "=5"},
- {arg: 6, result: "other"},
- {arg: "unknown", result: "other"},
- },
- }, {
- desc: "fractions",
- msg: Selectf(1, "%.2f", "one", "foo", "other", "bar"),
- tests: []test{
- // fractions are always plural in english
- {arg: 0, result: "bar"},
- {arg: 1, result: "bar"},
- },
- }, {
- desc: "decimal without fractions",
- msg: Selectf(1, "%.0f", "one", "foo", "other", "bar"),
- tests: []test{
- // fractions are always plural in english
- {arg: 0, result: "bar"},
- {arg: 1, result: "foo"},
- },
- }, {
- desc: "scientific",
- msg: Selectf(1, "%.0e", "one", "foo", "other", "bar"),
- tests: []test{
- {arg: 0, result: "bar"},
- {arg: 1, result: "foo"},
- },
- }, {
- desc: "variable",
- msg: Selectf(1, "%.1g", "one", "foo", "other", "bar"),
- tests: []test{
- // fractions are always plural in english
- {arg: 0, result: "bar"},
- {arg: 1, result: "foo"},
- {arg: 2, result: "bar"},
- },
- }, {
- desc: "default",
- msg: Selectf(1, "", "one", "foo", "other", "bar"),
- tests: []test{
- {arg: 0, result: "bar"},
- {arg: 1, result: "foo"},
- {arg: 2, result: "bar"},
- {arg: 1.0, result: "bar"},
- },
- }, {
- desc: "nested",
- msg: Selectf(1, "", "other", Selectf(2, "", "one", "foo", "other", "bar")),
- tests: []test{
- {arg: 0, result: "bar"},
- {arg: 1, result: "foo"},
- {arg: 2, result: "bar"},
- },
- }, {
- desc: "arg unavailable",
- msg: Selectf(100, "%.2f", "one", "foo", "other", "bar"),
- tests: []test{{arg: 1, result: "bar"}},
- }, {
- desc: "no match",
- msg: Selectf(1, "%.2f", "one", "foo"),
- tests: []test{{arg: 0, result: "bar", err: catmsg.ErrNoMatch.Error()}},
- }, {
- desc: "error invalid form",
- err: `invalid plural form "excessive"`,
- msg: Selectf(1, "%d", "excessive", "foo"),
- }, {
- desc: "error form not used by language",
- err: `form "many" not supported for language "en"`,
- msg: Selectf(1, "%d", "many", "foo"),
- }, {
- desc: "error invalid selector",
- err: `selector of type int; want string or Form`,
- msg: Selectf(1, "%d", 1, "foo"),
- }, {
- desc: "error missing message",
- err: `no message defined for selector one`,
- msg: Selectf(1, "%d", "one"),
- }, {
- desc: "error invalid number",
- err: `invalid number in selector "<1.00"`,
- msg: Selectf(1, "%d", "<1.00"),
- }, {
- desc: "error empty selector",
- err: `empty selector`,
- msg: Selectf(1, "%d", "", "foo"),
- }, {
- desc: "error invalid message",
- err: `message of type int; must be string or catalog.Message`,
- msg: Selectf(1, "%d", "one", 3),
- }, {
- desc: "nested error",
- err: `empty selector`,
- msg: Selectf(1, "", "other", Selectf(2, "", "")),
- }}
- for _, tc := range testCases {
- t.Run(tc.desc, func(t *testing.T) {
- data, err := catmsg.Compile(lang, nil, tc.msg)
- chkError(t, err, tc.err)
- for _, tx := range tc.tests {
- t.Run(fmt.Sprint(tx.arg), func(t *testing.T) {
- r := renderer{arg: tx.arg}
- d := catmsg.NewDecoder(lang, &r, nil)
- err := d.Execute(data)
- chkError(t, err, tx.err)
- if r.result != tx.result {
- t.Errorf("got %q; want %q", r.result, tx.result)
- }
- })
- }
- })
- }
- }
- func chkError(t *testing.T, got error, want string) {
- if (got == nil && want != "") ||
- (got != nil && (want == "" || !strings.Contains(got.Error(), want))) {
- t.Fatalf("got %v; want %v", got, want)
- }
- if got != nil {
- t.SkipNow()
- }
- }
- type renderer struct {
- arg interface{}
- result string
- }
- func (r *renderer) Render(s string) { r.result += s }
- func (r *renderer) Arg(i int) interface{} {
- if i > 10 { // Allow testing "arg unavailable" path
- return nil
- }
- return r.arg
- }
- type opposite int
- func (o opposite) PluralForm(lang language.Tag, scale int) (Form, int) {
- if o == 1 {
- return Other, 1
- }
- return One, int(o)
- }
|