152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia/* 2ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia * Copyright (C) 2011 The Libphonenumber Authors 352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * 452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * Licensed under the Apache License, Version 2.0 (the "License"); 552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * you may not use this file except in compliance with the License. 652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * You may obtain a copy of the License at 752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * 852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * http://www.apache.org/licenses/LICENSE-2.0 952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * 1052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * Unless required by applicable law or agreed to in writing, software 1152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * distributed under the License is distributed on an "AS IS" BASIS, 1252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * See the License for the specific language governing permissions and 1452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * limitations under the License. 1552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia */ 1652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 17a77faddfc3b3e4cca8f585c82d669054aec221f4Narayan Kamathpackage com.google.i18n.phonenumbers; 1852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 19a77faddfc3b3e4cca8f585c82d669054aec221f4Narayan Kamathimport com.google.i18n.phonenumbers.PhoneNumberUtil.Leniency; 20a77faddfc3b3e4cca8f585c82d669054aec221f4Narayan Kamathimport com.google.i18n.phonenumbers.Phonenumber.PhoneNumber; 21a77faddfc3b3e4cca8f585c82d669054aec221f4Narayan Kamathimport com.google.i18n.phonenumbers.Phonenumber.PhoneNumber.CountryCodeSource; 2252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 2352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jiaimport java.util.ArrayList; 24f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jiaimport java.util.Arrays; 2552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jiaimport java.util.Iterator; 2652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jiaimport java.util.List; 2752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jiaimport java.util.NoSuchElementException; 2852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 2952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia/** 3052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * Tests for {@link PhoneNumberMatcher}. This only tests basic functionality based on test metadata. 3152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * 3252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * @see PhoneNumberUtilTest {@link PhoneNumberUtilTest} for the origin of the test data 3352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia */ 34b0e21c22b1ca6b9aeb1426924cdf42a221c3d416Shaopeng Jiapublic class PhoneNumberMatcherTest extends TestMetadataTestCase { 3552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 36bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia public void testContainsMoreThanOneSlashInNationalNumber() throws Exception { 37bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia // A date should return true. 38bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia PhoneNumber number = new PhoneNumber(); 39bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia number.setCountryCode(1); 40bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia number.setCountryCodeSource(CountryCodeSource.FROM_DEFAULT_COUNTRY); 41bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia String candidate = "1/05/2013"; 42bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia assertTrue(PhoneNumberMatcher.containsMoreThanOneSlashInNationalNumber(number, candidate)); 43bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia 44bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia // Here, the country code source thinks it started with a country calling code, but this is not 45bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia // the same as the part before the slash, so it's still true. 46bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia number = new PhoneNumber(); 47bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia number.setCountryCode(274); 48bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia number.setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN); 49bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia candidate = "27/4/2013"; 50bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia assertTrue(PhoneNumberMatcher.containsMoreThanOneSlashInNationalNumber(number, candidate)); 51bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia 52bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia // Now it should be false, because the first slash is after the country calling code. 53bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia number = new PhoneNumber(); 54bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia number.setCountryCode(49); 55bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia number.setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN); 56bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia candidate = "49/69/2013"; 57bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia assertFalse(PhoneNumberMatcher.containsMoreThanOneSlashInNationalNumber(number, candidate)); 58bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia 59bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia number = new PhoneNumber(); 60bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia number.setCountryCode(49); 61bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia number.setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN); 62bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia candidate = "+49/69/2013"; 63bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia assertFalse(PhoneNumberMatcher.containsMoreThanOneSlashInNationalNumber(number, candidate)); 64bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia 65bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia candidate = "+ 49/69/2013"; 66bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia assertFalse(PhoneNumberMatcher.containsMoreThanOneSlashInNationalNumber(number, candidate)); 67bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia 68bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia candidate = "+ 49/69/20/13"; 69bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia assertTrue(PhoneNumberMatcher.containsMoreThanOneSlashInNationalNumber(number, candidate)); 70bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia 71bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia // Here, the first group is not assumed to be the country calling code, even though it is the 72bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia // same as it, so this should return true. 73bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia number = new PhoneNumber(); 74bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia number.setCountryCode(49); 75bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia number.setCountryCodeSource(CountryCodeSource.FROM_DEFAULT_COUNTRY); 76bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia candidate = "49/69/2013"; 77bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia assertTrue(PhoneNumberMatcher.containsMoreThanOneSlashInNationalNumber(number, candidate)); 78bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia } 79bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia 8052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia /** See {@link PhoneNumberUtilTest#testParseNationalNumber()}. */ 8152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia public void testFindNationalNumber() throws Exception { 8252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // same cases as in testParseNationalNumber 83ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("033316005", RegionCode.NZ); 84a48b2d221ba46df7446d1a87244efa985e8e292fShaopeng Jia // ("33316005", RegionCode.NZ) is omitted since the national prefix is obligatory for these 85a48b2d221ba46df7446d1a87244efa985e8e292fShaopeng Jia // types of numbers in New Zealand. 8652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // National prefix attached and some formatting present. 87ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("03-331 6005", RegionCode.NZ); 88ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("03 331 6005", RegionCode.NZ); 8952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // Testing international prefixes. 9052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // Should strip country code. 91ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("0064 3 331 6005", RegionCode.NZ); 9252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // Try again, but this time we have an international number with Region Code US. It should 9352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // recognize the country code and parse accordingly. 94ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("01164 3 331 6005", RegionCode.US); 95ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("+64 3 331 6005", RegionCode.US); 9652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 97ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("64(0)64123456", RegionCode.NZ); 9852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // Check that using a "/" is fine in a phone number. 99b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia // Note that real Polish numbers do *not* start with a 0. 100b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia doTestFindInContext("0123/456789", RegionCode.PL); 101ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("123-456-7890", RegionCode.US); 10252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 10352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 10452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia /** See {@link PhoneNumberUtilTest#testParseWithInternationalPrefixes()}. */ 10552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia public void testFindWithInternationalPrefixes() throws Exception { 106ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("+1 (650) 333-6000", RegionCode.NZ); 107ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("1-650-333-6000", RegionCode.US); 10852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // Calling the US number from Singapore by using different service providers 10952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // 1st test: calling using SingTel IDD service (IDD is 001) 110ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("0011-650-333-6000", RegionCode.SG); 11152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // 2nd test: calling using StarHub IDD service (IDD is 008) 112ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("0081-650-333-6000", RegionCode.SG); 11352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // 3rd test: calling using SingTel V019 service (IDD is 019) 114ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("0191-650-333-6000", RegionCode.SG); 11552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // Calling the US number from Poland 116ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("0~01-650-333-6000", RegionCode.PL); 11752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // Using "++" at the start. 118ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("++1 (650) 333-6000", RegionCode.PL); 11952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // Using a full-width plus sign. 120ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("\uFF0B1 (650) 333-6000", RegionCode.SG); 12152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // The whole number, including punctuation, is here represented in full-width form. 12252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia doTestFindInContext("\uFF0B\uFF11\u3000\uFF08\uFF16\uFF15\uFF10\uFF09" + 12352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia "\u3000\uFF13\uFF13\uFF13\uFF0D\uFF16\uFF10\uFF10\uFF10", 124ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia RegionCode.SG); 12552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 12652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 12752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia /** See {@link PhoneNumberUtilTest#testParseWithLeadingZero()}. */ 12852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia public void testFindWithLeadingZero() throws Exception { 129ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("+39 02-36618 300", RegionCode.NZ); 130ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("02-36618 300", RegionCode.IT); 131ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("312 345 678", RegionCode.IT); 13252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 13352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 13452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia /** See {@link PhoneNumberUtilTest#testParseNationalNumberArgentina()}. */ 13552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia public void testFindNationalNumberArgentina() throws Exception { 13652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // Test parsing mobile numbers of Argentina. 137ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("+54 9 343 555 1212", RegionCode.AR); 138ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("0343 15 555 1212", RegionCode.AR); 13952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 140ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("+54 9 3715 65 4320", RegionCode.AR); 141ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("03715 15 65 4320", RegionCode.AR); 14252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 14352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // Test parsing fixed-line numbers of Argentina. 144ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("+54 11 3797 0000", RegionCode.AR); 145ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("011 3797 0000", RegionCode.AR); 14652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 147ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("+54 3715 65 4321", RegionCode.AR); 148ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("03715 65 4321", RegionCode.AR); 14952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 150ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("+54 23 1234 0000", RegionCode.AR); 151ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("023 1234 0000", RegionCode.AR); 15252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 15352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 15452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia /** See {@link PhoneNumberUtilTest#testParseWithXInNumber()}. */ 15552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia public void testFindWithXInNumber() throws Exception { 156ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("(0xx) 123456789", RegionCode.AR); 157f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia // A case where x denotes both carrier codes and extension symbol. 158ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("(0xx) 123456789 x 1234", RegionCode.AR); 15952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 16052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // This test is intentionally constructed such that the number of digit after xx is larger than 16152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // 7, so that the number won't be mistakenly treated as an extension, as we allow extensions up 16252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // to 7 digits. This assumption is okay for now as all the countries where a carrier selection 16352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // code is written in the form of xx have a national significant number of length larger than 7. 164ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("011xx5481429712", RegionCode.US); 16552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 16652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 16752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia /** See {@link PhoneNumberUtilTest#testParseNumbersMexico()}. */ 16852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia public void testFindNumbersMexico() throws Exception { 16952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // Test parsing fixed-line numbers of Mexico. 170ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("+52 (449)978-0001", RegionCode.MX); 171ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("01 (449)978-0001", RegionCode.MX); 172ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("(449)978-0001", RegionCode.MX); 17352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 17452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // Test parsing mobile numbers of Mexico. 175ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("+52 1 33 1234-5678", RegionCode.MX); 176ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("044 (33) 1234-5678", RegionCode.MX); 177ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("045 33 1234-5678", RegionCode.MX); 17852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 17952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 18052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia /** See {@link PhoneNumberUtilTest#testParseNumbersWithPlusWithNoRegion()}. */ 18152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia public void testFindNumbersWithPlusWithNoRegion() throws Exception { 182ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia // RegionCode.ZZ is allowed only if the number starts with a '+' - then the country code can be 18352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // calculated. 184ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("+64 3 331 6005", RegionCode.ZZ); 18552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // Null is also allowed for the region code in these cases. 18652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia doTestFindInContext("+64 3 331 6005", null); 18752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 18852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 18952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia /** See {@link PhoneNumberUtilTest#testParseExtensions()}. */ 19052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia public void testFindExtensions() throws Exception { 191ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("03 331 6005 ext 3456", RegionCode.NZ); 192ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("03-3316005x3456", RegionCode.NZ); 193ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("03-3316005 int.3456", RegionCode.NZ); 194ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("03 3316005 #3456", RegionCode.NZ); 195ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("0~0 1800 7493 524", RegionCode.PL); 196ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("(1800) 7493.524", RegionCode.US); 19752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // Check that the last instance of an extension token is matched. 198ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("0~0 1800 7493 524 ~1234", RegionCode.PL); 19952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // Verifying bug-fix where the last digit of a number was previously omitted if it was a 0 when 20052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // extracting the extension. Also verifying a few different cases of extensions. 201ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("+44 2034567890x456", RegionCode.NZ); 202ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("+44 2034567890x456", RegionCode.GB); 203ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("+44 2034567890 x456", RegionCode.GB); 204ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("+44 2034567890 X456", RegionCode.GB); 205ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("+44 2034567890 X 456", RegionCode.GB); 206ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("+44 2034567890 X 456", RegionCode.GB); 207ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("+44 2034567890 X 456", RegionCode.GB); 208ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia 209ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("(800) 901-3355 x 7246433", RegionCode.US); 210ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("(800) 901-3355 , ext 7246433", RegionCode.US); 211ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("(800) 901-3355 ,extension 7246433", RegionCode.US); 212f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia // The next test differs from PhoneNumberUtil -> when matching we don't consider a lone comma to 213f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia // indicate an extension, although we accept it when parsing. 214ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("(800) 901-3355 ,x 7246433", RegionCode.US); 215ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("(800) 901-3355 ext: 7246433", RegionCode.US); 21652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 21752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 21852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia public void testFindInterspersedWithSpace() throws Exception { 219ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia doTestFindInContext("0 3 3 3 1 6 0 0 5", RegionCode.NZ); 22052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 22152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 22252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia /** 22352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * Test matching behavior when starting in the middle of a phone number. 22452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia */ 22552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia public void testIntermediateParsePositions() throws Exception { 22652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia String text = "Call 033316005 or 032316005!"; 22752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // | | | | | | 22852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // 0 5 10 15 20 25 22952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 23052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // Iterate over all possible indices. 23152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia for (int i = 0; i <= 5; i++) { 23252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertEqualRange(text, i, 5, 14); 23352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 23452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // 7 and 8 digits in a row are still parsed as number. 23552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertEqualRange(text, 6, 6, 14); 23652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertEqualRange(text, 7, 7, 14); 23752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // Anything smaller is skipped to the second instance. 23852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia for (int i = 8; i <= 19; i++) { 23952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertEqualRange(text, i, 19, 28); 24052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 24152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 24252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 243b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia public void testFourMatchesInARow() throws Exception { 244b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia String number1 = "415-666-7777"; 245b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia String number2 = "800-443-1223"; 246b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia String number3 = "212-443-1223"; 247b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia String number4 = "650-443-1223"; 248b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia String text = number1 + " - " + number2 + " - " + number3 + " - " + number4; 249b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia 250b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia Iterator<PhoneNumberMatch> iterator = 251b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia phoneUtil.findNumbers(text, RegionCode.US).iterator(); 252b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia PhoneNumberMatch match = iterator.hasNext() ? iterator.next() : null; 253b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia assertMatchProperties(match, text, number1, RegionCode.US); 254b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia 255b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia match = iterator.hasNext() ? iterator.next() : null; 256b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia assertMatchProperties(match, text, number2, RegionCode.US); 257b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia 258b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia match = iterator.hasNext() ? iterator.next() : null; 259b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia assertMatchProperties(match, text, number3, RegionCode.US); 260b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia 261b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia match = iterator.hasNext() ? iterator.next() : null; 262b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia assertMatchProperties(match, text, number4, RegionCode.US); 263b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia } 264b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia 265b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia public void testMatchesFoundWithMultipleSpaces() throws Exception { 266b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia String number1 = "(415) 666-7777"; 267b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia String number2 = "(800) 443-1223"; 268b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia String text = number1 + " " + number2; 269b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia 270b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia Iterator<PhoneNumberMatch> iterator = 271b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia phoneUtil.findNumbers(text, RegionCode.US).iterator(); 272b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia PhoneNumberMatch match = iterator.hasNext() ? iterator.next() : null; 273b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia assertMatchProperties(match, text, number1, RegionCode.US); 274b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia 275b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia match = iterator.hasNext() ? iterator.next() : null; 276b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia assertMatchProperties(match, text, number2, RegionCode.US); 277b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia } 278b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia 279372bff8dd464574d36737d47e495cad14346653cShaopeng Jia public void testMatchWithSurroundingZipcodes() throws Exception { 280372bff8dd464574d36737d47e495cad14346653cShaopeng Jia String number = "415-666-7777"; 281f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia String zipPreceding = "My address is CA 34215 - " + number + " is my number."; 282372bff8dd464574d36737d47e495cad14346653cShaopeng Jia 283f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia Iterator<PhoneNumberMatch> iterator = 284ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia phoneUtil.findNumbers(zipPreceding, RegionCode.US).iterator(); 285372bff8dd464574d36737d47e495cad14346653cShaopeng Jia PhoneNumberMatch match = iterator.hasNext() ? iterator.next() : null; 286b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia assertMatchProperties(match, zipPreceding, number, RegionCode.US); 287372bff8dd464574d36737d47e495cad14346653cShaopeng Jia 288372bff8dd464574d36737d47e495cad14346653cShaopeng Jia // Now repeat, but this time the phone number has spaces in it. It should still be found. 289372bff8dd464574d36737d47e495cad14346653cShaopeng Jia number = "(415) 666 7777"; 290372bff8dd464574d36737d47e495cad14346653cShaopeng Jia 291372bff8dd464574d36737d47e495cad14346653cShaopeng Jia String zipFollowing = "My number is " + number + ". 34215 is my zip-code."; 292ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia iterator = phoneUtil.findNumbers(zipFollowing, RegionCode.US).iterator(); 293372bff8dd464574d36737d47e495cad14346653cShaopeng Jia PhoneNumberMatch matchWithSpaces = iterator.hasNext() ? iterator.next() : null; 294b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia assertMatchProperties(matchWithSpaces, zipFollowing, number, RegionCode.US); 295372bff8dd464574d36737d47e495cad14346653cShaopeng Jia } 296372bff8dd464574d36737d47e495cad14346653cShaopeng Jia 297d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia public void testIsLatinLetter() throws Exception { 298d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia assertTrue(PhoneNumberMatcher.isLatinLetter('c')); 299d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia assertTrue(PhoneNumberMatcher.isLatinLetter('C')); 300d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia assertTrue(PhoneNumberMatcher.isLatinLetter('\u00C9')); 301d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia assertTrue(PhoneNumberMatcher.isLatinLetter('\u0301')); // Combining acute accent 302d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia // Punctuation, digits and white-space are not considered "latin letters". 303d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia assertFalse(PhoneNumberMatcher.isLatinLetter(':')); 304d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia assertFalse(PhoneNumberMatcher.isLatinLetter('5')); 305d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia assertFalse(PhoneNumberMatcher.isLatinLetter('-')); 306d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia assertFalse(PhoneNumberMatcher.isLatinLetter('.')); 307d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia assertFalse(PhoneNumberMatcher.isLatinLetter(' ')); 308d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia assertFalse(PhoneNumberMatcher.isLatinLetter('\u6211')); // Chinese character 309b210e301245cb5dc90aa3142f378632bd41cb172Shaopeng Jia assertFalse(PhoneNumberMatcher.isLatinLetter('\u306E')); // Hiragana letter no 310d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia } 311d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia 312d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia public void testMatchesWithSurroundingLatinChars() throws Exception { 313f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia ArrayList<NumberContext> possibleOnlyContexts = new ArrayList<NumberContext>(); 314f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia possibleOnlyContexts.add(new NumberContext("abc", "def")); 315f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia possibleOnlyContexts.add(new NumberContext("abc", "")); 316f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia possibleOnlyContexts.add(new NumberContext("", "def")); 317f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia // Latin capital letter e with an acute accent. 318f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia possibleOnlyContexts.add(new NumberContext("\u00C9", "")); 319f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia // e with an acute accent decomposed (with combining mark). 320f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia possibleOnlyContexts.add(new NumberContext("e\u0301", "")); 321d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia 322d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia // Numbers should not be considered valid, if they are surrounded by Latin characters, but 323d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia // should be considered possible. 324f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia findMatchesInContexts(possibleOnlyContexts, false, true); 325f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia } 326f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia 327f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia public void testMoneyNotSeenAsPhoneNumber() throws Exception { 328f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia ArrayList<NumberContext> possibleOnlyContexts = new ArrayList<NumberContext>(); 329f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia possibleOnlyContexts.add(new NumberContext("$", "")); 330f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia possibleOnlyContexts.add(new NumberContext("", "$")); 331f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia possibleOnlyContexts.add(new NumberContext("\u00A3", "")); // Pound sign 332f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia possibleOnlyContexts.add(new NumberContext("\u00A5", "")); // Yen sign 333f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia findMatchesInContexts(possibleOnlyContexts, false, true); 33496a7214cdabf08f53f5b1a560304601c9f65e0b9Shaopeng Jia } 33596a7214cdabf08f53f5b1a560304601c9f65e0b9Shaopeng Jia 33696a7214cdabf08f53f5b1a560304601c9f65e0b9Shaopeng Jia public void testPercentageNotSeenAsPhoneNumber() throws Exception { 33796a7214cdabf08f53f5b1a560304601c9f65e0b9Shaopeng Jia ArrayList<NumberContext> possibleOnlyContexts = new ArrayList<NumberContext>(); 33896a7214cdabf08f53f5b1a560304601c9f65e0b9Shaopeng Jia possibleOnlyContexts.add(new NumberContext("", "%")); 33996a7214cdabf08f53f5b1a560304601c9f65e0b9Shaopeng Jia // Numbers followed by % should be dropped. 34096a7214cdabf08f53f5b1a560304601c9f65e0b9Shaopeng Jia findMatchesInContexts(possibleOnlyContexts, false, true); 341f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia } 342f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia 343f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia public void testPhoneNumberWithLeadingOrTrailingMoneyMatches() throws Exception { 344f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia // Because of the space after the 20 (or before the 100) these dollar amounts should not stop 345f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia // the actual number from being found. 346f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia ArrayList<NumberContext> contexts = new ArrayList<NumberContext>(); 347f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia contexts.add(new NumberContext("$20 ", "")); 348f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia contexts.add(new NumberContext("", " 100$")); 349f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia findMatchesInContexts(contexts, true, true); 350d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia } 351d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia 352d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia public void testMatchesWithSurroundingLatinCharsAndLeadingPunctuation() throws Exception { 353d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia // Contexts with trailing characters. Leading characters are okay here since the numbers we will 354d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia // insert start with punctuation, but trailing characters are still not allowed. 355f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia ArrayList<NumberContext> possibleOnlyContexts = new ArrayList<NumberContext>(); 356d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia possibleOnlyContexts.add(new NumberContext("abc", "def")); 357d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia possibleOnlyContexts.add(new NumberContext("", "def")); 358d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia possibleOnlyContexts.add(new NumberContext("", "\u00C9")); 359d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia 360d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia // Numbers should not be considered valid, if they have trailing Latin characters, but should be 361d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia // considered possible. 362d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia String numberWithPlus = "+14156667777"; 363d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia String numberWithBrackets = "(415)6667777"; 364ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia findMatchesInContexts(possibleOnlyContexts, false, true, RegionCode.US, numberWithPlus); 365ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia findMatchesInContexts(possibleOnlyContexts, false, true, RegionCode.US, numberWithBrackets); 366d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia 367f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia ArrayList<NumberContext> validContexts = new ArrayList<NumberContext>(); 368d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia validContexts.add(new NumberContext("abc", "")); 369d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia validContexts.add(new NumberContext("\u00C9", "")); 370d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia validContexts.add(new NumberContext("\u00C9", ".")); // Trailing punctuation. 371d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia validContexts.add(new NumberContext("\u00C9", " def")); // Trailing white-space. 372d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia 373d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia // Numbers should be considered valid, since they start with punctuation. 374ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia findMatchesInContexts(validContexts, true, true, RegionCode.US, numberWithPlus); 375ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia findMatchesInContexts(validContexts, true, true, RegionCode.US, numberWithBrackets); 376d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia } 377d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia 378d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia public void testMatchesWithSurroundingChineseChars() throws Exception { 379f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia ArrayList<NumberContext> validContexts = new ArrayList<NumberContext>(); 380d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia validContexts.add(new NumberContext("\u6211\u7684\u7535\u8BDD\u53F7\u7801\u662F", "")); 381d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia validContexts.add(new NumberContext("", "\u662F\u6211\u7684\u7535\u8BDD\u53F7\u7801")); 382d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia validContexts.add(new NumberContext("\u8BF7\u62E8\u6253", "\u6211\u5728\u660E\u5929")); 383d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia 384d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia // Numbers should be considered valid, since they are surrounded by Chinese. 385d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia findMatchesInContexts(validContexts, true, true); 386d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia } 387d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia 388d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia public void testMatchesWithSurroundingPunctuation() throws Exception { 389f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia ArrayList<NumberContext> validContexts = new ArrayList<NumberContext>(); 390d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia validContexts.add(new NumberContext("My number-", "")); // At end of text. 391d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia validContexts.add(new NumberContext("", ".Nice day.")); // At start of text. 392d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia validContexts.add(new NumberContext("Tel:", ".")); // Punctuation surrounds number. 393d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia validContexts.add(new NumberContext("Tel: ", " on Saturdays.")); // White-space is also fine. 394d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia 395d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia // Numbers should be considered valid, since they are surrounded by punctuation. 396d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia findMatchesInContexts(validContexts, true, true); 397d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia } 398d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia 399f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia public void testMatchesMultiplePhoneNumbersSeparatedByPhoneNumberPunctuation() throws Exception { 400f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia String text = "Call 650-253-4561 -- 455-234-3451"; 401ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia String region = RegionCode.US; 402f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia 403f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia PhoneNumber number1 = new PhoneNumber(); 404f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia number1.setCountryCode(phoneUtil.getCountryCodeForRegion(region)); 405f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia number1.setNationalNumber(6502534561L); 406f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia PhoneNumberMatch match1 = new PhoneNumberMatch(5, "650-253-4561", number1); 407f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia 408f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia PhoneNumber number2 = new PhoneNumber(); 409f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia number2.setCountryCode(phoneUtil.getCountryCodeForRegion(region)); 410f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia number2.setNationalNumber(4552343451L); 411f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia PhoneNumberMatch match2 = new PhoneNumberMatch(21, "455-234-3451", number2); 412f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia 413f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia Iterator<PhoneNumberMatch> matches = phoneUtil.findNumbers(text, region).iterator(); 414f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia assertEquals(match1, matches.next()); 415f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia assertEquals(match2, matches.next()); 416f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia } 417f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia 418f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia public void testDoesNotMatchMultiplePhoneNumbersSeparatedWithNoWhiteSpace() throws Exception { 419f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia // No white-space found between numbers - neither is found. 420f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia String text = "Call 650-253-4561--455-234-3451"; 421ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia String region = RegionCode.US; 422f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia 423f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia assertTrue(hasNoMatches(phoneUtil.findNumbers(text, region))); 424f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia } 425f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia 426f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia /** 427f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia * Strings with number-like things that shouldn't be found under any level. 428f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia */ 429f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia private static final NumberTest[] IMPOSSIBLE_CASES = { 430ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("12345", RegionCode.US), 431ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("23456789", RegionCode.US), 432ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("234567890112", RegionCode.US), 433ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("650+253+1234", RegionCode.US), 434ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("3/10/1984", RegionCode.CA), 435ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("03/27/2011", RegionCode.US), 436ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("31/8/2011", RegionCode.US), 437ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("1/12/2011", RegionCode.US), 438ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("10/12/82", RegionCode.DE), 439528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia new NumberTest("650x2531234", RegionCode.US), 440cc0ae7326023c5da91dd9a84035c3dc3f6cc372fShaopeng Jia new NumberTest("2012-01-02 08:00", RegionCode.US), 441cc0ae7326023c5da91dd9a84035c3dc3f6cc372fShaopeng Jia new NumberTest("2012/01/02 08:00", RegionCode.US), 442cc0ae7326023c5da91dd9a84035c3dc3f6cc372fShaopeng Jia new NumberTest("20120102 08:00", RegionCode.US), 4437a81979b0076f18b31b47b7df2beac29735f3a37Cecilia Roes new NumberTest("2014-04-12 04:04 PM", RegionCode.US), 4447a81979b0076f18b31b47b7df2beac29735f3a37Cecilia Roes new NumberTest("2014-04-12 04:04 PM", RegionCode.US), 4457a81979b0076f18b31b47b7df2beac29735f3a37Cecilia Roes new NumberTest("2014-04-12 04:04 PM", RegionCode.US), 4467a81979b0076f18b31b47b7df2beac29735f3a37Cecilia Roes new NumberTest("2014-04-12 04:04 PM", RegionCode.US), 447f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia }; 448f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia 449f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia /** 450f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia * Strings with number-like things that should only be found under "possible". 451f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia */ 452f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia private static final NumberTest[] POSSIBLE_ONLY_CASES = { 453f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia // US numbers cannot start with 7 in the test metadata to be valid. 454ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("7121115678", RegionCode.US), 455f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia // 'X' should not be found in numbers at leniencies stricter than POSSIBLE, unless it represents 456f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia // a carrier code or extension. 457ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("1650 x 253 - 1234", RegionCode.US), 458ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("650 x 253 - 1234", RegionCode.US), 459528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia new NumberTest("6502531x234", RegionCode.US), 460a48b2d221ba46df7446d1a87244efa985e8e292fShaopeng Jia new NumberTest("(20) 3346 1234", RegionCode.GB), // Non-optional NP omitted 461f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia }; 462f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia 463f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia /** 464f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia * Strings with number-like things that should only be found up to and including the "valid" 465f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia * leniency level. 466f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia */ 467f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia private static final NumberTest[] VALID_CASES = { 468528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia new NumberTest("65 02 53 00 00", RegionCode.US), 469ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("6502 538365", RegionCode.US), 470ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("650//253-1234", RegionCode.US), // 2 slashes are illegal at higher levels 471ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("650/253/1234", RegionCode.US), 472ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("9002309. 158", RegionCode.US), 473528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia new NumberTest("12 7/8 - 14 12/34 - 5", RegionCode.US), 474ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("12.1 - 23.71 - 23.45", RegionCode.US), 475ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("800 234 1 111x1111", RegionCode.US), 476528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia new NumberTest("1979-2011 100", RegionCode.US), 477ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("+494949-4-94", RegionCode.DE), // National number in wrong format 478528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia new NumberTest("\uFF14\uFF11\uFF15\uFF16\uFF16\uFF16\uFF16-\uFF17\uFF17\uFF17", RegionCode.US), 479cc0ae7326023c5da91dd9a84035c3dc3f6cc372fShaopeng Jia new NumberTest("2012-0102 08", RegionCode.US), // Very strange formatting. 480cc0ae7326023c5da91dd9a84035c3dc3f6cc372fShaopeng Jia new NumberTest("2012-01-02 08", RegionCode.US), 4814b867acb917b73e699a596df94445c634c916519Shaopeng Jia // Breakdown assistance number with unexpected formatting. 4824b867acb917b73e699a596df94445c634c916519Shaopeng Jia new NumberTest("1800-1-0-10 22", RegionCode.AU), 4834b867acb917b73e699a596df94445c634c916519Shaopeng Jia new NumberTest("030-3-2 23 12 34", RegionCode.DE), 4844b867acb917b73e699a596df94445c634c916519Shaopeng Jia new NumberTest("03 0 -3 2 23 12 34", RegionCode.DE), 4854b867acb917b73e699a596df94445c634c916519Shaopeng Jia new NumberTest("(0)3 0 -3 2 23 12 34", RegionCode.DE), 4864b867acb917b73e699a596df94445c634c916519Shaopeng Jia new NumberTest("0 3 0 -3 2 23 12 34", RegionCode.DE), 487f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia }; 488f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia 489f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia /** 490f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia * Strings with number-like things that should only be found up to and including the 491f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia * "strict_grouping" leniency level. 492f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia */ 493f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia private static final NumberTest[] STRICT_GROUPING_CASES = { 494ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("(415) 6667777", RegionCode.US), 495ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("415-6667777", RegionCode.US), 496f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia // Should be found by strict grouping but not exact grouping, as the last two groups are 497f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia // formatted together as a block. 498a48b2d221ba46df7446d1a87244efa985e8e292fShaopeng Jia new NumberTest("0800-2491234", RegionCode.DE), 4994b867acb917b73e699a596df94445c634c916519Shaopeng Jia // Doesn't match any formatting in the test file, but almost matches an alternate format (the 5004b867acb917b73e699a596df94445c634c916519Shaopeng Jia // last two groups have been squashed together here). 5014b867acb917b73e699a596df94445c634c916519Shaopeng Jia new NumberTest("0900-1 123123", RegionCode.DE), 5024b867acb917b73e699a596df94445c634c916519Shaopeng Jia new NumberTest("(0)900-1 123123", RegionCode.DE), 5034b867acb917b73e699a596df94445c634c916519Shaopeng Jia new NumberTest("0 900-1 123123", RegionCode.DE), 504f9768eb3c8f303725fb4f899598481cbc4fb76a3Shaopeng Jia // NDC also found as part of the country calling code; this shouldn't ruin the grouping 505f9768eb3c8f303725fb4f899598481cbc4fb76a3Shaopeng Jia // expectations. 506f9768eb3c8f303725fb4f899598481cbc4fb76a3Shaopeng Jia new NumberTest("+33 3 34 2312", RegionCode.FR), 507f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia }; 508f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia 509f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia /** 510b210e301245cb5dc90aa3142f378632bd41cb172Shaopeng Jia * Strings with number-like things that should be found at all levels. 511f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia */ 512f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia private static final NumberTest[] EXACT_GROUPING_CASES = { 513ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("\uFF14\uFF11\uFF15\uFF16\uFF16\uFF16\uFF17\uFF17\uFF17\uFF17", RegionCode.US), 514ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("\uFF14\uFF11\uFF15-\uFF16\uFF16\uFF16-\uFF17\uFF17\uFF17\uFF17", RegionCode.US), 515ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("4156667777", RegionCode.US), 516ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("4156667777 x 123", RegionCode.US), 517ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("415-666-7777", RegionCode.US), 518ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("415/666-7777", RegionCode.US), 519ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("415-666-7777 ext. 503", RegionCode.US), 520ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("1 415 666 7777 x 123", RegionCode.US), 521ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("+1 415-666-7777", RegionCode.US), 522ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("+494949 49", RegionCode.DE), 523ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("+49-49-34", RegionCode.DE), 524ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("+49-4931-49", RegionCode.DE), 525ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("04931-49", RegionCode.DE), // With National Prefix 526ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("+49-494949", RegionCode.DE), // One group with country code 527ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("+49-494949 ext. 49", RegionCode.DE), 528ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("+49494949 ext. 49", RegionCode.DE), 529ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("0494949", RegionCode.DE), 530ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia new NumberTest("0494949 ext. 49", RegionCode.DE), 531a48b2d221ba46df7446d1a87244efa985e8e292fShaopeng Jia new NumberTest("01 (33) 3461 2234", RegionCode.MX), // Optional NP present 532a48b2d221ba46df7446d1a87244efa985e8e292fShaopeng Jia new NumberTest("(33) 3461 2234", RegionCode.MX), // Optional NP omitted 5334b867acb917b73e699a596df94445c634c916519Shaopeng Jia new NumberTest("1800-10-10 22", RegionCode.AU), // Breakdown assistance number. 5344b867acb917b73e699a596df94445c634c916519Shaopeng Jia // Doesn't match any formatting in the test file, but matches an alternate format exactly. 5354b867acb917b73e699a596df94445c634c916519Shaopeng Jia new NumberTest("0900-1 123 123", RegionCode.DE), 5364b867acb917b73e699a596df94445c634c916519Shaopeng Jia new NumberTest("(0)900-1 123 123", RegionCode.DE), 5374b867acb917b73e699a596df94445c634c916519Shaopeng Jia new NumberTest("0 900-1 123 123", RegionCode.DE), 538f9768eb3c8f303725fb4f899598481cbc4fb76a3Shaopeng Jia new NumberTest("+33 3 34 23 12", RegionCode.FR), 539f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia }; 540f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia 541528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia public void testMatchesWithPossibleLeniency() throws Exception { 542528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia List<NumberTest> testCases = new ArrayList<NumberTest>(); 543528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia testCases.addAll(Arrays.asList(STRICT_GROUPING_CASES)); 544528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia testCases.addAll(Arrays.asList(EXACT_GROUPING_CASES)); 545528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia testCases.addAll(Arrays.asList(VALID_CASES)); 546528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia testCases.addAll(Arrays.asList(POSSIBLE_ONLY_CASES)); 547528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia doTestNumberMatchesForLeniency(testCases, Leniency.POSSIBLE); 548528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia } 549528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia 550528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia public void testNonMatchesWithPossibleLeniency() throws Exception { 551528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia List<NumberTest> testCases = new ArrayList<NumberTest>(); 552528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia testCases.addAll(Arrays.asList(IMPOSSIBLE_CASES)); 553528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia doTestNumberNonMatchesForLeniency(testCases, Leniency.POSSIBLE); 554528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia } 555528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia 556528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia public void testMatchesWithValidLeniency() throws Exception { 557528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia List<NumberTest> testCases = new ArrayList<NumberTest>(); 558528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia testCases.addAll(Arrays.asList(STRICT_GROUPING_CASES)); 559528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia testCases.addAll(Arrays.asList(EXACT_GROUPING_CASES)); 560528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia testCases.addAll(Arrays.asList(VALID_CASES)); 561528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia doTestNumberMatchesForLeniency(testCases, Leniency.VALID); 562528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia } 563528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia 564528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia public void testNonMatchesWithValidLeniency() throws Exception { 565528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia List<NumberTest> testCases = new ArrayList<NumberTest>(); 566528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia testCases.addAll(Arrays.asList(IMPOSSIBLE_CASES)); 567528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia testCases.addAll(Arrays.asList(POSSIBLE_ONLY_CASES)); 568528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia doTestNumberNonMatchesForLeniency(testCases, Leniency.VALID); 569528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia } 570528b0d12a556ff0c2d16f99d56fcdd62657f433cShaopeng Jia 571f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia public void testMatchesWithStrictGroupingLeniency() throws Exception { 572f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia List<NumberTest> testCases = new ArrayList<NumberTest>(); 573f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia testCases.addAll(Arrays.asList(STRICT_GROUPING_CASES)); 574f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia testCases.addAll(Arrays.asList(EXACT_GROUPING_CASES)); 575f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia doTestNumberMatchesForLeniency(testCases, Leniency.STRICT_GROUPING); 576f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia } 577f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia 578f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia public void testNonMatchesWithStrictGroupLeniency() throws Exception { 579f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia List<NumberTest> testCases = new ArrayList<NumberTest>(); 580ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia testCases.addAll(Arrays.asList(IMPOSSIBLE_CASES)); 581f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia testCases.addAll(Arrays.asList(POSSIBLE_ONLY_CASES)); 582f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia testCases.addAll(Arrays.asList(VALID_CASES)); 583f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia doTestNumberNonMatchesForLeniency(testCases, Leniency.STRICT_GROUPING); 584f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia } 585f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia 586f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia public void testMatchesWithExactGroupingLeniency() throws Exception { 587f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia List<NumberTest> testCases = new ArrayList<NumberTest>(); 588f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia testCases.addAll(Arrays.asList(EXACT_GROUPING_CASES)); 589f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia doTestNumberMatchesForLeniency(testCases, Leniency.EXACT_GROUPING); 590f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia } 591f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia 592f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia public void testNonMatchesExactGroupLeniency() throws Exception { 593f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia List<NumberTest> testCases = new ArrayList<NumberTest>(); 594ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia testCases.addAll(Arrays.asList(IMPOSSIBLE_CASES)); 595f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia testCases.addAll(Arrays.asList(POSSIBLE_ONLY_CASES)); 596f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia testCases.addAll(Arrays.asList(VALID_CASES)); 597f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia testCases.addAll(Arrays.asList(STRICT_GROUPING_CASES)); 598f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia doTestNumberNonMatchesForLeniency(testCases, Leniency.EXACT_GROUPING); 599f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia } 600f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia 601bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia private void doTestNumberMatchesForLeniency(List<NumberTest> testCases, Leniency leniency) { 602f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia int noMatchFoundCount = 0; 603f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia int wrongMatchFoundCount = 0; 604f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia for (NumberTest test : testCases) { 605f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia Iterator<PhoneNumberMatch> iterator = 606f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia findNumbersForLeniency(test.rawString, test.region, leniency); 607f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia PhoneNumberMatch match = iterator.hasNext() ? iterator.next() : null; 608f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia if (match == null) { 609f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia noMatchFoundCount++; 610f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia System.err.println("No match found in " + test.toString() + " for leniency: " + leniency); 611f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia } else { 612f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia if (!test.rawString.equals(match.rawString())) { 613f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia wrongMatchFoundCount++; 614f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia System.err.println("Found wrong match in test " + test.toString() + 615f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia ". Found " + match.rawString()); 616f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia } 617f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia } 618f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia } 619f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia assertEquals(0, noMatchFoundCount); 620f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia assertEquals(0, wrongMatchFoundCount); 621f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia } 622f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia 623bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia private void doTestNumberNonMatchesForLeniency(List<NumberTest> testCases, Leniency leniency) { 624f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia int matchFoundCount = 0; 625f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia for (NumberTest test : testCases) { 626f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia Iterator<PhoneNumberMatch> iterator = 627f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia findNumbersForLeniency(test.rawString, test.region, leniency); 628f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia PhoneNumberMatch match = iterator.hasNext() ? iterator.next() : null; 629f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia if (match != null) { 630f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia matchFoundCount++; 631f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia System.err.println("Match found in " + test.toString() + " for leniency: " + leniency); 632f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia } 633f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia } 634f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia assertEquals(0, matchFoundCount); 635f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia } 636f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia 637d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia /** 638d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia * Helper method which tests the contexts provided and ensures that: 639d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia * -- if isValid is true, they all find a test number inserted in the middle when leniency of 640d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia * matching is set to VALID; else no test number should be extracted at that leniency level 641d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia * -- if isPossible is true, they all find a test number inserted in the middle when leniency of 642d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia * matching is set to POSSIBLE; else no test number should be extracted at that leniency level 643d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia */ 644d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia private void findMatchesInContexts(List<NumberContext> contexts, boolean isValid, 645d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia boolean isPossible, String region, String number) { 646d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia if (isValid) { 647d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia doTestInContext(number, region, contexts, Leniency.VALID); 648d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia } else { 649d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia for (NumberContext context : contexts) { 650d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia String text = context.leadingText + number + context.trailingText; 651d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia assertTrue("Should not have found a number in " + text, 652d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia hasNoMatches(phoneUtil.findNumbers(text, region))); 653d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia } 654d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia } 655d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia if (isPossible) { 656d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia doTestInContext(number, region, contexts, Leniency.POSSIBLE); 657d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia } else { 658d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia for (NumberContext context : contexts) { 659d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia String text = context.leadingText + number + context.trailingText; 660d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia assertTrue("Should not have found a number in " + text, 661d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia hasNoMatches(phoneUtil.findNumbers(text, region, Leniency.POSSIBLE, 662d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia Long.MAX_VALUE))); 663d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia } 664d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia } 665d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia } 666d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia 667d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia /** 668d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia * Variant of findMatchesInContexts that uses a default number and region. 669d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia */ 670d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia private void findMatchesInContexts(List<NumberContext> contexts, boolean isValid, 671d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia boolean isPossible) { 672ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia String region = RegionCode.US; 673d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia String number = "415-666-7777"; 674d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia 675d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia findMatchesInContexts(contexts, isValid, isPossible, region, number); 676d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia } 677d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia 678372bff8dd464574d36737d47e495cad14346653cShaopeng Jia public void testNonMatchingBracketsAreInvalid() throws Exception { 679372bff8dd464574d36737d47e495cad14346653cShaopeng Jia // The digits up to the ", " form a valid US number, but it shouldn't be matched as one since 680372bff8dd464574d36737d47e495cad14346653cShaopeng Jia // there was a non-matching bracket present. 681372bff8dd464574d36737d47e495cad14346653cShaopeng Jia assertTrue(hasNoMatches(phoneUtil.findNumbers( 682ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia "80.585 [79.964, 81.191]", RegionCode.US))); 683372bff8dd464574d36737d47e495cad14346653cShaopeng Jia 684372bff8dd464574d36737d47e495cad14346653cShaopeng Jia // The trailing "]" is thrown away before parsing, so the resultant number, while a valid US 685372bff8dd464574d36737d47e495cad14346653cShaopeng Jia // number, does not have matching brackets. 686372bff8dd464574d36737d47e495cad14346653cShaopeng Jia assertTrue(hasNoMatches(phoneUtil.findNumbers( 687ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia "80.585 [79.964]", RegionCode.US))); 688372bff8dd464574d36737d47e495cad14346653cShaopeng Jia 689372bff8dd464574d36737d47e495cad14346653cShaopeng Jia assertTrue(hasNoMatches(phoneUtil.findNumbers( 690ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia "80.585 ((79.964)", RegionCode.US))); 691372bff8dd464574d36737d47e495cad14346653cShaopeng Jia 692372bff8dd464574d36737d47e495cad14346653cShaopeng Jia // This case has too many sets of brackets to be valid. 693372bff8dd464574d36737d47e495cad14346653cShaopeng Jia assertTrue(hasNoMatches(phoneUtil.findNumbers( 694ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia "(80).(585) (79).(9)64", RegionCode.US))); 695372bff8dd464574d36737d47e495cad14346653cShaopeng Jia } 696372bff8dd464574d36737d47e495cad14346653cShaopeng Jia 69752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia public void testNoMatchIfRegionIsNull() throws Exception { 69852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // Fail on non-international prefix if region code is null. 69952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertTrue(hasNoMatches(phoneUtil.findNumbers( 70052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia "Random text body - number is 0331 6005, see you there", null))); 70152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 70252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 70352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia public void testNoMatchInEmptyString() throws Exception { 704ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia assertTrue(hasNoMatches(phoneUtil.findNumbers("", RegionCode.US))); 705ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia assertTrue(hasNoMatches(phoneUtil.findNumbers(" ", RegionCode.US))); 70652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 70752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 70852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia public void testNoMatchIfNoNumber() throws Exception { 70952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertTrue(hasNoMatches(phoneUtil.findNumbers( 710ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia "Random text body - number is foobar, see you there", RegionCode.US))); 71152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 71252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 71352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia public void testSequences() throws Exception { 71452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // Test multiple occurrences. 71552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia String text = "Call 033316005 or 032316005!"; 716ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia String region = RegionCode.NZ; 71752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 71852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia PhoneNumber number1 = new PhoneNumber(); 71952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia number1.setCountryCode(phoneUtil.getCountryCodeForRegion(region)); 72052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia number1.setNationalNumber(33316005); 72152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia PhoneNumberMatch match1 = new PhoneNumberMatch(5, "033316005", number1); 72252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 72352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia PhoneNumber number2 = new PhoneNumber(); 72452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia number2.setCountryCode(phoneUtil.getCountryCodeForRegion(region)); 72552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia number2.setNationalNumber(32316005); 72652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia PhoneNumberMatch match2 = new PhoneNumberMatch(19, "032316005", number2); 72752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 72852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia Iterator<PhoneNumberMatch> matches = 72952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia phoneUtil.findNumbers(text, region, Leniency.POSSIBLE, Long.MAX_VALUE).iterator(); 73052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 73152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertEquals(match1, matches.next()); 73252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertEquals(match2, matches.next()); 73352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 73452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 73552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia public void testNullInput() throws Exception { 736ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia assertTrue(hasNoMatches(phoneUtil.findNumbers(null, RegionCode.US))); 73752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertTrue(hasNoMatches(phoneUtil.findNumbers(null, null))); 73852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 73952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 74052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia public void testMaxMatches() throws Exception { 74152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // Set up text with 100 valid phone numbers. 74252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia StringBuilder numbers = new StringBuilder(); 74352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia for (int i = 0; i < 100; i++) { 74452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia numbers.append("My info: 415-666-7777,"); 74552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 74652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 74752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // Matches all 100. Max only applies to failed cases. 74852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia List<PhoneNumber> expected = new ArrayList<PhoneNumber>(100); 74952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia PhoneNumber number = phoneUtil.parse("+14156667777", null); 75052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia for (int i = 0; i < 100; i++) { 75152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia expected.add(number); 75252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 75352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 75452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia Iterable<PhoneNumberMatch> iterable = 755ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia phoneUtil.findNumbers(numbers.toString(), RegionCode.US, Leniency.VALID, 10); 75652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia List<PhoneNumber> actual = new ArrayList<PhoneNumber>(100); 75752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia for (PhoneNumberMatch match : iterable) { 75852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia actual.add(match.number()); 75952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 76052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertEquals(expected, actual); 76152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 76252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 76352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia public void testMaxMatchesInvalid() throws Exception { 76452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // Set up text with 10 invalid phone numbers followed by 100 valid. 76552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia StringBuilder numbers = new StringBuilder(); 76652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia for (int i = 0; i < 10; i++) { 76752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia numbers.append("My address 949-8945-0"); 76852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 76952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia for (int i = 0; i < 100; i++) { 77052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia numbers.append("My info: 415-666-7777,"); 77152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 77252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 77352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia Iterable<PhoneNumberMatch> iterable = 774ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia phoneUtil.findNumbers(numbers.toString(), RegionCode.US, Leniency.VALID, 10); 77552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertFalse(iterable.iterator().hasNext()); 77652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 77752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 77852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia public void testMaxMatchesMixed() throws Exception { 77952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // Set up text with 100 valid numbers inside an invalid number. 78052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia StringBuilder numbers = new StringBuilder(); 78152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia for (int i = 0; i < 100; i++) { 78252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia numbers.append("My info: 415-666-7777 123 fake street"); 78352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 78452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 785f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia // Only matches the first 10 despite there being 100 numbers due to max matches. 78652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia List<PhoneNumber> expected = new ArrayList<PhoneNumber>(100); 78752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia PhoneNumber number = phoneUtil.parse("+14156667777", null); 788f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia for (int i = 0; i < 10; i++) { 78952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia expected.add(number); 79052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 79152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 79252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia Iterable<PhoneNumberMatch> iterable = 793ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia phoneUtil.findNumbers(numbers.toString(), RegionCode.US, Leniency.VALID, 10); 79452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia List<PhoneNumber> actual = new ArrayList<PhoneNumber>(100); 79552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia for (PhoneNumberMatch match : iterable) { 79652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia actual.add(match.number()); 79752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 79852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertEquals(expected, actual); 79952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 80052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 801b0e21c22b1ca6b9aeb1426924cdf42a221c3d416Shaopeng Jia public void testNonPlusPrefixedNumbersNotFoundForInvalidRegion() throws Exception { 802b0e21c22b1ca6b9aeb1426924cdf42a221c3d416Shaopeng Jia // Does not start with a "+", we won't match it. 803b0e21c22b1ca6b9aeb1426924cdf42a221c3d416Shaopeng Jia Iterable<PhoneNumberMatch> iterable = phoneUtil.findNumbers("1 456 764 156", RegionCode.ZZ); 804b0e21c22b1ca6b9aeb1426924cdf42a221c3d416Shaopeng Jia Iterator<PhoneNumberMatch> iterator = iterable.iterator(); 805b0e21c22b1ca6b9aeb1426924cdf42a221c3d416Shaopeng Jia 806b0e21c22b1ca6b9aeb1426924cdf42a221c3d416Shaopeng Jia assertFalse(iterator.hasNext()); 807b0e21c22b1ca6b9aeb1426924cdf42a221c3d416Shaopeng Jia try { 808b0e21c22b1ca6b9aeb1426924cdf42a221c3d416Shaopeng Jia iterator.next(); 809b0e21c22b1ca6b9aeb1426924cdf42a221c3d416Shaopeng Jia fail("Violation of the Iterator contract."); 810b0e21c22b1ca6b9aeb1426924cdf42a221c3d416Shaopeng Jia } catch (NoSuchElementException e) { /* Success */ } 811b0e21c22b1ca6b9aeb1426924cdf42a221c3d416Shaopeng Jia assertFalse(iterator.hasNext()); 812b0e21c22b1ca6b9aeb1426924cdf42a221c3d416Shaopeng Jia } 813b0e21c22b1ca6b9aeb1426924cdf42a221c3d416Shaopeng Jia 81452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia public void testEmptyIteration() throws Exception { 815ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia Iterable<PhoneNumberMatch> iterable = phoneUtil.findNumbers("", RegionCode.ZZ); 81652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia Iterator<PhoneNumberMatch> iterator = iterable.iterator(); 81752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 81852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertFalse(iterator.hasNext()); 81952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertFalse(iterator.hasNext()); 82052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia try { 82152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia iterator.next(); 82252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia fail("Violation of the Iterator contract."); 82352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } catch (NoSuchElementException e) { /* Success */ } 82452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertFalse(iterator.hasNext()); 82552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 82652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 82752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia public void testSingleIteration() throws Exception { 828ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia Iterable<PhoneNumberMatch> iterable = phoneUtil.findNumbers("+14156667777", RegionCode.ZZ); 82952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 83052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // With hasNext() -> next(). 83152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia Iterator<PhoneNumberMatch> iterator = iterable.iterator(); 83252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // Double hasNext() to ensure it does not advance. 83352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertTrue(iterator.hasNext()); 83452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertTrue(iterator.hasNext()); 83552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertNotNull(iterator.next()); 83652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertFalse(iterator.hasNext()); 83752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia try { 83852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia iterator.next(); 83952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia fail("Violation of the Iterator contract."); 84052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } catch (NoSuchElementException e) { /* Success */ } 84152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertFalse(iterator.hasNext()); 84252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 84352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // With next() only. 84452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia iterator = iterable.iterator(); 84552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertNotNull(iterator.next()); 84652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia try { 84752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia iterator.next(); 84852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia fail("Violation of the Iterator contract."); 84952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } catch (NoSuchElementException e) { /* Success */ } 85052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 85152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 85252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia public void testDoubleIteration() throws Exception { 85352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia Iterable<PhoneNumberMatch> iterable = 854ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia phoneUtil.findNumbers("+14156667777 foobar +14156667777 ", RegionCode.ZZ); 85552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 85652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // With hasNext() -> next(). 85752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia Iterator<PhoneNumberMatch> iterator = iterable.iterator(); 85852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // Double hasNext() to ensure it does not advance. 85952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertTrue(iterator.hasNext()); 86052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertTrue(iterator.hasNext()); 86152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertNotNull(iterator.next()); 86252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertTrue(iterator.hasNext()); 86352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertTrue(iterator.hasNext()); 86452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertNotNull(iterator.next()); 86552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertFalse(iterator.hasNext()); 86652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia try { 86752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia iterator.next(); 86852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia fail("Violation of the Iterator contract."); 86952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } catch (NoSuchElementException e) { /* Success */ } 87052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertFalse(iterator.hasNext()); 87152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 87252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // With next() only. 87352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia iterator = iterable.iterator(); 87452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertNotNull(iterator.next()); 87552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertNotNull(iterator.next()); 87652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia try { 87752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia iterator.next(); 87852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia fail("Violation of the Iterator contract."); 87952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } catch (NoSuchElementException e) { /* Success */ } 88052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 88152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 88252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia /** 88352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * Ensures that {@link Iterator#remove()} is not supported and that calling it does not 88452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * change iteration behavior. 88552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia */ 88652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia public void testRemovalNotSupported() throws Exception { 887ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia Iterable<PhoneNumberMatch> iterable = phoneUtil.findNumbers("+14156667777", RegionCode.ZZ); 88852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 88952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia Iterator<PhoneNumberMatch> iterator = iterable.iterator(); 89052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia try { 89152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia iterator.remove(); 89252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia fail("Iterator must not support remove."); 89352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } catch (UnsupportedOperationException e) { /* success */ } 89452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 89552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertTrue(iterator.hasNext()); 89652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 89752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia try { 89852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia iterator.remove(); 89952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia fail("Iterator must not support remove."); 90052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } catch (UnsupportedOperationException e) { /* success */ } 90152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 90252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertNotNull(iterator.next()); 90352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 90452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia try { 90552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia iterator.remove(); 90652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia fail("Iterator must not support remove."); 90752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } catch (UnsupportedOperationException e) { /* success */ } 90852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 90952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertFalse(iterator.hasNext()); 91052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 911b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia 912b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia /** 913b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia * Asserts that the expected match is non-null, and that the raw string and expected 914b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia * proto buffer are set appropriately. 915b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia */ 916b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia private void assertMatchProperties( 917b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia PhoneNumberMatch match, String text, String number, String region) throws Exception { 918b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia PhoneNumber expectedResult = phoneUtil.parse(number, region); 919b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia assertNotNull("Did not find a number in '" + text + "'; expected " + number, match); 920b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia assertEquals(expectedResult, match.number()); 921b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia assertEquals(number, match.rawString()); 922b03a14984ad9b0d8b88337ca714cb831233b99c3Shaopeng Jia } 92352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 92452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia /** 92552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * Asserts that another number can be found in {@code text} starting at {@code index}, and that 92652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * its corresponding range is {@code [start, end)}. 92752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia */ 92852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia private void assertEqualRange(CharSequence text, int index, int start, int end) { 92952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia CharSequence sub = text.subSequence(index, text.length()); 93052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia Iterator<PhoneNumberMatch> matches = 931ca1e43d6e1fac07c7fc29c66c7da1fa9d7cf50f2Shaopeng Jia phoneUtil.findNumbers(sub, RegionCode.NZ, Leniency.POSSIBLE, Long.MAX_VALUE).iterator(); 93252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertTrue(matches.hasNext()); 93352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia PhoneNumberMatch match = matches.next(); 93452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertEquals(start - index, match.start()); 93552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertEquals(end - index, match.end()); 936f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia assertEquals(sub.subSequence(match.start(), match.end()).toString(), match.rawString()); 93752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 93852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 93952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia /** 940372bff8dd464574d36737d47e495cad14346653cShaopeng Jia * Tests numbers found by {@link PhoneNumberUtil#findNumbers(CharSequence, String)} in various 94152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * textual contexts. 94252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * 94352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * @param number the number to test and the corresponding region code to use 94452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia */ 94552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia private void doTestFindInContext(String number, String defaultCountry) throws Exception { 94652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia findPossibleInContext(number, defaultCountry); 94752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 94852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia PhoneNumber parsed = phoneUtil.parse(number, defaultCountry); 94952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia if (phoneUtil.isValidNumber(parsed)) { 95052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia findValidInContext(number, defaultCountry); 95152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 95252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 95352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 954d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia /** 955d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia * Tests valid numbers in contexts that should pass for {@link Leniency#POSSIBLE}. 956d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia */ 95752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia private void findPossibleInContext(String number, String defaultCountry) { 958f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia ArrayList<NumberContext> contextPairs = new ArrayList<NumberContext>(); 95952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia contextPairs.add(new NumberContext("", "")); // no context 96052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia contextPairs.add(new NumberContext(" ", "\t")); // whitespace only 96152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia contextPairs.add(new NumberContext("Hello ", "")); // no context at end 96252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia contextPairs.add(new NumberContext("", " to call me!")); // no context at start 96352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia contextPairs.add(new NumberContext("Hi there, call ", " to reach me!")); // no context at start 96452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia contextPairs.add(new NumberContext("Hi there, call ", ", or don't")); // with commas 96552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // Three examples without whitespace around the number. 96652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia contextPairs.add(new NumberContext("Hi call", "")); 96752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia contextPairs.add(new NumberContext("", "forme")); 96852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia contextPairs.add(new NumberContext("Hi call", "forme")); 96952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // With other small numbers. 97052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia contextPairs.add(new NumberContext("It's cheap! Call ", " before 6:30")); 97152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // With a second number later. 97252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia contextPairs.add(new NumberContext("Call ", " or +1800-123-4567!")); 9734b867acb917b73e699a596df94445c634c916519Shaopeng Jia contextPairs.add(new NumberContext("Call me on June 2 at", "")); // with a Month-Day date 97452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // With publication pages. 97552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia contextPairs.add(new NumberContext( 97652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia "As quoted by Alfonso 12-15 (2009), you may call me at ", "")); 97752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia contextPairs.add(new NumberContext( 97852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia "As quoted by Alfonso et al. 12-15 (2009), you may call me at ", "")); 979372bff8dd464574d36737d47e495cad14346653cShaopeng Jia // With dates, written in the American style. 980372bff8dd464574d36737d47e495cad14346653cShaopeng Jia contextPairs.add(new NumberContext( 981372bff8dd464574d36737d47e495cad14346653cShaopeng Jia "As I said on 03/10/2011, you may call me at ", "")); 982f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia // With trailing numbers after a comma. The 45 should not be considered an extension. 983f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia contextPairs.add(new NumberContext("", ", 45 days a year")); 984f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia // With a postfix stripped off as it looks like the start of another number. 98552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia contextPairs.add(new NumberContext("Call ", "/x12 more")); 98652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 98752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia doTestInContext(number, defaultCountry, contextPairs, Leniency.POSSIBLE); 98852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 98952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 99052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia /** 991d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia * Tests valid numbers in contexts that fail for {@link Leniency#POSSIBLE} but are valid for 992d1db4c508088ac27cb0815a222cf2600f16ad5b9Shaopeng Jia * {@link Leniency#VALID}. 99352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia */ 99452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia private void findValidInContext(String number, String defaultCountry) { 995f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia ArrayList<NumberContext> contextPairs = new ArrayList<NumberContext>(); 99652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // With other small numbers. 99752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia contextPairs.add(new NumberContext("It's only 9.99! Call ", " to buy")); 99852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // With a number Day.Month.Year date. 99952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia contextPairs.add(new NumberContext("Call me on 21.6.1984 at ", "")); 100052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // With a number Month/Day date. 100152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia contextPairs.add(new NumberContext("Call me on 06/21 at ", "")); 1002f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia // With a number Day.Month date. 100352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia contextPairs.add(new NumberContext("Call me on 21.6. at ", "")); 100452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // With a number Month/Day/Year date. 100552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia contextPairs.add(new NumberContext("Call me on 06/21/84 at ", "")); 1006f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia 100752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia doTestInContext(number, defaultCountry, contextPairs, Leniency.VALID); 100852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 100952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 101052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia private void doTestInContext(String number, String defaultCountry, 101152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia List<NumberContext> contextPairs, Leniency leniency) { 101252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia for (NumberContext context : contextPairs) { 101352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia String prefix = context.leadingText; 101452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia String text = prefix + number + context.trailingText; 101552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 101652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia int start = prefix.length(); 101752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia int end = start + number.length(); 1018f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia Iterator<PhoneNumberMatch> iterator = 1019f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia phoneUtil.findNumbers(text, defaultCountry, leniency, Long.MAX_VALUE).iterator(); 102052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 1021f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia PhoneNumberMatch match = iterator.hasNext() ? iterator.next() : null; 102252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertNotNull("Did not find a number in '" + text + "'; expected '" + number + "'", match); 102352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 102452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia CharSequence extracted = text.subSequence(match.start(), match.end()); 102552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertTrue("Unexpected phone region in '" + text + "'; extracted '" + extracted + "'", 102652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia start == match.start() && end == match.end()); 102752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertTrue(number.contentEquals(extracted)); 102852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia assertTrue(match.rawString().contentEquals(extracted)); 102952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 103052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia ensureTermination(text, defaultCountry, leniency); 103152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 103252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 103352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 103452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia /** 103552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * Exhaustively searches for phone numbers from each index within {@code text} to test that 103652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * finding matches always terminates. 103752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia */ 103852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia private void ensureTermination(String text, String defaultCountry, Leniency leniency) { 103952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia for (int index = 0; index <= text.length(); index++) { 104052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia String sub = text.substring(index); 1041372bff8dd464574d36737d47e495cad14346653cShaopeng Jia StringBuilder matches = new StringBuilder(); 104252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia // Iterates over all matches. 104352699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia for (PhoneNumberMatch match : 104452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia phoneUtil.findNumbers(sub, defaultCountry, leniency, Long.MAX_VALUE)) { 104552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia matches.append(", ").append(match.toString()); 104652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 104752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 104852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 104952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 1050f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia private Iterator<PhoneNumberMatch> findNumbersForLeniency( 1051bb78ce92eae2d5de9aa06b27ed3b87bc496c79eeShaopeng Jia String text, String defaultCountry, Leniency leniency) { 1052f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia return phoneUtil.findNumbers(text, defaultCountry, leniency, Long.MAX_VALUE).iterator(); 1053f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia } 1054f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia 105552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia private boolean hasNoMatches(Iterable<PhoneNumberMatch> iterable) { 105652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia return !iterable.iterator().hasNext(); 105752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 105852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 105952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia /** 106052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * Small class that holds the context of the number we are testing against. The test will 106152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia * insert the phone number to be found between leadingText and trailingText. 106252699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia */ 1063f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia private static class NumberContext { 106452699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia final String leadingText; 106552699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia final String trailingText; 106652699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia 106752699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia NumberContext(String leadingText, String trailingText) { 106852699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia this.leadingText = leadingText; 106952699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia this.trailingText = trailingText; 107052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 107152699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia } 1072f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia 1073f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia /** 1074f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia * Small class that holds the number we want to test and the region for which it should be valid. 1075f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia */ 1076f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia private static class NumberTest { 1077f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia final String rawString; 1078f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia final String region; 1079f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia 1080f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia NumberTest(String rawString, String regionCode) { 1081f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia this.rawString = rawString; 1082f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia this.region = regionCode; 1083f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia } 1084f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia 1085f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia @Override 1086f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia public String toString() { 1087f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia return rawString + " (" + region.toString() + ")"; 1088f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia } 1089f7e0224b862054893f28d2736b3f6804d9935886Shaopeng Jia } 109052699e08e855fb0957944b4e73358ad9e0007c0cShaopeng Jia} 1091