phonie 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/Gemfile +3 -4
- data/Rakefile +1 -9
- data/Readme.rdoc +14 -2
- data/lib/phonie.rb +1 -0
- data/lib/phonie/country.rb +1 -1
- data/lib/phonie/data/phone_countries.yml +1352 -1305
- data/lib/phonie/railties/locales/en.yml +4 -0
- data/lib/phonie/railties/locales/es.yml +4 -0
- data/lib/phonie/railties/validator.rb +15 -0
- data/lib/phonie/version.rb +1 -1
- data/phonie.gemspec +4 -1
- data/tasks/tests.rake +9 -0
- data/test/countries/am_test.rb +12 -0
- data/test/countries/az_test.rb +12 -0
- data/test/countries/bs_test.rb +13 -0
- data/test/countries/cl_test.rb +22 -0
- data/test/countries/it_test.rb +12 -0
- data/test/countries/lt_test.rb +12 -0
- data/test/countries/lu_test.rb +12 -0
- data/test/countries/lv_test.rb +12 -0
- data/test/countries/ru_test.rb +12 -0
- data/test/railties/validator_test.rb +37 -0
- data/test/test_helper.rb +1 -3
- data/tools/generate +112 -0
- data/tools/russian_area_codes.rb +13 -0
- metadata +67 -4
- data/Gemfile.lock +0 -10
@@ -0,0 +1,15 @@
|
|
1
|
+
I18n.load_path += Dir.glob( File.expand_path('../locales/*.{rb,yml}', __FILE__) )
|
2
|
+
|
3
|
+
class PhoneValidator < ActiveModel::EachValidator
|
4
|
+
def validate_each(object, attribute, value)
|
5
|
+
return if value.blank?
|
6
|
+
phone = Phonie::Phone.parse(value)
|
7
|
+
|
8
|
+
if phone.nil?
|
9
|
+
object.errors.add(attribute, :invalid_phone_number)
|
10
|
+
else
|
11
|
+
formated = phone.format( phone.extension ? :default_with_extension : :default)
|
12
|
+
object.send("#{attribute}=", formated) if object.respond_to?("#{attribute}=")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/phonie/version.rb
CHANGED
data/phonie.gemspec
CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.version = Phonie::VERSION
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
9
|
s.authors = ['Tomislav Car', 'Todd Eichel', 'Don Morrison', 'Wesley Moxam']
|
10
|
-
s.email = ['tomislav@infinum.hr', 'todd@toddeichel.com', 'elskwid@gmail.com', 'wesley@wmoxam.com']
|
10
|
+
s.email = ['tomislav@infinum.hr', 'todd@toddeichel.com', 'elskwid@gmail.com', 'wesley@wmoxam.com']
|
11
11
|
s.homepage = "http://github.com/wmoxam/phonie"
|
12
12
|
s.summary = %q{Phone number parsing, validation and formatting}
|
13
13
|
s.description = %q{Phone number parsing, validation and formatting}
|
@@ -15,4 +15,7 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.files = `git ls-files`.split("\n")
|
16
16
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
17
|
s.require_paths = ["lib"]
|
18
|
+
s.add_development_dependency 'rake'
|
19
|
+
s.add_development_dependency 'nokogiri'
|
20
|
+
s.add_development_dependency 'activemodel'
|
18
21
|
end
|
data/tasks/tests.rake
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
## Armenia
|
4
|
+
class AMTest < Phonie::TestCase
|
5
|
+
def test_local
|
6
|
+
parse_test('+37422212345', '374', '222', '12345', 'Armenia', false)
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_mobile
|
10
|
+
parse_test('+37451234567', '374', '5', '1234567', 'Armenia', true)
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
## Azerbaijan
|
4
|
+
class AZTest < Phonie::TestCase
|
5
|
+
def test_local
|
6
|
+
parse_test('+994221234567', '994', '22', '1234567', 'Azerbaijan', false)
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_mobile
|
10
|
+
parse_test('+994401234567', '994', '40', '1234567', 'Azerbaijan', true)
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
## Bahamas
|
4
|
+
class BSTest < Phonie::TestCase
|
5
|
+
|
6
|
+
def test_local
|
7
|
+
parse_test('+12424611234', '1', '242', '4611234', 'Bahamas')
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_mobile
|
11
|
+
parse_test('+12424621234', '1', '242', '4621234', 'Bahamas')
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
## Chile
|
4
|
+
class CLTest < Phonie::TestCase
|
5
|
+
|
6
|
+
def test_local
|
7
|
+
parse_test('+56 2 12345678', '56', '2', '12345678', 'Chile', false)
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_mobile
|
11
|
+
parse_test('+56 9 12345678', '56', '9', '12345678', 'Chile', true)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_other_cities
|
15
|
+
parse_test('+56 32 1234567', '56', '32', '1234567', 'Chile', false)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_voip
|
19
|
+
parse_test('+56 44 1234567', '56', '44', '1234567', 'Chile', false)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
## Italy
|
4
|
+
class ITTest < Phonie::TestCase
|
5
|
+
def test_local
|
6
|
+
parse_test('+39 035 1234567', '39', '035', '1234567', 'Italy', false)
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_mobile
|
10
|
+
parse_test('+39 383 1234567', '39', '383', '1234567', 'Italy', true)
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
## Lithuania
|
4
|
+
class LTTest < Phonie::TestCase
|
5
|
+
def test_local
|
6
|
+
parse_test('+37042512345', '370', '425', '12345', 'Lithuania', false)
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_mobile
|
10
|
+
parse_test('+37062512345', '370', '625', '12345', 'Lithuania', true)
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
## Luxembourg
|
4
|
+
class LUTest < Phonie::TestCase
|
5
|
+
def test_local
|
6
|
+
parse_test('+352 2422 1234', '352', '2422', '1234', "Luxembourg", false)
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_mobile
|
10
|
+
parse_test('+352 671 123456', '352', '671', '123456', "Luxembourg", true)
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
## Latvia
|
4
|
+
class LVTest < Phonie::TestCase
|
5
|
+
def test_local
|
6
|
+
parse_test('+37164123456', '371', '64', '123456', 'Latvia', false)
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_mobile
|
10
|
+
parse_test('+37129123456', '371', '29', '123456', 'Latvia', true)
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
## Russia
|
4
|
+
class RUTest < Phonie::TestCase
|
5
|
+
def test_local
|
6
|
+
parse_test('+74845612345', '7', '48456', '12345', 'Russian Federation', false)
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_mobile
|
10
|
+
parse_test('+79123456789', '7', '9', '123456789', 'Russian Federation', true)
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
require 'active_model'
|
4
|
+
require 'phonie/railties/validator'
|
5
|
+
class SomeModel < Struct.new(:phone)
|
6
|
+
include ActiveModel::Validations
|
7
|
+
validates :phone, phone: true
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
class PhoneValidatorTest < Phonie::TestCase
|
12
|
+
def test_blank_phone
|
13
|
+
assert SomeModel.new(nil).valid?
|
14
|
+
assert SomeModel.new('').valid?
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_valid_model
|
18
|
+
model = SomeModel.new('+1 251 123 4567')
|
19
|
+
assert model.valid?
|
20
|
+
|
21
|
+
assert model.phone == '+12511234567'
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_valid_number_with_extension
|
25
|
+
model = SomeModel.new('+1 251 123 4567 ex 1234')
|
26
|
+
assert model.valid?
|
27
|
+
|
28
|
+
assert model.phone == '+12511234567x1234'
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_invalid_model
|
32
|
+
model = SomeModel.new('+1 251 123 456')
|
33
|
+
assert model.invalid?
|
34
|
+
|
35
|
+
assert !model.errors[:phone].empty?
|
36
|
+
end
|
37
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -6,9 +6,7 @@ require 'test/unit'
|
|
6
6
|
require 'phonie'
|
7
7
|
|
8
8
|
def parse_test(raw, country_code, area_code, number, country_name = nil, is_mobile = nil)
|
9
|
-
pn = Phonie::Phone.parse(raw)
|
10
|
-
|
11
|
-
assert_not_nil pn, %Q{parse should pass}
|
9
|
+
pn = Phonie::Phone.parse!(raw)
|
12
10
|
assert_equal pn.country_code, country_code
|
13
11
|
assert_equal pn.area_code, area_code
|
14
12
|
assert_equal pn.number, number
|
data/tools/generate
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'tempfile'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
@data_file = File.join(File.dirname(__FILE__), '..', 'lib', 'phonie', 'data', 'phone_countries.yml')
|
8
|
+
@readme_file = File.join(File.dirname(__FILE__), '..', 'Readme.rdoc')
|
9
|
+
|
10
|
+
def usage
|
11
|
+
puts "USAGE: tools/generate COUNTRY_NAME"
|
12
|
+
puts "Generates test case, adds missing fields to country data, and updates README.rdoc to include country"
|
13
|
+
exit(0)
|
14
|
+
end
|
15
|
+
|
16
|
+
def already_exists?
|
17
|
+
if File.exists?(@test_filename)
|
18
|
+
puts "It appears that #{@country} is already supported. See #{@test_filename}"
|
19
|
+
true
|
20
|
+
else
|
21
|
+
false
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_country_code
|
26
|
+
YAML.load(File.read(@data_file)).each_pair do |key, c|
|
27
|
+
return c[:char_3_code].downcase if c[:name].downcase == @country.downcase
|
28
|
+
end
|
29
|
+
nil
|
30
|
+
end
|
31
|
+
|
32
|
+
def get_country_call_code
|
33
|
+
YAML.load(File.read(@data_file)).each_pair do |key, c|
|
34
|
+
return key if c[:name].downcase == @country.downcase
|
35
|
+
end
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def create_test_file
|
40
|
+
country_call_code = get_country_call_code
|
41
|
+
|
42
|
+
File.open(@test_filename, 'w') do |test_file|
|
43
|
+
test_file.print <<-eof
|
44
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
45
|
+
|
46
|
+
## #{@country}
|
47
|
+
class #{@country_code.upcase}Test < Phonie::TestCase
|
48
|
+
def test_local
|
49
|
+
parse_test('+#{country_call_code}', '#{country_call_code}', '', '', '#{@country}', false)
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_mobile
|
53
|
+
parse_test('+#{country_call_code}', '#{country_call_code}', '', '', '#{@country}', true)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
eof
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def add_missing_fields
|
61
|
+
hash = YAML.load(File.read(@data_file))
|
62
|
+
hash[get_country_call_code].merge!({:area_code => ' ',
|
63
|
+
:local_number_format => ' ',
|
64
|
+
:mobile_format => ' ',
|
65
|
+
:number_format => ' '})
|
66
|
+
File.open(@data_file, 'w') do |f|
|
67
|
+
f.puts hash.to_yaml
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def update_readme
|
72
|
+
readme = File.open(@readme_file, 'r')
|
73
|
+
new_readme = Tempfile.new('readme')
|
74
|
+
|
75
|
+
inserted_new_country = false
|
76
|
+
|
77
|
+
readme.each_line do |line|
|
78
|
+
match_data = line.match(/\[(\w+)\] (.+)$/)
|
79
|
+
if match_data.nil?
|
80
|
+
new_readme.puts(line)
|
81
|
+
else
|
82
|
+
code = match_data[1]
|
83
|
+
country = match_data[2]
|
84
|
+
|
85
|
+
if !inserted_new_country && code.downcase > @country_code
|
86
|
+
new_readme.puts "[#{@country_code.upcase}] #{@country}"
|
87
|
+
inserted_new_country = true
|
88
|
+
end
|
89
|
+
|
90
|
+
new_readme.puts "[#{code}] #{country}"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
FileUtils.mv(new_readme.path, readme.path)
|
95
|
+
end
|
96
|
+
|
97
|
+
def generate
|
98
|
+
return if already_exists?
|
99
|
+
|
100
|
+
create_test_file
|
101
|
+
add_missing_fields
|
102
|
+
update_readme
|
103
|
+
end
|
104
|
+
|
105
|
+
usage if ARGV.length < 1
|
106
|
+
|
107
|
+
@country = ARGV[0]
|
108
|
+
@country_code = get_country_code
|
109
|
+
|
110
|
+
@test_filename = File.join(File.dirname(__FILE__), '..', 'test', 'countries', "#{@country_code}_test.rb")
|
111
|
+
|
112
|
+
generate
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'nokogiri'
|
4
|
+
require 'open-uri'
|
5
|
+
|
6
|
+
url = 'http://old.rt.ru/en/help-info/mg/index.php?SELECTED_CHAR='
|
7
|
+
|
8
|
+
codes = %w{A B C D E F G H I J K L M N O P R S T U V Y Z}.collect do |c|
|
9
|
+
data = Nokogiri::HTML(open(url + c))
|
10
|
+
data.css("table.fmain_table tbody tr td:nth-child(3)").collect {|e| e.text.split(/,/).collect {|str| str.strip } }
|
11
|
+
end.flatten.uniq.compact.reject {|str| str =~ /\D/ }
|
12
|
+
|
13
|
+
puts codes.join("|")
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: phonie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,8 +12,56 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date:
|
16
|
-
dependencies:
|
15
|
+
date: 2013-01-29 00:00:00.000000000 Z
|
16
|
+
dependencies:
|
17
|
+
- !ruby/object:Gem::Dependency
|
18
|
+
name: rake
|
19
|
+
requirement: !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ! '>='
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: '0'
|
25
|
+
type: :development
|
26
|
+
prerelease: false
|
27
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: nokogiri
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
none: false
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
type: :development
|
42
|
+
prerelease: false
|
43
|
+
version_requirements: !ruby/object:Gem::Requirement
|
44
|
+
none: false
|
45
|
+
requirements:
|
46
|
+
- - ! '>='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: activemodel
|
51
|
+
requirement: !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ! '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
type: :development
|
58
|
+
prerelease: false
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ! '>='
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '0'
|
17
65
|
description: Phone number parsing, validation and formatting
|
18
66
|
email:
|
19
67
|
- tomislav@infinum.hr
|
@@ -26,7 +74,6 @@ extra_rdoc_files: []
|
|
26
74
|
files:
|
27
75
|
- .gitignore
|
28
76
|
- Gemfile
|
29
|
-
- Gemfile.lock
|
30
77
|
- LICENSE
|
31
78
|
- Rakefile
|
32
79
|
- Readme.rdoc
|
@@ -34,25 +81,33 @@ files:
|
|
34
81
|
- lib/phonie/country.rb
|
35
82
|
- lib/phonie/data/phone_countries.yml
|
36
83
|
- lib/phonie/phone.rb
|
84
|
+
- lib/phonie/railties/locales/en.yml
|
85
|
+
- lib/phonie/railties/locales/es.yml
|
86
|
+
- lib/phonie/railties/validator.rb
|
37
87
|
- lib/phonie/support.rb
|
38
88
|
- lib/phonie/version.rb
|
39
89
|
- phonie.gemspec
|
90
|
+
- tasks/tests.rake
|
40
91
|
- test/countries/ae_test.rb
|
41
92
|
- test/countries/af_test.rb
|
42
93
|
- test/countries/al_test.rb
|
94
|
+
- test/countries/am_test.rb
|
43
95
|
- test/countries/ar_test.rb
|
44
96
|
- test/countries/at_test.rb
|
45
97
|
- test/countries/au_test.rb
|
98
|
+
- test/countries/az_test.rb
|
46
99
|
- test/countries/ba_test.rb
|
47
100
|
- test/countries/bd_test.rb
|
48
101
|
- test/countries/be_test.rb
|
49
102
|
- test/countries/bg_test.rb
|
50
103
|
- test/countries/bo_test.rb
|
51
104
|
- test/countries/br_test.rb
|
105
|
+
- test/countries/bs_test.rb
|
52
106
|
- test/countries/bt_test.rb
|
53
107
|
- test/countries/by_test.rb
|
54
108
|
- test/countries/bz_test.rb
|
55
109
|
- test/countries/ca_test.rb
|
110
|
+
- test/countries/cl_test.rb
|
56
111
|
- test/countries/cr_test.rb
|
57
112
|
- test/countries/cy_test.rb
|
58
113
|
- test/countries/cz_test.rb
|
@@ -77,8 +132,12 @@ files:
|
|
77
132
|
- test/countries/il_test.rb
|
78
133
|
- test/countries/in_test.rb
|
79
134
|
- test/countries/ir_test.rb
|
135
|
+
- test/countries/it_test.rb
|
80
136
|
- test/countries/ke_test.rb
|
81
137
|
- test/countries/lk_test.rb
|
138
|
+
- test/countries/lt_test.rb
|
139
|
+
- test/countries/lu_test.rb
|
140
|
+
- test/countries/lv_test.rb
|
82
141
|
- test/countries/ng_test.rb
|
83
142
|
- test/countries/nl_test.rb
|
84
143
|
- test/countries/no_test.rb
|
@@ -88,6 +147,7 @@ files:
|
|
88
147
|
- test/countries/pt_test.rb
|
89
148
|
- test/countries/qa_test.rb
|
90
149
|
- test/countries/rs_test.rb
|
150
|
+
- test/countries/ru_test.rb
|
91
151
|
- test/countries/sa_test.rb
|
92
152
|
- test/countries/se_test.rb
|
93
153
|
- test/countries/si_test.rb
|
@@ -101,8 +161,11 @@ files:
|
|
101
161
|
- test/country_test.rb
|
102
162
|
- test/extension_test.rb
|
103
163
|
- test/phone_test.rb
|
164
|
+
- test/railties/validator_test.rb
|
104
165
|
- test/test_helper.rb
|
105
166
|
- test_usa_phones_with_extensions.csv
|
167
|
+
- tools/generate
|
168
|
+
- tools/russian_area_codes.rb
|
106
169
|
homepage: http://github.com/wmoxam/phonie
|
107
170
|
licenses: []
|
108
171
|
post_install_message:
|