| @ -0,0 +1,216 @@ | |||
| // Copyright (C) 2012 The Libphonenumber Authors | |||
| // | |||
| // Licensed under the Apache License, Version 2.0 (the "License"); | |||
| // you may not use this file except in compliance with the License. | |||
| // You may obtain a copy of the License at | |||
| // | |||
| // http://www.apache.org/licenses/LICENSE-2.0 | |||
| // | |||
| // Unless required by applicable law or agreed to in writing, software | |||
| // distributed under the License is distributed on an "AS IS" BASIS, | |||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| // See the License for the specific language governing permissions and | |||
| // limitations under the License. | |||
| // Author: Patrick Mezard | |||
| #include "phonenumbers/geocoding/phonenumber_offline_geocoder.h" | |||
| #include <algorithm> | |||
| #include <map> | |||
| #include <string> | |||
| #include <unicode/unistr.h> // NOLINT(build/include_order) | |||
| #include "phonenumbers/geocoding/area_code_map.h" | |||
| #include "phonenumbers/geocoding/geocoding_data.h" | |||
| #include "phonenumbers/geocoding/mapping_file_provider.h" | |||
| #include "phonenumbers/phonenumberutil.h" | |||
| #include "phonenumbers/stl_util.h" | |||
| namespace i18n { | |||
| namespace phonenumbers { | |||
| using icu::UnicodeString; | |||
| using std::map; | |||
| using std::string; | |||
| namespace { | |||
| // Returns true if s1 comes strictly before s2 in lexicographic order. | |||
| bool IsLowerThan(const char* s1, const char* s2) { | |||
| return strcmp(s1, s2) < 0; | |||
| } | |||
| } // namespace | |||
| PhoneNumberOfflineGeocoder::PhoneNumberOfflineGeocoder() { | |||
| Init(get_country_calling_codes(), get_country_calling_codes_size(), | |||
| get_country_languages, get_prefix_language_code_pairs(), | |||
| get_prefix_language_code_pairs_size(), get_prefix_descriptions); | |||
| } | |||
| PhoneNumberOfflineGeocoder::PhoneNumberOfflineGeocoder( | |||
| const int* country_calling_codes, int country_calling_codes_size, | |||
| country_languages_getter get_country_languages, | |||
| const char** prefix_language_code_pairs, | |||
| int prefix_language_code_pairs_size, | |||
| prefix_descriptions_getter get_prefix_descriptions) { | |||
| Init(country_calling_codes, country_calling_codes_size, | |||
| get_country_languages, prefix_language_code_pairs, | |||
| prefix_language_code_pairs_size, get_prefix_descriptions); | |||
| } | |||
| void PhoneNumberOfflineGeocoder::Init( | |||
| const int* country_calling_codes, int country_calling_codes_size, | |||
| country_languages_getter get_country_languages, | |||
| const char** prefix_language_code_pairs, | |||
| int prefix_language_code_pairs_size, | |||
| prefix_descriptions_getter get_prefix_descriptions) { | |||
| phone_util_ = PhoneNumberUtil::GetInstance(); | |||
| provider_.reset(new MappingFileProvider(country_calling_codes, | |||
| country_calling_codes_size, | |||
| get_country_languages)); | |||
| prefix_language_code_pairs_ = prefix_language_code_pairs; | |||
| prefix_language_code_pairs_size_ = prefix_language_code_pairs_size; | |||
| get_prefix_descriptions_ = get_prefix_descriptions; | |||
| } | |||
| PhoneNumberOfflineGeocoder::~PhoneNumberOfflineGeocoder() { | |||
| STLDeleteContainerPairSecondPointers( | |||
| available_maps_.begin(), available_maps_.end()); | |||
| } | |||
| const AreaCodeMap* PhoneNumberOfflineGeocoder::GetPhonePrefixDescriptions( | |||
| int prefix, const string& language, const string& script, | |||
| const string& region) const { | |||
| string filename; | |||
| provider_->GetFileName(prefix, language, script, region, &filename); | |||
| if (filename.empty()) { | |||
| return NULL; | |||
| } | |||
| AreaCodeMaps::const_iterator it = available_maps_.find(filename); | |||
| if (it == available_maps_.end()) { | |||
| it = LoadAreaCodeMapFromFile(filename); | |||
| if (it == available_maps_.end()) { | |||
| return NULL; | |||
| } | |||
| } | |||
| return it->second; | |||
| } | |||
| PhoneNumberOfflineGeocoder::AreaCodeMaps::const_iterator | |||
| PhoneNumberOfflineGeocoder::LoadAreaCodeMapFromFile( | |||
| const string& filename) const { | |||
| const char** const prefix_language_code_pairs_end = | |||
| prefix_language_code_pairs_ + prefix_language_code_pairs_size_; | |||
| const char** const prefix_language_code_pair = | |||
| std::lower_bound(prefix_language_code_pairs_, | |||
| prefix_language_code_pairs_end, | |||
| filename.c_str(), IsLowerThan); | |||
| if (prefix_language_code_pair != prefix_language_code_pairs_end && | |||
| filename.compare(*prefix_language_code_pair) == 0) { | |||
| AreaCodeMap* const m = new AreaCodeMap(); | |||
| m->ReadAreaCodeMap(get_prefix_descriptions_( | |||
| prefix_language_code_pair - prefix_language_code_pairs_)); | |||
| return available_maps_.insert(AreaCodeMaps::value_type(filename, m)).first; | |||
| } | |||
| return available_maps_.end(); | |||
| } | |||
| string PhoneNumberOfflineGeocoder::GetCountryNameForNumber( | |||
| const PhoneNumber& number, const Locale& language) const { | |||
| string region_code; | |||
| phone_util_->GetRegionCodeForNumber(number, ®ion_code); | |||
| return GetRegionDisplayName(®ion_code, language); | |||
| } | |||
| string PhoneNumberOfflineGeocoder::GetRegionDisplayName( | |||
| const string* region_code, const Locale& language) const { | |||
| if (region_code == NULL || region_code->compare("ZZ") == 0 || | |||
| region_code->compare( | |||
| PhoneNumberUtil::kRegionCodeForNonGeoEntity) == 0) { | |||
| return ""; | |||
| } | |||
| UnicodeString udisplay_country; | |||
| icu::Locale("", region_code->c_str()).getDisplayCountry( | |||
| language, udisplay_country); | |||
| string display_country; | |||
| udisplay_country.toUTF8String(display_country); | |||
| return display_country; | |||
| } | |||
| string PhoneNumberOfflineGeocoder::GetDescriptionForValidNumber( | |||
| const PhoneNumber& number, const Locale& language) const { | |||
| const char* const description = GetAreaDescription( | |||
| number, language.getLanguage(), "", language.getCountry()); | |||
| return *description != '\0' | |||
| ? description | |||
| : GetCountryNameForNumber(number, language); | |||
| } | |||
| string PhoneNumberOfflineGeocoder::GetDescriptionForValidNumber( | |||
| const PhoneNumber& number, const Locale& language, | |||
| const string& user_region) const { | |||
| // If the user region matches the number's region, then we just show the | |||
| // lower-level description, if one exists - if no description exists, we will | |||
| // show the region(country) name for the number. | |||
| string region_code; | |||
| phone_util_->GetRegionCodeForNumber(number, ®ion_code); | |||
| if (user_region.compare(region_code) == 0) { | |||
| return GetDescriptionForValidNumber(number, language); | |||
| } | |||
| // Otherwise, we just show the region(country) name for now. | |||
| return GetRegionDisplayName(®ion_code, language); | |||
| } | |||
| string PhoneNumberOfflineGeocoder::GetDescriptionForNumber( | |||
| const PhoneNumber& number, const Locale& locale) const { | |||
| if (!phone_util_->IsValidNumber(number)) { | |||
| return ""; | |||
| } | |||
| return GetDescriptionForValidNumber(number, locale); | |||
| } | |||
| string PhoneNumberOfflineGeocoder::GetDescriptionForNumber( | |||
| const PhoneNumber& number, const Locale& language, | |||
| const string& user_region) const { | |||
| if (!phone_util_->IsValidNumber(number)) { | |||
| return ""; | |||
| } | |||
| return GetDescriptionForValidNumber(number, language, user_region); | |||
| } | |||
| const char* PhoneNumberOfflineGeocoder::GetAreaDescription( | |||
| const PhoneNumber& number, const string& lang, const string& script, | |||
| const string& region) const { | |||
| const int country_calling_code = number.country_code(); | |||
| // NANPA area is not split in C++ code. | |||
| const int phone_prefix = country_calling_code; | |||
| const AreaCodeMap* const descriptions = GetPhonePrefixDescriptions( | |||
| phone_prefix, lang, script, region); | |||
| const char* description = descriptions ? descriptions->Lookup(number) : NULL; | |||
| // When a location is not available in the requested language, fall back to | |||
| // English. | |||
| if ((!description || *description == '\0') && MayFallBackToEnglish(lang)) { | |||
| const AreaCodeMap* default_descriptions = GetPhonePrefixDescriptions( | |||
| phone_prefix, "en", "", ""); | |||
| if (!default_descriptions) { | |||
| return ""; | |||
| } | |||
| description = default_descriptions->Lookup(number); | |||
| } | |||
| return description ? description : ""; | |||
| } | |||
| // Don't fall back to English if the requested language is among the following: | |||
| // - Chinese | |||
| // - Japanese | |||
| // - Korean | |||
| bool PhoneNumberOfflineGeocoder::MayFallBackToEnglish( | |||
| const string& lang) const { | |||
| return lang.compare("zh") && lang.compare("ja") && lang.compare("ko"); | |||
| } | |||
| } // namespace phonenumbers | |||
| } // namespace i18n | |||
| @ -0,0 +1,164 @@ | |||
| // Copyright (C) 2012 The Libphonenumber Authors | |||
| // | |||
| // Licensed under the Apache License, Version 2.0 (the "License"); | |||
| // you may not use this file except in compliance with the License. | |||
| // You may obtain a copy of the License at | |||
| // | |||
| // http://www.apache.org/licenses/LICENSE-2.0 | |||
| // | |||
| // Unless required by applicable law or agreed to in writing, software | |||
| // distributed under the License is distributed on an "AS IS" BASIS, | |||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| // See the License for the specific language governing permissions and | |||
| // limitations under the License. | |||
| // | |||
| // Author: Patrick Mezard | |||
| #ifndef I18N_PHONENUMBERS_GEOCODING_PHONENUMBER_OFFLINE_GEOCODER_H_ | |||
| #define I18N_PHONENUMBERS_GEOCODING_PHONENUMBER_OFFLINE_GEOCODER_H_ | |||
| #include <map> | |||
| #include <string> | |||
| #include <unicode/locid.h> // NOLINT(build/include_order) | |||
| #include "base/basictypes.h" | |||
| #include "base/memory/scoped_ptr.h" | |||
| namespace i18n { | |||
| namespace phonenumbers { | |||
| using std::map; | |||
| using std::string; | |||
| class AreaCodeMap; | |||
| class MappingFileProvider; | |||
| class PhoneNumber; | |||
| class PhoneNumberUtil; | |||
| struct CountryLanguages; | |||
| struct PrefixDescriptions; | |||
| typedef icu::Locale Locale; | |||
| // An offline geocoder which provides geographical information related to a | |||
| // phone number. | |||
| class PhoneNumberOfflineGeocoder { | |||
| private: | |||
| typedef map<string, const AreaCodeMap*> AreaCodeMaps; | |||
| public: | |||
| typedef const CountryLanguages* (*country_languages_getter)(int index); | |||
| typedef const PrefixDescriptions* (*prefix_descriptions_getter)(int index); | |||
| PhoneNumberOfflineGeocoder(); | |||
| // For tests | |||
| PhoneNumberOfflineGeocoder( | |||
| const int* country_calling_codes, | |||
| int country_calling_codes_size, | |||
| country_languages_getter get_country_languages, | |||
| const char** prefix_language_code_pairs, | |||
| int prefix_language_code_pairs_size, | |||
| prefix_descriptions_getter get_prefix_descriptions); | |||
| virtual ~PhoneNumberOfflineGeocoder(); | |||
| // Returns a text description for the given phone number, in the language | |||
| // provided. The description might consist of the name of the country where | |||
| // the phone number is from, or the name of the geographical area the phone | |||
| // number is from if more detailed information is available. | |||
| // | |||
| // This method assumes the validity of the number passed in has already been | |||
| // checked. | |||
| string GetDescriptionForValidNumber(const PhoneNumber& number, | |||
| const Locale& language) const; | |||
| // As per GetDescriptionForValidNumber(PhoneNumber, Locale) but also considers | |||
| // the region of the user. If the phone number is from the same region as the | |||
| // user, only a lower-level description will be returned, if one exists. | |||
| // Otherwise, the phone number's region will be returned, with optionally some | |||
| // more detailed information. | |||
| // | |||
| // For example, for a user from the region "US" (United States), we would show | |||
| // "Mountain View, CA" for a particular number, omitting the United States | |||
| // from the description. For a user from the United Kingdom (region "GB"), for | |||
| // the same number we may show "Mountain View, CA, United States" or even just | |||
| // "United States". | |||
| // | |||
| // This method assumes the validity of the number passed in has already been | |||
| // checked. | |||
| // | |||
| // user_region is the region code for a given user. This region will be | |||
| // omitted from the description if the phone number comes from this region. It | |||
| // is a two-letter uppercase ISO country code as defined by ISO 3166-1. | |||
| string GetDescriptionForValidNumber(const PhoneNumber& number, | |||
| const Locale& language, const string& user_region) const; | |||
| // As per GetDescriptionForValidNumber(PhoneNumber, Locale) but explicitly | |||
| // checks the validity of the number passed in. | |||
| string GetDescriptionForNumber(const PhoneNumber& number, | |||
| const Locale& locale) const; | |||
| // As per GetDescriptionForValidNumber(PhoneNumber, Locale, String) but | |||
| string GetDescriptionForNumber(const PhoneNumber& number, | |||
| const Locale& language, const string& user_region) const; | |||
| private: | |||
| void Init(const int* country_calling_codes, | |||
| int country_calling_codes_size, | |||
| country_languages_getter get_country_languages, | |||
| const char** prefix_language_code_pairs, | |||
| int prefix_language_code_pairs_size, | |||
| prefix_descriptions_getter get_prefix_descriptions); | |||
| const AreaCodeMap* GetPhonePrefixDescriptions(int prefix, | |||
| const string& language, const string& script, const string& region) const; | |||
| AreaCodeMaps::const_iterator LoadAreaCodeMapFromFile( | |||
| const string& filename) const; | |||
| // Returns the customary display name in the given language for the given | |||
| // region. | |||
| string GetRegionDisplayName(const string* region_code, | |||
| const Locale& language) const; | |||
| // Returns the customary display name in the given language for the given | |||
| // territory the phone number is from. | |||
| string GetCountryNameForNumber(const PhoneNumber& number, | |||
| const Locale& language) const; | |||
| // Returns an area-level text description in the given language for the given | |||
| // phone number, or an empty string. | |||
| // lang is a two-letter lowercase ISO language codes as defined by ISO 639-1. | |||
| // script is a four-letter titlecase (the first letter is uppercase and the | |||
| // rest of the letters are lowercase) ISO script codes as defined in ISO | |||
| // 15924. | |||
| // region is a two-letter uppercase ISO country codes as defined by ISO | |||
| // 3166-1. | |||
| const char* GetAreaDescription(const PhoneNumber& number, const string& lang, | |||
| const string& script, | |||
| const string& region) const; | |||
| bool MayFallBackToEnglish(const string& lang) const; | |||
| private: | |||
| const PhoneNumberUtil* phone_util_; | |||
| // The MappingFileProvider knows for which combination of country calling code | |||
| // and language a phone prefix mapping file is available in the file system, | |||
| // so that a file can be loaded when needed. | |||
| scoped_ptr<const MappingFileProvider> provider_; | |||
| const char** prefix_language_code_pairs_; | |||
| int prefix_language_code_pairs_size_; | |||
| prefix_descriptions_getter get_prefix_descriptions_; | |||
| // A mapping from country calling codes languages pairs to the corresponding | |||
| // phone prefix map that has been loaded. | |||
| mutable AreaCodeMaps available_maps_; | |||
| DISALLOW_COPY_AND_ASSIGN(PhoneNumberOfflineGeocoder); | |||
| }; | |||
| } // namespace phonenumbers | |||
| } // namespace i18n | |||
| #endif /* I18N_PHONENUMBERS_GEOCODING_PHONENUMBER_OFFLINE_GEOCODER_H_ */ | |||
| @ -0,0 +1,204 @@ | |||
| // Copyright (C) 2012 The Libphonenumber Authors | |||
| // | |||
| // Licensed under the Apache License, Version 2.0 (the "License"); | |||
| // you may not use this file except in compliance with the License. | |||
| // You may obtain a copy of the License at | |||
| // | |||
| // http://www.apache.org/licenses/LICENSE-2.0 | |||
| // | |||
| // Unless required by applicable law or agreed to in writing, software | |||
| // distributed under the License is distributed on an "AS IS" BASIS, | |||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| // See the License for the specific language governing permissions and | |||
| // limitations under the License. | |||
| // | |||
| // Author: Patrick Mezard | |||
| #include "phonenumbers/geocoding/phonenumber_offline_geocoder.h" | |||
| #include <gtest/gtest.h> | |||
| #include <unicode/locid.h> | |||
| #include "phonenumbers/geocoding/geocoding_test_data.h" | |||
| #include "phonenumbers/phonenumber.h" | |||
| #include "phonenumbers/phonenumber.pb.h" | |||
| namespace i18n { | |||
| namespace phonenumbers { | |||
| using icu::Locale; | |||
| namespace { | |||
| PhoneNumber MakeNumber(int32 country_code, uint64 national_number) { | |||
| PhoneNumber n; | |||
| n.set_country_code(country_code); | |||
| n.set_national_number(national_number); | |||
| return n; | |||
| } | |||
| const Locale kEnglishLocale = Locale("en", "GB"); | |||
| const Locale kFrenchLocale = Locale("fr", "FR"); | |||
| const Locale kGermanLocale = Locale("de", "DE"); | |||
| const Locale kItalianLocale = Locale("it", "IT"); | |||
| const Locale kKoreanLocale = Locale("ko", "KR"); | |||
| const Locale kSimplifiedChineseLocale = Locale("zh", "CN"); | |||
| } // namespace | |||
| class PhoneNumberOfflineGeocoderTest : public testing::Test { | |||
| protected: | |||
| PhoneNumberOfflineGeocoderTest() : | |||
| KO_NUMBER1(MakeNumber(82, 22123456L)), | |||
| KO_NUMBER2(MakeNumber(82, 322123456L)), | |||
| KO_NUMBER3(MakeNumber(82, 6421234567L)), | |||
| KO_INVALID_NUMBER(MakeNumber(82, 1234L)), | |||
| US_NUMBER1(MakeNumber(1, 6502530000L)), | |||
| US_NUMBER2(MakeNumber(1, 6509600000L)), | |||
| US_NUMBER3(MakeNumber(1, 2128120000L)), | |||
| US_NUMBER4(MakeNumber(1, 6174240000L)), | |||
| US_INVALID_NUMBER(MakeNumber(1, 123456789L)), | |||
| BS_NUMBER1(MakeNumber(1, 2423651234L)), | |||
| AU_NUMBER(MakeNumber(61, 236618300L)), | |||
| NUMBER_WITH_INVALID_COUNTRY_CODE(MakeNumber(999, 2423651234L)), | |||
| INTERNATIONAL_TOLL_FREE(MakeNumber(800, 12345678L)) { | |||
| } | |||
| virtual void SetUp() { | |||
| geocoder_.reset( | |||
| new PhoneNumberOfflineGeocoder( | |||
| get_test_country_calling_codes(), | |||
| get_test_country_calling_codes_size(), | |||
| get_test_country_languages, | |||
| get_test_prefix_language_code_pairs(), | |||
| get_test_prefix_language_code_pairs_size(), | |||
| get_test_prefix_descriptions)); | |||
| } | |||
| protected: | |||
| scoped_ptr<PhoneNumberOfflineGeocoder> geocoder_; | |||
| const PhoneNumber KO_NUMBER1; | |||
| const PhoneNumber KO_NUMBER2; | |||
| const PhoneNumber KO_NUMBER3; | |||
| const PhoneNumber KO_INVALID_NUMBER; | |||
| const PhoneNumber US_NUMBER1; | |||
| const PhoneNumber US_NUMBER2; | |||
| const PhoneNumber US_NUMBER3; | |||
| const PhoneNumber US_NUMBER4; | |||
| const PhoneNumber US_INVALID_NUMBER; | |||
| const PhoneNumber BS_NUMBER1; | |||
| const PhoneNumber AU_NUMBER; | |||
| const PhoneNumber NUMBER_WITH_INVALID_COUNTRY_CODE; | |||
| const PhoneNumber INTERNATIONAL_TOLL_FREE; | |||
| }; | |||
| TEST_F(PhoneNumberOfflineGeocoderTest, | |||
| TestGetDescriptionForNumberWithNoDataFile) { | |||
| // No data file containing mappings for US numbers is available in Chinese for | |||
| // the unittests. As a result, the country name of United States in simplified | |||
| // Chinese is returned. | |||
| // "\u7F8E\u56FD" (unicode escape sequences are not always supported) | |||
| EXPECT_EQ("\xe7""\xbe""\x8e""\xe5""\x9b""\xbd", | |||
| geocoder_->GetDescriptionForNumber(US_NUMBER1, | |||
| kSimplifiedChineseLocale)); | |||
| EXPECT_EQ("Bahamas", | |||
| geocoder_->GetDescriptionForNumber(BS_NUMBER1, Locale("en", "US"))); | |||
| EXPECT_EQ("Australia", | |||
| geocoder_->GetDescriptionForNumber(AU_NUMBER, Locale("en", "US"))); | |||
| EXPECT_EQ("", | |||
| geocoder_->GetDescriptionForNumber(NUMBER_WITH_INVALID_COUNTRY_CODE, | |||
| Locale("en", "US"))); | |||
| EXPECT_EQ("", | |||
| geocoder_->GetDescriptionForNumber(INTERNATIONAL_TOLL_FREE, | |||
| Locale("en", "US"))); | |||
| } | |||
| TEST_F(PhoneNumberOfflineGeocoderTest, | |||
| TestGetDescriptionForNumberWithMissingPrefix) { | |||
| // Test that the name of the country is returned when the number passed in is | |||
| // valid but not covered by the geocoding data file. | |||
| EXPECT_EQ("United States", | |||
| geocoder_->GetDescriptionForNumber(US_NUMBER4, Locale("en", "US"))); | |||
| } | |||
| TEST_F(PhoneNumberOfflineGeocoderTest, TestGetDescriptionForNumber_en_US) { | |||
| EXPECT_EQ("CA", | |||
| geocoder_->GetDescriptionForNumber(US_NUMBER1, Locale("en", "US"))); | |||
| EXPECT_EQ("Mountain View, CA", | |||
| geocoder_->GetDescriptionForNumber(US_NUMBER2, Locale("en", "US"))); | |||
| EXPECT_EQ("New York, NY", | |||
| geocoder_->GetDescriptionForNumber(US_NUMBER3, Locale("en", "US"))); | |||
| } | |||
| TEST_F(PhoneNumberOfflineGeocoderTest, TestGetDescriptionForKoreanNumber) { | |||
| EXPECT_EQ("Seoul", | |||
| geocoder_->GetDescriptionForNumber(KO_NUMBER1, kEnglishLocale)); | |||
| EXPECT_EQ("Incheon", | |||
| geocoder_->GetDescriptionForNumber(KO_NUMBER2, kEnglishLocale)); | |||
| EXPECT_EQ("Jeju", | |||
| geocoder_->GetDescriptionForNumber(KO_NUMBER3, kEnglishLocale)); | |||
| // "\uC11C\uC6B8" | |||
| EXPECT_EQ("\xec""\x84""\x9c""\xec""\x9a""\xb8", | |||
| geocoder_->GetDescriptionForNumber(KO_NUMBER1, kKoreanLocale)); | |||
| // "\uC778\uCC9C" | |||
| EXPECT_EQ("\xec""\x9d""\xb8""\xec""\xb2""\x9c", | |||
| geocoder_->GetDescriptionForNumber(KO_NUMBER2, kKoreanLocale)); | |||
| } | |||
| TEST_F(PhoneNumberOfflineGeocoderTest, TestGetDescriptionForFallBack) { | |||
| // No fallback, as the location name for the given phone number is available | |||
| // in the requested language. | |||
| EXPECT_EQ("Kalifornien", | |||
| geocoder_->GetDescriptionForNumber(US_NUMBER1, kGermanLocale)); | |||
| // German falls back to English. | |||
| EXPECT_EQ("New York, NY", | |||
| geocoder_->GetDescriptionForNumber(US_NUMBER3, kGermanLocale)); | |||
| // Italian falls back to English. | |||
| EXPECT_EQ("CA", | |||
| geocoder_->GetDescriptionForNumber(US_NUMBER1, kItalianLocale)); | |||
| // Korean doesn't fall back to English. | |||
| // "\uB300\uD55C\uBBFC\uAD6D" | |||
| EXPECT_EQ("\xeb""\x8c""\x80""\xed""\x95""\x9c""\xeb""\xaf""\xbc""\xea""\xb5" | |||
| "\xad", | |||
| geocoder_->GetDescriptionForNumber(KO_NUMBER3, kKoreanLocale)); | |||
| } | |||
| TEST_F(PhoneNumberOfflineGeocoderTest, | |||
| TestGetDescriptionForNumberWithUserRegion) { | |||
| // User in Italy, American number. We should just show United States, in | |||
| // Spanish, and not more detailed information. | |||
| EXPECT_EQ("Estados Unidos", | |||
| geocoder_->GetDescriptionForNumber(US_NUMBER1, Locale("es", "ES"), | |||
| "IT")); | |||
| // Unknown region - should just show country name. | |||
| EXPECT_EQ("Estados Unidos", | |||
| geocoder_->GetDescriptionForNumber(US_NUMBER1, Locale("es", "ES"), | |||
| "ZZ")); | |||
| // User in the States, language German, should show detailed data. | |||
| EXPECT_EQ("Kalifornien", | |||
| geocoder_->GetDescriptionForNumber(US_NUMBER1, kGermanLocale, | |||
| "US")); | |||
| // User in the States, language French, no data for French, so we fallback to | |||
| // English detailed data. | |||
| EXPECT_EQ("CA", | |||
| geocoder_->GetDescriptionForNumber(US_NUMBER1, kFrenchLocale, | |||
| "US")); | |||
| // Invalid number - return an empty string. | |||
| EXPECT_EQ("", | |||
| geocoder_->GetDescriptionForNumber(US_INVALID_NUMBER, | |||
| kEnglishLocale, "US")); | |||
| } | |||
| TEST_F(PhoneNumberOfflineGeocoderTest, TestGetDescriptionForInvalidNumber) { | |||
| EXPECT_EQ("", geocoder_->GetDescriptionForNumber(KO_INVALID_NUMBER, | |||
| kEnglishLocale)); | |||
| EXPECT_EQ("", geocoder_->GetDescriptionForNumber(US_INVALID_NUMBER, | |||
| kEnglishLocale)); | |||
| } | |||
| } // namespace phonenumbers | |||
| } // namespace i18n | |||