Skip to content

Commit

Permalink
Add support for localized layouts and regions, data for 14 countries.
Browse files Browse the repository at this point in the history
Expanded address formats for AE, AM, CA, CN, EG, HK, JP, KP, KR, TH, TW, RU, UA, VN.
  • Loading branch information
bojanz committed Oct 21, 2020
1 parent ee3a7f5 commit ce03019
Show file tree
Hide file tree
Showing 5 changed files with 444 additions and 3 deletions.
30 changes: 30 additions & 0 deletions address.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ func (a Address) IsEmpty() bool {

// Format represents an address format.
type Format struct {
Locale Locale
Layout string
LocalLayout string
Required []Field
SublocalityType SublocalityType
LocalityType LocalityType
Expand All @@ -42,6 +44,7 @@ type Format struct {
PostalCodePattern string
ShowRegionID bool
Regions map[string]string
LocalRegions map[string]string
}

// IsRequired returns whether the given field is required.
Expand Down Expand Up @@ -84,6 +87,33 @@ func (f Format) CheckPostalCode(postalCode string) bool {
return rx.MatchString(postalCode)
}

// SelectLayout selects the correct layout for the given locale.
func (f Format) SelectLayout(locale Locale) string {
if f.LocalLayout != "" && f.useLocalData(locale) {
return f.LocalLayout
}
return f.Layout
}

// SelectRegions selects the correct regions for the given locale.
func (f Format) SelectRegions(locale Locale) map[string]string {
if len(f.LocalRegions) > 0 && f.useLocalData(locale) {
return f.LocalRegions
}
return f.Regions
}

// useLocalData returns whether local data should be used for the given locale.
func (f Format) useLocalData(locale Locale) bool {
if locale.Script == "Latn" {
// Allow locales to opt out of local data. E.g: zh-Latn.
return false
}
// Scripts are not compared, matching libaddressinput behavior. This means
// that zh-Hant data will be shown to zh-Hans users, and vice-versa.
return locale.Language == f.Locale.Language
}

// CheckCountryCode checks whether the given country code is valid.
//
// An empty country code is considered valid.
Expand Down
77 changes: 77 additions & 0 deletions address_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,83 @@ func TestFormat_CheckPostalCode(t *testing.T) {
}
}

func TestFormat_SelectLayout(t *testing.T) {
tests := []struct {
countryCode string
locale string
wantLocal bool
}{
// China ("zh").
{"CN", "en", false},
{"CN", "ja", false},
{"CN", "zh-Latn", false},
{"CN", "zh", true},
{"CN", "zh-Hant", true},
// Hong Kong ("zh-Hant").
{"HK", "en", false},
{"HK", "ja", false},
{"HK", "zh-Latn", false},
{"HK", "zh", true},
{"HK", "zh-Hant", true},
// Serbia (no local layout defined).
{"RS", "en", false},
}

for _, tt := range tests {
t.Run("", func(t *testing.T) {
locale := address.NewLocale(tt.locale)
format := address.GetFormat(tt.countryCode)
got := format.SelectLayout(locale)
want := format.Layout
if tt.wantLocal {
want = format.LocalLayout
}

if got != want {
t.Errorf("got %v, want %v", got, want)
}
})
}
}

func TestFormat_SelectRegions(t *testing.T) {
tests := []struct {
countryCode string
locale string
wantLocal bool
}{
// China ("zh").
{"CN", "en", false},
{"CN", "ja", false},
{"CN", "zh-Latn", false},
{"CN", "zh", true},
{"CN", "zh-Hant", true},
// Hong Kong ("zh-Hant").
{"HK", "en", false},
{"HK", "ja", false},
{"HK", "zh-Latn", false},
{"HK", "zh", true},
{"HK", "zh-Hant", true},
// Serbia (no local regions defined).
{"RS", "en", false},
}

for _, tt := range tests {
t.Run("", func(t *testing.T) {
format := address.GetFormat(tt.countryCode)
locale := address.NewLocale(tt.locale)
got := format.SelectRegions(locale)
want := format.Regions
if tt.wantLocal {
want = format.LocalRegions
}
if !reflect.DeepEqual(got, want) {
t.Errorf("got %v, want %v", got, want)
}
})
}
}

func TestCheckCountryCode(t *testing.T) {
tests := []struct {
countryCode string
Expand Down
Loading

0 comments on commit ce03019

Please sign in to comment.