phony 2.18.3 → 2.20.5

Sign up to get free protection for your applications and to get access to all the features.
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