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