countries-phone_numbers 0.1.0 → 1.0.0

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.
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