func TestParents(t *testing.T) { testCases := []struct { tag, parent string }{ {"af", "und"}, {"en", "und"}, {"en-001", "en"}, {"en-AU", "en-001"}, {"en-US", "en"}, {"en-US-u-va-posix", "en-US"}, {"ca-ES-valencia", "ca-ES"}, } for _, tc := range testCases { tag, ok := language.CompactIndex(language.MustParse(tc.tag)) if !ok { t.Fatalf("Could not get index of flag %s", tc.tag) } want, ok := language.CompactIndex(language.MustParse(tc.parent)) if !ok { t.Fatalf("Could not get index of parent %s of tag %s", tc.parent, tc.tag) } if got := int(Parent[tag]); got != want { t.Errorf("Parent[%s] = %d; want %d (%s)", tc.tag, got, want, tc.parent) } } }
func MobileInit() { initChan := make(chan struct{}) initDone = initChan go func() { defer close(initChan) langs := preferredLanguages() fmt.Printf("PREFERRED LANGUAGES: %v\n", langs) matcher := language.NewMatcher([]language.Tag{ language.MustParse("en_US"), language.MustParse("es_MX"), }) tag, idx, conf := matcher.Match(langs...) fmt.Printf("I think we'll go with %s (%d th place choice with %s confidence)\n", tag, idx, conf) if locale := tag.String(); locale != "en-us" { t, err := loadDictionary(locale) if err != nil { panic(fmt.Sprintf("Cannot load '%s': %s", locale, err)) } translate = t } if t, err := loadDictionary("en-us"); err != nil { panic(fmt.Sprintf("Cannot load 'en-us': %s", err)) } else { translateFallback = t } }() }
func TestFormats(t *testing.T) { testCases := []struct { lang string pattern string index []byte }{ {"en", "#,##0.###", tagToDecimal}, {"de", "#,##0.###", tagToDecimal}, {"de-CH", "#,##0.###", tagToDecimal}, {"pa", "#,##,##0.###", tagToDecimal}, {"pa-Arab", "#,##0.###", tagToDecimal}, // Does NOT inherit from pa! {"mr", "#,##,##0.###", tagToDecimal}, {"mr-IN", "#,##,##0.###", tagToDecimal}, // Inherits from mr. {"nl", "#E0", tagToScientific}, {"nl-MX", "#E0", tagToScientific}, // Inherits through Tag.Parent. {"zgh", "#,##0 %", tagToPercent}, } for _, tc := range testCases { testtext.Run(t, tc.lang, func(t *testing.T) { got := formatForLang(language.MustParse(tc.lang), tc.index) want, _ := ParsePattern(tc.pattern) if *got != *want { t.Errorf("\ngot %#v;\nwant %#v", got, want) } }) } }
func ExampleNamer() { supported := []string{ "en-US", "en-GB", "ja", "zh", "zh-Hans", "zh-Hant", "pt", "pt-PT", "ko", "ar", "el", "ru", "uk", "pa", } en := display.English.Languages() for _, s := range supported { t := language.MustParse(s) fmt.Printf("%-20s (%s)\n", en.Name(t), display.Self.Name(t)) } // Output: // American English (American English) // British English (British English) // Japanese (日本語) // Chinese (中文) // Simplified Chinese (简体中文) // Traditional Chinese (繁體中文) // Portuguese (português) // European Portuguese (português europeu) // Korean (한국어) // Arabic (العربية) // Greek (Ελληνικά) // Russian (русский) // Ukrainian (українська) // Punjabi (ਪੰਜਾਬੀ) }
// TestUpdate tests whether dictionary entries for certain languages need to be // updated. For some languages, some of the headers may be empty or they may be // identical to the parent. This code detects if such entries need to be updated // after a table update. func TestUpdate(t *testing.T) { tests := []struct { d *Dictionary tag string }{ {ModernStandardArabic, "ar-001"}, {AmericanEnglish, "en-US"}, {EuropeanSpanish, "es-ES"}, {BrazilianPortuguese, "pt-BR"}, {SimplifiedChinese, "zh-Hans"}, } for _, tt := range tests { _, i, _ := matcher.Match(language.MustParse(tt.tag)) if !reflect.DeepEqual(tt.d.lang, langHeaders[i]) { t.Errorf("%s: lang table update needed", tt.tag) } if !reflect.DeepEqual(tt.d.script, scriptHeaders[i]) { t.Errorf("%s: script table update needed", tt.tag) } if !reflect.DeepEqual(tt.d.region, regionHeaders[i]) { t.Errorf("%s: region table update needed", tt.tag) } } }
func TestBinding(t *testing.T) { testCases := []struct { tag string value interface{} want string }{ {"en", 1, "1"}, {"en", "2", "2"}, { // Language is passed. "en", formatFunc(func(fs fmt.State, v rune) { s := fs.(format.State) io.WriteString(s, s.Language().String()) }), "en", }, } for i, tc := range testCases { p := NewPrinter(language.MustParse(tc.tag)) if got := p.Sprint(tc.value); got != tc.want { t.Errorf("%d:%s:Sprint(%v) = %q; want %q", i, tc.tag, tc.value, got, tc.want) } var buf bytes.Buffer p.Fprint(&buf, tc.value) if got := buf.String(); got != tc.want { t.Errorf("%d:%s:Fprint(%v) = %q; want %q", i, tc.tag, tc.value, got, tc.want) } } }
func TestTag(t *testing.T) { tests := []struct { dict string tag string name string }{ {"agq", "sr", ""}, // sr is in Value.Languages(), but is not supported by agq. {"nl", "nl", "Nederlands"}, {"nl", "nl-BE", "Vlaams"}, {"en", "en", "English"}, {"en", "en-GB", "British English"}, {"en", "en-US", "American English"}, // American English in CLDR 24+ {"ru", "ru", "русский"}, {"ru", "ru-RU", "русский (Россия)"}, {"ru", "ru-Cyrl", "русский (кириллица)"}, {"en", lastLang2zu.String(), "Zulu"}, {"en", firstLang2aa.String(), "Afar"}, {"en", lastLang3zza.String(), "Zaza"}, {"en", firstLang3ace.String(), "Achinese"}, {"en", firstTagAr001.String(), "Modern Standard Arabic"}, {"en", lastTagZhHant.String(), "Traditional Chinese"}, {"en", "aaa", ""}, {"en", "zzj", ""}, // If full tag doesn't match, try without script or region. {"en", "aa-Hans", "Afar (Simplified Han)"}, {"en", "af-Arab", "Afrikaans (Arabic)"}, {"en", "zu-Cyrl", "Zulu (Cyrillic)"}, {"en", "aa-GB", "Afar (United Kingdom)"}, {"en", "af-NA", "Afrikaans (Namibia)"}, {"en", "zu-BR", "Zulu (Brazil)"}, // Correct inheritance and language selection. {"zh", "zh-TW", "中文 (台湾)"}, {"zh", "zh-Hant-TW", "繁体中文 (台湾)"}, {"zh-Hant", "zh-TW", "中文 (台灣)"}, {"zh-Hant", "zh-Hant-TW", "繁體中文 (台灣)"}, // Some rather arbitrary interpretations for Serbian. This is arguably // correct and consistent with the way zh-[Hant-]TW is handled. It will // also give results more in line with the expectations if users // explicitly use "sh". {"sr-Latn", "sr-ME", "srpski (Crna Gora)"}, {"sr-Latn", "sr-Latn-ME", "Srpskohrvatski (Crna Gora)"}, // Double script and region {"nl", "en-Cyrl-BE", "Engels (Cyrillisch, België)"}, // Canonical equivalents. {"ro", "ro-MD", "moldovenească"}, {"ro", "mo", "moldovenească"}, } for i, tt := range tests { d := Tags(language.MustParse(tt.dict)) if n := d.Name(language.Raw.MustParse(tt.tag)); n != tt.name { // There are inconsistencies w.r.t. capitalization in the tests // due to CLDR's update procedure which treats modern and other // languages differently. // See http://unicode.org/cldr/trac/ticket/8051. // TODO: use language capitalization to sanitize the strings. t.Errorf("%d:%s:%s: was %q; want %q", i, tt.dict, tt.tag, n, tt.name) } } }
func init() { tags := []language.Tag{} for _, s := range strings.Split(supported, " ") { tags = append(tags, language.MustParse(s)) } matcher = language.NewMatcher(tags) Supported = language.NewCoverage(tags) }
func TestTables(t *testing.T) { if !*long { return } gen.Init() // Read the CLDR zip file. r := gen.OpenCLDRCoreZip() defer r.Close() d := &cldr.Decoder{} d.SetDirFilter("supplemental", "main") d.SetSectionFilter("numbers") data, err := d.DecodeZip(r) if err != nil { t.Fatalf("DecodeZip: %v", err) } dr, err := cldr.ParseDraft(*draft) if err != nil { t.Fatalf("filter: %v", err) } for _, lang := range data.Locales() { p := message.NewPrinter(language.MustParse(lang)) ldml := data.RawLDML(lang) if ldml.Numbers == nil || ldml.Numbers.Currencies == nil { continue } for _, c := range ldml.Numbers.Currencies.Currency { syms := cldr.MakeSlice(&c.Symbol) syms.SelectDraft(dr) for _, sym := range c.Symbol { cur, err := ParseISO(c.Type) if err != nil { continue } formatter := Symbol switch sym.Alt { case "": case "narrow": formatter = NarrowSymbol default: continue } want := sym.Data() if got := p.Sprint(formatter(cur)); got != want { t.Errorf("%s:%sSymbol(%s) = %s; want %s", lang, strings.Title(sym.Alt), c.Type, got, want) } } } } }
func initCat(entries []entry) (*Catalog, []language.Tag) { tags := []language.Tag{} cat := newCatalog() for _, e := range entries { tag := language.MustParse(e.tag) tags = append(tags, tag) cat.SetString(tag, e.key, e.msg) } return cat, internal.UniqueTags(tags) }
func (env *CollationEnvironment) getCacheEntry(locale string) collationEnvironmentCacheEntry { entry, ok := env.cache[locale] if !ok { if env.cache == nil { env.cache = make(map[string]collationEnvironmentCacheEntry) } entry = collationEnvironmentCacheEntry{locale, collate.New(language.MustParse(locale))} env.cache[locale] = entry } return entry }
// LanguageDefault returns the canonical name of the default encoding for a // given language. func LanguageDefault(tag language.Tag) string { matcherOnce.Do(func() { tags := []language.Tag{} for _, t := range strings.Split(locales, " ") { tags = append(tags, language.MustParse(t)) } matcher = language.NewMatcher(tags) }) _, i, _ := matcher.Match(tag) return canonical[localeMap[i]] // Default is Windows-1252. }
func (i18n JsonI18n) parseTranslationFile(fullpath string, f os.FileInfo, err error) error { if !f.IsDir() { rawTag := filepath.Base(filepath.Dir(fullpath)) tag := language.MustParse(rawTag) file, e := ioutil.ReadFile(fullpath) if e != nil { return e } return i18n.parseTranslations(file, tag) } return nil }
func dictTags() (tag []language.Tag) { // TODO: replace with language.Common.Tags() once supported. const str = "af am ar ar-001 az bg bn ca cs da de el en en-US en-GB " + "es es-ES es-419 et fa fi fil fr fr-CA gu he hi hr hu hy id is it ja " + "ka kk km kn ko ky lo lt lv mk ml mn mr ms my ne nl no pa pl pt pt-BR " + "pt-PT ro ru si sk sl sq sr sr-Latn sv sw ta te th tr uk ur uz vi " + "zh zh-Hans zh-Hant zu" for _, s := range strings.Split(str, " ") { tag = append(tag, language.MustParse(s)) } return tag }
func TestInfo(t *testing.T) { testCases := []struct { lang string sym SymbolType wantSym string wantNine rune }{ {"und", SymDecimal, ".", '9'}, {"de", SymGroup, ".", '9'}, {"de-BE", SymGroup, ".", '9'}, // inherits from de (no number data in CLDR) {"de-BE-oxendict", SymGroup, ".", '9'}, // inherits from de (no compact index) // U+096F DEVANAGARI DIGIT NINE ('९') {"de-BE-u-nu-deva", SymGroup, ".", '\u096f'}, // miss -> latn -> de {"de-Cyrl-BE", SymGroup, ",", '9'}, // inherits from root {"de-CH", SymGroup, "'", '9'}, // overrides values in de {"de-CH-oxendict", SymGroup, "'", '9'}, // inherits from de-CH (no compact index) {"de-CH-u-nu-deva", SymGroup, "'", '\u096f'}, // miss -> latn -> de-CH {"pa", SymExponential, "E", '9'}, // "×۱۰^" -> U+00d7 U+06f1 U+06f0^" // U+06F0 EXTENDED ARABIC-INDIC DIGIT ZERO // U+06F1 EXTENDED ARABIC-INDIC DIGIT ONE // U+06F9 EXTENDED ARABIC-INDIC DIGIT NINE {"pa-u-nu-arabext", SymExponential, "\u00d7\u06f1\u06f0^", '\u06f9'}, // "གྲངས་མེད" - > U+0f42 U+0fb2 U+0f44 U+0f66 U+0f0b U+0f58 U+0f7a U+0f51 // Examples: // U+0F29 TIBETAN DIGIT NINE (༩) {"dz", SymInfinity, "\u0f42\u0fb2\u0f44\u0f66\u0f0b\u0f58\u0f7a\u0f51", '\u0f29'}, // defaults to tibt {"dz-u-nu-latn", SymInfinity, "∞", '9'}, // select alternative {"dz-u-nu-tibt", SymInfinity, "\u0f42\u0fb2\u0f44\u0f66\u0f0b\u0f58\u0f7a\u0f51", '\u0f29'}, {"en-u-nu-tibt", SymInfinity, "∞", '\u0f29'}, // algorithmic number systems fall back to ASCII if Digits is used. {"en-u-nu-hanidec", SymPlusSign, "+", '9'}, {"en-u-nu-roman", SymPlusSign, "+", '9'}, } for _, tc := range testCases { info := InfoFromTag(language.MustParse(tc.lang)) if got := info.Symbol(tc.sym); got != tc.wantSym { t.Errorf("%s:%v:sym: got %q; want %q", tc.lang, tc.sym, got, tc.wantSym) } if got := info.Digit('9'); got != tc.wantNine { t.Errorf("%s:%v:nine: got %q; want %q", tc.lang, tc.sym, got, tc.wantNine) } } }
func doGo(tag, caser, input string) string { var c Caser t := language.MustParse(tag) switch caser { case "lower": c = Lower(t) case "upper": c = Upper(t) case "title": c = Title(t) case "fold": c = Fold() } return c.String(input) }
// Init 初始化 locale 包并返回当前系统默认的本地化语言信息。 func Init() (language.Tag, error) { for id, messages := range locales { tag := language.MustParse(id) for key, val := range messages { message.SetString(tag, key, val) } } localeName, err := getLocaleName() if err != nil { return language.Und, err } return language.Parse(localeName) }
func TestLanguageDefault(t *testing.T) { for _, tc := range []struct{ tag, want string }{ {"und", "windows-1252"}, // The default value. {"ar", "windows-1256"}, {"ba", "windows-1251"}, {"be", "windows-1251"}, {"bg", "windows-1251"}, {"cs", "windows-1250"}, {"el", "iso-8859-7"}, {"et", "windows-1257"}, {"fa", "windows-1256"}, {"he", "windows-1255"}, {"hr", "windows-1250"}, {"hu", "iso-8859-2"}, {"ja", "shift_jis"}, {"kk", "windows-1251"}, {"ko", "euc-kr"}, {"ku", "windows-1254"}, {"ky", "windows-1251"}, {"lt", "windows-1257"}, {"lv", "windows-1257"}, {"mk", "windows-1251"}, {"pl", "iso-8859-2"}, {"ru", "windows-1251"}, {"sah", "windows-1251"}, {"sk", "windows-1250"}, {"sl", "iso-8859-2"}, {"sr", "windows-1251"}, {"tg", "windows-1251"}, {"th", "windows-874"}, {"tr", "windows-1254"}, {"tt", "windows-1251"}, {"uk", "windows-1251"}, {"vi", "windows-1258"}, {"zh-hans", "gb18030"}, {"zh-hant", "big5"}, // Variants and close approximates of the above. {"ar_EG", "windows-1256"}, {"bs", "windows-1250"}, // Bosnian Latin maps to Croatian. // Use default fallback in case of miss. {"nl", "windows-1252"}, } { if got := LanguageDefault(language.MustParse(tc.tag)); got != tc.want { t.Errorf("LanguageDefault(%s) = %s; want %s", tc.tag, got, tc.want) } } }
func TestCatalog(t *testing.T) { for _, tc := range testCases { cat, wantTags := initCat(tc.cat) // languages if got := cat.Languages(); !reflect.DeepEqual(got, wantTags) { t.Errorf("%s:Languages: got %v; want %v", tc.desc, got, wantTags) } // Lookup for _, e := range tc.lookup { tag := language.MustParse(e.tag) msg, ok := cat.get(tag, e.key) if okWant := e.msg != ""; ok != okWant || msg != e.msg { t.Errorf("%s:Lookup(%s, %s) = %s, %v; want %s, %v", tc.desc, tag, e.key, msg, ok, e.msg, okWant) } } } }
func testPlurals(t *testing.T, p *pluralRules, testCases []pluralTest) { for _, tc := range testCases { for _, loc := range strings.Split(tc.locales, " ") { langIndex, _ := language.CompactIndex(language.MustParse(loc)) // Test integers for _, s := range tc.integer { a := strings.Split(s, "~") from := parseUint(t, a[0]) to := from if len(a) > 1 { to = parseUint(t, a[1]) } for n := from; n <= to; n++ { if f := matchPlural(p, langIndex, n, 0, 0); f != tc.form { t.Errorf("%s:int(%d) = %v; want %v", loc, n, f, tc.form) } } } // Test decimals for _, s := range tc.decimal { a := strings.Split(s, "~") from, scale := parseFixedPoint(t, a[0]) to := from if len(a) > 1 { var toScale int if to, toScale = parseFixedPoint(t, a[1]); toScale != scale { t.Fatalf("%s:%s: non-matching scales %d versus %d", loc, s, scale, toScale) } } m := 1 for i := 0; i < scale; i++ { m *= 10 } for n := from; n <= to; n++ { if f := matchPlural(p, langIndex, n/m, n%m, scale); f != tc.form { t.Errorf("%[1]s:dec(%[2]d.%0[4]*[3]d) = %[5]v; want %[6]v", loc, n/m, n%m, scale, f, tc.form) } } } } } }
func TestFromTag(t *testing.T) { testCases := []struct { tag, currency string conf language.Confidence }{ {"nl", "EUR", language.Low}, // nl also spoken outside Euro land. {"nl-BE", "EUR", language.Exact}, // region is known {"pt", "BRL", language.Low}, {"en", "USD", language.Low}, {"en-u-cu-eur", "EUR", language.Exact}, {"tlh", "XXX", language.No}, // Klingon has no country. {"es-419", "XXX", language.No}, {"und", "USD", language.Low}, } for _, tc := range testCases { cur, conf := FromTag(language.MustParse(tc.tag)) if cur.String() != tc.currency || conf != tc.conf { t.Errorf("%s: got %v, %v; want %v, %v", tc.tag, cur, conf, tc.currency, tc.conf) } } }
func (home Home) Index(w http.ResponseWriter, r *http.Request) { templateFiles := []string{ "resource/view/layout/base.html", "resource/view/home/index.html", } tName := filepath.Base(templateFiles[0]) funcs := template.FuncMap{ "trans": home.i18n.TransTemplate, } b := model.Base{ "indexTitle", []byte(""), language.MustParse("es"), } p := &model.Index{ b, service.GetTopAdsDescOrder(10), } t, _ := template.New(tName).Funcs(funcs).ParseFiles(templateFiles...) t.ExecuteTemplate(w, tName, p) }
func TestRegion(t *testing.T) { tests := []struct { dict string reg string name string }{ {"nl", "NL", "Nederland"}, {"en", "US", "United States"}, {"en", "ZZ", "Unknown Region"}, {"en", "UM", "U.S. Outlying Islands"}, {"en-GB", "UM", "U.S. Outlying Islands"}, {"en-GB", "NL", "Netherlands"}, // Canonical equivalents {"en", "UK", "United Kingdom"}, // No region {"en", "pt", "Unknown Region"}, {"en", "und", "Unknown Region"}, // Don't introduce regions with canonicalization. {"en", "mo", "Unknown Region"}, } for i, tt := range tests { d := Regions(language.MustParse(tt.dict)) var x interface{} if unicode.IsUpper(rune(tt.reg[0])) { // Region x = language.MustParseRegion(tt.reg) tag, _ := language.Raw.Compose(x) if n := d.Name(tag); n != tt.name { t.Errorf("%d:%s:%s: was %q; want %q", i, tt.dict, tt.reg, n, tt.name) } } else { // Tag x = language.Raw.MustParse(tt.reg) } if n := d.Name(x); n != tt.name { t.Errorf("%d:%s:%s: was %q; want %q", i, tt.dict, tt.reg, n, tt.name) } } }
func TestScript(t *testing.T) { tests := []struct { dict string scr string name string }{ {"nl", "Arab", "Arabisch"}, {"en", "Arab", "Arabic"}, {"en", "Zzzz", "Unknown Script"}, {"zh-Hant", "Hang", "韓文字"}, {"zh-Hant-HK", "Hang", "韓文字"}, {"zh", "Arab", "阿拉伯文"}, {"zh-Hans-HK", "Arab", "阿拉伯文"}, // same as zh {"zh-Hant", "Arab", "阿拉伯文"}, {"zh-Hant-HK", "Arab", "阿拉伯文"}, // same as zh // Canonicalized form {"en", "Qaai", "Inherited"}, // deprecated script, now is Zinh {"en", "sh", "Unknown Script"}, // sh canonicalizes to sr-Latn {"en", "en", "Unknown Script"}, // Don't introduce scripts with canonicalization. {"en", "sh", "Unknown Script"}, // sh canonicalizes to sr-Latn } for i, tt := range tests { d := Scripts(language.MustParse(tt.dict)) var x interface{} if unicode.IsUpper(rune(tt.scr[0])) { x = language.MustParseScript(tt.scr) tag, _ := language.Raw.Compose(x) if n := d.Name(tag); n != tt.name { t.Errorf("%d:%s:%s: was %q; want %q", i, tt.dict, tt.scr, n, tt.name) } } else { x = language.Raw.MustParse(tt.scr) } if n := d.Name(x); n != tt.name { t.Errorf("%d:%s:%s: was %q; want %q", i, tt.dict, tt.scr, n, tt.name) } } }
func TestDictionaryLang(t *testing.T) { tests := []struct { d *Dictionary tag string name string }{ {English, "en", "English"}, {Portuguese, "af", "africâner"}, {EuropeanPortuguese, "af", "africânder"}, {English, "nl-BE", "Flemish"}, } for i, test := range tests { tag := language.MustParse(test.tag) if got := test.d.Tags().Name(tag); got != test.name { t.Errorf("%d:%v: got %s; want %s", i, tag, got, test.name) } if base, _ := language.Compose(tag.Base()); base == tag { if got := test.d.Languages().Name(base); got != test.name { t.Errorf("%d:%v: got %s; want %s", i, tag, got, test.name) } } } }
func TestCaseMappings(t *testing.T) { for i, tt := range testCases { src, ok := tt.src.([]string) if !ok { src = strings.Split(tt.src.(string), " ") } for _, lang := range strings.Split(tt.lang, " ") { tag := language.MustParse(lang) testEntry := func(name string, mk func(language.Tag, options) transform.Transformer, gold interface{}) { c := Caser{mk(tag, tt.opts)} if gold != nil { wants, ok := gold.([]string) if !ok { wants = strings.Split(gold.(string), " ") } for j, want := range wants { if got := c.String(src[j]); got != want { t.Errorf("%d:%s:\n%s.String(%+q):\ngot %+q;\nwant %+q", i, lang, name, src[j], got, want) } } } dst := make([]byte, 256) // big enough to hold any result src := []byte(strings.Join(src, " ")) v := testing.AllocsPerRun(20, func() { c.Transform(dst, src, true) }) if v > 1.1 { t.Errorf("%d:%s:\n%s: number of allocs was %f; want 0", i, lang, name, v) } } testEntry("Upper", makeUpper, tt.upper) testEntry("Lower", makeLower, tt.lower) testEntry("Title", makeTitle, tt.title) } } }
func TestAlternateSortTypes(t *testing.T) { testCases := []struct { lang string in []string want []string }{{ lang: "zh,cmn,zh-Hant-u-co-pinyin,zh-HK-u-co-pinyin,zh-pinyin", in: []string{"爸爸", "妈妈", "儿子", "女儿"}, want: []string{"爸爸", "儿子", "妈妈", "女儿"}, }, { lang: "zh-Hant,zh-u-co-stroke,zh-Hant-u-co-stroke", in: []string{"爸爸", "妈妈", "儿子", "女儿"}, want: []string{"儿子", "女儿", "妈妈", "爸爸"}, }} for _, tc := range testCases { for _, tag := range strings.Split(tc.lang, ",") { got := append([]string{}, tc.in...) New(language.MustParse(tag)).SortStrings(got) if !reflect.DeepEqual(got, tc.want) { t.Errorf("New(%s).SortStrings(%v) = %v; want %v", tag, tc.in, got, tc.want) } } } }
func TestUnique(t *testing.T) { testCases := []struct { in, want string }{ {"", "[]"}, {"en", "[en]"}, {"en en", "[en]"}, {"en en en", "[en]"}, {"en-u-cu-eur en", "[en en-u-cu-eur]"}, {"nl en", "[en nl]"}, {"pt-Pt pt", "[pt pt-PT]"}, } for _, tc := range testCases { tags := []language.Tag{} for _, s := range strings.Split(tc.in, " ") { if s != "" { tags = append(tags, language.MustParse(s)) } } if got := fmt.Sprint(UniqueTags(tags)); got != tc.want { t.Errorf("Unique(%s) = %s; want %s", tc.in, got, tc.want) } } }
func main() { r := gen.OpenCLDRCoreZip() defer r.Close() d := &cldr.Decoder{} data, err := d.DecodeZip(r) if err != nil { log.Fatalf("DecodeZip: %v", err) } w := gen.NewCodeWriter() defer w.WriteGoFile("tables.go", "internal") // Create parents table. parents := make([]uint16, language.NumCompactTags) for _, loc := range data.Locales() { tag := language.MustParse(loc) index, ok := language.CompactIndex(tag) if !ok { continue } parentIndex := 0 // und for p := tag.Parent(); p != language.Und; p = p.Parent() { if x, ok := language.CompactIndex(p); ok { parentIndex = x break } } parents[index] = uint16(parentIndex) } w.WriteComment(` Parent maps a compact index of a tag to the compact index of the parent of this tag.`) w.WriteVar("Parent", parents) }
// genSymbols generates the symbols used for currencies. Most symbols are // defined in root and there is only very small variation per language. // The following rules apply: // - A symbol can be requested as normal or narrow. // - If a symbol is not defined for a currency, it defaults to its ISO code. func (b *builder) genSymbols(w *gen.CodeWriter, data *cldr.CLDR) { d, err := cldr.ParseDraft(*draft) if err != nil { log.Fatalf("filter: %v", err) } const ( normal = iota narrow numTypes ) // language -> currency -> type -> symbol var symbols [language.NumCompactTags][][numTypes]*string // Collect symbol information per language. for _, lang := range data.Locales() { ldml := data.RawLDML(lang) if ldml.Numbers == nil || ldml.Numbers.Currencies == nil { continue } langIndex, ok := language.CompactIndex(language.MustParse(lang)) if !ok { log.Fatalf("No compact index for language %s", lang) } symbols[langIndex] = make([][numTypes]*string, b.numCurrencies+1) for _, c := range ldml.Numbers.Currencies.Currency { syms := cldr.MakeSlice(&c.Symbol) syms.SelectDraft(d) for _, sym := range c.Symbol { v := sym.Data() if v == c.Type { // We define "" to mean the ISO symbol. v = "" } cur := b.currencies.Index([]byte(c.Type)) // XXX gets reassigned to 0 in the package's code. if c.Type == "XXX" { cur = 0 } if cur == -1 { fmt.Println("Unsupported:", c.Type) continue } switch sym.Alt { case "": symbols[langIndex][cur][normal] = &v case "narrow": symbols[langIndex][cur][narrow] = &v } } } } // Remove values identical to the parent. for langIndex, data := range symbols { for curIndex, curs := range data { for typ, sym := range curs { if sym == nil { continue } for p := uint16(langIndex); p != 0; { p = internal.Parent[p] x := symbols[p] if x == nil { continue } if v := x[curIndex][typ]; v != nil || p == 0 { // Value is equal to the default value root value is undefined. parentSym := "" if v != nil { parentSym = *v } if parentSym == *sym { // Value is the same as parent. data[curIndex][typ] = nil } break } } } } } // Create symbol index. symbolData := []byte{0} symbolLookup := map[string]uint16{"": 0} // 0 means default, so block that value. for _, data := range symbols { for _, curs := range data { for _, sym := range curs { if sym == nil { continue } if _, ok := symbolLookup[*sym]; !ok { symbolLookup[*sym] = uint16(len(symbolData)) symbolData = append(symbolData, byte(len(*sym))) symbolData = append(symbolData, *sym...) } } } } w.WriteComment(` symbols holds symbol data of the form <n> <str>, where n is the length of the symbol string str.`) w.WriteConst("symbols", string(symbolData)) // Create index from language to currency lookup to symbol. type curToIndex struct{ cur, idx uint16 } w.WriteType(curToIndex{}) prefix := []string{"normal", "narrow"} // Create data for regular and narrow symbol data. for typ := normal; typ <= narrow; typ++ { indexes := []curToIndex{} // maps currency to symbol index languages := []uint16{} for _, data := range symbols { languages = append(languages, uint16(len(indexes))) for curIndex, curs := range data { if sym := curs[typ]; sym != nil { indexes = append(indexes, curToIndex{uint16(curIndex), symbolLookup[*sym]}) } } } languages = append(languages, uint16(len(indexes))) w.WriteVar(prefix[typ]+"LangIndex", languages) w.WriteVar(prefix[typ]+"SymIndex", indexes) } }