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