123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457 |
- // 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 (
- "testing"
- "golang.org/x/text/internal/tag"
- )
- func b(s string) []byte {
- return []byte(s)
- }
- func TestLangID(t *testing.T) {
- tests := []struct {
- id, bcp47, iso3, norm string
- err error
- }{
- {id: "", bcp47: "und", iso3: "und", err: ErrSyntax},
- {id: " ", bcp47: "und", iso3: "und", err: ErrSyntax},
- {id: " ", bcp47: "und", iso3: "und", err: ErrSyntax},
- {id: " ", bcp47: "und", iso3: "und", err: ErrSyntax},
- {id: "xxx", bcp47: "und", iso3: "und", err: NewValueError([]byte("xxx"))},
- {id: "und", bcp47: "und", iso3: "und"},
- {id: "aju", bcp47: "aju", iso3: "aju", norm: "jrb"},
- {id: "jrb", bcp47: "jrb", iso3: "jrb"},
- {id: "es", bcp47: "es", iso3: "spa"},
- {id: "spa", bcp47: "es", iso3: "spa"},
- {id: "ji", bcp47: "ji", iso3: "yid-", norm: "yi"},
- {id: "jw", bcp47: "jw", iso3: "jav-", norm: "jv"},
- {id: "ar", bcp47: "ar", iso3: "ara"},
- {id: "kw", bcp47: "kw", iso3: "cor"},
- {id: "arb", bcp47: "arb", iso3: "arb", norm: "ar"},
- {id: "ar", bcp47: "ar", iso3: "ara"},
- {id: "kur", bcp47: "ku", iso3: "kur"},
- {id: "nl", bcp47: "nl", iso3: "nld"},
- {id: "NL", bcp47: "nl", iso3: "nld"},
- {id: "gsw", bcp47: "gsw", iso3: "gsw"},
- {id: "gSW", bcp47: "gsw", iso3: "gsw"},
- {id: "und", bcp47: "und", iso3: "und"},
- {id: "sh", bcp47: "sh", iso3: "hbs", norm: "sr"},
- {id: "hbs", bcp47: "sh", iso3: "hbs", norm: "sr"},
- {id: "no", bcp47: "no", iso3: "nor", norm: "no"},
- {id: "nor", bcp47: "no", iso3: "nor", norm: "no"},
- {id: "cmn", bcp47: "cmn", iso3: "cmn", norm: "zh"},
- }
- for i, tt := range tests {
- want, err := getLangID(b(tt.id))
- if err != tt.err {
- t.Errorf("%d:err(%s): found %q; want %q", i, tt.id, err, tt.err)
- }
- if err != nil {
- continue
- }
- if id, _ := getLangISO2(b(tt.bcp47)); len(tt.bcp47) == 2 && want != id {
- t.Errorf("%d:getISO2(%s): found %v; want %v", i, tt.bcp47, id, want)
- }
- if len(tt.iso3) == 3 {
- if id, _ := getLangISO3(b(tt.iso3)); want != id {
- t.Errorf("%d:getISO3(%s): found %q; want %q", i, tt.iso3, id, want)
- }
- if id, _ := getLangID(b(tt.iso3)); want != id {
- t.Errorf("%d:getID3(%s): found %v; want %v", i, tt.iso3, id, want)
- }
- }
- norm := want
- if tt.norm != "" {
- norm, _ = getLangID(b(tt.norm))
- }
- id, _ := normLang(want)
- if id != norm {
- t.Errorf("%d:norm(%s): found %v; want %v", i, tt.id, id, norm)
- }
- if id := want.String(); tt.bcp47 != id {
- t.Errorf("%d:String(): found %s; want %s", i, id, tt.bcp47)
- }
- if id := want.ISO3(); tt.iso3[:3] != id {
- t.Errorf("%d:iso3(): found %s; want %s", i, id, tt.iso3[:3])
- }
- }
- }
- func TestGrandfathered(t *testing.T) {
- for _, tt := range []struct{ in, out string }{
- {"art-lojban", "jbo"},
- {"i-ami", "ami"},
- {"i-bnn", "bnn"},
- {"i-hak", "hak"},
- {"i-klingon", "tlh"},
- {"i-lux", "lb"},
- {"i-navajo", "nv"},
- {"i-pwn", "pwn"},
- {"i-tao", "tao"},
- {"i-tay", "tay"},
- {"i-tsu", "tsu"},
- {"no-bok", "nb"},
- {"no-nyn", "nn"},
- {"sgn-BE-FR", "sfb"},
- {"sgn-BE-NL", "vgt"},
- {"sgn-CH-DE", "sgg"},
- {"sgn-ch-de", "sgg"},
- {"zh-guoyu", "cmn"},
- {"zh-hakka", "hak"},
- {"zh-min-nan", "nan"},
- {"zh-xiang", "hsn"},
- // Grandfathered tags with no modern replacement will be converted as follows:
- {"cel-gaulish", "xtg-x-cel-gaulish"},
- {"en-GB-oed", "en-GB-oxendict"},
- {"en-gb-oed", "en-GB-oxendict"},
- {"i-default", "en-x-i-default"},
- {"i-enochian", "und-x-i-enochian"},
- {"i-mingo", "see-x-i-mingo"},
- {"zh-min", "nan-x-zh-min"},
- {"root", "und"},
- {"en_US_POSIX", "en-US-u-va-posix"},
- {"en_us_posix", "en-US-u-va-posix"},
- {"en-us-posix", "en-US-u-va-posix"},
- } {
- got := Make(tt.in)
- want := MustParse(tt.out)
- if got != want {
- t.Errorf("%s: got %q; want %q", tt.in, got, want)
- }
- }
- }
- func TestRegionID(t *testing.T) {
- tests := []struct {
- in, out string
- }{
- {"_ ", ""},
- {"_000", ""},
- {"419", "419"},
- {"AA", "AA"},
- {"ATF", "TF"},
- {"HV", "HV"},
- {"CT", "CT"},
- {"DY", "DY"},
- {"IC", "IC"},
- {"FQ", "FQ"},
- {"JT", "JT"},
- {"ZZ", "ZZ"},
- {"EU", "EU"},
- {"QO", "QO"},
- {"FX", "FX"},
- }
- for i, tt := range tests {
- if tt.in[0] == '_' {
- id := tt.in[1:]
- if _, err := getRegionID(b(id)); err == nil {
- t.Errorf("%d:err(%s): found nil; want error", i, id)
- }
- continue
- }
- want, _ := getRegionID(b(tt.in))
- if s := want.String(); s != tt.out {
- t.Errorf("%d:%s: found %q; want %q", i, tt.in, s, tt.out)
- }
- if len(tt.in) == 2 {
- want, _ := getRegionISO2(b(tt.in))
- if s := want.String(); s != tt.out {
- t.Errorf("%d:getISO2(%s): found %q; want %q", i, tt.in, s, tt.out)
- }
- }
- }
- }
- func TestRegionType(t *testing.T) {
- for _, tt := range []struct {
- r string
- t byte
- }{
- {"NL", bcp47Region | ccTLD},
- {"EU", bcp47Region | ccTLD}, // exceptionally reserved
- {"AN", bcp47Region | ccTLD}, // transitionally reserved
- {"DD", bcp47Region}, // deleted in ISO, deprecated in BCP 47
- {"NT", bcp47Region}, // transitionally reserved, deprecated in BCP 47
- {"XA", iso3166UserAssigned | bcp47Region},
- {"ZZ", iso3166UserAssigned | bcp47Region},
- {"AA", iso3166UserAssigned | bcp47Region},
- {"QO", iso3166UserAssigned | bcp47Region},
- {"QM", iso3166UserAssigned | bcp47Region},
- {"XK", iso3166UserAssigned | bcp47Region},
- {"CT", 0}, // deleted in ISO, not in BCP 47, canonicalized in CLDR
- } {
- r := MustParseRegion(tt.r)
- if tp := r.typ(); tp != tt.t {
- t.Errorf("Type(%s): got %x; want %x", tt.r, tp, tt.t)
- }
- }
- }
- func TestRegionISO3(t *testing.T) {
- tests := []struct {
- from, iso3, to string
- }{
- {" ", "ZZZ", "ZZ"},
- {"000", "ZZZ", "ZZ"},
- {"AA", "AAA", ""},
- {"CT", "CTE", ""},
- {"DY", "DHY", ""},
- {"EU", "QUU", ""},
- {"HV", "HVO", ""},
- {"IC", "ZZZ", "ZZ"},
- {"JT", "JTN", ""},
- {"PZ", "PCZ", ""},
- {"QU", "QUU", "EU"},
- {"QO", "QOO", ""},
- {"YD", "YMD", ""},
- {"FQ", "ATF", "TF"},
- {"TF", "ATF", ""},
- {"FX", "FXX", ""},
- {"ZZ", "ZZZ", ""},
- {"419", "ZZZ", "ZZ"},
- }
- for _, tt := range tests {
- r, _ := getRegionID(b(tt.from))
- if s := r.ISO3(); s != tt.iso3 {
- t.Errorf("iso3(%q): found %q; want %q", tt.from, s, tt.iso3)
- }
- if tt.iso3 == "" {
- continue
- }
- want := tt.to
- if tt.to == "" {
- want = tt.from
- }
- r, _ = getRegionID(b(want))
- if id, _ := getRegionISO3(b(tt.iso3)); id != r {
- t.Errorf("%s: found %q; want %q", tt.iso3, id, want)
- }
- }
- }
- func TestRegionM49(t *testing.T) {
- fromTests := []struct {
- m49 int
- id string
- }{
- {0, ""},
- {-1, ""},
- {1000, ""},
- {10000, ""},
- {001, "001"},
- {104, "MM"},
- {180, "CD"},
- {230, "ET"},
- {231, "ET"},
- {249, "FX"},
- {250, "FR"},
- {276, "DE"},
- {278, "DD"},
- {280, "DE"},
- {419, "419"},
- {626, "TL"},
- {736, "SD"},
- {840, "US"},
- {854, "BF"},
- {891, "CS"},
- {899, ""},
- {958, "AA"},
- {966, "QT"},
- {967, "EU"},
- {999, "ZZ"},
- }
- for _, tt := range fromTests {
- id, err := getRegionM49(tt.m49)
- if want, have := err != nil, tt.id == ""; want != have {
- t.Errorf("error(%d): have %v; want %v", tt.m49, have, want)
- continue
- }
- r, _ := getRegionID(b(tt.id))
- if r != id {
- t.Errorf("region(%d): have %s; want %s", tt.m49, id, r)
- }
- }
- toTests := []struct {
- m49 int
- id string
- }{
- {0, "000"},
- {0, "IC"}, // Some codes don't have an ID
- {001, "001"},
- {104, "MM"},
- {104, "BU"},
- {180, "CD"},
- {180, "ZR"},
- {231, "ET"},
- {250, "FR"},
- {249, "FX"},
- {276, "DE"},
- {278, "DD"},
- {419, "419"},
- {626, "TL"},
- {626, "TP"},
- {729, "SD"},
- {826, "GB"},
- {840, "US"},
- {854, "BF"},
- {891, "YU"},
- {891, "CS"},
- {958, "AA"},
- {966, "QT"},
- {967, "EU"},
- {967, "QU"},
- {999, "ZZ"},
- // For codes that don't have an M49 code use the replacement value,
- // if available.
- {854, "HV"}, // maps to Burkino Faso
- }
- for _, tt := range toTests {
- r, _ := getRegionID(b(tt.id))
- if r.M49() != tt.m49 {
- t.Errorf("m49(%q): have %d; want %d", tt.id, r.M49(), tt.m49)
- }
- }
- }
- func TestRegionDeprecation(t *testing.T) {
- tests := []struct{ in, out string }{
- {"BU", "MM"},
- {"BUR", "MM"},
- {"CT", "KI"},
- {"DD", "DE"},
- {"DDR", "DE"},
- {"DY", "BJ"},
- {"FX", "FR"},
- {"HV", "BF"},
- {"JT", "UM"},
- {"MI", "UM"},
- {"NH", "VU"},
- {"NQ", "AQ"},
- {"PU", "UM"},
- {"PZ", "PA"},
- {"QU", "EU"},
- {"RH", "ZW"},
- {"TP", "TL"},
- {"UK", "GB"},
- {"VD", "VN"},
- {"WK", "UM"},
- {"YD", "YE"},
- {"NL", "NL"},
- }
- for _, tt := range tests {
- rIn, _ := getRegionID([]byte(tt.in))
- rOut, _ := getRegionISO2([]byte(tt.out))
- r := normRegion(rIn)
- if rOut == rIn && r != 0 {
- t.Errorf("%s: was %q; want %q", tt.in, r, tt.in)
- }
- if rOut != rIn && r != rOut {
- t.Errorf("%s: was %q; want %q", tt.in, r, tt.out)
- }
- }
- }
- func TestGetScriptID(t *testing.T) {
- idx := tag.Index("0000BbbbDdddEeeeZzzz\xff\xff\xff\xff")
- tests := []struct {
- in string
- out Script
- }{
- {" ", 0},
- {" ", 0},
- {" ", 0},
- {"", 0},
- {"Aaaa", 0},
- {"Bbbb", 1},
- {"Dddd", 2},
- {"dddd", 2},
- {"dDDD", 2},
- {"Eeee", 3},
- {"Zzzz", 4},
- }
- for i, tt := range tests {
- if id, err := getScriptID(idx, b(tt.in)); id != tt.out {
- t.Errorf("%d:%s: found %d; want %d", i, tt.in, id, tt.out)
- } else if id == 0 && err == nil {
- t.Errorf("%d:%s: no error; expected one", i, tt.in)
- }
- }
- }
- func TestIsPrivateUse(t *testing.T) {
- type test struct {
- s string
- private bool
- }
- tests := []test{
- {"en", false},
- {"und", false},
- {"pzn", false},
- {"qaa", true},
- {"qtz", true},
- {"qua", false},
- }
- for i, tt := range tests {
- x, _ := getLangID([]byte(tt.s))
- if b := x.IsPrivateUse(); b != tt.private {
- t.Errorf("%d: langID.IsPrivateUse(%s) was %v; want %v", i, tt.s, b, tt.private)
- }
- }
- tests = []test{
- {"001", false},
- {"419", false},
- {"899", false},
- {"900", false},
- {"957", false},
- {"958", true},
- {"AA", true},
- {"AC", false},
- {"EU", false}, // CLDR grouping, exceptionally reserved in ISO.
- {"QU", true}, // Canonicalizes to EU, User-assigned in ISO.
- {"QO", true}, // CLDR grouping, User-assigned in ISO.
- {"QA", false},
- {"QM", true},
- {"QZ", true},
- {"XA", true},
- {"XK", true}, // Assigned to Kosovo in CLDR, User-assigned in ISO.
- {"XZ", true},
- {"ZW", false},
- {"ZZ", true},
- }
- for i, tt := range tests {
- x, _ := getRegionID([]byte(tt.s))
- if b := x.IsPrivateUse(); b != tt.private {
- t.Errorf("%d: regionID.IsPrivateUse(%s) was %v; want %v", i, tt.s, b, tt.private)
- }
- }
- tests = []test{
- {"Latn", false},
- {"Laaa", false}, // invalid
- {"Qaaa", true},
- {"Qabx", true},
- {"Qaby", false},
- {"Zyyy", false},
- {"Zzzz", false},
- }
- for i, tt := range tests {
- x, _ := getScriptID(script, []byte(tt.s))
- if b := x.IsPrivateUse(); b != tt.private {
- t.Errorf("%d: scriptID.IsPrivateUse(%s) was %v; want %v", i, tt.s, b, tt.private)
- }
- }
- }
|