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