OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / text / feature / plural / message_test.go
1 // Copyright 2017 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package plural
6
7 import (
8         "fmt"
9         "strings"
10         "testing"
11
12         "golang.org/x/text/internal/catmsg"
13         "golang.org/x/text/language"
14         "golang.org/x/text/message/catalog"
15 )
16
17 func TestSelect(t *testing.T) {
18         lang := language.English
19         type test struct {
20                 arg    interface{}
21                 result string
22                 err    string
23         }
24         testCases := []struct {
25                 desc  string
26                 msg   catalog.Message
27                 err   string
28                 tests []test
29         }{{
30                 desc: "basic",
31                 msg:  Selectf(1, "%d", "one", "foo", "other", "bar"),
32                 tests: []test{
33                         {arg: 0, result: "bar"},
34                         {arg: 1, result: "foo"},
35                         {arg: 2, result: "bar"},
36                         {arg: opposite(1), result: "bar"},
37                         {arg: opposite(2), result: "foo"},
38                         {arg: "unknown", result: "bar"}, // other
39                 },
40         }, {
41                 desc: "comparisons",
42                 msg: Selectf(1, "%d",
43                         "=0", "zero",
44                         "=1", "one",
45                         "one", "cannot match", // never matches
46                         "<5", "<5", // never matches
47                         "=5", "=5",
48                         Other, "other"),
49                 tests: []test{
50                         {arg: 0, result: "zero"},
51                         {arg: 1, result: "one"},
52                         {arg: 2, result: "<5"},
53                         {arg: 4, result: "<5"},
54                         {arg: 5, result: "=5"},
55                         {arg: 6, result: "other"},
56                         {arg: "unknown", result: "other"},
57                 },
58         }, {
59                 desc: "fractions",
60                 msg:  Selectf(1, "%.2f", "one", "foo", "other", "bar"),
61                 tests: []test{
62                         // fractions are always plural in english
63                         {arg: 0, result: "bar"},
64                         {arg: 1, result: "bar"},
65                 },
66         }, {
67                 desc: "decimal without fractions",
68                 msg:  Selectf(1, "%.of", "one", "foo", "other", "bar"),
69                 tests: []test{
70                         // fractions are always plural in english
71                         {arg: 0, result: "bar"},
72                         {arg: 1, result: "foo"},
73                 },
74         }, {
75                 desc: "scientific",
76                 msg:  Selectf(1, "%.0e", "one", "foo", "other", "bar"),
77                 tests: []test{
78                         {arg: 0, result: "bar"},
79                         {arg: 1, result: "foo"},
80                 },
81         }, {
82                 desc: "variable",
83                 msg:  Selectf(1, "%.1g", "one", "foo", "other", "bar"),
84                 tests: []test{
85                         // fractions are always plural in english
86                         {arg: 0, result: "bar"},
87                         {arg: 1, result: "foo"},
88                         {arg: 2, result: "bar"},
89                 },
90         }, {
91                 desc: "default",
92                 msg:  Selectf(1, "", "one", "foo", "other", "bar"),
93                 tests: []test{
94                         {arg: 0, result: "bar"},
95                         {arg: 1, result: "foo"},
96                         {arg: 2, result: "bar"},
97                         {arg: 1.0, result: "bar"},
98                 },
99         }, {
100                 desc: "nested",
101                 msg:  Selectf(1, "", "other", Selectf(2, "", "one", "foo", "other", "bar")),
102                 tests: []test{
103                         {arg: 0, result: "bar"},
104                         {arg: 1, result: "foo"},
105                         {arg: 2, result: "bar"},
106                 },
107         }, {
108                 desc:  "arg unavailable",
109                 msg:   Selectf(100, "%.2f", "one", "foo", "other", "bar"),
110                 tests: []test{{arg: 1, result: "bar"}},
111         }, {
112                 desc:  "no match",
113                 msg:   Selectf(1, "%.2f", "one", "foo"),
114                 tests: []test{{arg: 0, result: "bar", err: catmsg.ErrNoMatch.Error()}},
115         }, {
116                 desc: "error invalid form",
117                 err:  `invalid plural form "excessive"`,
118                 msg:  Selectf(1, "%d", "excessive", "foo"),
119         }, {
120                 desc: "error form not used by language",
121                 err:  `form "many" not supported for language "en"`,
122                 msg:  Selectf(1, "%d", "many", "foo"),
123         }, {
124                 desc: "error invalid selector",
125                 err:  `selector of type int; want string or Form`,
126                 msg:  Selectf(1, "%d", 1, "foo"),
127         }, {
128                 desc: "error missing message",
129                 err:  `no message defined for selector one`,
130                 msg:  Selectf(1, "%d", "one"),
131         }, {
132                 desc: "error invalid number",
133                 err:  `invalid number in selector "<1.00"`,
134                 msg:  Selectf(1, "%d", "<1.00"),
135         }, {
136                 desc: "error empty selector",
137                 err:  `empty selector`,
138                 msg:  Selectf(1, "%d", "", "foo"),
139         }, {
140                 desc: "error invalid message",
141                 err:  `message of type int; must be string or catalog.Message`,
142                 msg:  Selectf(1, "%d", "one", 3),
143         }, {
144                 desc: "nested error",
145                 err:  `empty selector`,
146                 msg:  Selectf(1, "", "other", Selectf(2, "", "")),
147         }}
148         for _, tc := range testCases {
149                 t.Run(tc.desc, func(t *testing.T) {
150                         data, err := catmsg.Compile(lang, nil, tc.msg)
151                         chkError(t, err, tc.err)
152                         for _, tx := range tc.tests {
153                                 t.Run(fmt.Sprint(tx.arg), func(t *testing.T) {
154                                         r := renderer{arg: tx.arg}
155                                         d := catmsg.NewDecoder(lang, &r, nil)
156                                         err := d.Execute(data)
157                                         chkError(t, err, tx.err)
158                                         if r.result != tx.result {
159                                                 t.Errorf("got %q; want %q", r.result, tx.result)
160                                         }
161                                 })
162                         }
163                 })
164         }
165 }
166
167 func chkError(t *testing.T, got error, want string) {
168         if (got == nil && want != "") ||
169                 (got != nil && (want == "" || !strings.Contains(got.Error(), want))) {
170                 t.Fatalf("got %v; want %v", got, want)
171         }
172         if got != nil {
173                 t.SkipNow()
174         }
175 }
176
177 type renderer struct {
178         arg    interface{}
179         result string
180 }
181
182 func (r *renderer) Render(s string) { r.result += s }
183 func (r *renderer) Arg(i int) interface{} {
184         if i > 10 { // Allow testing "arg unavailable" path
185                 return nil
186         }
187         return r.arg
188 }
189
190 type opposite int
191
192 func (o opposite) PluralForm(lang language.Tag, scale int) (Form, int) {
193         if o == 1 {
194                 return Other, 1
195         }
196         return One, int(o)
197 }