phony 1.2.11 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/README.textile +1 -1
  2. data/lib/countries.rb +385 -0
  3. data/lib/phony.rb +11 -9
  4. data/lib/phony/countries.rb +1 -0
  5. data/lib/phony/countries/austria.rb +68 -67
  6. data/lib/phony/countries/belgium.rb +29 -57
  7. data/lib/phony/countries/chile.rb +5 -12
  8. data/lib/phony/countries/china.rb +21 -20
  9. data/lib/phony/countries/egypt.rb +12 -37
  10. data/lib/phony/countries/germany.rb +39 -36
  11. data/lib/phony/countries/greece.rb +21 -25
  12. data/lib/phony/countries/hungary.rb +6 -19
  13. data/lib/phony/countries/italy.rb +174 -152
  14. data/lib/phony/countries/malaysia.rb +17 -17
  15. data/lib/phony/countries/netherlands.rb +50 -52
  16. data/lib/phony/countries/romania.rb +28 -27
  17. data/lib/phony/countries/south_korea.rb +11 -11
  18. data/lib/phony/countries/sweden.rb +49 -49
  19. data/lib/phony/countries/united_kingdom.rb +4 -4
  20. data/lib/phony/country.rb +14 -80
  21. data/lib/phony/country_codes.rb +23 -3
  22. data/lib/phony/dsl.rb +78 -0
  23. data/lib/phony/national_code.rb +2 -5
  24. data/lib/phony/national_splitters/dsl.rb +20 -0
  25. data/lib/phony/national_splitters/fixed.rb +1 -1
  26. data/lib/phony/national_splitters/none.rb +1 -1
  27. data/lib/phony/national_splitters/regex.rb +49 -0
  28. data/lib/phony/national_splitters/variable.rb +6 -6
  29. data/lib/phony/vanity.rb +3 -0
  30. data/spec/lib/phony/country_codes_spec.rb +1 -1
  31. data/spec/lib/phony/country_spec.rb +12 -45
  32. data/spec/lib/phony/local_splitters/fixed_spec.rb +8 -0
  33. data/spec/lib/phony/national_code_spec.rb +13 -0
  34. data/spec/lib/phony/national_splitters/regex_spec.rb +23 -0
  35. data/spec/lib/phony/national_splitters/variable_spec.rb +2 -4
  36. data/spec/lib/phony_spec.rb +44 -4
  37. metadata +9 -21
  38. data/lib/phony/countries/all_other.rb +0 -455
  39. data/lib/phony/countries/norway.rb +0 -11
  40. data/lib/phony/countries/peru.rb +0 -19
  41. data/lib/phony/countries/portugal.rb +0 -16
  42. data/lib/phony/national_splitters/experimental.rb +0 -17
  43. data/spec/lib/phony/countries/austria_spec.rb +0 -24
  44. data/spec/lib/phony/countries/belgium_spec.rb +0 -33
  45. data/spec/lib/phony/countries/egypt_spec.rb +0 -18
  46. data/spec/lib/phony/countries/greece_spec.rb +0 -18
  47. data/spec/lib/phony/countries/portugal_spec.rb +0 -21
  48. data/spec/lib/phony/countries/switzerland_spec.rb +0 -18
  49. data/spec/lib/phony/countries/united_kingdom_spec.rb +0 -50
@@ -4,6 +4,12 @@ module Phony
4
4
  #
5
5
  class CountryCodes
6
6
 
7
+ attr_reader :mapping
8
+
9
+ def self.instance
10
+ @instance ||= new
11
+ end
12
+
7
13
  def normalize number
8
14
  # Remove non-digit chars.
9
15
  #
@@ -44,6 +50,8 @@ module Phony
44
50
  parts_ary.join space.to_s
45
51
  end
46
52
 
53
+ #
54
+ #
47
55
  def service? number
48
56
  national_handler, cc, rest = split_cc number
49
57
  national_handler.service? rest
@@ -80,10 +88,22 @@ module Phony
80
88
  # This line is never reached as CCs are in prefix code.
81
89
  end
82
90
 
83
- # Cached mapping of all countries.
91
+ # # TODO
92
+ # #
93
+ # def self.with_cc cc
94
+ # mapping[cc.size][cc.to_s]
95
+ # end
96
+
97
+ # Add the given country to the mapping under the
98
+ # given country code.
84
99
  #
85
- def mapping
86
- @mapping ||= Phony::Countries.mapping
100
+ def add country_code, country
101
+ country_code = country_code.to_s
102
+ optimized_country_code_access = country_code.size
103
+
104
+ @mapping ||= {}
105
+ @mapping[optimized_country_code_access] ||= {}
106
+ @mapping[optimized_country_code_access][country_code] = country
87
107
  end
88
108
 
89
109
  end
data/lib/phony/dsl.rb ADDED
@@ -0,0 +1,78 @@
1
+ # # Ideas for a DSL:
2
+ # #
3
+ #
4
+ # # Switzerland
5
+ # #
6
+ # country('41', fixed(2) >> local([3,2,2]))
7
+ # country(match(/^1.*$/) >> [3,3] || none >> [2,2,2,2])
8
+ #
9
+ # # Germany. Too big.
10
+ # #
11
+ # country('49', Countries::Germany)
12
+ # #
13
+ # # … and in Germany:
14
+ # #
15
+ # include Phony::DSL
16
+ # Countries::Germany = match(...) >> split([...]) ||
17
+ # one_of([...], :max_length => 5) >> split([...])
18
+ #
19
+ # # Denmark.
20
+ # #
21
+ # country('45', none >> split([2,2,2,2])) # Denmark.
22
+ #
23
+ # # Hungary.
24
+ # #
25
+ # country('36',
26
+ # match(/^104|105|107|112/) >> split([3,3]) ||
27
+ # one_of([1], :max_length => 2) >> split([3,4])
28
+ # )
29
+
30
+ module Phony
31
+
32
+ module DSL
33
+
34
+ #
35
+ #
36
+ def country country_code, country
37
+ Phony::CountryCodes.instance.add country_code, country
38
+ end
39
+
40
+ # National matcher & splitters.
41
+ #
42
+
43
+ #
44
+ #
45
+ def fixed size
46
+ NationalSplitters::Fixed.instance_for size
47
+ end
48
+ def none
49
+ NationalSplitters::None.instance_for
50
+ end
51
+ def one_of *ndcs
52
+ options = Hash === ndcs.last ? ndcs.pop : {}
53
+
54
+ # Ruby 1.8 compatibility mode.
55
+ #
56
+ ndcs = ndcs.first if Array === ndcs.first
57
+
58
+ NationalSplitters::Variable.new options[:max_length], ndcs
59
+ end
60
+ def match regex, options = {}
61
+ NationalSplitters::Regex.instance_for regex, options[:on_fail_take]
62
+ end
63
+
64
+ # Local splitters.
65
+ #
66
+
67
+ #
68
+ #
69
+ def split *local
70
+ LocalSplitters::Fixed.instance_for local
71
+ end
72
+ def matched_split options = {}
73
+ Phony::LocalSplitters::Regex.instance_for options
74
+ end
75
+
76
+ end
77
+
78
+ end
@@ -1,7 +1,5 @@
1
1
  module Phony
2
2
 
3
- # This is the superclass of all special national number handlers.
4
- #
5
3
  # NationalCodes have a special numbers splitter, a national code splitter and a local code splitter.
6
4
  #
7
5
  class NationalCode
@@ -11,7 +9,7 @@ module Phony
11
9
  def initialize national_splitter, local_splitter, normalize = nil
12
10
  @national_splitter = national_splitter
13
11
  @local_splitter = local_splitter
14
- @normalize = !(normalize == false) # if nil, true (default), if false, false, if true, true.
12
+ @normalize = normalize != false
15
13
  end
16
14
 
17
15
  # Split gets a number without country code and splits it into
@@ -20,8 +18,7 @@ module Phony
20
18
  def split national_number
21
19
  ndc, rest = @national_splitter.split national_number.dup
22
20
  return ndc unless rest
23
- local = @local_splitter.split rest
24
- ndc ? [ndc, *local] : local
21
+ [ndc, *@local_splitter.split(rest)]
25
22
  end
26
23
 
27
24
  # Split gets a number without country code and removes a relative zero.
@@ -0,0 +1,20 @@
1
+ module Phony
2
+
3
+ module NationalSplitters
4
+
5
+ # TODO
6
+ #
7
+ class DSL
8
+
9
+ # TODO normalize option!
10
+ #
11
+ def >> local_splitter
12
+ national_code = Phony::NationalCode.new self, local_splitter
13
+ Phony::Country.new national_code
14
+ end
15
+
16
+ end
17
+
18
+ end
19
+
20
+ end
@@ -4,7 +4,7 @@ module Phony
4
4
 
5
5
  # TODO
6
6
  #
7
- class Fixed < Experimental
7
+ class Fixed < DSL
8
8
 
9
9
  attr_writer :special_splitter
10
10
 
@@ -5,7 +5,7 @@ module Phony
5
5
  # This is a national splitter for countries
6
6
  # which have no NDC / Area Code.
7
7
  #
8
- class None < Experimental
8
+ class None < DSL
9
9
 
10
10
  # Get a splitter. Caches.
11
11
  #
@@ -0,0 +1,49 @@
1
+ module Phony
2
+
3
+ module NationalSplitters
4
+
5
+ # National splitter class to split the ndc-local part of a number.
6
+ #
7
+ # Countries can create new instances according to their needs.
8
+ #
9
+ # Note: Countries should use instance_for
10
+ # to avoid getting new local splitter instances.
11
+ #
12
+ class Regex < Fixed
13
+
14
+ attr_reader :on_fail_take, :regex
15
+
16
+ # Get a splitter for the given format.
17
+ #
18
+ # Note: Not cached.
19
+ #
20
+ def self.instance_for regex, on_fail_take = nil
21
+ new regex, on_fail_take
22
+ end
23
+
24
+ def initialize regex, on_fail_take = nil
25
+ super on_fail_take
26
+
27
+ @regex = regex
28
+ end
29
+
30
+ # Split a local number according to an assumed country specific format.
31
+ #
32
+ # Examples
33
+ # * split '3643533' # => ['364', '35', '33'] # (Switzerland)
34
+ #
35
+ def split number
36
+ # Improve matching.
37
+ #
38
+ return [number.slice!(0..$1.size-1), number] if number =~ regex
39
+
40
+ # Not found.
41
+ #
42
+ super number
43
+ end
44
+
45
+ end
46
+
47
+ end
48
+
49
+ end
@@ -6,9 +6,9 @@ module Phony
6
6
 
7
7
  #
8
8
  #
9
- def initialize fallback, ndc_map
9
+ def initialize fallback, ndcs
10
10
  super fallback
11
- @ndcs = restructure ndc_map
11
+ @ndcs = optimize ndcs
12
12
  end
13
13
 
14
14
  # Takes a national number and splits it into ndc and rest.
@@ -34,14 +34,14 @@ module Phony
34
34
 
35
35
  # Not found.
36
36
  #
37
- return super(fallback_number)
37
+ super fallback_number
38
38
  end
39
39
 
40
40
  private
41
41
 
42
- def restructure ndc_map
43
- optimize ndc_map.values.flatten
44
- end
42
+ # def restructure ndc_map
43
+ # optimize ndc_map.values.flatten
44
+ # end
45
45
 
46
46
  # Optimizes and restructures the given ndcs array.
47
47
  #
data/lib/phony/vanity.rb CHANGED
@@ -1,4 +1,7 @@
1
1
  module Phony
2
+
3
+ # Helper module that maps vanity numbers to digit numbers.
4
+ #
2
5
  module Vanity
3
6
 
4
7
  # Returns a char to number mapping string for the String#tr method.
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  describe Phony::CountryCodes do
4
4
 
5
5
  before(:all) do
6
- @countries = Phony::CountryCodes.new
6
+ @countries = Phony::CountryCodes.instance
7
7
  end
8
8
 
9
9
  describe 'split' do
@@ -2,57 +2,24 @@ require 'spec_helper'
2
2
 
3
3
  describe Phony::Country do
4
4
 
5
- describe "configured" do
6
- context "with variable ndcs" do
5
+ context 'regression' do
6
+ describe 'iceland' do
7
7
  before(:each) do
8
- @country = Phony::Country.configured :local_format => [3, 2, 2],
9
- :service_local_format => [3, 3],
10
- :mobile_local_format => [1, 2, 4],
11
- :ndc_fallback_length => 4,
12
- :ndc_mapping => {
13
- :normal => ['44'],
14
- :service => ['800'],
15
- :mobile => ['76']
16
- }
17
- end
18
- it 'works for normal numbers' do
19
- @country.split('443643532').should == ['44', '364', '35', '32']
20
- end
21
- it 'works with service numbers' do
22
- @country.split('800333666').should == ['800', '333', '666']
23
- end
24
- it 'works with mobile numbers' do
25
- @country.split('764333532').should == ['76', '4', '33', '3532']
26
- end
27
- it 'uses the fallback if it is not in the mapping' do
28
- @country.split('123456789').should == ['1234', '567', '89']
29
- end
30
- end
31
- context "with fixed ndcs" do
32
- before(:each) do
33
- @country = Phony::Country.fixed :ndc_length => 2,
34
- :local_format => [3, 2, 2],
35
- :service_local_format => [3, 3],
36
- :service_ndcs => ['800']
37
- end
38
- it 'works for non-service numbers' do
39
- @country.split('443643532').should == ['44', '364', '35', '32']
40
- end
41
- it 'works for service numbers' do
42
- @country.split('800333666').should == ['800', '333', '666']
43
- end
44
- it 'works with mobile numbers' do
45
- @country.split('764333532').should == ['76', '433', '35', '32']
8
+ national_splitter = Phony::NationalSplitters::None.instance_for
9
+ local_splitter = Phony::LocalSplitters::Fixed.instance_for [3, 4]
10
+
11
+ national_code = Phony::NationalCode.new national_splitter, local_splitter
12
+ @iceland = described_class.new national_code
46
13
  end
47
- it 'uses a fixed length' do
48
- @country.split('123456789').should == ['12', '345', '67', '89']
14
+ it 'splits correctly' do
15
+ @iceland.split('112').should == ['112']
49
16
  end
50
17
  end
51
18
  end
52
19
 
53
20
  context "without special cases" do
54
21
  before(:each) do
55
- national_splitter = Phony::NationalSplitters::Variable.new 4, { :normal => ['44'] }
22
+ national_splitter = Phony::NationalSplitters::Variable.new 4, ['44']
56
23
  local_splitter = Phony::LocalSplitters::Fixed.instance_for [3, 2, 2]
57
24
  national_code = Phony::NationalCode.new national_splitter, local_splitter
58
25
 
@@ -73,11 +40,11 @@ describe Phony::Country do
73
40
 
74
41
  context "without special cases" do
75
42
  before(:each) do
76
- special_national_splitter = Phony::NationalSplitters::Variable.new nil, { :service => ['800'] }
43
+ special_national_splitter = Phony::NationalSplitters::Variable.new nil, ['800']
77
44
  special_local_splitter = Phony::LocalSplitters::Fixed.instance_for [3, 3]
78
45
  special_code = Phony::NationalCode.new special_national_splitter, special_local_splitter
79
46
 
80
- national_splitter = Phony::NationalSplitters::Variable.new 4, { :normal => ['44'] }
47
+ national_splitter = Phony::NationalSplitters::Variable.new 4, ['44']
81
48
  local_splitter = Phony::LocalSplitters::Fixed.instance_for [3, 2, 2]
82
49
  national_code = Phony::NationalCode.new national_splitter, local_splitter
83
50
 
@@ -43,6 +43,14 @@ describe Phony::LocalSplitters::Fixed do
43
43
  @splitter.split('364353').should == ['364','35','3']
44
44
  end
45
45
  end
46
+ context "with hard number (iceland regression)" do
47
+ before(:each) do
48
+ @splitter = described_class.new [3, 4]
49
+ end
50
+ it 'splits correctly' do
51
+ @splitter.split('112').should == ['112']
52
+ end
53
+ end
46
54
  end
47
55
 
48
56
  end
@@ -3,6 +3,19 @@ require 'spec_helper'
3
3
  describe Phony::NationalCode do
4
4
 
5
5
  describe 'split' do
6
+ context 'regression' do
7
+ describe 'iceland' do
8
+ before(:each) do
9
+ national_splitter = Phony::NationalSplitters::None.instance_for
10
+ local_splitter = Phony::LocalSplitters::Fixed.instance_for [3, 4]
11
+
12
+ @national = Phony::NationalCode.new national_splitter, local_splitter
13
+ end
14
+ it 'splits correctly' do
15
+ @national.split('112').should == [nil, '112']
16
+ end
17
+ end
18
+ end
6
19
  context 'with fixed ndc (Swiss)' do
7
20
  before(:each) do
8
21
  national_splitter = Phony::NationalSplitters::Fixed.instance_for 2
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe Phony::NationalSplitters::Regex do
4
+
5
+ describe 'instance_for' do
6
+ it 'caches correctly (not)' do
7
+ described_class.instance_for(//).should_not equal(described_class.instance_for(//))
8
+ end
9
+ end
10
+
11
+ describe 'split' do
12
+ context 'without on_fail' do
13
+ let(:splitter) { described_class.instance_for(/^(123)\d+$/) }
14
+ end
15
+ context 'with on_fail 2' do
16
+ let(:splitter) { described_class.instance_for(/^(123)\d+$/, 2) }
17
+ it 'uses the on_fail_take' do
18
+ splitter.split('23456789').should == ['23', '456789']
19
+ end
20
+ end
21
+ end
22
+
23
+ end
@@ -5,9 +5,7 @@ describe Phony::NationalSplitters::Variable do
5
5
  describe 'split' do
6
6
  context 'normal' do
7
7
  before(:each) do
8
- @splitter = Phony::NationalSplitters::Variable.new 4, :normal => ['1', '316'],
9
- :mobile => ['67', '68',],
10
- :service => ['669', '711']
8
+ @splitter = Phony::NationalSplitters::Variable.new 4, ['1', '316', '67', '68', '669', '711']
11
9
  end
12
10
  it "handles Vienna" do
13
11
  @splitter.split('198110').should == ['1', '98110']
@@ -24,7 +22,7 @@ describe Phony::NationalSplitters::Variable do
24
22
  end
25
23
  context 'special handling for using the variable size splitter for Swiss service numbers' do
26
24
  before(:each) do
27
- @splitter = Phony::NationalSplitters::Variable.new 2, :service => ['800']
25
+ @splitter = Phony::NationalSplitters::Variable.new 2, ['800']
28
26
  end
29
27
  it "should handle swiss service numbers" do
30
28
  @splitter.split('800223344').should == ['800', '223344']