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