123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786 |
- // Copyright 2013 The Go Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- package language
- import (
- "reflect"
- "testing"
- )
- func TestTagSize(t *testing.T) {
- id := Tag{}
- typ := reflect.TypeOf(id)
- if typ.Size() > 24 {
- t.Errorf("size of Tag was %d; want 24", typ.Size())
- }
- }
- func TestIsRoot(t *testing.T) {
- loc := Tag{}
- if !loc.IsRoot() {
- t.Errorf("unspecified should be root.")
- }
- for i, tt := range parseTests() {
- loc, _ := Parse(tt.in)
- undef := tt.lang == "und" && tt.script == "" && tt.region == "" && tt.ext == ""
- if loc.IsRoot() != undef {
- t.Errorf("%d: was %v; want %v", i, loc.IsRoot(), undef)
- }
- }
- }
- func TestEquality(t *testing.T) {
- for i, tt := range parseTests() {
- s := tt.in
- tag := Make(s)
- t1 := Make(tag.String())
- if tag != t1 {
- t.Errorf("%d:%s: equality test 1 failed\n got: %#v\nwant: %#v)", i, s, t1, tag)
- }
- t2, _ := Compose(tag)
- if tag != t2 {
- t.Errorf("%d:%s: equality test 2 failed\n got: %#v\nwant: %#v", i, s, t2, tag)
- }
- }
- }
- func TestString(t *testing.T) {
- tests := []string{
- "no-u-rg-dkzzzz",
- }
- for i, s := range tests {
- tag := Make(s)
- if tag.String() != s {
- t.Errorf("%d:%s: got %s: want %s (%#v)", i, s, tag.String(), s, tag)
- }
- }
- }
- func TestMarshal(t *testing.T) {
- testCases := []string{
- // TODO: these values will change with each CLDR update. This issue
- // will be solved if we decide to fix the indexes.
- "und",
- "ca-ES-valencia",
- "ca-ES-valencia-u-va-posix",
- "ca-ES-valencia-u-co-phonebk",
- "ca-ES-valencia-u-co-phonebk-va-posix",
- "x-klingon",
- "en-US",
- "en-US-u-va-posix",
- "en",
- "en-u-co-phonebk",
- "en-001",
- "sh",
- "en-GB-u-rg-uszzzz",
- "en-GB-u-rg-uszzzz-va-posix",
- "en-GB-u-co-phonebk-rg-uszzzz",
- // Invalid tags should also roundtrip.
- "en-GB-u-co-phonebk-rg-uszz",
- }
- for _, tc := range testCases {
- var tag Tag
- err := tag.UnmarshalText([]byte(tc))
- if err != nil {
- t.Errorf("UnmarshalText(%q): unexpected error: %v", tc, err)
- }
- b, err := tag.MarshalText()
- if err != nil {
- t.Errorf("MarshalText(%q): unexpected error: %v", tc, err)
- }
- if got := string(b); got != tc {
- t.Errorf("%s: got %q; want %q", tc, got, tc)
- }
- }
- }
- func TestBase(t *testing.T) {
- tests := []struct {
- loc, lang string
- conf Confidence
- }{
- {"und", "en", Low},
- {"x-abc", "und", No},
- {"en", "en", Exact},
- {"und-Cyrl", "ru", High},
- // If a region is not included, the official language should be English.
- {"und-US", "en", High},
- // TODO: not-explicitly listed scripts should probably be und, No
- // Modify addTags to return info on how the match was derived.
- // {"und-Aghb", "und", No},
- }
- for i, tt := range tests {
- loc, _ := Parse(tt.loc)
- lang, conf := loc.Base()
- if lang.String() != tt.lang {
- t.Errorf("%d: language was %s; want %s", i, lang, tt.lang)
- }
- if conf != tt.conf {
- t.Errorf("%d: confidence was %d; want %d", i, conf, tt.conf)
- }
- }
- }
- func TestParseBase(t *testing.T) {
- tests := []struct {
- in string
- out string
- ok bool
- }{
- {"en", "en", true},
- {"EN", "en", true},
- {"nld", "nl", true},
- {"dut", "dut", true}, // bibliographic
- {"aaj", "und", false}, // unknown
- {"qaa", "qaa", true},
- {"a", "und", false},
- {"", "und", false},
- {"aaaa", "und", false},
- }
- for i, tt := range tests {
- x, err := ParseBase(tt.in)
- if x.String() != tt.out || err == nil != tt.ok {
- t.Errorf("%d:%s: was %s, %v; want %s, %v", i, tt.in, x, err == nil, tt.out, tt.ok)
- }
- if y, _, _ := Raw.Make(tt.out).Raw(); x != y {
- t.Errorf("%d:%s: tag was %s; want %s", i, tt.in, x, y)
- }
- }
- }
- func TestScript(t *testing.T) {
- tests := []struct {
- loc, scr string
- conf Confidence
- }{
- {"und", "Latn", Low},
- {"en-Latn", "Latn", Exact},
- {"en", "Latn", High},
- {"sr", "Cyrl", Low},
- {"kk", "Cyrl", High},
- {"kk-CN", "Arab", Low},
- {"cmn", "Hans", Low},
- {"ru", "Cyrl", High},
- {"ru-RU", "Cyrl", High},
- {"yue", "Hant", Low},
- {"x-abc", "Zzzz", Low},
- {"und-zyyy", "Zyyy", Exact},
- }
- for i, tt := range tests {
- loc, _ := Parse(tt.loc)
- sc, conf := loc.Script()
- if sc.String() != tt.scr {
- t.Errorf("%d:%s: script was %s; want %s", i, tt.loc, sc, tt.scr)
- }
- if conf != tt.conf {
- t.Errorf("%d:%s: confidence was %d; want %d", i, tt.loc, conf, tt.conf)
- }
- }
- }
- func TestParseScript(t *testing.T) {
- tests := []struct {
- in string
- out string
- ok bool
- }{
- {"Latn", "Latn", true},
- {"zzzz", "Zzzz", true},
- {"zyyy", "Zyyy", true},
- {"Latm", "Zzzz", false},
- {"Zzz", "Zzzz", false},
- {"", "Zzzz", false},
- {"Zzzxx", "Zzzz", false},
- }
- for i, tt := range tests {
- x, err := ParseScript(tt.in)
- if x.String() != tt.out || err == nil != tt.ok {
- t.Errorf("%d:%s: was %s, %v; want %s, %v", i, tt.in, x, err == nil, tt.out, tt.ok)
- }
- if err == nil {
- if _, y, _ := Raw.Make("und-" + tt.out).Raw(); x != y {
- t.Errorf("%d:%s: tag was %s; want %s", i, tt.in, x, y)
- }
- }
- }
- }
- func TestRegion(t *testing.T) {
- tests := []struct {
- loc, reg string
- conf Confidence
- }{
- {"und", "US", Low},
- {"en", "US", Low},
- {"zh-Hant", "TW", Low},
- {"en-US", "US", Exact},
- {"cmn", "CN", Low},
- {"ru", "RU", Low},
- {"yue", "HK", Low},
- {"x-abc", "ZZ", Low},
- }
- for i, tt := range tests {
- loc, _ := Raw.Parse(tt.loc)
- reg, conf := loc.Region()
- if reg.String() != tt.reg {
- t.Errorf("%d:%s: region was %s; want %s", i, tt.loc, reg, tt.reg)
- }
- if conf != tt.conf {
- t.Errorf("%d:%s: confidence was %d; want %d", i, tt.loc, conf, tt.conf)
- }
- }
- }
- func TestEncodeM49(t *testing.T) {
- tests := []struct {
- m49 int
- code string
- ok bool
- }{
- {1, "001", true},
- {840, "US", true},
- {899, "ZZ", false},
- }
- for i, tt := range tests {
- if r, err := EncodeM49(tt.m49); r.String() != tt.code || err == nil != tt.ok {
- t.Errorf("%d:%d: was %s, %v; want %s, %v", i, tt.m49, r, err == nil, tt.code, tt.ok)
- }
- }
- for i := 1; i <= 1000; i++ {
- if r, err := EncodeM49(i); err == nil && r.M49() == 0 {
- t.Errorf("%d has no error, but maps to undefined region", i)
- }
- }
- }
- func TestParseRegion(t *testing.T) {
- tests := []struct {
- in string
- out string
- ok bool
- }{
- {"001", "001", true},
- {"840", "US", true},
- {"899", "ZZ", false},
- {"USA", "US", true},
- {"US", "US", true},
- {"BC", "ZZ", false},
- {"C", "ZZ", false},
- {"CCCC", "ZZ", false},
- {"01", "ZZ", false},
- }
- for i, tt := range tests {
- r, err := ParseRegion(tt.in)
- if r.String() != tt.out || err == nil != tt.ok {
- t.Errorf("%d:%s: was %s, %v; want %s, %v", i, tt.in, r, err == nil, tt.out, tt.ok)
- }
- if err == nil {
- if _, _, y := Raw.Make("und-" + tt.out).Raw(); r != y {
- t.Errorf("%d:%s: tag was %s; want %s", i, tt.in, r, y)
- }
- }
- }
- }
- func TestIsCountry(t *testing.T) {
- tests := []struct {
- reg string
- country bool
- }{
- {"US", true},
- {"001", false},
- {"958", false},
- {"419", false},
- {"203", true},
- {"020", true},
- {"900", false},
- {"999", false},
- {"QO", false},
- {"EU", false},
- {"AA", false},
- {"XK", true},
- }
- for i, tt := range tests {
- r, _ := ParseRegion(tt.reg)
- if r.IsCountry() != tt.country {
- t.Errorf("%d: IsCountry(%s) was %v; want %v", i, tt.reg, r.IsCountry(), tt.country)
- }
- }
- }
- func TestIsGroup(t *testing.T) {
- tests := []struct {
- reg string
- group bool
- }{
- {"US", false},
- {"001", true},
- {"958", false},
- {"419", true},
- {"203", false},
- {"020", false},
- {"900", false},
- {"999", false},
- {"QO", true},
- {"EU", true},
- {"AA", false},
- {"XK", false},
- }
- for i, tt := range tests {
- r, _ := ParseRegion(tt.reg)
- if r.IsGroup() != tt.group {
- t.Errorf("%d: IsGroup(%s) was %v; want %v", i, tt.reg, r.IsGroup(), tt.group)
- }
- }
- }
- func TestContains(t *testing.T) {
- tests := []struct {
- enclosing, contained string
- contains bool
- }{
- // A region contains itself.
- {"US", "US", true},
- {"001", "001", true},
- // Direct containment.
- {"001", "002", true},
- {"039", "XK", true},
- {"150", "XK", true},
- {"EU", "AT", true},
- {"QO", "AQ", true},
- // Indirect containemnt.
- {"001", "US", true},
- {"001", "419", true},
- {"001", "013", true},
- // No containment.
- {"US", "001", false},
- {"155", "EU", false},
- }
- for i, tt := range tests {
- r := MustParseRegion(tt.enclosing)
- con := MustParseRegion(tt.contained)
- if got := r.Contains(con); got != tt.contains {
- t.Errorf("%d: %s.Contains(%s) was %v; want %v", i, tt.enclosing, tt.contained, got, tt.contains)
- }
- }
- }
- func TestRegionCanonicalize(t *testing.T) {
- for i, tt := range []struct{ in, out string }{
- {"UK", "GB"},
- {"TP", "TL"},
- {"QU", "EU"},
- {"SU", "SU"},
- {"VD", "VN"},
- {"DD", "DE"},
- } {
- r := MustParseRegion(tt.in)
- want := MustParseRegion(tt.out)
- if got := r.Canonicalize(); got != want {
- t.Errorf("%d: got %v; want %v", i, got, want)
- }
- }
- }
- func TestRegionTLD(t *testing.T) {
- for _, tt := range []struct {
- in, out string
- ok bool
- }{
- {"EH", "EH", true},
- {"FR", "FR", true},
- {"TL", "TL", true},
- // In ccTLD before in ISO.
- {"GG", "GG", true},
- // Non-standard assignment of ccTLD to ISO code.
- {"GB", "UK", true},
- // Exceptionally reserved in ISO and valid ccTLD.
- {"UK", "UK", true},
- {"AC", "AC", true},
- {"EU", "EU", true},
- {"SU", "SU", true},
- // Exceptionally reserved in ISO and invalid ccTLD.
- {"CP", "ZZ", false},
- {"DG", "ZZ", false},
- {"EA", "ZZ", false},
- {"FX", "ZZ", false},
- {"IC", "ZZ", false},
- {"TA", "ZZ", false},
- // Transitionally reserved in ISO (e.g. deprecated) but valid ccTLD as
- // it is still being phased out.
- {"AN", "AN", true},
- {"TP", "TP", true},
- // Transitionally reserved in ISO (e.g. deprecated) and invalid ccTLD.
- // Defined in package language as it has a mapping in CLDR.
- {"BU", "ZZ", false},
- {"CS", "ZZ", false},
- {"NT", "ZZ", false},
- {"YU", "ZZ", false},
- {"ZR", "ZZ", false},
- // Not defined in package: SF.
- // Indeterminately reserved in ISO.
- // Defined in package language as it has a legacy mapping in CLDR.
- {"DY", "ZZ", false},
- {"RH", "ZZ", false},
- {"VD", "ZZ", false},
- // Not defined in package: EW, FL, JA, LF, PI, RA, RB, RC, RI, RL, RM,
- // RN, RP, WG, WL, WV, and YV.
- // Not assigned in ISO, but legacy definitions in CLDR.
- {"DD", "ZZ", false},
- {"YD", "ZZ", false},
- // Normal mappings but somewhat special status in ccTLD.
- {"BL", "BL", true},
- {"MF", "MF", true},
- {"BV", "BV", true},
- {"SJ", "SJ", true},
- // Have values when normalized, but not as is.
- {"QU", "ZZ", false},
- // ISO Private Use.
- {"AA", "ZZ", false},
- {"QM", "ZZ", false},
- {"QO", "ZZ", false},
- {"XA", "ZZ", false},
- {"XK", "ZZ", false}, // Sometimes used for Kosovo, but invalid ccTLD.
- } {
- if tt.in == "" {
- continue
- }
- r := MustParseRegion(tt.in)
- var want Region
- if tt.out != "ZZ" {
- want = MustParseRegion(tt.out)
- }
- tld, err := r.TLD()
- if got := err == nil; got != tt.ok {
- t.Errorf("error(%v): got %v; want %v", r, got, tt.ok)
- }
- if tld != want {
- t.Errorf("TLD(%v): got %v; want %v", r, tld, want)
- }
- }
- }
- func TestCanonicalize(t *testing.T) {
- // TODO: do a full test using CLDR data in a separate regression test.
- tests := []struct {
- in, out string
- option CanonType
- }{
- {"en-Latn", "en", SuppressScript},
- {"sr-Cyrl", "sr-Cyrl", SuppressScript},
- {"sh", "sr-Latn", Legacy},
- {"sh-HR", "sr-Latn-HR", Legacy},
- {"sh-Cyrl-HR", "sr-Cyrl-HR", Legacy},
- {"tl", "fil", Legacy},
- {"no", "no", Legacy},
- {"no", "nb", Legacy | CLDR},
- {"cmn", "cmn", Legacy},
- {"cmn", "zh", Macro},
- {"cmn-u-co-stroke", "zh-u-co-stroke", Macro},
- {"yue", "yue", Macro},
- {"nb", "no", Macro},
- {"nb", "nb", Macro | CLDR},
- {"no", "no", Macro},
- {"no", "no", Macro | CLDR},
- {"iw", "he", DeprecatedBase},
- {"iw", "he", Deprecated | CLDR},
- {"mo", "ro-MD", Deprecated}, // Adopted by CLDR as of version 25.
- {"alb", "sq", Legacy}, // bibliographic
- {"dut", "nl", Legacy}, // bibliographic
- // As of CLDR 25, mo is no longer considered a legacy mapping.
- {"mo", "mo", Legacy | CLDR},
- {"und-AN", "und-AN", Deprecated},
- {"und-YD", "und-YE", DeprecatedRegion},
- {"und-YD", "und-YD", DeprecatedBase},
- {"und-Qaai", "und-Zinh", DeprecatedScript},
- {"und-Qaai", "und-Qaai", DeprecatedBase},
- {"drh", "mn", All}, // drh -> khk -> mn
- {"en-GB-u-rg-uszzzz", "en-GB-u-rg-uszzzz", Raw},
- {"en-GB-u-rg-USZZZZ", "en-GB-u-rg-uszzzz", Raw},
- // TODO: use different exact values for language and regional tag?
- {"en-GB-u-rg-uszzzz-va-posix", "en-GB-u-rg-uszzzz-va-posix", Raw},
- {"en-GB-u-rg-uszzzz-co-phonebk", "en-GB-u-co-phonebk-rg-uszzzz", Raw},
- // Invalid region specifications are left as is.
- {"en-GB-u-rg-usz", "en-GB-u-rg-usz", Raw},
- {"en-GB-u-rg-usz-va-posix", "en-GB-u-rg-usz-va-posix", Raw},
- {"en-GB-u-rg-usz-co-phonebk", "en-GB-u-co-phonebk-rg-usz", Raw},
- // CVE-2020-28851
- // invalid key-value pair of -u- extension.
- {"ES-u-000-00", "es-u-000-00", Raw},
- {"ES-u-000-00-v-00", "es-u-000-00-v-00", Raw},
- // reordered and unknown extension.
- {"ES-v-00-u-000-00", "es-u-000-00-v-00", Raw},
- }
- for i, tt := range tests {
- in, _ := Raw.Parse(tt.in)
- in, _ = tt.option.Canonicalize(in)
- if in.String() != tt.out {
- t.Errorf("%d:%s: was %s; want %s", i, tt.in, in.String(), tt.out)
- }
- }
- // Test idempotence.
- for _, base := range Supported.BaseLanguages() {
- tag, _ := Raw.Compose(base)
- got, _ := All.Canonicalize(tag)
- want, _ := All.Canonicalize(got)
- if got != want {
- t.Errorf("idem(%s): got %s; want %s", tag, got, want)
- }
- }
- }
- func TestTypeForKey(t *testing.T) {
- tests := []struct{ key, in, out string }{
- {"co", "en", ""},
- {"co", "en-u-abc", ""},
- {"co", "en-u-co-phonebk", "phonebk"},
- {"co", "en-u-co-phonebk-cu-aud", "phonebk"},
- {"co", "x-foo-u-co-phonebk", ""},
- {"va", "en-US-u-va-posix", "posix"},
- {"rg", "en-u-rg-gbzzzz", "gbzzzz"},
- {"nu", "en-u-co-phonebk-nu-arabic", "arabic"},
- {"kc", "cmn-u-co-stroke", ""},
- {"rg", "cmn-u-rg", ""},
- {"rg", "cmn-u-rg-co-stroke", ""},
- {"co", "cmn-u-rg-co-stroke", "stroke"},
- {"co", "cmn-u-co-rg-gbzzzz", ""},
- {"rg", "cmn-u-co-rg-gbzzzz", "gbzzzz"},
- {"rg", "cmn-u-rg-gbzzzz-nlzzzz", "gbzzzz"},
- }
- for _, tt := range tests {
- if v := Make(tt.in).TypeForKey(tt.key); v != tt.out {
- t.Errorf("%q[%q]: was %q; want %q", tt.in, tt.key, v, tt.out)
- }
- }
- }
- func TestParent(t *testing.T) {
- tests := []struct{ in, out string }{
- // Strip variants and extensions first
- {"de-u-co-phonebk", "de"},
- {"de-1994", "de"},
- {"de-Latn-1994", "de"}, // remove superfluous script.
- // Ensure the canonical Tag for an entry is in the chain for base-script
- // pairs.
- {"zh-Hans", "zh"},
- // Skip the script if it is the maximized version. CLDR files for the
- // skipped tag are always empty.
- {"zh-Hans-TW", "zh"},
- {"zh-Hans-CN", "zh"},
- // Insert the script if the maximized script is not the same as the
- // maximized script of the base language.
- {"zh-TW", "zh-Hant"},
- {"zh-HK", "zh-Hant"},
- {"zh-Hant-TW", "zh-Hant"},
- {"zh-Hant-HK", "zh-Hant"},
- // Non-default script skips to und.
- // CLDR
- {"az-Cyrl", "und"},
- {"bs-Cyrl", "und"},
- {"en-Dsrt", "und"},
- {"ha-Arab", "und"},
- {"mn-Mong", "und"},
- {"pa-Arab", "und"},
- {"shi-Latn", "und"},
- {"sr-Latn", "und"},
- {"uz-Arab", "und"},
- {"uz-Cyrl", "und"},
- {"vai-Latn", "und"},
- {"zh-Hant", "und"},
- // extra
- {"nl-Cyrl", "und"},
- // World english inherits from en-001.
- {"en-150", "en-001"},
- {"en-AU", "en-001"},
- {"en-BE", "en-001"},
- {"en-GG", "en-001"},
- {"en-GI", "en-001"},
- {"en-HK", "en-001"},
- {"en-IE", "en-001"},
- {"en-IM", "en-001"},
- {"en-IN", "en-001"},
- {"en-JE", "en-001"},
- {"en-MT", "en-001"},
- {"en-NZ", "en-001"},
- {"en-PK", "en-001"},
- {"en-SG", "en-001"},
- // Spanish in Latin-American countries have es-419 as parent.
- {"es-AR", "es-419"},
- {"es-BO", "es-419"},
- {"es-CL", "es-419"},
- {"es-CO", "es-419"},
- {"es-CR", "es-419"},
- {"es-CU", "es-419"},
- {"es-DO", "es-419"},
- {"es-EC", "es-419"},
- {"es-GT", "es-419"},
- {"es-HN", "es-419"},
- {"es-MX", "es-419"},
- {"es-NI", "es-419"},
- {"es-PA", "es-419"},
- {"es-PE", "es-419"},
- {"es-PR", "es-419"},
- {"es-PY", "es-419"},
- {"es-SV", "es-419"},
- {"es-US", "es-419"},
- {"es-UY", "es-419"},
- {"es-VE", "es-419"},
- // exceptions (according to CLDR)
- {"es-CW", "es"},
- // Inherit from pt-PT, instead of pt for these countries.
- {"pt-AO", "pt-PT"},
- {"pt-CV", "pt-PT"},
- {"pt-GW", "pt-PT"},
- {"pt-MO", "pt-PT"},
- {"pt-MZ", "pt-PT"},
- {"pt-ST", "pt-PT"},
- {"pt-TL", "pt-PT"},
- {"en-GB-u-co-phonebk-rg-uszzzz", "en-GB"},
- {"en-GB-u-rg-uszzzz", "en-GB"},
- {"en-US-u-va-posix", "en-US"},
- // Difference between language and regional tag.
- {"ca-ES-valencia", "ca-ES"},
- {"ca-ES-valencia-u-rg-ptzzzz", "ca-ES"},
- {"en-US-u-va-variant", "en-US"},
- {"en-u-va-variant", "en"},
- {"en-u-rg-gbzzzz", "en"},
- {"en-US-u-rg-gbzzzz", "en-US"},
- {"nl-US-u-rg-gbzzzz", "nl-US"},
- }
- for _, tt := range tests {
- tag := Raw.MustParse(tt.in)
- if p := Raw.MustParse(tt.out); p != tag.Parent() {
- t.Errorf("%s: was %v; want %v", tt.in, tag.Parent(), p)
- }
- }
- }
- var (
- // Tags without error that don't need to be changed.
- benchBasic = []string{
- "en",
- "en-Latn",
- "en-GB",
- "za",
- "zh-Hant",
- "zh",
- "zh-HK",
- "ar-MK",
- "en-CA",
- "fr-CA",
- "fr-CH",
- "fr",
- "lv",
- "he-IT",
- "tlh",
- "ja",
- "ja-Jpan",
- "ja-Jpan-JP",
- "de-1996",
- "de-CH",
- "sr",
- "sr-Latn",
- }
- // Tags with extensions, not changes required.
- benchExt = []string{
- "x-a-b-c-d",
- "x-aa-bbbb-cccccccc-d",
- "en-x_cc-b-bbb-a-aaa",
- "en-c_cc-b-bbb-a-aaa-x-x",
- "en-u-co-phonebk",
- "en-Cyrl-u-co-phonebk",
- "en-US-u-co-phonebk-cu-xau",
- "en-nedix-u-co-phonebk",
- "en-t-t0-abcd",
- "en-t-nl-latn",
- "en-t-t0-abcd-x-a",
- }
- // Change, but not memory allocation required.
- benchSimpleChange = []string{
- "EN",
- "i-klingon",
- "en-latn",
- "zh-cmn-Hans-CN",
- "iw-NL",
- }
- // Change and memory allocation required.
- benchChangeAlloc = []string{
- "en-c_cc-b-bbb-a-aaa",
- "en-u-cu-xua-co-phonebk",
- "en-u-cu-xua-co-phonebk-a-cd",
- "en-u-def-abc-cu-xua-co-phonebk",
- "en-t-en-Cyrl-NL-1994",
- "en-t-en-Cyrl-NL-1994-t0-abc-def",
- }
- // Tags that result in errors.
- benchErr = []string{
- // IllFormed
- "x_A.-B-C_D",
- "en-u-cu-co-phonebk",
- "en-u-cu-xau-co",
- "en-t-nl-abcd",
- // Invalid
- "xx",
- "nl-Uuuu",
- "nl-QB",
- }
- benchChange = append(benchSimpleChange, benchChangeAlloc...)
- benchAll = append(append(append(benchBasic, benchExt...), benchChange...), benchErr...)
- )
- func doParse(b *testing.B, tag []string) {
- for i := 0; i < b.N; i++ {
- // Use the modulo instead of looping over all tags so that we get a somewhat
- // meaningful ns/op.
- Parse(tag[i%len(tag)])
- }
- }
- func BenchmarkParse(b *testing.B) {
- doParse(b, benchAll)
- }
- func BenchmarkParseBasic(b *testing.B) {
- doParse(b, benchBasic)
- }
- func BenchmarkParseError(b *testing.B) {
- doParse(b, benchErr)
- }
- func BenchmarkParseSimpleChange(b *testing.B) {
- doParse(b, benchSimpleChange)
- }
- func BenchmarkParseChangeAlloc(b *testing.B) {
- doParse(b, benchChangeAlloc)
- }
|