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
5package date
6
7import (
8	"strconv"
9	"strings"
10	"testing"
11
12	"golang.org/x/text/internal/cldrtree"
13	"golang.org/x/text/internal/gen"
14	"golang.org/x/text/internal/testtext"
15	"golang.org/x/text/language"
16	"golang.org/x/text/unicode/cldr"
17)
18
19func TestTables(t *testing.T) {
20	testtext.SkipIfNotLong(t)
21
22	r := gen.OpenCLDRCoreZip()
23	defer r.Close()
24
25	d := &cldr.Decoder{}
26	d.SetDirFilter("supplemental", "main")
27	d.SetSectionFilter("dates")
28	data, err := d.DecodeZip(r)
29	if err != nil {
30		t.Fatalf("DecodeZip: %v", err)
31	}
32
33	count := 0
34	for _, lang := range data.Locales() {
35		ldml := data.RawLDML(lang)
36		if ldml.Dates == nil {
37			continue
38		}
39		tag, _ := language.CompactIndex(language.MustParse(lang))
40
41		test := func(want cldrtree.Element, path ...string) {
42			if count > 30 {
43				return
44			}
45			t.Run(lang+"/"+strings.Join(path, "/"), func(t *testing.T) {
46				p := make([]uint16, len(path))
47				for i, s := range path {
48					if v, err := strconv.Atoi(s); err == nil {
49						p[i] = uint16(v)
50					} else if v, ok := enumMap[s]; ok {
51						p[i] = v
52					} else {
53						count++
54						t.Fatalf("Unknown key %q", s)
55					}
56				}
57				wantStr := want.GetCommon().Data()
58				if got := tree.Lookup(tag, p...); got != wantStr {
59					count++
60					t.Errorf("got %q; want %q", got, wantStr)
61				}
62			})
63		}
64
65		width := func(s string) string { return "width" + strings.Title(s) }
66
67		if ldml.Dates.Calendars != nil {
68			for _, cal := range ldml.Dates.Calendars.Calendar {
69				if cal.Months != nil {
70					for _, mc := range cal.Months.MonthContext {
71						for _, mw := range mc.MonthWidth {
72							for _, m := range mw.Month {
73								test(m, "calendars", cal.Type, "months", mc.Type, width(mw.Type), m.Yeartype+m.Type)
74							}
75						}
76					}
77				}
78				if cal.MonthPatterns != nil {
79					for _, mc := range cal.MonthPatterns.MonthPatternContext {
80						for _, mw := range mc.MonthPatternWidth {
81							for _, m := range mw.MonthPattern {
82								test(m, "calendars", cal.Type, "monthPatterns", mc.Type, width(mw.Type))
83							}
84						}
85					}
86				}
87				if cal.CyclicNameSets != nil {
88					for _, cns := range cal.CyclicNameSets.CyclicNameSet {
89						for _, cc := range cns.CyclicNameContext {
90							for _, cw := range cc.CyclicNameWidth {
91								for _, c := range cw.CyclicName {
92									test(c, "calendars", cal.Type, "cyclicNameSets", cns.Type+"CycleType", cc.Type, width(cw.Type), c.Type)
93
94								}
95							}
96						}
97					}
98				}
99				if cal.Days != nil {
100					for _, dc := range cal.Days.DayContext {
101						for _, dw := range dc.DayWidth {
102							for _, d := range dw.Day {
103								test(d, "calendars", cal.Type, "days", dc.Type, width(dw.Type), d.Type)
104							}
105						}
106					}
107				}
108				if cal.Quarters != nil {
109					for _, qc := range cal.Quarters.QuarterContext {
110						for _, qw := range qc.QuarterWidth {
111							for _, q := range qw.Quarter {
112								test(q, "calendars", cal.Type, "quarters", qc.Type, width(qw.Type), q.Type)
113							}
114						}
115					}
116				}
117				if cal.DayPeriods != nil {
118					for _, dc := range cal.DayPeriods.DayPeriodContext {
119						for _, dw := range dc.DayPeriodWidth {
120							for _, d := range dw.DayPeriod {
121								test(d, "calendars", cal.Type, "dayPeriods", dc.Type, width(dw.Type), d.Type, d.Alt)
122							}
123						}
124					}
125				}
126				if cal.Eras != nil {
127					if cal.Eras.EraNames != nil {
128						for _, e := range cal.Eras.EraNames.Era {
129							test(e, "calendars", cal.Type, "eras", "widthWide", e.Alt, e.Type)
130						}
131					}
132					if cal.Eras.EraAbbr != nil {
133						for _, e := range cal.Eras.EraAbbr.Era {
134							test(e, "calendars", cal.Type, "eras", "widthAbbreviated", e.Alt, e.Type)
135						}
136					}
137					if cal.Eras.EraNarrow != nil {
138						for _, e := range cal.Eras.EraNarrow.Era {
139							test(e, "calendars", cal.Type, "eras", "widthNarrow", e.Alt, e.Type)
140						}
141					}
142				}
143				if cal.DateFormats != nil {
144					for _, dfl := range cal.DateFormats.DateFormatLength {
145						for _, df := range dfl.DateFormat {
146							for _, p := range df.Pattern {
147								test(p, "calendars", cal.Type, "dateFormats", dfl.Type, p.Alt)
148							}
149						}
150					}
151				}
152				if cal.TimeFormats != nil {
153					for _, tfl := range cal.TimeFormats.TimeFormatLength {
154						for _, tf := range tfl.TimeFormat {
155							for _, p := range tf.Pattern {
156								test(p, "calendars", cal.Type, "timeFormats", tfl.Type, p.Alt)
157							}
158						}
159					}
160				}
161				if cal.DateTimeFormats != nil {
162					for _, dtfl := range cal.DateTimeFormats.DateTimeFormatLength {
163						for _, dtf := range dtfl.DateTimeFormat {
164							for _, p := range dtf.Pattern {
165								test(p, "calendars", cal.Type, "dateTimeFormats", dtfl.Type, p.Alt)
166							}
167						}
168					}
169					// TODO:
170					// - appendItems
171					// - intervalFormats
172				}
173			}
174		}
175		// TODO: this is a lot of data and is probably relatively little used.
176		// Store this somewhere else.
177		if ldml.Dates.Fields != nil {
178			for _, f := range ldml.Dates.Fields.Field {
179				field := f.Type + "Field"
180				for _, d := range f.DisplayName {
181					test(d, "fields", field, "displayName", d.Alt)
182				}
183				for _, r := range f.Relative {
184					i, _ := strconv.Atoi(r.Type)
185					v := []string{"before2", "before1", "current", "after1", "after2", "after3"}[i+2]
186					test(r, "fields", field, "relative", v)
187				}
188				for _, rt := range f.RelativeTime {
189					for _, p := range rt.RelativeTimePattern {
190						test(p, "fields", field, "relativeTime", rt.Type, p.Count)
191					}
192				}
193				for _, rp := range f.RelativePeriod {
194					test(rp, "fields", field, "relativePeriod", rp.Alt)
195				}
196			}
197		}
198		if ldml.Dates.TimeZoneNames != nil {
199			for _, h := range ldml.Dates.TimeZoneNames.HourFormat {
200				test(h, "timeZoneNames", "zoneFormat", h.Element())
201			}
202			for _, g := range ldml.Dates.TimeZoneNames.GmtFormat {
203				test(g, "timeZoneNames", "zoneFormat", g.Element())
204			}
205			for _, g := range ldml.Dates.TimeZoneNames.GmtZeroFormat {
206				test(g, "timeZoneNames", "zoneFormat", g.Element())
207			}
208			for _, r := range ldml.Dates.TimeZoneNames.RegionFormat {
209				s := r.Type
210				if s == "" {
211					s = "generic"
212				}
213				test(r, "timeZoneNames", "regionFormat", s+"Time")
214			}
215
216			testZone := func(zoneType, zoneWidth, zone string, a ...[]*cldr.Common) {
217				for _, e := range a {
218					for _, n := range e {
219						test(n, "timeZoneNames", zoneType, zoneWidth, n.Element()+"Time", zone)
220					}
221				}
222			}
223			for _, z := range ldml.Dates.TimeZoneNames.Zone {
224				for _, l := range z.Long {
225					testZone("zone", l.Element(), z.Type, l.Generic, l.Standard, l.Daylight)
226				}
227				for _, l := range z.Short {
228					testZone("zone", l.Element(), z.Type, l.Generic, l.Standard, l.Daylight)
229				}
230			}
231			for _, z := range ldml.Dates.TimeZoneNames.Metazone {
232				for _, l := range z.Long {
233					testZone("metaZone", l.Element(), z.Type, l.Generic, l.Standard, l.Daylight)
234				}
235				for _, l := range z.Short {
236					testZone("metaZone", l.Element(), z.Type, l.Generic, l.Standard, l.Daylight)
237				}
238			}
239		}
240	}
241}
242