phony 2.18.3 → 2.20.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/README.textile +5 -1
  3. data/lib/phony/countries/argentina.rb +355 -0
  4. data/lib/phony/countries/austria.rb +2 -2
  5. data/lib/phony/countries/cambodia.rb +1 -5
  6. data/lib/phony/countries/china.rb +5 -2
  7. data/lib/phony/countries/germany.rb +1 -1
  8. data/lib/phony/countries/ireland.rb +6 -4
  9. data/lib/phony/countries/italy.rb +34 -17
  10. data/lib/phony/countries/japan.rb +58 -8
  11. data/lib/phony/countries/libya.rb +1 -1
  12. data/lib/phony/countries/serbia.rb +5 -1
  13. data/lib/phony/countries/taiwan.rb +1 -0
  14. data/lib/phony/countries/vietnam.rb +1 -0
  15. data/lib/phony/countries.rb +83 -53
  16. data/lib/phony/country.rb +8 -2
  17. data/lib/phony/country_codes.rb +15 -2
  18. data/lib/phony/dsl.rb +2 -2
  19. data/lib/phony/local_splitters/fixed.rb +2 -0
  20. data/lib/phony/national_code.rb +1 -1
  21. data/lib/phony/national_splitters/none.rb +1 -3
  22. data/lib/phony/trunk_code.rb +5 -5
  23. data/lib/phony.rb +1 -0
  24. data/spec/functional/config_spec.rb +5 -5
  25. data/spec/functional/plausibility_spec.rb +82 -16
  26. data/spec/lib/phony/countries_spec.rb +86 -23
  27. data/spec/lib/phony/country_codes_spec.rb +82 -58
  28. data/spec/lib/phony/country_spec.rb +29 -9
  29. data/spec/lib/phony/dsl_spec.rb +6 -2
  30. data/spec/lib/phony/local_splitters/regex_spec.rb +12 -15
  31. data/spec/lib/phony/national_code_spec.rb +15 -45
  32. data/spec/lib/phony/national_splitters/fixed_spec.rb +12 -16
  33. data/spec/lib/phony/national_splitters/none_spec.rb +3 -3
  34. data/spec/lib/phony/national_splitters/variable_spec.rb +9 -13
  35. data/spec/lib/phony/trunk_code_spec.rb +85 -0
  36. data/spec/lib/phony/vanity_spec.rb +4 -4
  37. metadata +21 -19
@@ -166,6 +166,7 @@ ndcs_with_6_subscriber_numbers = %w(
166
166
  422
167
167
  428
168
168
  436
169
+ 438
169
170
  439
170
171
  460
171
172
  463
@@ -281,7 +282,6 @@ ndcs_with_6_subscriber_numbers = %w(
281
282
  846
282
283
  847
283
284
  848
284
- 849
285
285
  852
286
286
  853
287
287
  854
@@ -361,7 +361,6 @@ ndcs_with_5_subscriber_numbers = %w(
361
361
  1374
362
362
  1377
363
363
  1392
364
- 1394
365
364
  1397
366
365
  1398
367
366
  1456
@@ -393,7 +392,6 @@ ndcs_with_5_subscriber_numbers = %w(
393
392
  8477
394
393
  8512
395
394
  8514
396
- 8636
397
395
  9496
398
396
  9802
399
397
  9912
@@ -403,16 +401,68 @@ ndcs_with_5_subscriber_numbers = %w(
403
401
 
404
402
  Phony.define do
405
403
  country '81',
406
- trunk('0') |
407
- one_of('20', '50', '60', '70', '90') >> split(4,4) | # mobile, VoIP telephony
404
+ trunk('0', normalize: true, format: true, split: true) |
405
+ one_of(%w(20 50 60 70 90)) >> split(4,4) | # mobile, VoIP telephony
406
+ match(/\A(597)9[0178]\d+\z/) >> split(2,4) |
408
407
  one_of(ndcs_with_5_subscriber_numbers) >> split(1,4) |
408
+ match(/\A(4)70[019]\d+\z/) >> split(4,4) |
409
+ match(/\A(4)71\d+\z/) >> split(4,4) |
410
+ match(/\A(4)20\d+\z/) >> split(4,4) |
411
+ match(/\A(4)29[02-69]\d+\z/) >> split(4,4) |
412
+ match(/\A(15)4[018]\d+\z/) >> split(3,4) |
413
+ match(/\A(22)3[014-9]\d+\z/) >> split(3,4) |
414
+ match(/\A(25)[04][01]\d+\z/) >> split(3,4) |
415
+ match(/\A(25)5[0-69]\d+\z/) >> split(3,4) |
416
+ match(/\A(25)[68][01]\d+\z/) >> split(3,4) |
417
+ match(/\A(25)7[015-9]\d+\z/) >> split(3,4) |
418
+ match(/\A(25)917\d+\z/) >> split(3,4) |
419
+ match(/\A(25)999\d+\z/) >> split(3,4) |
420
+ match(/\A(26)4[016-9]\d+\z/) >> split(3,4) |
421
+ match(/\A(28)3[0134]\d+\z/) >> split(3,4) |
422
+ match(/\A(28)9[0-5]\d+\z/) >> split(3,4) |
423
+ match(/\A(29)17\d+\z/) >> split(3,4) |
424
+ match(/\A(29)3[015-9]\d+\z/) >> split(3,4) |
425
+ match(/\A(42)21\d+\z/) >> split(3,4) |
426
+ match(/\A(42)8[01456]\d+\z/) >> split(3,4) |
427
+ match(/\A(47)5[019]\d+\z/) >> split(3,4) |
428
+ match(/\A(47)9[019]\d+\z/) >> split(3,4) |
429
+ match(/\A(59)8[019]\d+\z/) >> split(3,4) |
430
+ match(/\A(59)9[01]\d+\z/) >> split(3,4) |
431
+ match(/\A(79)4[0-59]\d+\z/) >> split(3,4) |
432
+ match(/\A(79)5[01569]\d+\z/) >> split(3,4) |
433
+ match(/\A(79)6[0167]\d+\z/) >> split(3,4) |
434
+ match(/\A(82)4[0-39]\d+\z/) >> split(3,4) |
435
+ match(/\A(82)9[019]\d+\z/) >> split(3,4) |
436
+ match(/\A(82)92[1-9]\d+\z/) >> split(3,4) |
437
+ match(/\A(82)94[1-3]\d+\z/) >> split(3,4) |
438
+ match(/\A(82)96[0-47-9]\d+\z/) >> split(3,4) |
439
+ match(/\A(82)965[01346-9]\d+\z/) >> split(3,4) |
440
+ match(/\A(82)966[1-9]\d+\z/) >> split(3,4) |
441
+ match(/\A(83)76[6-8]\d+\z/) >> split(3,4) |
442
+ match(/\A(83)7[01789]\d+\z/) >> split(3,4) |
443
+ match(/\A(83)8[01]\d+\z/) >> split(3,4) |
444
+ match(/\A(86)36[23]\d+\z/) >> split(3,4) |
445
+ match(/\A(86)5[0-389]\d+\z/) >> split(3,4) |
446
+ match(/\A(86)55[23]\d+\z/) >> split(3,4) |
447
+ match(/\A(86)[01]\d+\z/) >> split(3,4) |
448
+ match(/\A(86)9[178]\d+\z/) >> split(3,4) |
449
+ match(/\A(86)72\d+\z/) >> split(3,4) |
450
+ match(/\A(86)8[019]\d+\z/) >> split(3,4) |
451
+ match(/\A(86)9[0145]\d+\z/) >> split(3,4) |
452
+ match(/\A(86)99[014-9]\d+\z/) >> split(3,4) |
453
+ match(/\A(99)331\d+\z/) >> split(3,4) |
454
+ match(/\A(99)34[357]\d+\z/) >> split(3,4) |
455
+ match(/\A(99)4[0178]\d+\z/) >> split(3,4) |
409
456
  one_of(ndcs_with_6_subscriber_numbers) >> split(2,4) |
410
457
  one_of(%w(120)) >> split(3,3) | # freephone
411
- one_of(%w(120 800)) >> split(3,4) | # freephone
458
+ one_of(%w(800)) >> split(3,4) | # freephone
459
+ one_of(%w(180 570)) >> split(3,3) | # Tele-gong/Tele-dome, Navi-dial
460
+ one_of(%w(170 990)) >> split(2,4) | # Dengon-dial, Dial Q2 (discontinued)
461
+ one_of(%w(80)) >> split(4,4) | # mobile
412
462
  one_of(ndcs_with_7_subscriber_numbers) >> split(3,4) |
413
463
  one_of(ndcs_with_8_subscriber_numbers) >> split(4,4) |
414
464
  # TODO: 91(NDC) N(S)N length: 5-13 - Non-geographic number (Direct subscriber telephone service (legacy))
415
465
  fixed(2) >> split(4,4),
416
- :local_space => :- ,
417
- :space => :-
466
+ local_space: :-,
467
+ space: :-
418
468
  end
@@ -111,6 +111,6 @@ Phony.define do
111
111
  one_of(ndcs_with_5_subscriber_numbers) >> split(3,2) |
112
112
  one_of(ndcs_with_6_subscriber_numbers) >> split(3,3) |
113
113
  one_of(ndcs_with_7_subscriber_numbers) >> split(4,3) |
114
- one_of(%w(91 92)) >> split(4,3) | # mobile
114
+ one_of(%w(91 92 94 95)) >> split(4,3) | # mobile
115
115
  fixed(2) >> split(3,3)
116
116
  end
@@ -8,6 +8,9 @@ Phony.define do
8
8
  trunk('0') |
9
9
  one_of(%w(800)) >> split(3,2) | # freephone
10
10
  one_of(%w(808)) >> split(3,2) | # payphone
11
+ one_of(%w(677 678)) >> matched_split(
12
+ /\A\d{4}\z/ => [3],
13
+ /\A\d+\z/ => [3,3]) |
11
14
  one_of(%w(230)) >> matched_split(
12
15
  /\A\d{4}\z/ => [4],
13
16
  /\A\d+\z/ => [3,2]) |
@@ -21,6 +24,7 @@ Phony.define do
21
24
  one_of(%w(72)) >> split(3,3) | # ISP
22
25
  one_of(%w(60 61 68 69)) >> matched_split(
23
26
  /\A\d{3}\z/ => [3],
27
+ /\A\d{6}\z/ => [3,3],
24
28
  /\A\d{7}\z/ => [3,4],
25
29
  /\A\d+\z/ => [3,3,4]) | # mobile, voicemail (mobile)
26
30
  one_of(%w(66 63)) >> matched_split(
@@ -40,4 +44,4 @@ Phony.define do
40
44
  fixed(2) >> matched_split(
41
45
  /\A\d{5}\z/ => [3,2],
42
46
  /\A\d+\z/ => [3,3])
43
- end
47
+ end
@@ -11,6 +11,7 @@ Phony.define do
11
11
  match(/\A(836)\d{5}\z/) >> split(1,4) | # 馬祖, start with 0836, plus 5 digits
12
12
  match(/\A(82)\d{6}\z/) >> split(2,4) | # 金門, start with 082, plus 6 digits
13
13
  match(/\A(89)\d{6}\z/) >> split(2,4) | # 臺東, start with 089, plus 6 digits
14
+ match(/\A(80\d)\d{6}\z/)>> split(3,4) | # Toll-free number
14
15
  match(/\A(8)\d{7}\z/) >> split(3,4) | # 屏東, start with 08, plus 7 digits
15
16
  match(/\A(49)\d{7}\z/) >> split(3,4) | # 南投, start with 049, plus 7 digits
16
17
  one_of(%w(4)) >> matched_split(
@@ -104,6 +104,7 @@ mobile = [
104
104
  '84', # Vinaphone
105
105
  '85', # Vinaphone
106
106
  '86', # Viettel
107
+ '87', # Itelecom
107
108
  '88', # Vinaphone
108
109
  '89', # MobiFone,
109
110
  '90', # MobiFone
@@ -69,7 +69,7 @@ Phony.define do
69
69
  country '20', one_of('800') >> split(7..7) | # Egypt toll free
70
70
  one_of('3') >> split(7..7) | # Alexandria
71
71
  one_of('2') >> split(8..8) | # Cairo/Giza
72
- one_of('10', '11', '12') >> split(8..8) | # the 3 mobile operators
72
+ one_of('10', '11', '12', '15') >> split(8..8) | # the 4 mobile operators
73
73
  fixed(2) >> split(7..7) # all the other 24 provinces
74
74
 
75
75
  # South Africa.
@@ -96,15 +96,16 @@ Phony.define do
96
96
  # Belgium.
97
97
  #
98
98
  # http://en.wikipedia.org/wiki/Telephone_numbers_in_Belgium
99
+ # https://www.bipt.be/operators/publication/national-numbering-plan
99
100
  #
100
101
  country '32', trunk('0') |
101
- match(/^(7[08])\d+$/) >> split(3,3) | # Premium and national rate Services
102
- match(/^(800|90\d)\d+$/) >> split(2,3) | # Toll free service and premium numbers
103
- match(/^(46[05678])\d{6}$/) >> split(2,2,2) | # Mobile (Lycamobile, Telenet, Join Experience, Proximus 0460)
104
- match(/^(4[789]\d)\d{6}$/) >> split(2,2,2) | # Mobile
105
- match(/^(456)\d{6}$/) >> split(2,2,2) | # Mobile Vikings
106
- one_of('2','3','4','9') >> split(3,2,2) | # Short NDCs
107
- fixed(2) >> split(2,2,2) # 2-digit NDCs
102
+ match(/^(7[08])\d+$/) >> split(3,3) | # Premium and national rate Services
103
+ match(/^(800|90\d)\d+$/) >> split(2,3) | # Toll free service and premium numbers
104
+ match(/^(46[056789])\d{6}$/) >> split(2,2,2) | # Mobile (Lycamobile, Telenet, Join Experience, Proximus 0460)
105
+ match(/^(4[789]\d)\d{6}$/) >> split(2,2,2) | # Mobile
106
+ match(/^(45[56])\d{6}$/) >> split(2,2,2) | # Mobile Vikings and Voo
107
+ one_of('2','3','4','9') >> split(3,2,2) | # Short NDCs
108
+ fixed(2) >> split(2,2,2) # 2-digit NDCs
108
109
 
109
110
  # France.
110
111
  #
@@ -154,6 +155,7 @@ Phony.define do
154
155
  #
155
156
  country '41',
156
157
  trunk('0', normalize: true) |
158
+ match(/^(860)\d+$/) >> split(2, 3, 2, 2) | # Voice Mail access
157
159
  match(/^(8(?:00|4[0248]))\d+$/) >> split(3,3) | # Freecall/Shared Cost
158
160
  match(/^(90[016])\d+$/) >> split(3,3) | # Business
159
161
  fixed(2) >> split(3,2,2)
@@ -213,14 +215,7 @@ Phony.define do
213
215
  fixed(3) >> split(7) # 3-digit NDCs
214
216
 
215
217
  # Argentine Republic.
216
- #
217
- country '54',
218
- one_of('11', '911') >> split(4,4) | # Fixed & Mobile
219
- match(/^(22[0137]|237|26[14]|29[179]|34[1235]|35[138]|38[1578])/) >> split(3,4) | # Fixed
220
- match(/^(922[0137]|9237|926[14]|929[179]|934[1235]|935[138]|938[1578])/) >> split(3,4) | # Mobile
221
- match(/^(9\d{4})/) >> split(2,4) | # Mobile
222
- match(/^([68]\d{2})/) >> split(3,4) | # Service
223
- fixed(4) >> split(2,4) # Fixed
218
+ # country '54' # argentina, see special file.
224
219
 
225
220
  # Brazil (Federative Republic of).
226
221
  # http://en.wikipedia.org/wiki/Telephone_numbers_in_Brazil
@@ -237,6 +232,7 @@ Phony.define do
237
232
  # http://www.itu.int/oth/T020200002C/en
238
233
  country '57',
239
234
  match(/\A(3\d\d)\d+\z/) >> split(3,4) | # mobile (300 310 311 312 313 315 316)
235
+ match(/\A(60\d)\d+\z/) >> split(3,4) |
240
236
  fixed(1) >> split(3,4)
241
237
 
242
238
  # Venezuela (Bolivarian Republic of)
@@ -264,6 +260,7 @@ Phony.define do
264
260
  trunk('0') |
265
261
  # 7/10 digits for area code '2'.
266
262
  match(/\A(2)\d{10}\z/) >> split(10) |
263
+ match(/\A(2)\d{8}\z/) >> split(8) |
267
264
  one_of('2') >> split(7) |
268
265
  # mobile
269
266
  match(/\A([89]\d\d)\d{7}\z/) >> split(7) |
@@ -358,15 +355,23 @@ Phony.define do
358
355
 
359
356
  # Côte d'Ivoire
360
357
  # http://www.wtng.info/wtng-225-ci.html
361
- # http://www.itu.int/dms_pub/itu-t/oth/02/02/T02020000310001PDFE.pdf
358
+ # https://www.itu.int/dms_pub/itu-t/oth/02/02/T02020000310006PDFE.pdf
362
359
  # http://en.wikipedia.org/wiki/Telephone_numbers_in_Ivory_Coast
363
360
  #
364
361
  # There is no trunk code for this country and several of the mobile prefixes start with 0
365
362
  country '225',
366
363
  trunk('', :normalize => false) |
367
- fixed(2) >> split(2,2,2)
364
+ fixed(2) >> split(2,2,2,2)
365
+
366
+ # Burkina Faso
367
+ # http://www.wtng.info/wtng-226-bf.html
368
+ # https://en.wikipedia.org/wiki/Telephone_numbers_in_Burkina_Faso
369
+ #
370
+ # There is no trunk code for this country and several of the mobile prefixes start with 0
371
+ country '226',
372
+ trunk('', normalize: false) |
373
+ none >> split(2,2,2,2)
368
374
 
369
- country '226', none >> split(4,4) # Burkina Faso http://www.wtng.info/wtng-226-bf.html
370
375
  country '227', none >> split(4,4) # Niger http://www.wtng.info/wtng-227-ne.html
371
376
  country '228', none >> split(4,4) # Togolese Republic http://www.wtng.info/wtng-228-tg.html
372
377
  country '229', none >> split(4,4) # Benin http://www.itu.int/oth/T0202000017/en
@@ -389,18 +394,25 @@ Phony.define do
389
394
  # Ghana
390
395
  #
391
396
  # From http://www.itu.int/oth/T0202000052/en
397
+ # https://en.wikipedia.org/wiki/Telephone_numbers_in_Ghana
392
398
  #
393
- country '233', fixed(2) >> split(3,4)
399
+ country '233', trunk('0') | fixed(2) >> split(3,4)
394
400
 
395
401
  # Nigeria
396
- # Wikipedia says 3 4 split, many local number with no splitting
402
+ # 3 4 split for mobile and 1 digit NDC, 3 2 or 3 3 otherwise
403
+ # Many local numbers with no splitting
397
404
  #
398
- # mobile telephony number allocation taken from: http://www.ncc.gov.ng/index.php?option=com_content&view=article&id=113&Itemid=102
405
+ # mobile telephony number allocation taken from:
406
+ # https://www.ncc.gov.ng/technical-regulation/standards/numbering and
407
+ # https://www.itu.int/oth/T020200009C/en
399
408
  country '234',
400
- match(/^([7-9]0\d)\d+$/) >> split(3,4) | # Mobile
401
- match(/^(81\d)\d+$/) >> split(3,4) | # Mobile
402
- one_of('1', '2', '9') >> split(3,4) | # Lagos, Ibadan and Abuja
403
- fixed(2) >> split(3,4) # 2-digit NDC
409
+ match(/^([7-9]0\d)\d+$/) >> split(3,4) | # Mobile
410
+ match(/^(81\d)\d+$/) >> split(3,4) | # Mobile
411
+ match(/^(91\d)\d+$/) >> split(3,4) | # Mobile
412
+ one_of('1', '2') >> split(3,3..4) | # Lagos, Ibadan
413
+ one_of('9') >> split(3,4) | # Abuja
414
+ one_of((30..79).map(&:to_s)) >> split(3,2..3) | # 2-digit NDC
415
+ one_of(%w(82 83 84 85 86 87 88 89)) >> split(3,3) # 2-digit NDC
404
416
 
405
417
  country '235', none >> split(4,4) # Chad http://www.wtng.info/wtng-235-td.html
406
418
  country '236', none >> split(4,4) # Central African Republic http://www.wtng.info/wtng-236-cf.html
@@ -409,7 +421,9 @@ Phony.define do
409
421
  country '239', fixed(1) >> split(3,3) # Sao Tome and Principe, http://www.wtng.info/wtng-239-st.html
410
422
 
411
423
  country '240', none >> split(3,3,3) # Equatorial Guinea
412
- country '241', fixed(1) >> split(3,3) # Gabonese Republic http://www.wtng.info/wtng-241-ga.html
424
+ country '241',
425
+ match(/^(\d)\d{6}$/) >> split(3,3) | # Gabonese Republic http://www.wtng.info/wtng-241-ga.html
426
+ match(/^(\d\d)\d{6}$/) >> split(2,2,2) # 2019 update https://en.wikipedia.org/wiki/Telephone_numbers_in_Gabon
413
427
  country '242', # Congo http://www.wtng.info/wtng-242-cg.html
414
428
  trunk('', :normalize => false) |
415
429
  none >> split(4,5)
@@ -429,9 +443,9 @@ Phony.define do
429
443
  # http://en.wikipedia.org/wiki/Telephone_numbers_in_Rwanda
430
444
  country '250',
431
445
  trunk('0') |
432
- one_of('25') >> split(7) | # Geographic, fixed
433
- match(/^(7[238])/) >> split(7) | # Non-geographic, mobile
434
- one_of('06') >> split(6) # Satellite
446
+ one_of('25') >> split(7) | # Geographic, fixed
447
+ match(/^(7[2389])/) >> split(7) | # Non-geographic, mobile
448
+ one_of('06') >> split(6) # Satellite
435
449
 
436
450
  country '251', fixed(2) >> split(3, 4) # Ethiopia http://www.wtng.info/wtng-251-et.html
437
451
 
@@ -482,27 +496,32 @@ Phony.define do
482
496
  # Zambia
483
497
  # http://www.wtng.info/wtng-260-zm.html
484
498
  # https://github.com/googlei18n/libphonenumber/
499
+ # https://en.wikipedia.org/wiki/Telephone_numbers_in_Zambia
500
+
485
501
  country '260',
486
- match(/^(9(5[034589]|[67]\d))/) >> split(6) | # Mobile
487
- match(/^(800)/) >> split(3,3) | # Toll free
488
- match(/^(21[1-8])/) >> split(6) # Fixed
502
+ trunk('0') |
503
+ match(/^(75|76|77|94|95|96|97)/) >> split(3, 4) | # Mobile
504
+ match(/^(800)/) >> split(3,3) | # Toll free
505
+ match(/^(21[1-8])/) >> split(6) # Fixed
489
506
 
490
- # Madagascar http://www.wtng.info/wtng-261-mg.html
507
+ # Madagascar
508
+ # https://en.wikipedia.org/wiki/Telephone_numbers_in_Madagascar
491
509
  # http://www.itu.int/oth/T020200007F/en
492
510
  country '261',
493
- none >> matched_split(
494
- /\A200\d+\z/ => [2,3,3,3], # Telecom Malagasy (Telma)
495
- /\A20\d+\z/ => [2,3,4], # Telecom Malagasy (Telma)
496
- /\A23\d+\z/ => [2,3,4], # Digitel
497
- /\A30\d+\z/ => [2,3,4], # mobile Madamobil (CDMA2000)
498
- /\A31\d+\z/ => [2,3,4], # mobile Airtel Madagascar
499
- /\A32\d+\z/ => [2,3,4], # mobile Orange Madagascar
500
- /\A33\d+\z/ => [2,3,4], # mobile Airtel Madagascar
501
- /\A34\d+\z/ => [2,3,4], # mobile Telecom Malagasy (Telma)
502
- /\A5\d+\z/ => [3,3,3], # pager
503
- /\A22\d+\z/ => [3,3,3], # satellite GULFSAT Téléphonie
504
- /\A6\d+\z/ => [3,3,3] # satellite
505
- )
511
+ # none >> matched_split(
512
+ # /\A20\d+\z/ => [2,2,3,2], # Telecom Malagasy (Telma)
513
+ # /\A32\d+\z/ => [2,2,3,2], # mobile Orange Madagascar
514
+ # /\A33\d+\z/ => [2,2,3,2], # mobile Airtel Madagascar
515
+ # /\A34\d+\z/ => [2,2,3,2], # mobile Telecom Malagasy (Telma)
516
+ # /\A38\d+\z/ => [2,2,3,2], # mobile Telecom Malagasy (Telma)
517
+ # /\A39\d+\z => [2,2,3,2] # mobile Blueline
518
+ # ),
519
+ match(/\A(20)\d+\z/) >> split(2,3,2) | # fix Telecom Malagasy (Telma)
520
+ match(/\A(32)\d+\z/) >> split(2,3,2) | # mobile Orange Madagascar
521
+ match(/\A(33)\d+\z/) >> split(2,3,2) | # mobile Airtel Madagascar
522
+ match(/\A(34)\d+\z/) >> split(2,3,2) | # mobile Telecom Malagasy (Telma)
523
+ match(/\A(38)\d+\z/) >> split(2,3,2) | # mobile Telecom Malagasy (Telma)
524
+ match(/\A(39)\d+\z/) >> split(2,3,2) # mobile Blueline Madagascar
506
525
 
507
526
  country '262', # Reunion / Mayotte (new) http://www.wtng.info/wtng-262-fr.html
508
527
  trunk('0') |
@@ -738,11 +757,12 @@ Phony.define do
738
757
  # Monaco
739
758
  #
740
759
  country '377',
741
- one_of('6') >> split(2,2,2,2) | # mobile
760
+ one_of('6') >> split(2,2,2,2) | # mobile
742
761
  fixed(2) >> split(2,2,2)
743
762
 
744
763
  # San Marino
745
764
  country '378',
765
+ trunk('', :normalize => false) |
746
766
  none >> matched_split(
747
767
  /\A\d{6}\z/ => [3,3],
748
768
  /\A\d+\z/ => [3,3,4]
@@ -900,7 +920,14 @@ Phony.define do
900
920
  )
901
921
 
902
922
  country '671', todo # Spare code
903
- country '672', todo # Australian External Territories
923
+
924
+ # Australian External Territories https://en.wikipedia.org/wiki/Telephone_numbers_in_Norfolk_Island
925
+ # Norfolk Island
926
+ country '672',
927
+ fixed(1) >> split(2,3) |
928
+ match(/^(2\d+)$/) >> split(3) | # Fixed
929
+ match(/^(5\d+)$/) >> split(3) # Mobile
930
+
904
931
  country '673', fixed(1) >> split(3, 3) # Brunei Darussalam http://www.wtng.info/wtng-673-bn.html
905
932
  country '674', none >> split(3, 4) # Nauru (Republic of) http://www.wtng.info/wtng-674-nr.html
906
933
 
@@ -967,12 +994,12 @@ Phony.define do
967
994
  /\A800\d+\z/ => [3,3], # freephone
968
995
  /\A830\d+\z/ => [3,3], # shared cost
969
996
  /\A60\d+\z/ => [3,3], # wireless geographic
970
- /\A(72|75|76|77)\d+\z/ => [3,4], # mobile
997
+ /\A(71|72|75|76|77)\d+\z/ => [3,4], # mobile
971
998
  /\A84\d+\z/ => [3,4], # wireless geographic
972
999
  /\A\d+\z/ => [2,3] # geographic
973
1000
  )
974
1001
 
975
- country '686', none >> split(2,3) # Kiribati (Republic of) http://www.wtng.info/wtng-686-ki.html
1002
+ country '686', none >> split(8) # Kiribati (Republic of) https://www.numberingplans.com/?page=plans&sub=phonenr&alpha_2_input=KI
976
1003
  country '687', none >> split(3,3) # New Caledonia (Territoire français d'outre-mer) http://www.wtng.info/wtng-687-nc.html
977
1004
  country '688', none >> split(5) # Tuvalu http://www.wtng.info/wtng-688-tv.html
978
1005
  country '689', none >> split(2,2,2,2) # French Polynesia (Territoire français d'outre-mer) http://www.wtng.info/wtng-689-pf.html
@@ -988,7 +1015,10 @@ Phony.define do
988
1015
  country '698', todo # -
989
1016
  country '699', todo # -
990
1017
 
991
- country '800', todo # International Freephone Service
1018
+ # International Freephone Service
1019
+ # https://www.itu.int/en/ITU-T/inr/unum/Pages/uifn.aspx
1020
+ country '800', none >> split(8)
1021
+
992
1022
  country '801', todo # -
993
1023
  country '802', todo # -
994
1024
  country '803', todo # -
@@ -996,7 +1026,7 @@ Phony.define do
996
1026
  country '805', todo # -
997
1027
  country '806', todo # -
998
1028
  country '807', todo # -
999
- country '808', todo # International Shared Cost Service (ISCS)
1029
+ country '808', none >> split(12) # International Shared Cost Service (ISCS)
1000
1030
  country '809', todo # -
1001
1031
 
1002
1032
  country '830', todo # -
data/lib/phony/country.rb CHANGED
@@ -97,6 +97,9 @@ module Phony
97
97
  end
98
98
  end
99
99
  def format_cc_ndc trunk, ndc, local, type, space, parentheses, use_trunk
100
+ # Note: We mark NDCs that are of type "none" with false (nil trips plausible?). This would result in false being printed.
101
+ # Therefore we set NDC to nil when formatting.
102
+ ndc = nil if ndc == false
100
103
  case type
101
104
  when String
102
105
  trunk &&= trunk.format(space, use_trunk)
@@ -125,6 +128,7 @@ module Phony
125
128
  end
126
129
  end
127
130
  def format_ndc ndc, parentheses
131
+ ndc = nil if ndc == false # TODO
128
132
  parentheses ? "(#{ndc})" : ndc
129
133
  end
130
134
  def format_with_ndc format, cc, ndc, local, space
@@ -156,10 +160,12 @@ module Phony
156
160
  #
157
161
  # In some cases it doesn't, like Italy.
158
162
  #
159
- def normalize national_number
163
+ # Note: Options such as CC
164
+ #
165
+ def normalize national_number, options = {}
160
166
  clean! national_number
161
167
  normalized = @codes.reduce national_number do |number, code|
162
- result = code.normalize number
168
+ result = code.normalize number, options
163
169
  break result if result
164
170
  number
165
171
  end
@@ -66,7 +66,7 @@ module Phony
66
66
  country, cc, number = partial_split number
67
67
  country
68
68
  end
69
- number = country.normalize number
69
+ number = country.normalize number, cc: cc
70
70
  countrify! number, cc
71
71
  end
72
72
 
@@ -97,9 +97,20 @@ module Phony
97
97
 
98
98
  # False if it fails the basic check.
99
99
  #
100
- return false unless (4..16) === normalized.size
100
+ return false unless (4..16) === normalized.size # unless hints[:check_length] == false
101
101
 
102
102
  country, cc, rest = partial_split normalized
103
+
104
+ # Was a country calling code given?
105
+ #
106
+ if ccc = hints[:ccc]
107
+ cc, ndc, *local = split ccc
108
+
109
+ raise ArgumentError.new("The provided ccc option is too long and includes more than a cc ('#{cc}') and ndc ('#{ndc}'). It also includes '#{local.join}'.") unless local.size == 1 && local[0].empty?
110
+
111
+ hints[:cc] = cc
112
+ hints[:ndc] = ndc
113
+ end
103
114
 
104
115
  # Country code plausible?
105
116
  #
@@ -109,6 +120,8 @@ module Phony
109
120
  # Country specific tests.
110
121
  #
111
122
  country.plausible? rest, hints
123
+ rescue ArgumentError
124
+ raise
112
125
  rescue StandardError
113
126
  return false
114
127
  end
data/lib/phony/dsl.rb CHANGED
@@ -12,9 +12,9 @@ module Phony
12
12
  #
13
13
  # Phony.define.country ...
14
14
  #
15
- def self.define
15
+ def self.define(&block)
16
16
  dsl = DSL.new
17
- dsl.instance_eval(&Proc.new) if block_given?
17
+ dsl.instance_eval(&block) if block_given?
18
18
  dsl
19
19
  end
20
20
 
@@ -62,6 +62,8 @@ module Phony
62
62
  #
63
63
  #
64
64
  def plausible? rest, hints = {}
65
+ return true if hints[:check_length] == false
66
+
65
67
  @length === rest.inject(0) { |total, part| total + part.size }
66
68
  end
67
69
 
@@ -26,7 +26,7 @@ module Phony
26
26
  #
27
27
  # Note: Some cases, like Italy, don't remove the relative zero.
28
28
  #
29
- def normalize national_number
29
+ def normalize national_number, options = {}
30
30
  national_number.gsub(/\A0+/, EMPTY_STRING)
31
31
  end
32
32
 
@@ -31,9 +31,7 @@ module Phony
31
31
  # since using nil is dangerous and breaks
32
32
  # abstraction)
33
33
  #
34
- # Note: Actually, it might stay in.
35
- #
36
- # TODO Flip nil/false?
34
+ # Note: Decided it stays in. When formatting, it's turned into nil.
37
35
  #
38
36
  def split national_number
39
37
  [nil, false, national_number]
@@ -6,9 +6,9 @@ module Phony
6
6
  # * code: The trunk code, e.g. 0.
7
7
  #
8
8
  # Options:
9
- # * normalize: Remove the trunk code when normalizing (only use if number scheme is defined unambiguously).
10
- # * split: Remove the trunk code when splitting (only use if number scheme is defined unambiguously).
11
- # * format: Add the trunk code when formatting (passing `false` will not add it).
9
+ # * normalize: [true (default), false] Remove the trunk code when normalizing (only use if number scheme is defined unambiguously).
10
+ # * split: [true, false (default)] Remove the trunk code when splitting (only use if number scheme is defined unambiguously).
11
+ # * format: [true (default), false] Add the trunk code when formatting (passing `false` will not add it).
12
12
  #
13
13
  def initialize code, options = {}
14
14
  @code = code
@@ -35,8 +35,8 @@ module Phony
35
35
 
36
36
  # Normalize normalizes the given national number.
37
37
  #
38
- def normalize national_number
39
- national_number.gsub! @trunk_code_replacement, EMPTY_STRING if @normalize
38
+ def normalize national_number, options = {}
39
+ national_number.gsub! @trunk_code_replacement, EMPTY_STRING if @normalize && options[:cc]
40
40
  return national_number
41
41
  end
42
42
 
data/lib/phony.rb CHANGED
@@ -24,6 +24,7 @@ load File.expand_path '../phony/dsl.rb', __FILE__
24
24
  #
25
25
  # The ones that need more space to define.
26
26
  #
27
+ load File.expand_path '../phony/countries/argentina.rb', __FILE__
27
28
  load File.expand_path '../phony/countries/austria.rb', __FILE__
28
29
  load File.expand_path '../phony/countries/bangladesh.rb', __FILE__
29
30
  load File.expand_path '../phony/countries/belarus.rb', __FILE__
@@ -18,27 +18,27 @@ describe 'Phony::Config' do
18
18
  it 'does not fail when loading all' do
19
19
  Phony::Config.load
20
20
 
21
- Phony.split('15551115511').should == ['1', '555', '111', '5511']
21
+ expect(Phony.split('15551115511')).to eq ['1', '555', '111', '5511']
22
22
  end
23
23
  it 'raises when a CC is used that has not been loaded.' do
24
24
  Phony::Config.load('41')
25
25
 
26
- expect { Phony.split('15551115511') }.to raise_error
26
+ expect { Phony.split('15551115511') }.to raise_error(Phony::SplittingError)
27
27
  end
28
28
  it 'raises when a CC is used that has not been loaded.' do
29
29
  Phony::Config.load(only: ['41'])
30
30
 
31
- expect { Phony.split('15551115511') }.to raise_error
31
+ expect { Phony.split('15551115511') }.to raise_error(Phony::SplittingError)
32
32
  end
33
33
  it 'raises when a CC is used that has not been loaded.' do
34
34
  Phony::Config.load(except: ['1'])
35
35
 
36
- expect { Phony.split('15551115511') }.to raise_error
36
+ expect { Phony.split('15551115511') }.to raise_error(Phony::SplittingError)
37
37
  end
38
38
  it 'does not raise when a CC is used that has been loaded.' do
39
39
  Phony::Config.load(except: ['41'])
40
40
 
41
- Phony.split('15551115511').should == ['1', '555', '111', '5511']
41
+ expect(Phony.split('15551115511')).to eq ['1', '555', '111', '5511']
42
42
  end
43
43
  end
44
44
  end