golang.org/x/text@v0.14.0/language/display/display_test.go (about) 1 // Copyright 2014 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 display 6 7 import ( 8 "fmt" 9 "reflect" 10 "strings" 11 "testing" 12 "unicode" 13 14 "golang.org/x/text/internal/testtext" 15 "golang.org/x/text/language" 16 "golang.org/x/text/message" 17 ) 18 19 // TODO: test that tables are properly dropped by the linker for various use 20 // cases. 21 22 var ( 23 firstLang2aa = language.MustParseBase("aa") 24 lastLang2zu = language.MustParseBase("zu") 25 firstLang3ace = language.MustParseBase("ace") 26 lastLang3zza = language.MustParseBase("zza") 27 firstTagAr001 = language.MustParse("ar-001") 28 lastTagZhHant = language.MustParse("zh-Hant") 29 ) 30 31 // TestValues tests that for all languages, regions, and scripts in Values, at 32 // least one language has a name defined for it by checking it exists in 33 // English, which is assumed to be the most comprehensive. It is also tested 34 // that a Namer returns "" for unsupported values. 35 func TestValues(t *testing.T) { 36 type testcase struct { 37 kind string 38 n Namer 39 } 40 // checkDefined checks that a value exists in a Namer. 41 checkDefined := func(x interface{}, namers []testcase) { 42 for _, n := range namers { 43 testtext.Run(t, fmt.Sprintf("%s.Name(%s)", n.kind, x), func(t *testing.T) { 44 if n.n.Name(x) == "" { 45 // As of version 28 there is no data for az-Arab in English, 46 // although there is useful data in other languages. 47 if x.(fmt.Stringer).String() == "az-Arab" { 48 return 49 } 50 t.Errorf("supported but no result") 51 } 52 }) 53 } 54 } 55 // checkUnsupported checks that a value does not exist in a Namer. 56 checkUnsupported := func(x interface{}, namers []testcase) { 57 for _, n := range namers { 58 if got := n.n.Name(x); got != "" { 59 t.Fatalf("%s.Name(%s): unsupported tag gave non-empty result: %q", n.kind, x, got) 60 } 61 } 62 } 63 64 tags := map[language.Tag]bool{} 65 namers := []testcase{ 66 {"Languages(en)", Languages(language.English)}, 67 {"Tags(en)", Tags(language.English)}, 68 {"English.Languages()", English.Languages()}, 69 {"English.Tags()", English.Tags()}, 70 } 71 for _, tag := range Values.Tags() { 72 checkDefined(tag, namers) 73 tags[tag] = true 74 } 75 for _, base := range language.Supported.BaseLanguages() { 76 tag, _ := language.All.Compose(base) 77 if !tags[tag] { 78 checkUnsupported(tag, namers) 79 } 80 } 81 82 regions := map[language.Region]bool{} 83 namers = []testcase{ 84 {"Regions(en)", Regions(language.English)}, 85 {"English.Regions()", English.Regions()}, 86 } 87 for _, r := range Values.Regions() { 88 checkDefined(r, namers) 89 regions[r] = true 90 } 91 for _, r := range language.Supported.Regions() { 92 if r = r.Canonicalize(); !regions[r] { 93 checkUnsupported(r, namers) 94 } 95 } 96 97 scripts := map[language.Script]bool{} 98 namers = []testcase{ 99 {"Scripts(en)", Scripts(language.English)}, 100 {"English.Scripts()", English.Scripts()}, 101 } 102 for _, s := range Values.Scripts() { 103 checkDefined(s, namers) 104 scripts[s] = true 105 } 106 for _, s := range language.Supported.Scripts() { 107 // Canonicalize the script. 108 tag, _ := language.DeprecatedScript.Compose(s) 109 if _, s, _ = tag.Raw(); !scripts[s] { 110 checkUnsupported(s, namers) 111 } 112 } 113 } 114 115 // TestSupported tests that we have at least some Namers for languages that we 116 // claim to support. To test the claims in the documentation, it also verifies 117 // that if a Namer is returned, it will have at least some data. 118 func TestSupported(t *testing.T) { 119 supportedTags := Supported.Tags() 120 if len(supportedTags) != numSupported { 121 t.Errorf("number of supported was %d; want %d", len(supportedTags), numSupported) 122 } 123 124 namerFuncs := []struct { 125 kind string 126 fn func(language.Tag) Namer 127 }{ 128 {"Tags", Tags}, 129 {"Languages", Languages}, 130 {"Regions", Regions}, 131 {"Scripts", Scripts}, 132 } 133 134 // Verify that we have at least one Namer for all tags we claim to support. 135 tags := make(map[language.Tag]bool) 136 for _, tag := range supportedTags { 137 // Test we have at least one Namer for this supported Tag. 138 found := false 139 for _, kind := range namerFuncs { 140 if defined(t, kind.kind, kind.fn(tag), tag) { 141 found = true 142 } 143 } 144 if !found { 145 t.Errorf("%s: supported, but no data available", tag) 146 } 147 if tags[tag] { 148 t.Errorf("%s: included in Supported.Tags more than once", tag) 149 } 150 tags[tag] = true 151 } 152 153 // Verify that we have no Namers for tags we don't claim to support. 154 for _, base := range language.Supported.BaseLanguages() { 155 tag, _ := language.All.Compose(base) 156 // Skip tags that are supported after matching. 157 if _, _, conf := matcher.Match(tag); conf != language.No { 158 continue 159 } 160 // Test there are no Namers for this tag. 161 for _, kind := range namerFuncs { 162 if defined(t, kind.kind, kind.fn(tag), tag) { 163 t.Errorf("%[1]s(%[2]s) returns a Namer, but %[2]s is not in the set of supported Tags.", kind.kind, tag) 164 } 165 } 166 } 167 } 168 169 // defined reports whether n is a proper Namer, which means it is non-nil and 170 // must have at least one non-empty value. 171 func defined(t *testing.T, kind string, n Namer, tag language.Tag) bool { 172 if n == nil { 173 return false 174 } 175 switch kind { 176 case "Tags": 177 for _, t := range Values.Tags() { 178 if n.Name(t) != "" { 179 return true 180 } 181 } 182 case "Languages": 183 for _, t := range Values.BaseLanguages() { 184 if n.Name(t) != "" { 185 return true 186 } 187 } 188 case "Regions": 189 for _, t := range Values.Regions() { 190 if n.Name(t) != "" { 191 return true 192 } 193 } 194 case "Scripts": 195 for _, t := range Values.Scripts() { 196 if n.Name(t) != "" { 197 return true 198 } 199 } 200 } 201 t.Errorf("%s(%s) returns non-nil Namer without content", kind, tag) 202 return false 203 } 204 205 func TestCoverage(t *testing.T) { 206 en := language.English 207 tests := []struct { 208 n Namer 209 x interface{} 210 }{ 211 {Languages(en), Values.Tags()}, 212 {Scripts(en), Values.Scripts()}, 213 {Regions(en), Values.Regions()}, 214 } 215 for i, tt := range tests { 216 uniq := make(map[string]interface{}) 217 218 v := reflect.ValueOf(tt.x) 219 for j := 0; j < v.Len(); j++ { 220 x := v.Index(j).Interface() 221 // As of version 28 there is no data for az-Arab in English, 222 // although there is useful data in other languages. 223 if x.(fmt.Stringer).String() == "az-Arab" { 224 continue 225 } 226 s := tt.n.Name(x) 227 if s == "" { 228 t.Errorf("%d:%d:%s: missing content", i, j, x) 229 } else if uniq[s] != nil { 230 t.Errorf("%d:%d:%s: identical return value %q for %v and %v", i, j, x, s, x, uniq[s]) 231 } 232 uniq[s] = x 233 } 234 } 235 } 236 237 // TestUpdate tests whether dictionary entries for certain languages need to be 238 // updated. For some languages, some of the headers may be empty or they may be 239 // identical to the parent. This code detects if such entries need to be updated 240 // after a table update. 241 func TestUpdate(t *testing.T) { 242 tests := []struct { 243 d *Dictionary 244 tag string 245 }{ 246 {ModernStandardArabic, "ar-001"}, 247 {AmericanEnglish, "en-US"}, 248 {EuropeanSpanish, "es-ES"}, 249 {BrazilianPortuguese, "pt-BR"}, 250 {SimplifiedChinese, "zh-Hans"}, 251 } 252 253 for _, tt := range tests { 254 _, i, _ := matcher.Match(language.MustParse(tt.tag)) 255 if !reflect.DeepEqual(tt.d.lang, langHeaders[i]) { 256 t.Errorf("%s: lang table update needed", tt.tag) 257 } 258 if !reflect.DeepEqual(tt.d.script, scriptHeaders[i]) { 259 t.Errorf("%s: script table update needed", tt.tag) 260 } 261 if !reflect.DeepEqual(tt.d.region, regionHeaders[i]) { 262 t.Errorf("%s: region table update needed", tt.tag) 263 } 264 } 265 } 266 267 func TestIndex(t *testing.T) { 268 notIn := []string{"aa", "xx", "zz", "aaa", "xxx", "zzz", "Aaaa", "Xxxx", "Zzzz"} 269 tests := []tagIndex{ 270 { 271 "", 272 "", 273 "", 274 }, 275 { 276 "bb", 277 "", 278 "", 279 }, 280 { 281 "", 282 "bbb", 283 "", 284 }, 285 { 286 "", 287 "", 288 "Bbbb", 289 }, 290 { 291 "bb", 292 "bbb", 293 "Bbbb", 294 }, 295 { 296 "bbccddyy", 297 "bbbcccdddyyy", 298 "BbbbCcccDdddYyyy", 299 }, 300 } 301 for i, tt := range tests { 302 // Create the test set from the tagIndex. 303 cnt := 0 304 for sz := 2; sz <= 4; sz++ { 305 a := tt[sz-2] 306 for j := 0; j < len(a); j += sz { 307 s := a[j : j+sz] 308 if idx := tt.index(s); idx != cnt { 309 t.Errorf("%d:%s: index was %d; want %d", i, s, idx, cnt) 310 } 311 cnt++ 312 } 313 } 314 if n := tt.len(); n != cnt { 315 t.Errorf("%d: len was %d; want %d", i, n, cnt) 316 } 317 for _, x := range notIn { 318 if idx := tt.index(x); idx != -1 { 319 t.Errorf("%d:%s: index was %d; want -1", i, x, idx) 320 } 321 } 322 } 323 } 324 325 func TestTag(t *testing.T) { 326 tests := []struct { 327 dict string 328 tag string 329 name string 330 }{ 331 // sr is in Value.Languages(), but is not supported by agq. 332 {"agq", "sr", "|[language: sr]"}, 333 {"nl", "nl", "Nederlands"}, 334 // CLDR 30 dropped Vlaams as the word for nl-BE. It is still called 335 // Flemish in English, though. TODO: check if this is a CLDR bug. 336 // {"nl", "nl-BE", "Vlaams"}, 337 {"nl", "nl-BE", "Nederlands (België)"}, 338 {"nl", "vls", "West-Vlaams"}, 339 {"en", "nl-BE", "Flemish"}, 340 {"en", "en", "English"}, 341 {"en", "en-GB", "British English"}, 342 {"en", "en-US", "American English"}, // American English in CLDR 24+ 343 {"ru", "ru", "русский"}, 344 {"ru", "ru-RU", "русский (Россия)"}, 345 {"ru", "ru-Cyrl", "русский (кириллица)"}, 346 {"en", lastLang2zu.String(), "Zulu"}, 347 {"en", firstLang2aa.String(), "Afar"}, 348 {"en", lastLang3zza.String(), "Zaza"}, 349 {"en", firstLang3ace.String(), "Achinese"}, 350 {"en", firstTagAr001.String(), "Modern Standard Arabic"}, 351 {"en", lastTagZhHant.String(), "Traditional Chinese"}, 352 {"en", "aaa", "|Unknown language (aaa)"}, 353 {"en", "zzj", "|Unknown language (zzj)"}, 354 // If full tag doesn't match, try without script or region. 355 {"en", "aa-Hans", "Afar (Simplified Han)"}, 356 {"en", "af-Arab", "Afrikaans (Arabic)"}, 357 {"en", "zu-Cyrl", "Zulu (Cyrillic)"}, 358 {"en", "aa-GB", "Afar (United Kingdom)"}, 359 {"en", "af-NA", "Afrikaans (Namibia)"}, 360 {"en", "zu-BR", "Zulu (Brazil)"}, 361 // Correct inheritance and language selection. 362 {"zh", "zh-TW", "中文 (台湾)"}, 363 {"zh", "zh-Hant-TW", "繁体中文 (台湾)"}, 364 {"zh-Hant", "zh-TW", "中文 (台灣)"}, 365 {"zh-Hant", "zh-Hant-TW", "繁體中文 (台灣)"}, 366 // Some rather arbitrary interpretations for Serbian. This is arguably 367 // correct and consistent with the way zh-[Hant-]TW is handled. It will 368 // also give results more in line with the expectations if users 369 // explicitly use "sh". 370 {"sr-Latn", "sr-ME", "srpski (Crna Gora)"}, 371 {"sr-Latn", "sr-Latn-ME", "srpskohrvatski (Crna Gora)"}, 372 // Double script and region 373 {"nl", "en-Cyrl-BE", "Engels (Cyrillisch, België)"}, 374 } 375 for _, tt := range tests { 376 t.Run(tt.dict+"/"+tt.tag, func(t *testing.T) { 377 name, fmtName := splitName(tt.name) 378 dict := language.MustParse(tt.dict) 379 tag := language.Raw.MustParse(tt.tag) 380 d := Tags(dict) 381 if n := d.Name(tag); n != name { 382 // There are inconsistencies w.r.t. capitalization in the tests 383 // due to CLDR's update procedure which treats modern and other 384 // languages differently. 385 // See https://unicode.org/cldr/trac/ticket/8051. 386 // TODO: use language capitalization to sanitize the strings. 387 t.Errorf("Name(%s) = %q; want %q", tag, n, name) 388 } 389 390 p := message.NewPrinter(dict) 391 if n := p.Sprint(Tag(tag)); n != fmtName { 392 t.Errorf("Tag(%s) = %q; want %q", tag, n, fmtName) 393 } 394 }) 395 } 396 } 397 398 func splitName(names string) (name, formatName string) { 399 split := strings.Split(names, "|") 400 name, formatName = split[0], split[0] 401 if len(split) > 1 { 402 formatName = split[1] 403 } 404 return name, formatName 405 } 406 407 func TestLanguage(t *testing.T) { 408 tests := []struct { 409 dict string 410 tag string 411 name string 412 }{ 413 // sr is in Value.Languages(), but is not supported by agq. 414 {"agq", "sr", "|[language: sr]"}, 415 // CLDR 30 dropped Vlaams as the word for nl-BE. It is still called 416 // Flemish in English, though. TODO: this is probably incorrect. 417 // West-Vlaams (vls) is not Vlaams. West-Vlaams could be considered its 418 // own language, whereas Vlaams is generally Dutch. So expect to have 419 // to change these tests back. 420 {"nl", "nl", "Nederlands"}, 421 {"nl", "vls", "West-Vlaams"}, 422 {"nl", "nl-BE", "Nederlands"}, 423 {"en", "pt", "Portuguese"}, 424 {"en", "pt-PT", "European Portuguese"}, 425 {"en", "pt-BR", "Brazilian Portuguese"}, 426 {"en", "en", "English"}, 427 {"en", "en-GB", "British English"}, 428 {"en", "en-US", "American English"}, // American English in CLDR 24+ 429 {"en", lastLang2zu.String(), "Zulu"}, 430 {"en", firstLang2aa.String(), "Afar"}, 431 {"en", lastLang3zza.String(), "Zaza"}, 432 {"en", firstLang3ace.String(), "Achinese"}, 433 {"en", firstTagAr001.String(), "Modern Standard Arabic"}, 434 {"en", lastTagZhHant.String(), "Traditional Chinese"}, 435 {"en", "aaa", "|Unknown language (aaa)"}, 436 {"en", "zzj", "|Unknown language (zzj)"}, 437 // If full tag doesn't match, try without script or region. 438 {"en", "aa-Hans", "Afar"}, 439 {"en", "af-Arab", "Afrikaans"}, 440 {"en", "zu-Cyrl", "Zulu"}, 441 {"en", "aa-GB", "Afar"}, 442 {"en", "af-NA", "Afrikaans"}, 443 {"en", "zu-BR", "Zulu"}, 444 {"agq", "zh-Hant", "|[language: zh-Hant]"}, 445 {"en", "sh", "Serbo-Croatian"}, 446 {"en", "sr-Latn", "Serbo-Croatian"}, 447 {"en", "sr", "Serbian"}, 448 {"en", "sr-ME", "Serbian"}, 449 {"en", "sr-Latn-ME", "Serbo-Croatian"}, // See comments in TestTag. 450 } 451 for _, tt := range tests { 452 testtext.Run(t, tt.dict+"/"+tt.tag, func(t *testing.T) { 453 name, fmtName := splitName(tt.name) 454 dict := language.MustParse(tt.dict) 455 tag := language.Raw.MustParse(tt.tag) 456 p := message.NewPrinter(dict) 457 d := Languages(dict) 458 if n := d.Name(tag); n != name { 459 t.Errorf("Name(%v) = %q; want %q", tag, n, name) 460 } 461 if n := p.Sprint(Language(tag)); n != fmtName { 462 t.Errorf("Language(%v) = %q; want %q", tag, n, fmtName) 463 } 464 if len(tt.tag) <= 3 { 465 base := language.MustParseBase(tt.tag) 466 if n := d.Name(base); n != name { 467 t.Errorf("Name(%v) = %q; want %q", base, n, name) 468 } 469 if n := p.Sprint(Language(base)); n != fmtName { 470 t.Errorf("Language(%v) = %q; want %q", base, n, fmtName) 471 } 472 } 473 }) 474 } 475 } 476 477 func TestScript(t *testing.T) { 478 tests := []struct { 479 dict string 480 scr string 481 name string 482 }{ 483 {"nl", "Arab", "Arabisch"}, 484 {"en", "Arab", "Arabic"}, 485 {"en", "Zzzz", "Unknown Script"}, 486 {"zh-Hant", "Hang", "韓文字"}, 487 {"zh-Hant-HK", "Hang", "韓文字"}, 488 {"zh", "Arab", "阿拉伯文"}, 489 {"zh-Hans-HK", "Arab", "阿拉伯文"}, // same as zh 490 {"zh-Hant", "Arab", "阿拉伯文"}, 491 {"zh-Hant-HK", "Arab", "阿拉伯文"}, // same as zh 492 // Canonicalized form 493 {"en", "Qaai", "Inherited"}, // deprecated script, now is Zinh 494 {"en", "sh", "Unknown Script"}, // sh canonicalizes to sr-Latn 495 {"en", "en", "Unknown Script"}, 496 // Don't introduce scripts with canonicalization. 497 {"en", "sh", "Unknown Script"}, // sh canonicalizes to sr-Latn 498 } 499 for _, tt := range tests { 500 t.Run(tt.dict+"/"+tt.scr, func(t *testing.T) { 501 name, fmtName := splitName(tt.name) 502 dict := language.MustParse(tt.dict) 503 p := message.NewPrinter(dict) 504 d := Scripts(dict) 505 var tag language.Tag 506 if unicode.IsUpper(rune(tt.scr[0])) { 507 x := language.MustParseScript(tt.scr) 508 if n := d.Name(x); n != name { 509 t.Errorf("Name(%v) = %q; want %q", x, n, name) 510 } 511 if n := p.Sprint(Script(x)); n != fmtName { 512 t.Errorf("Script(%v) = %q; want %q", x, n, fmtName) 513 } 514 tag, _ = language.Raw.Compose(x) 515 } else { 516 tag = language.Raw.MustParse(tt.scr) 517 } 518 if n := d.Name(tag); n != name { 519 t.Errorf("Name(%v) = %q; want %q", tag, n, name) 520 } 521 if n := p.Sprint(Script(tag)); n != fmtName { 522 t.Errorf("Script(%v) = %q; want %q", tag, n, fmtName) 523 } 524 }) 525 } 526 } 527 528 func TestRegion(t *testing.T) { 529 tests := []struct { 530 dict string 531 reg string 532 name string 533 }{ 534 {"nl", "NL", "Nederland"}, 535 {"en", "US", "United States"}, 536 {"en", "ZZ", "Unknown Region"}, 537 {"en-GB", "NL", "Netherlands"}, 538 // Canonical equivalents 539 {"en", "UK", "United Kingdom"}, 540 // No region 541 {"en", "pt", "Unknown Region"}, 542 {"en", "und", "Unknown Region"}, 543 // Don't introduce regions with canonicalization. 544 {"en", "mo", "Unknown Region"}, 545 } 546 for _, tt := range tests { 547 t.Run(tt.dict+"/"+tt.reg, func(t *testing.T) { 548 dict := language.MustParse(tt.dict) 549 p := message.NewPrinter(dict) 550 d := Regions(dict) 551 var tag language.Tag 552 if unicode.IsUpper(rune(tt.reg[0])) { 553 // Region 554 x := language.MustParseRegion(tt.reg) 555 if n := d.Name(x); n != tt.name { 556 t.Errorf("Name(%v) = %q; want %q", x, n, tt.name) 557 } 558 if n := p.Sprint(Region(x)); n != tt.name { 559 t.Errorf("Region(%v) = %q; want %q", x, n, tt.name) 560 } 561 tag, _ = language.Raw.Compose(x) 562 } else { 563 tag = language.Raw.MustParse(tt.reg) 564 } 565 if n := d.Name(tag); n != tt.name { 566 t.Errorf("Name(%v) = %q; want %q", tag, n, tt.name) 567 } 568 if n := p.Sprint(Region(tag)); n != tt.name { 569 t.Errorf("Region(%v) = %q; want %q", tag, n, tt.name) 570 } 571 }) 572 } 573 } 574 575 func TestSelf(t *testing.T) { 576 tests := []struct { 577 tag string 578 name string 579 }{ 580 {"nl", "Nederlands"}, 581 // CLDR 30 dropped Vlaams as the word for nl-BE. It is still called 582 // Flemish in English, though. TODO: check if this is a CLDR bug. 583 // {"nl-BE", "Vlaams"}, 584 {"nl-BE", "Nederlands"}, 585 {"en-GB", "British English"}, 586 {lastLang2zu.String(), "isiZulu"}, 587 {firstLang2aa.String(), ""}, // not defined 588 {lastLang3zza.String(), ""}, // not defined 589 {firstLang3ace.String(), ""}, // not defined 590 {firstTagAr001.String(), "العربية الرسمية الحديثة"}, 591 {"ar", "العربية"}, 592 {lastTagZhHant.String(), "繁體中文"}, 593 {"aaa", ""}, 594 {"zzj", ""}, 595 // Drop entries that are not in the requested script, even if there is 596 // an entry for the language. 597 {"aa-Hans", ""}, 598 {"af-Arab", ""}, 599 {"zu-Cyrl", ""}, 600 // Append the country name in the language of the matching language. 601 {"af-NA", "Afrikaans"}, 602 {"zh", "中文"}, 603 // zh-TW should match zh-Hant instead of zh! 604 {"zh-TW", "繁體中文"}, 605 {"zh-Hant", "繁體中文"}, 606 {"zh-Hans", "简体中文"}, 607 {"zh-Hant-TW", "繁體中文"}, 608 {"zh-Hans-TW", "简体中文"}, 609 // Take the entry for sr which has the matching script. 610 // TODO: Capitalization changed as of CLDR 26, but change seems 611 // arbitrary. Revisit capitalization with revision 27. See 612 // https://unicode.org/cldr/trac/ticket/8051. 613 {"sr", "српски"}, 614 // TODO: sr-ME should show up as Serbian or Montenegrin, not Serbo- 615 // Croatian. This is an artifact of the current algorithm, which is the 616 // way it is to have the preferred behavior for other languages such as 617 // Chinese. We can hardwire this case in the table generator or package 618 // code, but we first check if CLDR can be updated. 619 // {"sr-ME", "Srpski"}, // Is Srpskohrvatski 620 {"sr-Latn-ME", "srpskohrvatski"}, 621 {"sr-Cyrl-ME", "српски"}, 622 {"sr-NL", "српски"}, 623 // NOTE: kk is defined, but in Cyrillic script. For China, Arab is the 624 // dominant script. We do not have data for kk-Arab and we chose to not 625 // fall back in such cases. 626 {"kk-CN", ""}, 627 } 628 for i, tt := range tests { 629 d := Self 630 if n := d.Name(language.Raw.MustParse(tt.tag)); n != tt.name { 631 t.Errorf("%d:%s: was %q; want %q", i, tt.tag, n, tt.name) 632 } 633 } 634 } 635 636 func TestEquivalence(t *testing.T) { 637 testCases := []struct { 638 desc string 639 namer Namer 640 }{ 641 {"Self", Self}, 642 {"Tags", Tags(language.Romanian)}, 643 {"Languages", Languages(language.Romanian)}, 644 {"Scripts", Scripts(language.Romanian)}, 645 } 646 for _, tc := range testCases { 647 t.Run(tc.desc, func(t *testing.T) { 648 ro := tc.namer.Name(language.Raw.MustParse("ro-MD")) 649 mo := tc.namer.Name(language.Raw.MustParse("mo")) 650 if ro != mo { 651 t.Errorf("%q != %q", ro, mo) 652 } 653 }) 654 } 655 } 656 657 func TestDictionaryLang(t *testing.T) { 658 tests := []struct { 659 d *Dictionary 660 tag string 661 name string 662 }{ 663 {English, "en", "English"}, 664 {Portuguese, "af", "africâner"}, 665 {EuropeanPortuguese, "af", "africanês"}, 666 {English, "nl-BE", "Flemish"}, 667 } 668 for i, test := range tests { 669 tag := language.MustParse(test.tag) 670 if got := test.d.Tags().Name(tag); got != test.name { 671 t.Errorf("%d:%v: got %s; want %s", i, tag, got, test.name) 672 } 673 if base, _ := language.Compose(tag.Base()); base == tag { 674 if got := test.d.Languages().Name(base); got != test.name { 675 t.Errorf("%d:%v: got %s; want %s", i, tag, got, test.name) 676 } 677 } 678 } 679 } 680 681 func TestDictionaryRegion(t *testing.T) { 682 tests := []struct { 683 d *Dictionary 684 region string 685 name string 686 }{ 687 {English, "FR", "France"}, 688 {Portuguese, "009", "Oceania"}, 689 {EuropeanPortuguese, "009", "Oceânia"}, 690 } 691 for i, test := range tests { 692 tag := language.MustParseRegion(test.region) 693 if got := test.d.Regions().Name(tag); got != test.name { 694 t.Errorf("%d:%v: got %s; want %s", i, tag, got, test.name) 695 } 696 } 697 } 698 699 func TestDictionaryScript(t *testing.T) { 700 tests := []struct { 701 d *Dictionary 702 script string 703 name string 704 }{ 705 {English, "Cyrl", "Cyrillic"}, 706 {EuropeanPortuguese, "Gujr", "guzerate"}, 707 } 708 for i, test := range tests { 709 tag := language.MustParseScript(test.script) 710 if got := test.d.Scripts().Name(tag); got != test.name { 711 t.Errorf("%d:%v: got %s; want %s", i, tag, got, test.name) 712 } 713 } 714 }