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