• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.i18n.phonenumbers;
18 
19 import com.android.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat;
20 import com.android.i18n.phonenumbers.Phonemetadata.NumberFormat;
21 import com.android.i18n.phonenumbers.Phonemetadata.PhoneMetadata;
22 import com.android.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc;
23 import com.android.i18n.phonenumbers.Phonenumber.PhoneNumber;
24 import com.android.i18n.phonenumbers.Phonenumber.PhoneNumber.CountryCodeSource;
25 
26 import junit.framework.TestCase;
27 
28 import java.util.ArrayList;
29 import java.util.List;
30 
31 /**
32  * Unit tests for PhoneNumberUtil.java
33  *
34  * Note that these tests use the metadata contained in the files with TEST_META_DATA_FILE_PREFIX,
35  * not the normal metadata files, so should not be used for regression test purposes - these tests
36  * are illustrative only and test functionality.
37  *
38  * @author Shaopeng Jia
39  * @author Lara Rennie
40  */
41 public class PhoneNumberUtilTest extends TestCase {
42   private PhoneNumberUtil phoneUtil;
43   // This is used by BuildMetadataProtoFromXml.
44   static final String TEST_META_DATA_FILE_PREFIX =
45       "/com/android/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting";
46 
47   // Set up some test numbers to re-use.
48   private static final PhoneNumber ALPHA_NUMERIC_NUMBER =
49       new PhoneNumber().setCountryCode(1).setNationalNumber(80074935247L);
50   private static final PhoneNumber AR_MOBILE =
51       new PhoneNumber().setCountryCode(54).setNationalNumber(91187654321L);
52   private static final PhoneNumber AR_NUMBER =
53       new PhoneNumber().setCountryCode(54).setNationalNumber(1187654321);
54   private static final PhoneNumber AU_NUMBER =
55       new PhoneNumber().setCountryCode(61).setNationalNumber(236618300L);
56   private static final PhoneNumber BS_MOBILE =
57       new PhoneNumber().setCountryCode(1).setNationalNumber(2423570000L);
58   private static final PhoneNumber BS_NUMBER =
59       new PhoneNumber().setCountryCode(1).setNationalNumber(2423651234L);
60   // Note that this is the same as the example number for DE in the metadata.
61   private static final PhoneNumber DE_NUMBER =
62       new PhoneNumber().setCountryCode(49).setNationalNumber(30123456L);
63   private static final PhoneNumber DE_SHORT_NUMBER =
64       new PhoneNumber().setCountryCode(49).setNationalNumber(1234L);
65   private static final PhoneNumber GB_MOBILE =
66       new PhoneNumber().setCountryCode(44).setNationalNumber(7912345678L);
67   private static final PhoneNumber GB_NUMBER =
68       new PhoneNumber().setCountryCode(44).setNationalNumber(2070313000L);
69   private static final PhoneNumber IT_MOBILE =
70       new PhoneNumber().setCountryCode(39).setNationalNumber(345678901L);
71   private static final PhoneNumber IT_NUMBER =
72       new PhoneNumber().setCountryCode(39).setNationalNumber(236618300L).
73       setItalianLeadingZero(true);
74   // Numbers to test the formatting rules from Mexico.
75   private static final PhoneNumber MX_MOBILE1 =
76       new PhoneNumber().setCountryCode(52).setNationalNumber(12345678900L);
77   private static final PhoneNumber MX_MOBILE2 =
78       new PhoneNumber().setCountryCode(52).setNationalNumber(15512345678L);
79   private static final PhoneNumber MX_NUMBER1 =
80       new PhoneNumber().setCountryCode(52).setNationalNumber(3312345678L);
81   private static final PhoneNumber MX_NUMBER2 =
82       new PhoneNumber().setCountryCode(52).setNationalNumber(8211234567L);
83   private static final PhoneNumber NZ_NUMBER =
84       new PhoneNumber().setCountryCode(64).setNationalNumber(33316005L);
85   private static final PhoneNumber SG_NUMBER =
86       new PhoneNumber().setCountryCode(65).setNationalNumber(65218000L);
87   // A too-long and hence invalid US number.
88   private static final PhoneNumber US_LONG_NUMBER =
89       new PhoneNumber().setCountryCode(1).setNationalNumber(65025300001L);
90   private static final PhoneNumber US_NUMBER =
91       new PhoneNumber().setCountryCode(1).setNationalNumber(6502530000L);
92   private static final PhoneNumber US_PREMIUM =
93       new PhoneNumber().setCountryCode(1).setNationalNumber(9002530000L);
94   // Too short, but still possible US numbers.
95   private static final PhoneNumber US_LOCAL_NUMBER =
96       new PhoneNumber().setCountryCode(1).setNationalNumber(2530000L);
97   private static final PhoneNumber US_SHORT_BY_ONE_NUMBER =
98       new PhoneNumber().setCountryCode(1).setNationalNumber(650253000L);
99   private static final PhoneNumber US_TOLLFREE =
100       new PhoneNumber().setCountryCode(1).setNationalNumber(8002530000L);
101   private static final PhoneNumber US_SPOOF =
102       new PhoneNumber().setCountryCode(1).setNationalNumber(0L);
103   private static final PhoneNumber US_SPOOF_WITH_RAW_INPUT =
104       new PhoneNumber().setCountryCode(1).setNationalNumber(0L)
105           .setRawInput("000-000-0000");
106 
107   // Class containing string constants of region codes for easier testing.
108   private static class RegionCode {
109     static final String AD = "AD";
110     static final String AO = "AO";
111     static final String AR = "AR";
112     static final String AU = "AU";
113     static final String BS = "BS";
114     static final String CS = "CS";
115     static final String DE = "DE";
116     static final String GB = "GB";
117     static final String IT = "IT";
118     static final String KR = "KR";
119     static final String MX = "MX";
120     static final String NZ = "NZ";
121     static final String PL = "PL";
122     static final String RE = "RE";
123     static final String SG = "SG";
124     static final String US = "US";
125     static final String YT = "YT";
126     // Official code for the unknown region.
127     static final String ZZ = "ZZ";
128   }
129 
PhoneNumberUtilTest()130   public PhoneNumberUtilTest() {
131     phoneUtil = initializePhoneUtilForTesting();
132   }
133 
initializePhoneUtilForTesting()134   static PhoneNumberUtil initializePhoneUtilForTesting() {
135     PhoneNumberUtil.resetInstance();
136     return PhoneNumberUtil.getInstance(
137         TEST_META_DATA_FILE_PREFIX,
138         CountryCodeToRegionCodeMapForTesting.getCountryCodeToRegionCodeMap());
139   }
140 
testGetSupportedRegions()141   public void testGetSupportedRegions() {
142     assertTrue(phoneUtil.getSupportedRegions().size() > 0);
143   }
144 
testGetInstanceLoadUSMetadata()145   public void testGetInstanceLoadUSMetadata() {
146     PhoneMetadata metadata = phoneUtil.getMetadataForRegion(RegionCode.US);
147     assertEquals("US", metadata.getId());
148     assertEquals(1, metadata.getCountryCode());
149     assertEquals("011", metadata.getInternationalPrefix());
150     assertTrue(metadata.hasNationalPrefix());
151     assertEquals(2, metadata.numberFormatSize());
152     assertEquals("(\\d{3})(\\d{3})(\\d{4})",
153                  metadata.getNumberFormat(1).getPattern());
154     assertEquals("$1 $2 $3", metadata.getNumberFormat(1).getFormat());
155     assertEquals("[13-689]\\d{9}|2[0-35-9]\\d{8}",
156                  metadata.getGeneralDesc().getNationalNumberPattern());
157     assertEquals("\\d{7}(?:\\d{3})?", metadata.getGeneralDesc().getPossibleNumberPattern());
158     assertTrue(metadata.getGeneralDesc().exactlySameAs(metadata.getFixedLine()));
159     assertEquals("\\d{10}", metadata.getTollFree().getPossibleNumberPattern());
160     assertEquals("900\\d{7}", metadata.getPremiumRate().getNationalNumberPattern());
161     // No shared-cost data is available, so it should be initialised to "NA".
162     assertEquals("NA", metadata.getSharedCost().getNationalNumberPattern());
163     assertEquals("NA", metadata.getSharedCost().getPossibleNumberPattern());
164   }
165 
testGetInstanceLoadDEMetadata()166   public void testGetInstanceLoadDEMetadata() {
167     PhoneMetadata metadata = phoneUtil.getMetadataForRegion(RegionCode.DE);
168     assertEquals("DE", metadata.getId());
169     assertEquals(49, metadata.getCountryCode());
170     assertEquals("00", metadata.getInternationalPrefix());
171     assertEquals("0", metadata.getNationalPrefix());
172     assertEquals(6, metadata.numberFormatSize());
173     assertEquals(1, metadata.getNumberFormat(5).leadingDigitsPatternSize());
174     assertEquals("900", metadata.getNumberFormat(5).getLeadingDigitsPattern(0));
175     assertEquals("(\\d{3})(\\d{3,4})(\\d{4})",
176                  metadata.getNumberFormat(5).getPattern());
177     assertEquals("$1 $2 $3", metadata.getNumberFormat(5).getFormat());
178     assertEquals("(?:[24-6]\\d{2}|3[03-9]\\d|[789](?:[1-9]\\d|0[2-9]))\\d{1,8}",
179                  metadata.getFixedLine().getNationalNumberPattern());
180     assertEquals("\\d{2,14}", metadata.getFixedLine().getPossibleNumberPattern());
181     assertEquals("30123456", metadata.getFixedLine().getExampleNumber());
182     assertEquals("\\d{10}", metadata.getTollFree().getPossibleNumberPattern());
183     assertEquals("900([135]\\d{6}|9\\d{7})", metadata.getPremiumRate().getNationalNumberPattern());
184   }
185 
testGetInstanceLoadARMetadata()186   public void testGetInstanceLoadARMetadata() {
187     PhoneMetadata metadata = phoneUtil.getMetadataForRegion(RegionCode.AR);
188     assertEquals("AR", metadata.getId());
189     assertEquals(54, metadata.getCountryCode());
190     assertEquals("00", metadata.getInternationalPrefix());
191     assertEquals("0", metadata.getNationalPrefix());
192     assertEquals("0(?:(11|343|3715)15)?", metadata.getNationalPrefixForParsing());
193     assertEquals("9$1", metadata.getNationalPrefixTransformRule());
194     assertEquals("$2 15 $3-$4", metadata.getNumberFormat(2).getFormat());
195     assertEquals("(9)(\\d{4})(\\d{2})(\\d{4})",
196                  metadata.getNumberFormat(3).getPattern());
197     assertEquals("(9)(\\d{4})(\\d{2})(\\d{4})",
198                  metadata.getIntlNumberFormat(3).getPattern());
199     assertEquals("$1 $2 $3 $4", metadata.getIntlNumberFormat(3).getFormat());
200   }
201 
testIsLeadingZeroPossible()202   public void testIsLeadingZeroPossible() {
203     assertTrue(phoneUtil.isLeadingZeroPossible(39));  // Italy
204     assertFalse(phoneUtil.isLeadingZeroPossible(1));  // USA
205     assertFalse(phoneUtil.isLeadingZeroPossible(800));  // Not in metadata file, just default to
206                                                         // false.
207   }
208 
testGetLengthOfGeographicalAreaCode()209   public void testGetLengthOfGeographicalAreaCode() {
210     // Google MTV, which has area code "650".
211     assertEquals(3, phoneUtil.getLengthOfGeographicalAreaCode(US_NUMBER));
212 
213     // A North America toll-free number, which has no area code.
214     assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(US_TOLLFREE));
215 
216     // Google London, which has area code "20".
217     assertEquals(2, phoneUtil.getLengthOfGeographicalAreaCode(GB_NUMBER));
218 
219     // A UK mobile phone, which has no area code.
220     assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(GB_MOBILE));
221 
222     // Google Buenos Aires, which has area code "11".
223     assertEquals(2, phoneUtil.getLengthOfGeographicalAreaCode(AR_NUMBER));
224 
225     // Google Sydney, which has area code "2".
226     assertEquals(1, phoneUtil.getLengthOfGeographicalAreaCode(AU_NUMBER));
227 
228     // Google Singapore. Singapore has no area code and no national prefix.
229     assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(SG_NUMBER));
230 
231     // An invalid US number (1 digit shorter), which has no area code.
232     assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(US_SHORT_BY_ONE_NUMBER));
233   }
234 
testGetLengthOfNationalDestinationCode()235   public void testGetLengthOfNationalDestinationCode() {
236     // Google MTV, which has national destination code (NDC) "650".
237     assertEquals(3, phoneUtil.getLengthOfNationalDestinationCode(US_NUMBER));
238 
239     // A North America toll-free number, which has NDC "800".
240     assertEquals(3, phoneUtil.getLengthOfNationalDestinationCode(US_TOLLFREE));
241 
242     // Google London, which has NDC "20".
243     assertEquals(2, phoneUtil.getLengthOfNationalDestinationCode(GB_NUMBER));
244 
245     // A UK mobile phone, which has NDC "7912".
246     assertEquals(4, phoneUtil.getLengthOfNationalDestinationCode(GB_MOBILE));
247 
248     // Google Buenos Aires, which has NDC "11".
249     assertEquals(2, phoneUtil.getLengthOfNationalDestinationCode(AR_NUMBER));
250 
251     // An Argentinian mobile which has NDC "911".
252     assertEquals(3, phoneUtil.getLengthOfNationalDestinationCode(AR_MOBILE));
253 
254     // Google Sydney, which has NDC "2".
255     assertEquals(1, phoneUtil.getLengthOfNationalDestinationCode(AU_NUMBER));
256 
257     // Google Singapore, which has NDC "6521".
258     assertEquals(4, phoneUtil.getLengthOfNationalDestinationCode(SG_NUMBER));
259 
260     // An invalid US number (1 digit shorter), which has no NDC.
261     assertEquals(0, phoneUtil.getLengthOfNationalDestinationCode(US_SHORT_BY_ONE_NUMBER));
262 
263     // A number containing an invalid country calling code, which shouldn't have any NDC.
264     PhoneNumber number = new PhoneNumber().setCountryCode(123).setNationalNumber(6502530000L);
265     assertEquals(0, phoneUtil.getLengthOfNationalDestinationCode(number));
266   }
267 
testGetNationalSignificantNumber()268   public void testGetNationalSignificantNumber() {
269     assertEquals("6502530000", phoneUtil.getNationalSignificantNumber(US_NUMBER));
270 
271     // An Italian mobile number.
272     assertEquals("345678901", phoneUtil.getNationalSignificantNumber(IT_MOBILE));
273 
274     // An Italian fixed line number.
275     assertEquals("0236618300", phoneUtil.getNationalSignificantNumber(IT_NUMBER));
276   }
277 
testGetExampleNumber()278   public void testGetExampleNumber() {
279     assertEquals(DE_NUMBER, phoneUtil.getExampleNumber(RegionCode.DE));
280 
281     assertEquals(DE_NUMBER,
282                  phoneUtil.getExampleNumberForType(RegionCode.DE,
283                                                    PhoneNumberUtil.PhoneNumberType.FIXED_LINE));
284     assertEquals(null,
285                  phoneUtil.getExampleNumberForType(RegionCode.DE,
286                                                    PhoneNumberUtil.PhoneNumberType.MOBILE));
287     // For the US, the example number is placed under general description, and hence should be used
288     // for both fixed line and mobile, so neither of these should return null.
289     assertNotNull(phoneUtil.getExampleNumberForType(RegionCode.US,
290                                                     PhoneNumberUtil.PhoneNumberType.FIXED_LINE));
291     assertNotNull(phoneUtil.getExampleNumberForType(RegionCode.US,
292                                                     PhoneNumberUtil.PhoneNumberType.MOBILE));
293     // CS is an invalid region, so we have no data for it.
294     assertNull(phoneUtil.getExampleNumberForType(RegionCode.CS,
295                                                  PhoneNumberUtil.PhoneNumberType.MOBILE));
296   }
297 
testConvertAlphaCharactersInNumber()298   public void testConvertAlphaCharactersInNumber() {
299     String input = "1800-ABC-DEF";
300     // Alpha chars are converted to digits; everything else is left untouched.
301     String expectedOutput = "1800-222-333";
302     assertEquals(expectedOutput, PhoneNumberUtil.convertAlphaCharactersInNumber(input));
303   }
304 
testNormaliseRemovePunctuation()305   public void testNormaliseRemovePunctuation() {
306     String inputNumber = "034-56&+#234";
307     String expectedOutput = "03456234";
308     assertEquals("Conversion did not correctly remove punctuation",
309                  expectedOutput,
310                  PhoneNumberUtil.normalize(inputNumber));
311   }
312 
testNormaliseReplaceAlphaCharacters()313   public void testNormaliseReplaceAlphaCharacters() {
314     String inputNumber = "034-I-am-HUNGRY";
315     String expectedOutput = "034426486479";
316     assertEquals("Conversion did not correctly replace alpha characters",
317                  expectedOutput,
318                  PhoneNumberUtil.normalize(inputNumber));
319   }
320 
testNormaliseOtherDigits()321   public void testNormaliseOtherDigits() {
322     String inputNumber = "\uFF125\u0665";
323     String expectedOutput = "255";
324     assertEquals("Conversion did not correctly replace non-latin digits",
325                  expectedOutput,
326                  PhoneNumberUtil.normalize(inputNumber));
327     // Eastern-Arabic digits.
328     inputNumber = "\u06F52\u06F0";
329     expectedOutput = "520";
330     assertEquals("Conversion did not correctly replace non-latin digits",
331                  expectedOutput,
332                  PhoneNumberUtil.normalize(inputNumber));
333   }
334 
testNormaliseStripAlphaCharacters()335   public void testNormaliseStripAlphaCharacters() {
336     String inputNumber = "034-56&+a#234";
337     String expectedOutput = "03456234";
338     assertEquals("Conversion did not correctly remove alpha character",
339                  expectedOutput,
340                  PhoneNumberUtil.normalizeDigitsOnly(inputNumber));
341   }
342 
testFormatUSNumber()343   public void testFormatUSNumber() {
344     assertEquals("650 253 0000", phoneUtil.format(US_NUMBER, PhoneNumberFormat.NATIONAL));
345     assertEquals("+1 650 253 0000", phoneUtil.format(US_NUMBER, PhoneNumberFormat.INTERNATIONAL));
346 
347     assertEquals("800 253 0000", phoneUtil.format(US_TOLLFREE, PhoneNumberFormat.NATIONAL));
348     assertEquals("+1 800 253 0000", phoneUtil.format(US_TOLLFREE, PhoneNumberFormat.INTERNATIONAL));
349 
350     assertEquals("900 253 0000", phoneUtil.format(US_PREMIUM, PhoneNumberFormat.NATIONAL));
351     assertEquals("+1 900 253 0000", phoneUtil.format(US_PREMIUM, PhoneNumberFormat.INTERNATIONAL));
352     assertEquals("+1-900-253-0000", phoneUtil.format(US_PREMIUM, PhoneNumberFormat.RFC3966));
353     // Numbers with all zeros in the national number part will be formatted by using the raw_input
354     // if that is available no matter which format is specified.
355     assertEquals("000-000-0000",
356                  phoneUtil.format(US_SPOOF_WITH_RAW_INPUT, PhoneNumberFormat.NATIONAL));
357     assertEquals("0", phoneUtil.format(US_SPOOF, PhoneNumberFormat.NATIONAL));
358   }
359 
testFormatBSNumber()360   public void testFormatBSNumber() {
361     assertEquals("242 365 1234", phoneUtil.format(BS_NUMBER, PhoneNumberFormat.NATIONAL));
362     assertEquals("+1 242 365 1234", phoneUtil.format(BS_NUMBER, PhoneNumberFormat.INTERNATIONAL));
363   }
364 
testFormatGBNumber()365   public void testFormatGBNumber() {
366     assertEquals("(020) 7031 3000", phoneUtil.format(GB_NUMBER, PhoneNumberFormat.NATIONAL));
367     assertEquals("+44 20 7031 3000", phoneUtil.format(GB_NUMBER, PhoneNumberFormat.INTERNATIONAL));
368 
369     assertEquals("(07912) 345 678", phoneUtil.format(GB_MOBILE, PhoneNumberFormat.NATIONAL));
370     assertEquals("+44 7912 345 678", phoneUtil.format(GB_MOBILE, PhoneNumberFormat.INTERNATIONAL));
371   }
372 
testFormatDENumber()373   public void testFormatDENumber() {
374     PhoneNumber deNumber = new PhoneNumber();
375     deNumber.setCountryCode(49).setNationalNumber(301234L);
376     assertEquals("030/1234", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
377     assertEquals("+49 30/1234", phoneUtil.format(deNumber, PhoneNumberFormat.INTERNATIONAL));
378     assertEquals("+49-30-1234", phoneUtil.format(deNumber, PhoneNumberFormat.RFC3966));
379 
380     deNumber.clear();
381     deNumber.setCountryCode(49).setNationalNumber(291123L);
382     assertEquals("0291 123", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
383     assertEquals("+49 291 123", phoneUtil.format(deNumber, PhoneNumberFormat.INTERNATIONAL));
384 
385     deNumber.clear();
386     deNumber.setCountryCode(49).setNationalNumber(29112345678L);
387     assertEquals("0291 12345678", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
388     assertEquals("+49 291 12345678", phoneUtil.format(deNumber, PhoneNumberFormat.INTERNATIONAL));
389 
390     deNumber.clear();
391     deNumber.setCountryCode(49).setNationalNumber(912312345L);
392     assertEquals("09123 12345", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
393     assertEquals("+49 9123 12345", phoneUtil.format(deNumber, PhoneNumberFormat.INTERNATIONAL));
394     deNumber.clear();
395     deNumber.setCountryCode(49).setNationalNumber(80212345L);
396     assertEquals("08021 2345", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
397     assertEquals("+49 8021 2345", phoneUtil.format(deNumber, PhoneNumberFormat.INTERNATIONAL));
398     // Note this number is correctly formatted without national prefix. Most of the numbers that
399     // are treated as invalid numbers by the library are short numbers, and they are usually not
400     // dialed with national prefix.
401     assertEquals("1234", phoneUtil.format(DE_SHORT_NUMBER, PhoneNumberFormat.NATIONAL));
402     assertEquals("+49 1234", phoneUtil.format(DE_SHORT_NUMBER, PhoneNumberFormat.INTERNATIONAL));
403 
404     deNumber.clear();
405     deNumber.setCountryCode(49).setNationalNumber(41341234);
406     assertEquals("04134 1234", phoneUtil.format(deNumber, PhoneNumberFormat.NATIONAL));
407   }
408 
testFormatITNumber()409   public void testFormatITNumber() {
410     assertEquals("02 3661 8300", phoneUtil.format(IT_NUMBER, PhoneNumberFormat.NATIONAL));
411     assertEquals("+39 02 3661 8300", phoneUtil.format(IT_NUMBER, PhoneNumberFormat.INTERNATIONAL));
412     assertEquals("+390236618300", phoneUtil.format(IT_NUMBER, PhoneNumberFormat.E164));
413 
414     assertEquals("345 678 901", phoneUtil.format(IT_MOBILE, PhoneNumberFormat.NATIONAL));
415     assertEquals("+39 345 678 901", phoneUtil.format(IT_MOBILE, PhoneNumberFormat.INTERNATIONAL));
416     assertEquals("+39345678901", phoneUtil.format(IT_MOBILE, PhoneNumberFormat.E164));
417   }
418 
testFormatAUNumber()419   public void testFormatAUNumber() {
420     assertEquals("02 3661 8300", phoneUtil.format(AU_NUMBER, PhoneNumberFormat.NATIONAL));
421     assertEquals("+61 2 3661 8300", phoneUtil.format(AU_NUMBER, PhoneNumberFormat.INTERNATIONAL));
422     assertEquals("+61236618300", phoneUtil.format(AU_NUMBER, PhoneNumberFormat.E164));
423 
424     PhoneNumber auNumber = new PhoneNumber().setCountryCode(61).setNationalNumber(1800123456L);
425     assertEquals("1800 123 456", phoneUtil.format(auNumber, PhoneNumberFormat.NATIONAL));
426     assertEquals("+61 1800 123 456", phoneUtil.format(auNumber, PhoneNumberFormat.INTERNATIONAL));
427     assertEquals("+611800123456", phoneUtil.format(auNumber, PhoneNumberFormat.E164));
428   }
429 
testFormatARNumber()430   public void testFormatARNumber() {
431     assertEquals("011 8765-4321", phoneUtil.format(AR_NUMBER, PhoneNumberFormat.NATIONAL));
432     assertEquals("+54 11 8765-4321", phoneUtil.format(AR_NUMBER, PhoneNumberFormat.INTERNATIONAL));
433     assertEquals("+541187654321", phoneUtil.format(AR_NUMBER, PhoneNumberFormat.E164));
434 
435     assertEquals("011 15 8765-4321", phoneUtil.format(AR_MOBILE, PhoneNumberFormat.NATIONAL));
436     assertEquals("+54 9 11 8765 4321", phoneUtil.format(AR_MOBILE,
437                                                         PhoneNumberFormat.INTERNATIONAL));
438     assertEquals("+5491187654321", phoneUtil.format(AR_MOBILE, PhoneNumberFormat.E164));
439   }
440 
testFormatMXNumber()441   public void testFormatMXNumber() {
442     assertEquals("045 234 567 8900", phoneUtil.format(MX_MOBILE1, PhoneNumberFormat.NATIONAL));
443     assertEquals("+52 1 234 567 8900", phoneUtil.format(
444         MX_MOBILE1, PhoneNumberFormat.INTERNATIONAL));
445     assertEquals("+5212345678900", phoneUtil.format(MX_MOBILE1, PhoneNumberFormat.E164));
446 
447     assertEquals("045 55 1234 5678", phoneUtil.format(MX_MOBILE2, PhoneNumberFormat.NATIONAL));
448     assertEquals("+52 1 55 1234 5678", phoneUtil.format(
449         MX_MOBILE2, PhoneNumberFormat.INTERNATIONAL));
450     assertEquals("+5215512345678", phoneUtil.format(MX_MOBILE2, PhoneNumberFormat.E164));
451 
452     assertEquals("01 33 1234 5678", phoneUtil.format(MX_NUMBER1, PhoneNumberFormat.NATIONAL));
453     assertEquals("+52 33 1234 5678", phoneUtil.format(MX_NUMBER1, PhoneNumberFormat.INTERNATIONAL));
454     assertEquals("+523312345678", phoneUtil.format(MX_NUMBER1, PhoneNumberFormat.E164));
455 
456     assertEquals("01 821 123 4567", phoneUtil.format(MX_NUMBER2, PhoneNumberFormat.NATIONAL));
457     assertEquals("+52 821 123 4567", phoneUtil.format(MX_NUMBER2, PhoneNumberFormat.INTERNATIONAL));
458     assertEquals("+528211234567", phoneUtil.format(MX_NUMBER2, PhoneNumberFormat.E164));
459   }
460 
testFormatOutOfCountryCallingNumber()461   public void testFormatOutOfCountryCallingNumber() {
462     assertEquals("00 1 900 253 0000",
463                  phoneUtil.formatOutOfCountryCallingNumber(US_PREMIUM, RegionCode.DE));
464 
465     assertEquals("1 650 253 0000",
466                  phoneUtil.formatOutOfCountryCallingNumber(US_NUMBER, RegionCode.BS));
467 
468     assertEquals("0~0 1 650 253 0000",
469                  phoneUtil.formatOutOfCountryCallingNumber(US_NUMBER, RegionCode.PL));
470 
471     assertEquals("011 44 7912 345 678",
472                  phoneUtil.formatOutOfCountryCallingNumber(GB_MOBILE, RegionCode.US));
473 
474     assertEquals("00 49 1234",
475                  phoneUtil.formatOutOfCountryCallingNumber(DE_SHORT_NUMBER, RegionCode.GB));
476     // Note this number is correctly formatted without national prefix. Most of the numbers that
477     // are treated as invalid numbers by the library are short numbers, and they are usually not
478     // dialed with national prefix.
479     assertEquals("1234", phoneUtil.formatOutOfCountryCallingNumber(DE_SHORT_NUMBER, RegionCode.DE));
480 
481     assertEquals("011 39 02 3661 8300",
482                  phoneUtil.formatOutOfCountryCallingNumber(IT_NUMBER, RegionCode.US));
483     assertEquals("02 3661 8300",
484                  phoneUtil.formatOutOfCountryCallingNumber(IT_NUMBER, RegionCode.IT));
485     assertEquals("+39 02 3661 8300",
486                  phoneUtil.formatOutOfCountryCallingNumber(IT_NUMBER, RegionCode.SG));
487 
488     assertEquals("6521 8000",
489                  phoneUtil.formatOutOfCountryCallingNumber(SG_NUMBER, RegionCode.SG));
490 
491     assertEquals("011 54 9 11 8765 4321",
492                  phoneUtil.formatOutOfCountryCallingNumber(AR_MOBILE, RegionCode.US));
493 
494     PhoneNumber arNumberWithExtn = new PhoneNumber().mergeFrom(AR_MOBILE).setExtension("1234");
495     assertEquals("011 54 9 11 8765 4321 ext. 1234",
496                  phoneUtil.formatOutOfCountryCallingNumber(arNumberWithExtn, RegionCode.US));
497     assertEquals("0011 54 9 11 8765 4321 ext. 1234",
498                  phoneUtil.formatOutOfCountryCallingNumber(arNumberWithExtn, RegionCode.AU));
499     assertEquals("011 15 8765-4321 ext. 1234",
500                  phoneUtil.formatOutOfCountryCallingNumber(arNumberWithExtn, RegionCode.AR));
501   }
502 
testFormatOutOfCountryWithPreferredIntlPrefix()503   public void testFormatOutOfCountryWithPreferredIntlPrefix() {
504     // This should use 0011, since that is the preferred international prefix (both 0011 and 0012
505     // are accepted as possible international prefixes in our test metadta.)
506     assertEquals("0011 39 02 3661 8300",
507                  phoneUtil.formatOutOfCountryCallingNumber(IT_NUMBER, RegionCode.AU));
508   }
509 
testFormatOutOfCountryKeepingAlphaChars()510   public void testFormatOutOfCountryKeepingAlphaChars() {
511     PhoneNumber alphaNumericNumber = new PhoneNumber();
512     alphaNumericNumber.setCountryCode(1).setNationalNumber(8007493524L)
513         .setRawInput("1800 six-flag");
514     assertEquals("0011 1 800 SIX-FLAG",
515                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));
516 
517     alphaNumericNumber.setRawInput("1-800-SIX-flag");
518     assertEquals("0011 1 800-SIX-FLAG",
519                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));
520 
521     alphaNumericNumber.setRawInput("Call us from UK: 00 1 800 SIX-flag");
522     assertEquals("0011 1 800 SIX-FLAG",
523                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));
524 
525     alphaNumericNumber.setRawInput("800 SIX-flag");
526     assertEquals("0011 1 800 SIX-FLAG",
527                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));
528 
529     // Formatting from within the NANPA region.
530     assertEquals("1 800 SIX-FLAG",
531                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.US));
532 
533     assertEquals("1 800 SIX-FLAG",
534                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.BS));
535 
536     // Testing that if the raw input doesn't exist, it is formatted using
537     // formatOutOfCountryCallingNumber.
538     alphaNumericNumber.clearRawInput();
539     assertEquals("00 1 800 749 3524",
540                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.DE));
541 
542     // Testing AU alpha number formatted from Australia.
543     alphaNumericNumber.setCountryCode(61).setNationalNumber(827493524L)
544         .setRawInput("+61 82749-FLAG");
545     // This number should have the national prefix fixed.
546     assertEquals("082749-FLAG",
547                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));
548 
549     alphaNumericNumber.setRawInput("082749-FLAG");
550     assertEquals("082749-FLAG",
551                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));
552 
553     alphaNumericNumber.setNationalNumber(18007493524L).setRawInput("1-800-SIX-flag");
554     // This number should not have the national prefix prefixed, in accordance with the override for
555     // this specific formatting rule.
556     assertEquals("1-800-SIX-FLAG",
557                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.AU));
558 
559     // The metadata should not be permanently changed, since we copied it before modifying patterns.
560     // Here we check this.
561     alphaNumericNumber.setNationalNumber(1800749352L);
562     assertEquals("1800 749 352",
563                  phoneUtil.formatOutOfCountryCallingNumber(alphaNumericNumber, RegionCode.AU));
564 
565     // Testing a region with multiple international prefixes.
566     assertEquals("+61 1-800-SIX-FLAG",
567                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.SG));
568 
569     // Testing the case with an invalid country calling code.
570     alphaNumericNumber.setCountryCode(0).setNationalNumber(18007493524L)
571         .setRawInput("1-800-SIX-flag");
572     // Uses the raw input only.
573     assertEquals("1-800-SIX-flag",
574                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.DE));
575 
576     // Testing the case of an invalid alpha number.
577     alphaNumericNumber.setCountryCode(1).setNationalNumber(80749L).setRawInput("180-SIX");
578     // No country-code stripping can be done.
579     assertEquals("00 1 180-SIX",
580                  phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber, RegionCode.DE));
581   }
582 
testFormatWithCarrierCode()583   public void testFormatWithCarrierCode() {
584     // We only support this for AR in our test metadata, and only for mobile numbers starting with
585     // certain values.
586     PhoneNumber arMobile = new PhoneNumber().setCountryCode(54).setNationalNumber(92234654321L);
587     assertEquals("02234 65-4321", phoneUtil.format(arMobile, PhoneNumberFormat.NATIONAL));
588     // Here we force 14 as the carrier code.
589     assertEquals("02234 14 65-4321",
590                  phoneUtil.formatNationalNumberWithCarrierCode(arMobile, "14"));
591     // Here we force the number to be shown with no carrier code.
592     assertEquals("02234 65-4321",
593                  phoneUtil.formatNationalNumberWithCarrierCode(arMobile, ""));
594     // Here the international rule is used, so no carrier code should be present.
595     assertEquals("+5492234654321", phoneUtil.format(arMobile, PhoneNumberFormat.E164));
596     // We don't support this for the US so there should be no change.
597     assertEquals("650 253 0000", phoneUtil.formatNationalNumberWithCarrierCode(US_NUMBER, "15"));
598   }
599 
testFormatWithPreferredCarrierCode()600   public void testFormatWithPreferredCarrierCode() {
601     // We only support this for AR in our test metadata.
602     PhoneNumber arNumber = new PhoneNumber();
603     arNumber.setCountryCode(54).setNationalNumber(91234125678L);
604     // Test formatting with no preferred carrier code stored in the number itself.
605     assertEquals("01234 15 12-5678",
606         phoneUtil.formatNationalNumberWithPreferredCarrierCode(arNumber, "15"));
607     assertEquals("01234 12-5678",
608         phoneUtil.formatNationalNumberWithPreferredCarrierCode(arNumber, ""));
609     // Test formatting with preferred carrier code present.
610     arNumber.setPreferredDomesticCarrierCode("19");
611     assertEquals("01234 12-5678", phoneUtil.format(arNumber, PhoneNumberFormat.NATIONAL));
612     assertEquals("01234 19 12-5678",
613         phoneUtil.formatNationalNumberWithPreferredCarrierCode(arNumber, "15"));
614     assertEquals("01234 19 12-5678",
615         phoneUtil.formatNationalNumberWithPreferredCarrierCode(arNumber, ""));
616     // When the preferred_domestic_carrier_code is present (even when it contains an empty string),
617     // use it instead of the default carrier code passed in.
618     arNumber.setPreferredDomesticCarrierCode("");
619     assertEquals("01234 12-5678",
620         phoneUtil.formatNationalNumberWithPreferredCarrierCode(arNumber, "15"));
621     // We don't support this for the US so there should be no change.
622     PhoneNumber usNumber = new PhoneNumber();
623     usNumber.setCountryCode(1).setNationalNumber(4241231234L).setPreferredDomesticCarrierCode("99");
624     assertEquals("424 123 1234", phoneUtil.format(usNumber, PhoneNumberFormat.NATIONAL));
625     assertEquals("424 123 1234",
626         phoneUtil.formatNationalNumberWithPreferredCarrierCode(usNumber, "15"));
627   }
628 
testFormatByPattern()629   public void testFormatByPattern() {
630     NumberFormat newNumFormat = new NumberFormat();
631     newNumFormat.setPattern("(\\d{3})(\\d{3})(\\d{4})");
632     newNumFormat.setFormat("($1) $2-$3");
633     List<NumberFormat> newNumberFormats = new ArrayList<NumberFormat>();
634     newNumberFormats.add(newNumFormat);
635 
636     assertEquals("(650) 253-0000", phoneUtil.formatByPattern(US_NUMBER, PhoneNumberFormat.NATIONAL,
637                                                              newNumberFormats));
638     assertEquals("+1 (650) 253-0000", phoneUtil.formatByPattern(US_NUMBER,
639                                                                 PhoneNumberFormat.INTERNATIONAL,
640                                                                 newNumberFormats));
641 
642     // $NP is set to '1' for the US. Here we check that for other NANPA countries the US rules are
643     // followed.
644     newNumFormat.setNationalPrefixFormattingRule("$NP ($FG)");
645     newNumFormat.setFormat("$1 $2-$3");
646     assertEquals("1 (242) 365-1234",
647                  phoneUtil.formatByPattern(BS_NUMBER, PhoneNumberFormat.NATIONAL,
648                                            newNumberFormats));
649     assertEquals("+1 242 365-1234",
650                  phoneUtil.formatByPattern(BS_NUMBER, PhoneNumberFormat.INTERNATIONAL,
651                                            newNumberFormats));
652 
653     newNumFormat.setPattern("(\\d{2})(\\d{5})(\\d{3})");
654     newNumFormat.setFormat("$1-$2 $3");
655     newNumberFormats.set(0, newNumFormat);
656 
657     assertEquals("02-36618 300",
658                  phoneUtil.formatByPattern(IT_NUMBER, PhoneNumberFormat.NATIONAL,
659                                            newNumberFormats));
660     assertEquals("+39 02-36618 300",
661                  phoneUtil.formatByPattern(IT_NUMBER, PhoneNumberFormat.INTERNATIONAL,
662                                            newNumberFormats));
663 
664     newNumFormat.setNationalPrefixFormattingRule("$NP$FG");
665     newNumFormat.setPattern("(\\d{2})(\\d{4})(\\d{4})");
666     newNumFormat.setFormat("$1 $2 $3");
667     newNumberFormats.set(0, newNumFormat);
668     assertEquals("020 7031 3000",
669                  phoneUtil.formatByPattern(GB_NUMBER, PhoneNumberFormat.NATIONAL,
670                                            newNumberFormats));
671 
672     newNumFormat.setNationalPrefixFormattingRule("($NP$FG)");
673     assertEquals("(020) 7031 3000",
674                  phoneUtil.formatByPattern(GB_NUMBER, PhoneNumberFormat.NATIONAL,
675                                            newNumberFormats));
676 
677     newNumFormat.setNationalPrefixFormattingRule("");
678     assertEquals("20 7031 3000",
679                  phoneUtil.formatByPattern(GB_NUMBER, PhoneNumberFormat.NATIONAL,
680                                            newNumberFormats));
681 
682     assertEquals("+44 20 7031 3000",
683                  phoneUtil.formatByPattern(GB_NUMBER, PhoneNumberFormat.INTERNATIONAL,
684                                            newNumberFormats));
685   }
686 
testFormatE164Number()687   public void testFormatE164Number() {
688     assertEquals("+16502530000", phoneUtil.format(US_NUMBER, PhoneNumberFormat.E164));
689     assertEquals("+4930123456", phoneUtil.format(DE_NUMBER, PhoneNumberFormat.E164));
690   }
691 
testFormatNumberWithExtension()692   public void testFormatNumberWithExtension() {
693     PhoneNumber nzNumber = new PhoneNumber().mergeFrom(NZ_NUMBER).setExtension("1234");
694     // Uses default extension prefix:
695     assertEquals("03-331 6005 ext. 1234", phoneUtil.format(nzNumber, PhoneNumberFormat.NATIONAL));
696     // Uses RFC 3966 syntax.
697     assertEquals("+64-3-331-6005;ext=1234", phoneUtil.format(nzNumber, PhoneNumberFormat.RFC3966));
698     // Extension prefix overridden in the territory information for the US:
699     PhoneNumber usNumberWithExtension = new PhoneNumber().mergeFrom(US_NUMBER).setExtension("4567");
700     assertEquals("650 253 0000 extn. 4567", phoneUtil.format(usNumberWithExtension,
701                                                              PhoneNumberFormat.NATIONAL));
702   }
703 
testFormatUsingOriginalNumberFormat()704   public void testFormatUsingOriginalNumberFormat() throws Exception {
705     PhoneNumber number1 = phoneUtil.parseAndKeepRawInput("+442087654321", RegionCode.GB);
706     assertEquals("+44 20 8765 4321", phoneUtil.formatInOriginalFormat(number1, RegionCode.GB));
707 
708     PhoneNumber number2 = phoneUtil.parseAndKeepRawInput("02087654321", RegionCode.GB);
709     assertEquals("(020) 8765 4321", phoneUtil.formatInOriginalFormat(number2, RegionCode.GB));
710 
711     PhoneNumber number3 = phoneUtil.parseAndKeepRawInput("011442087654321", RegionCode.US);
712     assertEquals("011 44 20 8765 4321", phoneUtil.formatInOriginalFormat(number3, RegionCode.US));
713 
714     PhoneNumber number4 = phoneUtil.parseAndKeepRawInput("442087654321", RegionCode.GB);
715     assertEquals("44 20 8765 4321", phoneUtil.formatInOriginalFormat(number4, RegionCode.GB));
716 
717     PhoneNumber number5 = phoneUtil.parse("+442087654321", RegionCode.GB);
718     assertEquals("(020) 8765 4321", phoneUtil.formatInOriginalFormat(number5, RegionCode.GB));
719   }
720 
testIsPremiumRate()721   public void testIsPremiumRate() {
722     assertEquals(PhoneNumberUtil.PhoneNumberType.PREMIUM_RATE, phoneUtil.getNumberType(US_PREMIUM));
723 
724     PhoneNumber premiumRateNumber = new PhoneNumber();
725     premiumRateNumber.setCountryCode(39).setNationalNumber(892123L);
726     assertEquals(PhoneNumberUtil.PhoneNumberType.PREMIUM_RATE,
727                  phoneUtil.getNumberType(premiumRateNumber));
728 
729     premiumRateNumber.clear();
730     premiumRateNumber.setCountryCode(44).setNationalNumber(9187654321L);
731     assertEquals(PhoneNumberUtil.PhoneNumberType.PREMIUM_RATE,
732                  phoneUtil.getNumberType(premiumRateNumber));
733 
734     premiumRateNumber.clear();
735     premiumRateNumber.setCountryCode(49).setNationalNumber(9001654321L);
736     assertEquals(PhoneNumberUtil.PhoneNumberType.PREMIUM_RATE,
737                  phoneUtil.getNumberType(premiumRateNumber));
738 
739     premiumRateNumber.clear();
740     premiumRateNumber.setCountryCode(49).setNationalNumber(90091234567L);
741     assertEquals(PhoneNumberUtil.PhoneNumberType.PREMIUM_RATE,
742                  phoneUtil.getNumberType(premiumRateNumber));
743   }
744 
testIsTollFree()745   public void testIsTollFree() {
746     PhoneNumber tollFreeNumber = new PhoneNumber();
747 
748     tollFreeNumber.setCountryCode(1).setNationalNumber(8881234567L);
749     assertEquals(PhoneNumberUtil.PhoneNumberType.TOLL_FREE,
750                  phoneUtil.getNumberType(tollFreeNumber));
751 
752     tollFreeNumber.clear();
753     tollFreeNumber.setCountryCode(39).setNationalNumber(803123L);
754     assertEquals(PhoneNumberUtil.PhoneNumberType.TOLL_FREE,
755                  phoneUtil.getNumberType(tollFreeNumber));
756 
757     tollFreeNumber.clear();
758     tollFreeNumber.setCountryCode(44).setNationalNumber(8012345678L);
759     assertEquals(PhoneNumberUtil.PhoneNumberType.TOLL_FREE,
760                  phoneUtil.getNumberType(tollFreeNumber));
761 
762     tollFreeNumber.clear();
763     tollFreeNumber.setCountryCode(49).setNationalNumber(8001234567L);
764     assertEquals(PhoneNumberUtil.PhoneNumberType.TOLL_FREE,
765                  phoneUtil.getNumberType(tollFreeNumber));
766   }
767 
testIsMobile()768   public void testIsMobile() {
769     assertEquals(PhoneNumberUtil.PhoneNumberType.MOBILE, phoneUtil.getNumberType(BS_MOBILE));
770     assertEquals(PhoneNumberUtil.PhoneNumberType.MOBILE, phoneUtil.getNumberType(GB_MOBILE));
771     assertEquals(PhoneNumberUtil.PhoneNumberType.MOBILE, phoneUtil.getNumberType(IT_MOBILE));
772     assertEquals(PhoneNumberUtil.PhoneNumberType.MOBILE, phoneUtil.getNumberType(AR_MOBILE));
773 
774     PhoneNumber mobileNumber = new PhoneNumber();
775     mobileNumber.setCountryCode(49).setNationalNumber(15123456789L);
776     assertEquals(PhoneNumberUtil.PhoneNumberType.MOBILE, phoneUtil.getNumberType(mobileNumber));
777   }
778 
testIsFixedLine()779   public void testIsFixedLine() {
780     assertEquals(PhoneNumberUtil.PhoneNumberType.FIXED_LINE, phoneUtil.getNumberType(BS_NUMBER));
781     assertEquals(PhoneNumberUtil.PhoneNumberType.FIXED_LINE, phoneUtil.getNumberType(IT_NUMBER));
782     assertEquals(PhoneNumberUtil.PhoneNumberType.FIXED_LINE, phoneUtil.getNumberType(GB_NUMBER));
783     assertEquals(PhoneNumberUtil.PhoneNumberType.FIXED_LINE, phoneUtil.getNumberType(DE_NUMBER));
784   }
785 
testIsFixedLineAndMobile()786   public void testIsFixedLineAndMobile() {
787     assertEquals(PhoneNumberUtil.PhoneNumberType.FIXED_LINE_OR_MOBILE,
788                  phoneUtil.getNumberType(US_NUMBER));
789 
790     PhoneNumber fixedLineAndMobileNumber = new PhoneNumber().
791         setCountryCode(54).setNationalNumber(1987654321L);
792     assertEquals(PhoneNumberUtil.PhoneNumberType.FIXED_LINE_OR_MOBILE,
793                  phoneUtil.getNumberType(fixedLineAndMobileNumber));
794   }
795 
testIsSharedCost()796   public void testIsSharedCost() {
797     PhoneNumber gbNumber = new PhoneNumber();
798     gbNumber.setCountryCode(44).setNationalNumber(8431231234L);
799     assertEquals(PhoneNumberUtil.PhoneNumberType.SHARED_COST, phoneUtil.getNumberType(gbNumber));
800   }
801 
testIsVoip()802   public void testIsVoip() {
803     PhoneNumber gbNumber = new PhoneNumber();
804     gbNumber.setCountryCode(44).setNationalNumber(5631231234L);
805     assertEquals(PhoneNumberUtil.PhoneNumberType.VOIP, phoneUtil.getNumberType(gbNumber));
806   }
807 
testIsPersonalNumber()808   public void testIsPersonalNumber() {
809     PhoneNumber gbNumber = new PhoneNumber();
810     gbNumber.setCountryCode(44).setNationalNumber(7031231234L);
811     assertEquals(PhoneNumberUtil.PhoneNumberType.PERSONAL_NUMBER,
812                  phoneUtil.getNumberType(gbNumber));
813   }
814 
testIsUnknown()815   public void testIsUnknown() {
816     // Invalid numbers should be of type UNKNOWN.
817     assertEquals(PhoneNumberUtil.PhoneNumberType.UNKNOWN, phoneUtil.getNumberType(US_LOCAL_NUMBER));
818   }
819 
testIsValidNumber()820   public void testIsValidNumber() {
821     assertTrue(phoneUtil.isValidNumber(US_NUMBER));
822     assertTrue(phoneUtil.isValidNumber(IT_NUMBER));
823     assertTrue(phoneUtil.isValidNumber(GB_MOBILE));
824 
825     PhoneNumber nzNumber = new PhoneNumber().setCountryCode(64).setNationalNumber(21387835L);
826     assertTrue(phoneUtil.isValidNumber(nzNumber));
827   }
828 
testIsValidForRegion()829   public void testIsValidForRegion() {
830     // This number is valid for the Bahamas, but is not a valid US number.
831     assertTrue(phoneUtil.isValidNumber(BS_NUMBER));
832     assertTrue(phoneUtil.isValidNumberForRegion(BS_NUMBER, RegionCode.BS));
833     assertFalse(phoneUtil.isValidNumberForRegion(BS_NUMBER, RegionCode.US));
834     PhoneNumber bsInvalidNumber =
835         new PhoneNumber().setCountryCode(1).setNationalNumber(2421232345L);
836     // This number is no longer valid.
837     assertFalse(phoneUtil.isValidNumber(bsInvalidNumber));
838 
839     // La Mayotte and Reunion use 'leadingDigits' to differentiate them.
840     PhoneNumber reNumber = new PhoneNumber();
841     reNumber.setCountryCode(262).setNationalNumber(262123456L);
842     assertTrue(phoneUtil.isValidNumber(reNumber));
843     assertTrue(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.RE));
844     assertFalse(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.YT));
845     // Now change the number to be a number for La Mayotte.
846     reNumber.setNationalNumber(269601234L);
847     assertTrue(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.YT));
848     assertFalse(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.RE));
849     // This number is no longer valid for La Reunion.
850     reNumber.setNationalNumber(269123456L);
851     assertFalse(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.YT));
852     assertFalse(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.RE));
853     assertFalse(phoneUtil.isValidNumber(reNumber));
854     // However, it should be recognised as from La Mayotte, since it is valid for this region.
855     assertEquals(RegionCode.YT, phoneUtil.getRegionCodeForNumber(reNumber));
856     // This number is valid in both places.
857     reNumber.setNationalNumber(800123456L);
858     assertTrue(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.YT));
859     assertTrue(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.RE));
860   }
861 
testIsNotValidNumber()862   public void testIsNotValidNumber() {
863     assertFalse(phoneUtil.isValidNumber(US_LOCAL_NUMBER));
864 
865     PhoneNumber invalidNumber = new PhoneNumber();
866     invalidNumber.setCountryCode(39).setNationalNumber(23661830000L).setItalianLeadingZero(true);
867     assertFalse(phoneUtil.isValidNumber(invalidNumber));
868 
869     invalidNumber.clear();
870     invalidNumber.setCountryCode(44).setNationalNumber(791234567L);
871     assertFalse(phoneUtil.isValidNumber(invalidNumber));
872 
873     invalidNumber.clear();
874     invalidNumber.setCountryCode(49).setNationalNumber(1234L);
875     assertFalse(phoneUtil.isValidNumber(invalidNumber));
876 
877     invalidNumber.clear();
878     invalidNumber.setCountryCode(64).setNationalNumber(3316005L);
879     assertFalse(phoneUtil.isValidNumber(invalidNumber));
880   }
881 
testGetRegionCodeForCountryCode()882   public void testGetRegionCodeForCountryCode() {
883     assertEquals(RegionCode.US, phoneUtil.getRegionCodeForCountryCode(1));
884     assertEquals(RegionCode.GB, phoneUtil.getRegionCodeForCountryCode(44));
885     assertEquals(RegionCode.DE, phoneUtil.getRegionCodeForCountryCode(49));
886   }
887 
testGetRegionCodeForNumber()888   public void testGetRegionCodeForNumber() {
889     assertEquals(RegionCode.BS, phoneUtil.getRegionCodeForNumber(BS_NUMBER));
890     assertEquals(RegionCode.US, phoneUtil.getRegionCodeForNumber(US_NUMBER));
891     assertEquals(RegionCode.GB, phoneUtil.getRegionCodeForNumber(GB_MOBILE));
892   }
893 
testGetCountryCodeForRegion()894   public void testGetCountryCodeForRegion() {
895     assertEquals(1, phoneUtil.getCountryCodeForRegion(RegionCode.US));
896     assertEquals(64, phoneUtil.getCountryCodeForRegion(RegionCode.NZ));
897     assertEquals(0, phoneUtil.getCountryCodeForRegion(null));
898     assertEquals(0, phoneUtil.getCountryCodeForRegion(RegionCode.ZZ));
899     // CS is already deprecated so the library doesn't support it.
900     assertEquals(0, phoneUtil.getCountryCodeForRegion(RegionCode.CS));
901   }
902 
testGetNationalDiallingPrefixForRegion()903   public void testGetNationalDiallingPrefixForRegion() {
904     assertEquals("1", phoneUtil.getNddPrefixForRegion(RegionCode.US, false));
905     // Test non-main country to see it gets the national dialling prefix for the main country with
906     // that country calling code.
907     assertEquals("1", phoneUtil.getNddPrefixForRegion(RegionCode.BS, false));
908     assertEquals("0", phoneUtil.getNddPrefixForRegion(RegionCode.NZ, false));
909     // Test case with non digit in the national prefix.
910     assertEquals("0~0", phoneUtil.getNddPrefixForRegion(RegionCode.AO, false));
911     assertEquals("00", phoneUtil.getNddPrefixForRegion(RegionCode.AO, true));
912     // Test cases with invalid regions.
913     assertEquals(null, phoneUtil.getNddPrefixForRegion(null, false));
914     assertEquals(null, phoneUtil.getNddPrefixForRegion(RegionCode.ZZ, false));
915     // CS is already deprecated so the library doesn't support it.
916     assertEquals(null, phoneUtil.getNddPrefixForRegion(RegionCode.CS, false));
917   }
918 
testIsNANPACountry()919   public void testIsNANPACountry() {
920     assertTrue(phoneUtil.isNANPACountry(RegionCode.US));
921     assertTrue(phoneUtil.isNANPACountry(RegionCode.BS));
922     assertFalse(phoneUtil.isNANPACountry(RegionCode.DE));
923     assertFalse(phoneUtil.isNANPACountry(RegionCode.ZZ));
924     assertFalse(phoneUtil.isNANPACountry(null));
925   }
926 
testIsPossibleNumber()927   public void testIsPossibleNumber() {
928     assertTrue(phoneUtil.isPossibleNumber(US_NUMBER));
929     assertTrue(phoneUtil.isPossibleNumber(US_LOCAL_NUMBER));
930     assertTrue(phoneUtil.isPossibleNumber(GB_NUMBER));
931 
932     assertTrue(phoneUtil.isPossibleNumber("+1 650 253 0000", RegionCode.US));
933     assertTrue(phoneUtil.isPossibleNumber("+1 650 GOO OGLE", RegionCode.US));
934     assertTrue(phoneUtil.isPossibleNumber("(650) 253-0000", RegionCode.US));
935     assertTrue(phoneUtil.isPossibleNumber("253-0000", RegionCode.US));
936     assertTrue(phoneUtil.isPossibleNumber("+1 650 253 0000", RegionCode.GB));
937     assertTrue(phoneUtil.isPossibleNumber("+44 20 7031 3000", RegionCode.GB));
938     assertTrue(phoneUtil.isPossibleNumber("(020) 7031 3000", RegionCode.GB));
939     assertTrue(phoneUtil.isPossibleNumber("7031 3000", RegionCode.GB));
940     assertTrue(phoneUtil.isPossibleNumber("3331 6005", RegionCode.NZ));
941   }
942 
testIsPossibleNumberWithReason()943   public void testIsPossibleNumberWithReason() {
944     // National numbers for country calling code +1 that are within 7 to 10 digits are possible.
945     assertEquals(PhoneNumberUtil.ValidationResult.IS_POSSIBLE,
946                  phoneUtil.isPossibleNumberWithReason(US_NUMBER));
947 
948     assertEquals(PhoneNumberUtil.ValidationResult.IS_POSSIBLE,
949                  phoneUtil.isPossibleNumberWithReason(US_LOCAL_NUMBER));
950 
951     assertEquals(PhoneNumberUtil.ValidationResult.TOO_LONG,
952                  phoneUtil.isPossibleNumberWithReason(US_LONG_NUMBER));
953 
954     PhoneNumber number = new PhoneNumber();
955     number.setCountryCode(0).setNationalNumber(2530000L);
956     assertEquals(PhoneNumberUtil.ValidationResult.INVALID_COUNTRY_CODE,
957                  phoneUtil.isPossibleNumberWithReason(number));
958 
959     number.clear();
960     number.setCountryCode(1).setNationalNumber(253000L);
961     assertEquals(PhoneNumberUtil.ValidationResult.TOO_SHORT,
962                  phoneUtil.isPossibleNumberWithReason(number));
963 
964     number.clear();
965     number.setCountryCode(65).setNationalNumber(1234567890L);
966     assertEquals(PhoneNumberUtil.ValidationResult.IS_POSSIBLE,
967                  phoneUtil.isPossibleNumberWithReason(number));
968 
969     // Try with number that we don't have metadata for.
970     PhoneNumber adNumber = new PhoneNumber();
971     adNumber.setCountryCode(376).setNationalNumber(12345L);
972     assertEquals(PhoneNumberUtil.ValidationResult.IS_POSSIBLE,
973                  phoneUtil.isPossibleNumberWithReason(adNumber));
974     adNumber.setCountryCode(376).setNationalNumber(13L);
975     assertEquals(PhoneNumberUtil.ValidationResult.TOO_SHORT,
976                  phoneUtil.isPossibleNumberWithReason(adNumber));
977     adNumber.setCountryCode(376).setNationalNumber(1234567890123456L);
978     assertEquals(PhoneNumberUtil.ValidationResult.TOO_LONG,
979                  phoneUtil.isPossibleNumberWithReason(adNumber));
980   }
981 
testIsNotPossibleNumber()982   public void testIsNotPossibleNumber() {
983     assertFalse(phoneUtil.isPossibleNumber(US_LONG_NUMBER));
984 
985     PhoneNumber number = new PhoneNumber();
986     number.setCountryCode(1).setNationalNumber(253000L);
987     assertFalse(phoneUtil.isPossibleNumber(number));
988 
989     number.clear();
990     number.setCountryCode(44).setNationalNumber(300L);
991     assertFalse(phoneUtil.isPossibleNumber(number));
992 
993     assertFalse(phoneUtil.isPossibleNumber("+1 650 253 00000", RegionCode.US));
994     assertFalse(phoneUtil.isPossibleNumber("(650) 253-00000", RegionCode.US));
995     assertFalse(phoneUtil.isPossibleNumber("I want a Pizza", RegionCode.US));
996     assertFalse(phoneUtil.isPossibleNumber("253-000", RegionCode.US));
997     assertFalse(phoneUtil.isPossibleNumber("1 3000", RegionCode.GB));
998     assertFalse(phoneUtil.isPossibleNumber("+44 300", RegionCode.GB));
999   }
1000 
testTruncateTooLongNumber()1001   public void testTruncateTooLongNumber() {
1002     // US number 650-253-0000, but entered with one additional digit at the end.
1003     assertTrue(phoneUtil.truncateTooLongNumber(US_LONG_NUMBER));
1004     assertEquals(US_NUMBER, US_LONG_NUMBER);
1005 
1006     // GB number 080 1234 5678, but entered with 4 extra digits at the end.
1007     PhoneNumber tooLongNumber = new PhoneNumber();
1008     tooLongNumber.setCountryCode(44).setNationalNumber(80123456780123L);
1009     PhoneNumber validNumber = new PhoneNumber();
1010     validNumber.setCountryCode(44).setNationalNumber(8012345678L);
1011     assertTrue(phoneUtil.truncateTooLongNumber(tooLongNumber));
1012     assertEquals(validNumber, tooLongNumber);
1013 
1014     // IT number 022 3456 7890, but entered with 3 extra digits at the end.
1015     tooLongNumber.clear();
1016     tooLongNumber.setCountryCode(39).setNationalNumber(2234567890123L).setItalianLeadingZero(true);
1017     validNumber.clear();
1018     validNumber.setCountryCode(39).setNationalNumber(2234567890L).setItalianLeadingZero(true);
1019     assertTrue(phoneUtil.truncateTooLongNumber(tooLongNumber));
1020     assertEquals(validNumber, tooLongNumber);
1021 
1022     // Tests what happens when a valid number is passed in.
1023     PhoneNumber validNumberCopy = new PhoneNumber().mergeFrom(validNumber);
1024     assertTrue(phoneUtil.truncateTooLongNumber(validNumber));
1025     // Tests the number is not modified.
1026     assertEquals(validNumberCopy, validNumber);
1027 
1028     // Tests what happens when a number with invalid prefix is passed in.
1029     PhoneNumber numberWithInvalidPrefix = new PhoneNumber();
1030     // The test metadata says US numbers cannot have prefix 240.
1031     numberWithInvalidPrefix.setCountryCode(1).setNationalNumber(2401234567L);
1032     PhoneNumber invalidNumberCopy = new PhoneNumber().mergeFrom(numberWithInvalidPrefix);
1033     assertFalse(phoneUtil.truncateTooLongNumber(numberWithInvalidPrefix));
1034     // Tests the number is not modified.
1035     assertEquals(invalidNumberCopy, numberWithInvalidPrefix);
1036 
1037     // Tests what happens when a too short number is passed in.
1038     PhoneNumber tooShortNumber = new PhoneNumber().setCountryCode(1).setNationalNumber(1234L);
1039     PhoneNumber tooShortNumberCopy = new PhoneNumber().mergeFrom(tooShortNumber);
1040     assertFalse(phoneUtil.truncateTooLongNumber(tooShortNumber));
1041     // Tests the number is not modified.
1042     assertEquals(tooShortNumberCopy, tooShortNumber);
1043   }
1044 
testIsViablePhoneNumber()1045   public void testIsViablePhoneNumber() {
1046     // Only one or two digits before strange non-possible punctuation.
1047     assertFalse(PhoneNumberUtil.isViablePhoneNumber("12. March"));
1048     assertFalse(PhoneNumberUtil.isViablePhoneNumber("1+1+1"));
1049     assertFalse(PhoneNumberUtil.isViablePhoneNumber("80+0"));
1050     assertFalse(PhoneNumberUtil.isViablePhoneNumber("00"));
1051     // Three digits is viable.
1052     assertTrue(PhoneNumberUtil.isViablePhoneNumber("111"));
1053     // Alpha numbers.
1054     assertTrue(PhoneNumberUtil.isViablePhoneNumber("0800-4-pizza"));
1055     assertTrue(PhoneNumberUtil.isViablePhoneNumber("0800-4-PIZZA"));
1056   }
1057 
testIsViablePhoneNumberNonAscii()1058   public void testIsViablePhoneNumberNonAscii() {
1059     // Only one or two digits before possible punctuation followed by more digits.
1060     assertTrue(PhoneNumberUtil.isViablePhoneNumber("1\u300034"));
1061     assertFalse(PhoneNumberUtil.isViablePhoneNumber("1\u30003+4"));
1062     // Unicode variants of possible starting character and other allowed punctuation/digits.
1063     assertTrue(PhoneNumberUtil.isViablePhoneNumber("\uFF081\uFF09\u30003456789"));
1064     // Testing a leading + is okay.
1065     assertTrue(PhoneNumberUtil.isViablePhoneNumber("+1\uFF09\u30003456789"));
1066   }
1067 
testExtractPossibleNumber()1068   public void testExtractPossibleNumber() {
1069     // Removes preceding funky punctuation and letters but leaves the rest untouched.
1070     assertEquals("0800-345-600", PhoneNumberUtil.extractPossibleNumber("Tel:0800-345-600"));
1071     assertEquals("0800 FOR PIZZA", PhoneNumberUtil.extractPossibleNumber("Tel:0800 FOR PIZZA"));
1072     // Should not remove plus sign
1073     assertEquals("+800-345-600", PhoneNumberUtil.extractPossibleNumber("Tel:+800-345-600"));
1074     // Should recognise wide digits as possible start values.
1075     assertEquals("\uFF10\uFF12\uFF13",
1076                  PhoneNumberUtil.extractPossibleNumber("\uFF10\uFF12\uFF13"));
1077     // Dashes are not possible start values and should be removed.
1078     assertEquals("\uFF11\uFF12\uFF13",
1079                  PhoneNumberUtil.extractPossibleNumber("Num-\uFF11\uFF12\uFF13"));
1080     // If not possible number present, return empty string.
1081     assertEquals("", PhoneNumberUtil.extractPossibleNumber("Num-...."));
1082     // Leading brackets are stripped - these are not used when parsing.
1083     assertEquals("650) 253-0000", PhoneNumberUtil.extractPossibleNumber("(650) 253-0000"));
1084 
1085     // Trailing non-alpha-numeric characters should be removed.
1086     assertEquals("650) 253-0000", PhoneNumberUtil.extractPossibleNumber("(650) 253-0000..- .."));
1087     assertEquals("650) 253-0000", PhoneNumberUtil.extractPossibleNumber("(650) 253-0000."));
1088     // This case has a trailing RTL char.
1089     assertEquals("650) 253-0000", PhoneNumberUtil.extractPossibleNumber("(650) 253-0000\u200F"));
1090   }
1091 
testMaybeStripNationalPrefix()1092   public void testMaybeStripNationalPrefix() {
1093     PhoneMetadata metadata = new PhoneMetadata();
1094     metadata.setNationalPrefixForParsing("34");
1095     metadata.setGeneralDesc(new PhoneNumberDesc().setNationalNumberPattern("\\d{4,8}"));
1096     StringBuilder numberToStrip = new StringBuilder("34356778");
1097     String strippedNumber = "356778";
1098     phoneUtil.maybeStripNationalPrefixAndCarrierCode(numberToStrip, metadata);
1099     assertEquals("Should have had national prefix stripped.",
1100                  strippedNumber, numberToStrip.toString());
1101     // Retry stripping - now the number should not start with the national prefix, so no more
1102     // stripping should occur.
1103     phoneUtil.maybeStripNationalPrefixAndCarrierCode(numberToStrip, metadata);
1104     assertEquals("Should have had no change - no national prefix present.",
1105                  strippedNumber, numberToStrip.toString());
1106     // Some countries have no national prefix. Repeat test with none specified.
1107     metadata.setNationalPrefixForParsing("");
1108     phoneUtil.maybeStripNationalPrefixAndCarrierCode(numberToStrip, metadata);
1109     assertEquals("Should not strip anything with empty national prefix.",
1110                  strippedNumber, numberToStrip.toString());
1111     // If the resultant number doesn't match the national rule, it shouldn't be stripped.
1112     metadata.setNationalPrefixForParsing("3");
1113     numberToStrip = new StringBuilder("3123");
1114     strippedNumber = "3123";
1115     phoneUtil.maybeStripNationalPrefixAndCarrierCode(numberToStrip, metadata);
1116     assertEquals("Should have had no change - after stripping, it wouldn't have matched " +
1117                  "the national rule.",
1118                  strippedNumber, numberToStrip.toString());
1119     // Test extracting carrier selection code.
1120     metadata.setNationalPrefixForParsing("0(81)?");
1121     numberToStrip = new StringBuilder("08122123456");
1122     strippedNumber = "22123456";
1123     assertEquals("81", phoneUtil.maybeStripNationalPrefixAndCarrierCode(numberToStrip, metadata));
1124     assertEquals("Should have had national prefix and carrier code stripped.",
1125                  strippedNumber, numberToStrip.toString());
1126     // If there was a transform rule, check it was applied.
1127     metadata.setNationalPrefixTransformRule("5$15");
1128     // Note that a capturing group is present here.
1129     metadata.setNationalPrefixForParsing("0(\\d{2})");
1130     numberToStrip = new StringBuilder("031123");
1131     String transformedNumber = "5315123";
1132     phoneUtil.maybeStripNationalPrefixAndCarrierCode(numberToStrip, metadata);
1133     assertEquals("Should transform the 031 to a 5315.",
1134                  transformedNumber, numberToStrip.toString());
1135   }
1136 
testMaybeStripInternationalPrefix()1137   public void testMaybeStripInternationalPrefix() {
1138     String internationalPrefix = "00[39]";
1139     StringBuilder numberToStrip = new StringBuilder("0034567700-3898003");
1140     // Note the dash is removed as part of the normalization.
1141     StringBuilder strippedNumber = new StringBuilder("45677003898003");
1142     assertEquals(CountryCodeSource.FROM_NUMBER_WITH_IDD,
1143                  phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
1144                                                                      internationalPrefix));
1145     assertEquals("The number supplied was not stripped of its international prefix.",
1146                  strippedNumber.toString(), numberToStrip.toString());
1147     // Now the number no longer starts with an IDD prefix, so it should now report
1148     // FROM_DEFAULT_COUNTRY.
1149     assertEquals(CountryCodeSource.FROM_DEFAULT_COUNTRY,
1150                  phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
1151                                                                      internationalPrefix));
1152 
1153     numberToStrip = new StringBuilder("00945677003898003");
1154     assertEquals(CountryCodeSource.FROM_NUMBER_WITH_IDD,
1155                  phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
1156                                                                      internationalPrefix));
1157     assertEquals("The number supplied was not stripped of its international prefix.",
1158                  strippedNumber.toString(), numberToStrip.toString());
1159     // Test it works when the international prefix is broken up by spaces.
1160     numberToStrip = new StringBuilder("00 9 45677003898003");
1161     assertEquals(CountryCodeSource.FROM_NUMBER_WITH_IDD,
1162                  phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
1163                                                                      internationalPrefix));
1164     assertEquals("The number supplied was not stripped of its international prefix.",
1165                  strippedNumber.toString(), numberToStrip.toString());
1166     // Now the number no longer starts with an IDD prefix, so it should now report
1167     // FROM_DEFAULT_COUNTRY.
1168     assertEquals(CountryCodeSource.FROM_DEFAULT_COUNTRY,
1169                  phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
1170                                                                      internationalPrefix));
1171 
1172     // Test the + symbol is also recognised and stripped.
1173     numberToStrip = new StringBuilder("+45677003898003");
1174     strippedNumber = new StringBuilder("45677003898003");
1175     assertEquals(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN,
1176                  phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
1177                                                                      internationalPrefix));
1178     assertEquals("The number supplied was not stripped of the plus symbol.",
1179                  strippedNumber.toString(), numberToStrip.toString());
1180 
1181     // If the number afterwards is a zero, we should not strip this - no country calling code begins
1182     // with 0.
1183     numberToStrip = new StringBuilder("0090112-3123");
1184     strippedNumber = new StringBuilder("00901123123");
1185     assertEquals(CountryCodeSource.FROM_DEFAULT_COUNTRY,
1186                  phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
1187                                                                      internationalPrefix));
1188     assertEquals("The number supplied had a 0 after the match so shouldn't be stripped.",
1189                  strippedNumber.toString(), numberToStrip.toString());
1190     // Here the 0 is separated by a space from the IDD.
1191     numberToStrip = new StringBuilder("009 0-112-3123");
1192     assertEquals(CountryCodeSource.FROM_DEFAULT_COUNTRY,
1193                  phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
1194                                                                      internationalPrefix));
1195   }
1196 
testMaybeExtractCountryCode()1197   public void testMaybeExtractCountryCode() {
1198     PhoneNumber number = new PhoneNumber();
1199     PhoneMetadata metadata = phoneUtil.getMetadataForRegion(RegionCode.US);
1200     // Note that for the US, the IDD is 011.
1201     try {
1202       String phoneNumber = "011112-3456789";
1203       String strippedNumber = "123456789";
1204       int countryCallingCode = 1;
1205       StringBuilder numberToFill = new StringBuilder();
1206       assertEquals("Did not extract country calling code " + countryCallingCode + " correctly.",
1207                    countryCallingCode,
1208                    phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true,
1209                                                      number));
1210       assertEquals("Did not figure out CountryCodeSource correctly",
1211                    CountryCodeSource.FROM_NUMBER_WITH_IDD, number.getCountryCodeSource());
1212       // Should strip and normalize national significant number.
1213       assertEquals("Did not strip off the country calling code correctly.",
1214                    strippedNumber,
1215                    numberToFill.toString());
1216     } catch (NumberParseException e) {
1217       fail("Should not have thrown an exception: " + e.toString());
1218     }
1219     number.clear();
1220     try {
1221       String phoneNumber = "+6423456789";
1222       int countryCallingCode = 64;
1223       StringBuilder numberToFill = new StringBuilder();
1224       assertEquals("Did not extract country calling code " + countryCallingCode + " correctly.",
1225                    countryCallingCode,
1226                    phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true,
1227                                                      number));
1228       assertEquals("Did not figure out CountryCodeSource correctly",
1229                    CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN, number.getCountryCodeSource());
1230     } catch (NumberParseException e) {
1231       fail("Should not have thrown an exception: " + e.toString());
1232     }
1233     number.clear();
1234     try {
1235       String phoneNumber = "2345-6789";
1236       StringBuilder numberToFill = new StringBuilder();
1237       assertEquals(
1238           "Should not have extracted a country calling code - no international prefix present.",
1239           0,
1240           phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true, number));
1241       assertEquals("Did not figure out CountryCodeSource correctly",
1242                    CountryCodeSource.FROM_DEFAULT_COUNTRY, number.getCountryCodeSource());
1243     } catch (NumberParseException e) {
1244       fail("Should not have thrown an exception: " + e.toString());
1245     }
1246     number.clear();
1247     try {
1248       String phoneNumber = "0119991123456789";
1249       StringBuilder numberToFill = new StringBuilder();
1250       phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true, number);
1251       fail("Should have thrown an exception, no valid country calling code present.");
1252     } catch (NumberParseException e) {
1253       // Expected.
1254       assertEquals("Wrong error type stored in exception.",
1255                    NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
1256                    e.getErrorType());
1257     }
1258     number.clear();
1259     try {
1260       String phoneNumber = "(1 610) 619 4466";
1261       int countryCallingCode = 1;
1262       StringBuilder numberToFill = new StringBuilder();
1263       assertEquals("Should have extracted the country calling code of the region passed in",
1264                    countryCallingCode,
1265                    phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true,
1266                                                      number));
1267       assertEquals("Did not figure out CountryCodeSource correctly",
1268                    CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN,
1269                    number.getCountryCodeSource());
1270     } catch (NumberParseException e) {
1271       fail("Should not have thrown an exception: " + e.toString());
1272     }
1273     number.clear();
1274     try {
1275       String phoneNumber = "(1 610) 619 4466";
1276       int countryCallingCode = 1;
1277       StringBuilder numberToFill = new StringBuilder();
1278       assertEquals("Should have extracted the country calling code of the region passed in",
1279                    countryCallingCode,
1280                    phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, false,
1281                                                      number));
1282       assertFalse("Should not contain CountryCodeSource.", number.hasCountryCodeSource());
1283     } catch (NumberParseException e) {
1284       fail("Should not have thrown an exception: " + e.toString());
1285     }
1286     number.clear();
1287     try {
1288       String phoneNumber = "(1 610) 619 446";
1289       StringBuilder numberToFill = new StringBuilder();
1290       assertEquals("Should not have extracted a country calling code - invalid number after " +
1291                    "extraction of uncertain country calling code.",
1292                    0,
1293                    phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, false,
1294                                                      number));
1295       assertFalse("Should not contain CountryCodeSource.", number.hasCountryCodeSource());
1296     } catch (NumberParseException e) {
1297       fail("Should not have thrown an exception: " + e.toString());
1298     }
1299     number.clear();
1300     try {
1301       String phoneNumber = "(1 610) 619";
1302       StringBuilder numberToFill = new StringBuilder();
1303       assertEquals("Should not have extracted a country calling code - too short number both " +
1304                    "before and after extraction of uncertain country calling code.",
1305                    0,
1306                    phoneUtil.maybeExtractCountryCode(phoneNumber, metadata, numberToFill, true,
1307                                                      number));
1308       assertEquals("Did not figure out CountryCodeSource correctly",
1309                    CountryCodeSource.FROM_DEFAULT_COUNTRY, number.getCountryCodeSource());
1310     } catch (NumberParseException e) {
1311       fail("Should not have thrown an exception: " + e.toString());
1312     }
1313   }
1314 
testParseNationalNumber()1315   public void testParseNationalNumber() throws Exception {
1316     // National prefix attached.
1317     assertEquals(NZ_NUMBER, phoneUtil.parse("033316005", RegionCode.NZ));
1318     assertEquals(NZ_NUMBER, phoneUtil.parse("33316005", RegionCode.NZ));
1319     // National prefix attached and some formatting present.
1320     assertEquals(NZ_NUMBER, phoneUtil.parse("03-331 6005", RegionCode.NZ));
1321     assertEquals(NZ_NUMBER, phoneUtil.parse("03 331 6005", RegionCode.NZ));
1322 
1323     // Testing international prefixes.
1324     // Should strip country calling code.
1325     assertEquals(NZ_NUMBER, phoneUtil.parse("0064 3 331 6005", RegionCode.NZ));
1326     // Try again, but this time we have an international number with Region Code US. It should
1327     // recognise the country calling code and parse accordingly.
1328     assertEquals(NZ_NUMBER, phoneUtil.parse("01164 3 331 6005", RegionCode.US));
1329     assertEquals(NZ_NUMBER, phoneUtil.parse("+64 3 331 6005", RegionCode.US));
1330 
1331     PhoneNumber nzNumber = new PhoneNumber();
1332     nzNumber.setCountryCode(64).setNationalNumber(64123456L);
1333     assertEquals(nzNumber, phoneUtil.parse("64(0)64123456", RegionCode.NZ));
1334     // Check that using a "/" is fine in a phone number.
1335     assertEquals(DE_NUMBER, phoneUtil.parse("301/23456", RegionCode.DE));
1336 
1337     PhoneNumber usNumber = new PhoneNumber();
1338     // Check it doesn't use the '1' as a country calling code when parsing if the phone number was
1339     // already possible.
1340     usNumber.setCountryCode(1).setNationalNumber(1234567890L);
1341     assertEquals(usNumber, phoneUtil.parse("123-456-7890", RegionCode.US));
1342   }
1343 
testParseNumberWithAlphaCharacters()1344   public void testParseNumberWithAlphaCharacters() throws Exception {
1345     // Test case with alpha characters.
1346     PhoneNumber tollfreeNumber = new PhoneNumber();
1347     tollfreeNumber.setCountryCode(64).setNationalNumber(800332005L);
1348     assertEquals(tollfreeNumber, phoneUtil.parse("0800 DDA 005", RegionCode.NZ));
1349     PhoneNumber premiumNumber = new PhoneNumber();
1350     premiumNumber.setCountryCode(64).setNationalNumber(9003326005L);
1351     assertEquals(premiumNumber, phoneUtil.parse("0900 DDA 6005", RegionCode.NZ));
1352     // Not enough alpha characters for them to be considered intentional, so they are stripped.
1353     assertEquals(premiumNumber, phoneUtil.parse("0900 332 6005a", RegionCode.NZ));
1354     assertEquals(premiumNumber, phoneUtil.parse("0900 332 600a5", RegionCode.NZ));
1355     assertEquals(premiumNumber, phoneUtil.parse("0900 332 600A5", RegionCode.NZ));
1356     assertEquals(premiumNumber, phoneUtil.parse("0900 a332 600A5", RegionCode.NZ));
1357   }
1358 
testParseWithInternationalPrefixes()1359   public void testParseWithInternationalPrefixes() throws Exception {
1360     assertEquals(US_NUMBER, phoneUtil.parse("+1 (650) 253-0000", RegionCode.NZ));
1361     assertEquals(US_NUMBER, phoneUtil.parse("1-650-253-0000", RegionCode.US));
1362     // Calling the US number from Singapore by using different service providers
1363     // 1st test: calling using SingTel IDD service (IDD is 001)
1364     assertEquals(US_NUMBER, phoneUtil.parse("0011-650-253-0000", RegionCode.SG));
1365     // 2nd test: calling using StarHub IDD service (IDD is 008)
1366     assertEquals(US_NUMBER, phoneUtil.parse("0081-650-253-0000", RegionCode.SG));
1367     // 3rd test: calling using SingTel V019 service (IDD is 019)
1368     assertEquals(US_NUMBER, phoneUtil.parse("0191-650-253-0000", RegionCode.SG));
1369     // Calling the US number from Poland
1370     assertEquals(US_NUMBER, phoneUtil.parse("0~01-650-253-0000", RegionCode.PL));
1371     // Using "++" at the start.
1372     assertEquals(US_NUMBER, phoneUtil.parse("++1 (650) 253-0000", RegionCode.PL));
1373   }
1374 
testParseNonAscii()1375   public void testParseNonAscii() throws Exception {
1376     // Using a full-width plus sign.
1377     assertEquals(US_NUMBER, phoneUtil.parse("\uFF0B1 (650) 253-0000", RegionCode.SG));
1378     // The whole number, including punctuation, is here represented in full-width form.
1379     assertEquals(US_NUMBER, phoneUtil.parse("\uFF0B\uFF11\u3000\uFF08\uFF16\uFF15\uFF10\uFF09" +
1380                                             "\u3000\uFF12\uFF15\uFF13\uFF0D\uFF10\uFF10\uFF10" +
1381                                             "\uFF10",
1382                                             RegionCode.SG));
1383     // Using U+30FC dash instead.
1384     assertEquals(US_NUMBER, phoneUtil.parse("\uFF0B\uFF11\u3000\uFF08\uFF16\uFF15\uFF10\uFF09" +
1385                                             "\u3000\uFF12\uFF15\uFF13\u30FC\uFF10\uFF10\uFF10" +
1386                                             "\uFF10",
1387                                             RegionCode.SG));
1388 
1389     // Using a very strange decimal digit range (Mongolian digits).
1390     assertEquals(US_NUMBER, phoneUtil.parse("\u1811 \u1816\u1815\u1810 " +
1391                                             "\u1812\u1815\u1813 \u1810\u1810\u1810\u1810",
1392                                             RegionCode.US));
1393   }
1394 
testParseWithLeadingZero()1395   public void testParseWithLeadingZero() throws Exception {
1396     assertEquals(IT_NUMBER, phoneUtil.parse("+39 02-36618 300", RegionCode.NZ));
1397     assertEquals(IT_NUMBER, phoneUtil.parse("02-36618 300", RegionCode.IT));
1398 
1399     assertEquals(IT_MOBILE, phoneUtil.parse("345 678 901", RegionCode.IT));
1400   }
1401 
testParseNationalNumberArgentina()1402   public void testParseNationalNumberArgentina() throws Exception {
1403     // Test parsing mobile numbers of Argentina.
1404     PhoneNumber arNumber = new PhoneNumber();
1405     arNumber.setCountryCode(54).setNationalNumber(93435551212L);
1406     assertEquals(arNumber, phoneUtil.parse("+54 9 343 555 1212", RegionCode.AR));
1407     assertEquals(arNumber, phoneUtil.parse("0343 15 555 1212", RegionCode.AR));
1408 
1409     arNumber.clear();
1410     arNumber.setCountryCode(54).setNationalNumber(93715654320L);
1411     assertEquals(arNumber, phoneUtil.parse("+54 9 3715 65 4320", RegionCode.AR));
1412     assertEquals(arNumber, phoneUtil.parse("03715 15 65 4320", RegionCode.AR));
1413     assertEquals(AR_MOBILE, phoneUtil.parse("911 876 54321", RegionCode.AR));
1414 
1415     // Test parsing fixed-line numbers of Argentina.
1416     assertEquals(AR_NUMBER, phoneUtil.parse("+54 11 8765 4321", RegionCode.AR));
1417     assertEquals(AR_NUMBER, phoneUtil.parse("011 8765 4321", RegionCode.AR));
1418 
1419     arNumber.clear();
1420     arNumber.setCountryCode(54).setNationalNumber(3715654321L);
1421     assertEquals(arNumber, phoneUtil.parse("+54 3715 65 4321", RegionCode.AR));
1422     assertEquals(arNumber, phoneUtil.parse("03715 65 4321", RegionCode.AR));
1423 
1424     arNumber.clear();
1425     arNumber.setCountryCode(54).setNationalNumber(2312340000L);
1426     assertEquals(arNumber, phoneUtil.parse("+54 23 1234 0000", RegionCode.AR));
1427     assertEquals(arNumber, phoneUtil.parse("023 1234 0000", RegionCode.AR));
1428   }
1429 
testParseWithXInNumber()1430   public void testParseWithXInNumber() throws Exception {
1431     // Test that having an 'x' in the phone number at the start is ok and that it just gets removed.
1432     assertEquals(AR_NUMBER, phoneUtil.parse("01187654321", RegionCode.AR));
1433     assertEquals(AR_NUMBER, phoneUtil.parse("(0) 1187654321", RegionCode.AR));
1434     assertEquals(AR_NUMBER, phoneUtil.parse("0 1187654321", RegionCode.AR));
1435     assertEquals(AR_NUMBER, phoneUtil.parse("(0xx) 1187654321", RegionCode.AR));
1436     PhoneNumber arFromUs = new PhoneNumber();
1437     arFromUs.setCountryCode(54).setNationalNumber(81429712L);
1438     // This test is intentionally constructed such that the number of digit after xx is larger than
1439     // 7, so that the number won't be mistakenly treated as an extension, as we allow extensions up
1440     // to 7 digits. This assumption is okay for now as all the countries where a carrier selection
1441     // code is written in the form of xx have a national significant number of length larger than 7.
1442     assertEquals(arFromUs, phoneUtil.parse("011xx5481429712", RegionCode.US));
1443   }
1444 
testParseNumbersMexico()1445   public void testParseNumbersMexico() throws Exception {
1446     // Test parsing fixed-line numbers of Mexico.
1447     PhoneNumber mxNumber = new PhoneNumber();
1448     mxNumber.setCountryCode(52).setNationalNumber(4499780001L);
1449     assertEquals(mxNumber, phoneUtil.parse("+52 (449)978-0001", RegionCode.MX));
1450     assertEquals(mxNumber, phoneUtil.parse("01 (449)978-0001", RegionCode.MX));
1451     assertEquals(mxNumber, phoneUtil.parse("(449)978-0001", RegionCode.MX));
1452 
1453     // Test parsing mobile numbers of Mexico.
1454     mxNumber.clear();
1455     mxNumber.setCountryCode(52).setNationalNumber(13312345678L);
1456     assertEquals(mxNumber, phoneUtil.parse("+52 1 33 1234-5678", RegionCode.MX));
1457     assertEquals(mxNumber, phoneUtil.parse("044 (33) 1234-5678", RegionCode.MX));
1458     assertEquals(mxNumber, phoneUtil.parse("045 33 1234-5678", RegionCode.MX));
1459   }
1460 
testFailedParseOnInvalidNumbers()1461   public void testFailedParseOnInvalidNumbers() {
1462     try {
1463       String sentencePhoneNumber = "This is not a phone number";
1464       phoneUtil.parse(sentencePhoneNumber, RegionCode.NZ);
1465       fail("This should not parse without throwing an exception " + sentencePhoneNumber);
1466     } catch (NumberParseException e) {
1467       // Expected this exception.
1468       assertEquals("Wrong error type stored in exception.",
1469                    NumberParseException.ErrorType.NOT_A_NUMBER,
1470                    e.getErrorType());
1471     }
1472     try {
1473       String tooLongPhoneNumber = "01495 72553301873 810104";
1474       phoneUtil.parse(tooLongPhoneNumber, RegionCode.GB);
1475       fail("This should not parse without throwing an exception " + tooLongPhoneNumber);
1476     } catch (NumberParseException e) {
1477       // Expected this exception.
1478       assertEquals("Wrong error type stored in exception.",
1479                    NumberParseException.ErrorType.TOO_LONG,
1480                    e.getErrorType());
1481     }
1482     try {
1483       String plusMinusPhoneNumber = "+---";
1484       phoneUtil.parse(plusMinusPhoneNumber, RegionCode.DE);
1485       fail("This should not parse without throwing an exception " + plusMinusPhoneNumber);
1486     } catch (NumberParseException e) {
1487       // Expected this exception.
1488       assertEquals("Wrong error type stored in exception.",
1489                    NumberParseException.ErrorType.NOT_A_NUMBER,
1490                    e.getErrorType());
1491     }
1492     try {
1493       String tooShortPhoneNumber = "+49 0";
1494       phoneUtil.parse(tooShortPhoneNumber, RegionCode.DE);
1495       fail("This should not parse without throwing an exception " + tooShortPhoneNumber);
1496     } catch (NumberParseException e) {
1497       // Expected this exception.
1498       assertEquals("Wrong error type stored in exception.",
1499                    NumberParseException.ErrorType.TOO_SHORT_NSN,
1500                    e.getErrorType());
1501     }
1502     try {
1503       String invalidCountryCode = "+210 3456 56789";
1504       phoneUtil.parse(invalidCountryCode, RegionCode.NZ);
1505       fail("This is not a recognised region code: should fail: " + invalidCountryCode);
1506     } catch (NumberParseException e) {
1507       // Expected this exception.
1508       assertEquals("Wrong error type stored in exception.",
1509                    NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
1510                    e.getErrorType());
1511     }
1512     try {
1513       String someNumber = "123 456 7890";
1514       phoneUtil.parse(someNumber, RegionCode.ZZ);
1515       fail("'Unknown' region code not allowed: should fail.");
1516     } catch (NumberParseException e) {
1517       // Expected this exception.
1518       assertEquals("Wrong error type stored in exception.",
1519                    NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
1520                    e.getErrorType());
1521     }
1522     try {
1523       String someNumber = "123 456 7890";
1524       phoneUtil.parse(someNumber, RegionCode.CS);
1525       fail("Deprecated region code not allowed: should fail.");
1526     } catch (NumberParseException e) {
1527       // Expected this exception.
1528       assertEquals("Wrong error type stored in exception.",
1529                    NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
1530                    e.getErrorType());
1531     }
1532     try {
1533       String someNumber = "123 456 7890";
1534       phoneUtil.parse(someNumber, null);
1535       fail("Null region code not allowed: should fail.");
1536     } catch (NumberParseException e) {
1537       // Expected this exception.
1538       assertEquals("Wrong error type stored in exception.",
1539                    NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
1540                    e.getErrorType());
1541     }
1542     try {
1543       String someNumber = "0044------";
1544       phoneUtil.parse(someNumber, RegionCode.GB);
1545       fail("No number provided, only region code: should fail");
1546     } catch (NumberParseException e) {
1547       // Expected this exception.
1548       assertEquals("Wrong error type stored in exception.",
1549                    NumberParseException.ErrorType.TOO_SHORT_AFTER_IDD,
1550                    e.getErrorType());
1551     }
1552     try {
1553       String someNumber = "0044";
1554       phoneUtil.parse(someNumber, RegionCode.GB);
1555       fail("No number provided, only region code: should fail");
1556     } catch (NumberParseException e) {
1557       // Expected this exception.
1558       assertEquals("Wrong error type stored in exception.",
1559                    NumberParseException.ErrorType.TOO_SHORT_AFTER_IDD,
1560                    e.getErrorType());
1561     }
1562     try {
1563       String someNumber = "011";
1564       phoneUtil.parse(someNumber, RegionCode.US);
1565       fail("Only IDD provided - should fail.");
1566     } catch (NumberParseException e) {
1567       // Expected this exception.
1568       assertEquals("Wrong error type stored in exception.",
1569                    NumberParseException.ErrorType.TOO_SHORT_AFTER_IDD,
1570                    e.getErrorType());
1571     }
1572     try {
1573       String someNumber = "0119";
1574       phoneUtil.parse(someNumber, RegionCode.US);
1575       fail("Only IDD provided and then 9 - should fail.");
1576     } catch (NumberParseException e) {
1577       // Expected this exception.
1578       assertEquals("Wrong error type stored in exception.",
1579                    NumberParseException.ErrorType.TOO_SHORT_AFTER_IDD,
1580                    e.getErrorType());
1581     }
1582     try {
1583       String emptyNumber = "";
1584       // Invalid region.
1585       phoneUtil.parse(emptyNumber, RegionCode.ZZ);
1586       fail("Empty string - should fail.");
1587     } catch (NumberParseException e) {
1588       // Expected this exception.
1589       assertEquals("Wrong error type stored in exception.",
1590                    NumberParseException.ErrorType.NOT_A_NUMBER,
1591                    e.getErrorType());
1592     }
1593     try {
1594       String nullNumber = null;
1595       // Invalid region.
1596       phoneUtil.parse(nullNumber, RegionCode.ZZ);
1597       fail("Null string - should fail.");
1598     } catch (NumberParseException e) {
1599       // Expected this exception.
1600       assertEquals("Wrong error type stored in exception.",
1601                    NumberParseException.ErrorType.NOT_A_NUMBER,
1602                    e.getErrorType());
1603     } catch (NullPointerException e) {
1604       fail("Null string - but should not throw a null pointer exception.");
1605     }
1606     try {
1607       String nullNumber = null;
1608       phoneUtil.parse(nullNumber, RegionCode.US);
1609       fail("Null string - should fail.");
1610     } catch (NumberParseException e) {
1611       // Expected this exception.
1612       assertEquals("Wrong error type stored in exception.",
1613                    NumberParseException.ErrorType.NOT_A_NUMBER,
1614                    e.getErrorType());
1615     } catch (NullPointerException e) {
1616       fail("Null string - but should not throw a null pointer exception.");
1617     }
1618   }
1619 
testParseNumbersWithPlusWithNoRegion()1620   public void testParseNumbersWithPlusWithNoRegion() throws Exception {
1621     // RegionCode.ZZ is allowed only if the number starts with a '+' - then the country calling code
1622     // can be calculated.
1623     assertEquals(NZ_NUMBER, phoneUtil.parse("+64 3 331 6005", RegionCode.ZZ));
1624     // Test with full-width plus.
1625     assertEquals(NZ_NUMBER, phoneUtil.parse("\uFF0B64 3 331 6005", RegionCode.ZZ));
1626     // Test with normal plus but leading characters that need to be stripped.
1627     assertEquals(NZ_NUMBER, phoneUtil.parse("Tel: +64 3 331 6005", RegionCode.ZZ));
1628     assertEquals(NZ_NUMBER, phoneUtil.parse("+64 3 331 6005", null));
1629 
1630     // It is important that we set the carrier code to an empty string, since we used
1631     // ParseAndKeepRawInput and no carrier code was found.
1632     PhoneNumber nzNumberWithRawInput = new PhoneNumber().mergeFrom(NZ_NUMBER).
1633         setRawInput("+64 3 331 6005").
1634         setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN).
1635         setPreferredDomesticCarrierCode("");
1636     assertEquals(nzNumberWithRawInput, phoneUtil.parseAndKeepRawInput("+64 3 331 6005",
1637                                                                       RegionCode.ZZ));
1638     // Null is also allowed for the region code in these cases.
1639     assertEquals(nzNumberWithRawInput, phoneUtil.parseAndKeepRawInput("+64 3 331 6005", null));
1640   }
1641 
testParseExtensions()1642   public void testParseExtensions() throws Exception {
1643     PhoneNumber nzNumber = new PhoneNumber();
1644     nzNumber.setCountryCode(64).setNationalNumber(33316005L).setExtension("3456");
1645     assertEquals(nzNumber, phoneUtil.parse("03 331 6005 ext 3456", RegionCode.NZ));
1646     assertEquals(nzNumber, phoneUtil.parse("03-3316005x3456", RegionCode.NZ));
1647     assertEquals(nzNumber, phoneUtil.parse("03-3316005 int.3456", RegionCode.NZ));
1648     assertEquals(nzNumber, phoneUtil.parse("03 3316005 #3456", RegionCode.NZ));
1649     // Test the following do not extract extensions:
1650     assertEquals(ALPHA_NUMERIC_NUMBER, phoneUtil.parse("1800 six-flags", RegionCode.US));
1651     assertEquals(ALPHA_NUMERIC_NUMBER, phoneUtil.parse("1800 SIX FLAGS", RegionCode.US));
1652     assertEquals(ALPHA_NUMERIC_NUMBER, phoneUtil.parse("0~0 1800 7493 5247", RegionCode.PL));
1653     assertEquals(ALPHA_NUMERIC_NUMBER, phoneUtil.parse("(1800) 7493.5247", RegionCode.US));
1654     // Check that the last instance of an extension token is matched.
1655     PhoneNumber extnNumber = new PhoneNumber().mergeFrom(ALPHA_NUMERIC_NUMBER).setExtension("1234");
1656     assertEquals(extnNumber, phoneUtil.parse("0~0 1800 7493 5247 ~1234", RegionCode.PL));
1657     // Verifying bug-fix where the last digit of a number was previously omitted if it was a 0 when
1658     // extracting the extension. Also verifying a few different cases of extensions.
1659     PhoneNumber ukNumber = new PhoneNumber();
1660     ukNumber.setCountryCode(44).setNationalNumber(2034567890L).setExtension("456");
1661     assertEquals(ukNumber, phoneUtil.parse("+44 2034567890x456", RegionCode.NZ));
1662     assertEquals(ukNumber, phoneUtil.parse("+44 2034567890x456", RegionCode.GB));
1663     assertEquals(ukNumber, phoneUtil.parse("+44 2034567890 x456", RegionCode.GB));
1664     assertEquals(ukNumber, phoneUtil.parse("+44 2034567890 X456", RegionCode.GB));
1665     assertEquals(ukNumber, phoneUtil.parse("+44 2034567890 X 456", RegionCode.GB));
1666     assertEquals(ukNumber, phoneUtil.parse("+44 2034567890 X  456", RegionCode.GB));
1667     assertEquals(ukNumber, phoneUtil.parse("+44 2034567890 x 456  ", RegionCode.GB));
1668     assertEquals(ukNumber, phoneUtil.parse("+44 2034567890  X 456", RegionCode.GB));
1669     assertEquals(ukNumber, phoneUtil.parse("+44-2034567890;ext=456", RegionCode.GB));
1670 
1671     PhoneNumber usWithExtension = new PhoneNumber();
1672     usWithExtension.setCountryCode(1).setNationalNumber(8009013355L).setExtension("7246433");
1673     assertEquals(usWithExtension, phoneUtil.parse("(800) 901-3355 x 7246433", RegionCode.US));
1674     assertEquals(usWithExtension, phoneUtil.parse("(800) 901-3355 , ext 7246433", RegionCode.US));
1675     assertEquals(usWithExtension,
1676                  phoneUtil.parse("(800) 901-3355 ,extension 7246433", RegionCode.US));
1677     assertEquals(usWithExtension,
1678                  phoneUtil.parse("(800) 901-3355 ,extensi\u00F3n 7246433", RegionCode.US));
1679     // Repeat with the small letter o with acute accent created by combining characters.
1680     assertEquals(usWithExtension,
1681                  phoneUtil.parse("(800) 901-3355 ,extensio\u0301n 7246433", RegionCode.US));
1682     assertEquals(usWithExtension, phoneUtil.parse("(800) 901-3355 , 7246433", RegionCode.US));
1683     assertEquals(usWithExtension, phoneUtil.parse("(800) 901-3355 ext: 7246433", RegionCode.US));
1684 
1685     // Test that if a number has two extensions specified, we ignore the second.
1686     PhoneNumber usWithTwoExtensionsNumber = new PhoneNumber();
1687     usWithTwoExtensionsNumber.setCountryCode(1).setNationalNumber(2121231234L).setExtension("508");
1688     assertEquals(usWithTwoExtensionsNumber, phoneUtil.parse("(212)123-1234 x508/x1234",
1689                                                             RegionCode.US));
1690     assertEquals(usWithTwoExtensionsNumber, phoneUtil.parse("(212)123-1234 x508/ x1234",
1691                                                             RegionCode.US));
1692     assertEquals(usWithTwoExtensionsNumber, phoneUtil.parse("(212)123-1234 x508\\x1234",
1693                                                             RegionCode.US));
1694 
1695     // Test parsing numbers in the form (645) 123-1234-910# works, where the last 3 digits before
1696     // the # are an extension.
1697     usWithExtension.clear();
1698     usWithExtension.setCountryCode(1).setNationalNumber(6451231234L).setExtension("910");
1699     assertEquals(usWithExtension, phoneUtil.parse("+1 (645) 123 1234-910#", RegionCode.US));
1700     // Retry with the same number in a slightly different format.
1701     assertEquals(usWithExtension, phoneUtil.parse("+1 (645) 123 1234 ext. 910#", RegionCode.US));
1702   }
1703 
testParseAndKeepRaw()1704   public void testParseAndKeepRaw() throws Exception {
1705     PhoneNumber alphaNumericNumber = new PhoneNumber().mergeFrom(ALPHA_NUMERIC_NUMBER).
1706         setRawInput("800 six-flags").
1707         setCountryCodeSource(CountryCodeSource.FROM_DEFAULT_COUNTRY).
1708         setPreferredDomesticCarrierCode("");
1709     assertEquals(alphaNumericNumber,
1710                  phoneUtil.parseAndKeepRawInput("800 six-flags", RegionCode.US));
1711 
1712     PhoneNumber shorterAlphaNumber = new PhoneNumber().
1713         setCountryCode(1).setNationalNumber(8007493524L).
1714         setRawInput("1800 six-flag").
1715         setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITHOUT_PLUS_SIGN).
1716         setPreferredDomesticCarrierCode("");
1717     assertEquals(shorterAlphaNumber,
1718                  phoneUtil.parseAndKeepRawInput("1800 six-flag", RegionCode.US));
1719 
1720     shorterAlphaNumber.setRawInput("+1800 six-flag").
1721         setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN);
1722     assertEquals(shorterAlphaNumber,
1723                  phoneUtil.parseAndKeepRawInput("+1800 six-flag", RegionCode.NZ));
1724 
1725     shorterAlphaNumber.setRawInput("001800 six-flag").
1726         setCountryCodeSource(CountryCodeSource.FROM_NUMBER_WITH_IDD);
1727     assertEquals(shorterAlphaNumber,
1728                  phoneUtil.parseAndKeepRawInput("001800 six-flag", RegionCode.NZ));
1729 
1730     // Invalid region code supplied.
1731     try {
1732       phoneUtil.parseAndKeepRawInput("123 456 7890", RegionCode.CS);
1733       fail("Deprecated region code not allowed: should fail.");
1734     } catch (NumberParseException e) {
1735       // Expected this exception.
1736       assertEquals("Wrong error type stored in exception.",
1737                    NumberParseException.ErrorType.INVALID_COUNTRY_CODE,
1738                    e.getErrorType());
1739     }
1740 
1741     PhoneNumber koreanNumber = new PhoneNumber();
1742     koreanNumber.setCountryCode(82).setNationalNumber(22123456).setRawInput("08122123456").
1743         setCountryCodeSource(CountryCodeSource.FROM_DEFAULT_COUNTRY).
1744         setPreferredDomesticCarrierCode("81");
1745     assertEquals(koreanNumber, phoneUtil.parseAndKeepRawInput("08122123456", RegionCode.KR));
1746   }
1747 
testCountryWithNoNumberDesc()1748   public void testCountryWithNoNumberDesc() {
1749     // Andorra is a country where we don't have PhoneNumberDesc info in the metadata.
1750     PhoneNumber adNumber = new PhoneNumber();
1751     adNumber.setCountryCode(376).setNationalNumber(12345L);
1752     assertEquals("+376 12345", phoneUtil.format(adNumber, PhoneNumberFormat.INTERNATIONAL));
1753     assertEquals("+37612345", phoneUtil.format(adNumber, PhoneNumberFormat.E164));
1754     assertEquals("12345", phoneUtil.format(adNumber, PhoneNumberFormat.NATIONAL));
1755     assertEquals(PhoneNumberUtil.PhoneNumberType.UNKNOWN, phoneUtil.getNumberType(adNumber));
1756     assertTrue(phoneUtil.isValidNumber(adNumber));
1757 
1758     // Test dialing a US number from within Andorra.
1759     assertEquals("00 1 650 253 0000",
1760                  phoneUtil.formatOutOfCountryCallingNumber(US_NUMBER, RegionCode.AD));
1761   }
1762 
testUnknownCountryCallingCodeForValidation()1763   public void testUnknownCountryCallingCodeForValidation() {
1764     PhoneNumber invalidNumber = new PhoneNumber();
1765     invalidNumber.setCountryCode(0).setNationalNumber(1234L);
1766     assertFalse(phoneUtil.isValidNumber(invalidNumber));
1767   }
1768 
testIsNumberMatchMatches()1769   public void testIsNumberMatchMatches() throws Exception {
1770     // Test simple matches where formatting is different, or leading zeroes, or country calling code
1771     // has been specified.
1772     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
1773                  phoneUtil.isNumberMatch("+64 3 331 6005", "+64 03 331 6005"));
1774     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
1775                  phoneUtil.isNumberMatch("+64 03 331-6005", "+64 03331 6005"));
1776     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
1777                  phoneUtil.isNumberMatch("+643 331-6005", "+64033316005"));
1778     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
1779                  phoneUtil.isNumberMatch("+643 331-6005", "+6433316005"));
1780     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
1781                  phoneUtil.isNumberMatch("+64 3 331-6005", "+6433316005"));
1782     // Test alpha numbers.
1783     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
1784                  phoneUtil.isNumberMatch("+1800 siX-Flags", "+1 800 7493 5247"));
1785     // Test numbers with extensions.
1786     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
1787                  phoneUtil.isNumberMatch("+64 3 331-6005 extn 1234", "+6433316005#1234"));
1788     // Test proto buffers.
1789     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
1790                  phoneUtil.isNumberMatch(NZ_NUMBER, "+6403 331 6005"));
1791 
1792     PhoneNumber nzNumber = new PhoneNumber().mergeFrom(NZ_NUMBER).setExtension("3456");
1793     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
1794                  phoneUtil.isNumberMatch(nzNumber, "+643 331 6005 ext 3456"));
1795     // Check empty extensions are ignored.
1796     nzNumber.setExtension("");
1797     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
1798                  phoneUtil.isNumberMatch(nzNumber, "+6403 331 6005"));
1799     // Check variant with two proto buffers.
1800     assertEquals("Number " + nzNumber.toString() + " did not match " + NZ_NUMBER.toString(),
1801                  PhoneNumberUtil.MatchType.EXACT_MATCH,
1802                  phoneUtil.isNumberMatch(nzNumber, NZ_NUMBER));
1803 
1804     // Check raw_input, country_code_source and preferred_domestic_carrier_code are ignored.
1805     PhoneNumber brNumberOne = new PhoneNumber();
1806     PhoneNumber brNumberTwo = new PhoneNumber();
1807     brNumberOne.setCountryCode(55).setNationalNumber(3121286979L)
1808         .setCountryCodeSource(PhoneNumber.CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN)
1809         .setPreferredDomesticCarrierCode("12").setRawInput("012 3121286979");
1810     brNumberTwo.setCountryCode(55).setNationalNumber(3121286979L)
1811         .setCountryCodeSource(PhoneNumber.CountryCodeSource.FROM_DEFAULT_COUNTRY)
1812         .setPreferredDomesticCarrierCode("14").setRawInput("143121286979");
1813     assertEquals(PhoneNumberUtil.MatchType.EXACT_MATCH,
1814                  phoneUtil.isNumberMatch(brNumberOne, brNumberTwo));
1815   }
1816 
testIsNumberMatchNonMatches()1817   public void testIsNumberMatchNonMatches() throws Exception {
1818     // Non-matches.
1819     assertEquals(PhoneNumberUtil.MatchType.NO_MATCH,
1820                  phoneUtil.isNumberMatch("03 331 6005", "03 331 6006"));
1821     // Different country calling code, partial number match.
1822     assertEquals(PhoneNumberUtil.MatchType.NO_MATCH,
1823                  phoneUtil.isNumberMatch("+64 3 331-6005", "+16433316005"));
1824     // Different country calling code, same number.
1825     assertEquals(PhoneNumberUtil.MatchType.NO_MATCH,
1826                  phoneUtil.isNumberMatch("+64 3 331-6005", "+6133316005"));
1827     // Extension different, all else the same.
1828     assertEquals(PhoneNumberUtil.MatchType.NO_MATCH,
1829                  phoneUtil.isNumberMatch("+64 3 331-6005 extn 1234", "0116433316005#1235"));
1830     // NSN matches, but extension is different - not the same number.
1831     assertEquals(PhoneNumberUtil.MatchType.NO_MATCH,
1832                  phoneUtil.isNumberMatch("+64 3 331-6005 ext.1235", "3 331 6005#1234"));
1833 
1834     // Invalid numbers that can't be parsed.
1835     assertEquals(PhoneNumberUtil.MatchType.NOT_A_NUMBER,
1836                  phoneUtil.isNumberMatch("43", "3 331 6043"));
1837     assertEquals(PhoneNumberUtil.MatchType.NOT_A_NUMBER,
1838                  phoneUtil.isNumberMatch("+43", "+64 3 331 6005"));
1839     assertEquals(PhoneNumberUtil.MatchType.NOT_A_NUMBER,
1840                  phoneUtil.isNumberMatch("+43", "64 3 331 6005"));
1841     assertEquals(PhoneNumberUtil.MatchType.NOT_A_NUMBER,
1842                  phoneUtil.isNumberMatch("Dog", "64 3 331 6005"));
1843   }
1844 
testIsNumberMatchNsnMatches()1845   public void testIsNumberMatchNsnMatches() throws Exception {
1846     // NSN matches.
1847     assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
1848                  phoneUtil.isNumberMatch("+64 3 331-6005", "03 331 6005"));
1849     assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
1850                  phoneUtil.isNumberMatch(NZ_NUMBER, "03 331 6005"));
1851     // Here the second number possibly starts with the country calling code for New Zealand,
1852     // although we are unsure.
1853     PhoneNumber unchangedNzNumber = new PhoneNumber().mergeFrom(NZ_NUMBER);
1854     assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
1855                  phoneUtil.isNumberMatch(unchangedNzNumber, "(64-3) 331 6005"));
1856     // Check the phone number proto was not edited during the method call.
1857     assertEquals(NZ_NUMBER, unchangedNzNumber);
1858 
1859     // Here, the 1 might be a national prefix, if we compare it to the US number, so the resultant
1860     // match is an NSN match.
1861     assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
1862                  phoneUtil.isNumberMatch(US_NUMBER, "1-650-253-0000"));
1863     assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
1864                  phoneUtil.isNumberMatch(US_NUMBER, "6502530000"));
1865     assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
1866                  phoneUtil.isNumberMatch("+1 650-253 0000", "1 650 253 0000"));
1867     assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
1868                  phoneUtil.isNumberMatch("1 650-253 0000", "1 650 253 0000"));
1869     assertEquals(PhoneNumberUtil.MatchType.NSN_MATCH,
1870                  phoneUtil.isNumberMatch("1 650-253 0000", "+1 650 253 0000"));
1871     // For this case, the match will be a short NSN match, because we cannot assume that the 1 might
1872     // be a national prefix, so don't remove it when parsing.
1873     PhoneNumber randomNumber = new PhoneNumber();
1874     randomNumber.setCountryCode(41).setNationalNumber(6502530000L);
1875     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
1876                  phoneUtil.isNumberMatch(randomNumber, "1-650-253-0000"));
1877   }
1878 
testIsNumberMatchShortNsnMatches()1879   public void testIsNumberMatchShortNsnMatches() throws Exception {
1880     // Short NSN matches with the country not specified for either one or both numbers.
1881     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
1882                  phoneUtil.isNumberMatch("+64 3 331-6005", "331 6005"));
1883     // We did not know that the "0" was a national prefix since neither number has a country code,
1884     // so this is considered a SHORT_NSN_MATCH.
1885     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
1886                  phoneUtil.isNumberMatch("3 331-6005", "03 331 6005"));
1887     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
1888                  phoneUtil.isNumberMatch("3 331-6005", "331 6005"));
1889     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
1890                  phoneUtil.isNumberMatch("3 331-6005", "+64 331 6005"));
1891     // Short NSN match with the country specified.
1892     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
1893                  phoneUtil.isNumberMatch("03 331-6005", "331 6005"));
1894     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
1895                  phoneUtil.isNumberMatch("1 234 345 6789", "345 6789"));
1896     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
1897                  phoneUtil.isNumberMatch("+1 (234) 345 6789", "345 6789"));
1898     // NSN matches, country calling code omitted for one number, extension missing for one.
1899     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
1900                  phoneUtil.isNumberMatch("+64 3 331-6005", "3 331 6005#1234"));
1901     // One has Italian leading zero, one does not.
1902     PhoneNumber italianNumberOne = new PhoneNumber();
1903     italianNumberOne.setCountryCode(39).setNationalNumber(1234L).setItalianLeadingZero(true);
1904     PhoneNumber italianNumberTwo = new PhoneNumber();
1905     italianNumberTwo.setCountryCode(39).setNationalNumber(1234L);
1906     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
1907                  phoneUtil.isNumberMatch(italianNumberOne, italianNumberTwo));
1908     // One has an extension, the other has an extension of "".
1909     italianNumberOne.setExtension("1234").clearItalianLeadingZero();
1910     italianNumberTwo.setExtension("");
1911     assertEquals(PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
1912                  phoneUtil.isNumberMatch(italianNumberOne, italianNumberTwo));
1913   }
1914 
testCanBeInternationallyDialled()1915   public void testCanBeInternationallyDialled() throws Exception {
1916     // We have no-international-dialling rules for the US in our test metadata that say that
1917     // toll-free numbers cannot be dialled internationally.
1918     assertFalse(phoneUtil.canBeInternationallyDialled(US_TOLLFREE));
1919 
1920     // Normal US numbers can be internationally dialled.
1921     assertTrue(phoneUtil.canBeInternationallyDialled(US_NUMBER));
1922 
1923     // Invalid number.
1924     assertTrue(phoneUtil.canBeInternationallyDialled(US_LOCAL_NUMBER));
1925 
1926     // We have no data for NZ - should return true.
1927     assertTrue(phoneUtil.canBeInternationallyDialled(NZ_NUMBER));
1928   }
1929 
testIsAlphaNumber()1930   public void testIsAlphaNumber() throws Exception {
1931     assertTrue(phoneUtil.isAlphaNumber("1800 six-flags"));
1932     assertTrue(phoneUtil.isAlphaNumber("1800 six-flags ext. 1234"));
1933     assertFalse(phoneUtil.isAlphaNumber("1800 123-1234"));
1934     assertFalse(phoneUtil.isAlphaNumber("1800 123-1234 extension: 1234"));
1935   }
1936 }
1937