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