1 /*
2  * Copyright (C) 2009 The Libphonenumber Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.i18n.phonenumbers;
18 
19 import static org.junit.Assert.assertThrows;
20 
21 import com.google.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat;
22 import com.google.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberType;
23 import com.google.i18n.phonenumbers.PhoneNumberUtil.ValidationResult;
24 import com.google.i18n.phonenumbers.Phonemetadata.NumberFormat;
25 import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata;
26 import com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc;
27 import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
28 import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber.CountryCodeSource;
29 
30 import com.google.i18n.phonenumbers.metadata.source.MetadataSource;
31 import java.util.ArrayList;
32 import java.util.List;
33 import java.util.Set;
34 import org.junit.Assert;
35 import org.junit.function.ThrowingRunnable;
36 import org.mockito.Mockito;
37 
38 /**
39  * Unit tests for PhoneNumberUtil.java
40  *
41  * Note that these tests use the test metadata, not the normal metadata file, so should not be used
42  * for regression test purposes - these tests are illustrative only and test functionality.
43  *
44  * @author Shaopeng Jia
45  */
46 public class PhoneNumberUtilTest extends TestMetadataTestCase {
47   // Set up some test numbers to re-use.
48   // TODO: Rewrite this as static functions that return new numbers each time to avoid
49   // any risk of accidental changes to mutable static state affecting many tests.
50   private static final PhoneNumber ALPHA_NUMERIC_NUMBER =
51       new PhoneNumber().setCountryCode(1).setNationalNumber(80074935247L);
52   private static final PhoneNumber AE_UAN =
53       new PhoneNumber().setCountryCode(971).setNationalNumber(600123456L);
54   private static final PhoneNumber AR_MOBILE =
55       new PhoneNumber().setCountryCode(54).setNationalNumber(91187654321L);
56   private static final PhoneNumber AR_NUMBER =
57       new PhoneNumber().setCountryCode(54).setNationalNumber(1187654321);
58   private static final PhoneNumber AU_NUMBER =
59       new PhoneNumber().setCountryCode(61).setNationalNumber(236618300L);
60   private static final PhoneNumber BS_MOBILE =
61       new PhoneNumber().setCountryCode(1).setNationalNumber(2423570000L);
62   private static final PhoneNumber BS_NUMBER =
63       new PhoneNumber().setCountryCode(1).setNationalNumber(2423651234L);
64   private static final PhoneNumber CO_FIXED_LINE =
65       new PhoneNumber().setCountryCode(57).setNationalNumber(6012345678L);
66   // Note that this is the same as the example number for DE in the metadata.
67   private static final PhoneNumber DE_NUMBER =
68       new PhoneNumber().setCountryCode(49).setNationalNumber(30123456L);
69   private static final PhoneNumber DE_SHORT_NUMBER =
70       new PhoneNumber().setCountryCode(49).setNationalNumber(1234L);
71   private static final PhoneNumber GB_MOBILE =
72       new PhoneNumber().setCountryCode(44).setNationalNumber(7912345678L);
73   private static final PhoneNumber GB_NUMBER =
74       new PhoneNumber().setCountryCode(44).setNationalNumber(2070313000L);
75   private static final PhoneNumber IT_MOBILE =
76       new PhoneNumber().setCountryCode(39).setNationalNumber(345678901L);
77   private static final PhoneNumber IT_NUMBER =
78       new PhoneNumber().setCountryCode(39).setNationalNumber(236618300L).
79       setItalianLeadingZero(true);
80   private static final PhoneNumber JP_STAR_NUMBER =
81       new PhoneNumber().setCountryCode(81).setNationalNumber(2345);
82   // Numbers to test the formatting rules from Mexico.
83   private static final PhoneNumber MX_MOBILE1 =
84       new PhoneNumber().setCountryCode(52).setNationalNumber(12345678900L);
85   private static final PhoneNumber MX_MOBILE2 =
86       new PhoneNumber().setCountryCode(52).setNationalNumber(15512345678L);
87   private static final PhoneNumber MX_NUMBER1 =
88       new PhoneNumber().setCountryCode(52).setNationalNumber(3312345678L);
89   private static final PhoneNumber MX_NUMBER2 =
90       new PhoneNumber().setCountryCode(52).setNationalNumber(8211234567L);
91   private static final PhoneNumber NZ_NUMBER =
92       new PhoneNumber().setCountryCode(64).setNationalNumber(33316005L);
93   private static final PhoneNumber SG_NUMBER =
94       new PhoneNumber().setCountryCode(65).setNationalNumber(65218000L);
95   // A too-long and hence invalid US number.
96   private static final PhoneNumber US_LONG_NUMBER =
97       new PhoneNumber().setCountryCode(1).setNationalNumber(65025300001L);
98   private static final PhoneNumber US_NUMBER =
99       new PhoneNumber().setCountryCode(1).setNationalNumber(6502530000L);
100   private static final PhoneNumber US_PREMIUM =
101       new PhoneNumber().setCountryCode(1).setNationalNumber(9002530000L);
102   // Too short, but still possible US numbers.
103   private static final PhoneNumber US_LOCAL_NUMBER =
104       new PhoneNumber().setCountryCode(1).setNationalNumber(2530000L);
105   private static final PhoneNumber US_SHORT_BY_ONE_NUMBER =
106       new PhoneNumber().setCountryCode(1).setNationalNumber(650253000L);
107   private static final PhoneNumber US_TOLLFREE =
108       new PhoneNumber().setCountryCode(1).setNationalNumber(8002530000L);
109   private static final PhoneNumber US_SPOOF =
110       new PhoneNumber().setCountryCode(1).setNationalNumber(0L);
111   private static final PhoneNumber US_SPOOF_WITH_RAW_INPUT =
112       new PhoneNumber().setCountryCode(1).setNationalNumber(0L)
113           .setRawInput("000-000-0000");
114   private static final PhoneNumber UZ_FIXED_LINE =
115       new PhoneNumber().setCountryCode(998).setNationalNumber(612201234L);
116   private static final PhoneNumber UZ_MOBILE =
117       new PhoneNumber().setCountryCode(998).setNationalNumber(950123456L);
118   private static final PhoneNumber INTERNATIONAL_TOLL_FREE =
119       new PhoneNumber().setCountryCode(800).setNationalNumber(12345678L);
120   // We set this to be the same length as numbers for the other non-geographical country prefix that
121   // we have in our test metadata. However, this is not considered valid because they differ in
122   // their country calling code.
123   private static final PhoneNumber INTERNATIONAL_TOLL_FREE_TOO_LONG =
124       new PhoneNumber().setCountryCode(800).setNationalNumber(123456789L);
125   private static final PhoneNumber UNIVERSAL_PREMIUM_RATE =
126       new PhoneNumber().setCountryCode(979).setNationalNumber(123456789L);
127   private static final PhoneNumber UNKNOWN_COUNTRY_CODE_NO_RAW_INPUT =
128       new PhoneNumber().setCountryCode(2).setNationalNumber(12345L);
129 
130   private final MetadataSource mockedMetadataSource = Mockito.mock(MetadataSource.class);
131   private final PhoneNumberUtil phoneNumberUtilWithMissingMetadata =
132       new PhoneNumberUtil(mockedMetadataSource,
133           CountryCodeToRegionCodeMapForTesting.getCountryCodeToRegionCodeMap());
134 
testGetSupportedRegions()135   public void testGetSupportedRegions() {
136     assertTrue(phoneUtil.getSupportedRegions().size() > 0);
137   }
138 
testGetSupportedGlobalNetworkCallingCodes()139   public void testGetSupportedGlobalNetworkCallingCodes() {
140     Set<Integer> globalNetworkCallingCodes =
141         phoneUtil.getSupportedGlobalNetworkCallingCodes();
142     assertTrue(globalNetworkCallingCodes.size() > 0);
143     for (int callingCode : globalNetworkCallingCodes) {
144       assertTrue(callingCode > 0);
145       assertEquals(RegionCode.UN001, phoneUtil.getRegionCodeForCountryCode(callingCode));
146     }
147   }
148 
testGetSupportedCallingCodes()149   public void testGetSupportedCallingCodes() {
150     Set<Integer> callingCodes = phoneUtil.getSupportedCallingCodes();
151     assertTrue(callingCodes.size() > 0);
152     for (int callingCode : callingCodes) {
153       assertTrue(callingCode > 0);
154       assertTrue(phoneUtil.getRegionCodeForCountryCode(callingCode) != RegionCode.ZZ);
155     }
156     // There should be more than just the global network calling codes in this set.
157     assertTrue(callingCodes.size() > phoneUtil.getSupportedGlobalNetworkCallingCodes().size());
158     // But they should be included. Testing one of them.
159     assertTrue(callingCodes.contains(979));
160   }
161 
testGetInstanceLoadBadMetadata()162   public void testGetInstanceLoadBadMetadata() {
163     assertNull(phoneUtil.getMetadataForRegion("No Such Region"));
164     assertNull(phoneUtil.getMetadataForNonGeographicalRegion(-1));
165   }
166 
testGetSupportedTypesForRegion()167   public void testGetSupportedTypesForRegion() {
168     assertTrue(phoneUtil.getSupportedTypesForRegion(RegionCode.BR)
169         .contains(PhoneNumberType.FIXED_LINE));
170     // Our test data has no mobile numbers for Brazil.
171     assertFalse(phoneUtil.getSupportedTypesForRegion(RegionCode.BR)
172         .contains(PhoneNumberType.MOBILE));
173     // UNKNOWN should never be returned.
174     assertFalse(phoneUtil.getSupportedTypesForRegion(RegionCode.BR)
175         .contains(PhoneNumberType.UNKNOWN));
176     // In the US, many numbers are classified as FIXED_LINE_OR_MOBILE; but we don't want to expose
177     // this as a supported type, instead we say FIXED_LINE and MOBILE are both present.
178     assertTrue(phoneUtil.getSupportedTypesForRegion(RegionCode.US)
179         .contains(PhoneNumberType.FIXED_LINE));
180     assertTrue(phoneUtil.getSupportedTypesForRegion(RegionCode.US)
181         .contains(PhoneNumberType.MOBILE));
182     assertFalse(phoneUtil.getSupportedTypesForRegion(RegionCode.US)
183         .contains(PhoneNumberType.FIXED_LINE_OR_MOBILE));
184 
185     // Test the invalid region code.
186     assertEquals(0, phoneUtil.getSupportedTypesForRegion(RegionCode.ZZ).size());
187   }
188 
testGetSupportedTypesForNonGeoEntity()189   public void testGetSupportedTypesForNonGeoEntity() {
190     // No data exists for 999 at all, no types should be returned.
191     assertEquals(0, phoneUtil.getSupportedTypesForNonGeoEntity(999).size());
192 
193     Set<PhoneNumberType> typesFor979 = phoneUtil.getSupportedTypesForNonGeoEntity(979);
194     assertTrue(typesFor979.contains(PhoneNumberType.PREMIUM_RATE));
195     assertFalse(typesFor979.contains(PhoneNumberType.MOBILE));
196     assertFalse(typesFor979.contains(PhoneNumberType.UNKNOWN));
197   }
198 
testGetInstanceLoadUSMetadata()199   public void testGetInstanceLoadUSMetadata() {
200     PhoneMetadata metadata = phoneUtil.getMetadataForRegion(RegionCode.US);
201     assertEquals("US", metadata.getId());
202     assertEquals(1, metadata.getCountryCode());
203     assertEquals("011", metadata.getInternationalPrefix());
204     assertTrue(metadata.hasNationalPrefix());
205     assertEquals(2, metadata.getNumberFormatCount());
206     assertEquals("(\\d{3})(\\d{3})(\\d{4})",
207                  metadata.getNumberFormat(1).getPattern());
208     assertEquals("$1 $2 $3", metadata.getNumberFormat(1).getFormat());
209     assertEquals("[13-689]\\d{9}|2[0-35-9]\\d{8}",
210                  metadata.getGeneralDesc().getNationalNumberPattern());
211     assertEquals("[13-689]\\d{9}|2[0-35-9]\\d{8}",
212                  metadata.getFixedLine().getNationalNumberPattern());
213     assertEquals(1, metadata.getGeneralDesc().getPossibleLengthCount());
214     assertEquals(10, metadata.getGeneralDesc().getPossibleLength(0));
215     // Possible lengths are the same as the general description, so aren't stored separately in the
216     // toll free element as well.
217     assertEquals(0, metadata.getTollFree().getPossibleLengthCount());
218     assertEquals("900\\d{7}", metadata.getPremiumRate().getNationalNumberPattern());
219     // No shared-cost data is available, so its national number data should not be set.
220     assertFalse(metadata.getSharedCost().hasNationalNumberPattern());
221   }
222 
testGetInstanceLoadDEMetadata()223   public void testGetInstanceLoadDEMetadata() {
224     PhoneMetadata metadata = phoneUtil.getMetadataForRegion(RegionCode.DE);
225     assertEquals("DE", metadata.getId());
226     assertEquals(49, metadata.getCountryCode());
227     assertEquals("00", metadata.getInternationalPrefix());
228     assertEquals("0", metadata.getNationalPrefix());
229     assertEquals(6, metadata.getNumberFormatCount());
230     assertEquals(1, metadata.getNumberFormat(5).getLeadingDigitsPatternCount());
231     assertEquals("900", metadata.getNumberFormat(5).getLeadingDigitsPattern(0));
232     assertEquals("(\\d{3})(\\d{3,4})(\\d{4})",
233                  metadata.getNumberFormat(5).getPattern());
234     assertEquals("$1 $2 $3", metadata.getNumberFormat(5).getFormat());
235     assertEquals(2, metadata.getGeneralDesc().getPossibleLengthLocalOnlyCount());
236     assertEquals(8, metadata.getGeneralDesc().getPossibleLengthCount());
237     // Nothing is present for fixed-line, since it is the same as the general desc, so for
238     // efficiency reasons we don't store an extra value.
239     assertEquals(0, metadata.getFixedLine().getPossibleLengthCount());
240     assertEquals(2, metadata.getMobile().getPossibleLengthCount());
241     assertEquals("(?:[24-6]\\d{2}|3[03-9]\\d|[789](?:0[2-9]|[1-9]\\d))\\d{1,8}",
242                  metadata.getFixedLine().getNationalNumberPattern());
243     assertEquals("30123456", metadata.getFixedLine().getExampleNumber());
244     assertEquals(10, metadata.getTollFree().getPossibleLength(0));
245     assertEquals("900([135]\\d{6}|9\\d{7})", metadata.getPremiumRate().getNationalNumberPattern());
246   }
247 
testGetInstanceLoadARMetadata()248   public void testGetInstanceLoadARMetadata() {
249     PhoneMetadata metadata = phoneUtil.getMetadataForRegion(RegionCode.AR);
250     assertEquals("AR", metadata.getId());
251     assertEquals(54, metadata.getCountryCode());
252     assertEquals("00", metadata.getInternationalPrefix());
253     assertEquals("0", metadata.getNationalPrefix());
254     assertEquals("0(?:(11|343|3715)15)?", metadata.getNationalPrefixForParsing());
255     assertEquals("9$1", metadata.getNationalPrefixTransformRule());
256     assertEquals("$2 15 $3-$4", metadata.getNumberFormat(2).getFormat());
257     assertEquals("(\\d)(\\d{4})(\\d{2})(\\d{4})",
258                  metadata.getNumberFormat(3).getPattern());
259     assertEquals("(\\d)(\\d{4})(\\d{2})(\\d{4})",
260                  metadata.getIntlNumberFormat(3).getPattern());
261     assertEquals("$1 $2 $3 $4", metadata.getIntlNumberFormat(3).getFormat());
262   }
263 
testGetInstanceLoadInternationalTollFreeMetadata()264   public void testGetInstanceLoadInternationalTollFreeMetadata() {
265     PhoneMetadata metadata = phoneUtil.getMetadataForNonGeographicalRegion(800);
266     assertEquals("001", metadata.getId());
267     assertEquals(800, metadata.getCountryCode());
268     assertEquals("$1 $2", metadata.getNumberFormat(0).getFormat());
269     assertEquals("(\\d{4})(\\d{4})", metadata.getNumberFormat(0).getPattern());
270     assertEquals(0, metadata.getGeneralDesc().getPossibleLengthLocalOnlyCount());
271     assertEquals(1, metadata.getGeneralDesc().getPossibleLengthCount());
272     assertEquals("12345678", metadata.getTollFree().getExampleNumber());
273   }
274 
testIsNumberGeographical()275   public void testIsNumberGeographical() {
276     assertFalse(phoneUtil.isNumberGeographical(BS_MOBILE));  // Bahamas, mobile phone number.
277     assertTrue(phoneUtil.isNumberGeographical(AU_NUMBER));  // Australian fixed line number.
278     assertFalse(phoneUtil.isNumberGeographical(INTERNATIONAL_TOLL_FREE));  // International toll
279                                                                            // free number.
280     // We test that mobile phone numbers in relevant regions are indeed considered geographical.
281     assertTrue(phoneUtil.isNumberGeographical(AR_MOBILE));  // Argentina, mobile phone number.
282     assertTrue(phoneUtil.isNumberGeographical(MX_MOBILE1));  // Mexico, mobile phone number.
283     assertTrue(phoneUtil.isNumberGeographical(MX_MOBILE2));  // Mexico, another mobile phone number.
284   }
285 
testGetLengthOfGeographicalAreaCode()286   public void testGetLengthOfGeographicalAreaCode() {
287     // Google MTV, which has area code "650".
288     assertEquals(3, phoneUtil.getLengthOfGeographicalAreaCode(US_NUMBER));
289 
290     // A North America toll-free number, which has no area code.
291     assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(US_TOLLFREE));
292 
293     // Google London, which has area code "20".
294     assertEquals(2, phoneUtil.getLengthOfGeographicalAreaCode(GB_NUMBER));
295 
296     // A mobile number in the UK does not have an area code (by default, mobile numbers do not,
297     // unless they have been added to our list of exceptions).
298     assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(GB_MOBILE));
299 
300     // Google Buenos Aires, which has area code "11".
301     assertEquals(2, phoneUtil.getLengthOfGeographicalAreaCode(AR_NUMBER));
302 
303     // A mobile number in Argentina also has an area code.
304     assertEquals(3, phoneUtil.getLengthOfGeographicalAreaCode(AR_MOBILE));
305 
306     // Google Sydney, which has area code "2".
307     assertEquals(1, phoneUtil.getLengthOfGeographicalAreaCode(AU_NUMBER));
308 
309     // Italian numbers - there is no national prefix, but it still has an area code.
310     assertEquals(2, phoneUtil.getLengthOfGeographicalAreaCode(IT_NUMBER));
311 
312     // Mexico numbers - there is no national prefix, but it still has an area code.
313     assertEquals(2, phoneUtil.getLengthOfGeographicalAreaCode(MX_NUMBER1));
314 
315     // Google Singapore. Singapore has no area code and no national prefix.
316     assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(SG_NUMBER));
317 
318     // An invalid US number (1 digit shorter), which has no area code.
319     assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(US_SHORT_BY_ONE_NUMBER));
320 
321     // An international toll free number, which has no area code.
322     assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(INTERNATIONAL_TOLL_FREE));
323 
324     // A mobile number from China is geographical, but does not have an area code.
325     PhoneNumber cnMobile = new PhoneNumber().setCountryCode(86).setNationalNumber(18912341234L);
326     assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(cnMobile));
327   }
328 
testGetLengthOfNationalDestinationCode()329   public void testGetLengthOfNationalDestinationCode() {
330     // Google MTV, which has national destination code (NDC) "650".
331     assertEquals(3, phoneUtil.getLengthOfNationalDestinationCode(US_NUMBER));
332 
333     // A North America toll-free number, which has NDC "800".
334     assertEquals(3, phoneUtil.getLengthOfNationalDestinationCode(US_TOLLFREE));
335 
336     // Google London, which has NDC "20".
337     assertEquals(2, phoneUtil.getLengthOfNationalDestinationCode(GB_NUMBER));
338 
339     // A UK mobile phone, which has NDC "7912".
340     assertEquals(4, phoneUtil.getLengthOfNationalDestinationCode(GB_MOBILE));
341 
342     // Google Buenos Aires, which has NDC "11".
343     assertEquals(2, phoneUtil.getLengthOfNationalDestinationCode(AR_NUMBER));
344 
345     // An Argentinian mobile which has NDC "911".
346     assertEquals(3, phoneUtil.getLengthOfNationalDestinationCode(AR_MOBILE));
347 
348     // Google Sydney, which has NDC "2".
349     assertEquals(1, phoneUtil.getLengthOfNationalDestinationCode(AU_NUMBER));
350 
351     // Google Singapore, which has NDC "6521".
352     assertEquals(4, phoneUtil.getLengthOfNationalDestinationCode(SG_NUMBER));
353 
354     // An invalid US number (1 digit shorter), which has no NDC.
355     assertEquals(0, phoneUtil.getLengthOfNationalDestinationCode(US_SHORT_BY_ONE_NUMBER));
356 
357     // A number containing an invalid country calling code, which shouldn't have any NDC.
358     PhoneNumber number = new PhoneNumber().setCountryCode(123).setNationalNumber(6502530000L);
359     assertEquals(0, phoneUtil.getLengthOfNationalDestinationCode(number));
360 
361     // An international toll free number, which has NDC "1234".
362     assertEquals(4, phoneUtil.getLengthOfNationalDestinationCode(INTERNATIONAL_TOLL_FREE));
363 
364     // A mobile number from China is geographical, but does not have an area code: however it still
365     // can be considered to have a national destination code.
366     PhoneNumber cnMobile = new PhoneNumber().setCountryCode(86).setNationalNumber(18912341234L);
367     assertEquals(3, phoneUtil.getLengthOfNationalDestinationCode(cnMobile));
368   }
369 
testGetCountryMobileToken()370   public void testGetCountryMobileToken() {
371     assertEquals("9", PhoneNumberUtil.getCountryMobileToken(phoneUtil.getCountryCodeForRegion(
372         RegionCode.AR)));
373 
374     // Country calling code for Sweden, which has no mobile token.
375     assertEquals("", PhoneNumberUtil.getCountryMobileToken(phoneUtil.getCountryCodeForRegion(
376         RegionCode.SE)));
377   }
378 
testGetNationalSignificantNumber()379   public void testGetNationalSignificantNumber() {
380     assertEquals("6502530000", phoneUtil.getNationalSignificantNumber(US_NUMBER));
381 
382     // An Italian mobile number.
383     assertEquals("345678901", phoneUtil.getNationalSignificantNumber(IT_MOBILE));
384 
385     // An Italian fixed line number.
386     assertEquals("0236618300", phoneUtil.getNationalSignificantNumber(IT_NUMBER));
387 
388     assertEquals("12345678", phoneUtil.getNationalSignificantNumber(INTERNATIONAL_TOLL_FREE));
389   }
390 
testGetNationalSignificantNumber_ManyLeadingZeros()391   public void testGetNationalSignificantNumber_ManyLeadingZeros() {
392     PhoneNumber number = new PhoneNumber();
393     number.setCountryCode(1);
394     number.setNationalNumber(650);
395     number.setItalianLeadingZero(true);
396     number.setNumberOfLeadingZeros(2);
397     assertEquals("00650", phoneUtil.getNationalSignificantNumber(number));
398 
399     // Set a bad value; we shouldn't crash, we shouldn't output any leading zeros at all.
400     number.setNumberOfLeadingZeros(-3);
401     assertEquals("650", phoneUtil.getNationalSignificantNumber(number));
402   }
403 
testGetExampleNumber()404   public void testGetExampleNumber() {
405     assertEquals(DE_NUMBER, phoneUtil.getExampleNumber(RegionCode.DE));
406 
407     assertEquals(
408         DE_NUMBER, phoneUtil.getExampleNumberForType(RegionCode.DE, PhoneNumberType.FIXED_LINE));
409     // Should return the same response if asked for FIXED_LINE_OR_MOBILE too.
410     assertEquals(DE_NUMBER,
411         phoneUtil.getExampleNumberForType(RegionCode.DE, PhoneNumberType.FIXED_LINE_OR_MOBILE));
412     assertNotNull(phoneUtil.getExampleNumberForType(RegionCode.US, PhoneNumberType.FIXED_LINE));
413     assertNotNull(phoneUtil.getExampleNumberForType(RegionCode.US, PhoneNumberType.MOBILE));
414 
415     // We have data for the US, but no data for VOICEMAIL, so return null.
416     assertNull(phoneUtil.getExampleNumberForType(RegionCode.US, PhoneNumberType.VOICEMAIL));
417     // CS is an invalid region, so we have no data for it.
418     assertNull(phoneUtil.getExampleNumberForType("CS", PhoneNumberType.MOBILE));
419     // RegionCode 001 is reserved for supporting non-geographical country calling code. We don't
420     // support getting an example number for it with this method.
421     assertNull(phoneUtil.getExampleNumber(RegionCode.UN001));
422   }
423 
testGetInvalidExampleNumber()424   public void testGetInvalidExampleNumber() {
425     // RegionCode 001 is reserved for supporting non-geographical country calling codes. We don't
426     // support getting an invalid example number for it with getInvalidExampleNumber.
427     assertNull(phoneUtil.getInvalidExampleNumber(RegionCode.UN001));
428     assertNull(phoneUtil.getInvalidExampleNumber("CS"));
429     PhoneNumber usInvalidNumber = phoneUtil.getInvalidExampleNumber(RegionCode.US);
430     assertEquals(1, usInvalidNumber.getCountryCode());
431     assertFalse(usInvalidNumber.getNationalNumber() == 0);
432   }
433 
testGetExampleNumberForNonGeoEntity()434   public void testGetExampleNumberForNonGeoEntity() {
435     assertEquals(INTERNATIONAL_TOLL_FREE, phoneUtil.getExampleNumberForNonGeoEntity(800));
436     assertEquals(UNIVERSAL_PREMIUM_RATE, phoneUtil.getExampleNumberForNonGeoEntity(979));
437   }
438 
testGetExampleNumberWithoutRegion()439   public void testGetExampleNumberWithoutRegion() {
440     // In our test metadata we don't cover all types: in our real metadata, we do.
441     assertNotNull(phoneUtil.getExampleNumberForType(PhoneNumberType.FIXED_LINE));
442     assertNotNull(phoneUtil.getExampleNumberForType(PhoneNumberType.MOBILE));
443     assertNotNull(phoneUtil.getExampleNumberForType(PhoneNumberType.PREMIUM_RATE));
444   }
445 
testConvertAlphaCharactersInNumber()446   public void testConvertAlphaCharactersInNumber() {
447     String input = "1800-ABC-DEF";
448     // Alpha chars are converted to digits; everything else is left untouched.
449     String expectedOutput = "1800-222-333";
450     assertEquals(expectedOutput, PhoneNumberUtil.convertAlphaCharactersInNumber(input));
451   }
452 
testNormaliseRemovePunctuation()453   public void testNormaliseRemovePunctuation() {
454     StringBuilder inputNumber = new StringBuilder("034-56&+#2\u00AD34");
455     String expectedOutput = "03456234";
456     assertEquals("Conversion did not correctly remove punctuation",
457                  expectedOutput, PhoneNumberUtil.normalize(inputNumber).toString());
458   }
459 
testNormaliseReplaceAlphaCharacters()460   public void testNormaliseReplaceAlphaCharacters() {
461     StringBuilder inputNumber = new StringBuilder("034-I-am-HUNGRY");
462     String expectedOutput = "034426486479";
463     assertEquals("Conversion did not correctly replace alpha characters",
464                  expectedOutput, PhoneNumberUtil.normalize(inputNumber).toString());
465   }
466 
testNormaliseOtherDigits()467   public void testNormaliseOtherDigits() {
468     StringBuilder inputNumber = new StringBuilder("\uFF125\u0665");
469     String expectedOutput = "255";
470     assertEquals("Conversion did not correctly replace non-latin digits",
471                  expectedOutput, PhoneNumberUtil.normalize(inputNumber).toString());
472     // Eastern-Arabic digits.
473     inputNumber = new StringBuilder("\u06F52\u06F0");
474     expectedOutput = "520";
475     assertEquals("Conversion did not correctly replace non-latin digits",
476                  expectedOutput, PhoneNumberUtil.normalize(inputNumber).toString());
477   }
478 
testNormaliseStripAlphaCharacters()479   public void testNormaliseStripAlphaCharacters() {
480     String inputNumber = "034-56&+a#234";
481     String expectedOutput = "03456234";
482     assertEquals("Conversion did not correctly remove alpha character",
483                  expectedOutput,
484                  PhoneNumberUtil.normalizeDigitsOnly(inputNumber));
485   }
486 
testNormaliseStripNonDiallableCharacters()487   public void testNormaliseStripNonDiallableCharacters() {
488     String inputNumber = "03*4-56&+1a#234";
489     String expectedOutput = "03*456+1#234";
490     assertEquals("Conversion did not correctly remove non-diallable characters",
491                  expectedOutput,
492                  PhoneNumberUtil.normalizeDiallableCharsOnly(inputNumber));
493   }
494 
testFormatUSNumber()495   public void testFormatUSNumber() {
496     assertEquals("650 253 0000", phoneUtil.format(US_NUMBER, PhoneNumberFormat.NATIONAL));
497     assertEquals("+1 650 253 0000", phoneUtil.format(US_NUMBER, PhoneNumberFormat.INTERNATIONAL));
498 
499     assertEquals("800 253 0000", phoneUtil.format(US_TOLLFREE, PhoneNumberFormat.NATIONAL));
500     assertEquals("+1 800 253 0000", phoneUtil.format(US_TOLLFREE, PhoneNumberFormat.INTERNATIONAL));
501 
502     assertEquals("900 253 0000", phoneUtil.format(US_PREMIUM, PhoneNumberFormat.NATIONAL));
503     assertEquals("+1 900 253 0000", phoneUtil.format(US_PREMIUM, PhoneNumberFormat.INTERNATIONAL));
504     assertEquals("tel:+1-900-253-0000", phoneUtil.format(US_PREMIUM, PhoneNumberFormat.RFC3966));
505     // Numbers with all zeros in the national number part will be formatted by using the raw_input
506     // if that is available no matter which format is specified.
507     assertEquals("000-000-0000",
508                  phoneUtil.format(US_SPOOF_WITH_RAW_INPUT, PhoneNumberFormat.NATIONAL));
509     assertEquals("0", phoneUtil.format(US_SPOOF, PhoneNumberFormat.NATIONAL));
510   }
511 
testFormatBSNumber()512   public void testFormatBSNumber() {
513     assertEquals("242 365 1234", phoneUtil.format(BS_NUMBER, PhoneNumberFormat.NATIONAL));
514     assertEquals("+1 242 365 1234", phoneUtil.format(BS_NUMBER, PhoneNumberFormat.INTERNATIONAL));
515   }
516 
testFormatGBNumber()517   public void testFormatGBNumber() {
518     assertEquals("(020) 7031 3000", phoneUtil.format(GB_NUMBER, PhoneNumberFormat.NATIONAL));
519     assertEquals("+44 20 7031 3000", phoneUtil.format(GB_NUMBER, PhoneNumberFormat.INTERNATIONAL));
520 
521     assertEquals("(07912) 345 678", phoneUtil.format(GB_MOBILE, PhoneNumberFormat.NATIONAL));
522     assertEquals("+44 7912 345 678", phoneUtil.format(GB_MOBILE, PhoneNumberFormat.INTERNATIONAL));
523   }
524 
testFormatDENumber()525   public void testFormatDENumber() {
526     PhoneNumber deNumber = new PhoneNumber();
527     deNumber.setCountryCode(49).setNationalNumber(301234L);
528     assertEquals("030/1234", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
529     assertEquals("+49 30/1234", phoneUtil.format(deNumber, PhoneNumberFormat.INTERNATIONAL));
530     assertEquals("tel:+49-30-1234", phoneUtil.format(deNumber, PhoneNumberFormat.RFC3966));
531 
532     deNumber.clear();
533     deNumber.setCountryCode(49).setNationalNumber(291123L);
534     assertEquals("0291 123", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
535     assertEquals("+49 291 123", phoneUtil.format(deNumber, PhoneNumberFormat.INTERNATIONAL));
536 
537     deNumber.clear();
538     deNumber.setCountryCode(49).setNationalNumber(29112345678L);
539     assertEquals("0291 12345678", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
540     assertEquals("+49 291 12345678", phoneUtil.format(deNumber, PhoneNumberFormat.INTERNATIONAL));
541 
542     deNumber.clear();
543     deNumber.setCountryCode(49).setNationalNumber(912312345L);
544     assertEquals("09123 12345", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
545     assertEquals("+49 9123 12345", phoneUtil.format(deNumber, PhoneNumberFormat.INTERNATIONAL));
546     deNumber.clear();
547     deNumber.setCountryCode(49).setNationalNumber(80212345L);
548     assertEquals("08021 2345", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
549     assertEquals("+49 8021 2345", phoneUtil.format(deNumber, PhoneNumberFormat.INTERNATIONAL));
550     // Note this number is correctly formatted without national prefix. Most of the numbers that
551     // are treated as invalid numbers by the library are short numbers, and they are usually not
552     // dialed with national prefix.
553     assertEquals("1234", phoneUtil.format(DE_SHORT_NUMBER, PhoneNumberFormat.NATIONAL));
554     assertEquals("+49 1234", phoneUtil.format(DE_SHORT_NUMBER, PhoneNumberFormat.INTERNATIONAL));
555 
556     deNumber.clear();
557     deNumber.setCountryCode(49).setNationalNumber(41341234);
558     assertEquals("04134 1234", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
559   }
560 
testFormatITNumber()561   public void testFormatITNumber() {
562     assertEquals("02 3661 8300", phoneUtil.format(IT_NUMBER, PhoneNumberFormat.NATIONAL));
563     assertEquals("+39 02 3661 8300", phoneUtil.format(IT_NUMBER, PhoneNumberFormat.INTERNATIONAL));
564     assertEquals("+390236618300", phoneUtil.format(IT_NUMBER, PhoneNumberFormat.E164));
565 
566     assertEquals("345 678 901", phoneUtil.format(IT_MOBILE, PhoneNumberFormat.NATIONAL));
567     assertEquals("+39 345 678 901", phoneUtil.format(IT_MOBILE, PhoneNumberFormat.INTERNATIONAL));
568     assertEquals("+39345678901", phoneUtil.format(IT_MOBILE, PhoneNumberFormat.E164));
569   }
570 
testFormatAUNumber()571   public void testFormatAUNumber() {
572     assertEquals("02 3661 8300", phoneUtil.format(AU_NUMBER, PhoneNumberFormat.NATIONAL));
573     assertEquals("+61 2 3661 8300", phoneUtil.format(AU_NUMBER, PhoneNumberFormat.INTERNATIONAL));
574     assertEquals("+61236618300", phoneUtil.format(AU_NUMBER, PhoneNumberFormat.E164));
575 
576     PhoneNumber auNumber = new PhoneNumber().setCountryCode(61).setNationalNumber(1800123456L);
577     assertEquals("1800 123 456", phoneUtil.format(auNumber, PhoneNumberFormat.NATIONAL));
578     assertEquals("+61 1800 123 456", phoneUtil.format(auNumber, PhoneNumberFormat.INTERNATIONAL));
579     assertEquals("+611800123456", phoneUtil.format(auNumber, PhoneNumberFormat.E164));
580   }
581 
testFormatARNumber()582   public void testFormatARNumber() {
583     assertEquals("011 8765-4321", phoneUtil.format(AR_NUMBER, PhoneNumberFormat.NATIONAL));
584     assertEquals("+54 11 8765-4321", phoneUtil.format(AR_NUMBER, PhoneNumberFormat.INTERNATIONAL));
585     assertEquals("+541187654321", phoneUtil.format(AR_NUMBER, PhoneNumberFormat.E164));
586 
587     assertEquals("011 15 8765-4321", phoneUtil.format(AR_MOBILE, PhoneNumberFormat.NATIONAL));
588     assertEquals("+54 9 11 8765 4321", phoneUtil.format(AR_MOBILE,
589                                                         PhoneNumberFormat.INTERNATIONAL));
590     assertEquals("+5491187654321", phoneUtil.format(AR_MOBILE, PhoneNumberFormat.E164));
591   }
592 
testFormatMXNumber()593   public void testFormatMXNumber() {
594     assertEquals("045 234 567 8900", phoneUtil.format(MX_MOBILE1, PhoneNumberFormat.NATIONAL));
595     assertEquals("+52 1 234 567 8900", phoneUtil.format(
596         MX_MOBILE1, PhoneNumberFormat.INTERNATIONAL));
597     assertEquals("+5212345678900", phoneUtil.format(MX_MOBILE1, PhoneNumberFormat.E164));
598 
599     assertEquals("045 55 1234 5678", phoneUtil.format(MX_MOBILE2, PhoneNumberFormat.NATIONAL));
600     assertEquals("+52 1 55 1234 5678", phoneUtil.format(
601         MX_MOBILE2, PhoneNumberFormat.INTERNATIONAL));
602     assertEquals("+5215512345678", phoneUtil.format(MX_MOBILE2, PhoneNumberFormat.E164));
603 
604     assertEquals("01 33 1234 5678", phoneUtil.format(MX_NUMBER1, PhoneNumberFormat.NATIONAL));
605     assertEquals("+52 33 1234 5678", phoneUtil.format(MX_NUMBER1, PhoneNumberFormat.INTERNATIONAL));
606     assertEquals("+523312345678", phoneUtil.format(MX_NUMBER1, PhoneNumberFormat.E164));
607 
608     assertEquals("01 821 123 4567", phoneUtil.format(MX_NUMBER2, PhoneNumberFormat.NATIONAL));
609     assertEquals("+52 821 123 4567", phoneUtil.format(MX_NUMBER2, PhoneNumberFormat.INTERNATIONAL));
610     assertEquals("+528211234567", phoneUtil.format(MX_NUMBER2, PhoneNumberFormat.E164));
611   }
612 
testFormatOutOfCountryCallingNumber()613   public void testFormatOutOfCountryCallingNumber() {
614     assertEquals("00 1 900 253 0000",
615                  phoneUtil.formatOutOfCountryCallingNumber(US_PREMIUM, RegionCode.DE));
616 
617     assertEquals("1 650 253 0000",
618                  phoneUtil.formatOutOfCountryCallingNumber(US_NUMBER, RegionCode.BS));
619 
620     assertEquals("00 1 650 253 0000",
621                  phoneUtil.formatOutOfCountryCallingNumber(US_NUMBER, RegionCode.PL));
622 
623     assertEquals("011 44 7912 345 678",
624                  phoneUtil.formatOutOfCountryCallingNumber(GB_MOBILE, RegionCode.US));
625 
626     assertEquals("00 49 1234",
627                  phoneUtil.formatOutOfCountryCallingNumber(DE_SHORT_NUMBER, RegionCode.GB));
628     // Note this number is correctly formatted without national prefix. Most of the numbers that
629     // are treated as invalid numbers by the library are short numbers, and they are usually not
630     // dialed with national prefix.
631     assertEquals("1234", phoneUtil.formatOutOfCountryCallingNumber(DE_SHORT_NUMBER, RegionCode.DE));
632 
633     assertEquals("011 39 02 3661 8300",
634                  phoneUtil.formatOutOfCountryCallingNumber(IT_NUMBER, RegionCode.US));
635     assertEquals("02 3661 8300",
636                  phoneUtil.formatOutOfCountryCallingNumber(IT_NUMBER, RegionCode.IT));
637     assertEquals("+39 02 3661 8300",
638                  phoneUtil.formatOutOfCountryCallingNumber(IT_NUMBER, RegionCode.SG));
639 
640     assertEquals("6521 8000",
641                  phoneUtil.formatOutOfCountryCallingNumber(SG_NUMBER, RegionCode.SG));
642 
643     assertEquals("011 54 9 11 8765 4321",
644                  phoneUtil.formatOutOfCountryCallingNumber(AR_MOBILE, RegionCode.US));
645     assertEquals("011 800 1234 5678",
646                  phoneUtil.formatOutOfCountryCallingNumber(INTERNATIONAL_TOLL_FREE, RegionCode.US));
647 
648     PhoneNumber arNumberWithExtn = new PhoneNumber().mergeFrom(AR_MOBILE).setExtension("1234");
649     assertEquals("011 54 9 11 8765 4321 ext. 1234",
650                  phoneUtil.formatOutOfCountryCallingNumber(arNumberWithExtn, RegionCode.US));
651     assertEquals("0011 54 9 11 8765 4321 ext. 1234",
652                  phoneUtil.formatOutOfCountryCallingNumber(arNumberWithExtn, RegionCode.AU));
653     assertEquals("011 15 8765-4321 ext. 1234",
654                  phoneUtil.formatOutOfCountryCallingNumber(arNumberWithExtn, RegionCode.AR));
655   }
656 
testFormatOutOfCountryWithInvalidRegion()657   public void testFormatOutOfCountryWithInvalidRegion() {
658     // AQ/Antarctica isn't a valid region code for phone number formatting,
659     // so this falls back to intl formatting.
660     assertEquals("+1 650 253 0000",
661                  phoneUtil.formatOutOfCountryCallingNumber(US_NUMBER, "AQ"));
662     // For region code 001, the out-of-country format always turns into the international format.
663     assertEquals("+1 650 253 0000",
664                  phoneUtil.formatOutOfCountryCallingNumber(US_NUMBER, RegionCode.UN001));
665   }
666 
testFormatOutOfCountryWithPreferredIntlPrefix()667   public void testFormatOutOfCountryWithPreferredIntlPrefix() {
668     // This should use 0011, since that is the preferred international prefix (both 0011 and 0012
669     // are accepted as possible international prefixes in our test metadta.)
670     assertEquals("0011 39 02 3661 8300",
671                  phoneUtil.formatOutOfCountryCallingNumber(IT_NUMBER, RegionCode.AU));
672 
673     // Testing preferred international prefixes with ~ are supported (designates waiting).
674     assertEquals("8~10 39 02 3661 8300",
675                  phoneUtil.formatOutOfCountryCallingNumber(IT_NUMBER, RegionCode.UZ));
676   }
677 
testFormatOutOfCountryKeepingAlphaChars()678   public void testFormatOutOfCountryKeepingAlphaChars() {
679     PhoneNumber alphaNumericNumber = new PhoneNumber();
680     alphaNumericNumber.setCountryCode(1).setNationalNumber(8007493524L)
681         .setRawInput("1800 six-flag");
682     assertEquals("0011 1 800 SIX-FLAG",
683                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));
684 
685     alphaNumericNumber.setRawInput("1-800-SIX-flag");
686     assertEquals("0011 1 800-SIX-FLAG",
687                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));
688 
689     alphaNumericNumber.setRawInput("Call us from UK: 00 1 800 SIX-flag");
690     assertEquals("0011 1 800 SIX-FLAG",
691                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));
692 
693     alphaNumericNumber.setRawInput("800 SIX-flag");
694     assertEquals("0011 1 800 SIX-FLAG",
695                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));
696 
697     // Formatting from within the NANPA region.
698     assertEquals("1 800 SIX-FLAG",
699                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.US));
700 
701     assertEquals("1 800 SIX-FLAG",
702                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.BS));
703 
704     // Testing that if the raw input doesn't exist, it is formatted using
705     // formatOutOfCountryCallingNumber.
706     alphaNumericNumber.clearRawInput();
707     assertEquals("00 1 800 749 3524",
708                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.DE));
709 
710     // Testing AU alpha number formatted from Australia.
711     alphaNumericNumber.setCountryCode(61).setNationalNumber(827493524L)
712         .setRawInput("+61 82749-FLAG");
713     // This number should have the national prefix fixed.
714     assertEquals("082749-FLAG",
715                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));
716 
717     alphaNumericNumber.setRawInput("082749-FLAG");
718     assertEquals("082749-FLAG",
719                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));
720 
721     alphaNumericNumber.setNationalNumber(18007493524L).setRawInput("1-800-SIX-flag");
722     // This number should not have the national prefix prefixed, in accordance with the override for
723     // this specific formatting rule.
724     assertEquals("1-800-SIX-FLAG",
725                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));
726 
727     // The metadata should not be permanently changed, since we copied it before modifying patterns.
728     // Here we check this.
729     alphaNumericNumber.setNationalNumber(1800749352L);
730     assertEquals("1800 749 352",
731                  phoneUtil.formatOutOfCountryCallingNumber(alphaNumericNumber, RegionCode.AU));
732 
733     // Testing a region with multiple international prefixes.
734     assertEquals("+61 1-800-SIX-FLAG",
735                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.SG));
736     // Testing the case of calling from a non-supported region.
737     assertEquals("+61 1-800-SIX-FLAG",
738                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, "AQ"));
739 
740     // Testing the case with an invalid country calling code.
741     alphaNumericNumber.setCountryCode(0).setNationalNumber(18007493524L)
742         .setRawInput("1-800-SIX-flag");
743     // Uses the raw input only.
744     assertEquals("1-800-SIX-flag",
745                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.DE));
746 
747     // Testing the case of an invalid alpha number.
748     alphaNumericNumber.setCountryCode(1).setNationalNumber(80749L).setRawInput("180-SIX");
749     // No country-code stripping can be done.
750     assertEquals("00 1 180-SIX",
751                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.DE));
752 
753     // Testing the case of calling from a non-supported region.
754     alphaNumericNumber.setCountryCode(1).setNationalNumber(80749L).setRawInput("180-SIX");
755     // No country-code stripping can be done since the number is invalid.
756     assertEquals("+1 180-SIX",
757                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, "AQ"));
758   }
759 
testFormatWithCarrierCode()760   public void testFormatWithCarrierCode() {
761     // We only support this for AR in our test metadata, and only for mobile numbers starting with
762     // certain values.
763     PhoneNumber arMobile = new PhoneNumber().setCountryCode(54).setNationalNumber(92234654321L);
764     assertEquals("02234 65-4321", phoneUtil.format(arMobile, PhoneNumberFormat.NATIONAL));
765     // Here we force 14 as the carrier code.
766     assertEquals("02234 14 65-4321",
767                  phoneUtil.formatNationalNumberWithCarrierCode(arMobile, "14"));
768     // Here we force the number to be shown with no carrier code.
769     assertEquals("02234 65-4321",
770                  phoneUtil.formatNationalNumberWithCarrierCode(arMobile, ""));
771     // Here the international rule is used, so no carrier code should be present.
772     assertEquals("+5492234654321", phoneUtil.format(arMobile, PhoneNumberFormat.E164));
773     // We don't support this for the US so there should be no change.
774     assertEquals("650 253 0000", phoneUtil.formatNationalNumberWithCarrierCode(US_NUMBER, "15"));
775 
776     // Invalid country code should just get the NSN.
777     assertEquals("12345",
778         phoneUtil.formatNationalNumberWithCarrierCode(UNKNOWN_COUNTRY_CODE_NO_RAW_INPUT, "89"));
779   }
780 
testFormatWithPreferredCarrierCode()781   public void testFormatWithPreferredCarrierCode() {
782     // We only support this for AR in our test metadata.
783     PhoneNumber arNumber = new PhoneNumber();
784     arNumber.setCountryCode(54).setNationalNumber(91234125678L);
785     // Test formatting with no preferred carrier code stored in the number itself.
786     assertEquals("01234 15 12-5678",
787         phoneUtil.formatNationalNumberWithPreferredCarrierCode(arNumber, "15"));
788     assertEquals("01234 12-5678",
789         phoneUtil.formatNationalNumberWithPreferredCarrierCode(arNumber, ""));
790     // Test formatting with preferred carrier code present.
791     arNumber.setPreferredDomesticCarrierCode("19");
792     assertEquals("01234 12-5678", phoneUtil.format(arNumber, PhoneNumberFormat.NATIONAL));
793     assertEquals("01234 19 12-5678",
794         phoneUtil.formatNationalNumberWithPreferredCarrierCode(arNumber, "15"));
795     assertEquals("01234 19 12-5678",
796         phoneUtil.formatNationalNumberWithPreferredCarrierCode(arNumber, ""));
797     // When the preferred_domestic_carrier_code is present (even when it is just a space), use it
798     // instead of the default carrier code passed in.
799     arNumber.setPreferredDomesticCarrierCode(" ");
800     assertEquals("01234   12-5678",
801         phoneUtil.formatNationalNumberWithPreferredCarrierCode(arNumber, "15"));
802     // When the preferred_domestic_carrier_code is present but empty, treat it as unset and use
803     // instead the default carrier code passed in.
804     arNumber.setPreferredDomesticCarrierCode("");
805     assertEquals("01234 15 12-5678",
806         phoneUtil.formatNationalNumberWithPreferredCarrierCode(arNumber, "15"));
807     // We don't support this for the US so there should be no change.
808     PhoneNumber usNumber = new PhoneNumber();
809     usNumber.setCountryCode(1).setNationalNumber(4241231234L).setPreferredDomesticCarrierCode("99");
810     assertEquals("424 123 1234", phoneUtil.format(usNumber, PhoneNumberFormat.NATIONAL));
811     assertEquals("424 123 1234",
812         phoneUtil.formatNationalNumberWithPreferredCarrierCode(usNumber, "15"));
813   }
814 
testFormatNumberForMobileDialing()815   public void testFormatNumberForMobileDialing() {
816     // Numbers are normally dialed in national format in-country, and international format from
817     // outside the country.
818     assertEquals("6012345678",
819         phoneUtil.formatNumberForMobileDialing(CO_FIXED_LINE, RegionCode.CO, false));
820     assertEquals("030123456",
821         phoneUtil.formatNumberForMobileDialing(DE_NUMBER, RegionCode.DE, false));
822     assertEquals("+4930123456",
823         phoneUtil.formatNumberForMobileDialing(DE_NUMBER, "CH", false));
824     PhoneNumber deNumberWithExtn = new PhoneNumber().mergeFrom(DE_NUMBER).setExtension("1234");
825     assertEquals("030123456",
826         phoneUtil.formatNumberForMobileDialing(deNumberWithExtn, RegionCode.DE, false));
827     assertEquals("+4930123456",
828         phoneUtil.formatNumberForMobileDialing(deNumberWithExtn, "CH", false));
829 
830     // US toll free numbers are marked as noInternationalDialling in the test metadata for testing
831     // purposes. For such numbers, we expect nothing to be returned when the region code is not the
832     // same one.
833     assertEquals("800 253 0000",
834         phoneUtil.formatNumberForMobileDialing(US_TOLLFREE, RegionCode.US,
835                                                true /*  keep formatting */));
836     assertEquals("", phoneUtil.formatNumberForMobileDialing(US_TOLLFREE, RegionCode.CN, true));
837     assertEquals("+1 650 253 0000",
838         phoneUtil.formatNumberForMobileDialing(US_NUMBER, RegionCode.US, true));
839     PhoneNumber usNumberWithExtn = new PhoneNumber().mergeFrom(US_NUMBER).setExtension("1234");
840     assertEquals("+1 650 253 0000",
841         phoneUtil.formatNumberForMobileDialing(usNumberWithExtn, RegionCode.US, true));
842 
843     assertEquals("8002530000",
844         phoneUtil.formatNumberForMobileDialing(US_TOLLFREE, RegionCode.US,
845                                                false /* remove formatting */));
846     assertEquals("", phoneUtil.formatNumberForMobileDialing(US_TOLLFREE, RegionCode.CN, false));
847     assertEquals("+16502530000",
848         phoneUtil.formatNumberForMobileDialing(US_NUMBER, RegionCode.US, false));
849     assertEquals("+16502530000",
850         phoneUtil.formatNumberForMobileDialing(usNumberWithExtn, RegionCode.US, false));
851 
852     // An invalid US number, which is one digit too long.
853     assertEquals("+165025300001",
854         phoneUtil.formatNumberForMobileDialing(US_LONG_NUMBER, RegionCode.US, false));
855     assertEquals("+1 65025300001",
856         phoneUtil.formatNumberForMobileDialing(US_LONG_NUMBER, RegionCode.US, true));
857 
858     // Star numbers. In real life they appear in Israel, but we have them in JP in our test
859     // metadata.
860     assertEquals("*2345",
861         phoneUtil.formatNumberForMobileDialing(JP_STAR_NUMBER, RegionCode.JP, false));
862     assertEquals("*2345",
863         phoneUtil.formatNumberForMobileDialing(JP_STAR_NUMBER, RegionCode.JP, true));
864 
865     assertEquals("+80012345678",
866         phoneUtil.formatNumberForMobileDialing(INTERNATIONAL_TOLL_FREE, RegionCode.JP, false));
867     assertEquals("+800 1234 5678",
868         phoneUtil.formatNumberForMobileDialing(INTERNATIONAL_TOLL_FREE, RegionCode.JP, true));
869 
870     // UAE numbers beginning with 600 (classified as UAN) need to be dialled without +971 locally.
871     assertEquals("+971600123456",
872         phoneUtil.formatNumberForMobileDialing(AE_UAN, RegionCode.JP, false));
873     assertEquals("600123456",
874         phoneUtil.formatNumberForMobileDialing(AE_UAN, RegionCode.AE, false));
875 
876     assertEquals("+523312345678",
877         phoneUtil.formatNumberForMobileDialing(MX_NUMBER1, RegionCode.MX, false));
878     assertEquals("+523312345678",
879         phoneUtil.formatNumberForMobileDialing(MX_NUMBER1, RegionCode.US, false));
880 
881     // Test whether Uzbek phone numbers are returned in international format even when dialled from
882     // same region or other regions.
883     assertEquals("+998612201234",
884         phoneUtil.formatNumberForMobileDialing(UZ_FIXED_LINE, RegionCode.UZ, false));
885     assertEquals("+998950123456",
886         phoneUtil.formatNumberForMobileDialing(UZ_MOBILE, RegionCode.UZ, false));
887     assertEquals("+998950123456",
888         phoneUtil.formatNumberForMobileDialing(UZ_MOBILE, RegionCode.US, false));
889 
890     // Non-geographical numbers should always be dialed in international format.
891     assertEquals("+80012345678",
892         phoneUtil.formatNumberForMobileDialing(INTERNATIONAL_TOLL_FREE, RegionCode.US, false));
893     assertEquals("+80012345678",
894         phoneUtil.formatNumberForMobileDialing(INTERNATIONAL_TOLL_FREE, RegionCode.UN001, false));
895 
896     // Test that a short number is formatted correctly for mobile dialing within the region,
897     // and is not diallable from outside the region.
898     PhoneNumber deShortNumber = new PhoneNumber().setCountryCode(49).setNationalNumber(123L);
899     assertEquals("123", phoneUtil.formatNumberForMobileDialing(deShortNumber, RegionCode.DE,
900         false));
901     assertEquals("", phoneUtil.formatNumberForMobileDialing(deShortNumber, RegionCode.IT, false));
902 
903     // Test the special logic for NANPA countries, for which regular length phone numbers are always
904     // output in international format, but short numbers are in national format.
905     assertEquals("+16502530000", phoneUtil.formatNumberForMobileDialing(US_NUMBER,
906         RegionCode.US, false));
907     assertEquals("+16502530000", phoneUtil.formatNumberForMobileDialing(US_NUMBER,
908         RegionCode.CA, false));
909     assertEquals("+16502530000", phoneUtil.formatNumberForMobileDialing(US_NUMBER,
910         RegionCode.BR, false));
911     PhoneNumber usShortNumber = new PhoneNumber().setCountryCode(1).setNationalNumber(911L);
912     assertEquals("911", phoneUtil.formatNumberForMobileDialing(usShortNumber, RegionCode.US,
913         false));
914     assertEquals("", phoneUtil.formatNumberForMobileDialing(usShortNumber, RegionCode.CA, false));
915     assertEquals("", phoneUtil.formatNumberForMobileDialing(usShortNumber, RegionCode.BR, false));
916 
917     // Test that the Australian emergency number 000 is formatted correctly.
918     PhoneNumber auNumber = new PhoneNumber().setCountryCode(61).setNationalNumber(0L)
919         .setItalianLeadingZero(true).setNumberOfLeadingZeros(2);
920     assertEquals("000", phoneUtil.formatNumberForMobileDialing(auNumber, RegionCode.AU, false));
921     assertEquals("", phoneUtil.formatNumberForMobileDialing(auNumber, RegionCode.NZ, false));
922   }
923 
testFormatByPattern()924   public void testFormatByPattern() {
925     NumberFormat.Builder newNumFormat = NumberFormat.newBuilder();
926     newNumFormat.setPattern("(\\d{3})(\\d{3})(\\d{4})");
927     newNumFormat.setFormat("($1) $2-$3");
928     List<NumberFormat> newNumberFormats = new ArrayList<NumberFormat>();
929     newNumberFormats.add(newNumFormat.build());
930 
931     assertEquals("(650) 253-0000", phoneUtil.formatByPattern(US_NUMBER, PhoneNumberFormat.NATIONAL,
932                                                              newNumberFormats));
933     assertEquals("+1 (650) 253-0000", phoneUtil.formatByPattern(US_NUMBER,
934                                                                 PhoneNumberFormat.INTERNATIONAL,
935                                                                 newNumberFormats));
936     PhoneNumber usNumber2 = new PhoneNumber().setCountryCode(1).setNationalNumber(6507129823L);
937     assertEquals(
938         "tel:+1-650-712-9823",
939         phoneUtil.formatByPattern(usNumber2, PhoneNumberFormat.RFC3966, newNumberFormats));
940 
941     // $NP is set to '1' for the US. Here we check that for other NANPA countries the US rules are
942     // followed.
943     newNumFormat.setNationalPrefixFormattingRule("$NP ($FG)");
944     newNumFormat.setFormat("$1 $2-$3");
945     newNumberFormats.set(0, newNumFormat.build());
946     assertEquals("1 (242) 365-1234",
947                  phoneUtil.formatByPattern(BS_NUMBER, PhoneNumberFormat.NATIONAL,
948                                            newNumberFormats));
949     assertEquals("+1 242 365-1234",
950                  phoneUtil.formatByPattern(BS_NUMBER, PhoneNumberFormat.INTERNATIONAL,
951                                            newNumberFormats));
952 
953     newNumFormat.setPattern("(\\d{2})(\\d{5})(\\d{3})");
954     newNumFormat.setFormat("$1-$2 $3");
955     newNumberFormats.set(0, newNumFormat.build());
956 
957     assertEquals("02-36618 300",
958                  phoneUtil.formatByPattern(IT_NUMBER, PhoneNumberFormat.NATIONAL,
959                                            newNumberFormats));
960     assertEquals("+39 02-36618 300",
961                  phoneUtil.formatByPattern(IT_NUMBER, PhoneNumberFormat.INTERNATIONAL,
962                                            newNumberFormats));
963 
964     newNumFormat.setNationalPrefixFormattingRule("$NP$FG");
965     newNumFormat.setPattern("(\\d{2})(\\d{4})(\\d{4})");
966     newNumFormat.setFormat("$1 $2 $3");
967     newNumberFormats.set(0, newNumFormat.build());
968     assertEquals("020 7031 3000",
969                  phoneUtil.formatByPattern(GB_NUMBER, PhoneNumberFormat.NATIONAL,
970                                            newNumberFormats));
971 
972     newNumFormat.setNationalPrefixFormattingRule("($NP$FG)");
973     newNumberFormats.set(0, newNumFormat.build());
974     assertEquals("(020) 7031 3000",
975                  phoneUtil.formatByPattern(GB_NUMBER, PhoneNumberFormat.NATIONAL,
976                                            newNumberFormats));
977 
978     newNumFormat.setNationalPrefixFormattingRule("");
979     newNumberFormats.set(0, newNumFormat.build());
980     assertEquals("20 7031 3000",
981                  phoneUtil.formatByPattern(GB_NUMBER, PhoneNumberFormat.NATIONAL,
982                                            newNumberFormats));
983 
984     assertEquals("+44 20 7031 3000",
985                  phoneUtil.formatByPattern(GB_NUMBER, PhoneNumberFormat.INTERNATIONAL,
986                                            newNumberFormats));
987   }
988 
testFormatE164Number()989   public void testFormatE164Number() {
990     assertEquals("+16502530000", phoneUtil.format(US_NUMBER, PhoneNumberFormat.E164));
991     assertEquals("+4930123456", phoneUtil.format(DE_NUMBER, PhoneNumberFormat.E164));
992     assertEquals("+80012345678", phoneUtil.format(INTERNATIONAL_TOLL_FREE, PhoneNumberFormat.E164));
993   }
994 
testFormatNumberWithExtension()995   public void testFormatNumberWithExtension() {
996     PhoneNumber nzNumber = new PhoneNumber().mergeFrom(NZ_NUMBER).setExtension("1234");
997     // Uses default extension prefix:
998     assertEquals("03-331 6005 ext. 1234", phoneUtil.format(nzNumber, PhoneNumberFormat.NATIONAL));
999     // Uses RFC 3966 syntax.
1000     assertEquals("tel:+64-3-331-6005;ext=1234",
1001         phoneUtil.format(nzNumber, PhoneNumberFormat.RFC3966));
1002     // Extension prefix overridden in the territory information for the US:
1003     PhoneNumber usNumberWithExtension = new PhoneNumber().mergeFrom(US_NUMBER).setExtension("4567");
1004     assertEquals("650 253 0000 extn. 4567", phoneUtil.format(usNumberWithExtension,
1005                                                              PhoneNumberFormat.NATIONAL));
1006   }
1007 
testFormatInOriginalFormat()1008   public void testFormatInOriginalFormat() throws Exception {
1009     PhoneNumber number1 = phoneUtil.parseAndKeepRawInput("+442087654321", RegionCode.GB);
1010     assertEquals("+44 20 8765 4321", phoneUtil.formatInOriginalFormat(number1, RegionCode.GB));
1011 
1012     PhoneNumber number2 = phoneUtil.parseAndKeepRawInput("02087654321", RegionCode.GB);
1013     assertEquals("(020) 8765 4321", phoneUtil.formatInOriginalFormat(number2, RegionCode.GB));
1014 
1015     PhoneNumber number3 = phoneUtil.parseAndKeepRawInput("011442087654321", RegionCode.US);
1016     assertEquals("011 44 20 8765 4321", phoneUtil.formatInOriginalFormat(number3, RegionCode.US));
1017 
1018     PhoneNumber number4 = phoneUtil.parseAndKeepRawInput("442087654321", RegionCode.GB);
1019     assertEquals("44 20 8765 4321", phoneUtil.formatInOriginalFormat(number4, RegionCode.GB));
1020 
1021     PhoneNumber number5 = phoneUtil.parse("+442087654321", RegionCode.GB);
1022     assertEquals("(020) 8765 4321", phoneUtil.formatInOriginalFormat(number5, RegionCode.GB));
1023 
1024     // Invalid numbers that we have a formatting pattern for should be formatted properly. Note area
1025     // codes starting with 7 are intentionally excluded in the test metadata for testing purposes.
1026     PhoneNumber number6 = phoneUtil.parseAndKeepRawInput("7345678901", RegionCode.US);
1027     assertEquals("734 567 8901", phoneUtil.formatInOriginalFormat(number6, RegionCode.US));
1028 
1029     // US is not a leading zero country, and the presence of the leading zero leads us to format the
1030     // number using raw_input.
1031     PhoneNumber number7 = phoneUtil.parseAndKeepRawInput("0734567 8901", RegionCode.US);
1032     assertEquals("0734567 8901", phoneUtil.formatInOriginalFormat(number7, RegionCode.US));
1033 
1034     // This number is valid, but we don't have a formatting pattern for it. Fall back to the raw
1035     // input.
1036     PhoneNumber number8 = phoneUtil.parseAndKeepRawInput("02-4567-8900", RegionCode.KR);
1037     assertEquals("02-4567-8900", phoneUtil.formatInOriginalFormat(number8, RegionCode.KR));
1038 
1039     PhoneNumber number9 = phoneUtil.parseAndKeepRawInput("01180012345678", RegionCode.US);
1040     assertEquals("011 800 1234 5678", phoneUtil.formatInOriginalFormat(number9, RegionCode.US));
1041 
1042     PhoneNumber number10 = phoneUtil.parseAndKeepRawInput("+80012345678", RegionCode.KR);
1043     assertEquals("+800 1234 5678", phoneUtil.formatInOriginalFormat(number10, RegionCode.KR));
1044 
1045     // US local numbers are formatted correctly, as we have formatting patterns for them.
1046     PhoneNumber localNumberUS = phoneUtil.parseAndKeepRawInput("2530000", RegionCode.US);
1047     assertEquals("253 0000", phoneUtil.formatInOriginalFormat(localNumberUS, RegionCode.US));
1048 
1049     PhoneNumber numberWithNationalPrefixUS =
1050         phoneUtil.parseAndKeepRawInput("18003456789", RegionCode.US);
1051     assertEquals("1 800 345 6789",
1052         phoneUtil.formatInOriginalFormat(numberWithNationalPrefixUS, RegionCode.US));
1053 
1054     PhoneNumber numberWithoutNationalPrefixGB =
1055         phoneUtil.parseAndKeepRawInput("2087654321", RegionCode.GB);
1056     assertEquals("20 8765 4321",
1057         phoneUtil.formatInOriginalFormat(numberWithoutNationalPrefixGB, RegionCode.GB));
1058     // Make sure no metadata is modified as a result of the previous function call.
1059     assertEquals("(020) 8765 4321", phoneUtil.formatInOriginalFormat(number5, RegionCode.GB));
1060 
1061     PhoneNumber numberWithNationalPrefixMX =
1062         phoneUtil.parseAndKeepRawInput("013312345678", RegionCode.MX);
1063     assertEquals("01 33 1234 5678",
1064         phoneUtil.formatInOriginalFormat(numberWithNationalPrefixMX, RegionCode.MX));
1065 
1066     PhoneNumber numberWithoutNationalPrefixMX =
1067         phoneUtil.parseAndKeepRawInput("3312345678", RegionCode.MX);
1068     assertEquals("33 1234 5678",
1069         phoneUtil.formatInOriginalFormat(numberWithoutNationalPrefixMX, RegionCode.MX));
1070 
1071     PhoneNumber italianFixedLineNumber =
1072         phoneUtil.parseAndKeepRawInput("0212345678", RegionCode.IT);
1073     assertEquals("02 1234 5678",
1074         phoneUtil.formatInOriginalFormat(italianFixedLineNumber, RegionCode.IT));
1075 
1076     PhoneNumber numberWithNationalPrefixJP =
1077         phoneUtil.parseAndKeepRawInput("00777012", RegionCode.JP);
1078     assertEquals("0077-7012",
1079         phoneUtil.formatInOriginalFormat(numberWithNationalPrefixJP, RegionCode.JP));
1080 
1081     PhoneNumber numberWithoutNationalPrefixJP =
1082         phoneUtil.parseAndKeepRawInput("0777012", RegionCode.JP);
1083     assertEquals("0777012",
1084         phoneUtil.formatInOriginalFormat(numberWithoutNationalPrefixJP, RegionCode.JP));
1085 
1086     PhoneNumber numberWithCarrierCodeBR =
1087         phoneUtil.parseAndKeepRawInput("012 3121286979", RegionCode.BR);
1088     assertEquals("012 3121286979",
1089         phoneUtil.formatInOriginalFormat(numberWithCarrierCodeBR, RegionCode.BR));
1090 
1091     // The default national prefix used in this case is 045. When a number with national prefix 044
1092     // is entered, we return the raw input as we don't want to change the number entered.
1093     PhoneNumber numberWithNationalPrefixMX1 =
1094         phoneUtil.parseAndKeepRawInput("044(33)1234-5678", RegionCode.MX);
1095     assertEquals("044(33)1234-5678",
1096         phoneUtil.formatInOriginalFormat(numberWithNationalPrefixMX1, RegionCode.MX));
1097 
1098     PhoneNumber numberWithNationalPrefixMX2 =
1099         phoneUtil.parseAndKeepRawInput("045(33)1234-5678", RegionCode.MX);
1100     assertEquals("045 33 1234 5678",
1101         phoneUtil.formatInOriginalFormat(numberWithNationalPrefixMX2, RegionCode.MX));
1102 
1103     // The default international prefix used in this case is 0011. When a number with international
1104     // prefix 0012 is entered, we return the raw input as we don't want to change the number
1105     // entered.
1106     PhoneNumber outOfCountryNumberFromAU1 =
1107         phoneUtil.parseAndKeepRawInput("0012 16502530000", RegionCode.AU);
1108     assertEquals("0012 16502530000",
1109         phoneUtil.formatInOriginalFormat(outOfCountryNumberFromAU1, RegionCode.AU));
1110 
1111     PhoneNumber outOfCountryNumberFromAU2 =
1112         phoneUtil.parseAndKeepRawInput("0011 16502530000", RegionCode.AU);
1113     assertEquals("0011 1 650 253 0000",
1114         phoneUtil.formatInOriginalFormat(outOfCountryNumberFromAU2, RegionCode.AU));
1115 
1116     // Test the star sign is not removed from or added to the original input by this method.
1117     PhoneNumber starNumber = phoneUtil.parseAndKeepRawInput("*1234", RegionCode.JP);
1118     assertEquals("*1234", phoneUtil.formatInOriginalFormat(starNumber, RegionCode.JP));
1119     PhoneNumber numberWithoutStar = phoneUtil.parseAndKeepRawInput("1234", RegionCode.JP);
1120     assertEquals("1234", phoneUtil.formatInOriginalFormat(numberWithoutStar, RegionCode.JP));
1121 
1122     // Test an invalid national number without raw input is just formatted as the national number.
1123     assertEquals("650253000",
1124         phoneUtil.formatInOriginalFormat(US_SHORT_BY_ONE_NUMBER, RegionCode.US));
1125   }
1126 
testIsPremiumRate()1127   public void testIsPremiumRate() {
1128     assertEquals(PhoneNumberType.PREMIUM_RATE, phoneUtil.getNumberType(US_PREMIUM));
1129 
1130     PhoneNumber premiumRateNumber = new PhoneNumber();
1131     premiumRateNumber.setCountryCode(39).setNationalNumber(892123L);
1132     assertEquals(PhoneNumberType.PREMIUM_RATE, phoneUtil.getNumberType(premiumRateNumber));
1133 
1134     premiumRateNumber.clear();
1135     premiumRateNumber.setCountryCode(44).setNationalNumber(9187654321L);
1136     assertEquals(PhoneNumberType.PREMIUM_RATE, phoneUtil.getNumberType(premiumRateNumber));
1137 
1138     premiumRateNumber.clear();
1139     premiumRateNumber.setCountryCode(49).setNationalNumber(9001654321L);
1140     assertEquals(PhoneNumberType.PREMIUM_RATE, phoneUtil.getNumberType(premiumRateNumber));
1141 
1142     premiumRateNumber.clear();
1143     premiumRateNumber.setCountryCode(49).setNationalNumber(90091234567L);
1144     assertEquals(PhoneNumberType.PREMIUM_RATE, phoneUtil.getNumberType(premiumRateNumber));
1145 
1146     assertEquals(PhoneNumberType.PREMIUM_RATE, phoneUtil.getNumberType(UNIVERSAL_PREMIUM_RATE));
1147   }
1148 
testIsTollFree()1149   public void testIsTollFree() {
1150     PhoneNumber tollFreeNumber = new PhoneNumber();
1151 
1152     tollFreeNumber.setCountryCode(1).setNationalNumber(8881234567L);
1153     assertEquals(PhoneNumberType.TOLL_FREE, phoneUtil.getNumberType(tollFreeNumber));
1154 
1155     tollFreeNumber.clear();
1156     tollFreeNumber.setCountryCode(39).setNationalNumber(803123L);
1157     assertEquals(PhoneNumberType.TOLL_FREE, phoneUtil.getNumberType(tollFreeNumber));
1158 
1159     tollFreeNumber.clear();
1160     tollFreeNumber.setCountryCode(44).setNationalNumber(8012345678L);
1161     assertEquals(PhoneNumberType.TOLL_FREE, phoneUtil.getNumberType(tollFreeNumber));
1162 
1163     tollFreeNumber.clear();
1164     tollFreeNumber.setCountryCode(49).setNationalNumber(8001234567L);
1165     assertEquals(PhoneNumberType.TOLL_FREE, phoneUtil.getNumberType(tollFreeNumber));
1166 
1167     assertEquals(PhoneNumberType.TOLL_FREE, phoneUtil.getNumberType(INTERNATIONAL_TOLL_FREE));
1168   }
1169 
testIsMobile()1170   public void testIsMobile() {
1171     assertEquals(PhoneNumberType.MOBILE, phoneUtil.getNumberType(BS_MOBILE));
1172     assertEquals(PhoneNumberType.MOBILE, phoneUtil.getNumberType(GB_MOBILE));
1173     assertEquals(PhoneNumberType.MOBILE, phoneUtil.getNumberType(IT_MOBILE));
1174     assertEquals(PhoneNumberType.MOBILE, phoneUtil.getNumberType(AR_MOBILE));
1175 
1176     PhoneNumber mobileNumber = new PhoneNumber();
1177     mobileNumber.setCountryCode(49).setNationalNumber(15123456789L);
1178     assertEquals(PhoneNumberType.MOBILE, phoneUtil.getNumberType(mobileNumber));
1179   }
1180 
testIsFixedLine()1181   public void testIsFixedLine() {
1182     assertEquals(PhoneNumberType.FIXED_LINE, phoneUtil.getNumberType(BS_NUMBER));
1183     assertEquals(PhoneNumberType.FIXED_LINE, phoneUtil.getNumberType(IT_NUMBER));
1184     assertEquals(PhoneNumberType.FIXED_LINE, phoneUtil.getNumberType(GB_NUMBER));
1185     assertEquals(PhoneNumberType.FIXED_LINE, phoneUtil.getNumberType(DE_NUMBER));
1186   }
1187 
testIsFixedLineAndMobile()1188   public void testIsFixedLineAndMobile() {
1189     assertEquals(PhoneNumberType.FIXED_LINE_OR_MOBILE, phoneUtil.getNumberType(US_NUMBER));
1190 
1191     PhoneNumber fixedLineAndMobileNumber = new PhoneNumber().
1192         setCountryCode(54).setNationalNumber(1987654321L);
1193     assertEquals(
1194         PhoneNumberType.FIXED_LINE_OR_MOBILE, phoneUtil.getNumberType(fixedLineAndMobileNumber));
1195   }
1196 
testIsSharedCost()1197   public void testIsSharedCost() {
1198     PhoneNumber gbNumber = new PhoneNumber();
1199     gbNumber.setCountryCode(44).setNationalNumber(8431231234L);
1200     assertEquals(PhoneNumberType.SHARED_COST, phoneUtil.getNumberType(gbNumber));
1201   }
1202 
testIsVoip()1203   public void testIsVoip() {
1204     PhoneNumber gbNumber = new PhoneNumber();
1205     gbNumber.setCountryCode(44).setNationalNumber(5631231234L);
1206     assertEquals(PhoneNumberType.VOIP, phoneUtil.getNumberType(gbNumber));
1207   }
1208 
testIsPersonalNumber()1209   public void testIsPersonalNumber() {
1210     PhoneNumber gbNumber = new PhoneNumber();
1211     gbNumber.setCountryCode(44).setNationalNumber(7031231234L);
1212     assertEquals(PhoneNumberType.PERSONAL_NUMBER, phoneUtil.getNumberType(gbNumber));
1213   }
1214 
testIsUnknown()1215   public void testIsUnknown() {
1216     // Invalid numbers should be of type UNKNOWN.
1217     assertEquals(PhoneNumberType.UNKNOWN, phoneUtil.getNumberType(US_LOCAL_NUMBER));
1218   }
1219 
testIsValidNumber()1220   public void testIsValidNumber() {
1221     assertTrue(phoneUtil.isValidNumber(US_NUMBER));
1222     assertTrue(phoneUtil.isValidNumber(IT_NUMBER));
1223     assertTrue(phoneUtil.isValidNumber(GB_MOBILE));
1224     assertTrue(phoneUtil.isValidNumber(INTERNATIONAL_TOLL_FREE));
1225     assertTrue(phoneUtil.isValidNumber(UNIVERSAL_PREMIUM_RATE));
1226 
1227     PhoneNumber nzNumber = new PhoneNumber().setCountryCode(64).setNationalNumber(21387835L);
1228     assertTrue(phoneUtil.isValidNumber(nzNumber));
1229   }
1230 
testIsValidForRegion()1231   public void testIsValidForRegion() {
1232     // This number is valid for the Bahamas, but is not a valid US number.
1233     assertTrue(phoneUtil.isValidNumber(BS_NUMBER));
1234     assertTrue(phoneUtil.isValidNumberForRegion(BS_NUMBER, RegionCode.BS));
1235     assertFalse(phoneUtil.isValidNumberForRegion(BS_NUMBER, RegionCode.US));
1236     PhoneNumber bsInvalidNumber =
1237         new PhoneNumber().setCountryCode(1).setNationalNumber(2421232345L);
1238     // This number is no longer valid.
1239     assertFalse(phoneUtil.isValidNumber(bsInvalidNumber));
1240 
1241     // La Mayotte and Reunion use 'leadingDigits' to differentiate them.
1242     PhoneNumber reNumber = new PhoneNumber();
1243     reNumber.setCountryCode(262).setNationalNumber(262123456L);
1244     assertTrue(phoneUtil.isValidNumber(reNumber));
1245     assertTrue(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.RE));
1246     assertFalse(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.YT));
1247     // Now change the number to be a number for La Mayotte.
1248     reNumber.setNationalNumber(269601234L);
1249     assertTrue(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.YT));
1250     assertFalse(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.RE));
1251     // This number is no longer valid for La Reunion.
1252     reNumber.setNationalNumber(269123456L);
1253     assertFalse(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.YT));
1254     assertFalse(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.RE));
1255     assertFalse(phoneUtil.isValidNumber(reNumber));
1256     // However, it should be recognised as from La Mayotte, since it is valid for this region.
1257     assertEquals(RegionCode.YT, phoneUtil.getRegionCodeForNumber(reNumber));
1258     // This number is valid in both places.
1259     reNumber.setNationalNumber(800123456L);
1260     assertTrue(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.YT));
1261     assertTrue(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.RE));
1262     assertTrue(phoneUtil.isValidNumberForRegion(INTERNATIONAL_TOLL_FREE, RegionCode.UN001));
1263     assertFalse(phoneUtil.isValidNumberForRegion(INTERNATIONAL_TOLL_FREE, RegionCode.US));
1264     assertFalse(phoneUtil.isValidNumberForRegion(INTERNATIONAL_TOLL_FREE, RegionCode.ZZ));
1265 
1266     PhoneNumber invalidNumber = new PhoneNumber();
1267     // Invalid country calling codes.
1268     invalidNumber.setCountryCode(3923).setNationalNumber(2366L);
1269     assertFalse(phoneUtil.isValidNumberForRegion(invalidNumber, RegionCode.ZZ));
1270     assertFalse(phoneUtil.isValidNumberForRegion(invalidNumber, RegionCode.UN001));
1271     invalidNumber.setCountryCode(0);
1272     assertFalse(phoneUtil.isValidNumberForRegion(invalidNumber, RegionCode.UN001));
1273     assertFalse(phoneUtil.isValidNumberForRegion(invalidNumber, RegionCode.ZZ));
1274   }
1275 
testIsNotValidNumber()1276   public void testIsNotValidNumber() {
1277     assertFalse(phoneUtil.isValidNumber(US_LOCAL_NUMBER));
1278 
1279     PhoneNumber invalidNumber = new PhoneNumber();
1280     invalidNumber.setCountryCode(39).setNationalNumber(23661830000L).setItalianLeadingZero(true);
1281     assertFalse(phoneUtil.isValidNumber(invalidNumber));
1282 
1283     invalidNumber.clear();
1284     invalidNumber.setCountryCode(44).setNationalNumber(791234567L);
1285     assertFalse(phoneUtil.isValidNumber(invalidNumber));
1286 
1287     invalidNumber.clear();
1288     invalidNumber.setCountryCode(49).setNationalNumber(1234L);
1289     assertFalse(phoneUtil.isValidNumber(invalidNumber));
1290 
1291     invalidNumber.clear();
1292     invalidNumber.setCountryCode(64).setNationalNumber(3316005L);
1293     assertFalse(phoneUtil.isValidNumber(invalidNumber));
1294 
1295     invalidNumber.clear();
1296     // Invalid country calling codes.
1297     invalidNumber.setCountryCode(3923).setNationalNumber(2366L);
1298     assertFalse(phoneUtil.isValidNumber(invalidNumber));
1299     invalidNumber.setCountryCode(0);
1300     assertFalse(phoneUtil.isValidNumber(invalidNumber));
1301 
1302     assertFalse(phoneUtil.isValidNumber(INTERNATIONAL_TOLL_FREE_TOO_LONG));
1303   }
1304 
testGetRegionCodeForCountryCode()1305   public void testGetRegionCodeForCountryCode() {
1306     assertEquals(RegionCode.US, phoneUtil.getRegionCodeForCountryCode(1));
1307     assertEquals(RegionCode.GB, phoneUtil.getRegionCodeForCountryCode(44));
1308     assertEquals(RegionCode.DE, phoneUtil.getRegionCodeForCountryCode(49));
1309     assertEquals(RegionCode.UN001, phoneUtil.getRegionCodeForCountryCode(800));
1310     assertEquals(RegionCode.UN001, phoneUtil.getRegionCodeForCountryCode(979));
1311   }
1312 
testGetRegionCodeForNumber()1313   public void testGetRegionCodeForNumber() {
1314     assertEquals(RegionCode.BS, phoneUtil.getRegionCodeForNumber(BS_NUMBER));
1315     assertEquals(RegionCode.US, phoneUtil.getRegionCodeForNumber(US_NUMBER));
1316     assertEquals(RegionCode.GB, phoneUtil.getRegionCodeForNumber(GB_MOBILE));
1317     assertEquals(RegionCode.UN001, phoneUtil.getRegionCodeForNumber(INTERNATIONAL_TOLL_FREE));
1318     assertEquals(RegionCode.UN001, phoneUtil.getRegionCodeForNumber(UNIVERSAL_PREMIUM_RATE));
1319   }
1320 
testGetRegionCodesForCountryCode()1321   public void testGetRegionCodesForCountryCode() {
1322     List<String> regionCodesForNANPA = phoneUtil.getRegionCodesForCountryCode(1);
1323     assertTrue(regionCodesForNANPA.contains(RegionCode.US));
1324     assertTrue(regionCodesForNANPA.contains(RegionCode.BS));
1325     assertTrue(phoneUtil.getRegionCodesForCountryCode(44).contains(RegionCode.GB));
1326     assertTrue(phoneUtil.getRegionCodesForCountryCode(49).contains(RegionCode.DE));
1327     assertTrue(phoneUtil.getRegionCodesForCountryCode(800).contains(RegionCode.UN001));
1328     // Test with invalid country calling code.
1329     assertTrue(phoneUtil.getRegionCodesForCountryCode(-1).isEmpty());
1330   }
1331 
testGetCountryCodeForRegion()1332   public void testGetCountryCodeForRegion() {
1333     assertEquals(1, phoneUtil.getCountryCodeForRegion(RegionCode.US));
1334     assertEquals(64, phoneUtil.getCountryCodeForRegion(RegionCode.NZ));
1335     assertEquals(0, phoneUtil.getCountryCodeForRegion(null));
1336     assertEquals(0, phoneUtil.getCountryCodeForRegion(RegionCode.ZZ));
1337     assertEquals(0, phoneUtil.getCountryCodeForRegion(RegionCode.UN001));
1338     // CS is already deprecated so the library doesn't support it.
1339     assertEquals(0, phoneUtil.getCountryCodeForRegion("CS"));
1340   }
1341 
testGetNationalDiallingPrefixForRegion()1342   public void testGetNationalDiallingPrefixForRegion() {
1343     assertEquals("1", phoneUtil.getNddPrefixForRegion(RegionCode.US, false));
1344     // Test non-main country to see it gets the national dialling prefix for the main country with
1345     // that country calling code.
1346     assertEquals("1", phoneUtil.getNddPrefixForRegion(RegionCode.BS, false));
1347     assertEquals("0", phoneUtil.getNddPrefixForRegion(RegionCode.NZ, false));
1348     // Test case with non digit in the national prefix.
1349     assertEquals("0~0", phoneUtil.getNddPrefixForRegion(RegionCode.AO, false));
1350     assertEquals("00", phoneUtil.getNddPrefixForRegion(RegionCode.AO, true));
1351     // Test cases with invalid regions.
1352     assertEquals(null, phoneUtil.getNddPrefixForRegion(null, false));
1353     assertEquals(null, phoneUtil.getNddPrefixForRegion(RegionCode.ZZ, false));
1354     assertEquals(null, phoneUtil.getNddPrefixForRegion(RegionCode.UN001, false));
1355     // CS is already deprecated so the library doesn't support it.
1356     assertEquals(null, phoneUtil.getNddPrefixForRegion("CS", false));
1357   }
1358 
testIsNANPACountry()1359   public void testIsNANPACountry() {
1360     assertTrue(phoneUtil.isNANPACountry(RegionCode.US));
1361     assertTrue(phoneUtil.isNANPACountry(RegionCode.BS));
1362     assertFalse(phoneUtil.isNANPACountry(RegionCode.DE));
1363     assertFalse(phoneUtil.isNANPACountry(RegionCode.ZZ));
1364     assertFalse(phoneUtil.isNANPACountry(RegionCode.UN001));
1365     assertFalse(phoneUtil.isNANPACountry(null));
1366   }
1367 
testIsPossibleNumber()1368   public void testIsPossibleNumber() {
1369     assertTrue(phoneUtil.isPossibleNumber(US_NUMBER));
1370     assertTrue(phoneUtil.isPossibleNumber(US_LOCAL_NUMBER));
1371     assertTrue(phoneUtil.isPossibleNumber(GB_NUMBER));
1372     assertTrue(phoneUtil.isPossibleNumber(INTERNATIONAL_TOLL_FREE));
1373 
1374     assertTrue(phoneUtil.isPossibleNumber("+1 650 253 0000", RegionCode.US));
1375     assertTrue(phoneUtil.isPossibleNumber("+1 650 GOO OGLE", RegionCode.US));
1376     assertTrue(phoneUtil.isPossibleNumber("(650) 253-0000", RegionCode.US));
1377     assertTrue(phoneUtil.isPossibleNumber("253-0000", RegionCode.US));
1378     assertTrue(phoneUtil.isPossibleNumber("+1 650 253 0000", RegionCode.GB));
1379     assertTrue(phoneUtil.isPossibleNumber("+44 20 7031 3000", RegionCode.GB));
1380     assertTrue(phoneUtil.isPossibleNumber("(020) 7031 300", RegionCode.GB));
1381     assertTrue(phoneUtil.isPossibleNumber("7031 3000", RegionCode.GB));
1382     assertTrue(phoneUtil.isPossibleNumber("3331 6005", RegionCode.NZ));
1383     assertTrue(phoneUtil.isPossibleNumber("+800 1234 5678", RegionCode.UN001));
1384   }
1385 
testIsPossibleNumberForType_DifferentTypeLengths()1386   public void testIsPossibleNumberForType_DifferentTypeLengths() {
1387     // We use Argentinian numbers since they have different possible lengths for different types.
1388     PhoneNumber number = new PhoneNumber();
1389     number.setCountryCode(54).setNationalNumber(12345L);
1390     // Too short for any Argentinian number, including fixed-line.
1391     assertFalse(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.FIXED_LINE));
1392     assertFalse(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.UNKNOWN));
1393 
1394     // 6-digit numbers are okay for fixed-line.
1395     number.setNationalNumber(123456L);
1396     assertTrue(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.UNKNOWN));
1397     assertTrue(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.FIXED_LINE));
1398     // But too short for mobile.
1399     assertFalse(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.MOBILE));
1400     // And too short for toll-free.
1401     assertFalse(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.TOLL_FREE));
1402 
1403     // The same applies to 9-digit numbers.
1404     number.setNationalNumber(123456789L);
1405     assertTrue(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.UNKNOWN));
1406     assertTrue(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.FIXED_LINE));
1407     assertFalse(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.MOBILE));
1408     assertFalse(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.TOLL_FREE));
1409 
1410     // 10-digit numbers are universally possible.
1411     number.setNationalNumber(1234567890L);
1412     assertTrue(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.UNKNOWN));
1413     assertTrue(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.FIXED_LINE));
1414     assertTrue(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.MOBILE));
1415     assertTrue(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.TOLL_FREE));
1416 
1417     // 11-digit numbers are only possible for mobile numbers. Note we don't require the leading 9,
1418     // which all mobile numbers start with, and would be required for a valid mobile number.
1419     number.setNationalNumber(12345678901L);
1420     assertTrue(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.UNKNOWN));
1421     assertFalse(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.FIXED_LINE));
1422     assertTrue(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.MOBILE));
1423     assertFalse(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.TOLL_FREE));
1424   }
1425 
testIsPossibleNumberForType_LocalOnly()1426   public void testIsPossibleNumberForType_LocalOnly() {
1427     PhoneNumber number = new PhoneNumber();
1428     // Here we test a number length which matches a local-only length.
1429     number.setCountryCode(49).setNationalNumber(12L);
1430     assertTrue(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.UNKNOWN));
1431     assertTrue(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.FIXED_LINE));
1432     // Mobile numbers must be 10 or 11 digits, and there are no local-only lengths.
1433     assertFalse(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.MOBILE));
1434   }
1435 
testIsPossibleNumberForType_DataMissingForSizeReasons()1436   public void testIsPossibleNumberForType_DataMissingForSizeReasons() {
1437     PhoneNumber number = new PhoneNumber();
1438     // Here we test something where the possible lengths match the possible lengths of the country
1439     // as a whole, and hence aren't present in the binary for size reasons - this should still work.
1440     // Local-only number.
1441     number.setCountryCode(55).setNationalNumber(12345678L);
1442     assertTrue(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.UNKNOWN));
1443     assertTrue(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.FIXED_LINE));
1444 
1445     number.setNationalNumber(1234567890L);
1446     assertTrue(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.UNKNOWN));
1447     assertTrue(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.FIXED_LINE));
1448   }
1449 
testIsPossibleNumberForType_NumberTypeNotSupportedForRegion()1450   public void testIsPossibleNumberForType_NumberTypeNotSupportedForRegion() {
1451     PhoneNumber number = new PhoneNumber();
1452     // There are *no* mobile numbers for this region at all, so we return false.
1453     number.setCountryCode(55).setNationalNumber(12345678L);
1454     assertFalse(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.MOBILE));
1455     // This matches a fixed-line length though.
1456     assertTrue(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.FIXED_LINE));
1457     assertTrue(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.FIXED_LINE_OR_MOBILE));
1458 
1459     // There are *no* fixed-line OR mobile numbers for this country calling code at all, so we
1460     // return false for these.
1461     number.setCountryCode(979).setNationalNumber(123456789L);
1462     assertFalse(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.MOBILE));
1463     assertFalse(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.FIXED_LINE));
1464     assertFalse(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.FIXED_LINE_OR_MOBILE));
1465     assertTrue(phoneUtil.isPossibleNumberForType(number, PhoneNumberType.PREMIUM_RATE));
1466   }
1467 
testIsPossibleNumberWithReason()1468   public void testIsPossibleNumberWithReason() {
1469     // National numbers for country calling code +1 that are within 7 to 10 digits are possible.
1470     assertEquals(ValidationResult.IS_POSSIBLE, phoneUtil.isPossibleNumberWithReason(US_NUMBER));
1471 
1472     assertEquals(ValidationResult.IS_POSSIBLE_LOCAL_ONLY,
1473         phoneUtil.isPossibleNumberWithReason(US_LOCAL_NUMBER));
1474 
1475     assertEquals(ValidationResult.TOO_LONG, phoneUtil.isPossibleNumberWithReason(US_LONG_NUMBER));
1476 
1477     PhoneNumber number = new PhoneNumber();
1478     number.setCountryCode(0).setNationalNumber(2530000L);
1479     assertEquals(
1480         ValidationResult.INVALID_COUNTRY_CODE, phoneUtil.isPossibleNumberWithReason(number));
1481 
1482     number.clear();
1483     number.setCountryCode(1).setNationalNumber(253000L);
1484     assertEquals(ValidationResult.TOO_SHORT, phoneUtil.isPossibleNumberWithReason(number));
1485 
1486     number.clear();
1487     number.setCountryCode(65).setNationalNumber(1234567890L);
1488     assertEquals(ValidationResult.IS_POSSIBLE, phoneUtil.isPossibleNumberWithReason(number));
1489 
1490     assertEquals(
1491         ValidationResult.TOO_LONG,
1492         phoneUtil.isPossibleNumberWithReason(INTERNATIONAL_TOLL_FREE_TOO_LONG));
1493   }
1494 
testIsPossibleNumberForTypeWithReason_DifferentTypeLengths()1495   public void testIsPossibleNumberForTypeWithReason_DifferentTypeLengths() {
1496     // We use Argentinian numbers since they have different possible lengths for different types.
1497     PhoneNumber number = new PhoneNumber();
1498     number.setCountryCode(54).setNationalNumber(12345L);
1499     // Too short for any Argentinian number.
1500     assertEquals(
1501         ValidationResult.TOO_SHORT,
1502         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.UNKNOWN));
1503     assertEquals(
1504         ValidationResult.TOO_SHORT,
1505         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE));
1506 
1507     // 6-digit numbers are okay for fixed-line.
1508     number.setNationalNumber(123456L);
1509     assertEquals(
1510         ValidationResult.IS_POSSIBLE,
1511         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.UNKNOWN));
1512     assertEquals(
1513         ValidationResult.IS_POSSIBLE,
1514         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE));
1515     // But too short for mobile.
1516     assertEquals(
1517         ValidationResult.TOO_SHORT,
1518         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.MOBILE));
1519     // And too short for toll-free.
1520     assertEquals(
1521         ValidationResult.TOO_SHORT,
1522         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.TOLL_FREE));
1523 
1524     // The same applies to 9-digit numbers.
1525     number.setNationalNumber(123456789L);
1526     assertEquals(
1527         ValidationResult.IS_POSSIBLE,
1528         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.UNKNOWN));
1529     assertEquals(
1530         ValidationResult.IS_POSSIBLE,
1531         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE));
1532     assertEquals(
1533         ValidationResult.TOO_SHORT,
1534         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.MOBILE));
1535     assertEquals(
1536         ValidationResult.TOO_SHORT,
1537         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.TOLL_FREE));
1538 
1539     // 10-digit numbers are universally possible.
1540     number.setNationalNumber(1234567890L);
1541     assertEquals(
1542         ValidationResult.IS_POSSIBLE,
1543         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.UNKNOWN));
1544     assertEquals(
1545         ValidationResult.IS_POSSIBLE,
1546         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE));
1547     assertEquals(
1548         ValidationResult.IS_POSSIBLE,
1549         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.MOBILE));
1550     assertEquals(
1551         ValidationResult.IS_POSSIBLE,
1552         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.TOLL_FREE));
1553 
1554     // 11-digit numbers are only possible for mobile numbers. Note we don't require the leading 9,
1555     // which all mobile numbers start with, and would be required for a valid mobile number.
1556     number.setNationalNumber(12345678901L);
1557     assertEquals(
1558         ValidationResult.IS_POSSIBLE,
1559         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.UNKNOWN));
1560     assertEquals(
1561         ValidationResult.TOO_LONG,
1562         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE));
1563     assertEquals(
1564         ValidationResult.IS_POSSIBLE,
1565         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.MOBILE));
1566     assertEquals(
1567         ValidationResult.TOO_LONG,
1568         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.TOLL_FREE));
1569   }
1570 
testIsPossibleNumberForTypeWithReason_LocalOnly()1571   public void testIsPossibleNumberForTypeWithReason_LocalOnly() {
1572     PhoneNumber number = new PhoneNumber();
1573     // Here we test a number length which matches a local-only length.
1574     number.setCountryCode(49).setNationalNumber(12L);
1575     assertEquals(
1576         ValidationResult.IS_POSSIBLE_LOCAL_ONLY,
1577         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.UNKNOWN));
1578     assertEquals(
1579         ValidationResult.IS_POSSIBLE_LOCAL_ONLY,
1580         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE));
1581     // Mobile numbers must be 10 or 11 digits, and there are no local-only lengths.
1582     assertEquals(
1583         ValidationResult.TOO_SHORT,
1584         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.MOBILE));
1585   }
1586 
testIsPossibleNumberForTypeWithReason_DataMissingForSizeReasons()1587   public void testIsPossibleNumberForTypeWithReason_DataMissingForSizeReasons() {
1588     PhoneNumber number = new PhoneNumber();
1589     // Here we test something where the possible lengths match the possible lengths of the country
1590     // as a whole, and hence aren't present in the binary for size reasons - this should still work.
1591     // Local-only number.
1592     number.setCountryCode(55).setNationalNumber(12345678L);
1593     assertEquals(
1594         ValidationResult.IS_POSSIBLE_LOCAL_ONLY,
1595         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.UNKNOWN));
1596     assertEquals(
1597         ValidationResult.IS_POSSIBLE_LOCAL_ONLY,
1598         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE));
1599 
1600     // Normal-length number.
1601     number.setNationalNumber(1234567890L);
1602     assertEquals(
1603         ValidationResult.IS_POSSIBLE,
1604         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.UNKNOWN));
1605     assertEquals(
1606         ValidationResult.IS_POSSIBLE,
1607         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE));
1608   }
1609 
testIsPossibleNumberForTypeWithReason_NumberTypeNotSupportedForRegion()1610   public void testIsPossibleNumberForTypeWithReason_NumberTypeNotSupportedForRegion() {
1611     PhoneNumber number = new PhoneNumber();
1612     // There are *no* mobile numbers for this region at all, so we return INVALID_LENGTH.
1613     number.setCountryCode(55).setNationalNumber(12345678L);
1614     assertEquals(
1615         ValidationResult.INVALID_LENGTH,
1616         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.MOBILE));
1617     // This matches a fixed-line length though.
1618     assertEquals(
1619         ValidationResult.IS_POSSIBLE_LOCAL_ONLY,
1620         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE_OR_MOBILE));
1621     // This is too short for fixed-line, and no mobile numbers exist.
1622     number.setCountryCode(55).setNationalNumber(1234567L);
1623     assertEquals(
1624         ValidationResult.INVALID_LENGTH,
1625         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.MOBILE));
1626     assertEquals(
1627         ValidationResult.TOO_SHORT,
1628         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE_OR_MOBILE));
1629     assertEquals(
1630         ValidationResult.TOO_SHORT,
1631         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE));
1632 
1633     // This is too short for mobile, and no fixed-line numbers exist.
1634     number.setCountryCode(882).setNationalNumber(1234567L);
1635     assertEquals(
1636         ValidationResult.TOO_SHORT,
1637         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.MOBILE));
1638     assertEquals(
1639         ValidationResult.TOO_SHORT,
1640         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE_OR_MOBILE));
1641     assertEquals(
1642         ValidationResult.INVALID_LENGTH,
1643         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE));
1644 
1645     // There are *no* fixed-line OR mobile numbers for this country calling code at all, so we
1646     // return INVALID_LENGTH.
1647     number.setCountryCode(979).setNationalNumber(123456789L);
1648     assertEquals(
1649         ValidationResult.INVALID_LENGTH,
1650         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.MOBILE));
1651     assertEquals(
1652         ValidationResult.INVALID_LENGTH,
1653         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE));
1654     assertEquals(
1655         ValidationResult.INVALID_LENGTH,
1656         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE_OR_MOBILE));
1657     assertEquals(
1658         ValidationResult.IS_POSSIBLE,
1659         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.PREMIUM_RATE));
1660   }
1661 
testIsPossibleNumberForTypeWithReason_FixedLineOrMobile()1662   public void testIsPossibleNumberForTypeWithReason_FixedLineOrMobile() {
1663     PhoneNumber number = new PhoneNumber();
1664     // For FIXED_LINE_OR_MOBILE, a number should be considered valid if it matches the possible
1665     // lengths for mobile *or* fixed-line numbers.
1666     number.setCountryCode(290).setNationalNumber(1234L);
1667     assertEquals(
1668         ValidationResult.TOO_SHORT,
1669         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE));
1670     assertEquals(
1671         ValidationResult.IS_POSSIBLE,
1672         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.MOBILE));
1673     assertEquals(
1674         ValidationResult.IS_POSSIBLE,
1675         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE_OR_MOBILE));
1676 
1677     number.setNationalNumber(12345L);
1678     assertEquals(
1679         ValidationResult.TOO_SHORT,
1680         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE));
1681     assertEquals(
1682         ValidationResult.TOO_LONG,
1683         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.MOBILE));
1684     assertEquals(
1685         ValidationResult.INVALID_LENGTH,
1686         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE_OR_MOBILE));
1687 
1688     number.setNationalNumber(123456L);
1689     assertEquals(
1690         ValidationResult.IS_POSSIBLE,
1691         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE));
1692     assertEquals(
1693         ValidationResult.TOO_LONG,
1694         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.MOBILE));
1695     assertEquals(
1696         ValidationResult.IS_POSSIBLE,
1697         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE_OR_MOBILE));
1698 
1699     number.setNationalNumber(1234567L);
1700     assertEquals(
1701         ValidationResult.TOO_LONG,
1702         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE));
1703     assertEquals(
1704         ValidationResult.TOO_LONG,
1705         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.MOBILE));
1706     assertEquals(
1707         ValidationResult.TOO_LONG,
1708         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE_OR_MOBILE));
1709 
1710     // 8-digit numbers are possible for toll-free and premium-rate numbers only.
1711     number.setNationalNumber(12345678L);
1712     assertEquals(
1713         ValidationResult.IS_POSSIBLE,
1714         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.TOLL_FREE));
1715     assertEquals(
1716         ValidationResult.TOO_LONG,
1717         phoneUtil.isPossibleNumberForTypeWithReason(number, PhoneNumberType.FIXED_LINE_OR_MOBILE));
1718   }
1719 
testIsNotPossibleNumber()1720   public void testIsNotPossibleNumber() {
1721     assertFalse(phoneUtil.isPossibleNumber(US_LONG_NUMBER));
1722     assertFalse(phoneUtil.isPossibleNumber(INTERNATIONAL_TOLL_FREE_TOO_LONG));
1723 
1724     PhoneNumber number = new PhoneNumber();
1725     number.setCountryCode(1).setNationalNumber(253000L);
1726     assertFalse(phoneUtil.isPossibleNumber(number));
1727 
1728     number.clear();
1729     number.setCountryCode(44).setNationalNumber(300L);
1730     assertFalse(phoneUtil.isPossibleNumber(number));
1731     assertFalse(phoneUtil.isPossibleNumber("+1 650 253 00000", RegionCode.US));
1732     assertFalse(phoneUtil.isPossibleNumber("(650) 253-00000", RegionCode.US));
1733     assertFalse(phoneUtil.isPossibleNumber("I want a Pizza", RegionCode.US));
1734     assertFalse(phoneUtil.isPossibleNumber("253-000", RegionCode.US));
1735     assertFalse(phoneUtil.isPossibleNumber("1 3000", RegionCode.GB));
1736     assertFalse(phoneUtil.isPossibleNumber("+44 300", RegionCode.GB));
1737     assertFalse(phoneUtil.isPossibleNumber("+800 1234 5678 9", RegionCode.UN001));
1738   }
1739 
testTruncateTooLongNumber()1740   public void testTruncateTooLongNumber() {
1741     // GB number 080 1234 5678, but entered with 4 extra digits at the end.
1742     PhoneNumber tooLongNumber = new PhoneNumber();
1743     tooLongNumber.setCountryCode(44).setNationalNumber(80123456780123L);
1744     PhoneNumber validNumber = new PhoneNumber();
1745     validNumber.setCountryCode(44).setNationalNumber(8012345678L);
1746     assertTrue(phoneUtil.truncateTooLongNumber(tooLongNumber));
1747     assertEquals(validNumber, tooLongNumber);
1748 
1749     // IT number 022 3456 7890, but entered with 3 extra digits at the end.
1750     tooLongNumber.clear();
1751     tooLongNumber.setCountryCode(39).setNationalNumber(2234567890123L).setItalianLeadingZero(true);
1752     validNumber.clear();
1753     validNumber.setCountryCode(39).setNationalNumber(2234567890L).setItalianLeadingZero(true);
1754     assertTrue(phoneUtil.truncateTooLongNumber(tooLongNumber));
1755     assertEquals(validNumber, tooLongNumber);
1756 
1757     // US number 650-253-0000, but entered with one additional digit at the end.
1758     tooLongNumber.clear();
1759     tooLongNumber.mergeFrom(US_LONG_NUMBER);
1760     assertTrue(phoneUtil.truncateTooLongNumber(tooLongNumber));
1761     assertEquals(US_NUMBER, tooLongNumber);
1762 
1763     tooLongNumber.clear();
1764     tooLongNumber.mergeFrom(INTERNATIONAL_TOLL_FREE_TOO_LONG);
1765     assertTrue(phoneUtil.truncateTooLongNumber(tooLongNumber));
1766     assertEquals(INTERNATIONAL_TOLL_FREE, tooLongNumber);
1767 
1768     // Tests what happens when a valid number is passed in.
1769     PhoneNumber validNumberCopy = new PhoneNumber().mergeFrom(validNumber);
1770     assertTrue(phoneUtil.truncateTooLongNumber(validNumber));
1771     // Tests the number is not modified.
1772     assertEquals(validNumberCopy, validNumber);
1773 
1774     // Tests what happens when a number with invalid prefix is passed in.
1775     PhoneNumber numberWithInvalidPrefix = new PhoneNumber();
1776     // The test metadata says US numbers cannot have prefix 240.
1777     numberWithInvalidPrefix.setCountryCode(1).setNationalNumber(2401234567L);
1778     PhoneNumber invalidNumberCopy = new PhoneNumber().mergeFrom(numberWithInvalidPrefix);
1779     assertFalse(phoneUtil.truncateTooLongNumber(numberWithInvalidPrefix));
1780     // Tests the number is not modified.
1781     assertEquals(invalidNumberCopy, numberWithInvalidPrefix);
1782 
1783     // Tests what happens when a too short number is passed in.
1784     PhoneNumber tooShortNumber = new PhoneNumber().setCountryCode(1).setNationalNumber(1234L);
1785     PhoneNumber tooShortNumberCopy = new PhoneNumber().mergeFrom(tooShortNumber);
1786     assertFalse(phoneUtil.truncateTooLongNumber(tooShortNumber));
1787     // Tests the number is not modified.
1788     assertEquals(tooShortNumberCopy, tooShortNumber);
1789   }
1790 
testIsViablePhoneNumber()1791   public void testIsViablePhoneNumber() {
1792     assertFalse(PhoneNumberUtil.isViablePhoneNumber("1"));
1793     // Only one or two digits before strange non-possible punctuation.
1794     assertFalse(PhoneNumberUtil.isViablePhoneNumber("1+1+1"));
1795     assertFalse(PhoneNumberUtil.isViablePhoneNumber("80+0"));
1796     // Two digits is viable.
1797     assertTrue(PhoneNumberUtil.isViablePhoneNumber("00"));
1798     assertTrue(PhoneNumberUtil.isViablePhoneNumber("111"));
1799     // Alpha numbers.
1800     assertTrue(PhoneNumberUtil.isViablePhoneNumber("0800-4-pizza"));
1801     assertTrue(PhoneNumberUtil.isViablePhoneNumber("0800-4-PIZZA"));
1802     // We need at least three digits before any alpha characters.
1803     assertFalse(PhoneNumberUtil.isViablePhoneNumber("08-PIZZA"));
1804     assertFalse(PhoneNumberUtil.isViablePhoneNumber("8-PIZZA"));
1805     assertFalse(PhoneNumberUtil.isViablePhoneNumber("12. March"));
1806   }
1807 
testIsViablePhoneNumberNonAscii()1808   public void testIsViablePhoneNumberNonAscii() {
1809     // Only one or two digits before possible punctuation followed by more digits.
1810     assertTrue(PhoneNumberUtil.isViablePhoneNumber("1\u300034"));
1811     assertFalse(PhoneNumberUtil.isViablePhoneNumber("1\u30003+4"));
1812     // Unicode variants of possible starting character and other allowed punctuation/digits.
1813     assertTrue(PhoneNumberUtil.isViablePhoneNumber("\uFF081\uFF09\u30003456789"));
1814     // Testing a leading + is okay.
1815     assertTrue(PhoneNumberUtil.isViablePhoneNumber("+1\uFF09\u30003456789"));
1816   }
1817 
testExtractPossibleNumber()1818   public void testExtractPossibleNumber() {
1819     // Removes preceding funky punctuation and letters but leaves the rest untouched.
1820     assertEquals("0800-345-600", PhoneNumberUtil.extractPossibleNumber("Tel:0800-345-600").toString());
1821     assertEquals("0800 FOR PIZZA", PhoneNumberUtil.extractPossibleNumber("Tel:0800 FOR PIZZA").toString());
1822     // Should not remove plus sign
1823     assertEquals("+800-345-600", PhoneNumberUtil.extractPossibleNumber("Tel:+800-345-600").toString());
1824     // Should recognise wide digits as possible start values.
1825     assertEquals("\uFF10\uFF12\uFF13",
1826                  PhoneNumberUtil.extractPossibleNumber("\uFF10\uFF12\uFF13").toString());
1827     // Dashes are not possible start values and should be removed.
1828     assertEquals("\uFF11\uFF12\uFF13",
1829                  PhoneNumberUtil.extractPossibleNumber("Num-\uFF11\uFF12\uFF13").toString());
1830     // If not possible number present, return empty string.
1831     assertEquals("", PhoneNumberUtil.extractPossibleNumber("Num-....").toString());
1832     // Leading brackets are stripped - these are not used when parsing.
1833     assertEquals("650) 253-0000", PhoneNumberUtil.extractPossibleNumber("(650) 253-0000").toString());
1834 
1835     // Trailing non-alpha-numeric characters should be removed.
1836     assertEquals("650) 253-0000", PhoneNumberUtil.extractPossibleNumber("(650) 253-0000..- ..").toString());
1837     assertEquals("650) 253-0000", PhoneNumberUtil.extractPossibleNumber("(650) 253-0000.").toString());
1838     // This case has a trailing RTL char.
1839     assertEquals("650) 253-0000", PhoneNumberUtil.extractPossibleNumber("(650) 253-0000\u200F").toString());
1840   }
1841 
testMaybeStripNationalPrefix()1842   public void testMaybeStripNationalPrefix() {
1843     PhoneMetadata.Builder metadata = PhoneMetadata.newBuilder();
1844     metadata.setId("ignored");
1845     metadata.setNationalPrefixForParsing("34");
1846     metadata
1847         .getGeneralDescBuilder()
1848         .setNationalNumberPattern("\\d{4,8}");
1849     StringBuilder numberToStrip = new StringBuilder("34356778");
1850     String strippedNumber = "356778";
1851     assertTrue(phoneUtil.maybeStripNationalPrefixAndCarrierCode(numberToStrip, metadata.build(), null));
1852     assertEquals("Should have had national prefix stripped.",
1853                  strippedNumber, numberToStrip.toString());
1854     // Retry stripping - now the number should not start with the national prefix, so no more
1855     // stripping should occur.
1856     assertFalse(phoneUtil.maybeStripNationalPrefixAndCarrierCode(numberToStrip, metadata.build(), null));
1857     assertEquals("Should have had no change - no national prefix present.",
1858                  strippedNumber, numberToStrip.toString());
1859     // Some countries have no national prefix. Repeat test with none specified.
1860     metadata.setNationalPrefixForParsing("");
1861     assertFalse(phoneUtil.maybeStripNationalPrefixAndCarrierCode(numberToStrip, metadata.build(), null));
1862     assertEquals("Should not strip anything with empty national prefix.",
1863                  strippedNumber, numberToStrip.toString());
1864     // If the resultant number doesn't match the national rule, it shouldn't be stripped.
1865     metadata.setNationalPrefixForParsing("3");
1866     numberToStrip = new StringBuilder("3123");
1867     strippedNumber = "3123";
1868     assertFalse(phoneUtil.maybeStripNationalPrefixAndCarrierCode(numberToStrip, metadata.build(), null));
1869     assertEquals("Should have had no change - after stripping, it wouldn't have matched "
1870         + "the national rule.",
1871         strippedNumber, numberToStrip.toString());
1872     // Test extracting carrier selection code.
1873     metadata.setNationalPrefixForParsing("0(81)?");
1874     numberToStrip = new StringBuilder("08122123456");
1875     strippedNumber = "22123456";
1876     StringBuilder carrierCode = new StringBuilder();
1877     assertTrue(
1878         phoneUtil.maybeStripNationalPrefixAndCarrierCode(
1879             numberToStrip, metadata.build(), carrierCode));
1880     assertEquals("81", carrierCode.toString());
1881     assertEquals("Should have had national prefix and carrier code stripped.",
1882                  strippedNumber, numberToStrip.toString());
1883     // If there was a transform rule, check it was applied.
1884     metadata.setNationalPrefixTransformRule("5$15");
1885     // Note that a capturing group is present here.
1886     metadata.setNationalPrefixForParsing("0(\\d{2})");
1887     numberToStrip = new StringBuilder("031123");
1888     String transformedNumber = "5315123";
1889     assertTrue(
1890         phoneUtil.maybeStripNationalPrefixAndCarrierCode(numberToStrip, metadata.build(), null));
1891     assertEquals("Should transform the 031 to a 5315.",
1892                  transformedNumber, numberToStrip.toString());
1893   }
1894 
testMaybeStripInternationalPrefix()1895   public void testMaybeStripInternationalPrefix() {
1896     String internationalPrefix = "00[39]";
1897     StringBuilder numberToStrip = new StringBuilder("0034567700-3898003");
1898     // Note the dash is removed as part of the normalization.
1899     StringBuilder strippedNumber = new StringBuilder("45677003898003");
1900     assertEquals(CountryCodeSource.FROM_NUMBER_WITH_IDD,
1901                  phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
1902                                                                      internationalPrefix));
1903     assertEquals("The number supplied was not stripped of its international prefix.",
1904                  strippedNumber.toString(), numberToStrip.toString());
1905     // Now the number no longer starts with an IDD prefix, so it should now report
1906     // FROM_DEFAULT_COUNTRY.
1907     assertEquals(CountryCodeSource.FROM_DEFAULT_COUNTRY,
1908                  phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
1909                                                                      internationalPrefix));
1910 
1911     numberToStrip = new StringBuilder("00945677003898003");
1912     assertEquals(CountryCodeSource.FROM_NUMBER_WITH_IDD,
1913                  phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
1914                                                                      internationalPrefix));
1915     assertEquals("The number supplied was not stripped of its international prefix.",
1916                  strippedNumber.toString(), numberToStrip.toString());
1917     // Test it works when the international prefix is broken up by spaces.
1918     numberToStrip = new StringBuilder("00 9 45677003898003");
1919     assertEquals(CountryCodeSource.FROM_NUMBER_WITH_IDD,
1920                  phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
1921                                                                      internationalPrefix));
1922     assertEquals("The number supplied was not stripped of its international prefix.",
1923                  strippedNumber.toString(), numberToStrip.toString());
1924     // Now the number no longer starts with an IDD prefix, so it should now report
1925     // FROM_DEFAULT_COUNTRY.
1926     assertEquals(CountryCodeSource.FROM_DEFAULT_COUNTRY,
1927                  phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
1928                                                                      internationalPrefix));
1929 
1930     // Test the + symbol is also recognised and stripped.
1931     numberToStrip = new StringBuilder("+45677003898003");
1932     strippedNumber = new StringBuilder("45677003898003");
1933     assertEquals(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN,
1934                  phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
1935                                                                      internationalPrefix));
1936     assertEquals("The number supplied was not stripped of the plus symbol.",
1937                  strippedNumber.toString(), numberToStrip.toString());
1938 
1939     // If the number afterwards is a zero, we should not strip this - no country calling code begins
1940     // with 0.
1941     numberToStrip = new StringBuilder("0090112-3123");
1942     strippedNumber = new StringBuilder("00901123123");
1943     assertEquals(CountryCodeSource.FROM_DEFAULT_COUNTRY,
1944                  phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
1945                                                                      internationalPrefix));
1946     assertEquals("The number supplied had a 0 after the match so shouldn't be stripped.",
1947                  strippedNumber.toString(), numberToStrip.toString());
1948     // Here the 0 is separated by a space from the IDD.
1949     numberToStrip = new StringBuilder("009 0-112-3123");
1950     assertEquals(CountryCodeSource.FROM_DEFAULT_COUNTRY,
1951                  phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
1952                                                                      internationalPrefix));
1953   }
1954 
testMaybeExtractCountryCode()1955   public void testMaybeExtractCountryCode() {
1956     PhoneNumber number = new PhoneNumber();
1957     PhoneMetadata metadata = phoneUtil.getMetadataForRegion(RegionCode.US);
1958     // Note that for the US, the IDD is 011.
1959     try {
1960       String phoneNumber = "011112-3456789";
1961       String strippedNumber = "123456789";
1962       int countryCallingCode = 1;
1963       StringBuilder numberToFill = new StringBuilder();
1964       assertEquals("Did not extract country calling code " + countryCallingCode + " correctly.",
1965                    countryCallingCode,
1966                    phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true,
1967                                                      number));
1968       assertEquals("Did not figure out CountryCodeSource correctly",
1969                    CountryCodeSource.FROM_NUMBER_WITH_IDD, number.getCountryCodeSource());
1970       // Should strip and normalize national significant number.
1971       assertEquals("Did not strip off the country calling code correctly.",
1972                    strippedNumber,
1973                    numberToFill.toString());
1974     } catch (NumberParseException e) {
1975       fail("Should not have thrown an exception: " + e.toString());
1976     }
1977     number.clear();
1978     try {
1979       String phoneNumber = "+6423456789";
1980       int countryCallingCode = 64;
1981       StringBuilder numberToFill = new StringBuilder();
1982       assertEquals("Did not extract country calling code " + countryCallingCode + " correctly.",
1983                    countryCallingCode,
1984                    phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true,
1985                                                      number));
1986       assertEquals("Did not figure out CountryCodeSource correctly",
1987                    CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN, number.getCountryCodeSource());
1988     } catch (NumberParseException e) {
1989       fail("Should not have thrown an exception: " + e.toString());
1990     }
1991     number.clear();
1992     try {
1993       String phoneNumber = "+80012345678";
1994       int countryCallingCode = 800;
1995       StringBuilder numberToFill = new StringBuilder();
1996       assertEquals("Did not extract country calling code " + countryCallingCode + " correctly.",
1997                    countryCallingCode,
1998                    phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true,
1999                                                      number));
2000       assertEquals("Did not figure out CountryCodeSource correctly",
2001                    CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN, number.getCountryCodeSource());
2002     } catch (NumberParseException e) {
2003       fail("Should not have thrown an exception: " + e.toString());
2004     }
2005     number.clear();
2006     try {
2007       String phoneNumber = "2345-6789";
2008       StringBuilder numberToFill = new StringBuilder();
2009       assertEquals(
2010           "Should not have extracted a country calling code - no international prefix present.",
2011           0,
2012           phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true, number));
2013       assertEquals("Did not figure out CountryCodeSource correctly",
2014                    CountryCodeSource.FROM_DEFAULT_COUNTRY, number.getCountryCodeSource());
2015     } catch (NumberParseException e) {
2016       fail("Should not have thrown an exception: " + e.toString());
2017     }
2018     number.clear();
2019     try {
2020       String phoneNumber = "0119991123456789";
2021       StringBuilder numberToFill = new StringBuilder();
2022       phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true, number);
2023       fail("Should have thrown an exception, no valid country calling code present.");
2024     } catch (NumberParseException e) {
2025       // Expected.
2026       assertEquals("Wrong error type stored in exception.",
2027                    NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
2028                    e.getErrorType());
2029     }
2030     number.clear();
2031     try {
2032       String phoneNumber = "(1 610) 619 4466";
2033       int countryCallingCode = 1;
2034       StringBuilder numberToFill = new StringBuilder();
2035       assertEquals("Should have extracted the country calling code of the region passed in",
2036                    countryCallingCode,
2037                    phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true,
2038                                                      number));
2039       assertEquals("Did not figure out CountryCodeSource correctly",
2040                    CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN,
2041                    number.getCountryCodeSource());
2042     } catch (NumberParseException e) {
2043       fail("Should not have thrown an exception: " + e.toString());
2044     }
2045     number.clear();
2046     try {
2047       String phoneNumber = "(1 610) 619 4466";
2048       int countryCallingCode = 1;
2049       StringBuilder numberToFill = new StringBuilder();
2050       assertEquals("Should have extracted the country calling code of the region passed in",
2051                    countryCallingCode,
2052                    phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, false,
2053                                                      number));
2054       assertFalse("Should not contain CountryCodeSource.", number.hasCountryCodeSource());
2055     } catch (NumberParseException e) {
2056       fail("Should not have thrown an exception: " + e.toString());
2057     }
2058     number.clear();
2059     try {
2060       String phoneNumber = "(1 610) 619 446";
2061       StringBuilder numberToFill = new StringBuilder();
2062       assertEquals("Should not have extracted a country calling code - invalid number after "
2063           + "extraction of uncertain country calling code.",
2064           0,
2065           phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, false, number));
2066       assertFalse("Should not contain CountryCodeSource.", number.hasCountryCodeSource());
2067     } catch (NumberParseException e) {
2068       fail("Should not have thrown an exception: " + e.toString());
2069     }
2070     number.clear();
2071     try {
2072       String phoneNumber = "(1 610) 619";
2073       StringBuilder numberToFill = new StringBuilder();
2074       assertEquals("Should not have extracted a country calling code - too short number both "
2075           + "before and after extraction of uncertain country calling code.",
2076           0,
2077           phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true, number));
2078       assertEquals("Did not figure out CountryCodeSource correctly",
2079                    CountryCodeSource.FROM_DEFAULT_COUNTRY, number.getCountryCodeSource());
2080     } catch (NumberParseException e) {
2081       fail("Should not have thrown an exception: " + e.toString());
2082     }
2083   }
2084 
testParseNationalNumber()2085   public void testParseNationalNumber() throws Exception {
2086     // National prefix attached.
2087     assertEquals(NZ_NUMBER, phoneUtil.parse("033316005", RegionCode.NZ));
2088     // Some fields are not filled in by parse, but only by parseAndKeepRawInput.
2089     assertFalse(NZ_NUMBER.hasCountryCodeSource());
2090     assertEquals(CountryCodeSource.UNSPECIFIED, NZ_NUMBER.getCountryCodeSource());
2091 
2092     assertEquals(NZ_NUMBER, phoneUtil.parse("33316005", RegionCode.NZ));
2093     // National prefix attached and some formatting present.
2094     assertEquals(NZ_NUMBER, phoneUtil.parse("03-331 6005", RegionCode.NZ));
2095     assertEquals(NZ_NUMBER, phoneUtil.parse("03 331 6005", RegionCode.NZ));
2096     // Test parsing RFC3966 format with a phone context.
2097     assertEquals(NZ_NUMBER, phoneUtil.parse("tel:03-331-6005;phone-context=+64", RegionCode.NZ));
2098     assertEquals(NZ_NUMBER, phoneUtil.parse("tel:331-6005;phone-context=+64-3", RegionCode.NZ));
2099     assertEquals(NZ_NUMBER, phoneUtil.parse("tel:331-6005;phone-context=+64-3", RegionCode.US));
2100     assertEquals(NZ_NUMBER, phoneUtil.parse(
2101         "My number is tel:03-331-6005;phone-context=+64", RegionCode.NZ));
2102     // Test parsing RFC3966 format with optional user-defined parameters. The parameters will appear
2103     // after the context if present.
2104     assertEquals(NZ_NUMBER, phoneUtil.parse("tel:03-331-6005;phone-context=+64;a=%A1",
2105         RegionCode.NZ));
2106     // Test parsing RFC3966 with an ISDN subaddress.
2107     assertEquals(NZ_NUMBER, phoneUtil.parse("tel:03-331-6005;isub=12345;phone-context=+64",
2108         RegionCode.NZ));
2109     assertEquals(NZ_NUMBER, phoneUtil.parse("tel:+64-3-331-6005;isub=12345", RegionCode.NZ));
2110     // Test parsing RFC3966 with "tel:" missing.
2111     assertEquals(NZ_NUMBER, phoneUtil.parse("03-331-6005;phone-context=+64", RegionCode.NZ));
2112     // Testing international prefixes.
2113     // Should strip country calling code.
2114     assertEquals(NZ_NUMBER, phoneUtil.parse("0064 3 331 6005", RegionCode.NZ));
2115     // Try again, but this time we have an international number with Region Code US. It should
2116     // recognise the country calling code and parse accordingly.
2117     assertEquals(NZ_NUMBER, phoneUtil.parse("01164 3 331 6005", RegionCode.US));
2118     assertEquals(NZ_NUMBER, phoneUtil.parse("+64 3 331 6005", RegionCode.US));
2119     // We should ignore the leading plus here, since it is not followed by a valid country code but
2120     // instead is followed by the IDD for the US.
2121     assertEquals(NZ_NUMBER, phoneUtil.parse("+01164 3 331 6005", RegionCode.US));
2122     assertEquals(NZ_NUMBER, phoneUtil.parse("+0064 3 331 6005", RegionCode.NZ));
2123     assertEquals(NZ_NUMBER, phoneUtil.parse("+ 00 64 3 331 6005", RegionCode.NZ));
2124 
2125     assertEquals(US_LOCAL_NUMBER,
2126         phoneUtil.parse("tel:253-0000;phone-context=www.google.com", RegionCode.US));
2127     assertEquals(US_LOCAL_NUMBER,
2128         phoneUtil.parse("tel:253-0000;isub=12345;phone-context=www.google.com", RegionCode.US));
2129     assertEquals(US_LOCAL_NUMBER,
2130         phoneUtil.parse("tel:2530000;isub=12345;phone-context=1234.com", RegionCode.US));
2131 
2132     PhoneNumber nzNumber = new PhoneNumber();
2133     nzNumber.setCountryCode(64).setNationalNumber(64123456L);
2134     assertEquals(nzNumber, phoneUtil.parse("64(0)64123456", RegionCode.NZ));
2135     // Check that using a "/" is fine in a phone number.
2136     assertEquals(DE_NUMBER, phoneUtil.parse("301/23456", RegionCode.DE));
2137 
2138     PhoneNumber usNumber = new PhoneNumber();
2139     // Check it doesn't use the '1' as a country calling code when parsing if the phone number was
2140     // already possible.
2141     usNumber.setCountryCode(1).setNationalNumber(1234567890L);
2142     assertEquals(usNumber, phoneUtil.parse("123-456-7890", RegionCode.US));
2143 
2144     // Test star numbers. Although this is not strictly valid, we would like to make sure we can
2145     // parse the output we produce when formatting the number.
2146     assertEquals(JP_STAR_NUMBER, phoneUtil.parse("+81 *2345", RegionCode.JP));
2147 
2148     PhoneNumber shortNumber = new PhoneNumber();
2149     shortNumber.setCountryCode(64).setNationalNumber(12L);
2150     assertEquals(shortNumber, phoneUtil.parse("12", RegionCode.NZ));
2151 
2152     // Test for short-code with leading zero for a country which has 0 as national prefix. Ensure
2153     // it's not interpreted as national prefix if the remaining number length is local-only in
2154     // terms of length. Example: In GB, length 6-7 are only possible local-only.
2155     shortNumber.setCountryCode(44).setNationalNumber(123456)
2156         .setItalianLeadingZero(true);
2157     assertEquals(shortNumber, phoneUtil.parse("0123456", RegionCode.GB));
2158   }
2159 
testParseNumberWithAlphaCharacters()2160   public void testParseNumberWithAlphaCharacters() throws Exception {
2161     // Test case with alpha characters.
2162     PhoneNumber tollfreeNumber = new PhoneNumber();
2163     tollfreeNumber.setCountryCode(64).setNationalNumber(800332005L);
2164     assertEquals(tollfreeNumber, phoneUtil.parse("0800 DDA 005", RegionCode.NZ));
2165     PhoneNumber premiumNumber = new PhoneNumber();
2166     premiumNumber.setCountryCode(64).setNationalNumber(9003326005L);
2167     assertEquals(premiumNumber, phoneUtil.parse("0900 DDA 6005", RegionCode.NZ));
2168     // Not enough alpha characters for them to be considered intentional, so they are stripped.
2169     assertEquals(premiumNumber, phoneUtil.parse("0900 332 6005a", RegionCode.NZ));
2170     assertEquals(premiumNumber, phoneUtil.parse("0900 332 600a5", RegionCode.NZ));
2171     assertEquals(premiumNumber, phoneUtil.parse("0900 332 600A5", RegionCode.NZ));
2172     assertEquals(premiumNumber, phoneUtil.parse("0900 a332 600A5", RegionCode.NZ));
2173   }
2174 
testParseMaliciousInput()2175   public void testParseMaliciousInput() throws Exception {
2176     // Lots of leading + signs before the possible number.
2177     StringBuilder maliciousNumber = new StringBuilder(6000);
2178     for (int i = 0; i < 6000; i++) {
2179       maliciousNumber.append('+');
2180     }
2181     maliciousNumber.append("12222-33-244 extensioB 343+");
2182     try {
2183       phoneUtil.parse(maliciousNumber.toString(), RegionCode.US);
2184       fail("This should not parse without throwing an exception " + maliciousNumber);
2185     } catch (NumberParseException e) {
2186       // Expected this exception.
2187       assertEquals("Wrong error type stored in exception.",
2188                    NumberParseException.ErrorType.TOO_LONG,
2189                    e.getErrorType());
2190     }
2191     StringBuilder maliciousNumberWithAlmostExt = new StringBuilder(6000);
2192     for (int i = 0; i < 350; i++) {
2193       maliciousNumberWithAlmostExt.append("200");
2194     }
2195     maliciousNumberWithAlmostExt.append(" extensiOB 345");
2196     try {
2197       phoneUtil.parse(maliciousNumberWithAlmostExt.toString(), RegionCode.US);
2198       fail("This should not parse without throwing an exception " + maliciousNumberWithAlmostExt);
2199     } catch (NumberParseException e) {
2200       // Expected this exception.
2201       assertEquals("Wrong error type stored in exception.",
2202                    NumberParseException.ErrorType.TOO_LONG,
2203                    e.getErrorType());
2204     }
2205   }
2206 
testParseWithInternationalPrefixes()2207   public void testParseWithInternationalPrefixes() throws Exception {
2208     assertEquals(US_NUMBER, phoneUtil.parse("+1 (650) 253-0000", RegionCode.NZ));
2209     assertEquals(INTERNATIONAL_TOLL_FREE, phoneUtil.parse("011 800 1234 5678", RegionCode.US));
2210     assertEquals(US_NUMBER, phoneUtil.parse("1-650-253-0000", RegionCode.US));
2211     // Calling the US number from Singapore by using different service providers
2212     // 1st test: calling using SingTel IDD service (IDD is 001)
2213     assertEquals(US_NUMBER, phoneUtil.parse("0011-650-253-0000", RegionCode.SG));
2214     // 2nd test: calling using StarHub IDD service (IDD is 008)
2215     assertEquals(US_NUMBER, phoneUtil.parse("0081-650-253-0000", RegionCode.SG));
2216     // 3rd test: calling using SingTel V019 service (IDD is 019)
2217     assertEquals(US_NUMBER, phoneUtil.parse("0191-650-253-0000", RegionCode.SG));
2218     // Calling the US number from Poland
2219     assertEquals(US_NUMBER, phoneUtil.parse("0~01-650-253-0000", RegionCode.PL));
2220     // Using "++" at the start.
2221     assertEquals(US_NUMBER, phoneUtil.parse("++1 (650) 253-0000", RegionCode.PL));
2222   }
2223 
testParseNonAscii()2224   public void testParseNonAscii() throws Exception {
2225     // Using a full-width plus sign.
2226     assertEquals(US_NUMBER, phoneUtil.parse("\uFF0B1 (650) 253-0000", RegionCode.SG));
2227     // Using a soft hyphen U+00AD.
2228     assertEquals(US_NUMBER, phoneUtil.parse("1 (650) 253\u00AD-0000", RegionCode.US));
2229     // The whole number, including punctuation, is here represented in full-width form.
2230     assertEquals(US_NUMBER, phoneUtil.parse("\uFF0B\uFF11\u3000\uFF08\uFF16\uFF15\uFF10\uFF09"
2231           + "\u3000\uFF12\uFF15\uFF13\uFF0D\uFF10\uFF10\uFF10\uFF10",
2232           RegionCode.SG));
2233     // Using U+30FC dash instead.
2234     assertEquals(US_NUMBER, phoneUtil.parse("\uFF0B\uFF11\u3000\uFF08\uFF16\uFF15\uFF10\uFF09"
2235           + "\u3000\uFF12\uFF15\uFF13\u30FC\uFF10\uFF10\uFF10\uFF10",
2236           RegionCode.SG));
2237 
2238     // Using a very strange decimal digit range (Mongolian digits).
2239     assertEquals(US_NUMBER, phoneUtil.parse("\u1811 \u1816\u1815\u1810 "
2240           + "\u1812\u1815\u1813 \u1810\u1810\u1810\u1810",
2241           RegionCode.US));
2242   }
2243 
testParseWithLeadingZero()2244   public void testParseWithLeadingZero() throws Exception {
2245     assertEquals(IT_NUMBER, phoneUtil.parse("+39 02-36618 300", RegionCode.NZ));
2246     assertEquals(IT_NUMBER, phoneUtil.parse("02-36618 300", RegionCode.IT));
2247 
2248     assertEquals(IT_MOBILE, phoneUtil.parse("345 678 901", RegionCode.IT));
2249   }
2250 
testParseNationalNumberArgentina()2251   public void testParseNationalNumberArgentina() throws Exception {
2252     // Test parsing mobile numbers of Argentina.
2253     PhoneNumber arNumber = new PhoneNumber();
2254     arNumber.setCountryCode(54).setNationalNumber(93435551212L);
2255     assertEquals(arNumber, phoneUtil.parse("+54 9 343 555 1212", RegionCode.AR));
2256     assertEquals(arNumber, phoneUtil.parse("0343 15 555 1212", RegionCode.AR));
2257 
2258     arNumber.clear();
2259     arNumber.setCountryCode(54).setNationalNumber(93715654320L);
2260     assertEquals(arNumber, phoneUtil.parse("+54 9 3715 65 4320", RegionCode.AR));
2261     assertEquals(arNumber, phoneUtil.parse("03715 15 65 4320", RegionCode.AR));
2262     assertEquals(AR_MOBILE, phoneUtil.parse("911 876 54321", RegionCode.AR));
2263 
2264     // Test parsing fixed-line numbers of Argentina.
2265     assertEquals(AR_NUMBER, phoneUtil.parse("+54 11 8765 4321", RegionCode.AR));
2266     assertEquals(AR_NUMBER, phoneUtil.parse("011 8765 4321", RegionCode.AR));
2267 
2268     arNumber.clear();
2269     arNumber.setCountryCode(54).setNationalNumber(3715654321L);
2270     assertEquals(arNumber, phoneUtil.parse("+54 3715 65 4321", RegionCode.AR));
2271     assertEquals(arNumber, phoneUtil.parse("03715 65 4321", RegionCode.AR));
2272 
2273     arNumber.clear();
2274     arNumber.setCountryCode(54).setNationalNumber(2312340000L);
2275     assertEquals(arNumber, phoneUtil.parse("+54 23 1234 0000", RegionCode.AR));
2276     assertEquals(arNumber, phoneUtil.parse("023 1234 0000", RegionCode.AR));
2277   }
2278 
testParseWithXInNumber()2279   public void testParseWithXInNumber() throws Exception {
2280     // Test that having an 'x' in the phone number at the start is ok and that it just gets removed.
2281     assertEquals(AR_NUMBER, phoneUtil.parse("01187654321", RegionCode.AR));
2282     assertEquals(AR_NUMBER, phoneUtil.parse("(0) 1187654321", RegionCode.AR));
2283     assertEquals(AR_NUMBER, phoneUtil.parse("0 1187654321", RegionCode.AR));
2284     assertEquals(AR_NUMBER, phoneUtil.parse("(0xx) 1187654321", RegionCode.AR));
2285     PhoneNumber arFromUs = new PhoneNumber();
2286     arFromUs.setCountryCode(54).setNationalNumber(81429712L);
2287     // This test is intentionally constructed such that the number of digit after xx is larger than
2288     // 7, so that the number won't be mistakenly treated as an extension, as we allow extensions up
2289     // to 7 digits. This assumption is okay for now as all the countries where a carrier selection
2290     // code is written in the form of xx have a national significant number of length larger than 7.
2291     assertEquals(arFromUs, phoneUtil.parse("011xx5481429712", RegionCode.US));
2292   }
2293 
testParseNumbersMexico()2294   public void testParseNumbersMexico() throws Exception {
2295     // Test parsing fixed-line numbers of Mexico.
2296     PhoneNumber mxNumber = new PhoneNumber();
2297     mxNumber.setCountryCode(52).setNationalNumber(4499780001L);
2298     assertEquals(mxNumber, phoneUtil.parse("+52 (449)978-0001", RegionCode.MX));
2299     assertEquals(mxNumber, phoneUtil.parse("01 (449)978-0001", RegionCode.MX));
2300     assertEquals(mxNumber, phoneUtil.parse("(449)978-0001", RegionCode.MX));
2301 
2302     // Test parsing mobile numbers of Mexico.
2303     mxNumber.clear();
2304     mxNumber.setCountryCode(52).setNationalNumber(13312345678L);
2305     assertEquals(mxNumber, phoneUtil.parse("+52 1 33 1234-5678", RegionCode.MX));
2306     assertEquals(mxNumber, phoneUtil.parse("044 (33) 1234-5678", RegionCode.MX));
2307     assertEquals(mxNumber, phoneUtil.parse("045 33 1234-5678", RegionCode.MX));
2308   }
2309 
testFailedParseOnInvalidNumbers()2310   public void testFailedParseOnInvalidNumbers() {
2311     try {
2312       String sentencePhoneNumber = "This is not a phone number";
2313       phoneUtil.parse(sentencePhoneNumber, RegionCode.NZ);
2314       fail("This should not parse without throwing an exception " + sentencePhoneNumber);
2315     } catch (NumberParseException e) {
2316       // Expected this exception.
2317       assertEquals("Wrong error type stored in exception.",
2318                    NumberParseException.ErrorType.NOT_A_NUMBER,
2319                    e.getErrorType());
2320     }
2321     try {
2322       String sentencePhoneNumber = "1 Still not a number";
2323       phoneUtil.parse(sentencePhoneNumber, RegionCode.NZ);
2324       fail("This should not parse without throwing an exception " + sentencePhoneNumber);
2325     } catch (NumberParseException e) {
2326       // Expected this exception.
2327       assertEquals("Wrong error type stored in exception.",
2328                    NumberParseException.ErrorType.NOT_A_NUMBER,
2329                    e.getErrorType());
2330     }
2331     try {
2332       String sentencePhoneNumber = "1 MICROSOFT";
2333       phoneUtil.parse(sentencePhoneNumber, RegionCode.NZ);
2334       fail("This should not parse without throwing an exception " + sentencePhoneNumber);
2335     } catch (NumberParseException e) {
2336       // Expected this exception.
2337       assertEquals("Wrong error type stored in exception.",
2338                    NumberParseException.ErrorType.NOT_A_NUMBER,
2339                    e.getErrorType());
2340     }
2341     try {
2342       String sentencePhoneNumber = "12 MICROSOFT";
2343       phoneUtil.parse(sentencePhoneNumber, RegionCode.NZ);
2344       fail("This should not parse without throwing an exception " + sentencePhoneNumber);
2345     } catch (NumberParseException e) {
2346       // Expected this exception.
2347       assertEquals("Wrong error type stored in exception.",
2348                    NumberParseException.ErrorType.NOT_A_NUMBER,
2349                    e.getErrorType());
2350     }
2351     try {
2352       String tooLongPhoneNumber = "01495 72553301873 810104";
2353       phoneUtil.parse(tooLongPhoneNumber, RegionCode.GB);
2354       fail("This should not parse without throwing an exception " + tooLongPhoneNumber);
2355     } catch (NumberParseException e) {
2356       // Expected this exception.
2357       assertEquals("Wrong error type stored in exception.",
2358                    NumberParseException.ErrorType.TOO_LONG,
2359                    e.getErrorType());
2360     }
2361     try {
2362       String plusMinusPhoneNumber = "+---";
2363       phoneUtil.parse(plusMinusPhoneNumber, RegionCode.DE);
2364       fail("This should not parse without throwing an exception " + plusMinusPhoneNumber);
2365     } catch (NumberParseException e) {
2366       // Expected this exception.
2367       assertEquals("Wrong error type stored in exception.",
2368                    NumberParseException.ErrorType.NOT_A_NUMBER,
2369                    e.getErrorType());
2370     }
2371     try {
2372       String plusStar = "+***";
2373       phoneUtil.parse(plusStar, RegionCode.DE);
2374       fail("This should not parse without throwing an exception " + plusStar);
2375     } catch (NumberParseException e) {
2376       // Expected this exception.
2377       assertEquals("Wrong error type stored in exception.",
2378                    NumberParseException.ErrorType.NOT_A_NUMBER,
2379                    e.getErrorType());
2380     }
2381     try {
2382       String plusStarPhoneNumber = "+*******91";
2383       phoneUtil.parse(plusStarPhoneNumber, RegionCode.DE);
2384       fail("This should not parse without throwing an exception " + plusStarPhoneNumber);
2385     } catch (NumberParseException e) {
2386       // Expected this exception.
2387       assertEquals("Wrong error type stored in exception.",
2388                    NumberParseException.ErrorType.NOT_A_NUMBER,
2389                    e.getErrorType());
2390     }
2391     try {
2392       String tooShortPhoneNumber = "+49 0";
2393       phoneUtil.parse(tooShortPhoneNumber, RegionCode.DE);
2394       fail("This should not parse without throwing an exception " + tooShortPhoneNumber);
2395     } catch (NumberParseException e) {
2396       // Expected this exception.
2397       assertEquals("Wrong error type stored in exception.",
2398                    NumberParseException.ErrorType.TOO_SHORT_NSN,
2399                    e.getErrorType());
2400     }
2401     try {
2402       String invalidCountryCode = "+210 3456 56789";
2403       phoneUtil.parse(invalidCountryCode, RegionCode.NZ);
2404       fail("This is not a recognised region code: should fail: " + invalidCountryCode);
2405     } catch (NumberParseException e) {
2406       // Expected this exception.
2407       assertEquals("Wrong error type stored in exception.",
2408                    NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
2409                    e.getErrorType());
2410     }
2411     try {
2412       String plusAndIddAndInvalidCountryCode = "+ 00 210 3 331 6005";
2413       phoneUtil.parse(plusAndIddAndInvalidCountryCode, RegionCode.NZ);
2414       fail("This should not parse without throwing an exception.");
2415     } catch (NumberParseException e) {
2416       // Expected this exception. 00 is a correct IDD, but 210 is not a valid country code.
2417       assertEquals("Wrong error type stored in exception.",
2418                    NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
2419                    e.getErrorType());
2420     }
2421     try {
2422       String someNumber = "123 456 7890";
2423       phoneUtil.parse(someNumber, RegionCode.ZZ);
2424       fail("'Unknown' region code not allowed: should fail.");
2425     } catch (NumberParseException e) {
2426       // Expected this exception.
2427       assertEquals("Wrong error type stored in exception.",
2428                    NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
2429                    e.getErrorType());
2430     }
2431     try {
2432       String someNumber = "123 456 7890";
2433       phoneUtil.parse(someNumber, "CS");
2434       fail("Deprecated region code not allowed: should fail.");
2435     } catch (NumberParseException e) {
2436       // Expected this exception.
2437       assertEquals("Wrong error type stored in exception.",
2438                    NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
2439                    e.getErrorType());
2440     }
2441     try {
2442       String someNumber = "123 456 7890";
2443       phoneUtil.parse(someNumber, null);
2444       fail("Null region code not allowed: should fail.");
2445     } catch (NumberParseException e) {
2446       // Expected this exception.
2447       assertEquals("Wrong error type stored in exception.",
2448                    NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
2449                    e.getErrorType());
2450     }
2451     try {
2452       String someNumber = "0044------";
2453       phoneUtil.parse(someNumber, RegionCode.GB);
2454       fail("No number provided, only region code: should fail");
2455     } catch (NumberParseException e) {
2456       // Expected this exception.
2457       assertEquals("Wrong error type stored in exception.",
2458                    NumberParseException.ErrorType.TOO_SHORT_AFTER_IDD,
2459                    e.getErrorType());
2460     }
2461     try {
2462       String someNumber = "0044";
2463       phoneUtil.parse(someNumber, RegionCode.GB);
2464       fail("No number provided, only region code: should fail");
2465     } catch (NumberParseException e) {
2466       // Expected this exception.
2467       assertEquals("Wrong error type stored in exception.",
2468                    NumberParseException.ErrorType.TOO_SHORT_AFTER_IDD,
2469                    e.getErrorType());
2470     }
2471     try {
2472       String someNumber = "011";
2473       phoneUtil.parse(someNumber, RegionCode.US);
2474       fail("Only IDD provided - should fail.");
2475     } catch (NumberParseException e) {
2476       // Expected this exception.
2477       assertEquals("Wrong error type stored in exception.",
2478                    NumberParseException.ErrorType.TOO_SHORT_AFTER_IDD,
2479                    e.getErrorType());
2480     }
2481     try {
2482       String someNumber = "0119";
2483       phoneUtil.parse(someNumber, RegionCode.US);
2484       fail("Only IDD provided and then 9 - should fail.");
2485     } catch (NumberParseException e) {
2486       // Expected this exception.
2487       assertEquals("Wrong error type stored in exception.",
2488                    NumberParseException.ErrorType.TOO_SHORT_AFTER_IDD,
2489                    e.getErrorType());
2490     }
2491     try {
2492       String emptyNumber = "";
2493       // Invalid region.
2494       phoneUtil.parse(emptyNumber, RegionCode.ZZ);
2495       fail("Empty string - should fail.");
2496     } catch (NumberParseException e) {
2497       // Expected this exception.
2498       assertEquals("Wrong error type stored in exception.",
2499                    NumberParseException.ErrorType.NOT_A_NUMBER,
2500                    e.getErrorType());
2501     }
2502     try {
2503       String nullNumber = null;
2504       // Invalid region.
2505       phoneUtil.parse(nullNumber, RegionCode.ZZ);
2506       fail("Null string - should fail.");
2507     } catch (NumberParseException e) {
2508       // Expected this exception.
2509       assertEquals("Wrong error type stored in exception.",
2510                    NumberParseException.ErrorType.NOT_A_NUMBER,
2511                    e.getErrorType());
2512     } catch (NullPointerException e) {
2513       fail("Null string - but should not throw a null pointer exception.");
2514     }
2515     try {
2516       String nullNumber = null;
2517       phoneUtil.parse(nullNumber, RegionCode.US);
2518       fail("Null string - should fail.");
2519     } catch (NumberParseException e) {
2520       // Expected this exception.
2521       assertEquals("Wrong error type stored in exception.",
2522                    NumberParseException.ErrorType.NOT_A_NUMBER,
2523                    e.getErrorType());
2524     } catch (NullPointerException e) {
2525       fail("Null string - but should not throw a null pointer exception.");
2526     }
2527     try {
2528       String domainRfcPhoneContext = "tel:555-1234;phone-context=www.google.com";
2529       phoneUtil.parse(domainRfcPhoneContext, RegionCode.ZZ);
2530       fail("'Unknown' region code not allowed: should fail.");
2531     } catch (NumberParseException e) {
2532       // Expected this exception.
2533       assertEquals("Wrong error type stored in exception.",
2534                    NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
2535                    e.getErrorType());
2536     }
2537     try {
2538       // This is invalid because no "+" sign is present as part of phone-context. This should not
2539       // succeed in being parsed.
2540       String invalidRfcPhoneContext = "tel:555-1234;phone-context=1-331";
2541       phoneUtil.parse(invalidRfcPhoneContext, RegionCode.ZZ);
2542       fail("phone-context is missing '+' sign: should fail.");
2543     } catch (NumberParseException e) {
2544       // Expected this exception.
2545       assertEquals("Wrong error type stored in exception.",
2546                    NumberParseException.ErrorType.NOT_A_NUMBER,
2547                    e.getErrorType());
2548     }
2549     try {
2550       // Only the phone-context symbol is present, but no data.
2551       String invalidRfcPhoneContext = ";phone-context=";
2552       phoneUtil.parse(invalidRfcPhoneContext, RegionCode.ZZ);
2553       fail("phone-context can't be empty: should fail.");
2554     } catch (NumberParseException e) {
2555       // Expected this exception.
2556       assertEquals("Wrong error type stored in exception.",
2557                    NumberParseException.ErrorType.NOT_A_NUMBER,
2558                    e.getErrorType());
2559     }
2560   }
2561 
testParseNumbersWithPlusWithNoRegion()2562   public void testParseNumbersWithPlusWithNoRegion() throws Exception {
2563     // RegionCode.ZZ is allowed only if the number starts with a '+' - then the country calling code
2564     // can be calculated.
2565     assertEquals(NZ_NUMBER, phoneUtil.parse("+64 3 331 6005", RegionCode.ZZ));
2566     // Test with full-width plus.
2567     assertEquals(NZ_NUMBER, phoneUtil.parse("\uFF0B64 3 331 6005", RegionCode.ZZ));
2568     // Test with normal plus but leading characters that need to be stripped.
2569     assertEquals(NZ_NUMBER, phoneUtil.parse("Tel: +64 3 331 6005", RegionCode.ZZ));
2570     assertEquals(NZ_NUMBER, phoneUtil.parse("+64 3 331 6005", null));
2571     assertEquals(INTERNATIONAL_TOLL_FREE, phoneUtil.parse("+800 1234 5678", null));
2572     assertEquals(UNIVERSAL_PREMIUM_RATE, phoneUtil.parse("+979 123 456 789", null));
2573 
2574     // Test parsing RFC3966 format with a phone context.
2575     assertEquals(NZ_NUMBER, phoneUtil.parse("tel:03-331-6005;phone-context=+64", RegionCode.ZZ));
2576     assertEquals(NZ_NUMBER, phoneUtil.parse("  tel:03-331-6005;phone-context=+64", RegionCode.ZZ));
2577     assertEquals(NZ_NUMBER, phoneUtil.parse("tel:03-331-6005;isub=12345;phone-context=+64",
2578         RegionCode.ZZ));
2579 
2580     PhoneNumber nzNumberWithRawInput = new PhoneNumber().mergeFrom(NZ_NUMBER).
2581         setRawInput("+64 3 331 6005").
2582         setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN);
2583     assertEquals(nzNumberWithRawInput, phoneUtil.parseAndKeepRawInput("+64 3 331 6005",
2584                                                                       RegionCode.ZZ));
2585     // Null is also allowed for the region code in these cases.
2586     assertEquals(nzNumberWithRawInput, phoneUtil.parseAndKeepRawInput("+64 3 331 6005", null));
2587   }
2588 
testParseNumberTooShortIfNationalPrefixStripped()2589   public void testParseNumberTooShortIfNationalPrefixStripped() throws Exception {
2590     // Test that a number whose first digits happen to coincide with the national prefix does not
2591     // get them stripped if doing so would result in a number too short to be a possible (regular
2592     // length) phone number for that region.
2593     PhoneNumber byNumber = new PhoneNumber().setCountryCode(375).setNationalNumber(8123L);
2594     assertEquals(byNumber, phoneUtil.parse("8123", RegionCode.BY));
2595     byNumber.setNationalNumber(81234L);
2596     assertEquals(byNumber, phoneUtil.parse("81234", RegionCode.BY));
2597 
2598     // The prefix doesn't get stripped, since the input is a viable 6-digit number, whereas the
2599     // result of stripping is only 5 digits.
2600     byNumber.setNationalNumber(812345L);
2601     assertEquals(byNumber, phoneUtil.parse("812345", RegionCode.BY));
2602 
2603     // The prefix gets stripped, since only 6-digit numbers are possible.
2604     byNumber.setNationalNumber(123456L);
2605     assertEquals(byNumber, phoneUtil.parse("8123456", RegionCode.BY));
2606   }
2607 
testParseExtensions()2608   public void testParseExtensions() throws Exception {
2609     PhoneNumber nzNumber = new PhoneNumber();
2610     nzNumber.setCountryCode(64).setNationalNumber(33316005L).setExtension("3456");
2611     assertEquals(nzNumber, phoneUtil.parse("03 331 6005 ext 3456", RegionCode.NZ));
2612     assertEquals(nzNumber, phoneUtil.parse("03-3316005x3456", RegionCode.NZ));
2613     assertEquals(nzNumber, phoneUtil.parse("03-3316005 int.3456", RegionCode.NZ));
2614     assertEquals(nzNumber, phoneUtil.parse("03 3316005 #3456", RegionCode.NZ));
2615     // Test the following do not extract extensions:
2616     assertEquals(ALPHA_NUMERIC_NUMBER, phoneUtil.parse("1800 six-flags", RegionCode.US));
2617     assertEquals(ALPHA_NUMERIC_NUMBER, phoneUtil.parse("1800 SIX FLAGS", RegionCode.US));
2618     assertEquals(ALPHA_NUMERIC_NUMBER, phoneUtil.parse("0~0 1800 7493 5247", RegionCode.PL));
2619     assertEquals(ALPHA_NUMERIC_NUMBER, phoneUtil.parse("(1800) 7493.5247", RegionCode.US));
2620     // Check that the last instance of an extension token is matched.
2621     PhoneNumber extnNumber = new PhoneNumber().mergeFrom(ALPHA_NUMERIC_NUMBER).setExtension("1234");
2622     assertEquals(extnNumber, phoneUtil.parse("0~0 1800 7493 5247 ~1234", RegionCode.PL));
2623     // Verifying bug-fix where the last digit of a number was previously omitted if it was a 0 when
2624     // extracting the extension. Also verifying a few different cases of extensions.
2625     PhoneNumber ukNumber = new PhoneNumber();
2626     ukNumber.setCountryCode(44).setNationalNumber(2034567890L).setExtension("456");
2627     assertEquals(ukNumber, phoneUtil.parse("+44 2034567890x456", RegionCode.NZ));
2628     assertEquals(ukNumber, phoneUtil.parse("+44 2034567890x456", RegionCode.GB));
2629     assertEquals(ukNumber, phoneUtil.parse("+44 2034567890 x456", RegionCode.GB));
2630     assertEquals(ukNumber, phoneUtil.parse("+44 2034567890 X456", RegionCode.GB));
2631     assertEquals(ukNumber, phoneUtil.parse("+44 2034567890 X 456", RegionCode.GB));
2632     assertEquals(ukNumber, phoneUtil.parse("+44 2034567890 X  456", RegionCode.GB));
2633     assertEquals(ukNumber, phoneUtil.parse("+44 2034567890 x 456  ", RegionCode.GB));
2634     assertEquals(ukNumber, phoneUtil.parse("+44 2034567890  X 456", RegionCode.GB));
2635     assertEquals(ukNumber, phoneUtil.parse("+44-2034567890;ext=456", RegionCode.GB));
2636     assertEquals(ukNumber, phoneUtil.parse("tel:2034567890;ext=456;phone-context=+44",
2637                                            RegionCode.ZZ));
2638     // Full-width extension, "extn" only.
2639     assertEquals(ukNumber, phoneUtil.parse("+442034567890\uFF45\uFF58\uFF54\uFF4E456",
2640                                            RegionCode.GB));
2641     // "xtn" only.
2642     assertEquals(ukNumber, phoneUtil.parse("+442034567890\uFF58\uFF54\uFF4E456",
2643                                            RegionCode.GB));
2644     // "xt" only.
2645     assertEquals(ukNumber, phoneUtil.parse("+442034567890\uFF58\uFF54456",
2646                                            RegionCode.GB));
2647 
2648     PhoneNumber usWithExtension = new PhoneNumber();
2649     usWithExtension.setCountryCode(1).setNationalNumber(8009013355L).setExtension("7246433");
2650     assertEquals(usWithExtension, phoneUtil.parse("(800) 901-3355 x 7246433", RegionCode.US));
2651     assertEquals(usWithExtension, phoneUtil.parse("(800) 901-3355 , ext 7246433", RegionCode.US));
2652     assertEquals(usWithExtension, phoneUtil.parse("(800) 901-3355 ; 7246433", RegionCode.US));
2653     // To test an extension character without surrounding spaces.
2654     assertEquals(usWithExtension, phoneUtil.parse("(800) 901-3355;7246433", RegionCode.US));
2655     assertEquals(usWithExtension,
2656                  phoneUtil.parse("(800) 901-3355 ,extension 7246433", RegionCode.US));
2657     assertEquals(usWithExtension,
2658                  phoneUtil.parse("(800) 901-3355 ,extensi\u00F3n 7246433", RegionCode.US));
2659     // Repeat with the small letter o with acute accent created by combining characters.
2660     assertEquals(usWithExtension,
2661                  phoneUtil.parse("(800) 901-3355 ,extensio\u0301n 7246433", RegionCode.US));
2662     assertEquals(usWithExtension, phoneUtil.parse("(800) 901-3355 , 7246433", RegionCode.US));
2663     assertEquals(usWithExtension, phoneUtil.parse("(800) 901-3355 ext: 7246433", RegionCode.US));
2664     // Testing Russian extension \u0434\u043E\u0431 with variants found online.
2665     PhoneNumber ruWithExtension = new PhoneNumber();
2666     ruWithExtension.setCountryCode(7).setNationalNumber(4232022511L).setExtension("100");
2667     assertEquals(ruWithExtension,
2668 		 phoneUtil.parse("8 (423) 202-25-11, \u0434\u043E\u0431. 100", RegionCode.RU));
2669     assertEquals(ruWithExtension,
2670 		 phoneUtil.parse("8 (423) 202-25-11 \u0434\u043E\u0431. 100", RegionCode.RU));
2671     assertEquals(ruWithExtension,
2672 		 phoneUtil.parse("8 (423) 202-25-11, \u0434\u043E\u0431 100", RegionCode.RU));
2673     assertEquals(ruWithExtension,
2674 		 phoneUtil.parse("8 (423) 202-25-11 \u0434\u043E\u0431 100", RegionCode.RU));
2675     assertEquals(ruWithExtension,
2676 		 phoneUtil.parse("8 (423) 202-25-11\u0434\u043E\u0431100", RegionCode.RU));
2677     // In upper case
2678     assertEquals(ruWithExtension,
2679                  phoneUtil.parse("8 (423) 202-25-11, \u0414\u041E\u0411. 100", RegionCode.RU));
2680 
2681     // Test that if a number has two extensions specified, we ignore the second.
2682     PhoneNumber usWithTwoExtensionsNumber = new PhoneNumber();
2683     usWithTwoExtensionsNumber.setCountryCode(1).setNationalNumber(2121231234L).setExtension("508");
2684     assertEquals(usWithTwoExtensionsNumber, phoneUtil.parse("(212)123-1234 x508/x1234",
2685                                                             RegionCode.US));
2686     assertEquals(usWithTwoExtensionsNumber, phoneUtil.parse("(212)123-1234 x508/ x1234",
2687                                                             RegionCode.US));
2688     assertEquals(usWithTwoExtensionsNumber, phoneUtil.parse("(212)123-1234 x508\\x1234",
2689                                                             RegionCode.US));
2690 
2691     // Test parsing numbers in the form (645) 123-1234-910# works, where the last 3 digits before
2692     // the # are an extension.
2693     usWithExtension.clear();
2694     usWithExtension.setCountryCode(1).setNationalNumber(6451231234L).setExtension("910");
2695     assertEquals(usWithExtension, phoneUtil.parse("+1 (645) 123 1234-910#", RegionCode.US));
2696     // Retry with the same number in a slightly different format.
2697     assertEquals(usWithExtension, phoneUtil.parse("+1 (645) 123 1234 ext. 910#", RegionCode.US));
2698   }
2699 
testParseHandlesLongExtensionsWithExplicitLabels()2700   public void testParseHandlesLongExtensionsWithExplicitLabels() throws Exception {
2701     // Test lower and upper limits of extension lengths for each type of label.
2702     PhoneNumber nzNumber = new PhoneNumber();
2703     nzNumber.setCountryCode(64).setNationalNumber(33316005L);
2704 
2705     // Firstly, when in RFC format: PhoneNumberUtil.extLimitAfterExplicitLabel
2706     nzNumber.setExtension("0");
2707     assertEquals(nzNumber, phoneUtil.parse("tel:+6433316005;ext=0", RegionCode.NZ));
2708     nzNumber.setExtension("01234567890123456789");
2709     assertEquals(
2710         nzNumber, phoneUtil.parse("tel:+6433316005;ext=01234567890123456789", RegionCode.NZ));
2711     // Extension too long.
2712     try {
2713       phoneUtil.parse("tel:+6433316005;ext=012345678901234567890", RegionCode.NZ);
2714       fail(
2715           "This should not parse as length of extension is higher than allowed: "
2716               + "tel:+6433316005;ext=012345678901234567890");
2717     } catch (NumberParseException e) {
2718       // Expected this exception.
2719       assertEquals(
2720           "Wrong error type stored in exception.",
2721           NumberParseException.ErrorType.NOT_A_NUMBER,
2722           e.getErrorType());
2723     }
2724 
2725     // Explicit extension label: PhoneNumberUtil.extLimitAfterExplicitLabel
2726     nzNumber.setExtension("1");
2727     assertEquals(nzNumber, phoneUtil.parse("03 3316005ext:1", RegionCode.NZ));
2728     nzNumber.setExtension("12345678901234567890");
2729     assertEquals(nzNumber, phoneUtil.parse("03 3316005 xtn:12345678901234567890", RegionCode.NZ));
2730     assertEquals(
2731         nzNumber, phoneUtil.parse("03 3316005 extension\t12345678901234567890", RegionCode.NZ));
2732     assertEquals(
2733         nzNumber, phoneUtil.parse("03 3316005 xtensio:12345678901234567890", RegionCode.NZ));
2734     assertEquals(
2735         nzNumber, phoneUtil.parse("03 3316005 xtensi\u00F3n, 12345678901234567890#", RegionCode.NZ));
2736     assertEquals(
2737         nzNumber, phoneUtil.parse("03 3316005extension.12345678901234567890", RegionCode.NZ));
2738     assertEquals(nzNumber, phoneUtil.parse("03 3316005 \u0434\u043E\u0431:12345678901234567890", RegionCode.NZ));
2739     // Extension too long.
2740     try {
2741       phoneUtil.parse("03 3316005 extension 123456789012345678901", RegionCode.NZ);
2742       fail(
2743           "This should not parse as length of extension is higher than allowed: "
2744               + "03 3316005 extension 123456789012345678901");
2745     } catch (NumberParseException e) {
2746       // Expected this exception.
2747       assertEquals(
2748           "Wrong error type stored in exception.",
2749           NumberParseException.ErrorType.TOO_LONG,
2750           e.getErrorType());
2751     }
2752   }
2753 
testParseHandlesLongExtensionsWithAutoDiallingLabels()2754   public void testParseHandlesLongExtensionsWithAutoDiallingLabels() throws Exception {
2755     // Secondly, cases of auto-dialling and other standard extension labels,
2756     // PhoneNumberUtil.extLimitAfterLikelyLabel
2757     PhoneNumber usNumberUserInput = new PhoneNumber();
2758     usNumberUserInput.setCountryCode(1).setNationalNumber(2679000000L);
2759     usNumberUserInput.setExtension("123456789012345");
2760     assertEquals(
2761         usNumberUserInput, phoneUtil.parse("+12679000000,,123456789012345#", RegionCode.US));
2762     assertEquals(
2763         usNumberUserInput, phoneUtil.parse("+12679000000;123456789012345#", RegionCode.US));
2764     PhoneNumber ukNumberUserInput = new PhoneNumber();
2765     ukNumberUserInput.setCountryCode(44).setNationalNumber(2034000000L).setExtension("123456789");
2766     assertEquals(ukNumberUserInput, phoneUtil.parse("+442034000000,,123456789#", RegionCode.GB));
2767     // Extension too long.
2768     try {
2769       phoneUtil.parse("+12679000000,,1234567890123456#", RegionCode.US);
2770       fail(
2771           "This should not parse as length of extension is higher than allowed: "
2772               + "+12679000000,,1234567890123456#");
2773     } catch (NumberParseException e) {
2774       // Expected this exception.
2775       assertEquals(
2776           "Wrong error type stored in exception.",
2777           NumberParseException.ErrorType.NOT_A_NUMBER,
2778           e.getErrorType());
2779     }
2780   }
2781 
testParseHandlesShortExtensionsWithAmbiguousChar()2782   public void testParseHandlesShortExtensionsWithAmbiguousChar() throws Exception {
2783     PhoneNumber nzNumber = new PhoneNumber();
2784     nzNumber.setCountryCode(64).setNationalNumber(33316005L);
2785 
2786     // Thirdly, for single and non-standard cases:
2787     // PhoneNumberUtil.extLimitAfterAmbiguousChar
2788     nzNumber.setExtension("123456789");
2789     assertEquals(nzNumber, phoneUtil.parse("03 3316005 x 123456789", RegionCode.NZ));
2790     assertEquals(nzNumber, phoneUtil.parse("03 3316005 x. 123456789", RegionCode.NZ));
2791     assertEquals(nzNumber, phoneUtil.parse("03 3316005 #123456789#", RegionCode.NZ));
2792     assertEquals(nzNumber, phoneUtil.parse("03 3316005 ~ 123456789", RegionCode.NZ));
2793     // Extension too long.
2794     try {
2795       phoneUtil.parse("03 3316005 ~ 1234567890", RegionCode.NZ);
2796       fail(
2797           "This should not parse as length of extension is higher than allowed: "
2798               + "03 3316005 ~ 1234567890");
2799     } catch (NumberParseException e) {
2800       // Expected this exception.
2801       assertEquals(
2802           "Wrong error type stored in exception.",
2803           NumberParseException.ErrorType.TOO_LONG,
2804           e.getErrorType());
2805     }
2806   }
2807 
testParseHandlesShortExtensionsWhenNotSureOfLabel()2808   public void testParseHandlesShortExtensionsWhenNotSureOfLabel() throws Exception {
2809     // Lastly, when no explicit extension label present, but denoted by tailing #:
2810     // PhoneNumberUtil.extLimitWhenNotSure
2811     PhoneNumber usNumber = new PhoneNumber();
2812     usNumber.setCountryCode(1).setNationalNumber(1234567890L).setExtension("666666");
2813     assertEquals(usNumber, phoneUtil.parse("+1123-456-7890 666666#", RegionCode.US));
2814     usNumber.setExtension("6");
2815     assertEquals(usNumber, phoneUtil.parse("+11234567890-6#", RegionCode.US));
2816     // Extension too long.
2817     try {
2818       phoneUtil.parse("+1123-456-7890 7777777#", RegionCode.US);
2819       fail(
2820           "This should not parse as length of extension is higher than allowed: "
2821               + "+1123-456-7890 7777777#");
2822     } catch (NumberParseException e) {
2823       // Expected this exception.
2824       assertEquals(
2825           "Wrong error type stored in exception.",
2826           NumberParseException.ErrorType.NOT_A_NUMBER,
2827           e.getErrorType());
2828     }
2829   }
2830 
testParseAndKeepRaw()2831   public void testParseAndKeepRaw() throws Exception {
2832     PhoneNumber alphaNumericNumber = new PhoneNumber().mergeFrom(ALPHA_NUMERIC_NUMBER).
2833         setRawInput("800 six-flags").
2834         setCountryCodeSource(CountryCodeSource.FROM_DEFAULT_COUNTRY);
2835     assertEquals(alphaNumericNumber,
2836                  phoneUtil.parseAndKeepRawInput("800 six-flags", RegionCode.US));
2837 
2838     PhoneNumber shorterAlphaNumber = new PhoneNumber().
2839         setCountryCode(1).setNationalNumber(8007493524L).
2840         setRawInput("1800 six-flag").
2841         setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN);
2842     assertEquals(shorterAlphaNumber,
2843                  phoneUtil.parseAndKeepRawInput("1800 six-flag", RegionCode.US));
2844 
2845     shorterAlphaNumber.setRawInput("+1800 six-flag").
2846         setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN);
2847     assertEquals(shorterAlphaNumber,
2848                  phoneUtil.parseAndKeepRawInput("+1800 six-flag", RegionCode.NZ));
2849 
2850     shorterAlphaNumber.setRawInput("001800 six-flag").
2851         setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_IDD);
2852     assertEquals(shorterAlphaNumber,
2853                  phoneUtil.parseAndKeepRawInput("001800 six-flag", RegionCode.NZ));
2854 
2855     // Invalid region code supplied.
2856     try {
2857       phoneUtil.parseAndKeepRawInput("123 456 7890", "CS");
2858       fail("Deprecated region code not allowed: should fail.");
2859     } catch (NumberParseException e) {
2860       // Expected this exception.
2861       assertEquals("Wrong error type stored in exception.",
2862                    NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
2863                    e.getErrorType());
2864     }
2865 
2866     PhoneNumber koreanNumber = new PhoneNumber();
2867     koreanNumber.setCountryCode(82).setNationalNumber(22123456).setRawInput("08122123456").
2868         setCountryCodeSource(CountryCodeSource.FROM_DEFAULT_COUNTRY).
2869         setPreferredDomesticCarrierCode("81");
2870     assertEquals(koreanNumber, phoneUtil.parseAndKeepRawInput("08122123456", RegionCode.KR));
2871   }
2872 
testParseItalianLeadingZeros()2873   public void testParseItalianLeadingZeros() throws Exception {
2874     // Test the number "011".
2875     PhoneNumber oneZero = new PhoneNumber();
2876     oneZero.setCountryCode(61).setNationalNumber(11L).setItalianLeadingZero(true);
2877     assertEquals(oneZero, phoneUtil.parse("011", RegionCode.AU));
2878 
2879     // Test the number "001".
2880     PhoneNumber twoZeros = new PhoneNumber();
2881     twoZeros.setCountryCode(61).setNationalNumber(1).setItalianLeadingZero(true)
2882         .setNumberOfLeadingZeros(2);
2883     assertEquals(twoZeros, phoneUtil.parse("001", RegionCode.AU));
2884 
2885     // Test the number "000". This number has 2 leading zeros.
2886     PhoneNumber stillTwoZeros = new PhoneNumber();
2887     stillTwoZeros.setCountryCode(61).setNationalNumber(0L).setItalianLeadingZero(true)
2888         .setNumberOfLeadingZeros(2);
2889     assertEquals(stillTwoZeros, phoneUtil.parse("000", RegionCode.AU));
2890 
2891     // Test the number "0000". This number has 3 leading zeros.
2892     PhoneNumber threeZeros = new PhoneNumber();
2893     threeZeros.setCountryCode(61).setNationalNumber(0L).setItalianLeadingZero(true)
2894         .setNumberOfLeadingZeros(3);
2895     assertEquals(threeZeros, phoneUtil.parse("0000", RegionCode.AU));
2896   }
2897 
testParseWithPhoneContext()2898   public void testParseWithPhoneContext() throws Exception {
2899     // context    = ";phone-context=" descriptor
2900     // descriptor = domainname / global-number-digits
2901 
2902     // Valid global-phone-digits
2903     assertEquals(NZ_NUMBER, phoneUtil.parse("tel:033316005;phone-context=+64", RegionCode.ZZ));
2904     assertEquals(
2905         NZ_NUMBER,
2906         phoneUtil.parse(
2907             "tel:033316005;phone-context=+64;{this isn't part of phone-context anymore!}",
2908             RegionCode.ZZ));
2909     PhoneNumber nzFromPhoneContext = new PhoneNumber();
2910     nzFromPhoneContext.setCountryCode(64).setNationalNumber(3033316005L);
2911     assertEquals(
2912         nzFromPhoneContext,
2913         phoneUtil.parse("tel:033316005;phone-context=+64-3", RegionCode.ZZ));
2914     PhoneNumber brFromPhoneContext = new PhoneNumber();
2915     brFromPhoneContext.setCountryCode(55).setNationalNumber(5033316005L);
2916     assertEquals(
2917         brFromPhoneContext,
2918         phoneUtil.parse("tel:033316005;phone-context=+(555)", RegionCode.ZZ));
2919     PhoneNumber usFromPhoneContext = new PhoneNumber();
2920     usFromPhoneContext.setCountryCode(1).setNationalNumber(23033316005L);
2921     assertEquals(
2922         usFromPhoneContext,
2923         phoneUtil.parse("tel:033316005;phone-context=+-1-2.3()", RegionCode.ZZ));
2924 
2925     // Valid domainname
2926     assertEquals(NZ_NUMBER, phoneUtil.parse("tel:033316005;phone-context=abc.nz", RegionCode.NZ));
2927     assertEquals(
2928         NZ_NUMBER,
2929         phoneUtil.parse("tel:033316005;phone-context=www.PHONE-numb3r.com", RegionCode.NZ));
2930     assertEquals(NZ_NUMBER, phoneUtil.parse("tel:033316005;phone-context=a", RegionCode.NZ));
2931     assertEquals(
2932         NZ_NUMBER, phoneUtil.parse("tel:033316005;phone-context=3phone.J.", RegionCode.NZ));
2933     assertEquals(NZ_NUMBER, phoneUtil.parse("tel:033316005;phone-context=a--z", RegionCode.NZ));
2934 
2935     // Invalid descriptor
2936     assertThrowsForInvalidPhoneContext("tel:033316005;phone-context=");
2937     assertThrowsForInvalidPhoneContext("tel:033316005;phone-context=+");
2938     assertThrowsForInvalidPhoneContext("tel:033316005;phone-context=64");
2939     assertThrowsForInvalidPhoneContext("tel:033316005;phone-context=++64");
2940     assertThrowsForInvalidPhoneContext("tel:033316005;phone-context=+abc");
2941     assertThrowsForInvalidPhoneContext("tel:033316005;phone-context=.");
2942     assertThrowsForInvalidPhoneContext("tel:033316005;phone-context=3phone");
2943     assertThrowsForInvalidPhoneContext("tel:033316005;phone-context=a-.nz");
2944     assertThrowsForInvalidPhoneContext("tel:033316005;phone-context=a{b}c");
2945   }
2946 
assertThrowsForInvalidPhoneContext(String numberToParse)2947   private void assertThrowsForInvalidPhoneContext(String numberToParse) {
2948     final String numberToParseFinal = numberToParse;
2949     assertEquals(
2950         NumberParseException.ErrorType.NOT_A_NUMBER,
2951         assertThrows(
2952             NumberParseException.class, new ThrowingRunnable() {
2953               @Override
2954               public void run() throws Throwable {
2955                 phoneUtil.parse(numberToParseFinal, RegionCode.ZZ);
2956               }
2957             })
2958             .getErrorType());
2959   }
2960 
testCountryWithNoNumberDesc()2961   public void testCountryWithNoNumberDesc() {
2962     // Andorra is a country where we don't have PhoneNumberDesc info in the metadata.
2963     PhoneNumber adNumber = new PhoneNumber();
2964     adNumber.setCountryCode(376).setNationalNumber(12345L);
2965     assertEquals("+376 12345", phoneUtil.format(adNumber, PhoneNumberFormat.INTERNATIONAL));
2966     assertEquals("+37612345", phoneUtil.format(adNumber, PhoneNumberFormat.E164));
2967     assertEquals("12345", phoneUtil.format(adNumber, PhoneNumberFormat.NATIONAL));
2968     assertEquals(PhoneNumberType.UNKNOWN, phoneUtil.getNumberType(adNumber));
2969     assertFalse(phoneUtil.isValidNumber(adNumber));
2970 
2971     // Test dialing a US number from within Andorra.
2972     assertEquals("00 1 650 253 0000",
2973                  phoneUtil.formatOutOfCountryCallingNumber(US_NUMBER, RegionCode.AD));
2974   }
2975 
testUnknownCountryCallingCode()2976   public void testUnknownCountryCallingCode() {
2977     assertFalse(phoneUtil.isValidNumber(UNKNOWN_COUNTRY_CODE_NO_RAW_INPUT));
2978     // It's not very well defined as to what the E164 representation for a number with an invalid
2979     // country calling code is, but just prefixing the country code and national number is about
2980     // the best we can do.
2981     assertEquals("+212345",
2982         phoneUtil.format(UNKNOWN_COUNTRY_CODE_NO_RAW_INPUT, PhoneNumberFormat.E164));
2983   }
2984 
testIsNumberMatchMatches()2985   public void testIsNumberMatchMatches() throws Exception {
2986     // Test simple matches where formatting is different, or leading zeros, or country calling code
2987     // has been specified.
2988     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
2989                  phoneUtil.isNumberMatch("+64 3 331 6005", "+64 03 331 6005"));
2990     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
2991                  phoneUtil.isNumberMatch("+800 1234 5678", "+80012345678"));
2992     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
2993                  phoneUtil.isNumberMatch("+64 03 331-6005", "+64 03331 6005"));
2994     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
2995                  phoneUtil.isNumberMatch("+643 331-6005", "+64033316005"));
2996     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
2997                  phoneUtil.isNumberMatch("+643 331-6005", "+6433316005"));
2998     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
2999                  phoneUtil.isNumberMatch("+64 3 331-6005", "+6433316005"));
3000     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
3001                  phoneUtil.isNumberMatch("+64 3 331-6005", "tel:+64-3-331-6005;isub=123"));
3002     // Test alpha numbers.
3003     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
3004                  phoneUtil.isNumberMatch("+1800 siX-Flags", "+1 800 7493 5247"));
3005     // Test numbers with extensions.
3006     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
3007                  phoneUtil.isNumberMatch("+64 3 331-6005 extn 1234", "+6433316005#1234"));
3008     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
3009                  phoneUtil.isNumberMatch("+64 3 331-6005 ext. 1234", "+6433316005;1234"));
3010     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
3011                  phoneUtil.isNumberMatch("+7 423 202-25-11 ext 100",
3012 					 "+7 4232022511 \u0434\u043E\u0431. 100"));
3013     // Test proto buffers.
3014     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
3015                  phoneUtil.isNumberMatch(NZ_NUMBER, "+6403 331 6005"));
3016 
3017     PhoneNumber nzNumber = new PhoneNumber().mergeFrom(NZ_NUMBER).setExtension("3456");
3018     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
3019                  phoneUtil.isNumberMatch(nzNumber, "+643 331 6005 ext 3456"));
3020     // Check empty extensions are ignored.
3021     nzNumber.setExtension("");
3022     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
3023                  phoneUtil.isNumberMatch(nzNumber, "+6403 331 6005"));
3024     // Check variant with two proto buffers.
3025     assertEquals("Number " + nzNumber.toString() + " did not match " + NZ_NUMBER.toString(),
3026                  PhoneNumberUtil.MatchType.EXACT_MATCH,
3027                  phoneUtil.isNumberMatch(nzNumber, NZ_NUMBER));
3028 
3029   }
3030 
testIsNumberMatchShortMatchIfDiffNumLeadingZeros()3031   public void testIsNumberMatchShortMatchIfDiffNumLeadingZeros() throws Exception {
3032     PhoneNumber nzNumberOne = new PhoneNumber();
3033     PhoneNumber nzNumberTwo = new PhoneNumber();
3034     nzNumberOne.setCountryCode(64).setNationalNumber(33316005L).setItalianLeadingZero(true);
3035     nzNumberTwo.setCountryCode(64).setNationalNumber(33316005L).setItalianLeadingZero(true)
3036         .setNumberOfLeadingZeros(2);
3037     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3038                  phoneUtil.isNumberMatch(nzNumberOne, nzNumberTwo));
3039 
3040     nzNumberOne.setItalianLeadingZero(false).setNumberOfLeadingZeros(1);
3041     nzNumberTwo.setItalianLeadingZero(true).setNumberOfLeadingZeros(1);
3042     // Since one doesn't have the "italian_leading_zero" set to true, we ignore the number of
3043     // leading zeros present (1 is in any case the default value).
3044     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3045                  phoneUtil.isNumberMatch(nzNumberOne, nzNumberTwo));
3046   }
3047 
testIsNumberMatchAcceptsProtoDefaultsAsMatch()3048   public void testIsNumberMatchAcceptsProtoDefaultsAsMatch() throws Exception {
3049     PhoneNumber nzNumberOne = new PhoneNumber();
3050     PhoneNumber nzNumberTwo = new PhoneNumber();
3051     nzNumberOne.setCountryCode(64).setNationalNumber(33316005L).setItalianLeadingZero(true);
3052     // The default for number_of_leading_zeros is 1, so it shouldn't normally be set, however if it
3053     // is it should be considered equivalent.
3054     nzNumberTwo.setCountryCode(64).setNationalNumber(33316005L).setItalianLeadingZero(true)
3055         .setNumberOfLeadingZeros(1);
3056     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
3057                  phoneUtil.isNumberMatch(nzNumberOne, nzNumberTwo));
3058   }
3059 
testIsNumberMatchMatchesDiffLeadingZerosIfItalianLeadingZeroFalse()3060   public void testIsNumberMatchMatchesDiffLeadingZerosIfItalianLeadingZeroFalse() throws Exception {
3061     PhoneNumber nzNumberOne = new PhoneNumber();
3062     PhoneNumber nzNumberTwo = new PhoneNumber();
3063     nzNumberOne.setCountryCode(64).setNationalNumber(33316005L);
3064     // The default for number_of_leading_zeros is 1, so it shouldn't normally be set, however if it
3065     // is it should be considered equivalent.
3066     nzNumberTwo.setCountryCode(64).setNationalNumber(33316005L).setNumberOfLeadingZeros(1);
3067     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
3068                  phoneUtil.isNumberMatch(nzNumberOne, nzNumberTwo));
3069 
3070     // Even if it is set to ten, it is still equivalent because in both cases
3071     // italian_leading_zero is not true.
3072     nzNumberTwo.setNumberOfLeadingZeros(10);
3073     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
3074                  phoneUtil.isNumberMatch(nzNumberOne, nzNumberTwo));
3075   }
3076 
testIsNumberMatchIgnoresSomeFields()3077   public void testIsNumberMatchIgnoresSomeFields() throws Exception {
3078     // Check raw_input, country_code_source and preferred_domestic_carrier_code are ignored.
3079     PhoneNumber brNumberOne = new PhoneNumber();
3080     PhoneNumber brNumberTwo = new PhoneNumber();
3081     brNumberOne.setCountryCode(55).setNationalNumber(3121286979L)
3082         .setCountryCodeSource(PhoneNumber.CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN)
3083         .setPreferredDomesticCarrierCode("12").setRawInput("012 3121286979");
3084     brNumberTwo.setCountryCode(55).setNationalNumber(3121286979L)
3085         .setCountryCodeSource(PhoneNumber.CountryCodeSource.FROM_DEFAULT_COUNTRY)
3086         .setPreferredDomesticCarrierCode("14").setRawInput("143121286979");
3087     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
3088                  phoneUtil.isNumberMatch(brNumberOne, brNumberTwo));
3089   }
3090 
testIsNumberMatchNonMatches()3091   public void testIsNumberMatchNonMatches() throws Exception {
3092     // Non-matches.
3093     assertEquals(PhoneNumberUtil.MatchType.NO_MATCH,
3094                  phoneUtil.isNumberMatch("03 331 6005", "03 331 6006"));
3095     assertEquals(PhoneNumberUtil.MatchType.NO_MATCH,
3096                  phoneUtil.isNumberMatch("+800 1234 5678", "+1 800 1234 5678"));
3097     // Different country calling code, partial number match.
3098     assertEquals(PhoneNumberUtil.MatchType.NO_MATCH,
3099                  phoneUtil.isNumberMatch("+64 3 331-6005", "+16433316005"));
3100     // Different country calling code, same number.
3101     assertEquals(PhoneNumberUtil.MatchType.NO_MATCH,
3102                  phoneUtil.isNumberMatch("+64 3 331-6005", "+6133316005"));
3103     // Extension different, all else the same.
3104     assertEquals(PhoneNumberUtil.MatchType.NO_MATCH,
3105                  phoneUtil.isNumberMatch("+64 3 331-6005 extn 1234", "0116433316005#1235"));
3106     assertEquals(PhoneNumberUtil.MatchType.NO_MATCH,
3107                  phoneUtil.isNumberMatch(
3108                      "+64 3 331-6005 extn 1234", "tel:+64-3-331-6005;ext=1235"));
3109     // NSN matches, but extension is different - not the same number.
3110     assertEquals(PhoneNumberUtil.MatchType.NO_MATCH,
3111                  phoneUtil.isNumberMatch("+64 3 331-6005 ext.1235", "3 331 6005#1234"));
3112 
3113     // Invalid numbers that can't be parsed.
3114     assertEquals(PhoneNumberUtil.MatchType.NOT_A_NUMBER,
3115                  phoneUtil.isNumberMatch("4", "3 331 6043"));
3116     assertEquals(PhoneNumberUtil.MatchType.NOT_A_NUMBER,
3117                  phoneUtil.isNumberMatch("+43", "+64 3 331 6005"));
3118     assertEquals(PhoneNumberUtil.MatchType.NOT_A_NUMBER,
3119                  phoneUtil.isNumberMatch("+43", "64 3 331 6005"));
3120     assertEquals(PhoneNumberUtil.MatchType.NOT_A_NUMBER,
3121                  phoneUtil.isNumberMatch("Dog", "64 3 331 6005"));
3122   }
3123 
testIsNumberMatchNsnMatches()3124   public void testIsNumberMatchNsnMatches() throws Exception {
3125     // NSN matches.
3126     assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
3127                  phoneUtil.isNumberMatch("+64 3 331-6005", "03 331 6005"));
3128     assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
3129                  phoneUtil.isNumberMatch(
3130                      "+64 3 331-6005", "tel:03-331-6005;isub=1234;phone-context=abc.nz"));
3131     assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
3132                  phoneUtil.isNumberMatch(NZ_NUMBER, "03 331 6005"));
3133     // Here the second number possibly starts with the country calling code for New Zealand,
3134     // although we are unsure.
3135     PhoneNumber unchangedNzNumber = new PhoneNumber().mergeFrom(NZ_NUMBER);
3136     assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
3137                  phoneUtil.isNumberMatch(unchangedNzNumber, "(64-3) 331 6005"));
3138     // Check the phone number proto was not edited during the method call.
3139     assertEquals(NZ_NUMBER, unchangedNzNumber);
3140 
3141     // Here, the 1 might be a national prefix, if we compare it to the US number, so the resultant
3142     // match is an NSN match.
3143     assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
3144                  phoneUtil.isNumberMatch(US_NUMBER, "1-650-253-0000"));
3145     assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
3146                  phoneUtil.isNumberMatch(US_NUMBER, "6502530000"));
3147     assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
3148                  phoneUtil.isNumberMatch("+1 650-253 0000", "1 650 253 0000"));
3149     assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
3150                  phoneUtil.isNumberMatch("1 650-253 0000", "1 650 253 0000"));
3151     assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
3152                  phoneUtil.isNumberMatch("1 650-253 0000", "+1 650 253 0000"));
3153     // For this case, the match will be a short NSN match, because we cannot assume that the 1 might
3154     // be a national prefix, so don't remove it when parsing.
3155     PhoneNumber randomNumber = new PhoneNumber();
3156     randomNumber.setCountryCode(41).setNationalNumber(6502530000L);
3157     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3158                  phoneUtil.isNumberMatch(randomNumber, "1-650-253-0000"));
3159   }
3160 
testIsNumberMatchShortNsnMatches()3161   public void testIsNumberMatchShortNsnMatches() throws Exception {
3162     // Short NSN matches with the country not specified for either one or both numbers.
3163     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3164                  phoneUtil.isNumberMatch("+64 3 331-6005", "331 6005"));
3165     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3166                  phoneUtil.isNumberMatch("+64 3 331-6005", "tel:331-6005;phone-context=abc.nz"));
3167     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3168                  phoneUtil.isNumberMatch("+64 3 331-6005",
3169                      "tel:331-6005;isub=1234;phone-context=abc.nz"));
3170     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3171                  phoneUtil.isNumberMatch("+64 3 331-6005",
3172                      "tel:331-6005;isub=1234;phone-context=abc.nz;a=%A1"));
3173     // We did not know that the "0" was a national prefix since neither number has a country code,
3174     // so this is considered a SHORT_NSN_MATCH.
3175     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3176                  phoneUtil.isNumberMatch("3 331-6005", "03 331 6005"));
3177     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3178                  phoneUtil.isNumberMatch("3 331-6005", "331 6005"));
3179     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3180                  phoneUtil.isNumberMatch("3 331-6005", "tel:331-6005;phone-context=abc.nz"));
3181     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3182                  phoneUtil.isNumberMatch("3 331-6005", "+64 331 6005"));
3183     // Short NSN match with the country specified.
3184     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3185                  phoneUtil.isNumberMatch("03 331-6005", "331 6005"));
3186     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3187                  phoneUtil.isNumberMatch("1 234 345 6789", "345 6789"));
3188     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3189                  phoneUtil.isNumberMatch("+1 (234) 345 6789", "345 6789"));
3190     // NSN matches, country calling code omitted for one number, extension missing for one.
3191     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3192                  phoneUtil.isNumberMatch("+64 3 331-6005", "3 331 6005#1234"));
3193     // One has Italian leading zero, one does not.
3194     PhoneNumber italianNumberOne = new PhoneNumber();
3195     italianNumberOne.setCountryCode(39).setNationalNumber(1234L).setItalianLeadingZero(true);
3196     PhoneNumber italianNumberTwo = new PhoneNumber();
3197     italianNumberTwo.setCountryCode(39).setNationalNumber(1234L);
3198     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3199                  phoneUtil.isNumberMatch(italianNumberOne, italianNumberTwo));
3200     // One has an extension, the other has an extension of "".
3201     italianNumberOne.setExtension("1234").clearItalianLeadingZero();
3202     italianNumberTwo.setExtension("");
3203     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3204                  phoneUtil.isNumberMatch(italianNumberOne, italianNumberTwo));
3205   }
3206 
testCanBeInternationallyDialled()3207   public void testCanBeInternationallyDialled() throws Exception {
3208     // We have no-international-dialling rules for the US in our test metadata that say that
3209     // toll-free numbers cannot be dialled internationally.
3210     assertFalse(phoneUtil.canBeInternationallyDialled(US_TOLLFREE));
3211 
3212     // Normal US numbers can be internationally dialled.
3213     assertTrue(phoneUtil.canBeInternationallyDialled(US_NUMBER));
3214 
3215     // Invalid number.
3216     assertTrue(phoneUtil.canBeInternationallyDialled(US_LOCAL_NUMBER));
3217 
3218     // We have no data for NZ - should return true.
3219     assertTrue(phoneUtil.canBeInternationallyDialled(NZ_NUMBER));
3220     assertTrue(phoneUtil.canBeInternationallyDialled(INTERNATIONAL_TOLL_FREE));
3221   }
3222 
testIsAlphaNumber()3223   public void testIsAlphaNumber() throws Exception {
3224     assertTrue(phoneUtil.isAlphaNumber("1800 six-flags"));
3225     assertTrue(phoneUtil.isAlphaNumber("1800 six-flags ext. 1234"));
3226     assertTrue(phoneUtil.isAlphaNumber("+800 six-flags"));
3227     assertTrue(phoneUtil.isAlphaNumber("180 six-flags"));
3228     assertFalse(phoneUtil.isAlphaNumber("1800 123-1234"));
3229     assertFalse(phoneUtil.isAlphaNumber("1 six-flags"));
3230     assertFalse(phoneUtil.isAlphaNumber("18 six-flags"));
3231     assertFalse(phoneUtil.isAlphaNumber("1800 123-1234 extension: 1234"));
3232     assertFalse(phoneUtil.isAlphaNumber("+800 1234-1234"));
3233   }
3234 
testIsMobileNumberPortableRegion()3235   public void testIsMobileNumberPortableRegion() {
3236     assertTrue(phoneUtil.isMobileNumberPortableRegion(RegionCode.US));
3237     assertTrue(phoneUtil.isMobileNumberPortableRegion(RegionCode.GB));
3238     assertFalse(phoneUtil.isMobileNumberPortableRegion(RegionCode.AE));
3239     assertFalse(phoneUtil.isMobileNumberPortableRegion(RegionCode.BS));
3240   }
3241 
testGetMetadataForRegionForNonGeoEntity_shouldBeNull()3242   public void testGetMetadataForRegionForNonGeoEntity_shouldBeNull() {
3243     assertNull(phoneUtil.getMetadataForRegion(RegionCode.UN001));
3244   }
3245 
testGetMetadataForRegionForUnknownRegion_shouldBeNull()3246   public void testGetMetadataForRegionForUnknownRegion_shouldBeNull() {
3247     assertNull(phoneUtil.getMetadataForRegion(RegionCode.ZZ));
3248   }
3249 
testGetMetadataForNonGeographicalRegionForGeoRegion_shouldBeNull()3250   public void testGetMetadataForNonGeographicalRegionForGeoRegion_shouldBeNull() {
3251     assertNull(phoneUtil.getMetadataForNonGeographicalRegion(/* countryCallingCode = */ 1));
3252   }
3253 
testGetMetadataForRegionForMissingMetadata()3254   public void testGetMetadataForRegionForMissingMetadata() {
3255     assertThrows(
3256         MissingMetadataException.class,
3257         new ThrowingRunnable() {
3258           @Override
3259           public void run() {
3260             phoneNumberUtilWithMissingMetadata.getMetadataForRegion(RegionCode.US);
3261           }
3262         });
3263   }
3264 
testGetMetadataForNonGeographicalRegionForMissingMetadata()3265   public void testGetMetadataForNonGeographicalRegionForMissingMetadata() {
3266     assertThrows(
3267         MissingMetadataException.class,
3268         new ThrowingRunnable() {
3269           @Override
3270           public void run() {
3271             phoneNumberUtilWithMissingMetadata.getMetadataForNonGeographicalRegion(800);
3272           }
3273         });
3274   }
3275 }
3276