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