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