Example #1
0
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>
}
Example #2
0
func supportedRegions() []language.Region {
	reg := make([]language.Region, 0, regionIndex.len())
	regionIndex.keys(func(s string) {
		reg = append(reg, language.MustParseRegion(s))
	})
	return reg
}
Example #3
0
func (r *regionInfo) Region() language.Region {
	// TODO: this could be much faster.
	var buf [2]byte
	buf[0] = uint8(r.region >> 8)
	buf[1] = uint8(r.region)
	return language.MustParseRegion(string(buf[:]))
}
Example #4
0
func TestCountry(t *testing.T) {

	ch := language.MustParseRegion("CH")
	tld, err := ch.Canonicalize().TLD()
	assert.NoError(t, err)
	t.Logf("\n%#v\n", tld.String())
}
Example #5
0
func TestDictionaryRegion(t *testing.T) {
	tests := []struct {
		d      *Dictionary
		region string
		name   string
	}{
		{English, "FR", "France"},
		{Portuguese, "009", "Oceania"},
		{EuropeanPortuguese, "009", "Oceânia"},
	}
	for i, test := range tests {
		tag := language.MustParseRegion(test.region)
		if got := test.d.Regions().Name(tag); got != test.name {
			t.Errorf("%d:%v: got %s; want %s", i, tag, got, test.name)
		}
	}
}
Example #6
0
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
}
Example #7
0
func TestRegion(t *testing.T) {
	tests := []struct {
		dict string
		reg  string
		name string
	}{
		{"nl", "NL", "Nederland"},
		{"en", "US", "United States"},
		{"en", "ZZ", "Unknown Region"},
		{"en", "UM", "U.S. Outlying Islands"},
		{"en-GB", "UM", "U.S. Outlying Islands"},
		{"en-GB", "NL", "Netherlands"},
		// Canonical equivalents
		{"en", "UK", "United Kingdom"},
		// No region
		{"en", "pt", "Unknown Region"},
		{"en", "und", "Unknown Region"},
		// Don't introduce regions with canonicalization.
		{"en", "mo", "Unknown Region"},
	}
	for i, tt := range tests {
		d := Regions(language.MustParse(tt.dict))
		var x interface{}
		if unicode.IsUpper(rune(tt.reg[0])) {
			// Region
			x = language.MustParseRegion(tt.reg)
			tag, _ := language.Raw.Compose(x)
			if n := d.Name(tag); n != tt.name {
				t.Errorf("%d:%s:%s: was %q; want %q", i, tt.dict, tt.reg, n, tt.name)
			}
		} else {
			// Tag
			x = language.Raw.MustParse(tt.reg)
		}
		if n := d.Name(x); n != tt.name {
			t.Errorf("%d:%s:%s: was %q; want %q", i, tt.dict, tt.reg, n, tt.name)
		}
	}
}
Example #8
0
func TestFromRegion(t *testing.T) {
	testCases := []struct {
		region, currency string
		ok               bool
	}{
		{"NL", "EUR", true},
		{"BE", "EUR", true},
		{"AG", "XCD", true},
		{"CH", "CHF", true},
		{"CU", "CUP", true},   // first of multiple
		{"DG", "USD", true},   // does not have M49 code
		{"150", "XXX", false}, // implicit false
		{"CP", "XXX", false},  // explicit false in CLDR
		{"CS", "XXX", false},  // all expired
		{"ZZ", "XXX", false},  // none match
	}
	for _, tc := range testCases {
		cur, ok := FromRegion(language.MustParseRegion(tc.region))
		if cur.String() != tc.currency || ok != tc.ok {
			t.Errorf("%s: got %v, %v; want %v, %v", tc.region, cur, ok, tc.currency, tc.ok)
		}
	}
}
Example #9
0
func (b *builder) genCurrencies(w *gen.CodeWriter, data *cldr.SupplementalData) {
	// 3-letter ISO currency codes
	// Start with dummy to let index start at 1.
	currencies := []string{"\x00\x00\x00\x00"}

	// currency codes
	for _, reg := range data.CurrencyData.Region {
		for _, cur := range reg.Currency {
			currencies = append(currencies, cur.Iso4217)
		}
	}
	// Not included in the list for some reasons:
	currencies = append(currencies, "MVP")

	sort.Strings(currencies)
	// Unique the elements.
	k := 0
	for i := 1; i < len(currencies); i++ {
		if currencies[k] != currencies[i] {
			currencies[k+1] = currencies[i]
			k++
		}
	}
	currencies = currencies[:k+1]

	// Close with dummy for simpler and faster searching.
	currencies = append(currencies, "\xff\xff\xff\xff")

	// Write currency values.
	fmt.Fprintln(w, "const (")
	for _, c := range constants {
		index := sort.SearchStrings(currencies, c)
		fmt.Fprintf(w, "\t%s = %d\n", strings.ToLower(c), index)
	}
	fmt.Fprint(w, ")")

	// Compute currency-related data that we merge into the table.
	for _, info := range data.CurrencyData.Fractions[0].Info {
		if info.Iso4217 == "DEFAULT" {
			continue
		}
		standard := getRoundingIndex(info.Digits, info.Rounding, 0)
		cash := getRoundingIndex(info.CashDigits, info.CashRounding, standard)

		index := sort.SearchStrings(currencies, info.Iso4217)
		currencies[index] += mkCurrencyInfo(standard, cash)
	}

	// Set default values for entries that weren't touched.
	for i, c := range currencies {
		if len(c) == 3 {
			currencies[i] += mkCurrencyInfo(0, 0)
		}
	}

	b.currencies = tag.Index(strings.Join(currencies, ""))
	w.WriteComment(`
	currency holds an alphabetically sorted list of canonical 3-letter currency
	identifiers. Each identifier is followed by a byte of type currencyInfo,
	defined in gen_common.go.`)
	w.WriteConst("currency", b.currencies)

	// Hack alert: gofmt indents a trailing comment after an indented string.
	// Ensure that the next thing written is not a comment.
	b.numCurrencies = (len(b.currencies) / 4) - 2
	w.WriteConst("numCurrencies", b.numCurrencies)

	// Create a table that maps regions to currencies.
	regionToCurrency := []toCurrency{}

	for _, reg := range data.CurrencyData.Region {
		if len(reg.Iso3166) != 2 {
			log.Fatalf("Unexpected group %q in region data", reg.Iso3166)
		}
		if len(reg.Currency) == 0 {
			continue
		}
		cur := reg.Currency[0]
		if cur.To != "" || cur.Tender == "false" {
			continue
		}
		regionToCurrency = append(regionToCurrency, toCurrency{
			region: regionToCode(language.MustParseRegion(reg.Iso3166)),
			code:   uint16(b.currencies.Index([]byte(cur.Iso4217))),
		})
	}
	sort.Sort(byRegion(regionToCurrency))

	w.WriteType(toCurrency{})
	w.WriteVar("regionToCurrency", regionToCurrency)
}
Example #10
0
var (
	langTagSet = tagSet{
		single: langIndex,
		long:   langTagsLong,
	}

	// selfTagSet is used for indexing the language strings in their own
	// language.
	selfTagSet = tagSet{
		single: selfIndex,
		long:   selfTagsLong,
	}

	zzzz = language.MustParseScript("Zzzz")
	zz   = language.MustParseRegion("ZZ")
)

// index returns the index of the tag for the given base, script and region or
// its parent if the tag is not available. If the match is for a parent entry,
// the excess script and region are returned.
func (ts *tagSet) index(base language.Base, scr language.Script, reg language.Region) (int, language.Script, language.Region) {
	lang := base.String()
	index := -1
	if (scr != language.Script{} || reg != language.Region{}) {
		if scr == zzzz {
			scr = language.Script{}
		}
		if reg == zz {
			reg = language.Region{}
		}
Example #11
0
// generate builds and writes all tables.
func (b *builder) generate() {
	fmt.Fprintf(b.w, versionInfo, cldr.Version)

	b.filter()
	b.setData("lang", func(g *group, loc language.Tag, ldn *cldr.LocaleDisplayNames) {
		if ldn.Languages != nil {
			for _, v := range ldn.Languages.Language {
				tag := tagForm.MustParse(v.Type)
				if tags.contains(tag) {
					g.set(loc, tag.String(), v.Data())
				}
			}
		}
	})
	b.setData("script", func(g *group, loc language.Tag, ldn *cldr.LocaleDisplayNames) {
		if ldn.Scripts != nil {
			for _, v := range ldn.Scripts.Script {
				g.set(loc, language.MustParseScript(v.Type).String(), v.Data())
			}
		}
	})
	b.setData("region", func(g *group, loc language.Tag, ldn *cldr.LocaleDisplayNames) {
		if ldn.Territories != nil {
			for _, v := range ldn.Territories.Territory {
				g.set(loc, language.MustParseRegion(v.Type).String(), v.Data())
			}
		}
	})

	b.makeSupported()

	n := b.writeParents()

	n += b.writeGroup("lang")
	n += b.writeGroup("script")
	n += b.writeGroup("region")

	b.writeSupported()

	n += b.writeDictionaries()

	b.supported = []language.Tag{self}

	// Compute the names of locales in their own language. Some of these names
	// may be specified in their parent locales. We iterate the maximum depth
	// of the parent three times to match successive parents of tags until a
	// possible match is found.
	for i := 0; i < 4; i++ {
		b.setData("self", func(g *group, tag language.Tag, ldn *cldr.LocaleDisplayNames) {
			parent := tag
			if b, s, r := tag.Raw(); i > 0 && (s != language.Script{} && r == language.Region{}) {
				parent, _ = language.Raw.Compose(b)
			}
			if ldn.Languages != nil {
				for _, v := range ldn.Languages.Language {
					key := tagForm.MustParse(v.Type)
					saved := key
					if key == parent {
						g.set(self, tag.String(), v.Data())
					}
					for k := 0; k < i; k++ {
						key = key.Parent()
					}
					if key == tag {
						g.set(self, saved.String(), v.Data()) // set does not overwrite a value.
					}
				}
			}
		})
	}

	n += b.writeGroup("self")

	fmt.Fprintf(b.w, "// TOTAL %d Bytes (%d KB)", n, n/1000)
}
Example #12
0
func TestTables(t *testing.T) {
	testtext.SkipIfNotLong(t)

	// Read the CLDR zip file.
	r := gen.OpenCLDRCoreZip()
	defer r.Close()

	d := &cldr.Decoder{}
	d.SetDirFilter("supplemental", "main")
	d.SetSectionFilter("numbers")
	data, err := d.DecodeZip(r)
	if err != nil {
		t.Fatalf("DecodeZip: %v", err)
	}

	dr, err := cldr.ParseDraft(*draft)
	if err != nil {
		t.Fatalf("filter: %v", err)
	}

	for _, lang := range data.Locales() {
		p := message.NewPrinter(language.MustParse(lang))

		ldml := data.RawLDML(lang)
		if ldml.Numbers == nil || ldml.Numbers.Currencies == nil {
			continue
		}
		for _, c := range ldml.Numbers.Currencies.Currency {
			syms := cldr.MakeSlice(&c.Symbol)
			syms.SelectDraft(dr)

			for _, sym := range c.Symbol {
				cur, err := ParseISO(c.Type)
				if err != nil {
					continue
				}
				formatter := Symbol
				switch sym.Alt {
				case "":
				case "narrow":
					formatter = NarrowSymbol
				default:
					continue
				}
				want := sym.Data()
				if got := p.Sprint(formatter(cur)); got != want {
					t.Errorf("%s:%sSymbol(%s) = %s; want %s", lang, strings.Title(sym.Alt), c.Type, got, want)
				}
			}
		}
	}

	for _, reg := range data.Supplemental().CurrencyData.Region {
		i := 0
		for ; regionData[i].Region().String() != reg.Iso3166; i++ {
		}
		it := Query(Historical, NonTender, Region(language.MustParseRegion(reg.Iso3166)))
		for _, cur := range reg.Currency {
			from, _ := time.Parse("2006-01-02", cur.From)
			to, _ := time.Parse("2006-01-02", cur.To)

			it.Next()
			for j, r := range []QueryIter{&iter{regionInfo: &regionData[i]}, it} {
				if got, _ := r.From(); from != got {
					t.Errorf("%d:%s:%s:from: got %v; want %v", j, reg.Iso3166, cur.Iso4217, got, from)
				}
				if got, _ := r.To(); to != got {
					t.Errorf("%d:%s:%s:to: got %v; want %v", j, reg.Iso3166, cur.Iso4217, got, to)
				}
			}
			i++
		}
	}
}
Example #13
0
func TestQuery(t *testing.T) {
	r := func(region string) language.Region {
		return language.MustParseRegion(region)
	}
	t1800, _ := time.Parse("2006-01-02", "1800-01-01")
	type result struct {
		region   language.Region
		unit     Unit
		isTender bool
		from, to string
	}
	testCases := []struct {
		name    string
		opts    []QueryOption
		results []result
	}{{
		name:    "XA",
		opts:    []QueryOption{Region(r("XA"))},
		results: []result{},
	}, {
		name: "AC",
		opts: []QueryOption{Region(r("AC"))},
		results: []result{
			{r("AC"), MustParseISO("SHP"), true, "1976-01-01", ""},
		},
	}, {
		name: "US",
		opts: []QueryOption{Region(r("US"))},
		results: []result{
			{r("US"), MustParseISO("USD"), true, "1792-01-01", ""},
		},
	}, {
		name: "US-hist",
		opts: []QueryOption{Region(r("US")), Historical},
		results: []result{
			{r("US"), MustParseISO("USD"), true, "1792-01-01", ""},
		},
	}, {
		name: "US-non-tender",
		opts: []QueryOption{Region(r("US")), NonTender},
		results: []result{
			{r("US"), MustParseISO("USD"), true, "1792-01-01", ""},
			{r("US"), MustParseISO("USN"), false, "", ""},
		},
	}, {
		name: "US-historical+non-tender",
		opts: []QueryOption{Region(r("US")), Historical, NonTender},
		results: []result{
			{r("US"), MustParseISO("USD"), true, "1792-01-01", ""},
			{r("US"), MustParseISO("USN"), false, "", ""},
			{r("US"), MustParseISO("USS"), false, "", "2014-03-01"},
		},
	}, {
		name: "1800",
		opts: []QueryOption{Date(t1800)},
		results: []result{
			{r("CH"), MustParseISO("CHF"), true, "1799-03-17", ""},
			{r("GB"), MustParseISO("GBP"), true, "1694-07-27", ""},
			{r("GI"), MustParseISO("GIP"), true, "1713-01-01", ""},
			// The date for IE and PR seem wrong, so these may be updated at
			// some point causing the tests to fail.
			{r("IE"), MustParseISO("GBP"), true, "1800-01-01", "1922-01-01"},
			{r("PR"), MustParseISO("ESP"), true, "1800-01-01", "1898-12-10"},
			{r("US"), MustParseISO("USD"), true, "1792-01-01", ""},
		},
	}}
	for _, tc := range testCases {
		n := 0
		for it := Query(tc.opts...); it.Next(); n++ {
			if n < len(tc.results) {
				got := result{
					it.Region(),
					it.Unit(),
					it.IsTender(),
					getTime(it.From()),
					getTime(it.To()),
				}
				if got != tc.results[n] {
					t.Errorf("%s:%d: got %v; want %v", tc.name, n, got, tc.results[n])
				}
			}
		}
		if n != len(tc.results) {
			t.Errorf("%s: unexpected number of results: got %d; want %d", tc.name, n, len(tc.results))
		}
	}
}
Example #14
0
// generate builds and writes all tables.
func (b *builder) generate() {
	fmt.Fprintf(b.w, versionInfo, cldr.Version)

	b.filter()
	b.setData("lang", func(g *group, loc language.Tag, ldn *cldr.LocaleDisplayNames) {
		if ldn.Languages != nil {
			for _, v := range ldn.Languages.Language {
				tag := tagForm.MustParse(v.Type)
				if tags.contains(tag) {
					g.set(loc, tag.String(), v.Data())
				}
			}
		}
	})
	b.setData("script", func(g *group, loc language.Tag, ldn *cldr.LocaleDisplayNames) {
		if ldn.Scripts != nil {
			for _, v := range ldn.Scripts.Script {
				code := language.MustParseScript(v.Type)
				if code.IsPrivateUse() { // Qaaa..Qabx
					// TODO: data currently appears to be very meager.
					// Reconsider if we have data for English.
					if loc == language.English {
						log.Fatal("Consider including data for private use scripts.")
					}
					continue
				}
				g.set(loc, code.String(), v.Data())
			}
		}
	})
	b.setData("region", func(g *group, loc language.Tag, ldn *cldr.LocaleDisplayNames) {
		if ldn.Territories != nil {
			for _, v := range ldn.Territories.Territory {
				g.set(loc, language.MustParseRegion(v.Type).String(), v.Data())
			}
		}
	})

	b.makeSupported()

	b.writeParents()

	b.writeGroup("lang")
	b.writeGroup("script")
	b.writeGroup("region")

	b.w.WriteConst("numSupported", len(b.supported))
	buf := bytes.Buffer{}
	for _, tag := range b.supported {
		fmt.Fprint(&buf, tag.String(), "|")
	}
	b.w.WriteConst("supported", buf.String())

	b.writeDictionaries()

	b.supported = []language.Tag{self}

	// Compute the names of locales in their own language. Some of these names
	// may be specified in their parent locales. We iterate the maximum depth
	// of the parent three times to match successive parents of tags until a
	// possible match is found.
	for i := 0; i < 4; i++ {
		b.setData("self", func(g *group, tag language.Tag, ldn *cldr.LocaleDisplayNames) {
			parent := tag
			if b, s, r := tag.Raw(); i > 0 && (s != language.Script{} && r == language.Region{}) {
				parent, _ = language.Raw.Compose(b)
			}
			if ldn.Languages != nil {
				for _, v := range ldn.Languages.Language {
					key := tagForm.MustParse(v.Type)
					saved := key
					if key == parent {
						g.set(self, tag.String(), v.Data())
					}
					for k := 0; k < i; k++ {
						key = key.Parent()
					}
					if key == tag {
						g.set(self, saved.String(), v.Data()) // set does not overwrite a value.
					}
				}
			}
		})
	}

	b.writeGroup("self")
}