parse.test.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
  2. function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
  3. function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
  4. import metadata from '../metadata.min.json' assert { type: 'json' };
  5. import _parseNumber from './parse.js';
  6. import Metadata from './metadata.js';
  7. function parseNumber() {
  8. for (var _len = arguments.length, parameters = new Array(_len), _key = 0; _key < _len; _key++) {
  9. parameters[_key] = arguments[_key];
  10. }
  11. if (parameters.length < 2) {
  12. // `options` parameter.
  13. parameters.push(undefined);
  14. } // Convert default country argument to an `options` object.
  15. if (typeof parameters[1] === 'string') {
  16. parameters[1] = _objectSpread(_objectSpread({}, parameters[2]), {}, {
  17. defaultCountry: parameters[1]
  18. });
  19. }
  20. if (parameters[2]) {
  21. parameters[2] = metadata;
  22. } else {
  23. parameters.push(metadata);
  24. }
  25. return _parseNumber.apply(this, parameters);
  26. }
  27. var USE_NON_GEOGRAPHIC_COUNTRY_CODE = false;
  28. describe('parse', function () {
  29. it('should not parse invalid phone numbers', function () {
  30. // Too short.
  31. parseNumber('+7 (800) 55-35-35').should.deep.equal({}); // Too long.
  32. parseNumber('+7 (800) 55-35-35-55').should.deep.equal({});
  33. parseNumber('+7 (800) 55-35-35', 'US').should.deep.equal({});
  34. parseNumber('(800) 55 35 35', {
  35. defaultCountry: 'RU'
  36. }).should.deep.equal({});
  37. parseNumber('+1 187 215 5230', 'US').should.deep.equal({});
  38. parseNumber('911231231', 'BE').should.deep.equal({});
  39. });
  40. it('should parse valid phone numbers', function () {
  41. // Instant loans
  42. // https://www.youtube.com/watch?v=6e1pMrYH5jI
  43. //
  44. // Restrict to RU
  45. parseNumber('Phone: 8 (800) 555 35 35.', 'RU').should.deep.equal({
  46. country: 'RU',
  47. phone: '8005553535'
  48. }); // International format
  49. parseNumber('Phone: +7 (800) 555-35-35.').should.deep.equal({
  50. country: 'RU',
  51. phone: '8005553535'
  52. }); // // Restrict to US, but not a US country phone code supplied
  53. // parseNumber('+7 (800) 555-35-35', 'US').should.deep.equal({})
  54. // Restrict to RU
  55. parseNumber('(800) 555 35 35', 'RU').should.deep.equal({
  56. country: 'RU',
  57. phone: '8005553535'
  58. }); // Default to RU
  59. parseNumber('8 (800) 555 35 35', {
  60. defaultCountry: 'RU'
  61. }).should.deep.equal({
  62. country: 'RU',
  63. phone: '8005553535'
  64. }); // Gangster partyline
  65. parseNumber('+1-213-373-4253').should.deep.equal({
  66. country: 'US',
  67. phone: '2133734253'
  68. }); // Switzerland (just in case)
  69. parseNumber('044 668 18 00', 'CH').should.deep.equal({
  70. country: 'CH',
  71. phone: '446681800'
  72. }); // China, Beijing
  73. parseNumber('010-852644821', 'CN').should.deep.equal({
  74. country: 'CN',
  75. phone: '10852644821'
  76. }); // France
  77. parseNumber('+33169454850').should.deep.equal({
  78. country: 'FR',
  79. phone: '169454850'
  80. }); // UK (Jersey)
  81. parseNumber('+44 7700 300000').should.deep.equal({
  82. country: 'JE',
  83. phone: '7700300000'
  84. }); // KZ
  85. parseNumber('+7 702 211 1111').should.deep.equal({
  86. country: 'KZ',
  87. phone: '7022111111'
  88. }); // Brazil
  89. parseNumber('11987654321', 'BR').should.deep.equal({
  90. country: 'BR',
  91. phone: '11987654321'
  92. }); // Long country phone code.
  93. parseNumber('+212659777777').should.deep.equal({
  94. country: 'MA',
  95. phone: '659777777'
  96. }); // No country could be derived.
  97. // parseNumber('+212569887076').should.deep.equal({ countryPhoneCode: '212', phone: '569887076' })
  98. // GB. Moible numbers starting 07624* are Isle of Man.
  99. parseNumber('07624369230', 'GB').should.deep.equal({
  100. country: 'IM',
  101. phone: '7624369230'
  102. });
  103. });
  104. it('should parse possible numbers', function () {
  105. // Invalid phone number for a given country.
  106. parseNumber('1112223344', 'RU', {
  107. extended: true
  108. }).should.deep.equal({
  109. country: 'RU',
  110. countryCallingCode: '7',
  111. phone: '1112223344',
  112. carrierCode: undefined,
  113. ext: undefined,
  114. valid: false,
  115. possible: true
  116. }); // International phone number.
  117. // Several countries with the same country phone code.
  118. parseNumber('+71112223344').should.deep.equal({});
  119. parseNumber('+71112223344', {
  120. extended: true
  121. }).should.deep.equal({
  122. country: undefined,
  123. countryCallingCode: '7',
  124. phone: '1112223344',
  125. carrierCode: undefined,
  126. ext: undefined,
  127. valid: false,
  128. possible: true
  129. }); // International phone number.
  130. // Single country with the given country phone code.
  131. parseNumber('+33011222333', {
  132. extended: true
  133. }).should.deep.equal({
  134. country: 'FR',
  135. countryCallingCode: '33',
  136. phone: '011222333',
  137. carrierCode: undefined,
  138. ext: undefined,
  139. valid: false,
  140. possible: true
  141. }); // Too short.
  142. // Won't strip national prefix `8` because otherwise the number would be too short.
  143. parseNumber('+7 (800) 55-35-35', {
  144. extended: true
  145. }).should.deep.equal({
  146. country: 'RU',
  147. countryCallingCode: '7',
  148. phone: '800553535',
  149. carrierCode: undefined,
  150. ext: undefined,
  151. valid: false,
  152. possible: false
  153. }); // Too long.
  154. parseNumber('+1 213 37342530', {
  155. extended: true
  156. }).should.deep.equal({
  157. country: undefined,
  158. countryCallingCode: '1',
  159. phone: '21337342530',
  160. carrierCode: undefined,
  161. ext: undefined,
  162. valid: false,
  163. possible: false
  164. }); // No national number to be parsed.
  165. parseNumber('+996', {
  166. extended: true
  167. }).should.deep.equal({// countryCallingCode : '996'
  168. }); // Valid number.
  169. parseNumber('+78005553535', {
  170. extended: true
  171. }).should.deep.equal({
  172. country: 'RU',
  173. countryCallingCode: '7',
  174. phone: '8005553535',
  175. carrierCode: undefined,
  176. ext: undefined,
  177. valid: true,
  178. possible: true
  179. }); // https://github.com/catamphetamine/libphonenumber-js/issues/211
  180. parseNumber('+966', {
  181. extended: true
  182. }).should.deep.equal({});
  183. parseNumber('+9664', {
  184. extended: true
  185. }).should.deep.equal({});
  186. parseNumber('+96645', {
  187. extended: true
  188. }).should.deep.equal({
  189. carrierCode: undefined,
  190. phone: '45',
  191. ext: undefined,
  192. country: 'SA',
  193. countryCallingCode: '966',
  194. possible: false,
  195. valid: false
  196. });
  197. });
  198. it('should parse non-European digits', function () {
  199. parseNumber('+١٢١٢٢٣٢٣٢٣٢').should.deep.equal({
  200. country: 'US',
  201. phone: '2122323232'
  202. });
  203. });
  204. it('should work in edge cases', function () {
  205. var thrower; // No input
  206. parseNumber('').should.deep.equal({}); // No country phone code
  207. parseNumber('+').should.deep.equal({}); // No country at all (non international number and no explicit country code)
  208. parseNumber('123').should.deep.equal({}); // No country metadata for this `require` country code
  209. thrower = function thrower() {
  210. return parseNumber('123', 'ZZ');
  211. };
  212. thrower.should["throw"]('Unknown country'); // No country metadata for this `default` country code
  213. thrower = function thrower() {
  214. return parseNumber('123', {
  215. defaultCountry: 'ZZ'
  216. });
  217. };
  218. thrower.should["throw"]('Unknown country'); // Invalid country phone code
  219. parseNumber('+210').should.deep.equal({}); // Invalid country phone code (extended parsing mode)
  220. parseNumber('+210', {
  221. extended: true
  222. }).should.deep.equal({}); // Too short of a number.
  223. parseNumber('1', 'US', {
  224. extended: true
  225. }).should.deep.equal({}); // Too long of a number.
  226. parseNumber('1111111111111111111', 'RU', {
  227. extended: true
  228. }).should.deep.equal({}); // Not a number.
  229. parseNumber('abcdefg', 'US', {
  230. extended: true
  231. }).should.deep.equal({}); // Country phone code beginning with a '0'
  232. parseNumber('+0123').should.deep.equal({}); // Barbados NANPA phone number
  233. parseNumber('+12460000000').should.deep.equal({
  234. country: 'BB',
  235. phone: '2460000000'
  236. }); // // A case when country (restricted to) is not equal
  237. // // to the one parsed out of an international number.
  238. // parseNumber('+1-213-373-4253', 'RU').should.deep.equal({})
  239. // National (significant) number too short
  240. parseNumber('2', 'US').should.deep.equal({}); // National (significant) number too long
  241. parseNumber('222222222222222222', 'US').should.deep.equal({}); // No `national_prefix_for_parsing`
  242. parseNumber('41111', 'AC').should.deep.equal({
  243. country: 'AC',
  244. phone: '41111'
  245. }); // https://github.com/catamphetamine/libphonenumber-js/issues/235
  246. // `matchesEntirely()` bug fix.
  247. parseNumber('+4915784846111‬').should.deep.equal({
  248. country: 'DE',
  249. phone: '15784846111'
  250. }); // No metadata
  251. thrower = function thrower() {
  252. return _parseNumber('');
  253. };
  254. thrower.should["throw"]('`metadata` argument not passed'); // // Numerical `value`
  255. // thrower = () => parseNumber(2141111111, 'US')
  256. // thrower.should.throw('A text for parsing must be a string.')
  257. // Input string too long.
  258. parseNumber('8005553535 ', 'RU').should.deep.equal({});
  259. });
  260. it('should parse phone number extensions', function () {
  261. // "ext"
  262. parseNumber('2134567890 ext 123', 'US').should.deep.equal({
  263. country: 'US',
  264. phone: '2134567890',
  265. ext: '123'
  266. }); // "ext."
  267. parseNumber('+12134567890 ext. 12345', 'US').should.deep.equal({
  268. country: 'US',
  269. phone: '2134567890',
  270. ext: '12345'
  271. }); // "доб."
  272. parseNumber('+78005553535 доб. 1234', 'RU').should.deep.equal({
  273. country: 'RU',
  274. phone: '8005553535',
  275. ext: '1234'
  276. }); // "#"
  277. parseNumber('+12134567890#1234').should.deep.equal({
  278. country: 'US',
  279. phone: '2134567890',
  280. ext: '1234'
  281. }); // "x"
  282. parseNumber('+78005553535 x1234').should.deep.equal({
  283. country: 'RU',
  284. phone: '8005553535',
  285. ext: '1234'
  286. }); // Not a valid extension
  287. parseNumber('2134567890 ext. abc', 'US').should.deep.equal({
  288. country: 'US',
  289. phone: '2134567890'
  290. });
  291. });
  292. it('should parse RFC 3966 phone numbers', function () {
  293. parseNumber('tel:+78005553535;ext=123').should.deep.equal({
  294. country: 'RU',
  295. phone: '8005553535',
  296. ext: '123'
  297. }); // Should parse "visual separators".
  298. parseNumber('tel:+7(800)555-35.35;ext=123').should.deep.equal({
  299. country: 'RU',
  300. phone: '8005553535',
  301. ext: '123'
  302. }); // Invalid number.
  303. parseNumber('tel:+7x8005553535;ext=123').should.deep.equal({});
  304. });
  305. it('should parse invalid international numbers even if they are invalid', function () {
  306. parseNumber('+7(8)8005553535', 'RU').should.deep.equal({
  307. country: 'RU',
  308. phone: '8005553535'
  309. });
  310. });
  311. it('should parse carrier codes', function () {
  312. parseNumber('0 15 21 5555-5555', 'BR', {
  313. extended: true
  314. }).should.deep.equal({
  315. country: 'BR',
  316. countryCallingCode: '55',
  317. phone: '2155555555',
  318. carrierCode: '15',
  319. ext: undefined,
  320. valid: true,
  321. possible: true
  322. });
  323. });
  324. it('should parse IDD prefixes', function () {
  325. parseNumber('011 61 2 3456 7890', 'US').should.deep.equal({
  326. phone: '234567890',
  327. country: 'AU'
  328. });
  329. parseNumber('011 61 2 3456 7890', 'FR').should.deep.equal({});
  330. parseNumber('00 61 2 3456 7890', 'US').should.deep.equal({});
  331. parseNumber('810 61 2 3456 7890', 'RU').should.deep.equal({
  332. phone: '234567890',
  333. country: 'AU'
  334. });
  335. });
  336. it('should work with v2 API', function () {
  337. parseNumber('+99989160151539');
  338. });
  339. it('should work with Argentina numbers', function () {
  340. // The same mobile number is written differently
  341. // in different formats in Argentina:
  342. // `9` gets prepended in international format.
  343. parseNumber('+54 9 3435 55 1212').should.deep.equal({
  344. country: 'AR',
  345. phone: '93435551212'
  346. });
  347. parseNumber('0343 15-555-1212', 'AR').should.deep.equal({
  348. country: 'AR',
  349. phone: '93435551212'
  350. });
  351. });
  352. it('should work with Mexico numbers', function () {
  353. // Fixed line.
  354. parseNumber('+52 449 978 0001').should.deep.equal({
  355. country: 'MX',
  356. phone: '4499780001'
  357. });
  358. parseNumber('01 (449)978-0001', 'MX').should.deep.equal({
  359. country: 'MX',
  360. phone: '4499780001'
  361. });
  362. parseNumber('(449)978-0001', 'MX').should.deep.equal({
  363. country: 'MX',
  364. phone: '4499780001'
  365. }); // Mobile.
  366. // `1` is prepended before area code to mobile numbers in international format.
  367. parseNumber('+52 1 33 1234-5678', 'MX').should.deep.equal({
  368. country: 'MX',
  369. phone: '3312345678'
  370. });
  371. parseNumber('+52 33 1234-5678', 'MX').should.deep.equal({
  372. country: 'MX',
  373. phone: '3312345678'
  374. });
  375. parseNumber('044 (33) 1234-5678', 'MX').should.deep.equal({
  376. country: 'MX',
  377. phone: '3312345678'
  378. });
  379. parseNumber('045 33 1234-5678', 'MX').should.deep.equal({
  380. country: 'MX',
  381. phone: '3312345678'
  382. });
  383. });
  384. it('should parse non-geographic numbering plan phone numbers', function () {
  385. parseNumber('+870773111632').should.deep.equal(USE_NON_GEOGRAPHIC_COUNTRY_CODE ? {
  386. country: '001',
  387. phone: '773111632'
  388. } : {});
  389. });
  390. it('should parse non-geographic numbering plan phone numbers (default country code)', function () {
  391. parseNumber('773111632', {
  392. defaultCallingCode: '870'
  393. }).should.deep.equal(USE_NON_GEOGRAPHIC_COUNTRY_CODE ? {
  394. country: '001',
  395. phone: '773111632'
  396. } : {});
  397. });
  398. it('should parse non-geographic numbering plan phone numbers (extended)', function () {
  399. parseNumber('+870773111632', {
  400. extended: true
  401. }).should.deep.equal({
  402. country: USE_NON_GEOGRAPHIC_COUNTRY_CODE ? '001' : undefined,
  403. countryCallingCode: '870',
  404. phone: '773111632',
  405. carrierCode: undefined,
  406. ext: undefined,
  407. possible: true,
  408. valid: true
  409. });
  410. });
  411. it('should parse non-geographic numbering plan phone numbers (default country code) (extended)', function () {
  412. parseNumber('773111632', {
  413. defaultCallingCode: '870',
  414. extended: true
  415. }).should.deep.equal({
  416. country: USE_NON_GEOGRAPHIC_COUNTRY_CODE ? '001' : undefined,
  417. countryCallingCode: '870',
  418. phone: '773111632',
  419. carrierCode: undefined,
  420. ext: undefined,
  421. possible: true,
  422. valid: true
  423. });
  424. });
  425. it('shouldn\'t crash when invalid `defaultCallingCode` is passed', function () {
  426. expect(function () {
  427. return parseNumber('773111632', {
  428. defaultCallingCode: '999'
  429. });
  430. }).to["throw"]('Unknown calling code');
  431. });
  432. it('shouldn\'t set `country` when there\'s no `defaultCountry` and `defaultCallingCode` is not of a "non-geographic entity"', function () {
  433. parseNumber('88005553535', {
  434. defaultCallingCode: '7'
  435. }).should.deep.equal({
  436. country: 'RU',
  437. phone: '8005553535'
  438. });
  439. });
  440. it('should correctly parse numbers starting with the same digit as the national prefix', function () {
  441. // https://github.com/catamphetamine/libphonenumber-js/issues/373
  442. // `BY`'s `national_prefix` is `8`.
  443. parseNumber('+37582004910060').should.deep.equal({
  444. country: 'BY',
  445. phone: '82004910060'
  446. });
  447. });
  448. it('should autocorrect numbers without a leading +', function () {
  449. // https://github.com/catamphetamine/libphonenumber-js/issues/376
  450. parseNumber('375447521111', 'BY').should.deep.equal({
  451. country: 'BY',
  452. phone: '447521111'
  453. }); // https://github.com/catamphetamine/libphonenumber-js/issues/316
  454. parseNumber('33612902554', 'FR').should.deep.equal({
  455. country: 'FR',
  456. phone: '612902554'
  457. }); // https://github.com/catamphetamine/libphonenumber-js/issues/375
  458. parseNumber('61438331999', 'AU').should.deep.equal({
  459. country: 'AU',
  460. phone: '438331999'
  461. }); // A case when `49` is a country calling code of a number without a leading `+`.
  462. parseNumber('4930123456', 'DE').should.deep.equal({
  463. country: 'DE',
  464. phone: '30123456'
  465. }); // A case when `49` is a valid area code.
  466. parseNumber('4951234567890', 'DE').should.deep.equal({
  467. country: 'DE',
  468. phone: '4951234567890'
  469. });
  470. });
  471. it('should parse extensions (long extensions with explicitl abels)', function () {
  472. // Test lower and upper limits of extension lengths for each type of label.
  473. // Firstly, when in RFC format: PhoneNumberUtil.extLimitAfterExplicitLabel
  474. parseNumber('33316005 ext 0', 'NZ').ext.should.equal('0');
  475. parseNumber('33316005 ext 01234567890123456789', 'NZ').ext.should.equal('01234567890123456789'); // Extension too long.
  476. expect(parseNumber('33316005 ext 012345678901234567890', 'NZ').ext).to.be.undefined; // Explicit extension label.
  477. parseNumber('03 3316005ext:1', 'NZ').ext.should.equal('1');
  478. parseNumber('03 3316005 xtn:12345678901234567890', 'NZ').ext.should.equal('12345678901234567890');
  479. parseNumber('03 3316005 extension\t12345678901234567890', 'NZ').ext.should.equal('12345678901234567890');
  480. parseNumber('03 3316005 xtensio:12345678901234567890', 'NZ').ext.should.equal('12345678901234567890');
  481. parseNumber('03 3316005 xtensión, 12345678901234567890#', 'NZ').ext.should.equal('12345678901234567890');
  482. parseNumber('03 3316005extension.12345678901234567890', 'NZ').ext.should.equal('12345678901234567890');
  483. parseNumber('03 3316005 доб:12345678901234567890', 'NZ').ext.should.equal('12345678901234567890'); // Extension too long.
  484. expect(parseNumber('03 3316005 extension 123456789012345678901', 'NZ').ext).to.be.undefined;
  485. });
  486. it('should parse extensions (long extensions with auto dialling labels)', function () {
  487. parseNumber('+12679000000,,123456789012345#').ext.should.equal('123456789012345');
  488. parseNumber('+12679000000;123456789012345#').ext.should.equal('123456789012345');
  489. parseNumber('+442034000000,,123456789#').ext.should.equal('123456789'); // Extension too long.
  490. expect(parseNumber('+12679000000,,1234567890123456#').ext).to.be.undefined;
  491. });
  492. it('should parse extensions (short extensions with ambiguous characters)', function () {
  493. parseNumber('03 3316005 x 123456789', 'NZ').ext.should.equal('123456789');
  494. parseNumber('03 3316005 x. 123456789', 'NZ').ext.should.equal('123456789');
  495. parseNumber('03 3316005 #123456789#', 'NZ').ext.should.equal('123456789');
  496. parseNumber('03 3316005 ~ 123456789', 'NZ').ext.should.equal('123456789'); // Extension too long.
  497. expect(parseNumber('03 3316005 ~ 1234567890', 'NZ').ext).to.be.undefined;
  498. });
  499. it('should parse extensions (short extensions when not sure of label)', function () {
  500. parseNumber('+1123-456-7890 666666#', {
  501. v2: true
  502. }).ext.should.equal('666666');
  503. parseNumber('+11234567890-6#', {
  504. v2: true
  505. }).ext.should.equal('6'); // Extension too long.
  506. expect(function () {
  507. return parseNumber('+1123-456-7890 7777777#', {
  508. v2: true
  509. });
  510. }).to["throw"]('NOT_A_NUMBER');
  511. });
  512. it('should choose `defaultCountry` (non-"main" one) when multiple countries match the number', function () {
  513. // https://gitlab.com/catamphetamine/libphonenumber-js/-/issues/103
  514. var phoneNumber = parseNumber('8004001000', {
  515. defaultCountry: 'CA',
  516. v2: true
  517. });
  518. phoneNumber.country.should.equal('CA');
  519. var phoneNumber2 = parseNumber('4389999999', {
  520. defaultCountry: 'US',
  521. v2: true
  522. });
  523. phoneNumber.country.should.equal('CA');
  524. });
  525. });
  526. //# sourceMappingURL=parse.test.js.map