Update go dependencies
This commit is contained in:
parent
15ffb51394
commit
bb4d483837
1621 changed files with 86368 additions and 284392 deletions
154
vendor/golang.org/x/text/language/coverage_test.go
generated
vendored
154
vendor/golang.org/x/text/language/coverage_test.go
generated
vendored
|
|
@ -1,154 +0,0 @@
|
|||
// Copyright 2014 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 (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSupported(t *testing.T) {
|
||||
// To prove the results are correct for a type, we test that the number of
|
||||
// results is identical to the number of results on record, that all results
|
||||
// are distinct and that all results are valid.
|
||||
tests := map[string]int{
|
||||
"BaseLanguages": numLanguages,
|
||||
"Scripts": numScripts,
|
||||
"Regions": numRegions,
|
||||
"Tags": 0,
|
||||
}
|
||||
sup := reflect.ValueOf(Supported)
|
||||
for name, num := range tests {
|
||||
v := sup.MethodByName(name).Call(nil)[0]
|
||||
if n := v.Len(); n != num {
|
||||
t.Errorf("len(%s()) was %d; want %d", name, n, num)
|
||||
}
|
||||
dup := make(map[string]bool)
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
x := v.Index(i).Interface()
|
||||
// An invalid value will either cause a crash or result in a
|
||||
// duplicate when passed to Sprint.
|
||||
s := fmt.Sprint(x)
|
||||
if dup[s] {
|
||||
t.Errorf("%s: duplicate entry %q", name, s)
|
||||
}
|
||||
dup[s] = true
|
||||
}
|
||||
if len(dup) != v.Len() {
|
||||
t.Errorf("%s: # unique entries was %d; want %d", name, len(dup), v.Len())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewCoverage(t *testing.T) {
|
||||
bases := []Base{Base{0}, Base{3}, Base{7}}
|
||||
scripts := []Script{Script{11}, Script{17}, Script{23}}
|
||||
regions := []Region{Region{101}, Region{103}, Region{107}}
|
||||
tags := []Tag{Make("pt"), Make("en"), Make("en-GB"), Make("en-US"), Make("pt-PT")}
|
||||
fbases := func() []Base { return bases }
|
||||
fscripts := func() []Script { return scripts }
|
||||
fregions := func() []Region { return regions }
|
||||
ftags := func() []Tag { return tags }
|
||||
|
||||
tests := []struct {
|
||||
desc string
|
||||
list []interface{}
|
||||
bases []Base
|
||||
scripts []Script
|
||||
regions []Region
|
||||
tags []Tag
|
||||
}{
|
||||
{
|
||||
desc: "empty",
|
||||
},
|
||||
{
|
||||
desc: "bases",
|
||||
list: []interface{}{bases},
|
||||
bases: bases,
|
||||
},
|
||||
{
|
||||
desc: "scripts",
|
||||
list: []interface{}{scripts},
|
||||
scripts: scripts,
|
||||
},
|
||||
{
|
||||
desc: "regions",
|
||||
list: []interface{}{regions},
|
||||
regions: regions,
|
||||
},
|
||||
{
|
||||
desc: "bases derives from tags",
|
||||
list: []interface{}{tags},
|
||||
bases: []Base{Base{_en}, Base{_pt}},
|
||||
tags: tags,
|
||||
},
|
||||
{
|
||||
desc: "tags and bases",
|
||||
list: []interface{}{tags, bases},
|
||||
bases: bases,
|
||||
tags: tags,
|
||||
},
|
||||
{
|
||||
desc: "fully specified",
|
||||
list: []interface{}{tags, bases, scripts, regions},
|
||||
bases: bases,
|
||||
scripts: scripts,
|
||||
regions: regions,
|
||||
tags: tags,
|
||||
},
|
||||
{
|
||||
desc: "bases func",
|
||||
list: []interface{}{fbases},
|
||||
bases: bases,
|
||||
},
|
||||
{
|
||||
desc: "scripts func",
|
||||
list: []interface{}{fscripts},
|
||||
scripts: scripts,
|
||||
},
|
||||
{
|
||||
desc: "regions func",
|
||||
list: []interface{}{fregions},
|
||||
regions: regions,
|
||||
},
|
||||
{
|
||||
desc: "tags func",
|
||||
list: []interface{}{ftags},
|
||||
bases: []Base{Base{_en}, Base{_pt}},
|
||||
tags: tags,
|
||||
},
|
||||
{
|
||||
desc: "tags and bases",
|
||||
list: []interface{}{ftags, fbases},
|
||||
bases: bases,
|
||||
tags: tags,
|
||||
},
|
||||
{
|
||||
desc: "fully specified",
|
||||
list: []interface{}{ftags, fbases, fscripts, fregions},
|
||||
bases: bases,
|
||||
scripts: scripts,
|
||||
regions: regions,
|
||||
tags: tags,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tt := range tests {
|
||||
l := NewCoverage(tt.list...)
|
||||
if a := l.BaseLanguages(); !reflect.DeepEqual(a, tt.bases) {
|
||||
t.Errorf("%d:%s: BaseLanguages was %v; want %v", i, tt.desc, a, tt.bases)
|
||||
}
|
||||
if a := l.Scripts(); !reflect.DeepEqual(a, tt.scripts) {
|
||||
t.Errorf("%d:%s: Scripts was %v; want %v", i, tt.desc, a, tt.scripts)
|
||||
}
|
||||
if a := l.Regions(); !reflect.DeepEqual(a, tt.regions) {
|
||||
t.Errorf("%d:%s: Regions was %v; want %v", i, tt.desc, a, tt.regions)
|
||||
}
|
||||
if a := l.Tags(); !reflect.DeepEqual(a, tt.tags) {
|
||||
t.Errorf("%d:%s: Tags was %v; want %v", i, tt.desc, a, tt.tags)
|
||||
}
|
||||
}
|
||||
}
|
||||
413
vendor/golang.org/x/text/language/examples_test.go
generated
vendored
413
vendor/golang.org/x/text/language/examples_test.go
generated
vendored
|
|
@ -1,413 +0,0 @@
|
|||
// 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_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
func ExampleCanonType() {
|
||||
p := func(id string) {
|
||||
fmt.Printf("Default(%s) -> %s\n", id, language.Make(id))
|
||||
fmt.Printf("BCP47(%s) -> %s\n", id, language.BCP47.Make(id))
|
||||
fmt.Printf("Macro(%s) -> %s\n", id, language.Macro.Make(id))
|
||||
fmt.Printf("All(%s) -> %s\n", id, language.All.Make(id))
|
||||
}
|
||||
p("en-Latn")
|
||||
p("sh")
|
||||
p("zh-cmn")
|
||||
p("bjd")
|
||||
p("iw-Latn-fonipa-u-cu-usd")
|
||||
// Output:
|
||||
// Default(en-Latn) -> en-Latn
|
||||
// BCP47(en-Latn) -> en
|
||||
// Macro(en-Latn) -> en-Latn
|
||||
// All(en-Latn) -> en
|
||||
// Default(sh) -> sr-Latn
|
||||
// BCP47(sh) -> sh
|
||||
// Macro(sh) -> sh
|
||||
// All(sh) -> sr-Latn
|
||||
// Default(zh-cmn) -> cmn
|
||||
// BCP47(zh-cmn) -> cmn
|
||||
// Macro(zh-cmn) -> zh
|
||||
// All(zh-cmn) -> zh
|
||||
// Default(bjd) -> drl
|
||||
// BCP47(bjd) -> drl
|
||||
// Macro(bjd) -> bjd
|
||||
// All(bjd) -> drl
|
||||
// Default(iw-Latn-fonipa-u-cu-usd) -> he-Latn-fonipa-u-cu-usd
|
||||
// BCP47(iw-Latn-fonipa-u-cu-usd) -> he-Latn-fonipa-u-cu-usd
|
||||
// Macro(iw-Latn-fonipa-u-cu-usd) -> iw-Latn-fonipa-u-cu-usd
|
||||
// All(iw-Latn-fonipa-u-cu-usd) -> he-Latn-fonipa-u-cu-usd
|
||||
}
|
||||
|
||||
func ExampleTag_Base() {
|
||||
fmt.Println(language.Make("und").Base())
|
||||
fmt.Println(language.Make("und-US").Base())
|
||||
fmt.Println(language.Make("und-NL").Base())
|
||||
fmt.Println(language.Make("und-419").Base()) // Latin America
|
||||
fmt.Println(language.Make("und-ZZ").Base())
|
||||
// Output:
|
||||
// en Low
|
||||
// en High
|
||||
// nl High
|
||||
// es Low
|
||||
// en Low
|
||||
}
|
||||
|
||||
func ExampleTag_Script() {
|
||||
en := language.Make("en")
|
||||
sr := language.Make("sr")
|
||||
sr_Latn := language.Make("sr_Latn")
|
||||
fmt.Println(en.Script())
|
||||
fmt.Println(sr.Script())
|
||||
// Was a script explicitly specified?
|
||||
_, c := sr.Script()
|
||||
fmt.Println(c == language.Exact)
|
||||
_, c = sr_Latn.Script()
|
||||
fmt.Println(c == language.Exact)
|
||||
// Output:
|
||||
// Latn High
|
||||
// Cyrl Low
|
||||
// false
|
||||
// true
|
||||
}
|
||||
|
||||
func ExampleTag_Region() {
|
||||
ru := language.Make("ru")
|
||||
en := language.Make("en")
|
||||
fmt.Println(ru.Region())
|
||||
fmt.Println(en.Region())
|
||||
// Output:
|
||||
// RU Low
|
||||
// US Low
|
||||
}
|
||||
|
||||
func ExampleRegion_TLD() {
|
||||
us := language.MustParseRegion("US")
|
||||
gb := language.MustParseRegion("GB")
|
||||
uk := language.MustParseRegion("UK")
|
||||
bu := language.MustParseRegion("BU")
|
||||
|
||||
fmt.Println(us.TLD())
|
||||
fmt.Println(gb.TLD())
|
||||
fmt.Println(uk.TLD())
|
||||
fmt.Println(bu.TLD())
|
||||
|
||||
fmt.Println(us.Canonicalize().TLD())
|
||||
fmt.Println(gb.Canonicalize().TLD())
|
||||
fmt.Println(uk.Canonicalize().TLD())
|
||||
fmt.Println(bu.Canonicalize().TLD())
|
||||
// Output:
|
||||
// US <nil>
|
||||
// UK <nil>
|
||||
// UK <nil>
|
||||
// ZZ language: region is not a valid ccTLD
|
||||
// US <nil>
|
||||
// UK <nil>
|
||||
// UK <nil>
|
||||
// MM <nil>
|
||||
}
|
||||
|
||||
func ExampleCompose() {
|
||||
nl, _ := language.ParseBase("nl")
|
||||
us, _ := language.ParseRegion("US")
|
||||
de := language.Make("de-1901-u-co-phonebk")
|
||||
jp := language.Make("ja-JP")
|
||||
fi := language.Make("fi-x-ing")
|
||||
|
||||
u, _ := language.ParseExtension("u-nu-arabic")
|
||||
x, _ := language.ParseExtension("x-piglatin")
|
||||
|
||||
// Combine a base language and region.
|
||||
fmt.Println(language.Compose(nl, us))
|
||||
// Combine a base language and extension.
|
||||
fmt.Println(language.Compose(nl, x))
|
||||
// Replace the region.
|
||||
fmt.Println(language.Compose(jp, us))
|
||||
// Combine several tags.
|
||||
fmt.Println(language.Compose(us, nl, u))
|
||||
|
||||
// Replace the base language of a tag.
|
||||
fmt.Println(language.Compose(de, nl))
|
||||
fmt.Println(language.Compose(de, nl, u))
|
||||
// Remove the base language.
|
||||
fmt.Println(language.Compose(de, language.Base{}))
|
||||
// Remove all variants.
|
||||
fmt.Println(language.Compose(de, []language.Variant{}))
|
||||
// Remove all extensions.
|
||||
fmt.Println(language.Compose(de, []language.Extension{}))
|
||||
fmt.Println(language.Compose(fi, []language.Extension{}))
|
||||
// Remove all variants and extensions.
|
||||
fmt.Println(language.Compose(de.Raw()))
|
||||
|
||||
// An error is gobbled or returned if non-nil.
|
||||
fmt.Println(language.Compose(language.ParseRegion("ZA")))
|
||||
fmt.Println(language.Compose(language.ParseRegion("HH")))
|
||||
|
||||
// Compose uses the same Default canonicalization as Make.
|
||||
fmt.Println(language.Compose(language.Raw.Parse("en-Latn-UK")))
|
||||
|
||||
// Call compose on a different CanonType for different results.
|
||||
fmt.Println(language.All.Compose(language.Raw.Parse("en-Latn-UK")))
|
||||
|
||||
// Output:
|
||||
// nl-US <nil>
|
||||
// nl-x-piglatin <nil>
|
||||
// ja-US <nil>
|
||||
// nl-US-u-nu-arabic <nil>
|
||||
// nl-1901-u-co-phonebk <nil>
|
||||
// nl-1901-u-nu-arabic <nil>
|
||||
// und-1901-u-co-phonebk <nil>
|
||||
// de-u-co-phonebk <nil>
|
||||
// de-1901 <nil>
|
||||
// fi <nil>
|
||||
// de <nil>
|
||||
// und-ZA <nil>
|
||||
// und language: subtag "HH" is well-formed but unknown
|
||||
// en-Latn-GB <nil>
|
||||
// en-GB <nil>
|
||||
}
|
||||
|
||||
func ExampleParse_errors() {
|
||||
for _, s := range []string{"Foo", "Bar", "Foobar"} {
|
||||
_, err := language.Parse(s)
|
||||
if err != nil {
|
||||
if inv, ok := err.(language.ValueError); ok {
|
||||
fmt.Println(inv.Subtag())
|
||||
} else {
|
||||
fmt.Println(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, s := range []string{"en", "aa-Uuuu", "AC", "ac-u"} {
|
||||
_, err := language.Parse(s)
|
||||
switch e := err.(type) {
|
||||
case language.ValueError:
|
||||
fmt.Printf("%s: culprit %q\n", s, e.Subtag())
|
||||
case nil:
|
||||
// No error.
|
||||
default:
|
||||
// A syntax error.
|
||||
fmt.Printf("%s: ill-formed\n", s)
|
||||
}
|
||||
}
|
||||
// Output:
|
||||
// foo
|
||||
// Foobar
|
||||
// aa-Uuuu: culprit "Uuuu"
|
||||
// AC: culprit "ac"
|
||||
// ac-u: ill-formed
|
||||
}
|
||||
|
||||
func ExampleParent() {
|
||||
p := func(tag string) {
|
||||
fmt.Printf("parent(%v): %v\n", tag, language.Make(tag).Parent())
|
||||
}
|
||||
p("zh-CN")
|
||||
|
||||
// Australian English inherits from World English.
|
||||
p("en-AU")
|
||||
|
||||
// If the tag has a different maximized script from its parent, a tag with
|
||||
// this maximized script is inserted. This allows different language tags
|
||||
// which have the same base language and script in common to inherit from
|
||||
// a common set of settings.
|
||||
p("zh-HK")
|
||||
|
||||
// If the maximized script of the parent is not identical, CLDR will skip
|
||||
// inheriting from it, as it means there will not be many entries in common
|
||||
// and inheriting from it is nonsensical.
|
||||
p("zh-Hant")
|
||||
|
||||
// The parent of a tag with variants and extensions is the tag with all
|
||||
// variants and extensions removed.
|
||||
p("de-1994-u-co-phonebk")
|
||||
|
||||
// Remove default script.
|
||||
p("de-Latn-LU")
|
||||
|
||||
// Output:
|
||||
// parent(zh-CN): zh
|
||||
// parent(en-AU): en-001
|
||||
// parent(zh-HK): zh-Hant
|
||||
// parent(zh-Hant): und
|
||||
// parent(de-1994-u-co-phonebk): de
|
||||
// parent(de-Latn-LU): de
|
||||
}
|
||||
|
||||
// ExampleMatcher_bestMatch gives some examples of getting the best match of
|
||||
// a set of tags to any of the tags of given set.
|
||||
func ExampleMatcher() {
|
||||
// This is the set of tags from which we want to pick the best match. These
|
||||
// can be, for example, the supported languages for some package.
|
||||
tags := []language.Tag{
|
||||
language.English,
|
||||
language.BritishEnglish,
|
||||
language.French,
|
||||
language.Afrikaans,
|
||||
language.BrazilianPortuguese,
|
||||
language.EuropeanPortuguese,
|
||||
language.Croatian,
|
||||
language.SimplifiedChinese,
|
||||
language.Raw.Make("iw-IL"),
|
||||
language.Raw.Make("iw"),
|
||||
language.Raw.Make("he"),
|
||||
}
|
||||
m := language.NewMatcher(tags)
|
||||
|
||||
// A simple match.
|
||||
fmt.Println(m.Match(language.Make("fr")))
|
||||
|
||||
// Australian English is closer to British than American English.
|
||||
fmt.Println(m.Match(language.Make("en-AU")))
|
||||
|
||||
// Default to the first tag passed to the Matcher if there is no match.
|
||||
fmt.Println(m.Match(language.Make("ar")))
|
||||
|
||||
// Get the default tag.
|
||||
fmt.Println(m.Match())
|
||||
|
||||
fmt.Println("----")
|
||||
|
||||
// Someone specifying sr-Latn is probably fine with getting Croatian.
|
||||
fmt.Println(m.Match(language.Make("sr-Latn")))
|
||||
|
||||
// We match SimplifiedChinese, but with Low confidence.
|
||||
fmt.Println(m.Match(language.TraditionalChinese))
|
||||
|
||||
// Serbian in Latin script is a closer match to Croatian than Traditional
|
||||
// Chinese to Simplified Chinese.
|
||||
fmt.Println(m.Match(language.TraditionalChinese, language.Make("sr-Latn")))
|
||||
|
||||
fmt.Println("----")
|
||||
|
||||
// In case a multiple variants of a language are available, the most spoken
|
||||
// variant is typically returned.
|
||||
fmt.Println(m.Match(language.Portuguese))
|
||||
|
||||
// Pick the first value passed to Match in case of a tie.
|
||||
fmt.Println(m.Match(language.Dutch, language.Make("fr-BE"), language.Make("af-NA")))
|
||||
fmt.Println(m.Match(language.Dutch, language.Make("af-NA"), language.Make("fr-BE")))
|
||||
|
||||
fmt.Println("----")
|
||||
|
||||
// If a Matcher is initialized with a language and it's deprecated version,
|
||||
// it will distinguish between them.
|
||||
fmt.Println(m.Match(language.Raw.Make("iw")))
|
||||
|
||||
// However, for non-exact matches, it will treat deprecated versions as
|
||||
// equivalent and consider other factors first.
|
||||
fmt.Println(m.Match(language.Raw.Make("he-IL")))
|
||||
|
||||
fmt.Println("----")
|
||||
|
||||
// User settings passed to the Unicode extension are ignored for matching
|
||||
// and preserved in the returned tag.
|
||||
fmt.Println(m.Match(language.Make("de-u-co-phonebk"), language.Make("fr-u-cu-frf")))
|
||||
|
||||
// Even if the matching language is different.
|
||||
fmt.Println(m.Match(language.Make("de-u-co-phonebk"), language.Make("br-u-cu-frf")))
|
||||
|
||||
// If there is no matching language, the options of the first preferred tag are used.
|
||||
fmt.Println(m.Match(language.Make("de-u-co-phonebk")))
|
||||
|
||||
// Output:
|
||||
// fr 2 Exact
|
||||
// en-GB 1 High
|
||||
// en 0 No
|
||||
// en 0 No
|
||||
// ----
|
||||
// hr 6 High
|
||||
// zh-Hans 7 Low
|
||||
// hr 6 High
|
||||
// ----
|
||||
// pt-BR 4 High
|
||||
// fr 2 High
|
||||
// af 3 High
|
||||
// ----
|
||||
// iw 9 Exact
|
||||
// he 10 Exact
|
||||
// ----
|
||||
// fr-u-cu-frf 2 Exact
|
||||
// fr-u-cu-frf 2 High
|
||||
// en-u-co-phonebk 0 No
|
||||
|
||||
// TODO: "he" should be "he-u-rg-IL High"
|
||||
}
|
||||
|
||||
func ExampleMatchStrings() {
|
||||
// languages supported by this service:
|
||||
matcher := language.NewMatcher([]language.Tag{
|
||||
language.English, language.Dutch, language.German,
|
||||
})
|
||||
|
||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
lang, _ := r.Cookie("lang")
|
||||
tag, _ := language.MatchStrings(matcher, lang.String(), r.Header.Get("Accept-Language"))
|
||||
|
||||
fmt.Println("User language:", tag)
|
||||
})
|
||||
}
|
||||
|
||||
func ExampleComprehends() {
|
||||
// Various levels of comprehensibility.
|
||||
fmt.Println(language.Comprehends(language.English, language.English))
|
||||
fmt.Println(language.Comprehends(language.AmericanEnglish, language.BritishEnglish))
|
||||
|
||||
// An explicit Und results in no match.
|
||||
fmt.Println(language.Comprehends(language.English, language.Und))
|
||||
|
||||
fmt.Println("----")
|
||||
|
||||
// There is usually no mutual comprehensibility between different scripts.
|
||||
fmt.Println(language.Comprehends(language.Make("en-Dsrt"), language.English))
|
||||
|
||||
// One exception is for Traditional versus Simplified Chinese, albeit with
|
||||
// a low confidence.
|
||||
fmt.Println(language.Comprehends(language.TraditionalChinese, language.SimplifiedChinese))
|
||||
|
||||
fmt.Println("----")
|
||||
|
||||
// A Swiss German speaker will often understand High German.
|
||||
fmt.Println(language.Comprehends(language.Make("gsw"), language.Make("de")))
|
||||
|
||||
// The converse is not generally the case.
|
||||
fmt.Println(language.Comprehends(language.Make("de"), language.Make("gsw")))
|
||||
|
||||
// Output:
|
||||
// Exact
|
||||
// High
|
||||
// No
|
||||
// ----
|
||||
// No
|
||||
// Low
|
||||
// ----
|
||||
// High
|
||||
// No
|
||||
}
|
||||
|
||||
func ExampleTag_values() {
|
||||
us := language.MustParseRegion("US")
|
||||
en := language.MustParseBase("en")
|
||||
|
||||
lang, _, region := language.AmericanEnglish.Raw()
|
||||
fmt.Println(lang == en, region == us)
|
||||
|
||||
lang, _, region = language.BritishEnglish.Raw()
|
||||
fmt.Println(lang == en, region == us)
|
||||
|
||||
// Tags can be compared for exact equivalence using '=='.
|
||||
en_us, _ := language.Compose(en, us)
|
||||
fmt.Println(en_us == language.AmericanEnglish)
|
||||
|
||||
// Output:
|
||||
// true true
|
||||
// true false
|
||||
// true
|
||||
}
|
||||
10
vendor/golang.org/x/text/language/gen.go
generated
vendored
10
vendor/golang.org/x/text/language/gen.go
generated
vendored
|
|
@ -1497,8 +1497,14 @@ func (b *builder) writeMatchData() {
|
|||
if desired == supported && desired == "*_*_*" {
|
||||
continue
|
||||
}
|
||||
if desired != supported { // (Weird but correct.)
|
||||
log.Fatalf("not supported: desired=%q; supported=%q", desired, supported)
|
||||
if desired != supported {
|
||||
// This is now supported by CLDR, but only one case, which
|
||||
// should already be covered by paradigm locales. For instance,
|
||||
// test case "und, en, en-GU, en-IN, en-GB ; en-ZA ; en-GB" in
|
||||
// testdata/CLDRLocaleMatcherTest.txt tests this.
|
||||
if supported != "en_*_GB" {
|
||||
log.Fatalf("not supported: desired=%q; supported=%q", desired, supported)
|
||||
}
|
||||
continue
|
||||
}
|
||||
ri := regionIntelligibility{
|
||||
|
|
|
|||
2
vendor/golang.org/x/text/language/gen_index.go
generated
vendored
2
vendor/golang.org/x/text/language/gen_index.go
generated
vendored
|
|
@ -49,7 +49,7 @@ func main() {
|
|||
defer func() {
|
||||
buf := &bytes.Buffer{}
|
||||
|
||||
if _, err = w.WriteGo(buf, "language"); err != nil {
|
||||
if _, err = w.WriteGo(buf, "language", ""); err != nil {
|
||||
log.Fatalf("Error formatting file index.go: %v", err)
|
||||
}
|
||||
|
||||
|
|
|
|||
48
vendor/golang.org/x/text/language/httpexample_test.go
generated
vendored
48
vendor/golang.org/x/text/language/httpexample_test.go
generated
vendored
|
|
@ -1,48 +0,0 @@
|
|||
// Copyright 2016 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_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
// matcher is a language.Matcher configured for all supported languages.
|
||||
var matcher = language.NewMatcher([]language.Tag{
|
||||
language.BritishEnglish,
|
||||
language.Norwegian,
|
||||
language.German,
|
||||
})
|
||||
|
||||
// handler is a http.HandlerFunc.
|
||||
func handler(w http.ResponseWriter, r *http.Request) {
|
||||
t, q, err := language.ParseAcceptLanguage(r.Header.Get("Accept-Language"))
|
||||
// We ignore the error: the default language will be selected for t == nil.
|
||||
tag, _, _ := matcher.Match(t...)
|
||||
fmt.Printf("%5v (t: %6v; q: %3v; err: %v)\n", tag, t, q, err)
|
||||
}
|
||||
|
||||
func ExampleParseAcceptLanguage() {
|
||||
for _, al := range []string{
|
||||
"nn;q=0.3, en-us;q=0.8, en,",
|
||||
"gsw, en;q=0.7, en-US;q=0.8",
|
||||
"gsw, nl, da",
|
||||
"invalid",
|
||||
} {
|
||||
// Create dummy request with Accept-Language set and pass it to handler.
|
||||
r, _ := http.NewRequest("GET", "example.com", strings.NewReader("Hello"))
|
||||
r.Header.Set("Accept-Language", al)
|
||||
handler(nil, r)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// en-GB (t: [ en en-US nn]; q: [ 1 0.8 0.3]; err: <nil>)
|
||||
// en-GB (t: [ gsw en-US en]; q: [ 1 0.8 0.7]; err: <nil>)
|
||||
// de (t: [ gsw nl da]; q: [ 1 1 1]; err: <nil>)
|
||||
// en-GB (t: []; q: []; err: language: tag is not well-formed)
|
||||
}
|
||||
1372
vendor/golang.org/x/text/language/index.go
generated
vendored
1372
vendor/golang.org/x/text/language/index.go
generated
vendored
File diff suppressed because it is too large
Load diff
20
vendor/golang.org/x/text/language/language.go
generated
vendored
20
vendor/golang.org/x/text/language/language.go
generated
vendored
|
|
@ -299,6 +299,26 @@ func (t Tag) String() string {
|
|||
return string(buf[:t.genCoreBytes(buf[:])])
|
||||
}
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler.
|
||||
func (t Tag) MarshalText() (text []byte, err error) {
|
||||
if t.str != "" {
|
||||
text = append(text, t.str...)
|
||||
} else if t.script == 0 && t.region == 0 {
|
||||
text = append(text, t.lang.String()...)
|
||||
} else {
|
||||
buf := [maxCoreSize]byte{}
|
||||
text = buf[:t.genCoreBytes(buf[:])]
|
||||
}
|
||||
return text, nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
func (t *Tag) UnmarshalText(text []byte) error {
|
||||
tag, err := Raw.Parse(string(text))
|
||||
*t = tag
|
||||
return err
|
||||
}
|
||||
|
||||
// Base returns the base language of the language tag. If the base language is
|
||||
// unspecified, an attempt will be made to infer it from the context.
|
||||
// It uses a variant of CLDR's Add Likely Subtags algorithm. This is subject to change.
|
||||
|
|
|
|||
878
vendor/golang.org/x/text/language/language_test.go
generated
vendored
878
vendor/golang.org/x/text/language/language_test.go
generated
vendored
|
|
@ -1,878 +0,0 @@
|
|||
// 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"
|
||||
|
||||
"golang.org/x/text/internal/testtext"
|
||||
)
|
||||
|
||||
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()[48:49] {
|
||||
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 TestMakeString(t *testing.T) {
|
||||
tests := []struct{ in, out string }{
|
||||
{"und", "und"},
|
||||
{"und", "und-CW"},
|
||||
{"nl", "nl-NL"},
|
||||
{"de-1901", "nl-1901"},
|
||||
{"de-1901", "de-Arab-1901"},
|
||||
{"x-a-b", "de-Arab-x-a-b"},
|
||||
{"x-a-b", "x-a-b"},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
id, _ := Parse(tt.in)
|
||||
mod, _ := Parse(tt.out)
|
||||
id.setTagsFrom(mod)
|
||||
for j := 0; j < 2; j++ {
|
||||
id.remakeString()
|
||||
if str := id.String(); str != tt.out {
|
||||
t.Errorf("%d:%d: found %s; want %s", i, j, id.String(), tt.out)
|
||||
}
|
||||
}
|
||||
// The bytes to string conversion as used in remakeString
|
||||
// occasionally measures as more than one alloc, breaking this test.
|
||||
// To alleviate this we set the number of runs to more than 1.
|
||||
if n := testtext.AllocsPerRun(8, id.remakeString); n > 1 {
|
||||
t.Errorf("%d: # allocs got %.1f; want <= 1", i, n)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompactIndex(t *testing.T) {
|
||||
tests := []struct {
|
||||
tag string
|
||||
index int
|
||||
ok bool
|
||||
}{
|
||||
// TODO: these values will change with each CLDR update. This issue
|
||||
// will be solved if we decide to fix the indexes.
|
||||
{"und", 0, true},
|
||||
{"ca-ES-valencia", 1, true},
|
||||
{"ca-ES-valencia-u-va-posix", 0, false},
|
||||
{"ca-ES-valencia-u-co-phonebk", 1, true},
|
||||
{"ca-ES-valencia-u-co-phonebk-va-posix", 0, false},
|
||||
{"x-klingon", 0, false},
|
||||
{"en-US", 229, true},
|
||||
{"en-US-u-va-posix", 2, true},
|
||||
{"en", 133, true},
|
||||
{"en-u-co-phonebk", 133, true},
|
||||
{"en-001", 134, true},
|
||||
{"sh", 0, false}, // We don't normalize.
|
||||
}
|
||||
for _, tt := range tests {
|
||||
x, ok := CompactIndex(Raw.MustParse(tt.tag))
|
||||
if x != tt.index || ok != tt.ok {
|
||||
t.Errorf("%s: got %d, %v; want %d %v", tt.tag, x, ok, tt.index, tt.ok)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
reg, _ := getRegionID([]byte(tt.reg))
|
||||
r := Region{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 {
|
||||
reg, _ := getRegionID([]byte(tt.reg))
|
||||
r := Region{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 {
|
||||
enc, _ := getRegionID([]byte(tt.enclosing))
|
||||
con, _ := getRegionID([]byte(tt.contained))
|
||||
r := Region{enc}
|
||||
if got := r.Contains(Region{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
|
||||
}
|
||||
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)
|
||||
}
|
||||
if int(in.pVariant) > int(in.pExt) || int(in.pExt) > len(in.str) {
|
||||
t.Errorf("%d:%s:offsets %d <= %d <= %d must be true", i, tt.in, in.pVariant, in.pExt, len(in.str))
|
||||
}
|
||||
}
|
||||
// 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", ""},
|
||||
{"nu", "en-u-co-phonebk-nu-arabic", "arabic"},
|
||||
{"kc", "cmn-u-co-stroke", ""},
|
||||
}
|
||||
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 TestSetTypeForKey(t *testing.T) {
|
||||
tests := []struct {
|
||||
key, value, in, out string
|
||||
err bool
|
||||
}{
|
||||
// replace existing value
|
||||
{"co", "pinyin", "en-u-co-phonebk", "en-u-co-pinyin", false},
|
||||
{"co", "pinyin", "en-u-co-phonebk-cu-xau", "en-u-co-pinyin-cu-xau", false},
|
||||
{"co", "pinyin", "en-u-co-phonebk-v-xx", "en-u-co-pinyin-v-xx", false},
|
||||
{"co", "pinyin", "en-u-co-phonebk-x-x", "en-u-co-pinyin-x-x", false},
|
||||
{"nu", "arabic", "en-u-co-phonebk-nu-vaai", "en-u-co-phonebk-nu-arabic", false},
|
||||
// add to existing -u extension
|
||||
{"co", "pinyin", "en-u-ca-gregory", "en-u-ca-gregory-co-pinyin", false},
|
||||
{"co", "pinyin", "en-u-ca-gregory-nu-vaai", "en-u-ca-gregory-co-pinyin-nu-vaai", false},
|
||||
{"co", "pinyin", "en-u-ca-gregory-v-va", "en-u-ca-gregory-co-pinyin-v-va", false},
|
||||
{"co", "pinyin", "en-u-ca-gregory-x-a", "en-u-ca-gregory-co-pinyin-x-a", false},
|
||||
{"ca", "gregory", "en-u-co-pinyin", "en-u-ca-gregory-co-pinyin", false},
|
||||
// remove pair
|
||||
{"co", "", "en-u-co-phonebk", "en", false},
|
||||
{"co", "", "en-u-ca-gregory-co-phonebk", "en-u-ca-gregory", false},
|
||||
{"co", "", "en-u-co-phonebk-nu-arabic", "en-u-nu-arabic", false},
|
||||
{"co", "", "en", "en", false},
|
||||
// add -u extension
|
||||
{"co", "pinyin", "en", "en-u-co-pinyin", false},
|
||||
{"co", "pinyin", "und", "und-u-co-pinyin", false},
|
||||
{"co", "pinyin", "en-a-aaa", "en-a-aaa-u-co-pinyin", false},
|
||||
{"co", "pinyin", "en-x-aaa", "en-u-co-pinyin-x-aaa", false},
|
||||
{"co", "pinyin", "en-v-aa", "en-u-co-pinyin-v-aa", false},
|
||||
{"co", "pinyin", "en-a-aaa-x-x", "en-a-aaa-u-co-pinyin-x-x", false},
|
||||
{"co", "pinyin", "en-a-aaa-v-va", "en-a-aaa-u-co-pinyin-v-va", false},
|
||||
// error on invalid values
|
||||
{"co", "pinyinxxx", "en", "en", true},
|
||||
{"co", "piny.n", "en", "en", true},
|
||||
{"co", "pinyinxxx", "en-a-aaa", "en-a-aaa", true},
|
||||
{"co", "pinyinxxx", "en-u-aaa", "en-u-aaa", true},
|
||||
{"co", "pinyinxxx", "en-u-aaa-co-pinyin", "en-u-aaa-co-pinyin", true},
|
||||
{"co", "pinyi.", "en-u-aaa-co-pinyin", "en-u-aaa-co-pinyin", true},
|
||||
{"col", "pinyin", "en", "en", true},
|
||||
{"co", "cu", "en", "en", true},
|
||||
// error when setting on a private use tag
|
||||
{"co", "phonebook", "x-foo", "x-foo", true},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
tag := Make(tt.in)
|
||||
if v, err := tag.SetTypeForKey(tt.key, tt.value); v.String() != tt.out {
|
||||
t.Errorf("%d:%q[%q]=%q: was %q; want %q", i, tt.in, tt.key, tt.value, v, tt.out)
|
||||
} else if (err != nil) != tt.err {
|
||||
t.Errorf("%d:%q[%q]=%q: error was %v; want %v", i, tt.in, tt.key, tt.value, err != nil, tt.err)
|
||||
} else if val := v.TypeForKey(tt.key); err == nil && val != tt.value {
|
||||
t.Errorf("%d:%q[%q]==%q: was %v; want %v", i, tt.out, tt.key, tt.value, val, tt.value)
|
||||
}
|
||||
if len(tag.String()) <= 3 {
|
||||
// Simulate a tag for which the string has not been set.
|
||||
tag.str, tag.pExt, tag.pVariant = "", 0, 0
|
||||
if tag, err := tag.SetTypeForKey(tt.key, tt.value); err == nil {
|
||||
if val := tag.TypeForKey(tt.key); err == nil && val != tt.value {
|
||||
t.Errorf("%d:%q[%q]==%q: was %v; want %v", i, tt.out, tt.key, tt.value, val, tt.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindKeyAndType(t *testing.T) {
|
||||
// out is either the matched type in case of a match or the original
|
||||
// string up till the insertion point.
|
||||
tests := []struct {
|
||||
key string
|
||||
hasExt bool
|
||||
in, out string
|
||||
}{
|
||||
// Don't search past a private use extension.
|
||||
{"co", false, "en-x-foo-u-co-pinyin", "en"},
|
||||
{"co", false, "x-foo-u-co-pinyin", ""},
|
||||
{"co", false, "en-s-fff-x-foo", "en-s-fff"},
|
||||
// Insertion points in absence of -u extension.
|
||||
{"cu", false, "en", ""}, // t.str is ""
|
||||
{"cu", false, "en-v-va", "en"},
|
||||
{"cu", false, "en-a-va", "en-a-va"},
|
||||
{"cu", false, "en-a-va-v-va", "en-a-va"},
|
||||
{"cu", false, "en-x-a", "en"},
|
||||
// Tags with the -u extension.
|
||||
{"co", true, "en-u-co-standard", "standard"},
|
||||
{"co", true, "yue-u-co-pinyin", "pinyin"},
|
||||
{"co", true, "en-u-co-abc", "abc"},
|
||||
{"co", true, "en-u-co-abc-def", "abc-def"},
|
||||
{"co", true, "en-u-co-abc-def-x-foo", "abc-def"},
|
||||
{"co", true, "en-u-co-standard-nu-arab", "standard"},
|
||||
{"co", true, "yue-u-co-pinyin-nu-arab", "pinyin"},
|
||||
// Insertion points.
|
||||
{"cu", true, "en-u-co-standard", "en-u-co-standard"},
|
||||
{"cu", true, "yue-u-co-pinyin-x-foo", "yue-u-co-pinyin"},
|
||||
{"cu", true, "en-u-co-abc", "en-u-co-abc"},
|
||||
{"cu", true, "en-u-nu-arabic", "en-u"},
|
||||
{"cu", true, "en-u-co-abc-def-nu-arabic", "en-u-co-abc-def"},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
start, end, hasExt := Make(tt.in).findTypeForKey(tt.key)
|
||||
if start != end {
|
||||
res := tt.in[start:end]
|
||||
if res != tt.out {
|
||||
t.Errorf("%d:%s: was %q; want %q", i, tt.in, res, tt.out)
|
||||
}
|
||||
} else {
|
||||
if hasExt != tt.hasExt {
|
||||
t.Errorf("%d:%s: hasExt was %v; want %v", i, tt.in, hasExt, tt.hasExt)
|
||||
continue
|
||||
}
|
||||
if tt.in[:start] != tt.out {
|
||||
t.Errorf("%d:%s: insertion point was %q; want %q", i, tt.in, tt.in[:start], 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"},
|
||||
}
|
||||
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)
|
||||
}
|
||||
457
vendor/golang.org/x/text/language/lookup_test.go
generated
vendored
457
vendor/golang.org/x/text/language/lookup_test.go
generated
vendored
|
|
@ -1,457 +0,0 @@
|
|||
// 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: mkErrInvalid([]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 := Raw.Make(tt.in)
|
||||
want := Raw.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 scriptID
|
||||
}{
|
||||
{" ", 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
505
vendor/golang.org/x/text/language/match_test.go
generated
vendored
505
vendor/golang.org/x/text/language/match_test.go
generated
vendored
|
|
@ -1,505 +0,0 @@
|
|||
// 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 (
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/text/internal/testtext"
|
||||
"golang.org/x/text/internal/ucd"
|
||||
)
|
||||
|
||||
var verbose = flag.Bool("verbose", false, "set to true to print the internal tables of matchers")
|
||||
|
||||
func TestCompliance(t *testing.T) {
|
||||
filepath.Walk("testdata", func(file string, info os.FileInfo, err error) error {
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
r, err := os.Open(file)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ucd.Parse(r, func(p *ucd.Parser) {
|
||||
name := strings.Replace(path.Join(p.String(0), p.String(1)), " ", "", -1)
|
||||
if skip[name] {
|
||||
return
|
||||
}
|
||||
t.Run(info.Name()+"/"+name, func(t *testing.T) {
|
||||
supported := makeTagList(p.String(0))
|
||||
desired := makeTagList(p.String(1))
|
||||
gotCombined, index, conf := NewMatcher(supported).Match(desired...)
|
||||
|
||||
gotMatch := supported[index]
|
||||
wantMatch := mk(p.String(2))
|
||||
if gotMatch != wantMatch {
|
||||
t.Fatalf("match: got %q; want %q (%v)", gotMatch, wantMatch, conf)
|
||||
}
|
||||
wantCombined, err := Raw.Parse(p.String(3))
|
||||
if err == nil && gotCombined != wantCombined {
|
||||
t.Errorf("combined: got %q; want %q (%v)", gotCombined, wantCombined, conf)
|
||||
}
|
||||
})
|
||||
})
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
var skip = map[string]bool{
|
||||
// TODO: bugs
|
||||
// Honor the wildcard match. This may only be useful to select non-exact
|
||||
// stuff.
|
||||
"mul,af/nl": true, // match: got "af"; want "mul"
|
||||
|
||||
// TODO: include other extensions.
|
||||
// combined: got "en-GB-u-ca-buddhist-nu-arab"; want "en-GB-fonipa-t-m0-iso-i0-pinyin-u-ca-buddhist-nu-arab"
|
||||
"und,en-GB-u-sd-gbsct/en-fonipa-u-nu-Arab-ca-buddhist-t-m0-iso-i0-pinyin": true,
|
||||
|
||||
// Inconsistencies with Mark Davis' implementation where it is not clear
|
||||
// which is better.
|
||||
|
||||
// Inconsistencies in combined. I think the Go approach is more appropriate.
|
||||
// We could use -u-rg- and -u-va- as alternative.
|
||||
"und,fr/fr-BE-fonipa": true, // combined: got "fr"; want "fr-BE-fonipa"
|
||||
"und,fr-CA/fr-BE-fonipa": true, // combined: got "fr-CA"; want "fr-BE-fonipa"
|
||||
"und,fr-fonupa/fr-BE-fonipa": true, // combined: got "fr-fonupa"; want "fr-BE-fonipa"
|
||||
"und,no/nn-BE-fonipa": true, // combined: got "no"; want "no-BE-fonipa"
|
||||
"50,und,fr-CA-fonupa/fr-BE-fonipa": true, // combined: got "fr-CA-fonupa"; want "fr-BE-fonipa"
|
||||
|
||||
// The initial number is a threshold. As we don't use scoring, we will not
|
||||
// implement this.
|
||||
"50,und,fr-Cyrl-CA-fonupa/fr-BE-fonipa": true,
|
||||
// match: got "und"; want "fr-Cyrl-CA-fonupa"
|
||||
// combined: got "und"; want "fr-Cyrl-BE-fonipa"
|
||||
|
||||
// Other interesting cases to test:
|
||||
// - Should same language or same script have the preference if there is
|
||||
// usually no understanding of the other script?
|
||||
// - More specific region in desired may replace enclosing supported.
|
||||
}
|
||||
|
||||
func makeTagList(s string) (tags []Tag) {
|
||||
for _, s := range strings.Split(s, ",") {
|
||||
tags = append(tags, mk(strings.TrimSpace(s)))
|
||||
}
|
||||
return tags
|
||||
}
|
||||
|
||||
func TestMatchStrings(t *testing.T) {
|
||||
testCases := []struct {
|
||||
supported string
|
||||
desired string // strings separted by |
|
||||
tag string
|
||||
index int
|
||||
}{{
|
||||
supported: "en",
|
||||
desired: "",
|
||||
tag: "en",
|
||||
index: 0,
|
||||
}, {
|
||||
supported: "en",
|
||||
desired: "nl",
|
||||
tag: "en",
|
||||
index: 0,
|
||||
}, {
|
||||
supported: "en,nl",
|
||||
desired: "nl",
|
||||
tag: "nl",
|
||||
index: 1,
|
||||
}, {
|
||||
supported: "en,nl",
|
||||
desired: "nl|en",
|
||||
tag: "nl",
|
||||
index: 1,
|
||||
}, {
|
||||
supported: "en-GB,nl",
|
||||
desired: "en ; q=0.1,nl",
|
||||
tag: "nl",
|
||||
index: 1,
|
||||
}, {
|
||||
supported: "en-GB,nl",
|
||||
desired: "en;q=0.005 | dk; q=0.1,nl ",
|
||||
tag: "en-GB",
|
||||
index: 0,
|
||||
}, {
|
||||
// do not match faulty tags with und
|
||||
supported: "en,und",
|
||||
desired: "|en",
|
||||
tag: "en",
|
||||
index: 0,
|
||||
}}
|
||||
for _, tc := range testCases {
|
||||
t.Run(path.Join(tc.supported, tc.desired), func(t *testing.T) {
|
||||
m := NewMatcher(makeTagList(tc.supported))
|
||||
tag, index := MatchStrings(m, strings.Split(tc.desired, "|")...)
|
||||
if tag.String() != tc.tag || index != tc.index {
|
||||
t.Errorf("got %v, %d; want %v, %d", tag, index, tc.tag, tc.index)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddLikelySubtags(t *testing.T) {
|
||||
tests := []struct{ in, out string }{
|
||||
{"aa", "aa-Latn-ET"},
|
||||
{"aa-Latn", "aa-Latn-ET"},
|
||||
{"aa-Arab", "aa-Arab-ET"},
|
||||
{"aa-Arab-ER", "aa-Arab-ER"},
|
||||
{"kk", "kk-Cyrl-KZ"},
|
||||
{"kk-CN", "kk-Arab-CN"},
|
||||
{"cmn", "cmn"},
|
||||
{"zh-AU", "zh-Hant-AU"},
|
||||
{"zh-VN", "zh-Hant-VN"},
|
||||
{"zh-SG", "zh-Hans-SG"},
|
||||
{"zh-Hant", "zh-Hant-TW"},
|
||||
{"zh-Hani", "zh-Hani-CN"},
|
||||
{"und-Hani", "zh-Hani-CN"},
|
||||
{"und", "en-Latn-US"},
|
||||
{"und-GB", "en-Latn-GB"},
|
||||
{"und-CW", "pap-Latn-CW"},
|
||||
{"und-YT", "fr-Latn-YT"},
|
||||
{"und-Arab", "ar-Arab-EG"},
|
||||
{"und-AM", "hy-Armn-AM"},
|
||||
{"und-TW", "zh-Hant-TW"},
|
||||
{"und-002", "en-Latn-NG"},
|
||||
{"und-Latn-002", "en-Latn-NG"},
|
||||
{"en-Latn-002", "en-Latn-NG"},
|
||||
{"en-002", "en-Latn-NG"},
|
||||
{"en-001", "en-Latn-US"},
|
||||
{"und-003", "en-Latn-US"},
|
||||
{"und-GB", "en-Latn-GB"},
|
||||
{"Latn-001", "en-Latn-US"},
|
||||
{"en-001", "en-Latn-US"},
|
||||
{"es-419", "es-Latn-419"},
|
||||
{"he-145", "he-Hebr-IL"},
|
||||
{"ky-145", "ky-Latn-TR"},
|
||||
{"kk", "kk-Cyrl-KZ"},
|
||||
// Don't specialize duplicate and ambiguous matches.
|
||||
{"kk-034", "kk-Arab-034"}, // Matches IR and AF. Both are Arab.
|
||||
{"ku-145", "ku-Latn-TR"}, // Matches IQ, TR, and LB, but kk -> TR.
|
||||
{"und-Arab-CC", "ms-Arab-CC"},
|
||||
{"und-Arab-GB", "ks-Arab-GB"},
|
||||
{"und-Hans-CC", "zh-Hans-CC"},
|
||||
{"und-CC", "en-Latn-CC"},
|
||||
{"sr", "sr-Cyrl-RS"},
|
||||
{"sr-151", "sr-Latn-151"}, // Matches RO and RU.
|
||||
// We would like addLikelySubtags to generate the same results if the input
|
||||
// only changes by adding tags that would otherwise have been added
|
||||
// by the expansion.
|
||||
// In other words:
|
||||
// und-AA -> xx-Scrp-AA implies und-Scrp-AA -> xx-Scrp-AA
|
||||
// und-AA -> xx-Scrp-AA implies xx-AA -> xx-Scrp-AA
|
||||
// und-Scrp -> xx-Scrp-AA implies und-Scrp-AA -> xx-Scrp-AA
|
||||
// und-Scrp -> xx-Scrp-AA implies xx-Scrp -> xx-Scrp-AA
|
||||
// xx -> xx-Scrp-AA implies xx-Scrp -> xx-Scrp-AA
|
||||
// xx -> xx-Scrp-AA implies xx-AA -> xx-Scrp-AA
|
||||
//
|
||||
// The algorithm specified in
|
||||
// http://unicode.org/reports/tr35/tr35-9.html#Supplemental_Data,
|
||||
// Section C.10, does not handle the first case. For example,
|
||||
// the CLDR data contains an entry und-BJ -> fr-Latn-BJ, but not
|
||||
// there is no rule for und-Latn-BJ. According to spec, und-Latn-BJ
|
||||
// would expand to en-Latn-BJ, violating the aforementioned principle.
|
||||
// We deviate from the spec by letting und-Scrp-AA expand to xx-Scrp-AA
|
||||
// if a rule of the form und-AA -> xx-Scrp-AA is defined.
|
||||
// Note that as of version 23, CLDR has some explicitly specified
|
||||
// entries that do not conform to these rules. The implementation
|
||||
// will not correct these explicit inconsistencies. A later versions of CLDR
|
||||
// is supposed to fix this.
|
||||
{"und-Latn-BJ", "fr-Latn-BJ"},
|
||||
{"und-Bugi-ID", "bug-Bugi-ID"},
|
||||
// regions, scripts and languages without definitions
|
||||
{"und-Arab-AA", "ar-Arab-AA"},
|
||||
{"und-Afak-RE", "fr-Afak-RE"},
|
||||
{"und-Arab-GB", "ks-Arab-GB"},
|
||||
{"abp-Arab-GB", "abp-Arab-GB"},
|
||||
// script has preference over region
|
||||
{"und-Arab-NL", "ar-Arab-NL"},
|
||||
{"zza", "zza-Latn-TR"},
|
||||
// preserve variants and extensions
|
||||
{"de-1901", "de-Latn-DE-1901"},
|
||||
{"de-x-abc", "de-Latn-DE-x-abc"},
|
||||
{"de-1901-x-abc", "de-Latn-DE-1901-x-abc"},
|
||||
{"x-abc", "x-abc"}, // TODO: is this the desired behavior?
|
||||
}
|
||||
for i, tt := range tests {
|
||||
in, _ := Parse(tt.in)
|
||||
out, _ := Parse(tt.out)
|
||||
in, _ = in.addLikelySubtags()
|
||||
if in.String() != out.String() {
|
||||
t.Errorf("%d: add(%s) was %s; want %s", i, tt.in, in, tt.out)
|
||||
}
|
||||
}
|
||||
}
|
||||
func TestMinimize(t *testing.T) {
|
||||
tests := []struct{ in, out string }{
|
||||
{"aa", "aa"},
|
||||
{"aa-Latn", "aa"},
|
||||
{"aa-Latn-ET", "aa"},
|
||||
{"aa-ET", "aa"},
|
||||
{"aa-Arab", "aa-Arab"},
|
||||
{"aa-Arab-ER", "aa-Arab-ER"},
|
||||
{"aa-Arab-ET", "aa-Arab"},
|
||||
{"und", "und"},
|
||||
{"und-Latn", "und"},
|
||||
{"und-Latn-US", "und"},
|
||||
{"en-Latn-US", "en"},
|
||||
{"cmn", "cmn"},
|
||||
{"cmn-Hans", "cmn-Hans"},
|
||||
{"cmn-Hant", "cmn-Hant"},
|
||||
{"zh-AU", "zh-AU"},
|
||||
{"zh-VN", "zh-VN"},
|
||||
{"zh-SG", "zh-SG"},
|
||||
{"zh-Hant", "zh-Hant"},
|
||||
{"zh-Hant-TW", "zh-TW"},
|
||||
{"zh-Hans", "zh"},
|
||||
{"zh-Hani", "zh-Hani"},
|
||||
{"und-Hans", "und-Hans"},
|
||||
{"und-Hani", "und-Hani"},
|
||||
|
||||
{"und-CW", "und-CW"},
|
||||
{"und-YT", "und-YT"},
|
||||
{"und-Arab", "und-Arab"},
|
||||
{"und-AM", "und-AM"},
|
||||
{"und-Arab-CC", "und-Arab-CC"},
|
||||
{"und-CC", "und-CC"},
|
||||
{"und-Latn-BJ", "und-BJ"},
|
||||
{"und-Bugi-ID", "und-Bugi"},
|
||||
{"bug-Bugi-ID", "bug-Bugi"},
|
||||
// regions, scripts and languages without definitions
|
||||
{"und-Arab-AA", "und-Arab-AA"},
|
||||
// preserve variants and extensions
|
||||
{"de-Latn-1901", "de-1901"},
|
||||
{"de-Latn-x-abc", "de-x-abc"},
|
||||
{"de-DE-1901-x-abc", "de-1901-x-abc"},
|
||||
{"x-abc", "x-abc"}, // TODO: is this the desired behavior?
|
||||
}
|
||||
for i, tt := range tests {
|
||||
in, _ := Parse(tt.in)
|
||||
out, _ := Parse(tt.out)
|
||||
min, _ := in.minimize()
|
||||
if min.String() != out.String() {
|
||||
t.Errorf("%d: min(%s) was %s; want %s", i, tt.in, min, tt.out)
|
||||
}
|
||||
max, _ := min.addLikelySubtags()
|
||||
if x, _ := in.addLikelySubtags(); x.String() != max.String() {
|
||||
t.Errorf("%d: max(min(%s)) = %s; want %s", i, tt.in, max, x)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegionGroups(t *testing.T) {
|
||||
testCases := []struct {
|
||||
a, b string
|
||||
distance uint8
|
||||
}{
|
||||
{"zh-TW", "zh-HK", 5},
|
||||
{"zh-MO", "zh-HK", 4},
|
||||
{"es-ES", "es-AR", 5},
|
||||
{"es-ES", "es", 4},
|
||||
{"es-419", "es-MX", 4},
|
||||
{"es-AR", "es-MX", 4},
|
||||
{"es-ES", "es-MX", 5},
|
||||
{"es-PT", "es-MX", 5},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
a := MustParse(tc.a)
|
||||
aScript, _ := a.Script()
|
||||
b := MustParse(tc.b)
|
||||
bScript, _ := b.Script()
|
||||
|
||||
if aScript != bScript {
|
||||
t.Errorf("scripts differ: %q vs %q", aScript, bScript)
|
||||
continue
|
||||
}
|
||||
d, _ := regionGroupDist(a.region, b.region, aScript.scriptID, a.lang)
|
||||
if d != tc.distance {
|
||||
t.Errorf("got %q; want %q", d, tc.distance)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsParadigmLocale(t *testing.T) {
|
||||
testCases := map[string]bool{
|
||||
"en-US": true,
|
||||
"en-GB": true,
|
||||
"en-VI": false,
|
||||
"es-GB": false,
|
||||
"es-ES": true,
|
||||
"es-419": true,
|
||||
}
|
||||
for str, want := range testCases {
|
||||
tag := Make(str)
|
||||
got := isParadigmLocale(tag.lang, tag.region)
|
||||
if got != want {
|
||||
t.Errorf("isPL(%q) = %v; want %v", str, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation of String methods for various types for debugging purposes.
|
||||
|
||||
func (m *matcher) String() string {
|
||||
w := &bytes.Buffer{}
|
||||
fmt.Fprintln(w, "Default:", m.default_)
|
||||
for tag, h := range m.index {
|
||||
fmt.Fprintf(w, " %s: %v\n", tag, h)
|
||||
}
|
||||
return w.String()
|
||||
}
|
||||
|
||||
func (h *matchHeader) String() string {
|
||||
w := &bytes.Buffer{}
|
||||
fmt.Fprint(w, "haveTag: ")
|
||||
for _, h := range h.haveTags {
|
||||
fmt.Fprintf(w, "%v, ", h)
|
||||
}
|
||||
return w.String()
|
||||
}
|
||||
|
||||
func (t haveTag) String() string {
|
||||
return fmt.Sprintf("%v:%d:%v:%v-%v|%v", t.tag, t.index, t.conf, t.maxRegion, t.maxScript, t.altScript)
|
||||
}
|
||||
|
||||
func TestBestMatchAlloc(t *testing.T) {
|
||||
m := NewMatcher(makeTagList("en sr nl"))
|
||||
// Go allocates when creating a list of tags from a single tag!
|
||||
list := []Tag{English}
|
||||
avg := testtext.AllocsPerRun(1, func() {
|
||||
m.Match(list...)
|
||||
})
|
||||
if avg > 0 {
|
||||
t.Errorf("got %f; want 0", avg)
|
||||
}
|
||||
}
|
||||
|
||||
var benchHave = []Tag{
|
||||
mk("en"),
|
||||
mk("en-GB"),
|
||||
mk("za"),
|
||||
mk("zh-Hant"),
|
||||
mk("zh-Hans-CN"),
|
||||
mk("zh"),
|
||||
mk("zh-HK"),
|
||||
mk("ar-MK"),
|
||||
mk("en-CA"),
|
||||
mk("fr-CA"),
|
||||
mk("fr-US"),
|
||||
mk("fr-CH"),
|
||||
mk("fr"),
|
||||
mk("lt"),
|
||||
mk("lv"),
|
||||
mk("iw"),
|
||||
mk("iw-NL"),
|
||||
mk("he"),
|
||||
mk("he-IT"),
|
||||
mk("tlh"),
|
||||
mk("ja"),
|
||||
mk("ja-Jpan"),
|
||||
mk("ja-Jpan-JP"),
|
||||
mk("de"),
|
||||
mk("de-CH"),
|
||||
mk("de-AT"),
|
||||
mk("de-DE"),
|
||||
mk("sr"),
|
||||
mk("sr-Latn"),
|
||||
mk("sr-Cyrl"),
|
||||
mk("sr-ME"),
|
||||
}
|
||||
|
||||
var benchWant = [][]Tag{
|
||||
[]Tag{
|
||||
mk("en"),
|
||||
},
|
||||
[]Tag{
|
||||
mk("en-AU"),
|
||||
mk("de-HK"),
|
||||
mk("nl"),
|
||||
mk("fy"),
|
||||
mk("lv"),
|
||||
},
|
||||
[]Tag{
|
||||
mk("en-AU"),
|
||||
mk("de-HK"),
|
||||
mk("nl"),
|
||||
mk("fy"),
|
||||
},
|
||||
[]Tag{
|
||||
mk("ja-Hant"),
|
||||
mk("da-HK"),
|
||||
mk("nl"),
|
||||
mk("zh-TW"),
|
||||
},
|
||||
[]Tag{
|
||||
mk("ja-Hant"),
|
||||
mk("da-HK"),
|
||||
mk("nl"),
|
||||
mk("hr"),
|
||||
},
|
||||
}
|
||||
|
||||
func BenchmarkMatch(b *testing.B) {
|
||||
m := newMatcher(benchHave, nil)
|
||||
for i := 0; i < b.N; i++ {
|
||||
for _, want := range benchWant {
|
||||
m.getBest(want...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMatchExact(b *testing.B) {
|
||||
want := mk("en")
|
||||
m := newMatcher(benchHave, nil)
|
||||
for i := 0; i < b.N; i++ {
|
||||
m.getBest(want)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMatchAltLanguagePresent(b *testing.B) {
|
||||
want := mk("hr")
|
||||
m := newMatcher(benchHave, nil)
|
||||
for i := 0; i < b.N; i++ {
|
||||
m.getBest(want)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMatchAltLanguageNotPresent(b *testing.B) {
|
||||
want := mk("nn")
|
||||
m := newMatcher(benchHave, nil)
|
||||
for i := 0; i < b.N; i++ {
|
||||
m.getBest(want)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMatchAltScriptPresent(b *testing.B) {
|
||||
want := mk("zh-Hant-CN")
|
||||
m := newMatcher(benchHave, nil)
|
||||
for i := 0; i < b.N; i++ {
|
||||
m.getBest(want)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMatchAltScriptNotPresent(b *testing.B) {
|
||||
want := mk("fr-Cyrl")
|
||||
m := newMatcher(benchHave, nil)
|
||||
for i := 0; i < b.N; i++ {
|
||||
m.getBest(want)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMatchLimitedExact(b *testing.B) {
|
||||
want := []Tag{mk("he-NL"), mk("iw-NL")}
|
||||
m := newMatcher(benchHave, nil)
|
||||
for i := 0; i < b.N; i++ {
|
||||
m.getBest(want...)
|
||||
}
|
||||
}
|
||||
517
vendor/golang.org/x/text/language/parse_test.go
generated
vendored
517
vendor/golang.org/x/text/language/parse_test.go
generated
vendored
|
|
@ -1,517 +0,0 @@
|
|||
// 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 (
|
||||
"bytes"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/text/internal/tag"
|
||||
)
|
||||
|
||||
type scanTest struct {
|
||||
ok bool // true if scanning does not result in an error
|
||||
in string
|
||||
tok []string // the expected tokens
|
||||
}
|
||||
|
||||
var tests = []scanTest{
|
||||
{true, "", []string{}},
|
||||
{true, "1", []string{"1"}},
|
||||
{true, "en", []string{"en"}},
|
||||
{true, "root", []string{"root"}},
|
||||
{true, "maxchars", []string{"maxchars"}},
|
||||
{false, "bad/", []string{}},
|
||||
{false, "morethan8", []string{}},
|
||||
{false, "-", []string{}},
|
||||
{false, "----", []string{}},
|
||||
{false, "_", []string{}},
|
||||
{true, "en-US", []string{"en", "US"}},
|
||||
{true, "en_US", []string{"en", "US"}},
|
||||
{false, "en-US-", []string{"en", "US"}},
|
||||
{false, "en-US--", []string{"en", "US"}},
|
||||
{false, "en-US---", []string{"en", "US"}},
|
||||
{false, "en--US", []string{"en", "US"}},
|
||||
{false, "-en-US", []string{"en", "US"}},
|
||||
{false, "-en--US-", []string{"en", "US"}},
|
||||
{false, "-en--US-", []string{"en", "US"}},
|
||||
{false, "en-.-US", []string{"en", "US"}},
|
||||
{false, ".-en--US-.", []string{"en", "US"}},
|
||||
{false, "en-u.-US", []string{"en", "US"}},
|
||||
{true, "en-u1-US", []string{"en", "u1", "US"}},
|
||||
{true, "maxchar1_maxchar2-maxchar3", []string{"maxchar1", "maxchar2", "maxchar3"}},
|
||||
{false, "moreThan8-moreThan8-e", []string{"e"}},
|
||||
}
|
||||
|
||||
func TestScan(t *testing.T) {
|
||||
for i, tt := range tests {
|
||||
scan := makeScannerString(tt.in)
|
||||
for j := 0; !scan.done; j++ {
|
||||
if j >= len(tt.tok) {
|
||||
t.Errorf("%d: extra token %q", i, scan.token)
|
||||
} else if tag.Compare(tt.tok[j], scan.token) != 0 {
|
||||
t.Errorf("%d: token %d: found %q; want %q", i, j, scan.token, tt.tok[j])
|
||||
break
|
||||
}
|
||||
scan.scan()
|
||||
}
|
||||
if s := strings.Join(tt.tok, "-"); tag.Compare(s, bytes.Replace(scan.b, b("_"), b("-"), -1)) != 0 {
|
||||
t.Errorf("%d: input: found %q; want %q", i, scan.b, s)
|
||||
}
|
||||
if (scan.err == nil) != tt.ok {
|
||||
t.Errorf("%d: ok: found %v; want %v", i, scan.err == nil, tt.ok)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAcceptMinSize(t *testing.T) {
|
||||
for i, tt := range tests {
|
||||
// count number of successive tokens with a minimum size.
|
||||
for sz := 1; sz <= 8; sz++ {
|
||||
scan := makeScannerString(tt.in)
|
||||
scan.end, scan.next = 0, 0
|
||||
end := scan.acceptMinSize(sz)
|
||||
n := 0
|
||||
for i := 0; i < len(tt.tok) && len(tt.tok[i]) >= sz; i++ {
|
||||
n += len(tt.tok[i])
|
||||
if i > 0 {
|
||||
n++
|
||||
}
|
||||
}
|
||||
if end != n {
|
||||
t.Errorf("%d:%d: found len %d; want %d", i, sz, end, n)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type parseTest struct {
|
||||
i int // the index of this test
|
||||
in string
|
||||
lang, script, region string
|
||||
variants, ext string
|
||||
extList []string // only used when more than one extension is present
|
||||
invalid bool
|
||||
rewrite bool // special rewrite not handled by parseTag
|
||||
changed bool // string needed to be reformatted
|
||||
}
|
||||
|
||||
func parseTests() []parseTest {
|
||||
tests := []parseTest{
|
||||
{in: "root", lang: "und"},
|
||||
{in: "und", lang: "und"},
|
||||
{in: "en", lang: "en"},
|
||||
{in: "xy", lang: "und", invalid: true},
|
||||
{in: "en-ZY", lang: "en", invalid: true},
|
||||
{in: "gsw", lang: "gsw"},
|
||||
{in: "sr_Latn", lang: "sr", script: "Latn"},
|
||||
{in: "af-Arab", lang: "af", script: "Arab"},
|
||||
{in: "nl-BE", lang: "nl", region: "BE"},
|
||||
{in: "es-419", lang: "es", region: "419"},
|
||||
{in: "und-001", lang: "und", region: "001"},
|
||||
{in: "de-latn-be", lang: "de", script: "Latn", region: "BE"},
|
||||
// Variants
|
||||
{in: "de-1901", lang: "de", variants: "1901"},
|
||||
// Accept with unsuppressed script.
|
||||
{in: "de-Latn-1901", lang: "de", script: "Latn", variants: "1901"},
|
||||
// Specialized.
|
||||
{in: "sl-rozaj", lang: "sl", variants: "rozaj"},
|
||||
{in: "sl-rozaj-lipaw", lang: "sl", variants: "rozaj-lipaw"},
|
||||
{in: "sl-rozaj-biske", lang: "sl", variants: "rozaj-biske"},
|
||||
{in: "sl-rozaj-biske-1994", lang: "sl", variants: "rozaj-biske-1994"},
|
||||
{in: "sl-rozaj-1994", lang: "sl", variants: "rozaj-1994"},
|
||||
// Maximum number of variants while adhering to prefix rules.
|
||||
{in: "sl-rozaj-biske-1994-alalc97-fonipa-fonupa-fonxsamp", lang: "sl", variants: "rozaj-biske-1994-alalc97-fonipa-fonupa-fonxsamp"},
|
||||
|
||||
// Sorting.
|
||||
{in: "sl-1994-biske-rozaj", lang: "sl", variants: "rozaj-biske-1994", changed: true},
|
||||
{in: "sl-rozaj-biske-1994-alalc97-fonupa-fonipa-fonxsamp", lang: "sl", variants: "rozaj-biske-1994-alalc97-fonipa-fonupa-fonxsamp", changed: true},
|
||||
{in: "nl-fonxsamp-alalc97-fonipa-fonupa", lang: "nl", variants: "alalc97-fonipa-fonupa-fonxsamp", changed: true},
|
||||
|
||||
// Duplicates variants are removed, but not an error.
|
||||
{in: "nl-fonupa-fonupa", lang: "nl", variants: "fonupa"},
|
||||
|
||||
// Variants that do not have correct prefixes. We still accept these.
|
||||
{in: "de-Cyrl-1901", lang: "de", script: "Cyrl", variants: "1901"},
|
||||
{in: "sl-rozaj-lipaw-1994", lang: "sl", variants: "rozaj-lipaw-1994"},
|
||||
{in: "sl-1994-biske-rozaj-1994-biske-rozaj", lang: "sl", variants: "rozaj-biske-1994", changed: true},
|
||||
{in: "de-Cyrl-1901", lang: "de", script: "Cyrl", variants: "1901"},
|
||||
|
||||
// Invalid variant.
|
||||
{in: "de-1902", lang: "de", variants: "", invalid: true},
|
||||
|
||||
{in: "EN_CYRL", lang: "en", script: "Cyrl"},
|
||||
// private use and extensions
|
||||
{in: "x-a-b-c-d", ext: "x-a-b-c-d"},
|
||||
{in: "x_A.-B-C_D", ext: "x-b-c-d", invalid: true, changed: true},
|
||||
{in: "x-aa-bbbb-cccccccc-d", ext: "x-aa-bbbb-cccccccc-d"},
|
||||
{in: "en-c_cc-b-bbb-a-aaa", lang: "en", changed: true, extList: []string{"a-aaa", "b-bbb", "c-cc"}},
|
||||
{in: "en-x_cc-b-bbb-a-aaa", lang: "en", ext: "x-cc-b-bbb-a-aaa", changed: true},
|
||||
{in: "en-c_cc-b-bbb-a-aaa-x-x", lang: "en", changed: true, extList: []string{"a-aaa", "b-bbb", "c-cc", "x-x"}},
|
||||
{in: "en-v-c", lang: "en", ext: "", invalid: true},
|
||||
{in: "en-v-abcdefghi", lang: "en", ext: "", invalid: true},
|
||||
{in: "en-v-abc-x", lang: "en", ext: "v-abc", invalid: true},
|
||||
{in: "en-v-abc-x-", lang: "en", ext: "v-abc", invalid: true},
|
||||
{in: "en-v-abc-w-x-xx", lang: "en", extList: []string{"v-abc", "x-xx"}, invalid: true, changed: true},
|
||||
{in: "en-v-abc-w-y-yx", lang: "en", extList: []string{"v-abc", "y-yx"}, invalid: true, changed: true},
|
||||
{in: "en-v-c-abc", lang: "en", ext: "c-abc", invalid: true, changed: true},
|
||||
{in: "en-v-w-abc", lang: "en", ext: "w-abc", invalid: true, changed: true},
|
||||
{in: "en-v-x-abc", lang: "en", ext: "x-abc", invalid: true, changed: true},
|
||||
{in: "en-v-x-a", lang: "en", ext: "x-a", invalid: true, changed: true},
|
||||
{in: "en-9-aa-0-aa-z-bb-x-a", lang: "en", extList: []string{"0-aa", "9-aa", "z-bb", "x-a"}, changed: true},
|
||||
{in: "en-u-c", lang: "en", ext: "", invalid: true},
|
||||
{in: "en-u-co-phonebk", lang: "en", ext: "u-co-phonebk"},
|
||||
{in: "en-u-co-phonebk-ca", lang: "en", ext: "u-co-phonebk", invalid: true},
|
||||
{in: "en-u-nu-arabic-co-phonebk-ca", lang: "en", ext: "u-co-phonebk-nu-arabic", invalid: true, changed: true},
|
||||
{in: "en-u-nu-arabic-co-phonebk-ca-x", lang: "en", ext: "u-co-phonebk-nu-arabic", invalid: true, changed: true},
|
||||
{in: "en-u-nu-arabic-co-phonebk-ca-s", lang: "en", ext: "u-co-phonebk-nu-arabic", invalid: true, changed: true},
|
||||
{in: "en-u-nu-arabic-co-phonebk-ca-a12345678", lang: "en", ext: "u-co-phonebk-nu-arabic", invalid: true, changed: true},
|
||||
{in: "en-u-co-phonebook", lang: "en", ext: "", invalid: true},
|
||||
{in: "en-u-co-phonebook-cu-xau", lang: "en", ext: "u-cu-xau", invalid: true, changed: true},
|
||||
{in: "en-Cyrl-u-co-phonebk", lang: "en", script: "Cyrl", ext: "u-co-phonebk"},
|
||||
{in: "en-US-u-co-phonebk", lang: "en", region: "US", ext: "u-co-phonebk"},
|
||||
{in: "en-US-u-co-phonebk-cu-xau", lang: "en", region: "US", ext: "u-co-phonebk-cu-xau"},
|
||||
{in: "en-scotland-u-co-phonebk", lang: "en", variants: "scotland", ext: "u-co-phonebk"},
|
||||
{in: "en-u-cu-xua-co-phonebk", lang: "en", ext: "u-co-phonebk-cu-xua", changed: true},
|
||||
{in: "en-u-def-abc-cu-xua-co-phonebk", lang: "en", ext: "u-abc-def-co-phonebk-cu-xua", changed: true},
|
||||
{in: "en-u-def-abc", lang: "en", ext: "u-abc-def", changed: true},
|
||||
{in: "en-u-cu-xua-co-phonebk-a-cd", lang: "en", extList: []string{"a-cd", "u-co-phonebk-cu-xua"}, changed: true},
|
||||
// Invalid "u" extension. Drop invalid parts.
|
||||
{in: "en-u-cu-co-phonebk", lang: "en", extList: []string{"u-co-phonebk"}, invalid: true, changed: true},
|
||||
{in: "en-u-cu-xau-co", lang: "en", extList: []string{"u-cu-xau"}, invalid: true},
|
||||
// We allow duplicate keys as the LDML spec does not explicitly prohibit it.
|
||||
// TODO: Consider eliminating duplicates and returning an error.
|
||||
{in: "en-u-cu-xau-co-phonebk-cu-xau", lang: "en", ext: "u-co-phonebk-cu-xau-cu-xau", changed: true},
|
||||
{in: "en-t-en-Cyrl-NL-fonipa", lang: "en", ext: "t-en-cyrl-nl-fonipa", changed: true},
|
||||
{in: "en-t-en-Cyrl-NL-fonipa-t0-abc-def", lang: "en", ext: "t-en-cyrl-nl-fonipa-t0-abc-def", changed: true},
|
||||
{in: "en-t-t0-abcd", lang: "en", ext: "t-t0-abcd"},
|
||||
// Not necessary to have changed here.
|
||||
{in: "en-t-nl-abcd", lang: "en", ext: "t-nl", invalid: true},
|
||||
{in: "en-t-nl-latn", lang: "en", ext: "t-nl-latn"},
|
||||
{in: "en-t-t0-abcd-x-a", lang: "en", extList: []string{"t-t0-abcd", "x-a"}},
|
||||
// invalid
|
||||
{in: "", lang: "und", invalid: true},
|
||||
{in: "-", lang: "und", invalid: true},
|
||||
{in: "x", lang: "und", invalid: true},
|
||||
{in: "x-", lang: "und", invalid: true},
|
||||
{in: "x--", lang: "und", invalid: true},
|
||||
{in: "a-a-b-c-d", lang: "und", invalid: true},
|
||||
{in: "en-", lang: "en", invalid: true},
|
||||
{in: "enne-", lang: "und", invalid: true},
|
||||
{in: "en.", lang: "und", invalid: true},
|
||||
{in: "en.-latn", lang: "und", invalid: true},
|
||||
{in: "en.-en", lang: "en", invalid: true},
|
||||
{in: "x-a-tooManyChars-c-d", ext: "x-a-c-d", invalid: true, changed: true},
|
||||
{in: "a-tooManyChars-c-d", lang: "und", invalid: true},
|
||||
// TODO: check key-value validity
|
||||
// { in: "en-u-cu-xd", lang: "en", ext: "u-cu-xd", invalid: true },
|
||||
{in: "en-t-abcd", lang: "en", invalid: true},
|
||||
{in: "en-Latn-US-en", lang: "en", script: "Latn", region: "US", invalid: true},
|
||||
// rewrites (more tests in TestGrandfathered)
|
||||
{in: "zh-min-nan", lang: "nan"},
|
||||
{in: "zh-yue", lang: "yue"},
|
||||
{in: "zh-xiang", lang: "hsn", rewrite: true},
|
||||
{in: "zh-guoyu", lang: "cmn", rewrite: true},
|
||||
{in: "iw", lang: "iw"},
|
||||
{in: "sgn-BE-FR", lang: "sfb", rewrite: true},
|
||||
{in: "i-klingon", lang: "tlh", rewrite: true},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
tests[i].i = i
|
||||
if tt.extList != nil {
|
||||
tests[i].ext = strings.Join(tt.extList, "-")
|
||||
}
|
||||
if tt.ext != "" && tt.extList == nil {
|
||||
tests[i].extList = []string{tt.ext}
|
||||
}
|
||||
}
|
||||
return tests
|
||||
}
|
||||
|
||||
func TestParseExtensions(t *testing.T) {
|
||||
for i, tt := range parseTests() {
|
||||
if tt.ext == "" || tt.rewrite {
|
||||
continue
|
||||
}
|
||||
scan := makeScannerString(tt.in)
|
||||
if len(scan.b) > 1 && scan.b[1] != '-' {
|
||||
scan.end = nextExtension(string(scan.b), 0)
|
||||
scan.next = scan.end + 1
|
||||
scan.scan()
|
||||
}
|
||||
start := scan.start
|
||||
scan.toLower(start, len(scan.b))
|
||||
parseExtensions(&scan)
|
||||
ext := string(scan.b[start:])
|
||||
if ext != tt.ext {
|
||||
t.Errorf("%d(%s): ext was %v; want %v", i, tt.in, ext, tt.ext)
|
||||
}
|
||||
if changed := !strings.HasPrefix(tt.in[start:], ext); changed != tt.changed {
|
||||
t.Errorf("%d(%s): changed was %v; want %v", i, tt.in, changed, tt.changed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// partChecks runs checks for each part by calling the function returned by f.
|
||||
func partChecks(t *testing.T, f func(*parseTest) (Tag, bool)) {
|
||||
for i, tt := range parseTests() {
|
||||
tag, skip := f(&tt)
|
||||
if skip {
|
||||
continue
|
||||
}
|
||||
if l, _ := getLangID(b(tt.lang)); l != tag.lang {
|
||||
t.Errorf("%d: lang was %q; want %q", i, tag.lang, l)
|
||||
}
|
||||
if sc, _ := getScriptID(script, b(tt.script)); sc != tag.script {
|
||||
t.Errorf("%d: script was %q; want %q", i, tag.script, sc)
|
||||
}
|
||||
if r, _ := getRegionID(b(tt.region)); r != tag.region {
|
||||
t.Errorf("%d: region was %q; want %q", i, tag.region, r)
|
||||
}
|
||||
if tag.str == "" {
|
||||
continue
|
||||
}
|
||||
p := int(tag.pVariant)
|
||||
if p < int(tag.pExt) {
|
||||
p++
|
||||
}
|
||||
if s, g := tag.str[p:tag.pExt], tt.variants; s != g {
|
||||
t.Errorf("%d: variants was %q; want %q", i, s, g)
|
||||
}
|
||||
p = int(tag.pExt)
|
||||
if p > 0 && p < len(tag.str) {
|
||||
p++
|
||||
}
|
||||
if s, g := (tag.str)[p:], tt.ext; s != g {
|
||||
t.Errorf("%d: extensions were %q; want %q", i, s, g)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseTag(t *testing.T) {
|
||||
partChecks(t, func(tt *parseTest) (id Tag, skip bool) {
|
||||
if strings.HasPrefix(tt.in, "x-") || tt.rewrite {
|
||||
return Tag{}, true
|
||||
}
|
||||
scan := makeScannerString(tt.in)
|
||||
id, end := parseTag(&scan)
|
||||
id.str = string(scan.b[:end])
|
||||
tt.ext = ""
|
||||
tt.extList = []string{}
|
||||
return id, false
|
||||
})
|
||||
}
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
partChecks(t, func(tt *parseTest) (id Tag, skip bool) {
|
||||
id, err := Raw.Parse(tt.in)
|
||||
ext := ""
|
||||
if id.str != "" {
|
||||
if strings.HasPrefix(id.str, "x-") {
|
||||
ext = id.str
|
||||
} else if int(id.pExt) < len(id.str) && id.pExt > 0 {
|
||||
ext = id.str[id.pExt+1:]
|
||||
}
|
||||
}
|
||||
if tag, _ := Raw.Parse(id.String()); tag.String() != id.String() {
|
||||
t.Errorf("%d:%s: reparse was %q; want %q", tt.i, tt.in, id.String(), tag.String())
|
||||
}
|
||||
if ext != tt.ext {
|
||||
t.Errorf("%d:%s: ext was %q; want %q", tt.i, tt.in, ext, tt.ext)
|
||||
}
|
||||
changed := id.str != "" && !strings.HasPrefix(tt.in, id.str)
|
||||
if changed != tt.changed {
|
||||
t.Errorf("%d:%s: changed was %v; want %v", tt.i, tt.in, changed, tt.changed)
|
||||
}
|
||||
if (err != nil) != tt.invalid {
|
||||
t.Errorf("%d:%s: invalid was %v; want %v. Error: %v", tt.i, tt.in, err != nil, tt.invalid, err)
|
||||
}
|
||||
return id, false
|
||||
})
|
||||
}
|
||||
|
||||
func TestErrors(t *testing.T) {
|
||||
mkInvalid := func(s string) error {
|
||||
return mkErrInvalid([]byte(s))
|
||||
}
|
||||
tests := []struct {
|
||||
in string
|
||||
out error
|
||||
}{
|
||||
// invalid subtags.
|
||||
{"ac", mkInvalid("ac")},
|
||||
{"AC", mkInvalid("ac")},
|
||||
{"aa-Uuuu", mkInvalid("Uuuu")},
|
||||
{"aa-AB", mkInvalid("AB")},
|
||||
// ill-formed wins over invalid.
|
||||
{"ac-u", errSyntax},
|
||||
{"ac-u-ca", errSyntax},
|
||||
{"ac-u-ca-co-pinyin", errSyntax},
|
||||
{"noob", errSyntax},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
_, err := Parse(tt.in)
|
||||
if err != tt.out {
|
||||
t.Errorf("%s: was %q; want %q", tt.in, err, tt.out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompose1(t *testing.T) {
|
||||
partChecks(t, func(tt *parseTest) (id Tag, skip bool) {
|
||||
l, _ := ParseBase(tt.lang)
|
||||
s, _ := ParseScript(tt.script)
|
||||
r, _ := ParseRegion(tt.region)
|
||||
v := []Variant{}
|
||||
for _, x := range strings.Split(tt.variants, "-") {
|
||||
p, _ := ParseVariant(x)
|
||||
v = append(v, p)
|
||||
}
|
||||
e := []Extension{}
|
||||
for _, x := range tt.extList {
|
||||
p, _ := ParseExtension(x)
|
||||
e = append(e, p)
|
||||
}
|
||||
id, _ = Raw.Compose(l, s, r, v, e)
|
||||
return id, false
|
||||
})
|
||||
}
|
||||
|
||||
func TestCompose2(t *testing.T) {
|
||||
partChecks(t, func(tt *parseTest) (id Tag, skip bool) {
|
||||
l, _ := ParseBase(tt.lang)
|
||||
s, _ := ParseScript(tt.script)
|
||||
r, _ := ParseRegion(tt.region)
|
||||
p := []interface{}{l, s, r, s, r, l}
|
||||
for _, x := range strings.Split(tt.variants, "-") {
|
||||
v, _ := ParseVariant(x)
|
||||
p = append(p, v)
|
||||
}
|
||||
for _, x := range tt.extList {
|
||||
e, _ := ParseExtension(x)
|
||||
p = append(p, e)
|
||||
}
|
||||
id, _ = Raw.Compose(p...)
|
||||
return id, false
|
||||
})
|
||||
}
|
||||
|
||||
func TestCompose3(t *testing.T) {
|
||||
partChecks(t, func(tt *parseTest) (id Tag, skip bool) {
|
||||
id, _ = Raw.Parse(tt.in)
|
||||
id, _ = Raw.Compose(id)
|
||||
return id, false
|
||||
})
|
||||
}
|
||||
|
||||
func mk(s string) Tag {
|
||||
return Raw.Make(s)
|
||||
}
|
||||
|
||||
func TestParseAcceptLanguage(t *testing.T) {
|
||||
type res struct {
|
||||
t Tag
|
||||
q float32
|
||||
}
|
||||
en := []res{{mk("en"), 1.0}}
|
||||
tests := []struct {
|
||||
out []res
|
||||
in string
|
||||
ok bool
|
||||
}{
|
||||
{en, "en", true},
|
||||
{en, " en", true},
|
||||
{en, "en ", true},
|
||||
{en, " en ", true},
|
||||
{en, "en,", true},
|
||||
{en, ",en", true},
|
||||
{en, ",,,en,,,", true},
|
||||
{en, ",en;q=1", true},
|
||||
|
||||
// We allow an empty input, contrary to spec.
|
||||
{nil, "", true},
|
||||
{[]res{{mk("aa"), 1}}, "aa;", true}, // allow unspecified weight
|
||||
|
||||
// errors
|
||||
{nil, ";", false},
|
||||
{nil, "$", false},
|
||||
{nil, "e;", false},
|
||||
{nil, "x;", false},
|
||||
{nil, "x", false},
|
||||
{nil, "ac", false}, // non-existing language
|
||||
{nil, "aa;q", false},
|
||||
{nil, "aa;q=", false},
|
||||
{nil, "aa;q=.", false},
|
||||
|
||||
// odd fallbacks
|
||||
{
|
||||
[]res{{mk("en"), 0.1}},
|
||||
" english ;q=.1",
|
||||
true,
|
||||
},
|
||||
{
|
||||
[]res{{mk("it"), 1.0}, {mk("de"), 1.0}, {mk("fr"), 1.0}},
|
||||
" italian, deutsch, french",
|
||||
true,
|
||||
},
|
||||
|
||||
// lists
|
||||
{
|
||||
[]res{{mk("en"), 0.1}},
|
||||
"en;q=.1",
|
||||
true,
|
||||
},
|
||||
{
|
||||
[]res{{mk("mul"), 1.0}},
|
||||
"*",
|
||||
true,
|
||||
},
|
||||
{
|
||||
[]res{{mk("en"), 1.0}, {mk("de"), 1.0}},
|
||||
"en,de",
|
||||
true,
|
||||
},
|
||||
{
|
||||
[]res{{mk("en"), 1.0}, {mk("de"), .5}},
|
||||
"en,de;q=0.5",
|
||||
true,
|
||||
},
|
||||
{
|
||||
[]res{{mk("de"), 0.8}, {mk("en"), 0.5}},
|
||||
" en ; q = 0.5 , , de;q=0.8",
|
||||
true,
|
||||
},
|
||||
{
|
||||
[]res{{mk("en"), 1.0}, {mk("de"), 1.0}, {mk("fr"), 1.0}, {mk("tlh"), 1.0}},
|
||||
"en,de,fr,i-klingon",
|
||||
true,
|
||||
},
|
||||
// sorting
|
||||
{
|
||||
[]res{{mk("tlh"), 0.4}, {mk("de"), 0.2}, {mk("fr"), 0.2}, {mk("en"), 0.1}},
|
||||
"en;q=0.1,de;q=0.2,fr;q=0.2,i-klingon;q=0.4",
|
||||
true,
|
||||
},
|
||||
// dropping
|
||||
{
|
||||
[]res{{mk("fr"), 0.2}, {mk("en"), 0.1}},
|
||||
"en;q=0.1,de;q=0,fr;q=0.2,i-klingon;q=0.0",
|
||||
true,
|
||||
},
|
||||
}
|
||||
for i, tt := range tests {
|
||||
tags, qs, e := ParseAcceptLanguage(tt.in)
|
||||
if e == nil != tt.ok {
|
||||
t.Errorf("%d:%s:err: was %v; want %v", i, tt.in, e == nil, tt.ok)
|
||||
}
|
||||
for j, tag := range tags {
|
||||
if out := tt.out[j]; !tag.equalTags(out.t) || qs[j] != out.q {
|
||||
t.Errorf("%d:%s: was %s, %1f; want %s, %1f", i, tt.in, tag, qs[j], out.t, out.q)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
4871
vendor/golang.org/x/text/language/tables.go
generated
vendored
4871
vendor/golang.org/x/text/language/tables.go
generated
vendored
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue