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