countries-phone_numbers 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 86db77726a2eb98b11c2aef026b1d121d3dcd184
4
- data.tar.gz: b0083df537fe9839eb25f25a1a19148d4b581e2d
3
+ metadata.gz: 6e01743be9db3b672170580db4f87af93098682b
4
+ data.tar.gz: f7ee78a09bebc978aa02c1260d29e86e1fec35e7
5
5
  SHA512:
6
- metadata.gz: db79a2bdc029e69156295bc0790c4034e4c213dc72d60ed70bff13ff3a972541dfbf7b94f6effc150f3d946774143ca3202fdcb57c908dbdc058d0917f41e8d9
7
- data.tar.gz: 2058fb544e19f9da9b3f9734f6112ec8043fa78e51513c9db3b6a524873ef705aa7f1ad7b842100498b21998f45c43c780bb54177f25dbb92196e3732848e837
6
+ metadata.gz: 7ef8f13cbb4faae29eb73b7bdcdaf163de76f6695648aa9545e0fcd1b1aa8f9e3feac59aa3f4b5d28a41858e273872eaa72abe18e68eb5a223d2ac3b0580c689
7
+ data.tar.gz: 017cd3072663ce7c2c39905adde84874f5a02959030c884d379c6566e892a0f80864bd4bbde511c9926871fb9718ceebf06c2c3da3d5e3bfd10758701f040810
data/README.md CHANGED
@@ -6,7 +6,7 @@ Integrate phone number to country lookup functionality into the ever-popular [Co
6
6
 
7
7
  Add this line to your application's Gemfile:
8
8
 
9
- gem 'countries-plus-phonenumbers'
9
+ gem 'countries-phone_numbers'
10
10
 
11
11
  And then execute:
12
12
 
@@ -14,7 +14,7 @@ And then execute:
14
14
 
15
15
  Or install it yourself as:
16
16
 
17
- $ gem install countries-plus-phonenumbers
17
+ $ gem install countries-phone_numbers
18
18
 
19
19
  ## Usage
20
20
 
@@ -35,7 +35,7 @@ This gives you the normal country object. Treat it like you would any other sear
35
35
 
36
36
  ## What about countries that share the same Country Code?
37
37
 
38
- When multiple countries share a single country code - for instance, the North American Number Plan (NANP) - CountryDetectors are employed to provide additional analysis and intepretation. These detectors are not perfect, but they should catch most ambiguous situations.
38
+ When multiple countries share a single country code - for instance, the North American Number Plan (NANP) - CountryDetectors are employed to provide additional intepretation. These detectors are not perfect, but they should catch many ambiguous situations.
39
39
 
40
40
  The detectors are configured in `country_detectors.yaml`.
41
41
 
@@ -18,8 +18,8 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_dependency 'countries', '>= 0.9'
22
- spec.add_dependency 'phony', '>= 1.9'
21
+ spec.add_dependency 'countries', '~> 0.9'
22
+ spec.add_dependency 'phony', '~> 2.2'
23
23
 
24
24
  spec.add_development_dependency "bundler", "~> 1.3"
25
25
  spec.add_development_dependency "rake"
@@ -5,16 +5,37 @@ require 'countries'
5
5
  require 'phony'
6
6
 
7
7
  # Country::PhoneNumber
8
+ require 'countries/phone_numbers/extensions'
8
9
  require 'countries/phone_numbers/detector_factory'
9
- require 'countries/phone_numbers/country_detector'
10
- require 'countries/phone_numbers/one_of_country_detector'
11
- require 'countries/phone_numbers/start_with_country_detector'
10
+ require 'countries/phone_numbers/detector'
11
+ require 'countries/phone_numbers/one_of_detector'
12
+ require 'countries/phone_numbers/start_with_detector'
12
13
 
13
14
  # Gem extensions
14
- require 'countries/iso3166'
15
+ # require 'countries/iso3166'
15
16
 
16
17
  module Countries
17
18
  module PhoneNumbers
19
+ extend Extensions::ClassMethods
18
20
  DATA_FILE = File.join( 'lib', 'countries', 'phone_numbers', 'detectors.yaml' )
21
+
22
+ ##
23
+ # Find all countries with shared country codes.
24
+ def self.shared_country_codes
25
+ codes = Country.all.map { |cc| Country[cc[1]].country_code }.uniq
26
+ shared = codes.each_with_object({}){ |cc,h| h[cc] = Country.find_all_countries_by_country_code(cc) }
27
+ shared.reject!{ |key,entry| entry.nil? or entry.count <= 1 }
28
+ shared.each{ |cc,countries| shared[cc] = countries.map{ |c| c.name } }
29
+ end
30
+
31
+ ##
32
+ # Find all countries with shared country codes and do not have a dedicated detector.
33
+ def self.unresolved_country_codes
34
+ shared_country_codes.reject{ |key,value| self.phone_number_detector_factory.detector_for? key or key == '' }
35
+ end
36
+
19
37
  end
20
38
  end
39
+
40
+ # Merge the phone number extensions into the base Country object.
41
+ require 'countries/phone_numbers/ext'
@@ -1,4 +1,4 @@
1
- class Countries::PhoneNumbers::CountryDetector
1
+ class Countries::PhoneNumbers::Detector
2
2
 
3
3
  attr_accessor :country_codes, :applies_to, :default
4
4
 
@@ -38,11 +38,11 @@ class Countries::PhoneNumbers::DetectorFactory
38
38
  # Build a new config tool based on the given strategy
39
39
  return case
40
40
  when config.include?('start_with')
41
- Countries::PhoneNumbers::StartWithCountryDetector.new config
41
+ Countries::PhoneNumbers::StartWithDetector.new config
42
42
  when config.include?('one_of')
43
- Countries::PhoneNumbers::OneOfCountryDetector.new config
43
+ Countries::PhoneNumbers::OneOfDetector.new config
44
44
  else
45
- Countries::PhoneNumbers::CountryDetector.new config
45
+ Countries::PhoneNumbers::Detector.new config
46
46
  end
47
47
  end
48
48
 
@@ -0,0 +1,5 @@
1
+ require 'countries/phone_numbers'
2
+
3
+ class ISO3166::Country
4
+ include Countries::PhoneNumbers::Extensions
5
+ end
@@ -0,0 +1,95 @@
1
+ module Countries::PhoneNumbers::Extensions
2
+
3
+ def self.included( base )
4
+ base.extend ClassMethods
5
+ end
6
+
7
+ def format_phone_number( number, options={} )
8
+ Phony.formatted( number, options )
9
+ end
10
+
11
+ def format_local_phone_number( number, options={} )
12
+ format_phone_number( number, {format: :local}.merge(options) )
13
+ end
14
+
15
+ def format_international_phone_number( number, options={} )
16
+ format_phone_number( number, {format: :international}.merge(options) )
17
+ end
18
+
19
+ def format_national_phone_number( number, options={} )
20
+ format_phone_number( number, {format: :national}.merge(options) )
21
+ end
22
+
23
+ module ClassMethods
24
+ def normalize_phone_number( number )
25
+ Phony.normalize( number )
26
+ end
27
+
28
+ def tokenize_phone_number( number )
29
+ Phony.split( normalize_phone_number( number ) )
30
+ end
31
+
32
+ ##
33
+ # Find the first country by the given telephone number. Returns an array of country code and data
34
+ def find_by_phone_number( number )
35
+ found = find_all_by_phone_number(number)
36
+ found.nil? ? nil : found.first
37
+ end
38
+
39
+ ##
40
+ # Find all possible countries for the given telephone number.
41
+ # Generally we try to eliminate duplicates by using country code specific detectors.
42
+ def find_all_by_phone_number( number )
43
+ normalised_number = tokenize_phone_number( number )
44
+ country_code = normalised_number.first
45
+
46
+ # Is this a detector country?
47
+ detector = phone_number_detector_factory.detector_for( country_code )
48
+ if detector
49
+ return detector.find_all_by_phone_number( normalised_number )
50
+
51
+ # Otherwise ask the general code base for the number
52
+ else
53
+ return Country.find_all_by_country_code( country_code )
54
+ end
55
+
56
+ rescue
57
+ return nil
58
+ end
59
+
60
+ ##
61
+ # Find the first country by the given telephone number. Returns the country object itself.
62
+ def find_country_by_phone_number( number )
63
+ found = Country.find_all_countries_by_phone_number(number)
64
+ found.nil? ? nil : found.first
65
+ end
66
+
67
+ ##
68
+ # Find all possible countries for the given telephone number.
69
+ # Generally we try to eliminate duplicates by using country code specific detectors.
70
+ def find_all_countries_by_phone_number( number )
71
+ normalised_number = tokenize_phone_number( number )
72
+ country_code = normalised_number.first
73
+
74
+ # Is this a detector country?
75
+ detector = phone_number_detector_factory.detector_for( country_code )
76
+ if detector
77
+ return detector.find_all_countries_by_phone_number( normalised_number )
78
+
79
+ # Otherwise ask Country for the number
80
+ else
81
+ return Country.find_all_countries_by_country_code( country_code )
82
+ end
83
+
84
+ rescue
85
+ return nil
86
+ end
87
+
88
+ protected
89
+
90
+ def phone_number_detector_factory
91
+ @@phone_number_detector_factory ||= Countries::PhoneNumbers::DetectorFactory.new
92
+ end
93
+ end
94
+
95
+ end
@@ -1,4 +1,4 @@
1
- class Countries::PhoneNumbers::OneOfCountryDetector < Countries::PhoneNumbers::CountryDetector
1
+ class Countries::PhoneNumbers::OneOfDetector < Countries::PhoneNumbers::Detector
2
2
 
3
3
  def initialize( config )
4
4
  super config
@@ -1,4 +1,4 @@
1
- class Countries::PhoneNumbers::StartWithCountryDetector < Countries::PhoneNumbers::CountryDetector
1
+ class Countries::PhoneNumbers::StartWithDetector < Countries::PhoneNumbers::Detector
2
2
 
3
3
  def initialize( config )
4
4
  super config
@@ -1,5 +1,5 @@
1
1
  module Countries
2
2
  module PhoneNumbers
3
- VERSION = "0.1.0"
3
+ VERSION = "1.0.0"
4
4
  end
5
5
  end
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'countries/phone_numbers'
3
2
 
4
3
  describe ISO3166::Country, '#find_*_by_phone_number' do
5
4
  subject { Country }
@@ -14,7 +13,7 @@ describe ISO3166::Country, '#find_*_by_phone_number' do
14
13
  Country.find_country_by_phone_number( 'abc' ).should == nil
15
14
  end
16
15
 
17
- # Test all data given in the 'TEST' block above
16
+ # Test all data given in the 'TEST' block (defined in the spec helper)
18
17
  TEST_DATA.each do |alpha2, numbers|
19
18
  numbers.each do |number|
20
19
  it "recognises #{number} as #{alpha2.to_s}" do
@@ -27,12 +26,4 @@ describe ISO3166::Country, '#find_*_by_phone_number' do
27
26
  end
28
27
  end
29
28
 
30
- Country.unresolved_country_codes.each do |country_code, countries|
31
- pending "Need to resolve CC: #{country_code} for #{countries.join(', ')}."
32
- end
33
-
34
- (Country.all.map{ |country| country[1] } - TEST_DATA.keys).each do |alpha2|
35
- pending "No tests for #{Country[alpha2].name} (#{alpha2})."
36
- end
37
-
38
29
  end
@@ -13,7 +13,7 @@ describe Countries::PhoneNumbers::DetectorFactory do
13
13
  let(:one_of_config) { { 'applies_to' => applies_to, 'default' => default_country, 'one_of' => { alternate_country => [ one_of_prefix ] } } }
14
14
  let(:start_with_config) { { 'applies_to' => applies_to, 'default' => default_country, 'start_with' => { alternate_country => [ start_with_prefix ] } } }
15
15
 
16
- let(:default_detector) { Countries::PhoneNumbers::CountryDetector.new(default_config) }
16
+ let(:default_detector) { Countries::PhoneNumbers::Detector.new(default_config) }
17
17
 
18
18
  describe '.new' do
19
19
 
@@ -96,15 +96,15 @@ describe Countries::PhoneNumbers::DetectorFactory do
96
96
 
97
97
  describe '#build_detector' do
98
98
  it 'returns a generic detector' do
99
- expect( subject.send(:build_detector, default_config) ).to be_a(Countries::PhoneNumbers::CountryDetector)
99
+ expect( subject.send(:build_detector, default_config) ).to be_a(Countries::PhoneNumbers::Detector)
100
100
  end
101
101
 
102
102
  it 'returns a one-of detector' do
103
- expect( subject.send(:build_detector, one_of_config) ).to be_a(Countries::PhoneNumbers::OneOfCountryDetector)
103
+ expect( subject.send(:build_detector, one_of_config) ).to be_a(Countries::PhoneNumbers::OneOfDetector)
104
104
  end
105
105
 
106
106
  it 'returns a start-with detector' do
107
- expect( subject.send(:build_detector, start_with_config) ).to be_a(Countries::PhoneNumbers::StartWithCountryDetector)
107
+ expect( subject.send(:build_detector, start_with_config) ).to be_a(Countries::PhoneNumbers::StartWithDetector)
108
108
  end
109
109
  end
110
110
 
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+ require 'countries/phone_numbers'
3
+
4
+ describe Countries::PhoneNumbers, '#find_*_by_phone_number' do
5
+ subject { Countries::PhoneNumbers }
6
+
7
+ # Test a bogus phone number
8
+ it 'ignores bogus phone numbers (single digit)' do
9
+ subject.find_country_by_phone_number( '5' ).should == nil
10
+ end
11
+
12
+ # Test another bogus phone number
13
+ it 'ignores bogus phone numbers (text)' do
14
+ subject.find_country_by_phone_number( 'abc' ).should == nil
15
+ end
16
+
17
+ # Test all data given in the 'TEST' block above
18
+ TEST_DATA.each do |alpha2, numbers|
19
+ numbers.each do |number|
20
+ it "recognises #{number} as #{alpha2.to_s}" do
21
+ subject.find_country_by_phone_number(number).should_not be_nil
22
+ subject.find_country_by_phone_number(number).alpha2.should == alpha2.to_s
23
+ end
24
+ it "returns only one country for #{number}" do
25
+ subject.find_all_countries_by_phone_number(number).should have(1).country
26
+ end
27
+ end
28
+ end
29
+
30
+ Countries::PhoneNumbers.unresolved_country_codes.each do |country_code, countries|
31
+ pending "Need to resolve CC: #{country_code} for #{countries.join(', ')}."
32
+ end
33
+
34
+ (Country.all.map{ |country| country[1] } - TEST_DATA.keys).each do |alpha2|
35
+ pending "No tests for #{Country[alpha2].name} (#{alpha2})."
36
+ end
37
+
38
+ end
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: countries-phone_numbers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ian Lloyd
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-03 00:00:00.000000000 Z
11
+ date: 2014-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: countries
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ~>
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0.9'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ~>
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.9'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: phony
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ~>
32
32
  - !ruby/object:Gem::Version
33
- version: '1.9'
33
+ version: '2.2'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ~>
39
39
  - !ruby/object:Gem::Version
40
- version: '1.9'
40
+ version: '2.2'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -122,16 +122,18 @@ files:
122
122
  - README.md
123
123
  - Rakefile
124
124
  - countries-phone_numbers.gemspec
125
- - lib/countries/iso3166.rb
126
125
  - lib/countries/phone_numbers.rb
127
- - lib/countries/phone_numbers/country_detector.rb
126
+ - lib/countries/phone_numbers/detector.rb
128
127
  - lib/countries/phone_numbers/detector_factory.rb
129
128
  - lib/countries/phone_numbers/detectors.yaml
130
- - lib/countries/phone_numbers/one_of_country_detector.rb
131
- - lib/countries/phone_numbers/start_with_country_detector.rb
129
+ - lib/countries/phone_numbers/ext.rb
130
+ - lib/countries/phone_numbers/extensions.rb
131
+ - lib/countries/phone_numbers/one_of_detector.rb
132
+ - lib/countries/phone_numbers/start_with_detector.rb
132
133
  - lib/countries/phone_numbers/version.rb
133
134
  - spec/countries/country_spec.rb
134
135
  - spec/countries/phone_numbers/detector_factory_spec.rb
136
+ - spec/countries/phone_numbers_spec.rb
135
137
  - spec/spec_helper.rb
136
138
  - spec/test_data.yaml
137
139
  homepage: http://github.com/illoyd/countries-phone_numbers
@@ -161,5 +163,6 @@ summary: Integrate phone number searching into the Country gem using Phony
161
163
  test_files:
162
164
  - spec/countries/country_spec.rb
163
165
  - spec/countries/phone_numbers/detector_factory_spec.rb
166
+ - spec/countries/phone_numbers_spec.rb
164
167
  - spec/spec_helper.rb
165
168
  - spec/test_data.yaml
@@ -1,91 +0,0 @@
1
- require 'countries'
2
- require 'phony'
3
-
4
- class ISO3166::Country
5
-
6
- def self.normalize_phone_number( number )
7
- Phony.normalize( number )
8
- end
9
-
10
- def self.tokenize_phone_number( number )
11
- Phony.split( normalize_phone_number( number ) )
12
- end
13
-
14
- ##
15
- # Find the first country by the given telephone number. Returns an array of country code and data
16
- def self.find_by_phone_number( number )
17
- found = find_all_by_phone_number(number)
18
- found.nil? ? nil : found.first
19
- end
20
-
21
- ##
22
- # Find all possible countries for the given telephone number.
23
- # Generally we try to eliminate duplicates by using country code specific detectors.
24
- def self.find_all_by_phone_number( number )
25
- normalised_number = tokenize_phone_number( number )
26
- country_code = normalised_number.first
27
-
28
- # Is this a detector country?
29
- detector = phone_number_detector_factory.detector_for( country_code )
30
- if detector
31
- return detector.find_all_by_phone_number( normalised_number )
32
-
33
- # Otherwise ask the general code base for the number
34
- else
35
- return find_all_by_country_code( country_code )
36
- end
37
-
38
- rescue
39
- return nil
40
- end
41
-
42
- ##
43
- # Find the first country by the given telephone number. Returns the country object itself.
44
- def self.find_country_by_phone_number( number )
45
- found = find_all_countries_by_phone_number(number)
46
- found.nil? ? nil : found.first
47
- end
48
-
49
- ##
50
- # Find all possible countries for the given telephone number.
51
- # Generally we try to eliminate duplicates by using country code specific detectors.
52
- def self.find_all_countries_by_phone_number( number )
53
- normalised_number = tokenize_phone_number( number )
54
- country_code = normalised_number.first
55
-
56
- # Is this a detector country?
57
- detector = phone_number_detector_factory.detector_for( country_code )
58
- if detector
59
- return detector.find_all_countries_by_phone_number( normalised_number )
60
-
61
- # Otherwise ask the general code base for the number
62
- else
63
- return find_all_countries_by_country_code( country_code )
64
- end
65
-
66
- rescue
67
- return nil
68
- end
69
-
70
- ##
71
- # Find all countries with shared country codes.
72
- def self.shared_country_codes
73
- codes = Country.all.map { |cc| Country[cc[1]].country_code }.uniq
74
- shared = codes.each_with_object({}){ |cc,h| h[cc] = Country.find_all_countries_by_country_code(cc) }
75
- shared.reject!{ |key,entry| entry.nil? or entry.count <= 1 }
76
- shared.each{ |cc,countries| shared[cc] = countries.map{ |c| c.name } }
77
- end
78
-
79
- ##
80
- # Find all countries with shared country codes and do not have a dedicated detector.
81
- def self.unresolved_country_codes
82
- self.shared_country_codes.reject{ |key,value| self.phone_number_detector_factory.detector_for? key or key == '' }
83
- end
84
-
85
- protected
86
-
87
- def self.phone_number_detector_factory
88
- @@phone_number_detector_factory ||= Countries::PhoneNumbers::DetectorFactory.new
89
- end
90
-
91
- end