From 29810dcd1b62d430c22587143ab458b4c6a74f74 Mon Sep 17 00:00:00 2001 From: lararennie Date: Mon, 10 Apr 2017 15:44:13 +0200 Subject: [PATCH] Returning new validation types for ValidationResult (#1679) IS_POSSIBLE_LOCAL_ONLY and INVALID_LENGTH are now being returned from IsPossibleNumberWithReason. The enums were added in v8.3.0 Groups announcement: https://groups.google.com/forum/#!topic/libphonenumber-discuss/sPhYzdzFCmg --- cpp/src/phonenumbers/phonenumberutil.cc | 17 ++-- cpp/src/phonenumbers/phonenumberutil.h | 59 ++++++++----- cpp/test/phonenumbers/phonenumberutil_test.cc | 28 +++--- .../i18n/phonenumbers/PhoneNumberUtil.java | 77 +++++++++------- .../phonenumbers/PhoneNumberUtilTest.java | 18 ++-- javascript/i18n/phonenumbers/demo-compiled.js | 84 +++++++++--------- .../i18n/phonenumbers/phonenumberutil.js | 88 +++++++++++-------- .../i18n/phonenumbers/phonenumberutil_test.js | 18 ++-- pending_code_changes.txt | 3 + 9 files changed, 214 insertions(+), 178 deletions(-) diff --git a/cpp/src/phonenumbers/phonenumberutil.cc b/cpp/src/phonenumbers/phonenumberutil.cc index 3740e22f9..15a808d33 100644 --- a/cpp/src/phonenumbers/phonenumberutil.cc +++ b/cpp/src/phonenumbers/phonenumberutil.cc @@ -369,9 +369,11 @@ PhoneNumberUtil::ValidationResult TestNumberLength( } int actual_length = number.length(); + // This is safe because there is never an overlap beween the possible lengths + // and the local-only lengths; this is checked at build time. if (std::find(local_lengths.begin(), local_lengths.end(), actual_length) != local_lengths.end()) { - return PhoneNumberUtil::IS_POSSIBLE; + return PhoneNumberUtil::IS_POSSIBLE_LOCAL_ONLY; } int minimum_length = possible_lengths.Get(0); if (minimum_length == actual_length) { @@ -381,16 +383,11 @@ PhoneNumberUtil::ValidationResult TestNumberLength( } else if (*(possible_lengths.end() - 1) < actual_length) { return PhoneNumberUtil::TOO_LONG; } - // Note that actually the number is not too long if possible_lengths does not - // contain the length: we know it is less than the highest possible number - // length, and higher than the lowest possible number length. However, we - // don't currently have an enum to express this, so we return TOO_LONG in the - // short-term. // We skip the first element; we've already checked it. return std::find(possible_lengths.begin() + 1, possible_lengths.end(), actual_length) != possible_lengths.end() ? PhoneNumberUtil::IS_POSSIBLE - : PhoneNumberUtil::TOO_LONG; + : PhoneNumberUtil::INVALID_LENGTH; } // Helper method to check a number against possible lengths for this region, @@ -2251,12 +2248,14 @@ void PhoneNumberUtil::ExtractPossibleNumber(const string& number, } bool PhoneNumberUtil::IsPossibleNumber(const PhoneNumber& number) const { - return IsPossibleNumberWithReason(number) == IS_POSSIBLE; + ValidationResult result = IsPossibleNumberWithReason(number); + return result == IS_POSSIBLE || result == IS_POSSIBLE_LOCAL_ONLY; } bool PhoneNumberUtil::IsPossibleNumberForType( const PhoneNumber& number, const PhoneNumberType type) const { - return IsPossibleNumberForTypeWithReason(number, type) == IS_POSSIBLE; + ValidationResult result = IsPossibleNumberForTypeWithReason(number, type); + return result == IS_POSSIBLE || result == IS_POSSIBLE_LOCAL_ONLY; } bool PhoneNumberUtil::IsPossibleNumberForString( diff --git a/cpp/src/phonenumbers/phonenumberutil.h b/cpp/src/phonenumbers/phonenumberutil.h index 572ea8602..3f539c8fa 100644 --- a/cpp/src/phonenumbers/phonenumberutil.h +++ b/cpp/src/phonenumbers/phonenumberutil.h @@ -499,20 +499,26 @@ class PhoneNumberUtil : public Singleton { // 2. It doesn't attempt to figure out the type of the number, but uses // general rules which applies to all types of phone numbers in a // region. Therefore, it is much faster than IsValidNumber(). - // 3. For fixed line numbers, many regions have the concept of area code, - // which together with subscriber number constitute the national - // significant number. It is sometimes okay to dial only the subscriber - // number when dialing in the same area. This function will return - // true if the subscriber-number-only version is passed in. On the other - // hand, because IsValidNumber() validates using information on both - // starting digits (for fixed line numbers, that would most likely be - // area codes) and length (obviously includes the length of area codes - // for fixed line numbers), it will return false for the - // subscriber-number-only version. + // 3. For some numbers (particularly fixed-line), many regions have the + // concept of area code, which together with subscriber number constitute + // the national significant number. It is sometimes okay to dial only the + // subscriber number when dialing in the same area. This function will + // return IS_POSSIBLE_LOCAL_ONLY if the subscriber-number-only version is + // passed in. On the other hand, because IsValidNumber() validates using + // information on both starting digits (for fixed line numbers, that + // would most likely be area codes) and length (obviously includes the + // length of area codes for fixed line numbers), it will return false for + // the subscriber-number-only version. ValidationResult IsPossibleNumberWithReason(const PhoneNumber& number) const; // Convenience wrapper around IsPossibleNumberWithReason(). Instead of - // returning the reason for failure, this method returns a boolean value. + // returning the reason for failure, this method returns true if the number is + // either a possible fully-qualified number (containing the area code and + // country code), or if the number could be a possible local number (with a + // country code, but missing an area code). Local numbers are considered + // possible if they could be possibly dialled in this format: if the area code + // is needed for a call to connect, the number is not considered possible + // without it. bool IsPossibleNumber(const PhoneNumber& number) const; // Check whether a phone number is a possible number of a particular type. For @@ -525,22 +531,29 @@ class PhoneNumberUtil : public Singleton { // This provides a more lenient check than IsValidNumber() in the following // sense: // - // * It only checks the length of phone numbers. In particular, it doesn't - // check starting digits of the number. - // * For fixed line numbers, many regions have the concept of area code, which - // together with subscriber number constitute the national significant - // number. It is sometimes okay to dial only the subscriber number when - // dialing in the same area. This function will return true if the - // subscriber-number-only version is passed in. On the other hand, because - // IsValidNumber() validates using information on both starting digits (for - // fixed line numbers, that would most likely be area codes) and length - // (obviously includes the length of area codes for fixed line numbers), it - // will return false for the subscriber-number-only version. + // 1. It only checks the length of phone numbers. In particular, it doesn't + // check starting digits of the number. + // 2. For some numbers (particularly fixed-line), many regions have the + // concept of area code, which together with subscriber number constitute + // the national significant number. It is sometimes okay to dial only the + // subscriber number when dialing in the same area. This function will + // return IS_POSSIBLE_LOCAL_ONLY if the subscriber-number-only version is + // passed in. On the other hand, because IsValidNumber() validates using + // information on both starting digits (for fixed line numbers, that + // would most likely be area codes) and length (obviously includes the + // length of area codes for fixed line numbers), it will return false for + // the subscriber-number-only version. ValidationResult IsPossibleNumberForTypeWithReason( const PhoneNumber& number, PhoneNumberType type) const; // Convenience wrapper around IsPossibleNumberForTypeWithReason(). Instead of - // returning the reason for failure, this method returns a boolean value. + // returning the reason for failure, this method returns true if the number is + // either a possible fully-qualified number (containing the area code and + // country code), or if the number could be a possible local number (with a + // country code, but missing an area code). Local numbers are considered + // possible if they could be possibly dialled in this format: if the area code + // is needed for a call to connect, the number is not considered possible + // without it. bool IsPossibleNumberForType(const PhoneNumber& number, PhoneNumberType type) const; diff --git a/cpp/test/phonenumbers/phonenumberutil_test.cc b/cpp/test/phonenumbers/phonenumberutil_test.cc index 540625236..f71bfddee 100644 --- a/cpp/test/phonenumbers/phonenumberutil_test.cc +++ b/cpp/test/phonenumbers/phonenumberutil_test.cc @@ -1780,18 +1780,18 @@ TEST_F(PhoneNumberUtilTest, IsPossibleNumber) { RegionCode::US())); EXPECT_TRUE(phone_util_.IsPossibleNumberForString("(650) 253-0000", RegionCode::US())); - EXPECT_TRUE(phone_util_.IsPossibleNumberForString("253-0000", - RegionCode::US())); + EXPECT_TRUE( + phone_util_.IsPossibleNumberForString("253-0000", RegionCode::US())); EXPECT_TRUE(phone_util_.IsPossibleNumberForString("+1 650 253 0000", RegionCode::GB())); EXPECT_TRUE(phone_util_.IsPossibleNumberForString("+44 20 7031 3000", RegionCode::GB())); EXPECT_TRUE(phone_util_.IsPossibleNumberForString("(020) 7031 300", RegionCode::GB())); - EXPECT_TRUE(phone_util_.IsPossibleNumberForString("7031 3000", - RegionCode::GB())); - EXPECT_TRUE(phone_util_.IsPossibleNumberForString("3331 6005", - RegionCode::NZ())); + EXPECT_TRUE( + phone_util_.IsPossibleNumberForString("7031 3000", RegionCode::GB())); + EXPECT_TRUE( + phone_util_.IsPossibleNumberForString("3331 6005", RegionCode::NZ())); EXPECT_TRUE(phone_util_.IsPossibleNumberForString("+800 1234 5678", RegionCode::UN001())); } @@ -1930,7 +1930,7 @@ TEST_F(PhoneNumberUtilTest, IsPossibleNumberWithReason) { number.set_country_code(1); number.set_national_number(2530000ULL); - EXPECT_EQ(PhoneNumberUtil::IS_POSSIBLE, + EXPECT_EQ(PhoneNumberUtil::IS_POSSIBLE_LOCAL_ONLY, phone_util_.IsPossibleNumberWithReason(number)); number.set_country_code(0); @@ -2050,10 +2050,10 @@ TEST_F(PhoneNumberUtilTest, IsPossibleNumberForTypeWithReason_LocalOnly) { // Here we test a number length which matches a local-only length. number.set_country_code(49); number.set_national_number(12ULL); - EXPECT_EQ(PhoneNumberUtil::IS_POSSIBLE, + EXPECT_EQ(PhoneNumberUtil::IS_POSSIBLE_LOCAL_ONLY, phone_util_.IsPossibleNumberForTypeWithReason( number, PhoneNumberUtil::UNKNOWN)); - EXPECT_EQ(PhoneNumberUtil::IS_POSSIBLE, + EXPECT_EQ(PhoneNumberUtil::IS_POSSIBLE_LOCAL_ONLY, phone_util_.IsPossibleNumberForTypeWithReason( number, PhoneNumberUtil::FIXED_LINE)); // Mobile numbers must be 10 or 11 digits, and there are no local-only @@ -2072,10 +2072,10 @@ TEST_F(PhoneNumberUtilTest, // Local-only number. number.set_country_code(55); number.set_national_number(12345678ULL); - EXPECT_EQ(PhoneNumberUtil::IS_POSSIBLE, + EXPECT_EQ(PhoneNumberUtil::IS_POSSIBLE_LOCAL_ONLY, phone_util_.IsPossibleNumberForTypeWithReason( number, PhoneNumberUtil::UNKNOWN)); - EXPECT_EQ(PhoneNumberUtil::IS_POSSIBLE, + EXPECT_EQ(PhoneNumberUtil::IS_POSSIBLE_LOCAL_ONLY, phone_util_.IsPossibleNumberForTypeWithReason( number, PhoneNumberUtil::FIXED_LINE)); // Normal-length number. @@ -2099,7 +2099,7 @@ TEST_F(PhoneNumberUtilTest, phone_util_.IsPossibleNumberForTypeWithReason( number, PhoneNumberUtil::MOBILE)); // This matches a fixed-line length though. - EXPECT_EQ(PhoneNumberUtil::IS_POSSIBLE, + EXPECT_EQ(PhoneNumberUtil::IS_POSSIBLE_LOCAL_ONLY, phone_util_.IsPossibleNumberForTypeWithReason( number, PhoneNumberUtil::FIXED_LINE_OR_MOBILE)); // This is too short for fixed-line, and no mobile numbers exist. @@ -2168,9 +2168,7 @@ TEST_F(PhoneNumberUtilTest, EXPECT_EQ(PhoneNumberUtil::TOO_LONG, phone_util_.IsPossibleNumberForTypeWithReason( number, PhoneNumberUtil::MOBILE)); - // This will change to INVALID_LENGTH once we start returning this type in the - // main isPossibleNumberWithReason API. - EXPECT_EQ(PhoneNumberUtil::TOO_LONG, + EXPECT_EQ(PhoneNumberUtil::INVALID_LENGTH, phone_util_.IsPossibleNumberForTypeWithReason( number, PhoneNumberUtil::FIXED_LINE_OR_MOBILE)); diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java index d521c8c68..c403759bd 100644 --- a/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java +++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java @@ -2468,24 +2468,37 @@ public class PhoneNumberUtil { /** * Convenience wrapper around {@link #isPossibleNumberWithReason}. Instead of returning the reason - * for failure, this method returns a boolean value. + * for failure, this method returns true if the number is either a possible fully-qualified number + * (containing the area code and country code), or if the number could be a possible local number + * (with a country code, but missing an area code). Local numbers are considered possible if they + * could be possibly dialled in this format: if the area code is needed for a call to connect, the + * number is not considered possible without it. + * * @param number the number that needs to be checked * @return true if the number is possible */ public boolean isPossibleNumber(PhoneNumber number) { - return isPossibleNumberWithReason(number) == ValidationResult.IS_POSSIBLE; + ValidationResult result = isPossibleNumberWithReason(number); + return result == ValidationResult.IS_POSSIBLE + || result == ValidationResult.IS_POSSIBLE_LOCAL_ONLY; } /** * Convenience wrapper around {@link #isPossibleNumberForTypeWithReason}. Instead of returning the - * reason for failure, this method returns a boolean value. + * reason for failure, this method returns true if the number is either a possible fully-qualified + * number (containing the area code and country code), or if the number could be a possible local + * number (with a country code, but missing an area code). Local numbers are considered possible + * if they could be possibly dialled in this format: if the area code is needed for a call to + * connect, the number is not considered possible without it. * * @param number the number that needs to be checked * @param type the type we are interested in * @return true if the number is possible for this particular type */ public boolean isPossibleNumberForType(PhoneNumber number, PhoneNumberType type) { - return isPossibleNumberForTypeWithReason(number, type) == ValidationResult.IS_POSSIBLE; + ValidationResult result = isPossibleNumberForTypeWithReason(number, type); + return result == ValidationResult.IS_POSSIBLE + || result == ValidationResult.IS_POSSIBLE_LOCAL_ONLY; } /** @@ -2556,8 +2569,10 @@ public class PhoneNumberUtil { } int actualLength = number.length(); + // This is safe because there is never an overlap beween the possible lengths and the local-only + // lengths; this is checked at build time. if (localLengths.contains(actualLength)) { - return ValidationResult.IS_POSSIBLE; + return ValidationResult.IS_POSSIBLE_LOCAL_ONLY; } int minimumLength = possibleLengths.get(0); @@ -2568,32 +2583,28 @@ public class PhoneNumberUtil { } else if (possibleLengths.get(possibleLengths.size() - 1) < actualLength) { return ValidationResult.TOO_LONG; } - // Note that actually the number is not too long if possibleLengths does not contain the length: - // we know it is less than the highest possible number length, and higher than the lowest - // possible number length. However, we don't currently have an enum to express this, so we - // return TOO_LONG in the short-term. // We skip the first element; we've already checked it. return possibleLengths.subList(1, possibleLengths.size()).contains(actualLength) - ? ValidationResult.IS_POSSIBLE : ValidationResult.TOO_LONG; + ? ValidationResult.IS_POSSIBLE : ValidationResult.INVALID_LENGTH; } /** * Check whether a phone number is a possible number. It provides a more lenient check than * {@link #isValidNumber} in the following sense: - *
    - *
  1. It only checks the length of phone numbers. In particular, it doesn't check starting - * digits of the number. - *
  2. It doesn't attempt to figure out the type of the number, but uses general rules which - * applies to all types of phone numbers in a region. Therefore, it is much faster than - * isValidNumber. - *
  3. For fixed line numbers, many regions have the concept of area code, which together with - * subscriber number constitute the national significant number. It is sometimes okay to dial - * only the subscriber number when dialing in the same area. This function will return - * true if the subscriber-number-only version is passed in. On the other hand, because - * isValidNumber validates using information on both starting digits (for fixed line - * numbers, that would most likely be area codes) and length (obviously includes the - * length of area codes for fixed line numbers), it will return false for the - * subscriber-number-only version. + *
      + *
    1. It only checks the length of phone numbers. In particular, it doesn't check starting + * digits of the number. + *
    2. It doesn't attempt to figure out the type of the number, but uses general rules which + * applies to all types of phone numbers in a region. Therefore, it is much faster than + * isValidNumber. + *
    3. For some numbers (particularly fixed-line), many regions have the concept of area code, + * which together with subscriber number constitute the national significant number. It is + * sometimes okay to dial only the subscriber number when dialing in the same area. This + * function will return IS_POSSIBLE_LOCAL_ONLY if the subscriber-number-only version is + * passed in. On the other hand, because isValidNumber validates using information on both + * starting digits (for fixed line numbers, that would most likely be area codes) and + * length (obviously includes the length of area codes for fixed line numbers), it will + * return false for the subscriber-number-only version. *
    * @param number the number that needs to be checked * @return a ValidationResult object which indicates whether the number is possible @@ -2613,15 +2624,15 @@ public class PhoneNumberUtil { * *
      *
    1. It only checks the length of phone numbers. In particular, it doesn't check starting - * digits of the number. - *
    2. For fixed line numbers, many regions have the concept of area code, which together with - * subscriber number constitute the national significant number. It is sometimes okay to - * dial the subscriber number only when dialing in the same area. This function will return - * true if the subscriber-number-only version is passed in. On the other hand, because - * isValidNumber validates using information on both starting digits (for fixed line - * numbers, that would most likely be area codes) and length (obviously includes the length - * of area codes for fixed line numbers), it will return false for the - * subscriber-number-only version. + * digits of the number. + *
    3. For some numbers (particularly fixed-line), many regions have the concept of area code, + * which together with subscriber number constitute the national significant number. It is + * sometimes okay to dial only the subscriber number when dialing in the same area. This + * function will return IS_POSSIBLE_LOCAL_ONLY if the subscriber-number-only version is + * passed in. On the other hand, because isValidNumber validates using information on both + * starting digits (for fixed line numbers, that would most likely be area codes) and + * length (obviously includes the length of area codes for fixed line numbers), it will + * return false for the subscriber-number-only version. *
    * * @param number the number that needs to be checked diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java b/java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java index 9e1b73d61..3975e6f03 100644 --- a/java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java +++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java @@ -1443,8 +1443,8 @@ public class PhoneNumberUtilTest extends TestMetadataTestCase { // National numbers for country calling code +1 that are within 7 to 10 digits are possible. assertEquals(ValidationResult.IS_POSSIBLE, phoneUtil.isPossibleNumberWithReason(US_NUMBER)); - assertEquals( - ValidationResult.IS_POSSIBLE, phoneUtil.isPossibleNumberWithReason(US_LOCAL_NUMBER)); + assertEquals(ValidationResult.IS_POSSIBLE_LOCAL_ONLY, + phoneUtil.isPossibleNumberWithReason(US_LOCAL_NUMBER)); assertEquals(ValidationResult.TOO_LONG, phoneUtil.isPossibleNumberWithReason(US_LONG_NUMBER)); @@ -1547,10 +1547,10 @@ public class PhoneNumberUtilTest extends TestMetadataTestCase { // Here we test a number length which matches a local-only length. number.setCountryCode(49).setNationalNumber(12L); assertEquals( - ValidationResult.IS_POSSIBLE, + ValidationResult.IS_POSSIBLE_LOCAL_ONLY, phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.UNKNOWN)); assertEquals( - ValidationResult.IS_POSSIBLE, + ValidationResult.IS_POSSIBLE_LOCAL_ONLY, phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE)); // Mobile numbers must be 10 or 11 digits, and there are no local-only lengths. assertEquals( @@ -1565,10 +1565,10 @@ public class PhoneNumberUtilTest extends TestMetadataTestCase { // Local-only number. number.setCountryCode(55).setNationalNumber(12345678L); assertEquals( - ValidationResult.IS_POSSIBLE, + ValidationResult.IS_POSSIBLE_LOCAL_ONLY, phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.UNKNOWN)); assertEquals( - ValidationResult.IS_POSSIBLE, + ValidationResult.IS_POSSIBLE_LOCAL_ONLY, phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE)); // Normal-length number. @@ -1590,7 +1590,7 @@ public class PhoneNumberUtilTest extends TestMetadataTestCase { phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.MOBILE)); // This matches a fixed-line length though. assertEquals( - ValidationResult.IS_POSSIBLE, + ValidationResult.IS_POSSIBLE_LOCAL_ONLY, phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE_OR_MOBILE)); // This is too short for fixed-line, and no mobile numbers exist. number.setCountryCode(55).setNationalNumber(1234567L); @@ -1655,10 +1655,8 @@ public class PhoneNumberUtilTest extends TestMetadataTestCase { assertEquals( ValidationResult.TOO_LONG, phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.MOBILE)); - // This will change to INVALID_LENGTH once we start returning this type in the main - // isPossibleNumberWithReason API. assertEquals( - ValidationResult.TOO_LONG, + ValidationResult.INVALID_LENGTH, phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE_OR_MOBILE)); number.setNationalNumber(123456L); diff --git a/javascript/i18n/phonenumbers/demo-compiled.js b/javascript/i18n/phonenumbers/demo-compiled.js index b9efd33f0..aa01509f1 100644 --- a/javascript/i18n/phonenumbers/demo-compiled.js +++ b/javascript/i18n/phonenumbers/demo-compiled.js @@ -2,15 +2,15 @@ function ca(a,b){if(b){for(var c=ba,d=a.split("."),e=0;ea||1342177279>>=1)b+=b;return d}});ca("Math.sign",function(a){return a?a:function(a){a=Number(a);return!a||isNaN(a)?a:0c?Math.max(0,a.length+c):c;if(k(a))return k(b)&&1==b.length?a.indexOf(b,c):-1;for(;cb?1:ac?Math.max(0,a.length+c):c;if(k(a))return k(b)&&1==b.length?a.indexOf(b,c):-1;for(;cb?1:aa.length?!1:N($a,a)}function hb(a){return N(Ya,a)?O(a,Ra):O(a,L)}function ib(a){var b=hb(a.toString());C(a);a.a(b)}function kb(a){return!!a&&(1!=y(a,9)||-1!=w(a,9)[0])} -function O(a,b){for(var c=new B,d,e=a.length,f=0;f=e)a=c;else if(d=d.substring(0,e),d=O(d,L),d.length)if(g=g.clone(),Ga(g,4),d=[g],g=x(b,1),c=R(b),g in J){a=T(a,g,U(g));if(e=sb(d,c))d=e.clone(),e=x(e,4),0b?2:f[f.length-1]=f&&f<=e;++f)if(d=parseInt(c.substring(0,f),10),d in J)return b.a(c.substring(f)),d;return 0} -function Db(a,b,c,d,e,f){if(!b.length)return 0;b=new B(b);var g;c&&(g=u(c,11));null==g&&(g="NonMatch");var h=b.toString();if(h.length)if(M.test(h))h=h.replace(M,""),C(b),b.a(hb(h)),g=1;else{h=new RegExp(g);ib(b);g=b.toString();if(g.search(h))g=!1;else{var h=g.match(h)[0].length,m=g.substring(h).match(Ua);m&&null!=m[1]&&0=b.b.length)throw Error("Phone number too short after IDD");if(a=Cb(b, -d))return v(f,1,a),a;throw Error("Invalid country calling code");}if(c&&(g=x(c,10),h=""+g,m=b.toString(),!m.lastIndexOf(h,0)&&(h=new B(m.substring(h.length)),m=u(c,1),m=new RegExp(x(m,2)),Eb(h,c,null),h=h.toString(),!N(m,b.toString())&&N(m,h)||3==Ab(a,b.toString(),c,-1))))return d.a(h),e&&v(f,6,10),v(f,1,g),g;v(f,1,0);return 0} -function Eb(a,b,c){var d=a.toString(),e=d.length,f=u(b,15);if(e&&null!=f&&f.length){var g=new RegExp("^(?:"+f+")");if(e=g.exec(d)){var f=new RegExp(x(u(b,1),2)),h=N(f,d),m=e.length-1;b=u(b,16);if(null!=b&&b.length&&null!=e[m]&&e[m].length){if(d=d.replace(g,b),!h||N(f,d))c&&0g.b.length)throw Error("The string supplied is too short to be a phone number");b&&(c=new B,e=new B(g.toString()),Eb(e,b,c),2!=Ab(a,e.toString(),b,-1)&&(g=e,d&&0d)throw Error("The string supplied is too short to be a phone number");if(17a.length?!1:N($a,a)}function hb(a){return N(Ya,a)?O(a,Ra):O(a,L)}function ib(a){var b=hb(a.toString());D(a);a.a(b)}function lb(a){return!!a&&(1!=z(a,9)||-1!=w(a,9)[0])} +function O(a,b){for(var c=new C,d,e=a.length,f=0;f=e)a=c;else if(d=d.substring(0,e),d=O(d,L),d.length)if(g=g.clone(),Ga(g,4),d=[g],g=y(b,1),c=Q(b),g in J){a=S(a,g,T(g));if(e=tb(d,c))d=e.clone(),e=y(e,4),0b?2:f[f.length-1]=f&&f<=e;++f)if(d=parseInt(c.substring(0,f),10),d in J)return b.a(c.substring(f)),d;return 0} +function Eb(a,b,c,d,e,f){if(!b.length)return 0;b=new C(b);var g;c&&(g=u(c,11));null==g&&(g="NonMatch");var h=b.toString();if(h.length)if(M.test(h))h=h.replace(M,""),D(b),b.a(hb(h)),g=1;else{h=new RegExp(g);ib(b);g=b.toString();if(g.search(h))g=!1;else{var h=g.match(h)[0].length,l=g.substring(h).match(Ua);l&&null!=l[1]&&0=b.b.length)throw Error("Phone number too short after IDD");if(a=Db(b, +d))return v(f,1,a),a;throw Error("Invalid country calling code");}if(c&&(g=y(c,10),h=""+g,l=b.toString(),!l.lastIndexOf(h,0)&&(h=new C(l.substring(h.length)),l=u(c,1),l=new RegExp(y(l,2)),Fb(h,c,null),h=h.toString(),!N(l,b.toString())&&N(l,h)||3==Bb(a,b.toString(),c,-1))))return d.a(h),e&&v(f,6,10),v(f,1,g),g;v(f,1,0);return 0} +function Fb(a,b,c){var d=a.toString(),e=d.length,f=u(b,15);if(e&&null!=f&&f.length){var g=new RegExp("^(?:"+f+")");if(e=g.exec(d)){var f=new RegExp(y(u(b,1),2)),h=N(f,d),l=e.length-1;b=u(b,16);if(null!=b&&b.length&&null!=e[l]&&e[l].length){if(d=d.replace(g,b),!h||N(f,d))c&&0g.b.length)throw Error("The string supplied is too short to be a phone number");b&&(c=new C,e=new C(g.toString()),Fb(e,b,c),2!=Bb(a,e.toString(),b,-1)&&(g=e,d&&0d)throw Error("The string supplied is too short to be a phone number");if(17 -1) { - return i18n.phonenumbers.PhoneNumberUtil.ValidationResult.IS_POSSIBLE; + return i18n.phonenumbers.PhoneNumberUtil.ValidationResult + .IS_POSSIBLE_LOCAL_ONLY; } var minimumLength = possibleLengths[0]; if (minimumLength == actualLength) { @@ -3415,15 +3436,10 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.testNumberLengthForType_ = } else if (possibleLengths[possibleLengths.length - 1] < actualLength) { return i18n.phonenumbers.PhoneNumberUtil.ValidationResult.TOO_LONG; } - // Note that actually the number is not too long if possible_lengths does not - // contain the length: we know it is less than the highest possible number - // length, and higher than the lowest possible number length. However, we - // don't currently have an enum to express this, so we return TOO_LONG in the - // short-term. // We skip the first element since we've already checked it. return (goog.array.indexOf(possibleLengths, actualLength, 1) > -1) ? i18n.phonenumbers.PhoneNumberUtil.ValidationResult.IS_POSSIBLE : - i18n.phonenumbers.PhoneNumberUtil.ValidationResult.TOO_LONG; + i18n.phonenumbers.PhoneNumberUtil.ValidationResult.INVALID_LENGTH; }; @@ -3436,15 +3452,15 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.testNumberLengthForType_ = *
  4. It doesn't attempt to figure out the type of the number, but uses general * rules which applies to all types of phone numbers in a region. Therefore, it * is much faster than isValidNumber. - *
  5. For fixed line numbers, many regions have the concept of area code, which - * together with subscriber number constitute the national significant number. - * It is sometimes okay to dial only the subscriber number when dialing in the - * same area. This function will return true if the subscriber-number-only - * version is passed in. On the other hand, because isValidNumber validates - * using information on both starting digits (for fixed line numbers, that would - * most likely be area codes) and length (obviously includes the length of area - * codes for fixed line numbers), it will return false for the - * subscriber-number-only version. + *
  6. For some numbers (particularly fixed-line), many regions have the concept + * of area code, which together with subscriber number constitute the national + * significant number. It is sometimes okay to dial only the subscriber number + * when dialing in the same area. This function will return + * IS_POSSIBLE_LOCAL_ONLY if the subscriber-number-only version is passed in. On + * the other hand, because isValidNumber validates using information on both + * starting digits (for fixed line numbers, that would most likely be area + * codes) and length (obviously includes the length of area codes for fixed line + * numbers), it will return false for the subscriber-number-only version. *
* * @param {i18n.phonenumbers.PhoneNumber} number the number that needs to be @@ -3465,15 +3481,15 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.isPossibleNumberWithReason = *
    *
  1. It only checks the length of phone numbers. In particular, it doesn't * check starting digits of the number. - *
  2. For fixed line numbers, many regions have the concept of area code, which - * together with subscriber number constitute the national significant number. - * It is sometimes okay to dial only the subscriber number when dialing in the - * same area. This function will return true if the subscriber-number-only - * version is passed in. On the other hand, because isValidNumber validates - * using information on both starting digits (for fixed line numbers, that would - * most likely be area codes) and length (obviously includes the length of area - * codes for fixed line numbers), it will return false for the - * subscriber-number-only version. + *
  3. For some numbers (particularly fixed-line), many regions have the concept + * of area code, which together with subscriber number constitute the national + * significant number. It is sometimes okay to dial only the subscriber number + * when dialing in the same area. This function will return + * IS_POSSIBLE_LOCAL_ONLY if the subscriber-number-only version is passed in. On + * the other hand, because isValidNumber validates using information on both + * starting digits (for fixed line numbers, that would most likely be area + * codes) and length (obviously includes the length of area codes for fixed line + * numbers), it will return false for the subscriber-number-only version. *
* * @param {i18n.phonenumbers.PhoneNumber} number the number that needs to be diff --git a/javascript/i18n/phonenumbers/phonenumberutil_test.js b/javascript/i18n/phonenumbers/phonenumberutil_test.js index 9e9eef23a..b359faf39 100644 --- a/javascript/i18n/phonenumbers/phonenumberutil_test.js +++ b/javascript/i18n/phonenumbers/phonenumberutil_test.js @@ -30,8 +30,8 @@ goog.require('goog.string.StringBuffer'); goog.require('goog.testing.jsunit'); goog.require('i18n.phonenumbers.NumberFormat'); goog.require('i18n.phonenumbers.PhoneMetadata'); -goog.require('i18n.phonenumbers.PhoneNumberDesc'); goog.require('i18n.phonenumbers.PhoneNumber'); +goog.require('i18n.phonenumbers.PhoneNumberDesc'); goog.require('i18n.phonenumbers.PhoneNumberUtil'); goog.require('i18n.phonenumbers.RegionCode'); @@ -1930,7 +1930,7 @@ function testIsPossibleNumberWithReason() { assertEquals(VR.IS_POSSIBLE, phoneUtil.isPossibleNumberWithReason(US_NUMBER)); - assertEquals(VR.IS_POSSIBLE, + assertEquals(VR.IS_POSSIBLE_LOCAL_ONLY, phoneUtil.isPossibleNumberWithReason(US_LOCAL_NUMBER)); assertEquals(VR.TOO_LONG, @@ -2049,9 +2049,9 @@ function testIsPossibleNumberForTypeWithReason_LocalOnly() { // Here we test a number length which matches a local-only length. number.setCountryCode(49); number.setNationalNumber(12); - assertEquals(VR.IS_POSSIBLE, + assertEquals(VR.IS_POSSIBLE_LOCAL_ONLY, phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.UNKNOWN)); - assertEquals(VR.IS_POSSIBLE, + assertEquals(VR.IS_POSSIBLE_LOCAL_ONLY, phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.FIXED_LINE)); // Mobile numbers must be 10 or 11 digits, and there are no local-only // lengths. @@ -2071,10 +2071,10 @@ function testIsPossibleNumberForTypeWithReason_DataMissingForSizeReasons() { number.setCountryCode(55); number.setNationalNumber(12345678); assertEquals( - VR.IS_POSSIBLE, + VR.IS_POSSIBLE_LOCAL_ONLY, phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.UNKNOWN)); assertEquals( - VR.IS_POSSIBLE, + VR.IS_POSSIBLE_LOCAL_ONLY, phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.FIXED_LINE)); // Normal-length number. @@ -2101,7 +2101,7 @@ function testIsPossibleNumberForTypeWithReason_NumberTypeNotSupportedForRegion() phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.MOBILE)); // This matches a fixed-line length though. assertEquals( - VR.IS_POSSIBLE, + VR.IS_POSSIBLE_LOCAL_ONLY, phoneUtil.isPossibleNumberForTypeWithReason( number, PNT.FIXED_LINE_OR_MOBILE)); // This is too short for fixed-line, and no mobile numbers exist. @@ -2178,10 +2178,8 @@ function testIsPossibleNumberForTypeWithReason_FixedLineOrMobile() { assertEquals( VR.TOO_LONG, phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.MOBILE)); - // This will change to INVALID_LENGTH once we start returning this type in the - // main isPossibleNumberWithReason API. assertEquals( - VR.TOO_LONG, + VR.INVALID_LENGTH, phoneUtil.isPossibleNumberForTypeWithReason( number, PNT.FIXED_LINE_OR_MOBILE)); diff --git a/pending_code_changes.txt b/pending_code_changes.txt index 1d00d8ee4..150e75acf 100644 --- a/pending_code_changes.txt +++ b/pending_code_changes.txt @@ -1,3 +1,6 @@ Code changes: + - Changing isPossibleWithReason to return the enums INVALID_LENGTH and + IS_POSSIBLE_LOCAL_ONLY, where these apply. isPossibleNumber continues to + consider IS_POSSIBLE or IS_POSSIBLE_LOCAL_ONLY numbers as possible to dial. - Doc updates for getRegionCodeForNumber to clarify that it does not work for short-codes or invalid numbers.