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