1 package cldr
2
3 import (
4 "fmt"
5 "log"
6 "reflect"
7 "testing"
8 )
9
10 func failOnError(err error) {
11 if err != nil {
12 log.Panic(err)
13 }
14 }
15
16 func data() *CLDR {
17 d := Decoder{}
18 data, err := d.Decode(testLoader{})
19 failOnError(err)
20 return data
21 }
22
23 type h struct {
24 A string `xml:"ha,attr"`
25 E string `xml:"he"`
26 D string `xml:",chardata"`
27 X string
28 }
29
30 type fieldTest struct {
31 Common
32 To string `xml:"to,attr"`
33 Key string `xml:"key,attr"`
34 E string `xml:"e"`
35 D string `xml:",chardata"`
36 X string
37 h
38 }
39
40 var testStruct = fieldTest{
41 Common: Common{
42 name: "mapping",
43 Type: "foo",
44 Alt: "foo",
45 },
46 To: "nyc",
47 Key: "k",
48 E: "E",
49 D: "D",
50 h: h{
51 A: "A",
52 E: "E",
53 D: "D",
54 },
55 }
56
57 func TestIter(t *testing.T) {
58 tests := map[string]string{
59 "Type": "foo",
60 "Alt": "foo",
61 "To": "nyc",
62 "A": "A",
63 "Alias": "<nil>",
64 }
65 k := 0
66 for i := iter(reflect.ValueOf(testStruct)); !i.done(); i.next() {
67 v := i.value()
68 if v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.String {
69 v = v.Elem()
70 }
71 name := i.field().Name
72 if w, ok := tests[name]; ok {
73 s := fmt.Sprint(v.Interface())
74 if w != s {
75 t.Errorf("value: found %q; want %q", w, s)
76 }
77 delete(tests, name)
78 }
79 k++
80 }
81 if len(tests) != 0 {
82 t.Errorf("missing fields: %v", tests)
83 }
84 }
85
86 func TestFindField(t *testing.T) {
87 tests := []struct {
88 name, val string
89 exist bool
90 }{
91 {"type", "foo", true},
92 {"alt", "foo", true},
93 {"to", "nyc", true},
94 {"he", "E", true},
95 {"q", "", false},
96 }
97 vf := reflect.ValueOf(testStruct)
98 for i, tt := range tests {
99 v, err := findField(vf, tt.name)
100 if (err == nil) != tt.exist {
101 t.Errorf("%d: field %q present is %v; want %v", i, tt.name, err == nil, tt.exist)
102 } else if tt.exist {
103 if v.Kind() == reflect.Ptr {
104 if v.IsNil() {
105 continue
106 }
107 v = v.Elem()
108 }
109 if v.String() != tt.val {
110 t.Errorf("%d: found value %q; want %q", i, v.String(), tt.val)
111 }
112 }
113 }
114 }
115
116 var keyTests = []struct {
117 exclude []string
118 key string
119 }{
120 {[]string{}, "alt=foo;key=k;to=nyc"},
121 {[]string{"type"}, "alt=foo;key=k;to=nyc"},
122 {[]string{"choice"}, "alt=foo;key=k;to=nyc"},
123 {[]string{"alt"}, "key=k;to=nyc"},
124 {[]string{"a"}, "alt=foo;key=k;to=nyc"},
125 {[]string{"to"}, "alt=foo;key=k"},
126 {[]string{"alt", "to"}, "key=k"},
127 {[]string{"alt", "to", "key"}, ""},
128 }
129
130 func TestAttrKey(t *testing.T) {
131 v := reflect.ValueOf(&testStruct)
132 for i, tt := range keyTests {
133 key := attrKey(v, tt.exclude...)
134 if key != tt.key {
135 t.Errorf("%d: found %q, want %q", i, key, tt.key)
136 }
137 }
138 }
139
140 func TestKey(t *testing.T) {
141 for i, tt := range keyTests {
142 key := Key(&testStruct, tt.exclude...)
143 if key != tt.key {
144 t.Errorf("%d: found %q, want %q", i, key, tt.key)
145 }
146 }
147 }
148
149 func testEnclosing(t *testing.T, x *LDML, name string) {
150 eq := func(a, b Elem, i int) {
151 for ; i > 0; i-- {
152 b = b.enclosing()
153 }
154 if a != b {
155 t.Errorf("%s: found path %q, want %q", name, getPath(a), getPath(b))
156 }
157 }
158 eq(x, x, 0)
159 eq(x, x.Identity, 1)
160 eq(x, x.Dates.Calendars, 2)
161 eq(x, x.Dates.Calendars.Calendar[0], 3)
162 eq(x, x.Dates.Calendars.Calendar[1], 3)
163
164 eq(x, x.Dates.Calendars.Calendar[1].Months, 4)
165 }
166
167 func TestEnclosing(t *testing.T) {
168 testEnclosing(t, data().RawLDML("de"), "enclosing-raw")
169 de, _ := data().LDML("de")
170 testEnclosing(t, de, "enclosing")
171 }
172
173 func TestDeepCopy(t *testing.T) {
174 eq := func(have, want string) {
175 if have != want {
176 t.Errorf("found %q; want %q", have, want)
177 }
178 }
179 x, _ := data().LDML("de")
180 vc := deepCopy(reflect.ValueOf(x))
181 c := vc.Interface().(*LDML)
182 linkEnclosing(nil, c)
183 if x == c {
184 t.Errorf("did not copy")
185 }
186
187 eq(c.name, "ldml")
188 eq(c.Dates.name, "dates")
189 testEnclosing(t, c, "deepCopy")
190 }
191
192 type getTest struct {
193 loc string
194 path string
195 field string
196 data string
197 altData string
198 typ string
199 length int
200 missing bool
201 }
202
203 const (
204 budMon = "dates/calendars/calendar[@type='buddhist']/months/"
205 chnMon = "dates/calendars/calendar[@type='chinese']/months/"
206 greMon = "dates/calendars/calendar[@type='gregorian']/months/"
207 )
208
209 func monthVal(path, context, width string, month int) string {
210 const format = "%s/monthContext[@type='%s']/monthWidth[@type='%s']/month[@type='%d']"
211 return fmt.Sprintf(format, path, context, width, month)
212 }
213
214 var rootGetTests = []getTest{
215 {loc: "root", path: "identity/language", typ: "root"},
216 {loc: "root", path: "characters/moreInformation", data: "?"},
217 {loc: "root", path: "characters", field: "exemplarCharacters", length: 3},
218 {loc: "root", path: greMon, field: "monthContext", length: 2},
219 {loc: "root", path: greMon + "monthContext[@type='format']/monthWidth[@type='narrow']", field: "month", length: 4},
220 {loc: "root", path: greMon + "monthContext[@type='stand-alone']/monthWidth[@type='wide']", field: "month", length: 4},
221
222 {loc: "root", path: "characters/exemplarCharacters[@type='punctuation']", data: `[\- ‐ – — … ' ‘ ‚ " “ „ \& #]`},
223
224 {loc: "root", path: "dates/calendars/calendar", typ: "gregorian"},
225
226 {loc: "root", path: budMon, field: "monthContext", length: 2},
227
228 {loc: "root", path: budMon + "monthContext[@type='format']/monthWidth[@type='narrow']", field: "month", length: 4},
229 {loc: "root", path: budMon + "monthContext[@type='stand-alone']/monthWidth[@type='wide']", field: "month", length: 4},
230 {loc: "root", path: monthVal(greMon, "format", "wide", 1), data: "11"},
231 {loc: "root", path: monthVal(greMon, "format", "narrow", 2), data: "2"},
232 {loc: "root", path: monthVal(greMon, "stand-alone", "wide", 3), data: "33"},
233 {loc: "root", path: monthVal(greMon, "stand-alone", "narrow", 4), data: "4"},
234 {loc: "root", path: monthVal(budMon, "format", "wide", 1), data: "11"},
235 {loc: "root", path: monthVal(budMon, "format", "narrow", 2), data: "2"},
236 {loc: "root", path: monthVal(budMon, "stand-alone", "wide", 3), data: "33"},
237 {loc: "root", path: monthVal(budMon, "stand-alone", "narrow", 4), data: "4"},
238 }
239
240
241 var deGetTests = []getTest{
242 {loc: "de", path: "identity/language", typ: "de"},
243 {loc: "de", path: "posix", length: 2},
244 {loc: "de", path: "characters", field: "exemplarCharacters", length: 4},
245 {loc: "de", path: "characters/exemplarCharacters[@type='auxiliary']", data: `[á à ă]`},
246
247 {loc: "de", path: "identity/generation", missing: true},
248
249 {loc: "root", path: "dates/calendars/calendar", typ: "gregorian"},
250
251
252 {loc: "gsw", path: "posix", field: "messages", length: 1},
253 {loc: "gsw", path: "posix/messages/yesstr", data: "yes:y"},
254 }
255
256
257 func calGetTests(s string) []getTest {
258 tests := []getTest{
259 {loc: "de", path: s, length: 2},
260 {loc: "de", path: s + "monthContext[@type='format']/monthWidth[@type='wide']", field: "month", length: 5},
261 {loc: "de", path: monthVal(s, "format", "wide", 1), data: "11"},
262 {loc: "de", path: monthVal(s, "format", "wide", 2), data: "22"},
263 {loc: "de", path: monthVal(s, "format", "wide", 3), data: "Maerz", altData: "bbb"},
264 {loc: "de", path: monthVal(s, "format", "wide", 4), data: "April"},
265 {loc: "de", path: monthVal(s, "format", "wide", 5), data: "Mai"},
266
267 {loc: "de", path: s + "monthContext[@type='format']/monthWidth[@type='narrow']", field: "month", length: 5},
268 {loc: "de", path: monthVal(s, "format", "narrow", 1), data: "1"},
269 {loc: "de", path: monthVal(s, "format", "narrow", 2), data: "2"},
270 {loc: "de", path: monthVal(s, "format", "narrow", 3), data: "M", altData: "BBB"},
271 {loc: "de", path: monthVal(s, "format", "narrow", 4), data: "A"},
272 {loc: "de", path: monthVal(s, "format", "narrow", 5), data: "m"},
273
274 {loc: "de", path: s + "monthContext[@type='stand-alone']/monthWidth[@type='wide']", field: "month", length: 5},
275 {loc: "de", path: monthVal(s, "stand-alone", "wide", 1), data: "11"},
276 {loc: "de", path: monthVal(s, "stand-alone", "wide", 2), data: "22"},
277 {loc: "de", path: monthVal(s, "stand-alone", "wide", 3), data: "Maerz", altData: "bbb"},
278 {loc: "de", path: monthVal(s, "stand-alone", "wide", 4), data: "april"},
279 {loc: "de", path: monthVal(s, "stand-alone", "wide", 5), data: "mai"},
280
281 {loc: "de", path: s + "monthContext[@type='stand-alone']/monthWidth[@type='narrow']", field: "month", length: 5},
282 {loc: "de", path: monthVal(s, "stand-alone", "narrow", 1), data: "1"},
283 {loc: "de", path: monthVal(s, "stand-alone", "narrow", 2), data: "2"},
284 {loc: "de", path: monthVal(s, "stand-alone", "narrow", 3), data: "m"},
285 {loc: "de", path: monthVal(s, "stand-alone", "narrow", 4), data: "4"},
286 {loc: "de", path: monthVal(s, "stand-alone", "narrow", 5), data: "m"},
287 }
288 if s == budMon {
289 for i, t := range tests {
290 if t.altData != "" {
291 tests[i].data = t.altData
292 }
293 }
294 }
295 return tests
296 }
297
298 var getTests = append(rootGetTests,
299 append(deGetTests,
300 append(calGetTests(greMon),
301 append(calGetTests(budMon),
302 calGetTests(chnMon)...)...)...)...)
303
304 func TestPath(t *testing.T) {
305 d := data()
306 for i, tt := range getTests {
307 x, _ := d.LDML(tt.loc)
308 e, err := walkXPath(x, tt.path)
309 if err != nil {
310 if !tt.missing {
311 t.Errorf("%d:error: %v %v", i, err, tt.missing)
312 }
313 continue
314 }
315 if tt.missing {
316 t.Errorf("%d: missing is %v; want %v", i, e == nil, tt.missing)
317 continue
318 }
319 if tt.data != "" && e.GetCommon().Data() != tt.data {
320 t.Errorf("%d: data is %v; want %v", i, e.GetCommon().Data(), tt.data)
321 continue
322 }
323 if tt.typ != "" && e.GetCommon().Type != tt.typ {
324 t.Errorf("%d: type is %v; want %v", i, e.GetCommon().Type, tt.typ)
325 continue
326 }
327 if tt.field != "" {
328 slice, _ := findField(reflect.ValueOf(e), tt.field)
329 if slice.Len() != tt.length {
330 t.Errorf("%d: length is %v; want %v", i, slice.Len(), tt.length)
331 continue
332 }
333 }
334 }
335 }
336
337 func TestGet(t *testing.T) {
338 d := data()
339 for i, tt := range getTests {
340 x, _ := d.LDML(tt.loc)
341 e, err := Get(x, tt.path)
342 if err != nil {
343 if !tt.missing {
344 t.Errorf("%d:error: %v %v", i, err, tt.missing)
345 }
346 continue
347 }
348 if tt.missing {
349 t.Errorf("%d: missing is %v; want %v", i, e == nil, tt.missing)
350 continue
351 }
352 if tt.data != "" && e.GetCommon().Data() != tt.data {
353 t.Errorf("%d: data is %v; want %v", i, e.GetCommon().Data(), tt.data)
354 continue
355 }
356 if tt.typ != "" && e.GetCommon().Type != tt.typ {
357 t.Errorf("%d: type is %v; want %v", i, e.GetCommon().Type, tt.typ)
358 continue
359 }
360 if tt.field != "" {
361 slice, _ := findField(reflect.ValueOf(e), tt.field)
362 if slice.Len() != tt.length {
363 t.Errorf("%d: length is %v; want %v", i, slice.Len(), tt.length)
364 continue
365 }
366 }
367 }
368 }
369
View as plain text