diff options
author | georgey@chromium.org <georgey@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-10 18:24:56 +0000 |
---|---|---|
committer | georgey@chromium.org <georgey@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-10 18:24:56 +0000 |
commit | 5b37cb72a5bfbcc1daa57249319a8235d0d4874a (patch) | |
tree | e2d51912bbcadb97537d09c41bf223d53536050c | |
parent | 65c03a0d3f341785989199b5fc2263e8cd41b3cc (diff) | |
download | chromium_src-5b37cb72a5bfbcc1daa57249319a8235d0d4874a.zip chromium_src-5b37cb72a5bfbcc1daa57249319a8235d0d4874a.tar.gz chromium_src-5b37cb72a5bfbcc1daa57249319a8235d0d4874a.tar.bz2 |
Autofill phone number enhancements and integration of Phone Number Util Library: part 2
Internal utility library with unit-test
BUG=71443
TEST=Unit-tested
Review URL: http://codereview.chromium.org/6929059
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@84822 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/autofill/phone_number_i18n.cc | 242 | ||||
-rw-r--r-- | chrome/browser/autofill/phone_number_i18n.h | 71 | ||||
-rw-r--r-- | chrome/browser/autofill/phone_number_i18n_unittest.cc | 341 |
3 files changed, 634 insertions, 20 deletions
diff --git a/chrome/browser/autofill/phone_number_i18n.cc b/chrome/browser/autofill/phone_number_i18n.cc index 8966d00..7c8a3c6 100644 --- a/chrome/browser/autofill/phone_number_i18n.cc +++ b/chrome/browser/autofill/phone_number_i18n.cc @@ -4,34 +4,238 @@ #include "chrome/browser/autofill/phone_number_i18n.h" -#include "base/logging.h" +#include "base/basictypes.h" +#include "base/string_number_conversions.h" +#include "base/string_util.h" #include "base/utf_string_conversions.h" #include "third_party/libphonenumber/cpp/src/phonenumberutil.h" -using i18n::phonenumbers::PhoneNumber; -using i18n::phonenumbers::PhoneNumberUtil; +namespace { + +std::string SanitizeLocaleCode(const std::string& locale_code) { + if (locale_code.length() == 2) + return locale_code; + // Use USA for incomplete locales. + return std::string("US"); +} + +i18n::phonenumbers::PhoneNumberUtil::PhoneNumberFormat UtilsTypeToPhoneLibType( + autofill_i18n::FullPhoneFormat phone_format) { + switch (phone_format) { + case autofill_i18n::E164: + return i18n::phonenumbers::PhoneNumberUtil::E164; + case autofill_i18n::INTERNATIONAL: + return i18n::phonenumbers::PhoneNumberUtil::INTERNATIONAL; + case autofill_i18n::NATIONAL: + return i18n::phonenumbers::PhoneNumberUtil::NATIONAL; + case autofill_i18n::RFC3966: + return i18n::phonenumbers::PhoneNumberUtil::RFC3966; + default: + NOTREACHED(); + } + return i18n::phonenumbers::PhoneNumberUtil::NATIONAL; +} + +} // namespace namespace autofill_i18n { +string16 NormalizePhoneNumber(const string16& value) { + std::string number(UTF16ToUTF8(value)); + i18n::phonenumbers::PhoneNumberUtil::NormalizeDigitsOnly(&number); + return UTF8ToUTF16(number); +} + +bool ParsePhoneNumber(const string16& value, + const std::string& locale, + string16* country_code, + string16* city_code, + string16* number) { + DCHECK(number); + DCHECK(city_code); + DCHECK(country_code); + + number->clear(); + city_code->clear(); + country_code->clear(); + + std::string number_text(UTF16ToUTF8(value)); + + // Parse phone number based on the locale. + i18n::phonenumbers::PhoneNumber i18n_number; + i18n::phonenumbers::PhoneNumberUtil* phone_util = + i18n::phonenumbers::PhoneNumberUtil::GetInstance(); + DCHECK(phone_util); + + if (phone_util->Parse(number_text, SanitizeLocaleCode(locale).c_str(), + &i18n_number) != + i18n::phonenumbers::PhoneNumberUtil::NO_PARSING_ERROR) { + return false; + } + + i18n::phonenumbers::PhoneNumberUtil::ValidationResult validation = + phone_util->IsPossibleNumberWithReason(i18n_number); + if (validation != i18n::phonenumbers::PhoneNumberUtil::IS_POSSIBLE) + return false; + + // This verifies that number has a valid area code (that in some cases could + // be empty) for parsed country code. Also verifies that this is a valid + // number (in US 1234567 is not valid, because numbers do not start with 1). + if (!phone_util->IsValidNumber(i18n_number)) + return false; + + std::string national_significant_number; + phone_util->GetNationalSignificantNumber(i18n_number, + &national_significant_number); + + std::string area_code; + std::string subscriber_number; + + int area_length = phone_util->GetLengthOfGeographicalAreaCode(i18n_number); + if (area_length > 0) { + area_code = national_significant_number.substr(0, area_length); + subscriber_number = national_significant_number.substr(area_length); + } else { + subscriber_number = national_significant_number; + } + *number = UTF8ToUTF16(subscriber_number); + *city_code = UTF8ToUTF16(area_code); + *country_code = string16(); + + i18n::phonenumbers::PhoneNumberUtil::NormalizeDigitsOnly(&number_text); + string16 normalized_number(UTF8ToUTF16(number_text)); + // Check if parsed number has country code and it was not inferred from the + // locale. + if (i18n_number.has_country_code()) { + *country_code = UTF8ToUTF16(base::StringPrintf("%d", + i18n_number.country_code())); + if (normalized_number.length() <= national_significant_number.length() && + (normalized_number.length() < country_code->length() || + normalized_number.compare(0, country_code->length(), *country_code))) { + country_code->clear(); + } + } + + return true; +} + +bool ConstructPhoneNumber(const string16& country_code, + const string16& city_code, + const string16& number, + const std::string& locale, + FullPhoneFormat phone_format, + string16* whole_number) { + DCHECK(whole_number); + + whole_number->clear(); + + std::string normalized_number(UTF16ToUTF8(city_code)); + normalized_number.append(UTF16ToUTF8(number)); + + i18n::phonenumbers::PhoneNumberUtil::NormalizeDigitsOnly(&normalized_number); + + int64 number_int = 0; + if (!base::StringToInt64(normalized_number, &number_int) || !number_int) + return false; + + i18n::phonenumbers::PhoneNumber i18n_number; + i18n_number.set_national_number(static_cast<uint64>(number_int)); + + i18n::phonenumbers::PhoneNumberUtil* phone_util = + i18n::phonenumbers::PhoneNumberUtil::GetInstance(); + DCHECK(phone_util); + + int country_int = phone_util->GetCountryCodeForRegion( + std::string(SanitizeLocaleCode(locale).c_str())); + if (!country_code.empty()) { + string16 country_code_stripped(country_code); + country_code_stripped = NormalizePhoneNumber(country_code_stripped); + if (!base::StringToInt(country_code_stripped, &country_int)) + return false; + } + if (country_int) + i18n_number.set_country_code(country_int); + + i18n::phonenumbers::PhoneNumberUtil::ValidationResult validation = + phone_util->IsPossibleNumberWithReason(i18n_number); + if (validation != i18n::phonenumbers::PhoneNumberUtil::IS_POSSIBLE) + return false; + + std::string formatted_number; + + phone_util->Format(i18n_number, UtilsTypeToPhoneLibType(phone_format), + &formatted_number); + *whole_number = UTF8ToUTF16(formatted_number); + return true; +} + +string16 FormatPhone(const string16& phone, const std::string& locale, + FullPhoneFormat phone_format) { + std::string number_text(UTF16ToUTF8(phone)); + + i18n::phonenumbers::PhoneNumberUtil::NormalizeDigitsOnly(&number_text); + + // Parse phone number based on the locale + i18n::phonenumbers::PhoneNumber i18n_number; + i18n::phonenumbers::PhoneNumberUtil* phone_util = + i18n::phonenumbers::PhoneNumberUtil::GetInstance(); + DCHECK(phone_util); + + if (phone_util->Parse(number_text, SanitizeLocaleCode(locale).c_str(), + &i18n_number) != + i18n::phonenumbers::PhoneNumberUtil::NO_PARSING_ERROR) { + return string16(); + } + std::string formatted_number; + phone_util->Format(i18n_number, UtilsTypeToPhoneLibType(phone_format), + &formatted_number); + return UTF8ToUTF16(formatted_number); +} + +PhoneMatch ComparePhones(const string16& phone1, const string16& phone2, + const std::string& locale) { + std::string number_text(UTF16ToUTF8(phone1)); + + // Parse phone number based on the locale + i18n::phonenumbers::PhoneNumber i18n_number1; + i18n::phonenumbers::PhoneNumberUtil* phone_util = + i18n::phonenumbers::PhoneNumberUtil::GetInstance(); + DCHECK(phone_util); + + if (phone_util->Parse(number_text, SanitizeLocaleCode(locale).c_str(), + &i18n_number1) != + i18n::phonenumbers::PhoneNumberUtil::NO_PARSING_ERROR) { + return PHONES_NOT_EQUAL; + } + number_text = UTF16ToUTF8(phone2); + + // Parse phone number based on the locale + i18n::phonenumbers::PhoneNumber i18n_number2; + if (phone_util->Parse(number_text, SanitizeLocaleCode(locale).c_str(), + &i18n_number2) != + i18n::phonenumbers::PhoneNumberUtil::NO_PARSING_ERROR) { + return PHONES_NOT_EQUAL; + } + switch (phone_util->IsNumberMatch(i18n_number1, i18n_number2)) { + case i18n::phonenumbers::PhoneNumberUtil::INVALID_NUMBER: + case i18n::phonenumbers::PhoneNumberUtil::NO_MATCH: + return PHONES_NOT_EQUAL; + case i18n::phonenumbers::PhoneNumberUtil::SHORT_NSN_MATCH: + return PHONES_SUBMATCH; + case i18n::phonenumbers::PhoneNumberUtil::NSN_MATCH: + case i18n::phonenumbers::PhoneNumberUtil::EXACT_MATCH: + return PHONES_EQUAL; + default: + NOTREACHED(); + } + return PHONES_NOT_EQUAL; +} + bool PhoneNumbersMatch(const string16& number_a, const string16& number_b, const std::string& country_code) { - DCHECK(country_code.size() == 0 || country_code.size() == 2); - std::string safe_country_code(country_code); - if (safe_country_code.size() == 0) - safe_country_code = "US"; - - PhoneNumberUtil *phone_util = PhoneNumberUtil::GetInstance(); - PhoneNumber phone_number_a; - phone_util->Parse(UTF16ToUTF8(number_a), safe_country_code, &phone_number_a); - PhoneNumber phone_number_b; - phone_util->Parse(UTF16ToUTF8(number_b), safe_country_code, &phone_number_b); - - PhoneNumberUtil::MatchType match = phone_util->IsNumberMatch(phone_number_a, - phone_number_b); - // Allow |NSN_MATCH| for implied country code if one is not set. - return match == PhoneNumberUtil::NSN_MATCH || - match == PhoneNumberUtil::EXACT_MATCH; + return ComparePhones(number_a, number_b, country_code) == PHONES_EQUAL; } } // namespace autofill_i18n + diff --git a/chrome/browser/autofill/phone_number_i18n.h b/chrome/browser/autofill/phone_number_i18n.h index 28b4c42..75541ad 100644 --- a/chrome/browser/autofill/phone_number_i18n.h +++ b/chrome/browser/autofill/phone_number_i18n.h @@ -7,11 +7,82 @@ #pragma once #include <string> +#include <vector> +#include "base/compiler_specific.h" #include "base/string16.h" +// Utilities to process, normalize and compare international phone numbers. + namespace autofill_i18n { +// Most of the following functions require |locale| to operate. The |locale| is +// a ISO 3166 standard code ("US" for USA, "CZ" for Czech Republic, etc.). + +// Normalizes phone number, by changing digits in the extended fonts +// (such as \xFF1x) into '0'-'9'. Also strips out non-digit characters. +string16 NormalizePhoneNumber(const string16& value); + +// Parses |value| to extract the components of a phone number. |number| +// returns the local number, |city_code| returns the city code, and +// |country_code| returns country code. For some regions the |city_code| is +// empty. +// The parsing is based on current locale - |locale|. +// Separator characters are stripped before parsing the digits. +// Returns true if parsing was successful, false otherwise. +bool ParsePhoneNumber(const string16& value, + const std::string& locale, + string16* country_code, + string16* city_code, + string16* number) WARN_UNUSED_RESULT; + +enum FullPhoneFormat { + E164, // Example: +16502345678 + INTERNATIONAL, // Example: +1 650-234-5678 + NATIONAL, // Example: (650) 234-5678 + RFC3966 // Example: +1-650-234-5678 +}; + +// Constructs whole phone number from parts. +// |city_code| - area code, could be empty. +// |country_code| - country code, could be empty +// |number| - local number, should not be empty. +// |locale| - current locale, the parsing is based on. +// |phone_format| - whole number constructed in that format, +// |whole_number| - constructed whole number. +// Separator characters are stripped before parsing the digits. +// Returns true if parsing was successful, false otherwise. +bool ConstructPhoneNumber(const string16& country_code, + const string16& city_code, + const string16& number, + const std::string& locale, + FullPhoneFormat phone_format, + string16* whole_number) WARN_UNUSED_RESULT; + +// Parses and then formats phone number either nationally or internationally. +// |phone| - raw, unsanitized phone number, as entered by user. +// |locale| - country locale code, such as "US". +// |phone_format| - the phone type format. +// The same as calling ParsePhoneNumber(phone, locale, &country, &city, +// &number); ConstructPhoneNumber(country, city, number, locale, phone_format, +// &formatted_phone); but almost twice as fast, as parsing done only once. +// Returns formatted phone on success, empty string on error. +string16 FormatPhone(const string16& phone, + const std::string& locale, + FullPhoneFormat phone_format); + +enum PhoneMatch { + PHONES_NOT_EQUAL, + PHONES_EQUAL, // +1(650)2345678 is equal to 1-650-234-56-78. + PHONES_SUBMATCH, // 650-234-56-78 or 2345678 is a submatch for + // +1(650)2345678. The submatch is symmetric. +}; + +// Compares two phones, normalizing them before comparision. +PhoneMatch ComparePhones(const string16& phone1, + const string16& phone2, + const std::string& locale); + bool PhoneNumbersMatch(const string16& number_a, const string16& number_b, const std::string& country_code); diff --git a/chrome/browser/autofill/phone_number_i18n_unittest.cc b/chrome/browser/autofill/phone_number_i18n_unittest.cc index d74d124..4134a82 100644 --- a/chrome/browser/autofill/phone_number_i18n_unittest.cc +++ b/chrome/browser/autofill/phone_number_i18n_unittest.cc @@ -6,7 +6,346 @@ #include "chrome/browser/autofill/phone_number_i18n.h" #include "testing/gtest/include/gtest/gtest.h" -using namespace autofill_i18n; +using autofill_i18n::NormalizePhoneNumber; +using autofill_i18n::ParsePhoneNumber; +using autofill_i18n::ConstructPhoneNumber; +using autofill_i18n::FormatPhone; +using autofill_i18n::ComparePhones; +using autofill_i18n::PhoneNumbersMatch; + +TEST(PhoneNumberI18NTest, NormalizePhoneNumber) { + // The string is split to avoid problem with MSVC compiler when it thinks + // 123 is a part of character code. + string16 phone1(UTF8ToUTF16("\x92\x32" "123\xe2\x8a\x90")); + EXPECT_EQ(NormalizePhoneNumber(phone1), ASCIIToUTF16("2123")); + + string16 phone2(UTF8ToUTF16( + "\xef\xbc\x92\x32\x92\x37\xd9\xa9\xce\xb2\xe2\x8a\x90")); + EXPECT_EQ(NormalizePhoneNumber(phone2), ASCIIToUTF16("2279")); + + string16 phone3(UTF8ToUTF16("\xef\xbc\x92\x35\xd9\xa5")); + EXPECT_EQ(NormalizePhoneNumber(phone3), ASCIIToUTF16("255")); + + string16 phone4(UTF8ToUTF16("+1(650)2346789")); + EXPECT_EQ(NormalizePhoneNumber(phone4), ASCIIToUTF16("16502346789")); + + string16 phone5(UTF8ToUTF16("6502346789")); + EXPECT_EQ(NormalizePhoneNumber(phone5), ASCIIToUTF16("6502346789")); +} + +TEST(PhoneNumberI18NTest, ParsePhoneNumber) { + string16 number; + string16 city_code; + string16 country_code; + + // Test for empty string. Should give back empty strings. + string16 phone0; + EXPECT_FALSE(ParsePhoneNumber(phone0, "US", + &country_code, + &city_code, + &number)); + EXPECT_EQ(string16(), number); + EXPECT_EQ(string16(), city_code); + EXPECT_EQ(string16(), country_code); + + // Test for string with less than 7 digits. Should give back empty strings. + string16 phone1(ASCIIToUTF16("1234")); + EXPECT_FALSE(ParsePhoneNumber(phone1, "US", + &country_code, + &city_code, + &number)); + EXPECT_EQ(string16(), number); + EXPECT_EQ(string16(), city_code); + EXPECT_EQ(string16(), country_code); + + // Test for string with exactly 7 digits. + // Not a valid number - starts with 1 + string16 phone2(ASCIIToUTF16("1234567")); + EXPECT_FALSE(ParsePhoneNumber(phone2, "US", + &country_code, + &city_code, + &number)); + EXPECT_EQ(string16(), number); + EXPECT_EQ(string16(), city_code); + EXPECT_EQ(string16(), country_code); + + // Not a valid number - does not have area code. + string16 phone3(ASCIIToUTF16("2234567")); + EXPECT_FALSE(ParsePhoneNumber(phone3, "US", + &country_code, + &city_code, + &number)); + EXPECT_EQ(string16(), number); + EXPECT_EQ(string16(), city_code); + EXPECT_EQ(string16(), country_code); + + // Test for string with greater than 7 digits but less than 10 digits. + // Should fail parsing in US. + string16 phone4(ASCIIToUTF16("123456789")); + EXPECT_FALSE(ParsePhoneNumber(phone4, "US", + &country_code, + &city_code, + &number)); + EXPECT_EQ(string16(), number); + EXPECT_EQ(string16(), city_code); + EXPECT_EQ(string16(), country_code); + + // Test for string with greater than 7 digits but less than 10 digits and + // separators. + // Should fail parsing in US. + string16 phone_separator4(ASCIIToUTF16("12.345-6789")); + EXPECT_FALSE(ParsePhoneNumber(phone_separator4, "US", + &country_code, + &city_code, + &number)); + EXPECT_EQ(string16(), number); + EXPECT_EQ(string16(), city_code); + EXPECT_EQ(string16(), country_code); + + // Test for string with exactly 10 digits. + // Should give back phone number and city code. + // This one going to fail because of the incorrect area code. + string16 phone5(ASCIIToUTF16("1234567890")); + EXPECT_FALSE(ParsePhoneNumber(phone5, "US", + &country_code, + &city_code, + &number)); + EXPECT_EQ(string16(), number); + EXPECT_EQ(string16(), city_code); + EXPECT_EQ(string16(), country_code); + + string16 phone6(ASCIIToUTF16("6501567890")); + // This one going to fail because of the incorrect number (starts with 1). + EXPECT_FALSE(ParsePhoneNumber(phone6, "US", + &country_code, + &city_code, + &number)); + EXPECT_EQ(string16(), number); + EXPECT_EQ(string16(), city_code); + EXPECT_EQ(string16(), country_code); + + string16 phone7(ASCIIToUTF16("6504567890")); + EXPECT_TRUE(ParsePhoneNumber(phone7, "US", + &country_code, + &city_code, + &number)); + EXPECT_EQ(ASCIIToUTF16("4567890"), number); + EXPECT_EQ(ASCIIToUTF16("650"), city_code); + EXPECT_EQ(string16(), country_code); + + // Test for string with exactly 10 digits and separators. + // Should give back phone number and city code. + string16 phone_separator7(ASCIIToUTF16("(650) 456-7890")); + EXPECT_TRUE(ParsePhoneNumber(phone_separator7, "US", + &country_code, + &city_code, + &number)); + EXPECT_EQ(ASCIIToUTF16("4567890"), number); + EXPECT_EQ(ASCIIToUTF16("650"), city_code); + EXPECT_EQ(string16(), country_code); + + // Tests for string with over 10 digits. + // 01 is incorrect prefix in the USA, and if we interpret 011 as prefix, the + // rest is too short for international number - the parsing should fail. + string16 phone8(ASCIIToUTF16("0116504567890")); + EXPECT_FALSE(ParsePhoneNumber(phone8, "US", + &country_code, + &city_code, + &number)); + EXPECT_EQ(string16(), number); + EXPECT_EQ(string16(), city_code); + EXPECT_EQ(string16(), country_code); + + // 011 is a correct "dial out" prefix in the USA - the parsing should succeed. + string16 phone9(ASCIIToUTF16("01116504567890")); + EXPECT_TRUE(ParsePhoneNumber(phone9, "US", + &country_code, + &city_code, + &number)); + EXPECT_EQ(ASCIIToUTF16("4567890"), number); + EXPECT_EQ(ASCIIToUTF16("650"), city_code); + EXPECT_EQ(ASCIIToUTF16("1"), country_code); + + // 011 is a correct "dial out" prefix in the USA - the parsing should succeed. + string16 phone10(ASCIIToUTF16("01178124567890")); + EXPECT_TRUE(ParsePhoneNumber(phone10, "US", + &country_code, + &city_code, + &number)); + EXPECT_EQ(ASCIIToUTF16("4567890"), number); + EXPECT_EQ(ASCIIToUTF16("812"), city_code); + EXPECT_EQ(ASCIIToUTF16("7"), country_code); + + // Test for string with over 10 digits with separator characters. + // Should give back phone number, city code, and country code. "011" is + // US "dial out" code, which is discarded. + string16 phone11(ASCIIToUTF16("(0111) 650-456.7890")); + EXPECT_TRUE(ParsePhoneNumber(phone11, "US", + &country_code, + &city_code, + &number)); + EXPECT_EQ(ASCIIToUTF16("4567890"), number); + EXPECT_EQ(ASCIIToUTF16("650"), city_code); + EXPECT_EQ(ASCIIToUTF16("1"), country_code); + + // Now try phone from Chech republic - it has 00 dial out code, 420 country + // code and variable length area codes. + string16 phone12(ASCIIToUTF16("+420 27-89.10.112")); + EXPECT_TRUE(ParsePhoneNumber(phone12, "US", + &country_code, + &city_code, + &number)); + EXPECT_EQ(ASCIIToUTF16("278910112"), number); + EXPECT_EQ(ASCIIToUTF16(""), city_code); + EXPECT_EQ(ASCIIToUTF16("420"), country_code); + + EXPECT_TRUE(ParsePhoneNumber(phone12, "CZ", + &country_code, + &city_code, + &number)); + EXPECT_EQ(ASCIIToUTF16("278910112"), number); + EXPECT_EQ(ASCIIToUTF16(""), city_code); + EXPECT_EQ(ASCIIToUTF16("420"), country_code); + + string16 phone13(ASCIIToUTF16("420 57-89.10.112")); + EXPECT_FALSE(ParsePhoneNumber(phone13, "US", + &country_code, + &city_code, + &number)); + EXPECT_TRUE(ParsePhoneNumber(phone13, "CZ", + &country_code, + &city_code, + &number)); + EXPECT_EQ(ASCIIToUTF16("578910112"), number); + EXPECT_EQ(ASCIIToUTF16(""), city_code); + EXPECT_EQ(ASCIIToUTF16("420"), country_code); + + string16 phone14(ASCIIToUTF16("1-650-FLOWERS")); + EXPECT_TRUE(ParsePhoneNumber(phone14, "US", + &country_code, + &city_code, + &number)); + EXPECT_EQ(ASCIIToUTF16("3569377"), number); + EXPECT_EQ(ASCIIToUTF16("650"), city_code); + EXPECT_EQ(ASCIIToUTF16("1"), country_code); +} + +TEST(PhoneNumberI18NTest, ConstructPhoneNumber) { + string16 number; + EXPECT_TRUE(ConstructPhoneNumber(ASCIIToUTF16("1"), + ASCIIToUTF16("650"), + ASCIIToUTF16("2345678"), + "US", + autofill_i18n::E164, + &number)); + EXPECT_EQ(number, ASCIIToUTF16("+16502345678")); + EXPECT_TRUE(ConstructPhoneNumber(ASCIIToUTF16("1"), + ASCIIToUTF16("650"), + ASCIIToUTF16("2345678"), + "US", + autofill_i18n::INTERNATIONAL, + &number)); + EXPECT_EQ(number, ASCIIToUTF16("+1 650-234-5678")); + EXPECT_TRUE(ConstructPhoneNumber(ASCIIToUTF16("1"), + ASCIIToUTF16("650"), + ASCIIToUTF16("2345678"), + "US", + autofill_i18n::NATIONAL, + &number)); + EXPECT_EQ(number, ASCIIToUTF16("(650) 234-5678")); + EXPECT_TRUE(ConstructPhoneNumber(ASCIIToUTF16("1"), + ASCIIToUTF16("650"), + ASCIIToUTF16("2345678"), + "US", + autofill_i18n::RFC3966, + &number)); + EXPECT_EQ(number, ASCIIToUTF16("+1-650-234-5678")); + EXPECT_TRUE(ConstructPhoneNumber(ASCIIToUTF16(""), + ASCIIToUTF16("650"), + ASCIIToUTF16("2345678"), + "US", + autofill_i18n::INTERNATIONAL, + &number)); + EXPECT_EQ(number, ASCIIToUTF16("+1 650-234-5678")); + EXPECT_TRUE(ConstructPhoneNumber(ASCIIToUTF16(""), + ASCIIToUTF16(""), + ASCIIToUTF16("6502345678"), + "US", + autofill_i18n::INTERNATIONAL, + &number)); + EXPECT_EQ(number, ASCIIToUTF16("+1 650-234-5678")); + + EXPECT_FALSE(ConstructPhoneNumber(ASCIIToUTF16(""), + ASCIIToUTF16("650"), + ASCIIToUTF16("234567890"), + "US", + autofill_i18n::INTERNATIONAL, + &number)); + EXPECT_EQ(number, string16()); + // Italian number + EXPECT_TRUE(ConstructPhoneNumber(ASCIIToUTF16("39"), + ASCIIToUTF16(""), + ASCIIToUTF16("236618300"), + "US", + autofill_i18n::INTERNATIONAL, + &number)); + EXPECT_EQ(number, ASCIIToUTF16("+39 236618300")); + EXPECT_TRUE(ConstructPhoneNumber(ASCIIToUTF16("39"), + ASCIIToUTF16(""), + ASCIIToUTF16("236618300"), + "US", + autofill_i18n::NATIONAL, + &number)); + EXPECT_EQ(number, ASCIIToUTF16("236618300")); +} + +TEST(PhoneNumberI18NTest, FormatPhone) { + EXPECT_EQ(FormatPhone(ASCIIToUTF16("1[650]234-56-78"), "US", + autofill_i18n::NATIONAL), + ASCIIToUTF16("(650) 234-5678")); + EXPECT_EQ(FormatPhone(ASCIIToUTF16("(650)234-56-78"), "US", + autofill_i18n::NATIONAL), + ASCIIToUTF16("(650) 234-5678")); + EXPECT_EQ(FormatPhone(ASCIIToUTF16("(650)234-56-78"), "US", + autofill_i18n::INTERNATIONAL), + ASCIIToUTF16("+1 650-234-5678")); + EXPECT_EQ(FormatPhone(ASCIIToUTF16("01139236618300"), "US", + autofill_i18n::INTERNATIONAL), + ASCIIToUTF16("+39 236618300")); + EXPECT_EQ(FormatPhone(ASCIIToUTF16("1(650)234-56-78"), "CZ", + autofill_i18n::NATIONAL), + ASCIIToUTF16("16502345678")); + EXPECT_EQ(FormatPhone(ASCIIToUTF16("1(650)234-56-78"), "CZ", + autofill_i18n::INTERNATIONAL), + ASCIIToUTF16("+420 16502345678")); +} + +TEST(PhoneNumberI18NTest, ComparePhones) { + EXPECT_EQ(ComparePhones(ASCIIToUTF16("1(650)234-56-78"), + ASCIIToUTF16("+16502345678"), + "US"), + autofill_i18n::PHONES_EQUAL); + EXPECT_EQ(ComparePhones(ASCIIToUTF16("1(650)234-56-78"), + ASCIIToUTF16("6502345678"), + "US"), + autofill_i18n::PHONES_EQUAL); + EXPECT_EQ(ComparePhones(ASCIIToUTF16("1-800-FLOWERS"), + ASCIIToUTF16("18003569377"), + "US"), + autofill_i18n::PHONES_EQUAL); + EXPECT_EQ(ComparePhones(ASCIIToUTF16("1(650)234-56-78"), + ASCIIToUTF16("2345678"), + "US"), + autofill_i18n::PHONES_SUBMATCH); + EXPECT_EQ(ComparePhones(ASCIIToUTF16("234-56-78"), + ASCIIToUTF16("+16502345678"), + "US"), + autofill_i18n::PHONES_SUBMATCH); + EXPECT_EQ(ComparePhones(ASCIIToUTF16("1650234"), + ASCIIToUTF16("+16502345678"), + "US"), + autofill_i18n::PHONES_NOT_EQUAL); +} TEST(PhoneNumberI18NTest, PhoneNumbersMatch) { // Same numbers, defined country code. |