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