• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**
2 * @license
3 * Copyright (C) 2010 The Libphonenumber Authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/**
19 * @fileoverview  Unit tests for the PhoneNumberUtil.
20 *
21 * Note that these tests use the metadata contained in metadatafortesting.js,
22 * not the normal metadata files, so should not be used for regression test
23 * purposes - these tests are illustrative only and test functionality.
24 *
25 * @author Nikolaos Trogkanis
26 */
27
28goog.require('goog.array');
29goog.require('goog.string.StringBuffer');
30goog.require('goog.testing.jsunit');
31goog.require('i18n.phonenumbers.NumberFormat');
32goog.require('i18n.phonenumbers.PhoneMetadata');
33goog.require('i18n.phonenumbers.PhoneNumber');
34goog.require('i18n.phonenumbers.PhoneNumberDesc');
35goog.require('i18n.phonenumbers.PhoneNumberUtil');
36goog.require('i18n.phonenumbers.RegionCode');
37
38
39/** @type {!i18n.phonenumbers.PhoneNumberUtil} */
40var phoneUtil = i18n.phonenumbers.PhoneNumberUtil.getInstance();
41
42
43// Set up some test numbers to re-use.
44// TODO: Rewrite this as static functions that return new numbers each time to
45// avoid any risk of accidental changes to mutable static state affecting many
46// tests.
47/** @type {!i18n.phonenumbers.PhoneNumber} */
48var ALPHA_NUMERIC_NUMBER = new i18n.phonenumbers.PhoneNumber();
49ALPHA_NUMERIC_NUMBER.setCountryCode(1);
50ALPHA_NUMERIC_NUMBER.setNationalNumber(80074935247);
51
52
53/** @type {!i18n.phonenumbers.PhoneNumber} */
54var AE_UAN = new i18n.phonenumbers.PhoneNumber();
55AE_UAN.setCountryCode(971);
56AE_UAN.setNationalNumber(600123456);
57
58
59/** @type {!i18n.phonenumbers.PhoneNumber} */
60var AR_MOBILE = new i18n.phonenumbers.PhoneNumber();
61AR_MOBILE.setCountryCode(54);
62AR_MOBILE.setNationalNumber(91187654321);
63
64
65/** @type {!i18n.phonenumbers.PhoneNumber} */
66var AR_NUMBER = new i18n.phonenumbers.PhoneNumber();
67AR_NUMBER.setCountryCode(54);
68AR_NUMBER.setNationalNumber(1187654321);
69
70
71/** @type {!i18n.phonenumbers.PhoneNumber} */
72var AU_NUMBER = new i18n.phonenumbers.PhoneNumber();
73AU_NUMBER.setCountryCode(61);
74AU_NUMBER.setNationalNumber(236618300);
75
76
77/** @type {!i18n.phonenumbers.PhoneNumber} */
78var BS_MOBILE = new i18n.phonenumbers.PhoneNumber();
79BS_MOBILE.setCountryCode(1);
80BS_MOBILE.setNationalNumber(2423570000);
81
82
83/** @type {!i18n.phonenumbers.PhoneNumber} */
84var BS_NUMBER = new i18n.phonenumbers.PhoneNumber();
85BS_NUMBER.setCountryCode(1);
86BS_NUMBER.setNationalNumber(2423651234);
87
88
89// Note that this is the same as the example number for DE in the metadata.
90/** @type {!i18n.phonenumbers.PhoneNumber} */
91var DE_NUMBER = new i18n.phonenumbers.PhoneNumber();
92DE_NUMBER.setCountryCode(49);
93DE_NUMBER.setNationalNumber(30123456);
94
95
96/** @type {!i18n.phonenumbers.PhoneNumber} */
97var DE_SHORT_NUMBER = new i18n.phonenumbers.PhoneNumber();
98DE_SHORT_NUMBER.setCountryCode(49);
99DE_SHORT_NUMBER.setNationalNumber(1234);
100
101
102/** @type {!i18n.phonenumbers.PhoneNumber} */
103var GB_MOBILE = new i18n.phonenumbers.PhoneNumber();
104GB_MOBILE.setCountryCode(44);
105GB_MOBILE.setNationalNumber(7912345678);
106
107
108/** @type {!i18n.phonenumbers.PhoneNumber} */
109var GB_NUMBER = new i18n.phonenumbers.PhoneNumber();
110GB_NUMBER.setCountryCode(44);
111GB_NUMBER.setNationalNumber(2070313000);
112
113
114/** @type {!i18n.phonenumbers.PhoneNumber} */
115var IT_MOBILE = new i18n.phonenumbers.PhoneNumber();
116IT_MOBILE.setCountryCode(39);
117IT_MOBILE.setNationalNumber(345678901);
118
119
120/** @type {!i18n.phonenumbers.PhoneNumber} */
121var IT_NUMBER = new i18n.phonenumbers.PhoneNumber();
122IT_NUMBER.setCountryCode(39);
123IT_NUMBER.setNationalNumber(236618300);
124IT_NUMBER.setItalianLeadingZero(true);
125
126
127/** @type {!i18n.phonenumbers.PhoneNumber} */
128var JP_STAR_NUMBER = new i18n.phonenumbers.PhoneNumber();
129JP_STAR_NUMBER.setCountryCode(81);
130JP_STAR_NUMBER.setNationalNumber(2345);
131
132
133// Numbers to test the formatting rules from Mexico.
134/** @type {!i18n.phonenumbers.PhoneNumber} */
135var MX_MOBILE1 = new i18n.phonenumbers.PhoneNumber();
136MX_MOBILE1.setCountryCode(52);
137MX_MOBILE1.setNationalNumber(12345678900);
138
139
140/** @type {!i18n.phonenumbers.PhoneNumber} */
141var MX_MOBILE2 = new i18n.phonenumbers.PhoneNumber();
142MX_MOBILE2.setCountryCode(52);
143MX_MOBILE2.setNationalNumber(15512345678);
144
145
146/** @type {!i18n.phonenumbers.PhoneNumber} */
147var MX_NUMBER1 = new i18n.phonenumbers.PhoneNumber();
148MX_NUMBER1.setCountryCode(52);
149MX_NUMBER1.setNationalNumber(3312345678);
150
151
152/** @type {!i18n.phonenumbers.PhoneNumber} */
153var MX_NUMBER2 = new i18n.phonenumbers.PhoneNumber();
154MX_NUMBER2.setCountryCode(52);
155MX_NUMBER2.setNationalNumber(8211234567);
156
157
158/** @type {!i18n.phonenumbers.PhoneNumber} */
159var NZ_NUMBER = new i18n.phonenumbers.PhoneNumber();
160NZ_NUMBER.setCountryCode(64);
161NZ_NUMBER.setNationalNumber(33316005);
162
163
164/** @type {!i18n.phonenumbers.PhoneNumber} */
165var SG_NUMBER = new i18n.phonenumbers.PhoneNumber();
166SG_NUMBER.setCountryCode(65);
167SG_NUMBER.setNationalNumber(65218000);
168
169
170// A too-long and hence invalid US number.
171/** @type {!i18n.phonenumbers.PhoneNumber} */
172var US_LONG_NUMBER = new i18n.phonenumbers.PhoneNumber();
173US_LONG_NUMBER.setCountryCode(1);
174US_LONG_NUMBER.setNationalNumber(65025300001);
175
176
177/** @type {!i18n.phonenumbers.PhoneNumber} */
178var US_NUMBER = new i18n.phonenumbers.PhoneNumber();
179US_NUMBER.setCountryCode(1);
180US_NUMBER.setNationalNumber(6502530000);
181
182
183/** @type {!i18n.phonenumbers.PhoneNumber} */
184var US_PREMIUM = new i18n.phonenumbers.PhoneNumber();
185US_PREMIUM.setCountryCode(1);
186US_PREMIUM.setNationalNumber(9002530000);
187
188
189// Too short, but still possible US numbers.
190/** @type {!i18n.phonenumbers.PhoneNumber} */
191var US_LOCAL_NUMBER = new i18n.phonenumbers.PhoneNumber();
192US_LOCAL_NUMBER.setCountryCode(1);
193US_LOCAL_NUMBER.setNationalNumber(2530000);
194
195
196/** @type {!i18n.phonenumbers.PhoneNumber} */
197var US_SHORT_BY_ONE_NUMBER = new i18n.phonenumbers.PhoneNumber();
198US_SHORT_BY_ONE_NUMBER.setCountryCode(1);
199US_SHORT_BY_ONE_NUMBER.setNationalNumber(650253000);
200
201
202/** @type {!i18n.phonenumbers.PhoneNumber} */
203var US_TOLLFREE = new i18n.phonenumbers.PhoneNumber();
204US_TOLLFREE.setCountryCode(1);
205US_TOLLFREE.setNationalNumber(8002530000);
206
207
208/** @type {!i18n.phonenumbers.PhoneNumber} */
209var US_SPOOF = new i18n.phonenumbers.PhoneNumber();
210US_SPOOF.setCountryCode(1);
211US_SPOOF.setNationalNumber(0);
212
213
214/** @type {!i18n.phonenumbers.PhoneNumber} */
215var US_SPOOF_WITH_RAW_INPUT = new i18n.phonenumbers.PhoneNumber();
216US_SPOOF_WITH_RAW_INPUT.setCountryCode(1);
217US_SPOOF_WITH_RAW_INPUT.setNationalNumber(0);
218US_SPOOF_WITH_RAW_INPUT.setRawInput('000-000-0000');
219
220
221/** @type {!i18n.phonenumbers.PhoneNumber} */
222var UZ_FIXED_LINE = new i18n.phonenumbers.PhoneNumber();
223UZ_FIXED_LINE.setCountryCode(998);
224UZ_FIXED_LINE.setNationalNumber(612201234);
225
226
227/** @type {!i18n.phonenumbers.PhoneNumber} */
228var UZ_MOBILE = new i18n.phonenumbers.PhoneNumber();
229UZ_MOBILE.setCountryCode(998);
230UZ_MOBILE.setNationalNumber(950123456);
231
232
233/** @type {!i18n.phonenumbers.PhoneNumber} */
234var INTERNATIONAL_TOLL_FREE = new i18n.phonenumbers.PhoneNumber();
235INTERNATIONAL_TOLL_FREE.setCountryCode(800);
236INTERNATIONAL_TOLL_FREE.setNationalNumber(12345678);
237
238
239// We set this to be the same length as numbers for the other non-geographical
240// country prefix that we have in our test metadata. However, this is not
241// considered valid because they differ in their country calling code.
242/** @type {!i18n.phonenumbers.PhoneNumber} */
243var INTERNATIONAL_TOLL_FREE_TOO_LONG = new i18n.phonenumbers.PhoneNumber();
244INTERNATIONAL_TOLL_FREE_TOO_LONG.setCountryCode(800);
245INTERNATIONAL_TOLL_FREE_TOO_LONG.setNationalNumber(123456789);
246
247
248/** @type {!i18n.phonenumbers.PhoneNumber} */
249var UNIVERSAL_PREMIUM_RATE = new i18n.phonenumbers.PhoneNumber();
250UNIVERSAL_PREMIUM_RATE.setCountryCode(979);
251UNIVERSAL_PREMIUM_RATE.setNationalNumber(123456789);
252
253
254/** @type {!i18n.phonenumbers.PhoneNumber} */
255var UNKNOWN_COUNTRY_CODE_NO_RAW_INPUT = new i18n.phonenumbers.PhoneNumber();
256UNKNOWN_COUNTRY_CODE_NO_RAW_INPUT.setCountryCode(2);
257UNKNOWN_COUNTRY_CODE_NO_RAW_INPUT.setNationalNumber(12345);
258
259var RegionCode = i18n.phonenumbers.RegionCode;
260
261function testGetInstanceLoadUSMetadata() {
262  /** @type {i18n.phonenumbers.PhoneMetadata} */
263  var metadata = phoneUtil.getMetadataForRegion(RegionCode.US);
264  assertEquals(RegionCode.US, metadata.getId());
265  assertEquals(1, metadata.getCountryCode());
266  assertEquals('011', metadata.getInternationalPrefix());
267  assertTrue(metadata.hasNationalPrefix());
268  assertEquals(2, metadata.numberFormatCount());
269  assertEquals('(\\d{3})(\\d{3})(\\d{4})',
270               metadata.getNumberFormat(1).getPattern());
271  assertEquals('$1 $2 $3', metadata.getNumberFormat(1).getFormat());
272  assertEquals('[13-689]\\d{9}|2[0-35-9]\\d{8}',
273               metadata.getGeneralDesc().getNationalNumberPattern());
274  assertEquals('[13-689]\\d{9}|2[0-35-9]\\d{8}',
275               metadata.getFixedLine().getNationalNumberPattern());
276  assertEquals('900\\d{7}',
277               metadata.getPremiumRate().getNationalNumberPattern());
278  // No shared-cost data is available, so its national number data should not be
279  // set.
280  assertFalse(metadata.getSharedCost().hasNationalNumberPattern());
281}
282
283function testGetInstanceLoadDEMetadata() {
284  /** @type {i18n.phonenumbers.PhoneMetadata} */
285  var metadata = phoneUtil.getMetadataForRegion(RegionCode.DE);
286  assertEquals(RegionCode.DE, metadata.getId());
287  assertEquals(49, metadata.getCountryCode());
288  assertEquals('00', metadata.getInternationalPrefix());
289  assertEquals('0', metadata.getNationalPrefix());
290  assertEquals(6, metadata.numberFormatCount());
291  assertEquals(1, metadata.getNumberFormat(5).leadingDigitsPatternCount());
292  assertEquals('900', metadata.getNumberFormat(5).getLeadingDigitsPattern(0));
293  assertEquals('(\\d{3})(\\d{3,4})(\\d{4})',
294               metadata.getNumberFormat(5).getPattern());
295  assertEquals('$1 $2 $3', metadata.getNumberFormat(5).getFormat());
296  assertEquals('(?:[24-6]\\d{2}|3[03-9]\\d|[789](?:0[2-9]|[1-9]\\d))\\d{1,8}',
297               metadata.getFixedLine().getNationalNumberPattern());
298  assertEquals('30123456', metadata.getFixedLine().getExampleNumber());
299  assertEquals('900([135]\\d{6}|9\\d{7})',
300               metadata.getPremiumRate().getNationalNumberPattern());
301}
302
303function testGetInstanceLoadARMetadata() {
304  /** @type {i18n.phonenumbers.PhoneMetadata} */
305  var metadata = phoneUtil.getMetadataForRegion(RegionCode.AR);
306  assertEquals(RegionCode.AR, metadata.getId());
307  assertEquals(54, metadata.getCountryCode());
308  assertEquals('00', metadata.getInternationalPrefix());
309  assertEquals('0', metadata.getNationalPrefix());
310  assertEquals('0(?:(11|343|3715)15)?', metadata.getNationalPrefixForParsing());
311  assertEquals('9$1', metadata.getNationalPrefixTransformRule());
312  assertEquals('$2 15 $3-$4', metadata.getNumberFormat(2).getFormat());
313  assertEquals('(\\d)(\\d{4})(\\d{2})(\\d{4})',
314               metadata.getNumberFormat(3).getPattern());
315  assertEquals('(\\d)(\\d{4})(\\d{2})(\\d{4})',
316               metadata.getIntlNumberFormat(3).getPattern());
317  assertEquals('$1 $2 $3 $4', metadata.getIntlNumberFormat(3).getFormat());
318}
319
320function testGetInstanceLoadInternationalTollFreeMetadata() {
321  /** @type {i18n.phonenumbers.PhoneMetadata} */
322  var metadata = phoneUtil.getMetadataForNonGeographicalRegion(800);
323  assertEquals('001', metadata.getId());
324  assertEquals(800, metadata.getCountryCode());
325  assertEquals('$1 $2', metadata.getNumberFormat(0).getFormat());
326  assertEquals('(\\d{4})(\\d{4})', metadata.getNumberFormat(0).getPattern());
327  assertEquals(0, metadata.getGeneralDesc().possibleLengthLocalOnlyCount());
328  assertEquals(1, metadata.getGeneralDesc().possibleLengthCount());
329  assertEquals('12345678', metadata.getTollFree().getExampleNumber());
330}
331
332function testIsNumberGeographical() {
333  // Bahamas, mobile phone number.
334  assertFalse(phoneUtil.isNumberGeographical(BS_MOBILE));
335  // Australian fixed line number.
336  assertTrue(phoneUtil.isNumberGeographical(AU_NUMBER));
337  // International toll free number.
338  assertFalse(phoneUtil.isNumberGeographical(INTERNATIONAL_TOLL_FREE));
339  // We test that mobile phone numbers in relevant regions are indeed considered
340  // geographical.
341  // Argentina, mobile phone number.
342  assertTrue(phoneUtil.isNumberGeographical(AR_MOBILE));
343  // Mexico, mobile phone number.
344  assertTrue(phoneUtil.isNumberGeographical(MX_MOBILE1));
345  // Mexico, another mobile phone number.
346  assertTrue(phoneUtil.isNumberGeographical(MX_MOBILE2));
347}
348
349function testGetLengthOfGeographicalAreaCode() {
350  // Google MTV, which has area code '650'.
351  assertEquals(3, phoneUtil.getLengthOfGeographicalAreaCode(US_NUMBER));
352
353  // A North America toll-free number, which has no area code.
354  assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(US_TOLLFREE));
355
356  // Google London, which has area code '20'.
357  assertEquals(2, phoneUtil.getLengthOfGeographicalAreaCode(GB_NUMBER));
358
359  // A UK mobile phone, which has no area code.
360  assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(GB_MOBILE));
361
362  // Google Buenos Aires, which has area code '11'.
363  assertEquals(2, phoneUtil.getLengthOfGeographicalAreaCode(AR_NUMBER));
364
365  // Google Sydney, which has area code '2'.
366  assertEquals(1, phoneUtil.getLengthOfGeographicalAreaCode(AU_NUMBER));
367
368  // Italian numbers - there is no national prefix, but it still has an area
369  // code.
370  assertEquals(2, phoneUtil.getLengthOfGeographicalAreaCode(IT_NUMBER));
371
372  // Google Singapore. Singapore has no area code and no national prefix.
373  assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(SG_NUMBER));
374
375  // An invalid US number (1 digit shorter), which has no area code.
376  assertEquals(0,
377      phoneUtil.getLengthOfGeographicalAreaCode(US_SHORT_BY_ONE_NUMBER));
378
379  // An international toll free number, which has no area code.
380  assertEquals(0,
381      phoneUtil.getLengthOfGeographicalAreaCode(INTERNATIONAL_TOLL_FREE));
382}
383
384function testGetLengthOfNationalDestinationCode() {
385  // Google MTV, which has national destination code (NDC) '650'.
386  assertEquals(3, phoneUtil.getLengthOfNationalDestinationCode(US_NUMBER));
387
388  // A North America toll-free number, which has NDC '800'.
389  assertEquals(3, phoneUtil.getLengthOfNationalDestinationCode(US_TOLLFREE));
390
391  // Google London, which has NDC '20'.
392  assertEquals(2, phoneUtil.getLengthOfNationalDestinationCode(GB_NUMBER));
393
394  // A UK mobile phone, which has NDC '7912'.
395  assertEquals(4, phoneUtil.getLengthOfNationalDestinationCode(GB_MOBILE));
396
397  // Google Buenos Aires, which has NDC '11'.
398  assertEquals(2, phoneUtil.getLengthOfNationalDestinationCode(AR_NUMBER));
399
400  // An Argentinian mobile which has NDC '911'.
401  assertEquals(3, phoneUtil.getLengthOfNationalDestinationCode(AR_MOBILE));
402
403  // Google Sydney, which has NDC '2'.
404  assertEquals(1, phoneUtil.getLengthOfNationalDestinationCode(AU_NUMBER));
405
406  // Google Singapore, which has NDC '6521'.
407  assertEquals(4, phoneUtil.getLengthOfNationalDestinationCode(SG_NUMBER));
408
409  // An invalid US number (1 digit shorter), which has no NDC.
410  assertEquals(0,
411      phoneUtil.getLengthOfNationalDestinationCode(US_SHORT_BY_ONE_NUMBER));
412
413  // A number containing an invalid country calling code, which shouldn't have
414  // any NDC.
415  /** @type {!i18n.phonenumbers.PhoneNumber} */
416  var number = new i18n.phonenumbers.PhoneNumber();
417  number.setCountryCode(123);
418  number.setNationalNumber(6502530000);
419  assertEquals(0, phoneUtil.getLengthOfNationalDestinationCode(number));
420
421  // An international toll free number, which has NDC '1234'.
422  assertEquals(4,
423      phoneUtil.getLengthOfNationalDestinationCode(INTERNATIONAL_TOLL_FREE));
424}
425
426function testGetCountryMobileToken() {
427  assertEquals('9', i18n.phonenumbers.PhoneNumberUtil.getCountryMobileToken(
428      phoneUtil.getCountryCodeForRegion(RegionCode.AR)));
429
430  // Country calling code for Sweden, which has no mobile token.
431  assertEquals('', i18n.phonenumbers.PhoneNumberUtil.getCountryMobileToken(
432      phoneUtil.getCountryCodeForRegion(RegionCode.SE)));
433}
434
435function testGetSupportedRegions() {
436  assertTrue(phoneUtil.getSupportedRegions().length > 0);
437  assertTrue(goog.array.contains(
438      phoneUtil.getSupportedRegions(), RegionCode.US));
439  assertFalse(goog.array.contains(
440      phoneUtil.getSupportedRegions(), RegionCode.UN001));
441  assertFalse(goog.array.contains(phoneUtil.getSupportedRegions(), '800'));
442}
443
444function testGetSupportedGlobalNetworkCallingCodes() {
445  assertTrue(phoneUtil.getSupportedGlobalNetworkCallingCodes().length > 0);
446  assertFalse(goog.array.contains(
447      phoneUtil.getSupportedGlobalNetworkCallingCodes(), RegionCode.US));
448  assertTrue(goog.array.contains(
449      phoneUtil.getSupportedGlobalNetworkCallingCodes(), 800));
450  goog.array.forEach(
451      phoneUtil.getSupportedGlobalNetworkCallingCodes(),
452      function(countryCallingCode) {
453        assertEquals(RegionCode.UN001,
454            phoneUtil.getRegionCodeForCountryCode(countryCallingCode));
455      });
456}
457
458function testGetSupportedCallingCodes() {
459  assertTrue(phoneUtil.getSupportedCallingCodes().length > 0);
460  goog.array.forEach(
461      phoneUtil.getSupportedCallingCodes(),
462      function(callingCode) {
463        assertTrue(callingCode > 0);
464        assertFalse(phoneUtil.getRegionCodeForCountryCode(callingCode) ==
465            RegionCode.ZZ);
466      });
467  // There should be more than just the global network calling codes in this set.
468  assertTrue(phoneUtil.getSupportedCallingCodes().length >
469      phoneUtil.getSupportedGlobalNetworkCallingCodes().length);
470  // But they should be included. Testing one of them.
471  assertTrue(goog.array.contains(
472      phoneUtil.getSupportedGlobalNetworkCallingCodes(), 979));
473}
474
475function testGetSupportedTypesForRegion() {
476  var PNT = i18n.phonenumbers.PhoneNumberType;
477  var types = phoneUtil.getSupportedTypesForRegion(RegionCode.BR);
478  assertTrue(goog.array.contains(types, PNT.FIXED_LINE));
479  // Our test data has no mobile numbers for Brazil.
480  assertFalse(goog.array.contains(types, PNT.MOBILE));
481  // UNKNOWN should never be returned.
482  assertFalse(goog.array.contains(types, PNT.UNKNOWN));
483
484  // In the US, many numbers are classified as FIXED_LINE_OR_MOBILE; but we
485  // don't want to expose this as a supported type, instead we say FIXED_LINE
486  // and MOBILE are both present.
487  types = phoneUtil.getSupportedTypesForRegion(RegionCode.US);
488  assertTrue(goog.array.contains(types, PNT.FIXED_LINE));
489  assertTrue(goog.array.contains(types, PNT.MOBILE));
490  assertFalse(goog.array.contains(types, PNT.FIXED_LINE_OR_MOBILE));
491
492  types = phoneUtil.getSupportedTypesForRegion(RegionCode.ZZ);
493  assertTrue(types.length == 0);
494}
495
496function testGetSupportedTypesForNonGeoEntity() {
497  var PNT = i18n.phonenumbers.PhoneNumberType;
498  var types = phoneUtil.getSupportedTypesForNonGeoEntity(999);
499  // No data exists for 999 at all, no types should be returned.
500  assertTrue(types.length == 0);
501
502  types = phoneUtil.getSupportedTypesForNonGeoEntity(979);
503  assertTrue(goog.array.contains(types, PNT.PREMIUM_RATE));
504  // Our test data has no mobile numbers for Brazil.
505  assertFalse(goog.array.contains(types, PNT.MOBILE));
506  // UNKNOWN should never be returned.
507  assertFalse(goog.array.contains(types, PNT.UNKNOWN));
508}
509
510function testGetNationalSignificantNumber() {
511  assertEquals('6502530000',
512      phoneUtil.getNationalSignificantNumber(US_NUMBER));
513
514  // An Italian mobile number.
515  assertEquals('345678901',
516      phoneUtil.getNationalSignificantNumber(IT_MOBILE));
517
518  // An Italian fixed line number.
519  assertEquals('0236618300',
520      phoneUtil.getNationalSignificantNumber(IT_NUMBER));
521
522  assertEquals('12345678',
523      phoneUtil.getNationalSignificantNumber(INTERNATIONAL_TOLL_FREE));
524
525  // An empty number.
526  /** @type {!i18n.phonenumbers.PhoneNumber} */
527  var emptyNumber = new i18n.phonenumbers.PhoneNumber();
528  assertEquals('', phoneUtil.getNationalSignificantNumber(emptyNumber));
529}
530
531function testGetNationalSignificantNumber_ManyLeadingZeros() {
532  /** @type {!i18n.phonenumbers.PhoneNumber} */
533  var number = new i18n.phonenumbers.PhoneNumber();
534  number.setCountryCode(1);
535  number.setNationalNumber(650);
536  number.setItalianLeadingZero(true);
537  number.setNumberOfLeadingZeros(2);
538  assertEquals('00650', phoneUtil.getNationalSignificantNumber(number));
539
540  // Set a bad value; we shouldn't crash, we shouldn't output any leading zeros
541  // at all.
542  number.setNumberOfLeadingZeros(-3);
543  assertEquals('650', phoneUtil.getNationalSignificantNumber(number));
544}
545
546function testGetExampleNumber() {
547  var PNT = i18n.phonenumbers.PhoneNumberType;
548  assertTrue(DE_NUMBER.equals(phoneUtil.getExampleNumber(RegionCode.DE)));
549
550  assertTrue(DE_NUMBER.equals(
551      phoneUtil.getExampleNumberForType(RegionCode.DE, PNT.FIXED_LINE)));
552
553  // Should return the same response if asked for FIXED_LINE_OR_MOBILE too.
554  assertTrue(DE_NUMBER.equals(
555      phoneUtil.getExampleNumberForType(
556          RegionCode.DE, PNT.FIXED_LINE_OR_MOBILE)));
557  // We have data for the US, but no data for VOICEMAIL.
558  assertNull(
559      phoneUtil.getExampleNumberForType(RegionCode.US, PNT.VOICEMAIL));
560
561  assertNotNull(
562      phoneUtil.getExampleNumberForType(RegionCode.US, PNT.FIXED_LINE));
563  assertNotNull(phoneUtil.getExampleNumberForType(RegionCode.US, PNT.MOBILE));
564  // CS is an invalid region, so we have no data for it.
565  assertNull(phoneUtil.getExampleNumberForType(RegionCode.CS, PNT.MOBILE));
566  // RegionCode 001 is reserved for supporting non-geographical country calling
567  // code. We don't support getting an example number for it with this method.
568  assertNull(phoneUtil.getExampleNumber(RegionCode.UN001));
569}
570
571function testGetExampleNumberForNonGeoEntity() {
572  assertTrue(INTERNATIONAL_TOLL_FREE.equals(
573      phoneUtil.getExampleNumberForNonGeoEntity(800)));
574  assertTrue(UNIVERSAL_PREMIUM_RATE.equals(
575      phoneUtil.getExampleNumberForNonGeoEntity(979)));
576}
577
578function testConvertAlphaCharactersInNumber() {
579  /** @type {string} */
580  var input = '1800-ABC-DEF';
581  // Alpha chars are converted to digits; everything else is left untouched.
582  /** @type {string} */
583  var expectedOutput = '1800-222-333';
584  assertEquals(expectedOutput,
585      i18n.phonenumbers.PhoneNumberUtil.convertAlphaCharactersInNumber(input));
586}
587
588function testNormaliseRemovePunctuation() {
589  /** @type {string} */
590  var inputNumber = '034-56&+#2\u00AD34';
591  /** @type {string} */
592  var expectedOutput = '03456234';
593  assertEquals('Conversion did not correctly remove punctuation',
594      expectedOutput,
595      i18n.phonenumbers.PhoneNumberUtil.normalize(inputNumber));
596}
597
598function testNormaliseReplaceAlphaCharacters() {
599  /** @type {string} */
600  var inputNumber = '034-I-am-HUNGRY';
601  /** @type {string} */
602  var expectedOutput = '034426486479';
603  assertEquals('Conversion did not correctly replace alpha characters',
604      expectedOutput,
605      i18n.phonenumbers.PhoneNumberUtil.normalize(inputNumber));
606}
607
608function testNormaliseOtherDigits() {
609  /** @type {string} */
610  var inputNumber = '\uFF125\u0665';
611  /** @type {string} */
612  var expectedOutput = '255';
613  assertEquals('Conversion did not correctly replace non-latin digits',
614      expectedOutput,
615      i18n.phonenumbers.PhoneNumberUtil.normalize(inputNumber));
616  // Eastern-Arabic digits.
617  inputNumber = '\u06F52\u06F0';
618  expectedOutput = '520';
619  assertEquals('Conversion did not correctly replace non-latin digits',
620      expectedOutput,
621      i18n.phonenumbers.PhoneNumberUtil.normalize(inputNumber));
622}
623
624function testNormaliseStripAlphaCharacters() {
625  /** @type {string} */
626  var inputNumber = '034-56&+a#234';
627  /** @type {string} */
628  var expectedOutput = '03456234';
629  assertEquals('Conversion did not correctly remove alpha character',
630      expectedOutput,
631      i18n.phonenumbers.PhoneNumberUtil.normalizeDigitsOnly(inputNumber));
632}
633
634function testNormaliseStripNonDiallableCharacters() {
635  /** @type {string} */
636  var inputNumber = '03*4-56&+1a#234';
637  /** @type {string} */
638  var expectedOutput = '03*456+1#234';
639  assertEquals('Conversion did not correctly remove non-diallable characters',
640               expectedOutput,
641               i18n.phonenumbers.PhoneNumberUtil.normalizeDiallableCharsOnly(
642                   inputNumber));
643}
644
645function testFormatUSNumber() {
646  var PNF = i18n.phonenumbers.PhoneNumberFormat;
647  assertEquals('650 253 0000',
648               phoneUtil.format(US_NUMBER, PNF.NATIONAL));
649  assertEquals('+1 650 253 0000',
650               phoneUtil.format(US_NUMBER, PNF.INTERNATIONAL));
651
652  assertEquals('800 253 0000',
653               phoneUtil.format(US_TOLLFREE, PNF.NATIONAL));
654  assertEquals('+1 800 253 0000',
655               phoneUtil.format(US_TOLLFREE, PNF.INTERNATIONAL));
656
657  assertEquals('900 253 0000',
658               phoneUtil.format(US_PREMIUM, PNF.NATIONAL));
659  assertEquals('+1 900 253 0000',
660               phoneUtil.format(US_PREMIUM, PNF.INTERNATIONAL));
661  assertEquals('tel:+1-900-253-0000',
662               phoneUtil.format(US_PREMIUM, PNF.RFC3966));
663  // Numbers with all zeros in the national number part will be formatted by
664  // using the raw_input if that is available no matter which format is
665  // specified.
666  assertEquals('000-000-0000',
667               phoneUtil.format(US_SPOOF_WITH_RAW_INPUT, PNF.NATIONAL));
668  assertEquals('0', phoneUtil.format(US_SPOOF, PNF.NATIONAL));
669}
670
671function testFormatBSNumber() {
672  var PNF = i18n.phonenumbers.PhoneNumberFormat;
673  assertEquals('242 365 1234',
674               phoneUtil.format(BS_NUMBER, PNF.NATIONAL));
675  assertEquals('+1 242 365 1234',
676               phoneUtil.format(BS_NUMBER, PNF.INTERNATIONAL));
677}
678
679function testFormatGBNumber() {
680  var PNF = i18n.phonenumbers.PhoneNumberFormat;
681  assertEquals('(020) 7031 3000',
682               phoneUtil.format(GB_NUMBER, PNF.NATIONAL));
683  assertEquals('+44 20 7031 3000',
684               phoneUtil.format(GB_NUMBER, PNF.INTERNATIONAL));
685
686  assertEquals('(07912) 345 678',
687               phoneUtil.format(GB_MOBILE, PNF.NATIONAL));
688  assertEquals('+44 7912 345 678',
689               phoneUtil.format(GB_MOBILE, PNF.INTERNATIONAL));
690}
691
692function testFormatDENumber() {
693  var PNF = i18n.phonenumbers.PhoneNumberFormat;
694  /** @type {!i18n.phonenumbers.PhoneNumber} */
695  var deNumber = new i18n.phonenumbers.PhoneNumber();
696  deNumber.setCountryCode(49);
697  deNumber.setNationalNumber(301234);
698  assertEquals('030/1234',
699               phoneUtil.format(deNumber, PNF.NATIONAL));
700  assertEquals('+49 30/1234',
701               phoneUtil.format(deNumber, PNF.INTERNATIONAL));
702  assertEquals('tel:+49-30-1234',
703               phoneUtil.format(deNumber, PNF.RFC3966));
704
705  deNumber = new i18n.phonenumbers.PhoneNumber();
706  deNumber.setCountryCode(49);
707  deNumber.setNationalNumber(291123);
708  assertEquals('0291 123',
709               phoneUtil.format(deNumber, PNF.NATIONAL));
710  assertEquals('+49 291 123',
711               phoneUtil.format(deNumber, PNF.INTERNATIONAL));
712
713  deNumber = new i18n.phonenumbers.PhoneNumber();
714  deNumber.setCountryCode(49);
715  deNumber.setNationalNumber(29112345678);
716  assertEquals('0291 12345678',
717               phoneUtil.format(deNumber, PNF.NATIONAL));
718  assertEquals('+49 291 12345678',
719               phoneUtil.format(deNumber, PNF.INTERNATIONAL));
720
721  deNumber = new i18n.phonenumbers.PhoneNumber();
722  deNumber.setCountryCode(49);
723  deNumber.setNationalNumber(912312345);
724  assertEquals('09123 12345',
725               phoneUtil.format(deNumber, PNF.NATIONAL));
726  assertEquals('+49 9123 12345',
727               phoneUtil.format(deNumber, PNF.INTERNATIONAL));
728
729  deNumber = new i18n.phonenumbers.PhoneNumber();
730  deNumber.setCountryCode(49);
731  deNumber.setNationalNumber(80212345);
732  assertEquals('08021 2345',
733               phoneUtil.format(deNumber, PNF.NATIONAL));
734  assertEquals('+49 8021 2345',
735               phoneUtil.format(deNumber, PNF.INTERNATIONAL));
736
737  // Note this number is correctly formatted without national prefix. Most of
738  // the numbers that are treated as invalid numbers by the library are short
739  // numbers, and they are usually not dialed with national prefix.
740  assertEquals('1234',
741               phoneUtil.format(DE_SHORT_NUMBER, PNF.NATIONAL));
742  assertEquals('+49 1234',
743               phoneUtil.format(DE_SHORT_NUMBER, PNF.INTERNATIONAL));
744
745  deNumber = new i18n.phonenumbers.PhoneNumber();
746  deNumber.setCountryCode(49);
747  deNumber.setNationalNumber(41341234);
748  assertEquals('04134 1234',
749               phoneUtil.format(deNumber, PNF.NATIONAL));
750}
751
752function testFormatITNumber() {
753  var PNF = i18n.phonenumbers.PhoneNumberFormat;
754  assertEquals('02 3661 8300',
755               phoneUtil.format(IT_NUMBER, PNF.NATIONAL));
756  assertEquals('+39 02 3661 8300',
757               phoneUtil.format(IT_NUMBER, PNF.INTERNATIONAL));
758  assertEquals('+390236618300',
759               phoneUtil.format(IT_NUMBER, PNF.E164));
760
761  assertEquals('345 678 901',
762               phoneUtil.format(IT_MOBILE, PNF.NATIONAL));
763  assertEquals('+39 345 678 901',
764               phoneUtil.format(IT_MOBILE, PNF.INTERNATIONAL));
765  assertEquals('+39345678901',
766               phoneUtil.format(IT_MOBILE, PNF.E164));
767}
768
769function testFormatAUNumber() {
770  var PNF = i18n.phonenumbers.PhoneNumberFormat;
771  assertEquals('02 3661 8300',
772               phoneUtil.format(AU_NUMBER, PNF.NATIONAL));
773  assertEquals('+61 2 3661 8300',
774               phoneUtil.format(AU_NUMBER, PNF.INTERNATIONAL));
775  assertEquals('+61236618300',
776               phoneUtil.format(AU_NUMBER, PNF.E164));
777
778  /** @type {!i18n.phonenumbers.PhoneNumber} */
779  var auNumber = new i18n.phonenumbers.PhoneNumber();
780  auNumber.setCountryCode(61);
781  auNumber.setNationalNumber(1800123456);
782  assertEquals('1800 123 456',
783               phoneUtil.format(auNumber, PNF.NATIONAL));
784  assertEquals('+61 1800 123 456',
785               phoneUtil.format(auNumber, PNF.INTERNATIONAL));
786  assertEquals('+611800123456',
787               phoneUtil.format(auNumber, PNF.E164));
788}
789
790function testFormatARNumber() {
791  var PNF = i18n.phonenumbers.PhoneNumberFormat;
792  assertEquals('011 8765-4321',
793               phoneUtil.format(AR_NUMBER, PNF.NATIONAL));
794  assertEquals('+54 11 8765-4321',
795               phoneUtil.format(AR_NUMBER, PNF.INTERNATIONAL));
796  assertEquals('+541187654321',
797               phoneUtil.format(AR_NUMBER, PNF.E164));
798
799  assertEquals('011 15 8765-4321',
800               phoneUtil.format(AR_MOBILE, PNF.NATIONAL));
801  assertEquals('+54 9 11 8765 4321',
802               phoneUtil.format(AR_MOBILE, PNF.INTERNATIONAL));
803  assertEquals('+5491187654321',
804               phoneUtil.format(AR_MOBILE, PNF.E164));
805}
806
807function testFormatMXNumber() {
808  var PNF = i18n.phonenumbers.PhoneNumberFormat;
809  assertEquals('045 234 567 8900',
810               phoneUtil.format(MX_MOBILE1, PNF.NATIONAL));
811  assertEquals('+52 1 234 567 8900',
812               phoneUtil.format(MX_MOBILE1, PNF.INTERNATIONAL));
813  assertEquals('+5212345678900',
814               phoneUtil.format(MX_MOBILE1, PNF.E164));
815
816  assertEquals('045 55 1234 5678',
817               phoneUtil.format(MX_MOBILE2, PNF.NATIONAL));
818  assertEquals('+52 1 55 1234 5678',
819               phoneUtil.format(MX_MOBILE2, PNF.INTERNATIONAL));
820  assertEquals('+5215512345678',
821               phoneUtil.format(MX_MOBILE2, PNF.E164));
822
823  assertEquals('01 33 1234 5678',
824               phoneUtil.format(MX_NUMBER1, PNF.NATIONAL));
825  assertEquals('+52 33 1234 5678',
826               phoneUtil.format(MX_NUMBER1, PNF.INTERNATIONAL));
827  assertEquals('+523312345678',
828               phoneUtil.format(MX_NUMBER1, PNF.E164));
829
830  assertEquals('01 821 123 4567',
831               phoneUtil.format(MX_NUMBER2, PNF.NATIONAL));
832  assertEquals('+52 821 123 4567',
833               phoneUtil.format(MX_NUMBER2, PNF.INTERNATIONAL));
834  assertEquals('+528211234567',
835               phoneUtil.format(MX_NUMBER2, PNF.E164));
836}
837
838function testFormatOutOfCountryCallingNumber() {
839  assertEquals('00 1 900 253 0000',
840      phoneUtil.formatOutOfCountryCallingNumber(US_PREMIUM, RegionCode.DE));
841
842  assertEquals('1 650 253 0000',
843      phoneUtil.formatOutOfCountryCallingNumber(US_NUMBER, RegionCode.BS));
844
845  assertEquals('00 1 650 253 0000',
846      phoneUtil.formatOutOfCountryCallingNumber(US_NUMBER, RegionCode.PL));
847
848  assertEquals('011 44 7912 345 678',
849      phoneUtil.formatOutOfCountryCallingNumber(GB_MOBILE, RegionCode.US));
850
851  assertEquals('00 49 1234',
852      phoneUtil.formatOutOfCountryCallingNumber(DE_SHORT_NUMBER,
853                                                RegionCode.GB));
854  // Note this number is correctly formatted without national prefix. Most of
855  // the numbers that are treated as invalid numbers by the library are short
856  // numbers, and they are usually not dialed with national prefix.
857  assertEquals('1234',
858      phoneUtil.formatOutOfCountryCallingNumber(DE_SHORT_NUMBER,
859                                                RegionCode.DE));
860
861  assertEquals('011 39 02 3661 8300',
862      phoneUtil.formatOutOfCountryCallingNumber(IT_NUMBER, RegionCode.US));
863  assertEquals('02 3661 8300',
864      phoneUtil.formatOutOfCountryCallingNumber(IT_NUMBER, RegionCode.IT));
865  assertEquals('+39 02 3661 8300',
866      phoneUtil.formatOutOfCountryCallingNumber(IT_NUMBER, RegionCode.SG));
867
868  assertEquals('6521 8000',
869      phoneUtil.formatOutOfCountryCallingNumber(SG_NUMBER, RegionCode.SG));
870
871  assertEquals('011 54 9 11 8765 4321',
872      phoneUtil.formatOutOfCountryCallingNumber(AR_MOBILE, RegionCode.US));
873  assertEquals('011 800 1234 5678',
874      phoneUtil.formatOutOfCountryCallingNumber(INTERNATIONAL_TOLL_FREE,
875                                                RegionCode.US));
876
877  /** @type {!i18n.phonenumbers.PhoneNumber} */
878  var arNumberWithExtn = AR_MOBILE.clone();
879  arNumberWithExtn.setExtension('1234');
880  assertEquals('011 54 9 11 8765 4321 ext. 1234',
881      phoneUtil.formatOutOfCountryCallingNumber(arNumberWithExtn,
882                                                RegionCode.US));
883  assertEquals('0011 54 9 11 8765 4321 ext. 1234',
884      phoneUtil.formatOutOfCountryCallingNumber(arNumberWithExtn,
885                                                RegionCode.AU));
886  assertEquals('011 15 8765-4321 ext. 1234',
887      phoneUtil.formatOutOfCountryCallingNumber(arNumberWithExtn,
888                                                RegionCode.AR));
889}
890
891function testFormatOutOfCountryWithInvalidRegion() {
892  // AQ/Antarctica isn't a valid region code for phone number formatting,
893  // so this falls back to intl formatting.
894  assertEquals('+1 650 253 0000',
895      phoneUtil.formatOutOfCountryCallingNumber(US_NUMBER, RegionCode.AQ));
896  // For region code 001, the out-of-country format always turns into the
897  // international format.
898  assertEquals('+1 650 253 0000',
899      phoneUtil.formatOutOfCountryCallingNumber(US_NUMBER, RegionCode.UN001));
900}
901
902function testFormatOutOfCountryWithPreferredIntlPrefix() {
903  // This should use 0011, since that is the preferred international prefix
904  // (both 0011 and 0012 are accepted as possible international prefixes in our
905  // test metadta.)
906  assertEquals('0011 39 02 3661 8300',
907               phoneUtil.formatOutOfCountryCallingNumber(IT_NUMBER,
908                                                         RegionCode.AU));
909}
910
911function testFormatOutOfCountryKeepingAlphaChars() {
912  /** @type {!i18n.phonenumbers.PhoneNumber} */
913  var alphaNumericNumber = new i18n.phonenumbers.PhoneNumber();
914  alphaNumericNumber.setCountryCode(1);
915  alphaNumericNumber.setNationalNumber(8007493524);
916  alphaNumericNumber.setRawInput('1800 six-flag');
917  assertEquals('0011 1 800 SIX-FLAG',
918      phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber,
919                                                    RegionCode.AU));
920
921  alphaNumericNumber.setRawInput('1-800-SIX-flag');
922  assertEquals('0011 1 800-SIX-FLAG',
923      phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber,
924                                                    RegionCode.AU));
925
926  alphaNumericNumber.setRawInput('Call us from UK: 00 1 800 SIX-flag');
927  assertEquals('0011 1 800 SIX-FLAG',
928      phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber,
929                                                    RegionCode.AU));
930
931  alphaNumericNumber.setRawInput('800 SIX-flag');
932  assertEquals('0011 1 800 SIX-FLAG',
933      phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber,
934                                                    RegionCode.AU));
935
936  // Formatting from within the NANPA region.
937  assertEquals('1 800 SIX-FLAG',
938      phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber,
939                                                    RegionCode.US));
940
941  assertEquals('1 800 SIX-FLAG',
942      phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber,
943                                                    RegionCode.BS));
944
945  // Testing that if the raw input doesn't exist, it is formatted using
946  // formatOutOfCountryCallingNumber.
947  alphaNumericNumber.clearRawInput();
948  assertEquals('00 1 800 749 3524',
949      phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber,
950                                                    RegionCode.DE));
951
952  // Testing AU alpha number formatted from Australia.
953  alphaNumericNumber.setCountryCode(61);
954  alphaNumericNumber.setNationalNumber(827493524);
955  alphaNumericNumber.setRawInput('+61 82749-FLAG');
956  // This number should have the national prefix fixed.
957  assertEquals('082749-FLAG',
958      phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber,
959                                                    RegionCode.AU));
960
961  alphaNumericNumber.setRawInput('082749-FLAG');
962  assertEquals('082749-FLAG',
963      phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber,
964                                                    RegionCode.AU));
965
966  alphaNumericNumber.setNationalNumber(18007493524);
967  alphaNumericNumber.setRawInput('1-800-SIX-flag');
968  // This number should not have the national prefix prefixed, in accordance
969  // with the override for this specific formatting rule.
970  assertEquals('1-800-SIX-FLAG',
971      phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber,
972                                                    RegionCode.AU));
973
974  // The metadata should not be permanently changed, since we copied it before
975  // modifying patterns. Here we check this.
976  alphaNumericNumber.setNationalNumber(1800749352);
977  assertEquals('1800 749 352',
978      phoneUtil.formatOutOfCountryCallingNumber(alphaNumericNumber,
979                                                RegionCode.AU));
980
981  // Testing a region with multiple international prefixes.
982  assertEquals('+61 1-800-SIX-FLAG',
983      phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber,
984                                                    RegionCode.SG));
985  // Testing the case of calling from a non-supported region.
986  assertEquals('+61 1-800-SIX-FLAG',
987      phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber,
988                                                    RegionCode.AQ));
989
990  // Testing the case with an invalid country calling code.
991  alphaNumericNumber.setCountryCode(0);
992  alphaNumericNumber.setNationalNumber(18007493524);
993  alphaNumericNumber.setRawInput('1-800-SIX-flag');
994  // Uses the raw input only.
995  assertEquals('1-800-SIX-flag',
996      phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber,
997                                                    RegionCode.DE));
998
999  // Testing the case of an invalid alpha number.
1000  alphaNumericNumber.setCountryCode(1);
1001  alphaNumericNumber.setNationalNumber(80749);
1002  alphaNumericNumber.setRawInput('180-SIX');
1003  // No country-code stripping can be done.
1004  assertEquals('00 1 180-SIX',
1005      phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber,
1006                                                    RegionCode.DE));
1007
1008  // Testing the case of calling from a non-supported region.
1009  alphaNumericNumber.setCountryCode(1);
1010  alphaNumericNumber.setNationalNumber(80749);
1011  alphaNumericNumber.setRawInput('180-SIX');
1012  // No country-code stripping can be done since the number is invalid.
1013  assertEquals('+1 180-SIX',
1014      phoneUtil.formatOutOfCountryKeepingAlphaChars(alphaNumericNumber,
1015                                                    RegionCode.AQ));
1016}
1017
1018function testFormatWithCarrierCode() {
1019  var PNF = i18n.phonenumbers.PhoneNumberFormat;
1020  // We only support this for AR in our test metadata, and only for mobile
1021  // numbers starting with certain values.
1022  /** @type {!i18n.phonenumbers.PhoneNumber} */
1023  var arMobile = new i18n.phonenumbers.PhoneNumber();
1024  arMobile.setCountryCode(54);
1025  arMobile.setNationalNumber(92234654321);
1026  assertEquals('02234 65-4321', phoneUtil.format(arMobile, PNF.NATIONAL));
1027  // Here we force 14 as the carrier code.
1028  assertEquals('02234 14 65-4321',
1029               phoneUtil.formatNationalNumberWithCarrierCode(arMobile, '14'));
1030  // Here we force the number to be shown with no carrier code.
1031  assertEquals('02234 65-4321',
1032               phoneUtil.formatNationalNumberWithCarrierCode(arMobile, ''));
1033  // Here the international rule is used, so no carrier code should be present.
1034  assertEquals('+5492234654321', phoneUtil.format(arMobile, PNF.E164));
1035  // We don't support this for the US so there should be no change.
1036  assertEquals('650 253 0000',
1037               phoneUtil.formatNationalNumberWithCarrierCode(US_NUMBER, '15'));
1038  // Invalid country code should just get the NSN.
1039  assertEquals('12345', phoneUtil.formatNationalNumberWithCarrierCode(
1040      UNKNOWN_COUNTRY_CODE_NO_RAW_INPUT, '89'));
1041}
1042
1043function testFormatWithPreferredCarrierCode() {
1044  var PNF = i18n.phonenumbers.PhoneNumberFormat;
1045  // We only support this for AR in our test metadata.
1046  /** @type {!i18n.phonenumbers.PhoneNumber} */
1047  var arNumber = new i18n.phonenumbers.PhoneNumber();
1048  arNumber.setCountryCode(54);
1049  arNumber.setNationalNumber(91234125678);
1050  // Test formatting with no preferred carrier code stored in the number itself.
1051  assertEquals('01234 15 12-5678',
1052      phoneUtil.formatNationalNumberWithPreferredCarrierCode(arNumber, '15'));
1053  assertEquals('01234 12-5678',
1054      phoneUtil.formatNationalNumberWithPreferredCarrierCode(arNumber, ''));
1055  // Test formatting with preferred carrier code present.
1056  arNumber.setPreferredDomesticCarrierCode('19');
1057  assertEquals('01234 12-5678', phoneUtil.format(arNumber, PNF.NATIONAL));
1058  assertEquals('01234 19 12-5678',
1059      phoneUtil.formatNationalNumberWithPreferredCarrierCode(arNumber, '15'));
1060  assertEquals('01234 19 12-5678',
1061      phoneUtil.formatNationalNumberWithPreferredCarrierCode(arNumber, ''));
1062  // When the preferred_domestic_carrier_code is present (even when it is just a
1063  // space), use it instead of the default carrier code passed in.
1064  arNumber.setPreferredDomesticCarrierCode(' ');
1065  assertEquals('01234   12-5678',
1066      phoneUtil.formatNationalNumberWithPreferredCarrierCode(arNumber, '15'));
1067  // When the preferred_domestic_carrier_code is present but empty, treat it as
1068  // unset and use instead the default carrier code passed in.
1069  arNumber.setPreferredDomesticCarrierCode('');
1070  assertEquals('01234 15 12-5678',
1071      phoneUtil.formatNationalNumberWithPreferredCarrierCode(arNumber, '15'));
1072  // We don't support this for the US so there should be no change.
1073  /** @type {!i18n.phonenumbers.PhoneNumber} */
1074  var usNumber = new i18n.phonenumbers.PhoneNumber();
1075  usNumber.setCountryCode(1);
1076  usNumber.setNationalNumber(4241231234);
1077  usNumber.setPreferredDomesticCarrierCode('99');
1078  assertEquals('424 123 1234', phoneUtil.format(usNumber, PNF.NATIONAL));
1079  assertEquals('424 123 1234',
1080      phoneUtil.formatNationalNumberWithPreferredCarrierCode(usNumber, '15'));
1081}
1082
1083function testFormatNumberForMobileDialing() {
1084  // Numbers are normally dialed in national format in-country, and
1085  // international format from outside the country.
1086  assertEquals('030123456',
1087      phoneUtil.formatNumberForMobileDialing(DE_NUMBER, RegionCode.DE, false));
1088  assertEquals('+4930123456',
1089      phoneUtil.formatNumberForMobileDialing(DE_NUMBER, RegionCode.CH, false));
1090  var deNumberWithExtn = DE_NUMBER.clone();
1091  deNumberWithExtn.setExtension('1234');
1092  assertEquals('030123456',
1093      phoneUtil.formatNumberForMobileDialing(deNumberWithExtn, RegionCode.DE,
1094                                             false));
1095  assertEquals('+4930123456',
1096      phoneUtil.formatNumberForMobileDialing(deNumberWithExtn, RegionCode.CH,
1097                                             false));
1098
1099  // US toll free numbers are marked as noInternationalDialling in the test
1100  // metadata for testing purposes. For such numbers, we expect nothing to be
1101  // returned when the region code is not the same one.
1102  assertEquals('800 253 0000',
1103      phoneUtil.formatNumberForMobileDialing(US_TOLLFREE, RegionCode.US, true));
1104  assertEquals('',
1105      phoneUtil.formatNumberForMobileDialing(US_TOLLFREE, RegionCode.CN, true));
1106  assertEquals('+1 650 253 0000',
1107      phoneUtil.formatNumberForMobileDialing(US_NUMBER, RegionCode.US, true));
1108  /** @type {!i18n.phonenumbers.PhoneNumber} */
1109  var usNumberWithExtn = US_NUMBER.clone();
1110  usNumberWithExtn.setExtension('1234');
1111  assertEquals('+1 650 253 0000',
1112      phoneUtil.formatNumberForMobileDialing(usNumberWithExtn,
1113                                             RegionCode.US, true));
1114
1115  assertEquals('8002530000',
1116      phoneUtil.formatNumberForMobileDialing(US_TOLLFREE,
1117                                             RegionCode.US, false));
1118  assertEquals('',
1119      phoneUtil.formatNumberForMobileDialing(US_TOLLFREE,
1120                                             RegionCode.CN, false));
1121  assertEquals('+16502530000',
1122      phoneUtil.formatNumberForMobileDialing(US_NUMBER, RegionCode.US, false));
1123  assertEquals('+16502530000',
1124      phoneUtil.formatNumberForMobileDialing(usNumberWithExtn,
1125                                             RegionCode.US, false));
1126
1127  // An invalid US number, which is one digit too long.
1128  assertEquals('+165025300001',
1129      phoneUtil.formatNumberForMobileDialing(US_LONG_NUMBER,
1130                                             RegionCode.US, false));
1131  assertEquals('+1 65025300001',
1132      phoneUtil.formatNumberForMobileDialing(US_LONG_NUMBER,
1133                                             RegionCode.US, true));
1134
1135  // Star numbers. In real life they appear in Israel, but we have them in JP
1136  // in our test metadata.
1137  assertEquals('*2345',
1138      phoneUtil.formatNumberForMobileDialing(JP_STAR_NUMBER,
1139                                             RegionCode.JP, false));
1140  assertEquals('*2345',
1141      phoneUtil.formatNumberForMobileDialing(JP_STAR_NUMBER,
1142                                             RegionCode.JP, true));
1143
1144  assertEquals('+80012345678',
1145      phoneUtil.formatNumberForMobileDialing(INTERNATIONAL_TOLL_FREE,
1146                                             RegionCode.JP, false));
1147  assertEquals('+800 1234 5678',
1148      phoneUtil.formatNumberForMobileDialing(INTERNATIONAL_TOLL_FREE,
1149                                             RegionCode.JP, true));
1150
1151  // UAE numbers beginning with 600 (classified as UAN) need to be dialled
1152  // without +971 locally.
1153  assertEquals('+971600123456',
1154      phoneUtil.formatNumberForMobileDialing(AE_UAN, RegionCode.JP, false));
1155  assertEquals('600123456',
1156      phoneUtil.formatNumberForMobileDialing(AE_UAN, RegionCode.AE, false));
1157
1158  assertEquals('+523312345678',
1159      phoneUtil.formatNumberForMobileDialing(MX_NUMBER1, RegionCode.MX,
1160                                             false));
1161  assertEquals('+523312345678',
1162      phoneUtil.formatNumberForMobileDialing(MX_NUMBER1, RegionCode.US,
1163                                             false));
1164
1165  // Test whether Uzbek phone numbers are returned in international format even
1166  // when dialled from same region or other regions.
1167  // Fixed-line number
1168  assertEquals('+998612201234',
1169      phoneUtil.formatNumberForMobileDialing(UZ_FIXED_LINE, RegionCode.UZ,
1170                                             false));
1171  // Mobile number
1172  assertEquals('+998950123456',
1173      phoneUtil.formatNumberForMobileDialing(UZ_MOBILE, RegionCode.UZ,
1174                                             false));
1175  assertEquals('+998950123456',
1176      phoneUtil.formatNumberForMobileDialing(UZ_MOBILE, RegionCode.US,
1177                                             false));
1178
1179  // Non-geographical numbers should always be dialed in international format.
1180  assertEquals('+80012345678',
1181      phoneUtil.formatNumberForMobileDialing(INTERNATIONAL_TOLL_FREE,
1182                                             RegionCode.US, false));
1183  assertEquals('+80012345678',
1184      phoneUtil.formatNumberForMobileDialing(INTERNATIONAL_TOLL_FREE,
1185                                             RegionCode.UN001, false));
1186
1187  // Test that a short number is formatted correctly for mobile dialing within
1188  // the region, and is not diallable from outside the region.
1189  var deShortNumber = new i18n.phonenumbers.PhoneNumber();
1190  deShortNumber.setCountryCode(49);
1191  deShortNumber.setNationalNumber(123);
1192  assertEquals('123',
1193      phoneUtil.formatNumberForMobileDialing(deShortNumber,
1194                                             RegionCode.DE, false));
1195  assertEquals('',
1196      phoneUtil.formatNumberForMobileDialing(deShortNumber,
1197                                             RegionCode.IT, false));
1198
1199  // Test the special logic for NANPA countries, for which regular length phone
1200  // numbers are always output in international format, but short numbers are in
1201  // national format.
1202  assertEquals('+16502530000',
1203      phoneUtil.formatNumberForMobileDialing(US_NUMBER,
1204          RegionCode.US, false));
1205  assertEquals('+16502530000',
1206      phoneUtil.formatNumberForMobileDialing(US_NUMBER,
1207          RegionCode.CA, false));
1208  assertEquals('+16502530000',
1209      phoneUtil.formatNumberForMobileDialing(US_NUMBER,
1210          RegionCode.BR, false));
1211  var usShortNumber = new i18n.phonenumbers.PhoneNumber();
1212  usShortNumber.setCountryCode(1);
1213  usShortNumber.setNationalNumber(911);
1214  assertEquals('911',
1215      phoneUtil.formatNumberForMobileDialing(usShortNumber,
1216          RegionCode.US, false));
1217  assertEquals('',
1218      phoneUtil.formatNumberForMobileDialing(usShortNumber,
1219          RegionCode.CA, false));
1220  assertEquals('',
1221      phoneUtil.formatNumberForMobileDialing(usShortNumber,
1222          RegionCode.BR, false));
1223
1224  // Test that the Australian emergency number 000 is formatted correctly.
1225  var auShortNumber = new i18n.phonenumbers.PhoneNumber();
1226  auShortNumber.setCountryCode(61);
1227  auShortNumber.setNationalNumber(0);
1228  auShortNumber.setItalianLeadingZero(true);
1229  auShortNumber.setNumberOfLeadingZeros(2);
1230  assertEquals('000',
1231      phoneUtil.formatNumberForMobileDialing(auShortNumber,
1232          RegionCode.AU, false));
1233  assertEquals('',
1234      phoneUtil.formatNumberForMobileDialing(auShortNumber,
1235          RegionCode.NZ, false));
1236}
1237
1238function testFormatByPattern() {
1239  var PNF = i18n.phonenumbers.PhoneNumberFormat;
1240  /** @type {!i18n.phonenumbers.NumberFormat} */
1241  var newNumFormat = new i18n.phonenumbers.NumberFormat();
1242  newNumFormat.setPattern('(\\d{3})(\\d{3})(\\d{4})');
1243  newNumFormat.setFormat('($1) $2-$3');
1244
1245  assertEquals('(650) 253-0000',
1246               phoneUtil.formatByPattern(US_NUMBER,
1247                                         PNF.NATIONAL,
1248                                         [newNumFormat]));
1249  assertEquals('+1 (650) 253-0000',
1250               phoneUtil.formatByPattern(US_NUMBER,
1251                                         PNF.INTERNATIONAL,
1252                                         [newNumFormat]));
1253  assertEquals('tel:+1-650-253-0000',
1254               phoneUtil.formatByPattern(US_NUMBER,
1255                                         PNF.RFC3966,
1256                                         [newNumFormat]));
1257
1258  // $NP is set to '1' for the US. Here we check that for other NANPA countries
1259  // the US rules are followed.
1260  newNumFormat.setNationalPrefixFormattingRule('$NP ($FG)');
1261  newNumFormat.setFormat('$1 $2-$3');
1262  assertEquals('1 (242) 365-1234',
1263               phoneUtil.formatByPattern(BS_NUMBER,
1264                                         PNF.NATIONAL,
1265                                         [newNumFormat]));
1266  assertEquals('+1 242 365-1234',
1267               phoneUtil.formatByPattern(BS_NUMBER,
1268                                         PNF.INTERNATIONAL,
1269                                         [newNumFormat]));
1270
1271  newNumFormat.setPattern('(\\d{2})(\\d{5})(\\d{3})');
1272  newNumFormat.setFormat('$1-$2 $3');
1273
1274  assertEquals('02-36618 300',
1275               phoneUtil.formatByPattern(IT_NUMBER,
1276                                         PNF.NATIONAL,
1277                                         [newNumFormat]));
1278  assertEquals('+39 02-36618 300',
1279               phoneUtil.formatByPattern(IT_NUMBER,
1280                                         PNF.INTERNATIONAL,
1281                                         [newNumFormat]));
1282
1283  newNumFormat.setNationalPrefixFormattingRule('$NP$FG');
1284  newNumFormat.setPattern('(\\d{2})(\\d{4})(\\d{4})');
1285  newNumFormat.setFormat('$1 $2 $3');
1286  assertEquals('020 7031 3000',
1287               phoneUtil.formatByPattern(GB_NUMBER,
1288                                         PNF.NATIONAL,
1289                                         [newNumFormat]));
1290
1291  newNumFormat.setNationalPrefixFormattingRule('($NP$FG)');
1292  assertEquals('(020) 7031 3000',
1293               phoneUtil.formatByPattern(GB_NUMBER,
1294                                         PNF.NATIONAL,
1295                                         [newNumFormat]));
1296
1297  newNumFormat.setNationalPrefixFormattingRule('');
1298  assertEquals('20 7031 3000',
1299               phoneUtil.formatByPattern(GB_NUMBER,
1300                                         PNF.NATIONAL,
1301                                         [newNumFormat]));
1302
1303  assertEquals('+44 20 7031 3000',
1304               phoneUtil.formatByPattern(GB_NUMBER,
1305                                         PNF.INTERNATIONAL,
1306                                         [newNumFormat]));
1307}
1308
1309function testFormatE164Number() {
1310  var PNF = i18n.phonenumbers.PhoneNumberFormat;
1311  assertEquals('+16502530000', phoneUtil.format(US_NUMBER, PNF.E164));
1312  assertEquals('+4930123456', phoneUtil.format(DE_NUMBER, PNF.E164));
1313  assertEquals('+80012345678',
1314      phoneUtil.format(INTERNATIONAL_TOLL_FREE, PNF.E164));
1315}
1316
1317function testFormatNumberWithExtension() {
1318  var PNF = i18n.phonenumbers.PhoneNumberFormat;
1319  /** @type {!i18n.phonenumbers.PhoneNumber} */
1320  var nzNumber = NZ_NUMBER.clone();
1321  nzNumber.setExtension('1234');
1322  // Uses default extension prefix:
1323  assertEquals('03-331 6005 ext. 1234',
1324               phoneUtil.format(nzNumber, PNF.NATIONAL));
1325  // Uses RFC 3966 syntax.
1326  assertEquals('tel:+64-3-331-6005;ext=1234',
1327               phoneUtil.format(nzNumber, PNF.RFC3966));
1328  // Extension prefix overridden in the territory information for the US:
1329  /** @type {!i18n.phonenumbers.PhoneNumber} */
1330  var usNumberWithExtension = US_NUMBER.clone();
1331  usNumberWithExtension.setExtension('4567');
1332  assertEquals('650 253 0000 extn. 4567',
1333               phoneUtil.format(usNumberWithExtension, PNF.NATIONAL));
1334}
1335
1336function testFormatInOriginalFormat() {
1337  /** @type {!i18n.phonenumbers.PhoneNumber} */
1338  var number1 = phoneUtil.parseAndKeepRawInput('+442087654321', RegionCode.GB);
1339  assertEquals('+44 20 8765 4321',
1340      phoneUtil.formatInOriginalFormat(number1, RegionCode.GB));
1341
1342  /** @type {!i18n.phonenumbers.PhoneNumber} */
1343  var number2 = phoneUtil.parseAndKeepRawInput('02087654321', RegionCode.GB);
1344  assertEquals('(020) 8765 4321',
1345      phoneUtil.formatInOriginalFormat(number2, RegionCode.GB));
1346
1347  /** @type {!i18n.phonenumbers.PhoneNumber} */
1348  var number3 = phoneUtil.parseAndKeepRawInput('011442087654321',
1349                                               RegionCode.US);
1350  assertEquals('011 44 20 8765 4321',
1351      phoneUtil.formatInOriginalFormat(number3, RegionCode.US));
1352
1353  /** @type {!i18n.phonenumbers.PhoneNumber} */
1354  var number4 = phoneUtil.parseAndKeepRawInput('442087654321', RegionCode.GB);
1355  assertEquals('44 20 8765 4321',
1356      phoneUtil.formatInOriginalFormat(number4, RegionCode.GB));
1357
1358  /** @type {!i18n.phonenumbers.PhoneNumber} */
1359  var number5 = phoneUtil.parse('+442087654321', RegionCode.GB);
1360  assertEquals('(020) 8765 4321',
1361      phoneUtil.formatInOriginalFormat(number5, RegionCode.GB));
1362
1363  // Invalid numbers that we have a formatting pattern for should be formatted
1364  // properly. Note area codes starting with 7 are intentionally excluded in
1365  // the test metadata for testing purposes.
1366  /** @type {!i18n.phonenumbers.PhoneNumber} */
1367  var number6 = phoneUtil.parseAndKeepRawInput('7345678901', RegionCode.US);
1368  assertEquals('734 567 8901',
1369      phoneUtil.formatInOriginalFormat(number6, RegionCode.US));
1370
1371  // US is not a leading zero country, and the presence of the leading zero
1372  // leads us to format the number using raw_input.
1373  /** @type {!i18n.phonenumbers.PhoneNumber} */
1374  var number7 = phoneUtil.parseAndKeepRawInput('0734567 8901', RegionCode.US);
1375  assertEquals('0734567 8901',
1376      phoneUtil.formatInOriginalFormat(number7, RegionCode.US));
1377
1378  // This number is valid, but we don't have a formatting pattern for it.
1379  // Fall back to the raw input.
1380  /** @type {!i18n.phonenumbers.PhoneNumber} */
1381  var number8 = phoneUtil.parseAndKeepRawInput('02-4567-8900', RegionCode.KR);
1382  assertEquals('02-4567-8900',
1383      phoneUtil.formatInOriginalFormat(number8, RegionCode.KR));
1384
1385  /** @type {!i18n.phonenumbers.PhoneNumber} */
1386  var number9 = phoneUtil.parseAndKeepRawInput('01180012345678', RegionCode.US);
1387  assertEquals('011 800 1234 5678',
1388      phoneUtil.formatInOriginalFormat(number9, RegionCode.US));
1389
1390  /** @type {!i18n.phonenumbers.PhoneNumber} */
1391  var number10 = phoneUtil.parseAndKeepRawInput('+80012345678', RegionCode.KR);
1392  assertEquals('+800 1234 5678',
1393      phoneUtil.formatInOriginalFormat(number10, RegionCode.KR));
1394
1395  // US local numbers are formatted correctly, as we have formatting patterns
1396  // for them.
1397  /** @type {!i18n.phonenumbers.PhoneNumber} */
1398  var localNumberUS = phoneUtil.parseAndKeepRawInput('2530000', RegionCode.US);
1399  assertEquals('253 0000',
1400      phoneUtil.formatInOriginalFormat(localNumberUS, RegionCode.US));
1401
1402  /** @type {!i18n.phonenumbers.PhoneNumber} */
1403  var numberWithNationalPrefixUS =
1404      phoneUtil.parseAndKeepRawInput('18003456789', RegionCode.US);
1405  assertEquals('1 800 345 6789',
1406      phoneUtil.formatInOriginalFormat(numberWithNationalPrefixUS,
1407                                       RegionCode.US));
1408
1409  /** @type {!i18n.phonenumbers.PhoneNumber} */
1410  var numberWithoutNationalPrefixGB =
1411      phoneUtil.parseAndKeepRawInput('2087654321', RegionCode.GB);
1412  assertEquals('20 8765 4321',
1413      phoneUtil.formatInOriginalFormat(numberWithoutNationalPrefixGB,
1414                                       RegionCode.GB));
1415  // Make sure no metadata is modified as a result of the previous function
1416  // call.
1417  assertEquals('(020) 8765 4321',
1418      phoneUtil.formatInOriginalFormat(number5, RegionCode.GB));
1419
1420  /** @type {!i18n.phonenumbers.PhoneNumber} */
1421  var numberWithNationalPrefixMX =
1422      phoneUtil.parseAndKeepRawInput('013312345678', RegionCode.MX);
1423  assertEquals('01 33 1234 5678',
1424      phoneUtil.formatInOriginalFormat(numberWithNationalPrefixMX,
1425                                       RegionCode.MX));
1426
1427  /** @type {!i18n.phonenumbers.PhoneNumber} */
1428  var numberWithoutNationalPrefixMX =
1429      phoneUtil.parseAndKeepRawInput('3312345678', RegionCode.MX);
1430  assertEquals('33 1234 5678',
1431      phoneUtil.formatInOriginalFormat(numberWithoutNationalPrefixMX,
1432                                       RegionCode.MX));
1433
1434  /** @type {!i18n.phonenumbers.PhoneNumber} */
1435  var italianFixedLineNumber =
1436      phoneUtil.parseAndKeepRawInput('0212345678', RegionCode.IT);
1437  assertEquals('02 1234 5678',
1438      phoneUtil.formatInOriginalFormat(italianFixedLineNumber, RegionCode.IT));
1439
1440  /** @type {!i18n.phonenumbers.PhoneNumber} */
1441  var numberWithNationalPrefixJP =
1442      phoneUtil.parseAndKeepRawInput('00777012', RegionCode.JP);
1443  assertEquals('0077-7012',
1444      phoneUtil.formatInOriginalFormat(numberWithNationalPrefixJP,
1445                                       RegionCode.JP));
1446
1447  /** @type {!i18n.phonenumbers.PhoneNumber} */
1448  var numberWithoutNationalPrefixJP =
1449      phoneUtil.parseAndKeepRawInput('0777012', RegionCode.JP);
1450  assertEquals('0777012',
1451      phoneUtil.formatInOriginalFormat(numberWithoutNationalPrefixJP,
1452                                       RegionCode.JP));
1453
1454  /** @type {!i18n.phonenumbers.PhoneNumber} */
1455  var numberWithCarrierCodeBR =
1456      phoneUtil.parseAndKeepRawInput('012 3121286979', RegionCode.BR);
1457  assertEquals('012 3121286979',
1458      phoneUtil.formatInOriginalFormat(numberWithCarrierCodeBR, RegionCode.BR));
1459
1460  // The default national prefix used in this case is 045. When a number with
1461  // national prefix 044 is entered, we return the raw input as we don't want to
1462  // change the number entered.
1463  /** @type {!i18n.phonenumbers.PhoneNumber} */
1464  var numberWithNationalPrefixMX1 =
1465      phoneUtil.parseAndKeepRawInput('044(33)1234-5678', RegionCode.MX);
1466  assertEquals('044(33)1234-5678',
1467      phoneUtil.formatInOriginalFormat(numberWithNationalPrefixMX1,
1468                                       RegionCode.MX));
1469
1470  /** @type {!i18n.phonenumbers.PhoneNumber} */
1471  var numberWithNationalPrefixMX2 =
1472      phoneUtil.parseAndKeepRawInput('045(33)1234-5678', RegionCode.MX);
1473  assertEquals('045 33 1234 5678',
1474      phoneUtil.formatInOriginalFormat(numberWithNationalPrefixMX2,
1475                                       RegionCode.MX));
1476
1477  // The default international prefix used in this case is 0011. When a number
1478  // with international prefix 0012 is entered, we return the raw input as we
1479  // don't want to change the number entered.
1480  /** @type {!i18n.phonenumbers.PhoneNumber} */
1481  var outOfCountryNumberFromAU1 =
1482      phoneUtil.parseAndKeepRawInput('0012 16502530000', RegionCode.AU);
1483  assertEquals('0012 16502530000',
1484      phoneUtil.formatInOriginalFormat(outOfCountryNumberFromAU1,
1485                                       RegionCode.AU));
1486
1487  /** @type {!i18n.phonenumbers.PhoneNumber} */
1488  var outOfCountryNumberFromAU2 =
1489      phoneUtil.parseAndKeepRawInput('0011 16502530000', RegionCode.AU);
1490  assertEquals('0011 1 650 253 0000',
1491      phoneUtil.formatInOriginalFormat(outOfCountryNumberFromAU2,
1492                                       RegionCode.AU));
1493
1494  // Test the star sign is not removed from or added to the original input by
1495  // this method.
1496  /** @type {!i18n.phonenumbers.PhoneNumber} */
1497  var starNumber =
1498      phoneUtil.parseAndKeepRawInput('*1234', RegionCode.JP);
1499  assertEquals('*1234', phoneUtil.formatInOriginalFormat(starNumber,
1500                                                         RegionCode.JP));
1501  /** @type {!i18n.phonenumbers.PhoneNumber} */
1502  var numberWithoutStar = phoneUtil.parseAndKeepRawInput('1234', RegionCode.JP);
1503  assertEquals('1234', phoneUtil.formatInOriginalFormat(numberWithoutStar,
1504                                                        RegionCode.JP));
1505
1506  // Test an invalid national number without raw input is just formatted as the
1507  // national number.
1508  assertEquals('650253000',
1509      phoneUtil.formatInOriginalFormat(US_SHORT_BY_ONE_NUMBER, RegionCode.US));
1510}
1511
1512function testIsPremiumRate() {
1513  var PNT = i18n.phonenumbers.PhoneNumberType;
1514  assertEquals(PNT.PREMIUM_RATE, phoneUtil.getNumberType(US_PREMIUM));
1515
1516  /** @type {!i18n.phonenumbers.PhoneNumber} */
1517  var premiumRateNumber = new i18n.phonenumbers.PhoneNumber();
1518  premiumRateNumber.setCountryCode(39);
1519  premiumRateNumber.setNationalNumber(892123);
1520  assertEquals(PNT.PREMIUM_RATE, phoneUtil.getNumberType(premiumRateNumber));
1521
1522  premiumRateNumber = new i18n.phonenumbers.PhoneNumber();
1523  premiumRateNumber.setCountryCode(44);
1524  premiumRateNumber.setNationalNumber(9187654321);
1525  assertEquals(PNT.PREMIUM_RATE, phoneUtil.getNumberType(premiumRateNumber));
1526
1527  premiumRateNumber = new i18n.phonenumbers.PhoneNumber();
1528  premiumRateNumber.setCountryCode(49);
1529  premiumRateNumber.setNationalNumber(9001654321);
1530  assertEquals(PNT.PREMIUM_RATE, phoneUtil.getNumberType(premiumRateNumber));
1531
1532  premiumRateNumber = new i18n.phonenumbers.PhoneNumber();
1533  premiumRateNumber.setCountryCode(49);
1534  premiumRateNumber.setNationalNumber(90091234567);
1535  assertEquals(PNT.PREMIUM_RATE, phoneUtil.getNumberType(premiumRateNumber));
1536  assertEquals(PNT.PREMIUM_RATE, phoneUtil.getNumberType(
1537      UNIVERSAL_PREMIUM_RATE));
1538}
1539
1540function testIsTollFree() {
1541  var PNT = i18n.phonenumbers.PhoneNumberType;
1542  /** @type {!i18n.phonenumbers.PhoneNumber} */
1543  var tollFreeNumber = new i18n.phonenumbers.PhoneNumber();
1544
1545  tollFreeNumber.setCountryCode(1);
1546  tollFreeNumber.setNationalNumber(8881234567);
1547  assertEquals(PNT.TOLL_FREE, phoneUtil.getNumberType(tollFreeNumber));
1548
1549  tollFreeNumber = new i18n.phonenumbers.PhoneNumber();
1550  tollFreeNumber.setCountryCode(39);
1551  tollFreeNumber.setNationalNumber(803123);
1552  assertEquals(PNT.TOLL_FREE, phoneUtil.getNumberType(tollFreeNumber));
1553
1554  tollFreeNumber = new i18n.phonenumbers.PhoneNumber();
1555  tollFreeNumber.setCountryCode(44);
1556  tollFreeNumber.setNationalNumber(8012345678);
1557  assertEquals(PNT.TOLL_FREE, phoneUtil.getNumberType(tollFreeNumber));
1558
1559  tollFreeNumber = new i18n.phonenumbers.PhoneNumber();
1560  tollFreeNumber.setCountryCode(49);
1561  tollFreeNumber.setNationalNumber(8001234567);
1562  assertEquals(PNT.TOLL_FREE, phoneUtil.getNumberType(tollFreeNumber));
1563
1564  assertEquals(PNT.TOLL_FREE, phoneUtil.getNumberType(INTERNATIONAL_TOLL_FREE));
1565}
1566
1567function testIsMobile() {
1568  var PNT = i18n.phonenumbers.PhoneNumberType;
1569  assertEquals(PNT.MOBILE, phoneUtil.getNumberType(BS_MOBILE));
1570  assertEquals(PNT.MOBILE, phoneUtil.getNumberType(GB_MOBILE));
1571  assertEquals(PNT.MOBILE, phoneUtil.getNumberType(IT_MOBILE));
1572  assertEquals(PNT.MOBILE, phoneUtil.getNumberType(AR_MOBILE));
1573
1574  /** @type {!i18n.phonenumbers.PhoneNumber} */
1575  var mobileNumber = new i18n.phonenumbers.PhoneNumber();
1576  mobileNumber.setCountryCode(49);
1577  mobileNumber.setNationalNumber(15123456789);
1578  assertEquals(PNT.MOBILE, phoneUtil.getNumberType(mobileNumber));
1579}
1580
1581function testIsFixedLine() {
1582  var PNT = i18n.phonenumbers.PhoneNumberType;
1583  assertEquals(PNT.FIXED_LINE, phoneUtil.getNumberType(BS_NUMBER));
1584  assertEquals(PNT.FIXED_LINE, phoneUtil.getNumberType(IT_NUMBER));
1585  assertEquals(PNT.FIXED_LINE, phoneUtil.getNumberType(GB_NUMBER));
1586  assertEquals(PNT.FIXED_LINE, phoneUtil.getNumberType(DE_NUMBER));
1587}
1588
1589function testIsFixedLineAndMobile() {
1590  var PNT = i18n.phonenumbers.PhoneNumberType;
1591  assertEquals(PNT.FIXED_LINE_OR_MOBILE,
1592               phoneUtil.getNumberType(US_NUMBER));
1593
1594  /** @type {!i18n.phonenumbers.PhoneNumber} */
1595  var fixedLineAndMobileNumber = new i18n.phonenumbers.PhoneNumber();
1596  fixedLineAndMobileNumber.setCountryCode(54);
1597  fixedLineAndMobileNumber.setNationalNumber(1987654321);
1598  assertEquals(PNT.FIXED_LINE_OR_MOBILE,
1599               phoneUtil.getNumberType(fixedLineAndMobileNumber));
1600}
1601
1602function testIsSharedCost() {
1603  var PNT = i18n.phonenumbers.PhoneNumberType;
1604  /** @type {!i18n.phonenumbers.PhoneNumber} */
1605  var gbNumber = new i18n.phonenumbers.PhoneNumber();
1606  gbNumber.setCountryCode(44);
1607  gbNumber.setNationalNumber(8431231234);
1608  assertEquals(PNT.SHARED_COST, phoneUtil.getNumberType(gbNumber));
1609}
1610
1611function testIsVoip() {
1612  var PNT = i18n.phonenumbers.PhoneNumberType;
1613  /** @type {!i18n.phonenumbers.PhoneNumber} */
1614  var gbNumber = new i18n.phonenumbers.PhoneNumber();
1615  gbNumber.setCountryCode(44);
1616  gbNumber.setNationalNumber(5631231234);
1617  assertEquals(PNT.VOIP, phoneUtil.getNumberType(gbNumber));
1618}
1619
1620function testIsPersonalNumber() {
1621  var PNT = i18n.phonenumbers.PhoneNumberType;
1622  /** @type {!i18n.phonenumbers.PhoneNumber} */
1623  var gbNumber = new i18n.phonenumbers.PhoneNumber();
1624  gbNumber.setCountryCode(44);
1625  gbNumber.setNationalNumber(7031231234);
1626  assertEquals(PNT.PERSONAL_NUMBER, phoneUtil.getNumberType(gbNumber));
1627}
1628
1629function testIsUnknown() {
1630  var PNT = i18n.phonenumbers.PhoneNumberType;
1631  // Invalid numbers should be of type UNKNOWN.
1632  assertEquals(PNT.UNKNOWN, phoneUtil.getNumberType(US_LOCAL_NUMBER));
1633}
1634
1635function testIsValidNumber() {
1636  assertTrue(phoneUtil.isValidNumber(US_NUMBER));
1637  assertTrue(phoneUtil.isValidNumber(IT_NUMBER));
1638  assertTrue(phoneUtil.isValidNumber(GB_MOBILE));
1639  assertTrue(phoneUtil.isValidNumber(INTERNATIONAL_TOLL_FREE));
1640  assertTrue(phoneUtil.isValidNumber(UNIVERSAL_PREMIUM_RATE));
1641
1642  /** @type {!i18n.phonenumbers.PhoneNumber} */
1643  var nzNumber = new i18n.phonenumbers.PhoneNumber();
1644  nzNumber.setCountryCode(64);
1645  nzNumber.setNationalNumber(21387835);
1646  assertTrue(phoneUtil.isValidNumber(nzNumber));
1647}
1648
1649function testIsValidForRegion() {
1650  // This number is valid for the Bahamas, but is not a valid US number.
1651  assertTrue(phoneUtil.isValidNumber(BS_NUMBER));
1652  assertTrue(phoneUtil.isValidNumberForRegion(BS_NUMBER, RegionCode.BS));
1653  assertFalse(phoneUtil.isValidNumberForRegion(BS_NUMBER, RegionCode.US));
1654  /** @type {!i18n.phonenumbers.PhoneNumber} */
1655  var bsInvalidNumber = new i18n.phonenumbers.PhoneNumber();
1656  bsInvalidNumber.setCountryCode(1);
1657  bsInvalidNumber.setNationalNumber(2421232345);
1658  // This number is no longer valid.
1659  assertFalse(phoneUtil.isValidNumber(bsInvalidNumber));
1660
1661  // La Mayotte and Reunion use 'leadingDigits' to differentiate them.
1662  /** @type {!i18n.phonenumbers.PhoneNumber} */
1663  var reNumber = new i18n.phonenumbers.PhoneNumber();
1664  reNumber.setCountryCode(262);
1665  reNumber.setNationalNumber(262123456);
1666  assertTrue(phoneUtil.isValidNumber(reNumber));
1667  assertTrue(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.RE));
1668  assertFalse(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.YT));
1669  // Now change the number to be a number for La Mayotte.
1670  reNumber.setNationalNumber(269601234);
1671  assertTrue(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.YT));
1672  assertFalse(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.RE));
1673  // This number is no longer valid for La Reunion.
1674  reNumber.setNationalNumber(269123456);
1675  assertFalse(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.YT));
1676  assertFalse(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.RE));
1677  assertFalse(phoneUtil.isValidNumber(reNumber));
1678  // However, it should be recognised as from La Mayotte, since it is valid for
1679  // this region.
1680  assertEquals(RegionCode.YT, phoneUtil.getRegionCodeForNumber(reNumber));
1681  // This number is valid in both places.
1682  reNumber.setNationalNumber(800123456);
1683  assertTrue(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.YT));
1684  assertTrue(phoneUtil.isValidNumberForRegion(reNumber, RegionCode.RE));
1685  assertTrue(phoneUtil.isValidNumberForRegion(INTERNATIONAL_TOLL_FREE,
1686                                              RegionCode.UN001));
1687  assertFalse(phoneUtil.isValidNumberForRegion(INTERNATIONAL_TOLL_FREE,
1688                                               RegionCode.US));
1689  assertFalse(phoneUtil.isValidNumberForRegion(INTERNATIONAL_TOLL_FREE,
1690                                               RegionCode.ZZ));
1691
1692  /** @type {!i18n.phonenumbers.PhoneNumber} */
1693  var invalidNumber = new i18n.phonenumbers.PhoneNumber();
1694  // Invalid country calling codes.
1695  invalidNumber.setCountryCode(3923);
1696  invalidNumber.setNationalNumber(2366);
1697  assertFalse(phoneUtil.isValidNumberForRegion(invalidNumber, RegionCode.ZZ));
1698  assertFalse(phoneUtil.isValidNumberForRegion(invalidNumber,
1699                                               RegionCode.UN001));
1700  invalidNumber.setCountryCode(0);
1701  assertFalse(phoneUtil.isValidNumberForRegion(invalidNumber,
1702                                               RegionCode.UN001));
1703  assertFalse(phoneUtil.isValidNumberForRegion(invalidNumber, RegionCode.ZZ));
1704}
1705
1706function testIsNotValidNumber() {
1707  assertFalse(phoneUtil.isValidNumber(US_LOCAL_NUMBER));
1708
1709  /** @type {!i18n.phonenumbers.PhoneNumber} */
1710  var invalidNumber = new i18n.phonenumbers.PhoneNumber();
1711  invalidNumber.setCountryCode(39);
1712  invalidNumber.setNationalNumber(23661830000);
1713  invalidNumber.setItalianLeadingZero(true);
1714  assertFalse(phoneUtil.isValidNumber(invalidNumber));
1715
1716  invalidNumber = new i18n.phonenumbers.PhoneNumber();
1717  invalidNumber.setCountryCode(44);
1718  invalidNumber.setNationalNumber(791234567);
1719  assertFalse(phoneUtil.isValidNumber(invalidNumber));
1720
1721  invalidNumber = new i18n.phonenumbers.PhoneNumber();
1722  invalidNumber.setCountryCode(49);
1723  invalidNumber.setNationalNumber(1234);
1724  assertFalse(phoneUtil.isValidNumber(invalidNumber));
1725
1726  invalidNumber = new i18n.phonenumbers.PhoneNumber();
1727  invalidNumber.setCountryCode(64);
1728  invalidNumber.setNationalNumber(3316005);
1729  assertFalse(phoneUtil.isValidNumber(invalidNumber));
1730
1731  invalidNumber = new i18n.phonenumbers.PhoneNumber();
1732  // Invalid country calling codes.
1733  invalidNumber.setCountryCode(3923);
1734  invalidNumber.setNationalNumber(2366);
1735  assertFalse(phoneUtil.isValidNumber(invalidNumber));
1736  invalidNumber.setCountryCode(0);
1737  assertFalse(phoneUtil.isValidNumber(invalidNumber));
1738
1739  assertFalse(phoneUtil.isValidNumber(INTERNATIONAL_TOLL_FREE_TOO_LONG));
1740}
1741
1742function testGetRegionCodeForCountryCode() {
1743  assertEquals(RegionCode.US, phoneUtil.getRegionCodeForCountryCode(1));
1744  assertEquals(RegionCode.GB, phoneUtil.getRegionCodeForCountryCode(44));
1745  assertEquals(RegionCode.DE, phoneUtil.getRegionCodeForCountryCode(49));
1746  assertEquals(RegionCode.UN001, phoneUtil.getRegionCodeForCountryCode(800));
1747  assertEquals(RegionCode.UN001, phoneUtil.getRegionCodeForCountryCode(979));
1748}
1749
1750function testGetRegionCodeForNumber() {
1751  assertEquals(RegionCode.BS, phoneUtil.getRegionCodeForNumber(BS_NUMBER));
1752  assertEquals(RegionCode.US, phoneUtil.getRegionCodeForNumber(US_NUMBER));
1753  assertEquals(RegionCode.GB, phoneUtil.getRegionCodeForNumber(GB_MOBILE));
1754  assertEquals(RegionCode.UN001,
1755      phoneUtil.getRegionCodeForNumber(INTERNATIONAL_TOLL_FREE));
1756  assertEquals(RegionCode.UN001,
1757      phoneUtil.getRegionCodeForNumber(UNIVERSAL_PREMIUM_RATE));
1758}
1759
1760function testGetRegionCodesForCountryCode() {
1761  /** @type {!Array.<string>} */
1762  var regionCodesForNANPA = phoneUtil.getRegionCodesForCountryCode(1);
1763  assertTrue(goog.array.contains(regionCodesForNANPA, RegionCode.US));
1764  assertTrue(goog.array.contains(regionCodesForNANPA, RegionCode.BS));
1765  assertTrue(goog.array.contains(
1766      phoneUtil.getRegionCodesForCountryCode(44), RegionCode.GB));
1767  assertTrue(goog.array.contains(
1768      phoneUtil.getRegionCodesForCountryCode(49), RegionCode.DE));
1769  assertTrue(goog.array.contains(
1770      phoneUtil.getRegionCodesForCountryCode(800), RegionCode.UN001));
1771  // Test with invalid country calling code.
1772  assertTrue(goog.array.isEmpty(phoneUtil.getRegionCodesForCountryCode(-1)));
1773}
1774
1775function testGetCountryCodeForRegion() {
1776  assertEquals(1, phoneUtil.getCountryCodeForRegion(RegionCode.US));
1777  assertEquals(64, phoneUtil.getCountryCodeForRegion(RegionCode.NZ));
1778  assertEquals(0, phoneUtil.getCountryCodeForRegion(null));
1779  assertEquals(0, phoneUtil.getCountryCodeForRegion(RegionCode.ZZ));
1780  assertEquals(0, phoneUtil.getCountryCodeForRegion(RegionCode.UN001));
1781  // CS is already deprecated so the library doesn't support it.
1782  assertEquals(0, phoneUtil.getCountryCodeForRegion(RegionCode.CS));
1783}
1784
1785function testGetNationalDiallingPrefixForRegion() {
1786  assertEquals('1', phoneUtil.getNddPrefixForRegion(RegionCode.US, false));
1787  // Test non-main country to see it gets the national dialling prefix for the
1788  // main country with that country calling code.
1789  assertEquals('1', phoneUtil.getNddPrefixForRegion(RegionCode.BS, false));
1790  assertEquals('0', phoneUtil.getNddPrefixForRegion(RegionCode.NZ, false));
1791  // Test case with non digit in the national prefix.
1792  assertEquals('0~0', phoneUtil.getNddPrefixForRegion(RegionCode.AO, false));
1793  assertEquals('00', phoneUtil.getNddPrefixForRegion(RegionCode.AO, true));
1794  // Test cases with invalid regions.
1795  assertNull(phoneUtil.getNddPrefixForRegion(null, false));
1796  assertNull(phoneUtil.getNddPrefixForRegion(RegionCode.ZZ, false));
1797  assertNull(phoneUtil.getNddPrefixForRegion(RegionCode.UN001, false));
1798  // CS is already deprecated so the library doesn't support it.
1799  assertNull(phoneUtil.getNddPrefixForRegion(RegionCode.CS, false));
1800}
1801
1802function testIsNANPACountry() {
1803  assertTrue(phoneUtil.isNANPACountry(RegionCode.US));
1804  assertTrue(phoneUtil.isNANPACountry(RegionCode.BS));
1805  assertFalse(phoneUtil.isNANPACountry(RegionCode.DE));
1806  assertFalse(phoneUtil.isNANPACountry(RegionCode.ZZ));
1807  assertFalse(phoneUtil.isNANPACountry(RegionCode.UN001));
1808  assertFalse(phoneUtil.isNANPACountry(null));
1809}
1810
1811function testIsPossibleNumber() {
1812  assertTrue(phoneUtil.isPossibleNumber(US_NUMBER));
1813  assertTrue(phoneUtil.isPossibleNumber(US_LOCAL_NUMBER));
1814  assertTrue(phoneUtil.isPossibleNumber(GB_NUMBER));
1815  assertTrue(phoneUtil.isPossibleNumber(INTERNATIONAL_TOLL_FREE));
1816
1817  assertTrue(
1818      phoneUtil.isPossibleNumberString('+1 650 253 0000', RegionCode.US));
1819  assertTrue(
1820      phoneUtil.isPossibleNumberString('+1 650 GOO OGLE', RegionCode.US));
1821  assertTrue(
1822      phoneUtil.isPossibleNumberString('(650) 253-0000', RegionCode.US));
1823  assertTrue(
1824      phoneUtil.isPossibleNumberString('253-0000', RegionCode.US));
1825  assertTrue(
1826      phoneUtil.isPossibleNumberString('+1 650 253 0000', RegionCode.GB));
1827  assertTrue(
1828      phoneUtil.isPossibleNumberString('+44 20 7031 3000', RegionCode.GB));
1829  assertTrue(
1830      phoneUtil.isPossibleNumberString('(020) 7031 3000', RegionCode.GB));
1831  assertTrue(
1832      phoneUtil.isPossibleNumberString('7031 3000', RegionCode.GB));
1833  assertTrue(
1834      phoneUtil.isPossibleNumberString('3331 6005', RegionCode.NZ));
1835  assertTrue(
1836      phoneUtil.isPossibleNumberString('+800 1234 5678', RegionCode.UN001));
1837}
1838
1839function testIsPossibleNumberForType_DifferentTypeLengths() {
1840  var PNT = i18n.phonenumbers.PhoneNumberType;
1841  // We use Argentinian numbers since they have different possible lengths for
1842  // different types.
1843  /** @type {!i18n.phonenumbers.PhoneNumber} */
1844  var number = new i18n.phonenumbers.PhoneNumber();
1845  number.setCountryCode(54);
1846  number.setNationalNumber(12345);
1847  // Too short for any Argentinian number, including fixed-line.
1848  assertFalse(phoneUtil.isPossibleNumberForType(number, PNT.FIXED_LINE));
1849  assertFalse(phoneUtil.isPossibleNumberForType(number, PNT.UNKNOWN));
1850
1851  // 6-digit numbers are okay for fixed-line.
1852  number.setNationalNumber(123456);
1853  assertTrue(phoneUtil.isPossibleNumberForType(number, PNT.UNKNOWN));
1854  assertTrue(phoneUtil.isPossibleNumberForType(number, PNT.FIXED_LINE));
1855  // But too short for mobile.
1856  assertFalse(phoneUtil.isPossibleNumberForType(number, PNT.MOBILE));
1857  // And too short for toll-free.
1858  assertFalse(phoneUtil.isPossibleNumberForType(number, PNT.TOLL_FREE));
1859
1860  // The same applies to 9-digit numbers.
1861  number.setNationalNumber(123456789);
1862  assertTrue(phoneUtil.isPossibleNumberForType(number, PNT.UNKNOWN));
1863  assertTrue(phoneUtil.isPossibleNumberForType(number, PNT.FIXED_LINE));
1864  assertFalse(phoneUtil.isPossibleNumberForType(number, PNT.MOBILE));
1865  assertFalse(phoneUtil.isPossibleNumberForType(number, PNT.TOLL_FREE));
1866
1867  // 10-digit numbers are universally possible.
1868  number.setNationalNumber(1234567890);
1869  assertTrue(phoneUtil.isPossibleNumberForType(number, PNT.UNKNOWN));
1870  assertTrue(phoneUtil.isPossibleNumberForType(number, PNT.FIXED_LINE));
1871  assertTrue(phoneUtil.isPossibleNumberForType(number, PNT.MOBILE));
1872  assertTrue(phoneUtil.isPossibleNumberForType(number, PNT.TOLL_FREE));
1873
1874  // 11-digit numbers are only possible for mobile numbers. Note we don't
1875  // require the leading 9, which all mobile numbers start with, and would be
1876  // required for a valid mobile number.
1877  number.setNationalNumber(12345678901);
1878  assertTrue(phoneUtil.isPossibleNumberForType(number, PNT.UNKNOWN));
1879  assertFalse(phoneUtil.isPossibleNumberForType(number, PNT.FIXED_LINE));
1880  assertTrue(phoneUtil.isPossibleNumberForType(number, PNT.MOBILE));
1881  assertFalse(phoneUtil.isPossibleNumberForType(number, PNT.TOLL_FREE));
1882}
1883
1884function testIsPossibleNumberForType_LocalOnly() {
1885  var PNT = i18n.phonenumbers.PhoneNumberType;
1886  /** @type {!i18n.phonenumbers.PhoneNumber} */
1887  var number = new i18n.phonenumbers.PhoneNumber();
1888  // Here we test a number length which matches a local-only length.
1889  number.setCountryCode(49);
1890  number.setNationalNumber(12);
1891  assertTrue(phoneUtil.isPossibleNumberForType(number, PNT.UNKNOWN));
1892  assertTrue(phoneUtil.isPossibleNumberForType(number, PNT.FIXED_LINE));
1893  // Mobile numbers must be 10 or 11 digits, and there are no local-only
1894  // lengths.
1895  assertFalse(phoneUtil.isPossibleNumberForType(number, PNT.MOBILE));
1896}
1897
1898function testIsPossibleNumberForType_DataMissingForSizeReasons() {
1899  var PNT = i18n.phonenumbers.PhoneNumberType;
1900  /** @type {!i18n.phonenumbers.PhoneNumber} */
1901  var number = new i18n.phonenumbers.PhoneNumber();
1902  // Here we test something where the possible lengths match the possible
1903  // lengths of the country as a whole, and hence aren't present in the .js file
1904  // for size reasons - this should still work.
1905  // Local-only number.
1906  number.setCountryCode(55);
1907  number.setNationalNumber(12345678);
1908  assertTrue(phoneUtil.isPossibleNumberForType(number, PNT.UNKNOWN));
1909  assertTrue(phoneUtil.isPossibleNumberForType(number, PNT.FIXED_LINE));
1910  number.setNationalNumber(1234567890);
1911  assertTrue(phoneUtil.isPossibleNumberForType(number, PNT.UNKNOWN));
1912  assertTrue(phoneUtil.isPossibleNumberForType(number, PNT.FIXED_LINE));
1913}
1914
1915function testIsPossibleNumberForType_NumberTypeNotSupportedForRegion() {
1916  var PNT = i18n.phonenumbers.PhoneNumberType;
1917  /** @type {!i18n.phonenumbers.PhoneNumber} */
1918  var number = new i18n.phonenumbers.PhoneNumber();
1919  // There are *no* mobile numbers for this region at all, so we return false.
1920  number.setCountryCode(55);
1921  number.setNationalNumber(12345678);
1922  assertFalse(phoneUtil.isPossibleNumberForType(number, PNT.MOBILE));
1923  // This matches a fixed-line length though.
1924  assertTrue(phoneUtil.isPossibleNumberForType(number, PNT.FIXED_LINE));
1925  assertTrue(
1926      phoneUtil.isPossibleNumberForType(number, PNT.FIXED_LINE_OR_MOBILE));
1927
1928  // There are *no* fixed-line OR mobile numbers for this country calling code
1929  // at all, so we return false for these.
1930  number.setCountryCode(979);
1931  number.setNationalNumber(123456789);
1932  assertFalse(phoneUtil.isPossibleNumberForType(number, PNT.MOBILE));
1933  assertFalse(phoneUtil.isPossibleNumberForType(number, PNT.FIXED_LINE));
1934  assertFalse(phoneUtil.isPossibleNumberForType(
1935      number, PNT.FIXED_LINE_OR_MOBILE));
1936  assertTrue(phoneUtil.isPossibleNumberForType(number, PNT.PREMIUM_RATE));
1937}
1938
1939function testIsPossibleNumberWithReason() {
1940  var VR = i18n.phonenumbers.PhoneNumberUtil.ValidationResult;
1941  // National numbers for country calling code +1 that are within 7 to 10 digits
1942  // are possible.
1943  assertEquals(VR.IS_POSSIBLE,
1944      phoneUtil.isPossibleNumberWithReason(US_NUMBER));
1945
1946  assertEquals(VR.IS_POSSIBLE_LOCAL_ONLY,
1947      phoneUtil.isPossibleNumberWithReason(US_LOCAL_NUMBER));
1948
1949  assertEquals(VR.TOO_LONG,
1950      phoneUtil.isPossibleNumberWithReason(US_LONG_NUMBER));
1951
1952  /** @type {!i18n.phonenumbers.PhoneNumber} */
1953  var number = new i18n.phonenumbers.PhoneNumber();
1954  number.setCountryCode(0);
1955  number.setNationalNumber(2530000);
1956  assertEquals(VR.INVALID_COUNTRY_CODE,
1957      phoneUtil.isPossibleNumberWithReason(number));
1958
1959  number = new i18n.phonenumbers.PhoneNumber();
1960  number.setCountryCode(1);
1961  number.setNationalNumber(253000);
1962  assertEquals(VR.TOO_SHORT,
1963      phoneUtil.isPossibleNumberWithReason(number));
1964
1965  number = new i18n.phonenumbers.PhoneNumber();
1966  number.setCountryCode(65);
1967  number.setNationalNumber(1234567890);
1968  assertEquals(VR.IS_POSSIBLE,
1969      phoneUtil.isPossibleNumberWithReason(number));
1970
1971  assertEquals(VR.TOO_LONG,
1972      phoneUtil.isPossibleNumberWithReason(INTERNATIONAL_TOLL_FREE_TOO_LONG));
1973}
1974
1975function testIsPossibleNumberForTypeWithReason_DifferentTypeLengths() {
1976  var VR = i18n.phonenumbers.PhoneNumberUtil.ValidationResult;
1977  var PNT = i18n.phonenumbers.PhoneNumberType;
1978  /** @type {!i18n.phonenumbers.PhoneNumber} */
1979  var number = new i18n.phonenumbers.PhoneNumber();
1980  // We use Argentinian numbers since they have different possible lengths for
1981  // different types.
1982  number.setCountryCode(54);
1983  number.setNationalNumber(12345);
1984  // Too short for any Argentinian number.
1985  assertEquals(
1986      VR.TOO_SHORT,
1987      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.UNKNOWN));
1988  assertEquals(
1989      VR.TOO_SHORT,
1990      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.FIXED_LINE));
1991
1992  // 6-digit numbers are okay for fixed-line.
1993  number.setNationalNumber(123456);
1994  assertEquals(
1995      VR.IS_POSSIBLE,
1996      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.UNKNOWN));
1997  assertEquals(
1998      VR.IS_POSSIBLE,
1999      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.FIXED_LINE));
2000  // But too short for mobile.
2001  assertEquals(
2002      VR.TOO_SHORT,
2003      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.MOBILE));
2004  // And too short for toll-free.
2005  assertEquals(
2006      VR.TOO_SHORT,
2007      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.TOLL_FREE));
2008
2009  // The same applies to 9-digit numbers.
2010  number.setNationalNumber(123456789);
2011  assertEquals(
2012      VR.IS_POSSIBLE,
2013      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.UNKNOWN));
2014  assertEquals(
2015      VR.IS_POSSIBLE,
2016      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.FIXED_LINE));
2017  assertEquals(
2018      VR.TOO_SHORT,
2019      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.MOBILE));
2020  assertEquals(
2021      VR.TOO_SHORT,
2022      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.TOLL_FREE));
2023
2024  // 10-digit numbers are universally possible.
2025  number.setNationalNumber(1234567890);
2026  assertEquals(
2027      VR.IS_POSSIBLE,
2028      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.UNKNOWN));
2029  assertEquals(
2030      VR.IS_POSSIBLE,
2031      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.FIXED_LINE));
2032  assertEquals(
2033      VR.IS_POSSIBLE,
2034      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.MOBILE));
2035  assertEquals(
2036      VR.IS_POSSIBLE,
2037      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.TOLL_FREE));
2038
2039  // 11-digit numbers are only possible for mobile numbers. Note we don't
2040  // require the leading 9, which all mobile numbers start with, and would be
2041  // required for a valid mobile number.
2042  number.setNationalNumber(12345678901);
2043  assertEquals(
2044      VR.IS_POSSIBLE,
2045      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.UNKNOWN));
2046  assertEquals(
2047      VR.TOO_LONG,
2048      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.FIXED_LINE));
2049  assertEquals(
2050      VR.IS_POSSIBLE,
2051      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.MOBILE));
2052  assertEquals(
2053      VR.TOO_LONG,
2054      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.TOLL_FREE));
2055}
2056
2057function testIsPossibleNumberForTypeWithReason_LocalOnly() {
2058  var VR = i18n.phonenumbers.PhoneNumberUtil.ValidationResult;
2059  var PNT = i18n.phonenumbers.PhoneNumberType;
2060  /** @type {!i18n.phonenumbers.PhoneNumber} */
2061  var number = new i18n.phonenumbers.PhoneNumber();
2062  // Here we test a number length which matches a local-only length.
2063  number.setCountryCode(49);
2064  number.setNationalNumber(12);
2065  assertEquals(VR.IS_POSSIBLE_LOCAL_ONLY,
2066      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.UNKNOWN));
2067  assertEquals(VR.IS_POSSIBLE_LOCAL_ONLY,
2068      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.FIXED_LINE));
2069  // Mobile numbers must be 10 or 11 digits, and there are no local-only
2070  // lengths.
2071  assertEquals(VR.TOO_SHORT,
2072      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.MOBILE));
2073}
2074
2075function testIsPossibleNumberForTypeWithReason_DataMissingForSizeReasons() {
2076  var VR = i18n.phonenumbers.PhoneNumberUtil.ValidationResult;
2077  var PNT = i18n.phonenumbers.PhoneNumberType;
2078  /** @type {!i18n.phonenumbers.PhoneNumber} */
2079  var number = new i18n.phonenumbers.PhoneNumber();
2080  // Here we test something where the possible lengths match the possible
2081  // lengths of the country as a whole, and hence aren't present in the binary
2082  // for size reasons - this should still work.
2083  // Local-only number.
2084  number.setCountryCode(55);
2085  number.setNationalNumber(12345678);
2086  assertEquals(
2087      VR.IS_POSSIBLE_LOCAL_ONLY,
2088      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.UNKNOWN));
2089  assertEquals(
2090      VR.IS_POSSIBLE_LOCAL_ONLY,
2091      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.FIXED_LINE));
2092
2093  // Normal-length number.
2094  number.setNationalNumber(1234567890);
2095  assertEquals(
2096      VR.IS_POSSIBLE,
2097      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.UNKNOWN));
2098  assertEquals(
2099      VR.IS_POSSIBLE,
2100      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.FIXED_LINE));
2101}
2102
2103function testIsPossibleNumberForTypeWithReason_NumberTypeNotSupportedForRegion() {
2104  var VR = i18n.phonenumbers.PhoneNumberUtil.ValidationResult;
2105  var PNT = i18n.phonenumbers.PhoneNumberType;
2106  /** @type {!i18n.phonenumbers.PhoneNumber} */
2107  var number = new i18n.phonenumbers.PhoneNumber();
2108  // There are *no* mobile numbers for this region at all, so we return
2109  // INVALID_LENGTH.
2110  number.setCountryCode(55);
2111  number.setNationalNumber(12345678);
2112  assertEquals(
2113      VR.INVALID_LENGTH,
2114      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.MOBILE));
2115  // This matches a fixed-line length though.
2116  assertEquals(
2117      VR.IS_POSSIBLE_LOCAL_ONLY,
2118      phoneUtil.isPossibleNumberForTypeWithReason(
2119          number, PNT.FIXED_LINE_OR_MOBILE));
2120  // This is too short for fixed-line, and no mobile numbers exist.
2121  number.setCountryCode(55);
2122  number.setNationalNumber(1234567);
2123  assertEquals(
2124      VR.INVALID_LENGTH,
2125      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.MOBILE));
2126  assertEquals(
2127      VR.TOO_SHORT,
2128      phoneUtil.isPossibleNumberForTypeWithReason(
2129          number, PNT.FIXED_LINE_OR_MOBILE));
2130  assertEquals(
2131      VR.TOO_SHORT,
2132      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.FIXED_LINE));
2133
2134  // This is too short for mobile, and no fixed-line numbers exist.
2135  number.setCountryCode(882);
2136  number.setNationalNumber(1234567);
2137  assertEquals(
2138      VR.TOO_SHORT,
2139      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.MOBILE));
2140  assertEquals(
2141      VR.TOO_SHORT,
2142      phoneUtil.isPossibleNumberForTypeWithReason(
2143          number, PNT.FIXED_LINE_OR_MOBILE));
2144  assertEquals(
2145      VR.INVALID_LENGTH,
2146      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.FIXED_LINE));
2147
2148  // There are *no* fixed-line OR mobile numbers for this country calling code
2149  // at all, so we return INVALID_LENGTH.
2150  number.setCountryCode(979);
2151  number.setNationalNumber(123456789);
2152  assertEquals(
2153      VR.INVALID_LENGTH,
2154      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.MOBILE));
2155  assertEquals(
2156      VR.INVALID_LENGTH,
2157      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.FIXED_LINE));
2158  assertEquals(
2159      VR.INVALID_LENGTH,
2160      phoneUtil.isPossibleNumberForTypeWithReason(
2161          number, PNT.FIXED_LINE_OR_MOBILE));
2162  assertEquals(
2163      VR.IS_POSSIBLE,
2164      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.PREMIUM_RATE));
2165}
2166
2167function testIsPossibleNumberForTypeWithReason_FixedLineOrMobile() {
2168  var VR = i18n.phonenumbers.PhoneNumberUtil.ValidationResult;
2169  var PNT = i18n.phonenumbers.PhoneNumberType;
2170  /** @type {!i18n.phonenumbers.PhoneNumber} */
2171  var number = new i18n.phonenumbers.PhoneNumber();
2172  // For FIXED_LINE_OR_MOBILE, a number should be considered valid if it matches
2173  // the possible lengths for mobile *or* fixed-line numbers.
2174  number.setCountryCode(290);
2175  number.setNationalNumber(1234);
2176  assertEquals(
2177      VR.TOO_SHORT,
2178      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.FIXED_LINE));
2179  assertEquals(
2180      VR.IS_POSSIBLE,
2181      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.MOBILE));
2182  assertEquals(
2183      VR.IS_POSSIBLE,
2184      phoneUtil.isPossibleNumberForTypeWithReason(
2185          number, PNT.FIXED_LINE_OR_MOBILE));
2186
2187  number.setNationalNumber(12345);
2188  assertEquals(
2189      VR.TOO_SHORT,
2190      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.FIXED_LINE));
2191  assertEquals(
2192      VR.TOO_LONG,
2193      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.MOBILE));
2194  assertEquals(
2195      VR.INVALID_LENGTH,
2196      phoneUtil.isPossibleNumberForTypeWithReason(
2197          number, PNT.FIXED_LINE_OR_MOBILE));
2198
2199  number.setNationalNumber(123456);
2200  assertEquals(
2201      VR.IS_POSSIBLE,
2202      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.FIXED_LINE));
2203  assertEquals(
2204      VR.TOO_LONG,
2205      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.MOBILE));
2206  assertEquals(
2207      VR.IS_POSSIBLE,
2208      phoneUtil.isPossibleNumberForTypeWithReason(
2209          number, PNT.FIXED_LINE_OR_MOBILE));
2210
2211  number.setNationalNumber(1234567);
2212  assertEquals(
2213      VR.TOO_LONG,
2214      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.FIXED_LINE));
2215  assertEquals(
2216      VR.TOO_LONG,
2217      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.MOBILE));
2218  assertEquals(
2219      VR.TOO_LONG,
2220      phoneUtil.isPossibleNumberForTypeWithReason(
2221          number, PNT.FIXED_LINE_OR_MOBILE));
2222
2223  // 8-digit numbers are possible for toll-free and premium-rate numbers only.
2224  number.setNationalNumber(12345678);
2225  assertEquals(
2226      VR.IS_POSSIBLE,
2227      phoneUtil.isPossibleNumberForTypeWithReason(number, PNT.TOLL_FREE));
2228  assertEquals(
2229      VR.TOO_LONG,
2230      phoneUtil.isPossibleNumberForTypeWithReason(
2231          number, PNT.FIXED_LINE_OR_MOBILE));
2232}
2233
2234function testIsNotPossibleNumber() {
2235  assertFalse(phoneUtil.isPossibleNumber(US_LONG_NUMBER));
2236  assertFalse(phoneUtil.isPossibleNumber(INTERNATIONAL_TOLL_FREE_TOO_LONG));
2237
2238  /** @type {!i18n.phonenumbers.PhoneNumber} */
2239  var number = new i18n.phonenumbers.PhoneNumber();
2240  number.setCountryCode(1);
2241  number.setNationalNumber(253000);
2242  assertFalse(phoneUtil.isPossibleNumber(number));
2243
2244  number = new i18n.phonenumbers.PhoneNumber();
2245  number.setCountryCode(44);
2246  number.setNationalNumber(300);
2247  assertFalse(phoneUtil.isPossibleNumber(number));
2248  assertFalse(
2249      phoneUtil.isPossibleNumberString('+1 650 253 00000', RegionCode.US));
2250  assertFalse(
2251      phoneUtil.isPossibleNumberString('(650) 253-00000', RegionCode.US));
2252  assertFalse(
2253      phoneUtil.isPossibleNumberString('I want a Pizza', RegionCode.US));
2254  assertFalse(phoneUtil.isPossibleNumberString('253-000', RegionCode.US));
2255  assertFalse(phoneUtil.isPossibleNumberString('1 3000', RegionCode.GB));
2256  assertFalse(phoneUtil.isPossibleNumberString('+44 300', RegionCode.GB));
2257  assertFalse(
2258      phoneUtil.isPossibleNumberString('+800 1234 5678 9', RegionCode.UN001));
2259}
2260
2261function testTruncateTooLongNumber() {
2262  // GB number 080 1234 5678, but entered with 4 extra digits at the end.
2263  /** @type {!i18n.phonenumbers.PhoneNumber} */
2264  var tooLongNumber = new i18n.phonenumbers.PhoneNumber();
2265  tooLongNumber.setCountryCode(44);
2266  tooLongNumber.setNationalNumber(80123456780123);
2267  /** @type {!i18n.phonenumbers.PhoneNumber} */
2268  var validNumber = new i18n.phonenumbers.PhoneNumber();
2269  validNumber.setCountryCode(44);
2270  validNumber.setNationalNumber(8012345678);
2271  assertTrue(phoneUtil.truncateTooLongNumber(tooLongNumber));
2272  assertTrue(validNumber.equals(tooLongNumber));
2273
2274  // IT number 022 3456 7890, but entered with 3 extra digits at the end.
2275  tooLongNumber = new i18n.phonenumbers.PhoneNumber();
2276  tooLongNumber.setCountryCode(39);
2277  tooLongNumber.setNationalNumber(2234567890123);
2278  tooLongNumber.setItalianLeadingZero(true);
2279  validNumber = new i18n.phonenumbers.PhoneNumber();
2280  validNumber.setCountryCode(39);
2281  validNumber.setNationalNumber(2234567890);
2282  validNumber.setItalianLeadingZero(true);
2283  assertTrue(phoneUtil.truncateTooLongNumber(tooLongNumber));
2284  assertTrue(validNumber.equals(tooLongNumber));
2285
2286  // US number 650-253-0000, but entered with one additional digit at the end.
2287  tooLongNumber = US_LONG_NUMBER.clone();
2288  assertTrue(phoneUtil.truncateTooLongNumber(tooLongNumber));
2289  assertTrue(US_NUMBER.equals(tooLongNumber));
2290
2291  tooLongNumber = INTERNATIONAL_TOLL_FREE_TOO_LONG.clone();
2292  assertTrue(phoneUtil.truncateTooLongNumber(tooLongNumber));
2293  assertTrue(INTERNATIONAL_TOLL_FREE.equals(tooLongNumber));
2294
2295  // Tests what happens when a valid number is passed in.
2296  /** @type {!i18n.phonenumbers.PhoneNumber} */
2297  var validNumberCopy = validNumber.clone();
2298  assertTrue(phoneUtil.truncateTooLongNumber(validNumber));
2299  // Tests the number is not modified.
2300  assertTrue(validNumber.equals(validNumberCopy));
2301
2302  // Tests what happens when a number with invalid prefix is passed in.
2303  /** @type {!i18n.phonenumbers.PhoneNumber} */
2304  var numberWithInvalidPrefix = new i18n.phonenumbers.PhoneNumber();
2305  // The test metadata says US numbers cannot have prefix 240.
2306  numberWithInvalidPrefix.setCountryCode(1);
2307  numberWithInvalidPrefix.setNationalNumber(2401234567);
2308  /** @type {!i18n.phonenumbers.PhoneNumber} */
2309  var invalidNumberCopy = numberWithInvalidPrefix.clone();
2310  assertFalse(phoneUtil.truncateTooLongNumber(numberWithInvalidPrefix));
2311  // Tests the number is not modified.
2312  assertTrue(numberWithInvalidPrefix.equals(invalidNumberCopy));
2313
2314  // Tests what happens when a too short number is passed in.
2315  /** @type {!i18n.phonenumbers.PhoneNumber} */
2316  var tooShortNumber = new i18n.phonenumbers.PhoneNumber();
2317  tooShortNumber.setCountryCode(1);
2318  tooShortNumber.setNationalNumber(1234);
2319  /** @type {!i18n.phonenumbers.PhoneNumber} */
2320  var tooShortNumberCopy = tooShortNumber.clone();
2321  assertFalse(phoneUtil.truncateTooLongNumber(tooShortNumber));
2322  // Tests the number is not modified.
2323  assertTrue(tooShortNumber.equals(tooShortNumberCopy));
2324}
2325
2326function testIsViablePhoneNumber() {
2327  var isViable = i18n.phonenumbers.PhoneNumberUtil.isViablePhoneNumber;
2328  assertFalse(isViable('1'));
2329  // Only one or two digits before strange non-possible punctuation.
2330  assertFalse(isViable('1+1+1'));
2331  assertFalse(isViable('80+0'));
2332  // Two digits is viable.
2333  assertTrue(isViable('00'));
2334  assertTrue(isViable('111'));
2335  // Alpha numbers.
2336  assertTrue(isViable('0800-4-pizza'));
2337  assertTrue(isViable('0800-4-PIZZA'));
2338  // We need at least three digits before any alpha characters.
2339  assertFalse(isViable('08-PIZZA'));
2340  assertFalse(isViable('8-PIZZA'));
2341  assertFalse(isViable('12. March'));
2342}
2343
2344function testIsViablePhoneNumberNonAscii() {
2345  var isViable = i18n.phonenumbers.PhoneNumberUtil.isViablePhoneNumber;
2346  // Only one or two digits before possible punctuation followed by more digits.
2347  assertTrue(isViable('1\u300034'));
2348  assertFalse(isViable('1\u30003+4'));
2349  // Unicode variants of possible starting character and other allowed
2350  // punctuation/digits.
2351  assertTrue(isViable('\uFF081\uFF09\u30003456789'));
2352  // Testing a leading + is okay.
2353  assertTrue(isViable('+1\uFF09\u30003456789'));
2354}
2355
2356function testExtractPossibleNumber() {
2357  var extract = i18n.phonenumbers.PhoneNumberUtil.extractPossibleNumber;
2358  // Removes preceding funky punctuation and letters but leaves the rest
2359  // untouched.
2360  assertEquals('0800-345-600', extract('Tel:0800-345-600'));
2361  assertEquals('0800 FOR PIZZA', extract('Tel:0800 FOR PIZZA'));
2362  // Should not remove plus sign
2363  assertEquals('+800-345-600', extract('Tel:+800-345-600'));
2364  // Should recognise wide digits as possible start values.
2365  assertEquals('\uFF10\uFF12\uFF13', extract('\uFF10\uFF12\uFF13'));
2366  // Dashes are not possible start values and should be removed.
2367  assertEquals('\uFF11\uFF12\uFF13', extract('Num-\uFF11\uFF12\uFF13'));
2368  // If not possible number present, return empty string.
2369  assertEquals('', extract('Num-....'));
2370  // Leading brackets are stripped - these are not used when parsing.
2371  assertEquals('650) 253-0000', extract('(650) 253-0000'));
2372
2373  // Trailing non-alpha-numeric characters should be removed.
2374  assertEquals('650) 253-0000', extract('(650) 253-0000..- ..'));
2375  assertEquals('650) 253-0000', extract('(650) 253-0000.'));
2376  // This case has a trailing RTL char.
2377  assertEquals('650) 253-0000', extract('(650) 253-0000\u200F'));
2378}
2379
2380function testMaybeStripNationalPrefix() {
2381  /** @type {!i18n.phonenumbers.PhoneMetadata} */
2382  var metadata = new i18n.phonenumbers.PhoneMetadata();
2383  metadata.setNationalPrefixForParsing('34');
2384  /** @type {!i18n.phonenumbers.PhoneNumberDesc} */
2385  var generalDesc = new i18n.phonenumbers.PhoneNumberDesc();
2386  generalDesc.setNationalNumberPattern('\\d{4,8}');
2387  metadata.setGeneralDesc(generalDesc);
2388  /** @type {!goog.string.StringBuffer} */
2389  var numberToStrip = new goog.string.StringBuffer('34356778');
2390  /** @type {string} */
2391  var strippedNumber = '356778';
2392  assertTrue(phoneUtil.maybeStripNationalPrefixAndCarrierCode(
2393      numberToStrip, metadata, null));
2394  assertEquals('Should have had national prefix stripped.',
2395               strippedNumber, numberToStrip.toString());
2396  // Retry stripping - now the number should not start with the national prefix,
2397  // so no more stripping should occur.
2398  assertFalse(phoneUtil.maybeStripNationalPrefixAndCarrierCode(
2399      numberToStrip, metadata, null));
2400  assertEquals('Should have had no change - no national prefix present.',
2401               strippedNumber, numberToStrip.toString());
2402  // Some countries have no national prefix. Repeat test with none specified.
2403  metadata.setNationalPrefixForParsing('');
2404  assertFalse(phoneUtil.maybeStripNationalPrefixAndCarrierCode(
2405      numberToStrip, metadata, null));
2406  assertEquals('Should not strip anything with empty national prefix.',
2407               strippedNumber, numberToStrip.toString());
2408  // If the resultant number doesn't match the national rule, it shouldn't be
2409  // stripped.
2410  metadata.setNationalPrefixForParsing('3');
2411  numberToStrip = new goog.string.StringBuffer('3123');
2412  strippedNumber = '3123';
2413  assertFalse(phoneUtil.maybeStripNationalPrefixAndCarrierCode(
2414      numberToStrip, metadata, null));
2415  assertEquals('Should have had no change - after stripping, it would not ' +
2416               'have matched the national rule.',
2417               strippedNumber, numberToStrip.toString());
2418  // Test extracting carrier selection code.
2419  metadata.setNationalPrefixForParsing('0(81)?');
2420  numberToStrip = new goog.string.StringBuffer('08122123456');
2421  strippedNumber = '22123456';
2422  /** @type {!goog.string.StringBuffer} */
2423  var carrierCode = new goog.string.StringBuffer();
2424  assertTrue(phoneUtil.maybeStripNationalPrefixAndCarrierCode(
2425      numberToStrip, metadata, carrierCode));
2426  assertEquals('81', carrierCode.toString());
2427  assertEquals('Should have had national prefix and carrier code stripped.',
2428               strippedNumber, numberToStrip.toString());
2429  // If there was a transform rule, check it was applied.
2430  metadata.setNationalPrefixTransformRule('5$15');
2431  // Note that a capturing group is present here.
2432  metadata.setNationalPrefixForParsing('0(\\d{2})');
2433  numberToStrip = new goog.string.StringBuffer('031123');
2434  /** @type {string} */
2435  var transformedNumber = '5315123';
2436  assertTrue(phoneUtil.maybeStripNationalPrefixAndCarrierCode(
2437      numberToStrip, metadata, null));
2438  assertEquals('Should transform the 031 to a 5315.',
2439               transformedNumber, numberToStrip.toString());
2440}
2441
2442function testMaybeStripInternationalPrefix() {
2443  var CCS = i18n.phonenumbers.PhoneNumber.CountryCodeSource;
2444  /** @type {string} */
2445  var internationalPrefix = '00[39]';
2446  /** @type {!goog.string.StringBuffer} */
2447  var numberToStrip = new goog.string.StringBuffer('0034567700-3898003');
2448  // Note the dash is removed as part of the normalization.
2449  /** @type {!goog.string.StringBuffer} */
2450  var strippedNumber = new goog.string.StringBuffer('45677003898003');
2451  assertEquals(CCS.FROM_NUMBER_WITH_IDD,
2452      phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
2453                                                          internationalPrefix));
2454  assertEquals('The number supplied was not stripped of its international ' +
2455               'prefix.',
2456               strippedNumber.toString(), numberToStrip.toString());
2457  // Now the number no longer starts with an IDD prefix, so it should now report
2458  // FROM_DEFAULT_COUNTRY.
2459  assertEquals(CCS.FROM_DEFAULT_COUNTRY,
2460      phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
2461                                                          internationalPrefix));
2462
2463  numberToStrip = new goog.string.StringBuffer('00945677003898003');
2464  assertEquals(CCS.FROM_NUMBER_WITH_IDD,
2465      phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
2466                                                          internationalPrefix));
2467  assertEquals('The number supplied was not stripped of its international ' +
2468               'prefix.',
2469               strippedNumber.toString(), numberToStrip.toString());
2470  // Test it works when the international prefix is broken up by spaces.
2471  numberToStrip = new goog.string.StringBuffer('00 9 45677003898003');
2472  assertEquals(CCS.FROM_NUMBER_WITH_IDD,
2473      phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
2474                                                          internationalPrefix));
2475  assertEquals('The number supplied was not stripped of its international ' +
2476               'prefix.',
2477               strippedNumber.toString(), numberToStrip.toString());
2478  // Now the number no longer starts with an IDD prefix, so it should now report
2479  // FROM_DEFAULT_COUNTRY.
2480  assertEquals(CCS.FROM_DEFAULT_COUNTRY,
2481      phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
2482                                                          internationalPrefix));
2483
2484  // Test the + symbol is also recognised and stripped.
2485  numberToStrip = new goog.string.StringBuffer('+45677003898003');
2486  strippedNumber = new goog.string.StringBuffer('45677003898003');
2487  assertEquals(CCS.FROM_NUMBER_WITH_PLUS_SIGN,
2488      phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
2489                                                          internationalPrefix));
2490  assertEquals('The number supplied was not stripped of the plus symbol.',
2491               strippedNumber.toString(), numberToStrip.toString());
2492
2493  // If the number afterwards is a zero, we should not strip this - no country
2494  // calling code begins with 0.
2495  numberToStrip = new goog.string.StringBuffer('0090112-3123');
2496  strippedNumber = new goog.string.StringBuffer('00901123123');
2497  assertEquals(CCS.FROM_DEFAULT_COUNTRY,
2498      phoneUtil.maybeStripInternationalPrefixAndNormalize(
2499          numberToStrip, internationalPrefix));
2500  assertEquals('The number supplied had a 0 after the match so should not be ' +
2501               'stripped.',
2502               strippedNumber.toString(), numberToStrip.toString());
2503  // Here the 0 is separated by a space from the IDD.
2504  numberToStrip = new goog.string.StringBuffer('009 0-112-3123');
2505  assertEquals(CCS.FROM_DEFAULT_COUNTRY,
2506      phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
2507                                                          internationalPrefix));
2508}
2509
2510function testMaybeExtractCountryCode() {
2511  var CCS = i18n.phonenumbers.PhoneNumber.CountryCodeSource;
2512  /** @type {!i18n.phonenumbers.PhoneNumber} */
2513  var number = new i18n.phonenumbers.PhoneNumber();
2514  /** @type {i18n.phonenumbers.PhoneMetadata} */
2515  var metadata = phoneUtil.getMetadataForRegion(RegionCode.US);
2516  // Note that for the US, the IDD is 011.
2517  try {
2518    /** @type {string} */
2519    var phoneNumber = '011112-3456789';
2520    /** @type {string} */
2521    var strippedNumber = '123456789';
2522    /** @type {number} */
2523    var countryCallingCode = 1;
2524    /** @type {!goog.string.StringBuffer} */
2525    var numberToFill = new goog.string.StringBuffer();
2526    assertEquals('Did not extract country calling code ' + countryCallingCode +
2527                 ' correctly.',
2528                 countryCallingCode,
2529                 phoneUtil.maybeExtractCountryCode(phoneNumber, metadata,
2530                                                   numberToFill, true, number));
2531    assertEquals('Did not figure out CountryCodeSource correctly',
2532                 CCS.FROM_NUMBER_WITH_IDD,
2533                 number.getCountryCodeSource());
2534    // Should strip and normalize national significant number.
2535    assertEquals('Did not strip off the country calling code correctly.',
2536                 strippedNumber,
2537                 numberToFill.toString());
2538  } catch (e) {
2539    fail('Should not have thrown an exception: ' + e.toString());
2540  }
2541  number = new i18n.phonenumbers.PhoneNumber();
2542  try {
2543    phoneNumber = '+6423456789';
2544    countryCallingCode = 64;
2545    numberToFill = new goog.string.StringBuffer();
2546    assertEquals('Did not extract country calling code ' + countryCallingCode +
2547                 ' correctly.',
2548                 countryCallingCode,
2549                 phoneUtil.maybeExtractCountryCode(phoneNumber, metadata,
2550                                                   numberToFill, true, number));
2551    assertEquals('Did not figure out CountryCodeSource correctly',
2552                 CCS.FROM_NUMBER_WITH_PLUS_SIGN,
2553                 number.getCountryCodeSource());
2554  } catch (e) {
2555    fail('Should not have thrown an exception: ' + e.toString());
2556  }
2557  number = new i18n.phonenumbers.PhoneNumber();
2558  try {
2559    phoneNumber = '+80012345678';
2560    countryCallingCode = 800;
2561    numberToFill = new goog.string.StringBuffer();
2562    assertEquals('Did not extract country calling code ' + countryCallingCode +
2563                 ' correctly.',
2564                 countryCallingCode,
2565                 phoneUtil.maybeExtractCountryCode(phoneNumber, metadata,
2566                                                   numberToFill, true, number));
2567    assertEquals('Did not figure out CountryCodeSource correctly',
2568                 CCS.FROM_NUMBER_WITH_PLUS_SIGN,
2569                 number.getCountryCodeSource());
2570  } catch (e) {
2571    fail('Should not have thrown an exception: ' + e.toString());
2572  }
2573  number = new i18n.phonenumbers.PhoneNumber();
2574  try {
2575    phoneNumber = '2345-6789';
2576    numberToFill = new goog.string.StringBuffer();
2577    assertEquals('Should not have extracted a country calling code - ' +
2578                 'no international prefix present.',
2579                 0,
2580                 phoneUtil.maybeExtractCountryCode(phoneNumber, metadata,
2581                                                   numberToFill, true, number));
2582    assertEquals('Did not figure out CountryCodeSource correctly',
2583                 CCS.FROM_DEFAULT_COUNTRY,
2584                 number.getCountryCodeSource());
2585  } catch (e) {
2586    fail('Should not have thrown an exception: ' + e.toString());
2587  }
2588  number = new i18n.phonenumbers.PhoneNumber();
2589  try {
2590    phoneNumber = '0119991123456789';
2591    numberToFill = new goog.string.StringBuffer();
2592    phoneUtil.maybeExtractCountryCode(phoneNumber, metadata,
2593                                      numberToFill, true, number);
2594    fail('Should have thrown an exception, no valid country calling code ' +
2595         'present.');
2596  } catch (e) {
2597    // Expected.
2598    assertEquals('Wrong error type stored in exception.',
2599                 i18n.phonenumbers.Error.INVALID_COUNTRY_CODE,
2600                 e.message);
2601  }
2602  number = new i18n.phonenumbers.PhoneNumber();
2603  try {
2604    phoneNumber = '(1 610) 619 4466';
2605    countryCallingCode = 1;
2606    numberToFill = new goog.string.StringBuffer();
2607    assertEquals('Should have extracted the country calling code of the ' +
2608                 'region passed in',
2609                 countryCallingCode,
2610                 phoneUtil.maybeExtractCountryCode(phoneNumber, metadata,
2611                                                   numberToFill, true, number));
2612    assertEquals('Did not figure out CountryCodeSource correctly',
2613                 CCS.FROM_NUMBER_WITHOUT_PLUS_SIGN,
2614                 number.getCountryCodeSource());
2615  } catch (e) {
2616    fail('Should not have thrown an exception: ' + e.toString());
2617  }
2618  number = new i18n.phonenumbers.PhoneNumber();
2619  try {
2620    phoneNumber = '(1 610) 619 4466';
2621    countryCallingCode = 1;
2622    numberToFill = new goog.string.StringBuffer();
2623    assertEquals('Should have extracted the country calling code of the ' +
2624                 'region passed in',
2625                 countryCallingCode,
2626                 phoneUtil.maybeExtractCountryCode(phoneNumber, metadata,
2627                                                   numberToFill, false,
2628                                                   number));
2629    assertFalse('Should not contain CountryCodeSource.',
2630                number.hasCountryCodeSource());
2631  } catch (e) {
2632    fail('Should not have thrown an exception: ' + e.toString());
2633  }
2634  number = new i18n.phonenumbers.PhoneNumber();
2635  try {
2636    phoneNumber = '(1 610) 619 446';
2637    numberToFill = new goog.string.StringBuffer();
2638    assertEquals('Should not have extracted a country calling code - invalid ' +
2639                 'number after extraction of uncertain country calling code.',
2640                 0,
2641                 phoneUtil.maybeExtractCountryCode(phoneNumber, metadata,
2642                                                   numberToFill, false,
2643                                                   number));
2644    assertFalse('Should not contain CountryCodeSource.',
2645                number.hasCountryCodeSource());
2646  } catch (e) {
2647    fail('Should not have thrown an exception: ' + e.toString());
2648  }
2649  number = new i18n.phonenumbers.PhoneNumber();
2650  try {
2651    phoneNumber = '(1 610) 619';
2652    numberToFill = new goog.string.StringBuffer();
2653    assertEquals('Should not have extracted a country calling code - too ' +
2654                 'short number both before and after extraction of uncertain ' +
2655                 'country calling code.',
2656                 0,
2657                 phoneUtil.maybeExtractCountryCode(phoneNumber, metadata,
2658                                                   numberToFill, true, number));
2659    assertEquals('Did not figure out CountryCodeSource correctly',
2660                 CCS.FROM_DEFAULT_COUNTRY,
2661                 number.getCountryCodeSource());
2662  } catch (e) {
2663    fail('Should not have thrown an exception: ' + e.toString());
2664  }
2665}
2666
2667function testParseNationalNumber() {
2668  // National prefix attached.
2669  assertTrue(NZ_NUMBER.equals(phoneUtil.parse('033316005', RegionCode.NZ)));
2670  // Some fields are not filled in by parse, but only by parseAndKeepRawInput.
2671  assertFalse(NZ_NUMBER.hasCountryCodeSource());
2672  assertNull(NZ_NUMBER.getCountryCodeSource());
2673  assertEquals(i18n.phonenumbers.PhoneNumber.CountryCodeSource.UNSPECIFIED,
2674      NZ_NUMBER.getCountryCodeSourceOrDefault());
2675
2676  assertTrue(NZ_NUMBER.equals(phoneUtil.parse('33316005', RegionCode.NZ)));
2677  // National prefix attached and some formatting present.
2678  assertTrue(NZ_NUMBER.equals(phoneUtil.parse('03-331 6005', RegionCode.NZ)));
2679  assertTrue(NZ_NUMBER.equals(phoneUtil.parse('03 331 6005', RegionCode.NZ)));
2680  // Test parsing RFC3966 format with a phone context.
2681  assertTrue(NZ_NUMBER.equals(
2682      phoneUtil.parse('tel:03-331-6005;phone-context=+64', RegionCode.NZ)));
2683  assertTrue(NZ_NUMBER.equals(
2684      phoneUtil.parse('tel:331-6005;phone-context=+64-3', RegionCode.NZ)));
2685  assertTrue(NZ_NUMBER.equals(
2686      phoneUtil.parse('tel:331-6005;phone-context=+64-3', RegionCode.US)));
2687  assertTrue(NZ_NUMBER.equals(
2688      phoneUtil.parse('My number is tel:03-331-6005;phone-context=+64',
2689                      RegionCode.NZ)));
2690  // Test parsing RFC3966 format with optional user-defined parameters. The
2691  // parameters will appear after the context if present.
2692  assertTrue(NZ_NUMBER.equals(
2693      phoneUtil.parse('tel:03-331-6005;phone-context=+64;a=%A1',
2694                      RegionCode.NZ)));
2695  // Test parsing RFC3966 with an ISDN subaddress.
2696  assertTrue(NZ_NUMBER.equals(
2697      phoneUtil.parse('tel:03-331-6005;isub=12345;phone-context=+64',
2698                      RegionCode.NZ)));
2699  assertTrue(NZ_NUMBER.equals(
2700      phoneUtil.parse('tel:+64-3-331-6005;isub=12345', RegionCode.NZ)));
2701  // Test parsing RFC3966 with "tel:" missing.
2702  assertTrue(NZ_NUMBER.equals(
2703      phoneUtil.parse('03-331-6005;phone-context=+64', RegionCode.NZ)));
2704  // Testing international prefixes.
2705  // Should strip country calling code.
2706  assertTrue(
2707      NZ_NUMBER.equals(phoneUtil.parse('0064 3 331 6005', RegionCode.NZ)));
2708  // Try again, but this time we have an international number with Region Code
2709  // US. It should recognise the country calling code and parse accordingly.
2710  assertTrue(
2711      NZ_NUMBER.equals(phoneUtil.parse('01164 3 331 6005', RegionCode.US)));
2712  assertTrue(
2713      NZ_NUMBER.equals(phoneUtil.parse('+64 3 331 6005', RegionCode.US)));
2714  // We should ignore the leading plus here, since it is not followed by a valid
2715  // country code but instead is followed by the IDD for the US.
2716  assertTrue(
2717      NZ_NUMBER.equals(phoneUtil.parse('+01164 3 331 6005', RegionCode.US)));
2718  assertTrue(
2719      NZ_NUMBER.equals(phoneUtil.parse('+0064 3 331 6005', RegionCode.NZ)));
2720  assertTrue(
2721      NZ_NUMBER.equals(phoneUtil.parse('+ 00 64 3 331 6005', RegionCode.NZ)));
2722
2723  assertTrue(US_LOCAL_NUMBER.equals(
2724      phoneUtil.parse('tel:253-0000;phone-context=www.google.com',
2725                      RegionCode.US)));
2726  assertTrue(US_LOCAL_NUMBER.equals(
2727      phoneUtil.parse('tel:253-0000;isub=12345;phone-context=www.google.com',
2728                      RegionCode.US)));
2729  // This is invalid because no "+" sign is present as part of phone-context.
2730  // The phone context is simply ignored in this case just as if it contains a
2731  // domain.
2732  assertTrue(US_LOCAL_NUMBER.equals(
2733      phoneUtil.parse('tel:2530000;isub=12345;phone-context=1-650',
2734                      RegionCode.US)));
2735  assertTrue(US_LOCAL_NUMBER.equals(
2736      phoneUtil.parse('tel:2530000;isub=12345;phone-context=1234.com',
2737                      RegionCode.US)));
2738
2739  /** @type {!i18n.phonenumbers.PhoneNumber} */
2740  var nzNumber = new i18n.phonenumbers.PhoneNumber();
2741  nzNumber.setCountryCode(64);
2742  nzNumber.setNationalNumber(64123456);
2743  assertTrue(nzNumber.equals(phoneUtil.parse('64(0)64123456', RegionCode.NZ)));
2744  // Check that using a '/' is fine in a phone number.
2745  assertTrue(DE_NUMBER.equals(phoneUtil.parse('301/23456', RegionCode.DE)));
2746
2747  /** @type {!i18n.phonenumbers.PhoneNumber} */
2748  var usNumber = new i18n.phonenumbers.PhoneNumber();
2749  // Check it doesn't use the '1' as a country calling code when parsing if the
2750  // phone number was already possible.
2751  usNumber.setCountryCode(1);
2752  usNumber.setNationalNumber(1234567890);
2753  assertTrue(usNumber.equals(phoneUtil.parse('123-456-7890', RegionCode.US)));
2754
2755  // Test star numbers. Although this is not strictly valid, we would like to
2756  // make sure we can parse the output we produce when formatting the number.
2757  assertTrue(
2758      JP_STAR_NUMBER.equals(phoneUtil.parse('+81 *2345', RegionCode.JP)));
2759
2760  /** @type {!i18n.phonenumbers.PhoneNumber} */
2761  var shortNumber = new i18n.phonenumbers.PhoneNumber();
2762  shortNumber.setCountryCode(64);
2763  shortNumber.setNationalNumber(12);
2764  assertTrue(shortNumber.equals(phoneUtil.parse('12', RegionCode.NZ)));
2765
2766  // Test for short-code with leading zero for a country which has 0 as
2767  // national prefix. Ensure it's not interpreted as national prefix if the
2768  // remaining number length is local-only in terms of length. Example: In GB,
2769  // length 6-7 are only possible local-only.
2770  shortNumber.setCountryCode(44);
2771  shortNumber.setNationalNumber(123456);
2772  shortNumber.setItalianLeadingZero(true);
2773  assertTrue(shortNumber.equals(phoneUtil.parse('0123456', RegionCode.GB)));
2774}
2775
2776function testParseNumberWithAlphaCharacters() {
2777  // Test case with alpha characters.
2778  /** @type {!i18n.phonenumbers.PhoneNumber} */
2779  var tollfreeNumber = new i18n.phonenumbers.PhoneNumber();
2780  tollfreeNumber.setCountryCode(64);
2781  tollfreeNumber.setNationalNumber(800332005);
2782  assertTrue(tollfreeNumber.equals(
2783      phoneUtil.parse('0800 DDA 005', RegionCode.NZ)));
2784  /** @type {!i18n.phonenumbers.PhoneNumber} */
2785  var premiumNumber = new i18n.phonenumbers.PhoneNumber();
2786  premiumNumber.setCountryCode(64);
2787  premiumNumber.setNationalNumber(9003326005);
2788  assertTrue(premiumNumber.equals(
2789      phoneUtil.parse('0900 DDA 6005', RegionCode.NZ)));
2790  // Not enough alpha characters for them to be considered intentional, so they
2791  // are stripped.
2792  assertTrue(premiumNumber.equals(
2793      phoneUtil.parse('0900 332 6005a', RegionCode.NZ)));
2794  assertTrue(premiumNumber.equals(
2795      phoneUtil.parse('0900 332 600a5', RegionCode.NZ)));
2796  assertTrue(premiumNumber.equals(
2797      phoneUtil.parse('0900 332 600A5', RegionCode.NZ)));
2798  assertTrue(premiumNumber.equals(
2799      phoneUtil.parse('0900 a332 600A5', RegionCode.NZ)));
2800}
2801
2802function testParseMaliciousInput() {
2803  // Lots of leading + signs before the possible number.
2804  /** @type {!goog.string.StringBuffer} */
2805  var maliciousNumber = new goog.string.StringBuffer();
2806  for (var i = 0; i < 6000; i++) {
2807    maliciousNumber.append('+');
2808  }
2809  maliciousNumber.append('12222-33-244 extensioB 343+');
2810  try {
2811    phoneUtil.parse(maliciousNumber.toString(), RegionCode.US);
2812    fail('This should not parse without throwing an exception ' +
2813         maliciousNumber.toString());
2814  } catch (e) {
2815    // Expected this exception.
2816    assertEquals('Wrong error type stored in exception.',
2817                 i18n.phonenumbers.Error.TOO_LONG,
2818                 e.message);
2819  }
2820  /** @type {!goog.string.StringBuffer} */
2821  var maliciousNumberWithAlmostExt = new goog.string.StringBuffer();
2822  for (i = 0; i < 350; i++) {
2823    maliciousNumberWithAlmostExt.append('200');
2824  }
2825  maliciousNumberWithAlmostExt.append(' extensiOB 345');
2826  try {
2827    phoneUtil.parse(maliciousNumberWithAlmostExt.toString(), RegionCode.US);
2828    fail('This should not parse without throwing an exception ' +
2829         maliciousNumberWithAlmostExt.toString());
2830  } catch (e) {
2831    // Expected this exception.
2832    assertEquals('Wrong error type stored in exception.',
2833                 i18n.phonenumbers.Error.TOO_LONG,
2834                 e.message);
2835  }
2836}
2837
2838function testParseWithInternationalPrefixes() {
2839  assertTrue(US_NUMBER.equals(
2840      phoneUtil.parse('+1 (650) 253-0000', RegionCode.NZ)));
2841  assertTrue(INTERNATIONAL_TOLL_FREE.equals(
2842      phoneUtil.parse('011 800 1234 5678', RegionCode.US)));
2843  assertTrue(US_NUMBER.equals(
2844      phoneUtil.parse('1-650-253-0000', RegionCode.US)));
2845  // Calling the US number from Singapore by using different service providers
2846  // 1st test: calling using SingTel IDD service (IDD is 001)
2847  assertTrue(US_NUMBER.equals(
2848      phoneUtil.parse('0011-650-253-0000', RegionCode.SG)));
2849  // 2nd test: calling using StarHub IDD service (IDD is 008)
2850  assertTrue(US_NUMBER.equals(
2851      phoneUtil.parse('0081-650-253-0000', RegionCode.SG)));
2852  // 3rd test: calling using SingTel V019 service (IDD is 019)
2853  assertTrue(US_NUMBER.equals(
2854      phoneUtil.parse('0191-650-253-0000', RegionCode.SG)));
2855  // Calling the US number from Poland
2856  assertTrue(US_NUMBER.equals(
2857      phoneUtil.parse('0~01-650-253-0000', RegionCode.PL)));
2858  // Using '++' at the start.
2859  assertTrue(US_NUMBER.equals(
2860      phoneUtil.parse('++1 (650) 253-0000', RegionCode.PL)));
2861}
2862
2863function testParseNonAscii() {
2864  // Using a full-width plus sign.
2865  assertTrue(US_NUMBER.equals(
2866      phoneUtil.parse('\uFF0B1 (650) 253-0000', RegionCode.SG)));
2867  // Using a soft hyphen U+00AD.
2868  assertTrue(US_NUMBER.equals(
2869      phoneUtil.parse('1 (650) 253\u00AD-0000', RegionCode.US)));
2870  // The whole number, including punctuation, is here represented in full-width
2871  // form.
2872  assertTrue(US_NUMBER.equals(
2873      phoneUtil.parse('\uFF0B\uFF11\u3000\uFF08\uFF16\uFF15\uFF10\uFF09' +
2874                      '\u3000\uFF12\uFF15\uFF13\uFF0D\uFF10\uFF10\uFF10\uFF10',
2875                      RegionCode.SG)));
2876  // Using U+30FC dash instead.
2877  assertTrue(US_NUMBER.equals(
2878      phoneUtil.parse('\uFF0B\uFF11\u3000\uFF08\uFF16\uFF15\uFF10\uFF09' +
2879                      '\u3000\uFF12\uFF15\uFF13\u30FC\uFF10\uFF10\uFF10\uFF10',
2880                      RegionCode.SG)));
2881
2882  // Using a very strange decimal digit range (Mongolian digits).
2883  // TODO(user): Support Mongolian digits
2884  // assertTrue(US_NUMBER.equals(
2885  //     phoneUtil.parse('\u1811 \u1816\u1815\u1810 ' +
2886  //                     '\u1812\u1815\u1813 \u1810\u1810\u1810\u1810',
2887  //                     RegionCode.US)));
2888}
2889
2890function testParseWithLeadingZero() {
2891  assertTrue(
2892      IT_NUMBER.equals(phoneUtil.parse('+39 02-36618 300', RegionCode.NZ)));
2893  assertTrue(
2894      IT_NUMBER.equals(phoneUtil.parse('02-36618 300', RegionCode.IT)));
2895
2896  assertTrue(
2897      IT_MOBILE.equals(phoneUtil.parse('345 678 901', RegionCode.IT)));
2898}
2899
2900function testParseNationalNumberArgentina() {
2901  // Test parsing mobile numbers of Argentina.
2902  /** @type {!i18n.phonenumbers.PhoneNumber} */
2903  var arNumber = new i18n.phonenumbers.PhoneNumber();
2904  arNumber.setCountryCode(54);
2905  arNumber.setNationalNumber(93435551212);
2906  assertTrue(
2907      arNumber.equals(phoneUtil.parse('+54 9 343 555 1212', RegionCode.AR)));
2908  assertTrue(
2909      arNumber.equals(phoneUtil.parse('0343 15 555 1212', RegionCode.AR)));
2910
2911  arNumber = new i18n.phonenumbers.PhoneNumber();
2912  arNumber.setCountryCode(54);
2913  arNumber.setNationalNumber(93715654320);
2914  assertTrue(
2915      arNumber.equals(phoneUtil.parse('+54 9 3715 65 4320', RegionCode.AR)));
2916  assertTrue(
2917      arNumber.equals(phoneUtil.parse('03715 15 65 4320', RegionCode.AR)));
2918  assertTrue(
2919      AR_MOBILE.equals(phoneUtil.parse('911 876 54321', RegionCode.AR)));
2920
2921  // Test parsing fixed-line numbers of Argentina.
2922  assertTrue(
2923      AR_NUMBER.equals(phoneUtil.parse('+54 11 8765 4321', RegionCode.AR)));
2924  assertTrue(
2925      AR_NUMBER.equals(phoneUtil.parse('011 8765 4321', RegionCode.AR)));
2926
2927  arNumber = new i18n.phonenumbers.PhoneNumber();
2928  arNumber.setCountryCode(54);
2929  arNumber.setNationalNumber(3715654321);
2930  assertTrue(
2931      arNumber.equals(phoneUtil.parse('+54 3715 65 4321', RegionCode.AR)));
2932  assertTrue(
2933      arNumber.equals(phoneUtil.parse('03715 65 4321', RegionCode.AR)));
2934
2935  arNumber = new i18n.phonenumbers.PhoneNumber();
2936  arNumber.setCountryCode(54);
2937  arNumber.setNationalNumber(2312340000);
2938  assertTrue(
2939      arNumber.equals(phoneUtil.parse('+54 23 1234 0000', RegionCode.AR)));
2940  assertTrue(
2941      arNumber.equals(phoneUtil.parse('023 1234 0000', RegionCode.AR)));
2942}
2943
2944function testParseWithXInNumber() {
2945  // Test that having an 'x' in the phone number at the start is ok and that it
2946  // just gets removed.
2947  assertTrue(
2948      AR_NUMBER.equals(phoneUtil.parse('01187654321', RegionCode.AR)));
2949  assertTrue(
2950      AR_NUMBER.equals(phoneUtil.parse('(0) 1187654321', RegionCode.AR)));
2951  assertTrue(
2952      AR_NUMBER.equals(phoneUtil.parse('0 1187654321', RegionCode.AR)));
2953  assertTrue(
2954      AR_NUMBER.equals(phoneUtil.parse('(0xx) 1187654321', RegionCode.AR)));
2955  /** @type {!i18n.phonenumbers.PhoneNumber} */
2956  var arFromUs = new i18n.phonenumbers.PhoneNumber();
2957  arFromUs.setCountryCode(54);
2958  arFromUs.setNationalNumber(81429712);
2959  // This test is intentionally constructed such that the number of digit after
2960  // xx is larger than 7, so that the number won't be mistakenly treated as an
2961  // extension, as we allow extensions up to 7 digits. This assumption is okay
2962  // for now as all the countries where a carrier selection code is written in
2963  // the form of xx have a national significant number of length larger than 7.
2964  assertTrue(
2965      arFromUs.equals(phoneUtil.parse('011xx5481429712', RegionCode.US)));
2966}
2967
2968function testParseNumbersMexico() {
2969  // Test parsing fixed-line numbers of Mexico.
2970  /** @type {!i18n.phonenumbers.PhoneNumber} */
2971  var mxNumber = new i18n.phonenumbers.PhoneNumber();
2972  mxNumber.setCountryCode(52);
2973  mxNumber.setNationalNumber(4499780001);
2974  assertTrue(mxNumber.equals(
2975      phoneUtil.parse('+52 (449)978-0001', RegionCode.MX)));
2976  assertTrue(
2977      mxNumber.equals(phoneUtil.parse('01 (449)978-0001', RegionCode.MX)));
2978  assertTrue(
2979      mxNumber.equals(phoneUtil.parse('(449)978-0001', RegionCode.MX)));
2980
2981  // Test parsing mobile numbers of Mexico.
2982  mxNumber = new i18n.phonenumbers.PhoneNumber();
2983  mxNumber.setCountryCode(52);
2984  mxNumber.setNationalNumber(13312345678);
2985  assertTrue(mxNumber.equals(
2986      phoneUtil.parse('+52 1 33 1234-5678', RegionCode.MX)));
2987  assertTrue(mxNumber.equals(
2988      phoneUtil.parse('044 (33) 1234-5678', RegionCode.MX)));
2989  assertTrue(mxNumber.equals(
2990      phoneUtil.parse('045 33 1234-5678', RegionCode.MX)));
2991}
2992
2993function testFailedParseOnInvalidNumbers() {
2994  try {
2995    /** @type {string} */
2996    var sentencePhoneNumber = 'This is not a phone number';
2997    phoneUtil.parse(sentencePhoneNumber, RegionCode.NZ);
2998    fail('This should not parse without throwing an exception ' +
2999         sentencePhoneNumber);
3000  } catch (e) {
3001    // Expected this exception.
3002    assertEquals('Wrong error type stored in exception.',
3003                 i18n.phonenumbers.Error.NOT_A_NUMBER,
3004                 e.message);
3005  }
3006  try {
3007    sentencePhoneNumber = '1 Still not a number';
3008    phoneUtil.parse(sentencePhoneNumber, RegionCode.NZ);
3009    fail('This should not parse without throwing an exception ' +
3010         sentencePhoneNumber);
3011  } catch (e) {
3012    // Expected this exception.
3013    assertEquals('Wrong error type stored in exception.',
3014                 i18n.phonenumbers.Error.NOT_A_NUMBER,
3015                 e.message);
3016  }
3017  try {
3018    sentencePhoneNumber = '1 MICROSOFT';
3019    phoneUtil.parse(sentencePhoneNumber, RegionCode.NZ);
3020    fail('This should not parse without throwing an exception ' +
3021         sentencePhoneNumber);
3022  } catch (e) {
3023    // Expected this exception.
3024    assertEquals('Wrong error type stored in exception.',
3025                 i18n.phonenumbers.Error.NOT_A_NUMBER,
3026                 e.message);
3027  }
3028  try {
3029    sentencePhoneNumber = '12 MICROSOFT';
3030    phoneUtil.parse(sentencePhoneNumber, RegionCode.NZ);
3031    fail('This should not parse without throwing an exception ' +
3032         sentencePhoneNumber);
3033  } catch (e) {
3034    // Expected this exception.
3035    assertEquals('Wrong error type stored in exception.',
3036                 i18n.phonenumbers.Error.NOT_A_NUMBER,
3037                 e.message);
3038  }
3039  try {
3040    /** @type {string} */
3041    var tooLongPhoneNumber = '01495 72553301873 810104';
3042    phoneUtil.parse(tooLongPhoneNumber, RegionCode.GB);
3043    fail('This should not parse without throwing an exception ' +
3044         tooLongPhoneNumber);
3045  } catch (e) {
3046    // Expected this exception.
3047    assertEquals('Wrong error type stored in exception.',
3048                 i18n.phonenumbers.Error.TOO_LONG,
3049                 e.message);
3050  }
3051  try {
3052    /** @type {string} */
3053    var plusMinusPhoneNumber = '+---';
3054    phoneUtil.parse(plusMinusPhoneNumber, RegionCode.DE);
3055    fail('This should not parse without throwing an exception ' +
3056         plusMinusPhoneNumber);
3057  } catch (e) {
3058    // Expected this exception.
3059    assertEquals('Wrong error type stored in exception.',
3060                 i18n.phonenumbers.Error.NOT_A_NUMBER,
3061                 e.message);
3062  }
3063  try {
3064    /** @type {string} */
3065    var plusStar = '+***';
3066    phoneUtil.parse(plusStar, RegionCode.DE);
3067    fail('This should not parse without throwing an exception ' + plusStar);
3068  } catch (e) {
3069    // Expected this exception.
3070    assertEquals('Wrong error type stored in exception.',
3071                 i18n.phonenumbers.Error.NOT_A_NUMBER,
3072                 e.message);
3073  }
3074  try {
3075    /** @type {string} */
3076    var plusStarPhoneNumber = '+*******91';
3077    phoneUtil.parse(plusStarPhoneNumber, RegionCode.DE);
3078    fail('This should not parse without throwing an exception ' +
3079         plusStarPhoneNumber);
3080  } catch (e) {
3081    // Expected this exception.
3082    assertEquals('Wrong error type stored in exception.',
3083                 i18n.phonenumbers.Error.NOT_A_NUMBER,
3084                 e.message);
3085  }
3086  try {
3087    /** @type {string} */
3088    var tooShortPhoneNumber = '+49 0';
3089    phoneUtil.parse(tooShortPhoneNumber, RegionCode.DE);
3090    fail('This should not parse without throwing an exception ' +
3091         tooShortPhoneNumber);
3092  } catch (e) {
3093    // Expected this exception.
3094    assertEquals('Wrong error type stored in exception.',
3095                 i18n.phonenumbers.Error.TOO_SHORT_NSN,
3096                 e.message);
3097  }
3098  try {
3099    /** @type {string} */
3100    var invalidCountryCode = '+210 3456 56789';
3101    phoneUtil.parse(invalidCountryCode, RegionCode.NZ);
3102    fail('This is not a recognised region code: should fail: ' +
3103         invalidCountryCode);
3104  } catch (e) {
3105    // Expected this exception.
3106    assertEquals('Wrong error type stored in exception.',
3107                 i18n.phonenumbers.Error.INVALID_COUNTRY_CODE,
3108                 e.message);
3109  }
3110  try {
3111    /** @type {string} */
3112    var plusAndIddAndInvalidCountryCode = '+ 00 210 3 331 6005';
3113    phoneUtil.parse(plusAndIddAndInvalidCountryCode, RegionCode.NZ);
3114    fail('This should not parse without throwing an exception.');
3115  } catch (e) {
3116    // Expected this exception. 00 is a correct IDD, but 210 is not a valid
3117    // country code.
3118    assertEquals('Wrong error type stored in exception.',
3119                 i18n.phonenumbers.Error.INVALID_COUNTRY_CODE,
3120                 e.message);
3121  }
3122  try {
3123    /** @type {string} */
3124    var someNumber = '123 456 7890';
3125    phoneUtil.parse(someNumber, RegionCode.ZZ);
3126    fail('Unknown region code not allowed: should fail.');
3127  } catch (e) {
3128    // Expected this exception.
3129    assertEquals('Wrong error type stored in exception.',
3130                 i18n.phonenumbers.Error.INVALID_COUNTRY_CODE,
3131                 e.message);
3132  }
3133  try {
3134    someNumber = '123 456 7890';
3135    phoneUtil.parse(someNumber, RegionCode.CS);
3136    fail('Deprecated region code not allowed: should fail.');
3137  } catch (e) {
3138    // Expected this exception.
3139    assertEquals('Wrong error type stored in exception.',
3140                 i18n.phonenumbers.Error.INVALID_COUNTRY_CODE,
3141                 e.message);
3142  }
3143  try {
3144    someNumber = '123 456 7890';
3145    phoneUtil.parse(someNumber, null);
3146    fail('Null region code not allowed: should fail.');
3147  } catch (e) {
3148    // Expected this exception.
3149    assertEquals('Wrong error type stored in exception.',
3150                 i18n.phonenumbers.Error.INVALID_COUNTRY_CODE,
3151                 e.message);
3152  }
3153  try {
3154    someNumber = '0044------';
3155    phoneUtil.parse(someNumber, RegionCode.GB);
3156    fail('No number provided, only region code: should fail');
3157  } catch (e) {
3158    // Expected this exception.
3159    assertEquals('Wrong error type stored in exception.',
3160                 i18n.phonenumbers.Error.TOO_SHORT_AFTER_IDD,
3161                 e.message);
3162  }
3163  try {
3164    someNumber = '0044';
3165    phoneUtil.parse(someNumber, RegionCode.GB);
3166    fail('No number provided, only region code: should fail');
3167  } catch (e) {
3168    // Expected this exception.
3169    assertEquals('Wrong error type stored in exception.',
3170                 i18n.phonenumbers.Error.TOO_SHORT_AFTER_IDD,
3171                 e.message);
3172  }
3173  try {
3174    someNumber = '011';
3175    phoneUtil.parse(someNumber, RegionCode.US);
3176    fail('Only IDD provided - should fail.');
3177  } catch (e) {
3178    // Expected this exception.
3179    assertEquals('Wrong error type stored in exception.',
3180                 i18n.phonenumbers.Error.TOO_SHORT_AFTER_IDD,
3181                 e.message);
3182  }
3183  try {
3184    someNumber = '0119';
3185    phoneUtil.parse(someNumber, RegionCode.US);
3186    fail('Only IDD provided and then 9 - should fail.');
3187  } catch (e) {
3188    // Expected this exception.
3189    assertEquals('Wrong error type stored in exception.',
3190                 i18n.phonenumbers.Error.TOO_SHORT_AFTER_IDD,
3191                 e.message);
3192  }
3193  try {
3194    /** @type {string} */
3195    var emptyNumber = '';
3196    // Invalid region.
3197    phoneUtil.parse(emptyNumber, RegionCode.ZZ);
3198    fail('Empty string - should fail.');
3199  } catch (e) {
3200    // Expected this exception.
3201    assertEquals('Wrong error type stored in exception.',
3202                 i18n.phonenumbers.Error.NOT_A_NUMBER,
3203                 e.message);
3204  }
3205  try {
3206    // Invalid region.
3207    phoneUtil.parse(null, RegionCode.ZZ);
3208    fail('Null string - should fail.');
3209  } catch (e) {
3210    // Expected this exception.
3211    assertEquals('Wrong error type stored in exception.',
3212                 i18n.phonenumbers.Error.NOT_A_NUMBER,
3213                 e.message);
3214  }
3215  try {
3216    phoneUtil.parse(null, RegionCode.US);
3217    fail('Null string - should fail.');
3218  } catch (e) {
3219    // Expected this exception.
3220    assertEquals('Wrong error type stored in exception.',
3221                 i18n.phonenumbers.Error.NOT_A_NUMBER,
3222                 e.message);
3223  }
3224  try {
3225    /** @type {string} */
3226    var domainRfcPhoneContext = 'tel:555-1234;phone-context=www.google.com';
3227    phoneUtil.parse(domainRfcPhoneContext, RegionCode.ZZ);
3228    fail('"Unknown" region code not allowed: should fail.');
3229  } catch (e) {
3230    // Expected this exception.
3231    assertEquals('Wrong error type stored in exception.',
3232                 i18n.phonenumbers.Error.INVALID_COUNTRY_CODE,
3233                 e.message);
3234  }
3235  try {
3236    // This is invalid because no '+' sign is present as part of phone-context.
3237    // This should not succeed in being parsed.
3238    /** @type {string} */
3239    var invalidRfcPhoneContext = 'tel:555-1234;phone-context=1-331';
3240    phoneUtil.parse(invalidRfcPhoneContext, RegionCode.ZZ);
3241    fail('"Unknown" region code not allowed: should fail.');
3242  } catch (e) {
3243    // Expected this exception.
3244    assertEquals('Wrong error type stored in exception.',
3245                 i18n.phonenumbers.Error.INVALID_COUNTRY_CODE,
3246                 e.message);
3247  }
3248  try {
3249    // Only the phone-context symbol is present, but no data.
3250    invalidRfcPhoneContext = ';phone-context=';
3251    phoneUtil.parse(invalidRfcPhoneContext, RegionCode.ZZ);
3252    fail('Should have thrown an exception, no valid country calling code ' +
3253         'present.');
3254  } catch (e) {
3255    // Expected.
3256    assertEquals('Wrong error type stored in exception.',
3257                 i18n.phonenumbers.Error.NOT_A_NUMBER,
3258                 e.message);
3259  }
3260}
3261
3262function testParseNumbersWithPlusWithNoRegion() {
3263  // RegionCode.ZZ is allowed only if the number starts with a '+' - then the
3264  // country calling code can be calculated.
3265  assertTrue(
3266      NZ_NUMBER.equals(phoneUtil.parse('+64 3 331 6005', RegionCode.ZZ)));
3267  // Test with full-width plus.
3268  assertTrue(
3269      NZ_NUMBER.equals(phoneUtil.parse('\uFF0B64 3 331 6005', RegionCode.ZZ)));
3270  // Test with normal plus but leading characters that need to be stripped.
3271  assertTrue(
3272      NZ_NUMBER.equals(phoneUtil.parse('Tel: +64 3 331 6005', RegionCode.ZZ)));
3273  assertTrue(
3274      NZ_NUMBER.equals(phoneUtil.parse('+64 3 331 6005', null)));
3275  assertTrue(
3276      INTERNATIONAL_TOLL_FREE.equals(phoneUtil.parse('+800 1234 5678', null)));
3277  assertTrue(
3278      UNIVERSAL_PREMIUM_RATE.equals(phoneUtil.parse('+979 123 456 789', null)));
3279
3280  // Test parsing RFC3966 format with a phone context.
3281  assertTrue(NZ_NUMBER.equals(
3282      phoneUtil.parse('tel:03-331-6005;phone-context=+64', RegionCode.ZZ)));
3283  assertTrue(NZ_NUMBER.equals(
3284      phoneUtil.parse('  tel:03-331-6005;phone-context=+64', RegionCode.ZZ)));
3285  assertTrue(NZ_NUMBER.equals(
3286      phoneUtil.parse('tel:03-331-6005;isub=12345;phone-context=+64',
3287                      RegionCode.ZZ)));
3288
3289  /** @type {!i18n.phonenumbers.PhoneNumber} */
3290  var nzNumberWithRawInput = NZ_NUMBER.clone();
3291  nzNumberWithRawInput.setRawInput('+64 3 331 6005');
3292  nzNumberWithRawInput.setCountryCodeSource(i18n.phonenumbers.PhoneNumber
3293      .CountryCodeSource.FROM_NUMBER_WITH_PLUS_SIGN);
3294  assertTrue(nzNumberWithRawInput.equals(
3295      phoneUtil.parseAndKeepRawInput('+64 3 331 6005', RegionCode.ZZ)));
3296  // Null is also allowed for the region code in these cases.
3297  assertTrue(nzNumberWithRawInput.equals(
3298      phoneUtil.parseAndKeepRawInput('+64 3 331 6005', null)));
3299}
3300
3301function testParseNumberTooShortIfNationalPrefixStripped() {
3302  // Test that a number whose first digits happen to coincide with the national
3303  // prefix does not get them stripped if doing so would result in a number too
3304  // short to be a possible (regular length) phone number for that region.
3305  /** @type {!i18n.phonenumbers.PhoneNumber} */
3306  var byNumber = new i18n.phonenumbers.PhoneNumber();
3307  byNumber.setCountryCode(375);
3308  byNumber.setNationalNumber(8123);
3309  assertTrue(byNumber.equals(phoneUtil.parse('8123', RegionCode.BY)));
3310  byNumber.setNationalNumber(81234);
3311  assertTrue(byNumber.equals(phoneUtil.parse('81234', RegionCode.BY)));
3312
3313  // The prefix doesn't get stripped, since the input is a viable 6-digit
3314  // number, whereas the result of stripping is only 5 digits.
3315  byNumber.setNationalNumber(812345);
3316  assertTrue(byNumber.equals(phoneUtil.parse('812345', RegionCode.BY)));
3317
3318  // The prefix gets stripped, since only 6-digit numbers are possible.
3319  byNumber.setNationalNumber(123456);
3320  assertTrue(byNumber.equals(phoneUtil.parse('8123456', RegionCode.BY)));
3321}
3322
3323function testParseExtensions() {
3324  /** @type {!i18n.phonenumbers.PhoneNumber} */
3325  var nzNumber = new i18n.phonenumbers.PhoneNumber();
3326  nzNumber.setCountryCode(64);
3327  nzNumber.setNationalNumber(33316005);
3328  nzNumber.setExtension('3456');
3329  assertTrue(nzNumber.equals(
3330      phoneUtil.parse('03 331 6005 ext 3456', RegionCode.NZ)));
3331  assertTrue(nzNumber.equals(
3332      phoneUtil.parse('03-3316005x3456', RegionCode.NZ)));
3333  assertTrue(nzNumber.equals(
3334      phoneUtil.parse('03-3316005 int.3456', RegionCode.NZ)));
3335  assertTrue(nzNumber.equals(
3336      phoneUtil.parse('03 3316005 #3456', RegionCode.NZ)));
3337
3338  // Test the following do not extract extensions:
3339  assertTrue(ALPHA_NUMERIC_NUMBER.equals(
3340      phoneUtil.parse('1800 six-flags', RegionCode.US)));
3341  assertTrue(ALPHA_NUMERIC_NUMBER.equals(
3342      phoneUtil.parse('1800 SIX FLAGS', RegionCode.US)));
3343  assertTrue(ALPHA_NUMERIC_NUMBER.equals(
3344      phoneUtil.parse('0~0 1800 7493 5247', RegionCode.PL)));
3345  assertTrue(ALPHA_NUMERIC_NUMBER.equals(
3346      phoneUtil.parse('(1800) 7493.5247', RegionCode.US)));
3347
3348  // Check that the last instance of an extension token is matched.
3349  /** @type {!i18n.phonenumbers.PhoneNumber} */
3350  var extnNumber = ALPHA_NUMERIC_NUMBER.clone();
3351  extnNumber.setExtension('1234');
3352  assertTrue(extnNumber.equals(
3353      phoneUtil.parse('0~0 1800 7493 5247 ~1234', RegionCode.PL)));
3354
3355  // Verifying bug-fix where the last digit of a number was previously omitted
3356  // if it was a 0 when extracting the extension. Also verifying a few different
3357  // cases of extensions.
3358  /** @type {!i18n.phonenumbers.PhoneNumber} */
3359  var ukNumber = new i18n.phonenumbers.PhoneNumber();
3360  ukNumber.setCountryCode(44);
3361  ukNumber.setNationalNumber(2034567890);
3362  ukNumber.setExtension('456');
3363  assertTrue(ukNumber.equals(
3364      phoneUtil.parse('+44 2034567890x456', RegionCode.NZ)));
3365  assertTrue(ukNumber.equals(
3366      phoneUtil.parse('+44 2034567890x456', RegionCode.GB)));
3367  assertTrue(ukNumber.equals(
3368      phoneUtil.parse('+44 2034567890 x456', RegionCode.GB)));
3369  assertTrue(ukNumber.equals(
3370      phoneUtil.parse('+44 2034567890 X456', RegionCode.GB)));
3371  assertTrue(ukNumber.equals(
3372      phoneUtil.parse('+44 2034567890 X 456', RegionCode.GB)));
3373  assertTrue(ukNumber.equals(
3374      phoneUtil.parse('+44 2034567890 X  456', RegionCode.GB)));
3375  assertTrue(ukNumber.equals(
3376      phoneUtil.parse('+44 2034567890 x 456  ', RegionCode.GB)));
3377  assertTrue(ukNumber.equals(
3378      phoneUtil.parse('+44 2034567890  X 456', RegionCode.GB)));
3379  assertTrue(ukNumber.equals(
3380      phoneUtil.parse('+44-2034567890;ext=456', RegionCode.GB)));
3381  assertTrue(ukNumber.equals(
3382      phoneUtil.parse('tel:2034567890;ext=456;phone-context=+44',
3383                      RegionCode.ZZ)));
3384  // Full-width extension, 'extn' only.
3385  assertTrue(ukNumber.equals(
3386      phoneUtil.parse('+442034567890\uFF45\uFF58\uFF54\uFF4E456',
3387                      RegionCode.GB)));
3388  // 'xtn' only.
3389  assertTrue(ukNumber.equals(
3390      phoneUtil.parse('+442034567890\uFF58\uFF54\uFF4E456', RegionCode.GB)));
3391  // 'xt' only.
3392  assertTrue(ukNumber.equals(
3393      phoneUtil.parse('+442034567890\uFF58\uFF54456', RegionCode.GB)));
3394
3395  /** @type {!i18n.phonenumbers.PhoneNumber} */
3396  var usWithExtension = new i18n.phonenumbers.PhoneNumber();
3397  usWithExtension.setCountryCode(1);
3398  usWithExtension.setNationalNumber(8009013355);
3399  usWithExtension.setExtension('7246433');
3400  assertTrue(usWithExtension.equals(
3401      phoneUtil.parse('(800) 901-3355 x 7246433', RegionCode.US)));
3402  assertTrue(usWithExtension.equals(
3403      phoneUtil.parse('(800) 901-3355 , ext 7246433', RegionCode.US)));
3404  assertTrue(usWithExtension.equals(
3405      phoneUtil.parse('(800) 901-3355 ; 7246433', RegionCode.US)));
3406  // To test an extension character without surrounding spaces.
3407  assertTrue(usWithExtension.equals(
3408      phoneUtil.parse('(800) 901-3355;7246433', RegionCode.US)));
3409  assertTrue(usWithExtension.equals(
3410      phoneUtil.parse('(800) 901-3355 ,extension 7246433', RegionCode.US)));
3411  assertTrue(usWithExtension.equals(
3412      phoneUtil.parse('(800) 901-3355 ,extensi\u00F3n 7246433',
3413      RegionCode.US)));
3414  // Repeat with the small letter o with acute accent created by combining
3415  // characters.
3416  assertTrue(usWithExtension.equals(
3417      phoneUtil.parse('(800) 901-3355 ,extensio\u0301n 7246433',
3418      RegionCode.US)));
3419  assertTrue(usWithExtension.equals(
3420      phoneUtil.parse('(800) 901-3355 , 7246433', RegionCode.US)));
3421  assertTrue(usWithExtension.equals(
3422      phoneUtil.parse('(800) 901-3355 ext: 7246433', RegionCode.US)));
3423  // Testing Russian extension "доб" with variants found online.
3424  var ruWithExtension = new i18n.phonenumbers.PhoneNumber();
3425  ruWithExtension.setCountryCode(7);
3426  ruWithExtension.setNationalNumber(4232022511);
3427  ruWithExtension.setExtension('100');
3428  assertTrue(ruWithExtension.equals(
3429      phoneUtil.parse('8 (423) 202-25-11, доб. 100', RegionCode.RU)));
3430  assertTrue(ruWithExtension.equals(
3431      phoneUtil.parse('8 (423) 202-25-11 доб. 100', RegionCode.RU)));
3432  assertTrue(ruWithExtension.equals(
3433      phoneUtil.parse('8 (423) 202-25-11, доб 100', RegionCode.RU)));
3434  assertTrue(ruWithExtension.equals(
3435      phoneUtil.parse('8 (423) 202-25-11 доб 100', RegionCode.RU)));
3436  assertTrue(ruWithExtension.equals(
3437      phoneUtil.parse('8 (423) 202-25-11доб100', RegionCode.RU)));
3438  // Testing in unicode format
3439  assertTrue(ruWithExtension.equals(
3440      phoneUtil.parse('8 (423) 202-25-11, \u0434\u043E\u0431. 100',
3441                      RegionCode.RU)));
3442  // In upper case
3443  assertTrue(ruWithExtension.equals(
3444      phoneUtil.parse('8 (423) 202-25-11ДОБ100', RegionCode.RU)));
3445  assertTrue(ruWithExtension.equals(
3446      phoneUtil.parse('8 (423) 202-25-11\u0414\u041E\u0411100', RegionCode.RU)));
3447
3448  // Test that if a number has two extensions specified, we ignore the second.
3449  /** @type {!i18n.phonenumbers.PhoneNumber} */
3450  var usWithTwoExtensionsNumber = new i18n.phonenumbers.PhoneNumber();
3451  usWithTwoExtensionsNumber.setCountryCode(1);
3452  usWithTwoExtensionsNumber.setNationalNumber(2121231234);
3453  usWithTwoExtensionsNumber.setExtension('508');
3454  assertTrue(usWithTwoExtensionsNumber.equals(
3455      phoneUtil.parse('(212)123-1234 x508/x1234', RegionCode.US)));
3456  assertTrue(usWithTwoExtensionsNumber.equals(
3457      phoneUtil.parse('(212)123-1234 x508/ x1234', RegionCode.US)));
3458  assertTrue(usWithTwoExtensionsNumber.equals(
3459      phoneUtil.parse('(212)123-1234 x508\\x1234', RegionCode.US)));
3460
3461  // Test parsing numbers in the form (645) 123-1234-910# works, where the last
3462  // 3 digits before the # are an extension.
3463  usWithExtension = new i18n.phonenumbers.PhoneNumber();
3464  usWithExtension.setCountryCode(1);
3465  usWithExtension.setNationalNumber(6451231234);
3466  usWithExtension.setExtension('910');
3467  assertTrue(usWithExtension.equals(
3468      phoneUtil.parse('+1 (645) 123 1234-910#', RegionCode.US)));
3469  // Retry with the same number in a slightly different format.
3470  assertTrue(usWithExtension.equals(
3471      phoneUtil.parse('+1 (645) 123 1234 ext. 910#', RegionCode.US)));
3472}
3473
3474function testParseAndKeepRaw() {
3475  var CCS = i18n.phonenumbers.PhoneNumber.CountryCodeSource;
3476  /** @type {!i18n.phonenumbers.PhoneNumber} */
3477  var alphaNumericNumber = ALPHA_NUMERIC_NUMBER.clone();
3478  alphaNumericNumber.setRawInput('800 six-flags');
3479  alphaNumericNumber.setCountryCodeSource(CCS.FROM_DEFAULT_COUNTRY);
3480  assertTrue(alphaNumericNumber.equals(
3481      phoneUtil.parseAndKeepRawInput('800 six-flags', RegionCode.US)));
3482
3483  /** @type {!i18n.phonenumbers.PhoneNumber} */
3484  var shorterAlphaNumber = new i18n.phonenumbers.PhoneNumber();
3485  shorterAlphaNumber.setCountryCode(1);
3486  shorterAlphaNumber.setNationalNumber(8007493524);
3487  shorterAlphaNumber.setRawInput('1800 six-flag');
3488  shorterAlphaNumber.setCountryCodeSource(CCS.FROM_NUMBER_WITHOUT_PLUS_SIGN);
3489  assertTrue(shorterAlphaNumber.equals(
3490      phoneUtil.parseAndKeepRawInput('1800 six-flag', RegionCode.US)));
3491
3492  shorterAlphaNumber.setRawInput('+1800 six-flag');
3493  shorterAlphaNumber.setCountryCodeSource(CCS.FROM_NUMBER_WITH_PLUS_SIGN);
3494  assertTrue(shorterAlphaNumber.equals(
3495      phoneUtil.parseAndKeepRawInput('+1800 six-flag', RegionCode.NZ)));
3496
3497  alphaNumericNumber.setCountryCode(1);
3498  alphaNumericNumber.setNationalNumber(8007493524);
3499  alphaNumericNumber.setRawInput('001800 six-flag');
3500  alphaNumericNumber.setCountryCodeSource(CCS.FROM_NUMBER_WITH_IDD);
3501  assertTrue(alphaNumericNumber.equals(
3502      phoneUtil.parseAndKeepRawInput('001800 six-flag', RegionCode.NZ)));
3503
3504  // Invalid region code supplied.
3505  try {
3506    phoneUtil.parseAndKeepRawInput('123 456 7890', RegionCode.CS);
3507    fail('Deprecated region code not allowed: should fail.');
3508  } catch (e) {
3509    // Expected this exception.
3510    assertEquals('Wrong error type stored in exception.',
3511                 i18n.phonenumbers.Error.INVALID_COUNTRY_CODE,
3512                 e.message);
3513  }
3514
3515  /** @type {!i18n.phonenumbers.PhoneNumber} */
3516  var koreanNumber = new i18n.phonenumbers.PhoneNumber();
3517  koreanNumber.setCountryCode(82);
3518  koreanNumber.setNationalNumber(22123456);
3519  koreanNumber.setRawInput('08122123456');
3520  koreanNumber.setCountryCodeSource(CCS.FROM_DEFAULT_COUNTRY);
3521  koreanNumber.setPreferredDomesticCarrierCode('81');
3522  assertTrue(koreanNumber.equals(
3523      phoneUtil.parseAndKeepRawInput('08122123456', RegionCode.KR)));
3524}
3525
3526function testParseItalianLeadingZeros() {
3527  // Test the number "011".
3528  /** @type {!i18n.phonenumbers.PhoneNumber} */
3529  var oneZero = new i18n.phonenumbers.PhoneNumber();
3530  oneZero.setCountryCode(61);
3531  oneZero.setNationalNumber(11);
3532  oneZero.setItalianLeadingZero(true);
3533  assertTrue(oneZero.equals(phoneUtil.parse('011', RegionCode.AU)));
3534
3535  // Test the number "001".
3536  /** @type {!i18n.phonenumbers.PhoneNumber} */
3537  var twoZeros = new i18n.phonenumbers.PhoneNumber();
3538  twoZeros.setCountryCode(61);
3539  twoZeros.setNationalNumber(1);
3540  twoZeros.setItalianLeadingZero(true);
3541  twoZeros.setNumberOfLeadingZeros(2);
3542  assertTrue(twoZeros.equals(phoneUtil.parse('001', RegionCode.AU)));
3543
3544  // Test the number "000". This number has 2 leading zeros.
3545  /** @type {!i18n.phonenumbers.PhoneNumber} */
3546  var stillTwoZeros = new i18n.phonenumbers.PhoneNumber();
3547  stillTwoZeros.setCountryCode(61);
3548  stillTwoZeros.setNationalNumber(0);
3549  stillTwoZeros.setItalianLeadingZero(true);
3550  stillTwoZeros.setNumberOfLeadingZeros(2);
3551  assertTrue(stillTwoZeros.equals(phoneUtil.parse('000', RegionCode.AU)));
3552
3553  // Test the number "0000". This number has 3 leading zeros.
3554  /** @type {!i18n.phonenumbers.PhoneNumber} */
3555  var threeZeros = new i18n.phonenumbers.PhoneNumber();
3556  threeZeros.setCountryCode(61);
3557  threeZeros.setNationalNumber(0);
3558  threeZeros.setItalianLeadingZero(true);
3559  threeZeros.setNumberOfLeadingZeros(3);
3560  assertTrue(threeZeros.equals(phoneUtil.parse('0000', RegionCode.AU)));
3561}
3562
3563function testCountryWithNoNumberDesc() {
3564  var PNF = i18n.phonenumbers.PhoneNumberFormat;
3565  var PNT = i18n.phonenumbers.PhoneNumberType;
3566  // Andorra is a country where we don't have PhoneNumberDesc info in the
3567  // metadata.
3568  /** @type {!i18n.phonenumbers.PhoneNumber} */
3569  var adNumber = new i18n.phonenumbers.PhoneNumber();
3570  adNumber.setCountryCode(376);
3571  adNumber.setNationalNumber(12345);
3572  assertEquals('+376 12345', phoneUtil.format(adNumber, PNF.INTERNATIONAL));
3573  assertEquals('+37612345', phoneUtil.format(adNumber, PNF.E164));
3574  assertEquals('12345', phoneUtil.format(adNumber, PNF.NATIONAL));
3575  assertEquals(PNT.UNKNOWN, phoneUtil.getNumberType(adNumber));
3576  assertFalse(phoneUtil.isValidNumber(adNumber));
3577
3578  // Test dialing a US number from within Andorra.
3579  assertEquals('00 1 650 253 0000',
3580               phoneUtil.formatOutOfCountryCallingNumber(US_NUMBER,
3581                                                         RegionCode.AD));
3582}
3583
3584function testUnknownCountryCallingCode() {
3585  var PNF = i18n.phonenumbers.PhoneNumberFormat;
3586  assertFalse(phoneUtil.isValidNumber(UNKNOWN_COUNTRY_CODE_NO_RAW_INPUT));
3587  // It's not very well defined as to what the E164 representation for a number
3588  // with an invalid country calling code is, but just prefixing the country
3589  // code and national number is about the best we can do.
3590  assertEquals('+212345',
3591               phoneUtil.format(UNKNOWN_COUNTRY_CODE_NO_RAW_INPUT, PNF.E164));
3592}
3593
3594function testIsNumberMatchMatches() {
3595  // Test simple matches where formatting is different, or leading zeros, or
3596  // country calling code has been specified.
3597  /** @type {!i18n.phonenumbers.PhoneNumber} */
3598  var num1 = phoneUtil.parse('+64 3 331 6005', RegionCode.NZ);
3599  /** @type {!i18n.phonenumbers.PhoneNumber} */
3600  var num2 = phoneUtil.parse('+64 03 331 6005', RegionCode.NZ);
3601  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH,
3602               phoneUtil.isNumberMatch(num1, num2));
3603  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH,
3604               phoneUtil.isNumberMatch('+64 3 331 6005', '+64 03 331 6005'));
3605  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH,
3606               phoneUtil.isNumberMatch('+800 1234 5678', '+80012345678'));
3607  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH,
3608               phoneUtil.isNumberMatch('+64 03 331-6005', '+64 03331 6005'));
3609  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH,
3610               phoneUtil.isNumberMatch('+643 331-6005', '+64033316005'));
3611  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH,
3612               phoneUtil.isNumberMatch('+643 331-6005', '+6433316005'));
3613  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH,
3614               phoneUtil.isNumberMatch('+64 3 331-6005', '+6433316005'));
3615  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH,
3616               phoneUtil.isNumberMatch('+64 3 331-6005',
3617                                       'tel:+64-3-331-6005;isub=123'));
3618  // Test alpha numbers.
3619  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH,
3620               phoneUtil.isNumberMatch('+1800 siX-Flags', '+1 800 7493 5247'));
3621  // Test numbers with extensions.
3622  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH,
3623               phoneUtil.isNumberMatch('+64 3 331-6005 extn 1234',
3624                                       '+6433316005#1234'));
3625  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH,
3626               phoneUtil.isNumberMatch('+64 3 331-6005 ext. 1234',
3627                                       '+6433316005;1234'));
3628  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH,
3629                 phoneUtil.isNumberMatch('+7 423 202-25-11 ext 100',
3630                                         '+7 4232022511 доб. 100'));
3631  // Test proto buffers.
3632  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH,
3633               phoneUtil.isNumberMatch(NZ_NUMBER, '+6403 331 6005'));
3634
3635  /** @type {!i18n.phonenumbers.PhoneNumber} */
3636  var nzNumber = NZ_NUMBER.clone();
3637  nzNumber.setExtension('3456');
3638  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH,
3639               phoneUtil.isNumberMatch(nzNumber, '+643 331 6005 ext 3456'));
3640  // Check empty extensions are ignored.
3641  nzNumber.setExtension('');
3642  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH,
3643               phoneUtil.isNumberMatch(nzNumber, '+6403 331 6005'));
3644  // Check variant with two proto buffers.
3645  assertEquals('Numbers did not match',
3646               i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH,
3647               phoneUtil.isNumberMatch(nzNumber, NZ_NUMBER));
3648}
3649
3650function testIsNumberMatchShortMatchIfDiffNumLeadingZeros() {
3651  /** @type {!i18n.phonenumbers.PhoneNumber} */
3652  var nzNumberOne = new i18n.phonenumbers.PhoneNumber();
3653  /** @type {!i18n.phonenumbers.PhoneNumber} */
3654  var nzNumberTwo = new i18n.phonenumbers.PhoneNumber();
3655
3656  nzNumberOne.setCountryCode(64);
3657  nzNumberOne.setNationalNumber(33316005);
3658  nzNumberOne.setItalianLeadingZero(true);
3659
3660  nzNumberTwo.setCountryCode(64);
3661  nzNumberTwo.setNationalNumber(33316005);
3662  nzNumberTwo.setItalianLeadingZero(true);
3663  nzNumberTwo.setNumberOfLeadingZeros(2);
3664
3665  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3666               phoneUtil.isNumberMatch(nzNumberOne, nzNumberTwo));
3667
3668  nzNumberOne.setItalianLeadingZero(false);
3669  nzNumberOne.setNumberOfLeadingZeros(1);
3670  nzNumberTwo.setItalianLeadingZero(true);
3671  nzNumberTwo.setNumberOfLeadingZeros(1);
3672  // Since one doesn't have the "italian_leading_zero" set to true, we ignore
3673  // the number of leading zeros present (1 is in any case the default value).
3674  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3675               phoneUtil.isNumberMatch(nzNumberOne, nzNumberTwo));
3676}
3677
3678function testIsNumberMatchAcceptsProtoDefaultsAsMatch() {
3679  /** @type {!i18n.phonenumbers.PhoneNumber} */
3680  var nzNumberOne = new i18n.phonenumbers.PhoneNumber();
3681  /** @type {!i18n.phonenumbers.PhoneNumber} */
3682  var nzNumberTwo = new i18n.phonenumbers.PhoneNumber();
3683
3684  nzNumberOne.setCountryCode(64);
3685  nzNumberOne.setNationalNumber(33316005);
3686  nzNumberOne.setItalianLeadingZero(true);
3687
3688  // The default for number_of_leading_zeros is 1, so it shouldn't normally be
3689  // set, however if it is it should be considered equivalent.
3690  nzNumberTwo.setCountryCode(64);
3691  nzNumberTwo.setNationalNumber(33316005);
3692  nzNumberTwo.setItalianLeadingZero(true);
3693  nzNumberTwo.setNumberOfLeadingZeros(1);
3694
3695  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH,
3696               phoneUtil.isNumberMatch(nzNumberOne, nzNumberTwo));
3697}
3698
3699function testIsNumberMatchMatchesDiffLeadingZerosIfItalianLeadingZeroFalse() {
3700  /** @type {!i18n.phonenumbers.PhoneNumber} */
3701  var nzNumberOne = new i18n.phonenumbers.PhoneNumber();
3702  /** @type {!i18n.phonenumbers.PhoneNumber} */
3703  var nzNumberTwo = new i18n.phonenumbers.PhoneNumber();
3704
3705  nzNumberOne.setCountryCode(64);
3706  nzNumberOne.setNationalNumber(33316005);
3707
3708  // The default for number_of_leading_zeros is 1, so it shouldn't normally be
3709  // set, however if it is it should be considered equivalent.
3710  nzNumberTwo.setCountryCode(64);
3711  nzNumberTwo.setNationalNumber(33316005);
3712  nzNumberTwo.setNumberOfLeadingZeros(1);
3713
3714  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH,
3715               phoneUtil.isNumberMatch(nzNumberOne, nzNumberTwo));
3716
3717  // Even if it is set to ten, it is still equivalent because in both cases
3718  // italian_leading_zero is not true.
3719  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH,
3720               phoneUtil.isNumberMatch(nzNumberOne, nzNumberTwo));
3721}
3722
3723function testIsNumberMatchIgnoresSomeFields() {
3724  var CCS = i18n.phonenumbers.PhoneNumber.CountryCodeSource;
3725  // Check raw_input, country_code_source and preferred_domestic_carrier_code
3726  // are ignored.
3727  /** @type {!i18n.phonenumbers.PhoneNumber} */
3728  var brNumberOne = new i18n.phonenumbers.PhoneNumber();
3729  /** @type {!i18n.phonenumbers.PhoneNumber} */
3730  var brNumberTwo = new i18n.phonenumbers.PhoneNumber();
3731  brNumberOne.setCountryCode(55);
3732  brNumberOne.setNationalNumber(3121286979);
3733  brNumberOne.setCountryCodeSource(CCS.FROM_NUMBER_WITH_PLUS_SIGN);
3734  brNumberOne.setPreferredDomesticCarrierCode('12');
3735  brNumberOne.setRawInput('012 3121286979');
3736  brNumberTwo.setCountryCode(55);
3737  brNumberTwo.setNationalNumber(3121286979);
3738  brNumberTwo.setCountryCodeSource(CCS.FROM_DEFAULT_COUNTRY);
3739  brNumberTwo.setPreferredDomesticCarrierCode('14');
3740  brNumberTwo.setRawInput('143121286979');
3741  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.EXACT_MATCH,
3742               phoneUtil.isNumberMatch(brNumberOne, brNumberTwo));
3743}
3744
3745function testIsNumberMatchNonMatches() {
3746  // Non-matches.
3747  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NO_MATCH,
3748               phoneUtil.isNumberMatch('03 331 6005', '03 331 6006'));
3749  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NO_MATCH,
3750               phoneUtil.isNumberMatch('+800 1234 5678', '+1 800 1234 5678'));
3751  // Different country calling code, partial number match.
3752  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NO_MATCH,
3753               phoneUtil.isNumberMatch('+64 3 331-6005', '+16433316005'));
3754  // Different country calling code, same number.
3755  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NO_MATCH,
3756               phoneUtil.isNumberMatch('+64 3 331-6005', '+6133316005'));
3757  // Extension different, all else the same.
3758  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NO_MATCH,
3759               phoneUtil.isNumberMatch('+64 3 331-6005 extn 1234',
3760                                       '0116433316005#1235'));
3761  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NO_MATCH,
3762               phoneUtil.isNumberMatch('+64 3 331-6005 extn 1234',
3763                                       'tel:+64-3-331-6005;ext=1235'));
3764  // NSN matches, but extension is different - not the same number.
3765  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NO_MATCH,
3766               phoneUtil.isNumberMatch('+64 3 331-6005 ext.1235',
3767                                       '3 331 6005#1234'));
3768
3769  // Invalid numbers that can't be parsed.
3770  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NOT_A_NUMBER,
3771               phoneUtil.isNumberMatch('4', '3 331 6043'));
3772  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NOT_A_NUMBER,
3773               phoneUtil.isNumberMatch('+43', '+64 3 331 6005'));
3774  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NOT_A_NUMBER,
3775               phoneUtil.isNumberMatch('+43', '64 3 331 6005'));
3776  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NOT_A_NUMBER,
3777               phoneUtil.isNumberMatch('Dog', '64 3 331 6005'));
3778}
3779
3780function testIsNumberMatchNsnMatches() {
3781  // NSN matches.
3782  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NSN_MATCH,
3783               phoneUtil.isNumberMatch('+64 3 331-6005', '03 331 6005'));
3784  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NSN_MATCH,
3785               phoneUtil.isNumberMatch('+64 3 331-6005',
3786               'tel:03-331-6005;isub=1234;phone-context=abc.nz'));
3787  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NSN_MATCH,
3788               phoneUtil.isNumberMatch(NZ_NUMBER, '03 331 6005'));
3789  // Here the second number possibly starts with the country calling code for
3790  // New Zealand, although we are unsure.
3791  /** @type {!i18n.phonenumbers.PhoneNumber} */
3792  var unchangedNzNumber = NZ_NUMBER.clone();
3793  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NSN_MATCH,
3794               phoneUtil.isNumberMatch(unchangedNzNumber, '(64-3) 331 6005'));
3795  // Check the phone number proto was not edited during the method call.
3796  assertTrue(NZ_NUMBER.equals(unchangedNzNumber));
3797
3798  // Here, the 1 might be a national prefix, if we compare it to the US number,
3799  // so the resultant match is an NSN match.
3800  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NSN_MATCH,
3801               phoneUtil.isNumberMatch(US_NUMBER, '1-650-253-0000'));
3802  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NSN_MATCH,
3803               phoneUtil.isNumberMatch(US_NUMBER, '6502530000'));
3804  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NSN_MATCH,
3805               phoneUtil.isNumberMatch('+1 650-253 0000', '1 650 253 0000'));
3806  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NSN_MATCH,
3807               phoneUtil.isNumberMatch('1 650-253 0000', '1 650 253 0000'));
3808  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.NSN_MATCH,
3809               phoneUtil.isNumberMatch('1 650-253 0000', '+1 650 253 0000'));
3810  // For this case, the match will be a short NSN match, because we cannot
3811  // assume that the 1 might be a national prefix, so don't remove it when
3812  // parsing.
3813  /** @type {!i18n.phonenumbers.PhoneNumber} */
3814  var randomNumber = new i18n.phonenumbers.PhoneNumber();
3815  randomNumber.setCountryCode(41);
3816  randomNumber.setNationalNumber(6502530000);
3817  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3818               phoneUtil.isNumberMatch(randomNumber, '1-650-253-0000'));
3819}
3820
3821function testIsNumberMatchShortNsnMatches() {
3822  // Short NSN matches with the country not specified for either one or both
3823  // numbers.
3824  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3825               phoneUtil.isNumberMatch('+64 3 331-6005', '331 6005'));
3826  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3827               phoneUtil.isNumberMatch('+64 3 331-6005',
3828                                       'tel:331-6005;phone-context=abc.nz'));
3829  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3830               phoneUtil.isNumberMatch(
3831                   '+64 3 331-6005',
3832                   'tel:331-6005;isub=1234;phone-context=abc.nz'));
3833  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3834               phoneUtil.isNumberMatch(
3835                   '+64 3 331-6005',
3836                   'tel:331-6005;isub=1234;phone-context=abc.nz;a=%A1'));
3837  // We did not know that the '0' was a national prefix since neither number has
3838  // a country code, so this is considered a SHORT_NSN_MATCH.
3839  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3840               phoneUtil.isNumberMatch('3 331-6005', '03 331 6005'));
3841  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3842               phoneUtil.isNumberMatch('3 331-6005', '331 6005'));
3843  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3844               phoneUtil.isNumberMatch('3 331-6005',
3845                                       'tel:331-6005;phone-context=abc.nz'));
3846  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3847               phoneUtil.isNumberMatch('3 331-6005', '+64 331 6005'));
3848  // Short NSN match with the country specified.
3849  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3850               phoneUtil.isNumberMatch('03 331-6005', '331 6005'));
3851  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3852               phoneUtil.isNumberMatch('1 234 345 6789', '345 6789'));
3853  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3854               phoneUtil.isNumberMatch('+1 (234) 345 6789', '345 6789'));
3855  // NSN matches, country calling code omitted for one number, extension missing
3856  // for one.
3857  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3858               phoneUtil.isNumberMatch('+64 3 331-6005', '3 331 6005#1234'));
3859  // One has Italian leading zero, one does not.
3860  /** @type {!i18n.phonenumbers.PhoneNumber} */
3861  var italianNumberOne = new i18n.phonenumbers.PhoneNumber();
3862  italianNumberOne.setCountryCode(39);
3863  italianNumberOne.setNationalNumber(1234);
3864  italianNumberOne.setItalianLeadingZero(true);
3865  /** @type {!i18n.phonenumbers.PhoneNumber} */
3866  var italianNumberTwo = new i18n.phonenumbers.PhoneNumber();
3867  italianNumberTwo.setCountryCode(39);
3868  italianNumberTwo.setNationalNumber(1234);
3869  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3870               phoneUtil.isNumberMatch(italianNumberOne, italianNumberTwo));
3871  // One has an extension, the other has an extension of ''.
3872  italianNumberOne.setExtension('1234');
3873  italianNumberOne.clearItalianLeadingZero();
3874  italianNumberTwo.setExtension('');
3875  assertEquals(i18n.phonenumbers.PhoneNumberUtil.MatchType.SHORT_NSN_MATCH,
3876               phoneUtil.isNumberMatch(italianNumberOne, italianNumberTwo));
3877}
3878
3879function testCanBeInternationallyDialled() {
3880  // We have no-international-dialling rules for the US in our test metadata
3881  // that say that toll-free numbers cannot be dialled internationally.
3882  assertFalse(phoneUtil.canBeInternationallyDialled(US_TOLLFREE));
3883
3884  // Normal US numbers can be internationally dialled.
3885  assertTrue(phoneUtil.canBeInternationallyDialled(US_NUMBER));
3886
3887  // Invalid number.
3888  assertTrue(phoneUtil.canBeInternationallyDialled(US_LOCAL_NUMBER));
3889
3890  // We have no data for NZ - should return true.
3891  assertTrue(phoneUtil.canBeInternationallyDialled(NZ_NUMBER));
3892  assertTrue(phoneUtil.canBeInternationallyDialled(INTERNATIONAL_TOLL_FREE));
3893}
3894
3895function testIsAlphaNumber() {
3896  assertTrue(phoneUtil.isAlphaNumber('1800 six-flags'));
3897  assertTrue(phoneUtil.isAlphaNumber('1800 six-flags ext. 1234'));
3898  assertTrue(phoneUtil.isAlphaNumber('+800 six-flags'));
3899  assertTrue(phoneUtil.isAlphaNumber('180 six-flags'));
3900  assertFalse(phoneUtil.isAlphaNumber('1800 123-1234'));
3901  assertFalse(phoneUtil.isAlphaNumber('1 six-flags'));
3902  assertFalse(phoneUtil.isAlphaNumber('18 six-flags'));
3903  assertFalse(phoneUtil.isAlphaNumber('1800 123-1234 extension: 1234'));
3904  assertFalse(phoneUtil.isAlphaNumber('+800 1234-1234'));
3905}
3906