validators 0.1.0 → 0.1.1

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.
data/README.rdoc CHANGED
@@ -22,6 +22,12 @@ Then add it to your Gemfile:
22
22
  validates :email, :email => true
23
23
  end
24
24
 
25
+ === validates_url_format_of
26
+
27
+ class User < ActiveRecord::Base
28
+ validates_url_format_of :site
29
+ end
30
+
25
31
  === validates_ownership_of
26
32
 
27
33
  class Task < ActiveRecord::Base
@@ -45,6 +51,14 @@ Then add it to your Gemfile:
45
51
  task.valid?
46
52
  #=> false
47
53
 
54
+ === validates_ip_address
55
+
56
+ class Server < ActiveRecord::Base
57
+ validates_ip_address :address
58
+ validates_ip_address :address, :only => :v4
59
+ validates_ip_address :address, :only => :v6
60
+ end
61
+
48
62
  == Maintainer
49
63
 
50
64
  * Nando Vieira - http://simplesideias.com.br
@@ -0,0 +1,30 @@
1
+ module Validators
2
+ EMAIL_FORMAT = /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
3
+
4
+ # Source: https://github.com/henrik/validates_url_format_of
5
+ IPv4_PART = /\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]/ # 0-255
6
+
7
+ if RUBY_VERSION >= "1.9"
8
+ URL_FORMAT = %r[
9
+ \A
10
+ https?:// # http:// or https://
11
+ ([^\s:@]+:[^\s:@]*@)? # optional username:pw@
12
+ ( (([^\W_]+\.)*xn--)?[^\W_]+([-.][^\W_]+)*\.[a-z]{2,6}\.? | # domain (including Punycode/IDN)...
13
+ #{IPv4_PART}(\.#{IPv4_PART}){3} ) # or IPv4
14
+ (:\d{1,5})? # optional port
15
+ ([/?]\S*)? # optional /whatever or ?whatever
16
+ \Z
17
+ ]ixs
18
+ else
19
+ URL_FORMAT = %r[
20
+ \A
21
+ https?:// # http:// or https://
22
+ ([^\s:@]+:[^\s:@]*@)? # optional username:pw@
23
+ ( (([^\W_]+\.)*xn--)?[^\W_]+([-.][^\W_]+)*\.[a-z]{2,6}\.? | # domain (including Punycode/IDN)...
24
+ #{IPv4_PART}(\.#{IPv4_PART}){3} ) # or IPv4
25
+ (:\d{1,5})? # optional port
26
+ ([/?]\S*)? # optional /whatever or ?whatever
27
+ \Z
28
+ ]ixu
29
+ end
30
+ end
@@ -0,0 +1,29 @@
1
+ module Validators
2
+ module Ip
3
+ extend self
4
+
5
+ # Extracted from Ruby 1.8.7
6
+ def v4?(addr)
7
+ matches = addr.match(/\A(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\Z/)
8
+ matches && matches.captures.all? {|i| i.to_i < 256}
9
+ end
10
+
11
+ # Extracted from Ruby 1.8.7
12
+ def v6?(addr)
13
+ # IPv6 (normal)
14
+ return true if /\A[\da-f]{1,4}(:[\da-f]{1,4})*\Z/i =~ addr
15
+ return true if /\A[\da-f]{1,4}(:[\da-f]{1,4})*::([\da-f]{1,4}(:[\da-f]{1,4})*)?\Z/i =~ addr
16
+ return true if /\A::([\da-f]{1,4}(:[\da-f]{1,4})*)?\Z/i =~ addr
17
+ # IPv6 (IPv4 compat)
18
+ return true if /\A[\da-f]{1,4}(:[\da-f]{1,4})*:/i =~ addr && v4?($')
19
+ return true if /\A[\da-f]{1,4}(:[\da-f]{1,4})*::([\da-f]{1,4}(:[\da-f]{1,4})*:)?/i =~ addr && v4?($')
20
+ return true if /\A::([\da-f]{1,4}(:[\da-f]{1,4})*:)?/i =~ addr && v4?($')
21
+
22
+ false
23
+ end
24
+
25
+ def valid?(addr)
26
+ v4?(addr) || v6?(addr)
27
+ end
28
+ end
29
+ end
@@ -21,6 +21,8 @@ module ActiveModel
21
21
  def validates_email_format_of(*attr_names)
22
22
  validates_with EmailValidator, _merge_attributes(attr_names)
23
23
  end
24
+
25
+ alias_method :validates_email, :validates_email_format_of
24
26
  end
25
27
  end
26
28
  end
@@ -0,0 +1,47 @@
1
+ module ActiveModel
2
+ module Validations
3
+ class IpAddressValidator < EachValidator
4
+ def validate_each(record, attribute, value)
5
+ return if value.blank? && options[:allow_blank]
6
+ return if value.nil? && options[:allow_nil]
7
+
8
+ valid = false
9
+
10
+ case options[:only]
11
+ when :v4
12
+ valid = Validators::Ip.v4?(value.to_s)
13
+ scope = :invalid_ipv4_address
14
+ when :v6
15
+ valid = Validators::Ip.v6?(value.to_s)
16
+ scope = :invalid_ipv6_address
17
+ else
18
+ valid = Validators::Ip.valid?(value.to_s)
19
+ scope = :invalid_ip_address
20
+ end
21
+
22
+ unless valid
23
+ record.errors.add(
24
+ attribute, scope,
25
+ :message => options[:message], :value => value
26
+ )
27
+ end
28
+ end
29
+
30
+ def check_validity!
31
+ raise ArgumentError, ":only accepts a symbol that can be either :v6 or :v4" if options.key?(:only) && ![:v4, :v6].include?(options[:only])
32
+ end
33
+ end
34
+
35
+ module ClassMethods
36
+ # Validates weather or not the specified URL is valid.
37
+ #
38
+ # validates_ip_address :ip #=> accepts both v4 and v6
39
+ # validates_ip_address :ip, :only => :v4
40
+ # validates_ip_address :ip, :only => :v6
41
+ #
42
+ def validates_ip_address(*attr_names)
43
+ validates_with IpAddressValidator, _merge_attributes(attr_names)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,28 @@
1
+ module ActiveModel
2
+ module Validations
3
+ class UrlValidator < EachValidator
4
+ def validate_each(record, attribute, value)
5
+ if value.to_s !~ Validators::URL_FORMAT
6
+ record.errors.add(
7
+ attribute, :invalid_url,
8
+ :message => options[:message], :value => value
9
+ )
10
+ end
11
+ end
12
+ end
13
+
14
+ module ClassMethods
15
+ # Validates weather or not the specified URL is valid.
16
+ #
17
+ # class User < ActiveRecord::Base
18
+ # validates_url_format_of :site
19
+ # end
20
+ #
21
+ def validates_url_format_of(*attr_names)
22
+ validates_with UrlValidator, _merge_attributes(attr_names)
23
+ end
24
+
25
+ alias_method :validates_url, :validates_url_format_of
26
+ end
27
+ end
28
+ end
@@ -2,7 +2,7 @@ module Validators
2
2
  module Version
3
3
  MAJOR = 0
4
4
  MINOR = 1
5
- PATCH = 0
5
+ PATCH = 1
6
6
  STRING = "#{MAJOR}.#{MINOR}.#{PATCH}"
7
7
  end
8
8
  end
data/lib/validators.rb CHANGED
@@ -1,7 +1,10 @@
1
1
  require "active_record"
2
+ require "validators/constants"
3
+ require "validators/validates_ip_address"
2
4
  require "validators/validates_email_format_of"
5
+ require "validators/validates_url_format_of"
3
6
  require "validators/validates_ownership_of"
4
7
 
5
8
  module Validators
6
- EMAIL_FORMAT = /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
9
+ autoload :Ip, "validators/ip"
7
10
  end
data/spec/schema.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  ActiveRecord::Schema.define(:version => 0) do
2
2
  create_table :users do |t|
3
- t.string :email, :corporate_email
3
+ t.string :email, :corporate_email, :url
4
4
  end
5
5
 
6
6
  create_table :categories do |t|
@@ -0,0 +1,20 @@
1
+ VALID_IPV4 = [
2
+ "192.168.1.1",
3
+ "64.233.163.104",
4
+ "127.0.0.1",
5
+ "0.0.0.0"
6
+ ]
7
+
8
+ VALID_IPV6 = [
9
+ "FE80:0000:0000:0000:0202:B3FF:FE1E:8329",
10
+ "fe80:0000:0000:0000:0202:b3ff:fe1e:8329",
11
+ "FE80::0202:B3FF:FE1E:8329",
12
+ "1050:0000:0000:0000:0005:0600:300c:326b",
13
+ "1050:0:0:0:5:600:300c:326b",
14
+ "ff06:0:0:0:0:0:0:c3",
15
+ "ff06::c3",
16
+ "0:0:0:0:0:0:192.1.56.10",
17
+ "3ffe:1900:4545:3:200:f8ff:fe21:67cf",
18
+ "fe80:0:0:0:200:f8ff:fe21:67cf",
19
+ "fe80::200:f8ff:fe21:67cf"
20
+ ]
@@ -4,6 +4,10 @@ en:
4
4
  messages:
5
5
  record_invalid: "Errors: %{errors}"
6
6
  invalid_email: "is not a valid address"
7
+ invalid_url: "is not a valid address"
8
+ invalid_ipv4_address: "is not a valid IPv4 address"
9
+ invalid_ipv6_address: "is not a valid IPv6 address"
10
+ invalid_address: "is not a valid IP address"
7
11
  invalid_owner: "is not associated with your user"
8
12
 
9
13
  pt-BR:
@@ -12,4 +16,5 @@ pt-BR:
12
16
  messages:
13
17
  record_invalid: "Erros: %{errors}"
14
18
  invalid_email: "não parece ser um e-mail válido"
19
+ invalid_url: "não parece ser uma URL válida"
15
20
  invalid_owner: "não está associado ao seu usuário"
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+ VALID_URLS = [
3
+ 'http://example.com',
4
+ 'http://example.com/',
5
+ 'http://www.example.com/',
6
+ 'http://sub.domain.example.com/',
7
+ 'http://bbc.co.uk',
8
+ 'http://example.com?foo',
9
+ 'http://example.com?url=http://example.com',
10
+ 'http://example.com:8000',
11
+ 'http://www.sub.example.com/page.html?foo=bar&baz=%23#anchor',
12
+ 'http://user:pass@example.com',
13
+ 'http://user:@example.com',
14
+ 'http://example.com/~user',
15
+ 'http://example.xy', # Not a real TLD, but we're fine with anything of 2-6 chars
16
+ 'http://example.museum',
17
+ 'http://1.0.255.249',
18
+ 'http://1.2.3.4:80',
19
+ 'HttP://example.com',
20
+ 'https://example.com',
21
+ # 'http://räksmörgås.nu', # IDN
22
+ 'http://xn--rksmrgs-5wao1o.nu', # Punycode
23
+ 'http://www.xn--rksmrgs-5wao1o.nu',
24
+ 'http://foo.bar.xn--rksmrgs-5wao1o.nu',
25
+ 'http://example.com.', # Explicit TLD root period
26
+ 'http://example.com./foo'
27
+ ]
28
+
29
+ INVALID_URLS = [
30
+ "url",
31
+ "www.example.com",
32
+ "http://ex ample.com",
33
+ "http://example.com/foo bar",
34
+ 'http://256.0.0.1',
35
+ 'http://u:u:u@example.com',
36
+ 'http://r?ksmorgas.com',
37
+
38
+ # These can all be valid local URLs, but should not be considered valid
39
+ # for public consumption.
40
+ "http://example",
41
+ "http://example.c",
42
+ 'http://example.toolongtld'
43
+ ]
@@ -0,0 +1,25 @@
1
+ require "spec_helper"
2
+
3
+ describe Validators::Ip do
4
+ context "IPv4" do
5
+ VALID_IPV4.each do |ip|
6
+ it "should accept #{ip.inspect} as ip address" do
7
+ Validators::Ip.should be_v4(ip)
8
+ end
9
+ end
10
+ end
11
+
12
+ context "IPv6" do
13
+ VALID_IPV6.each do |ip|
14
+ it "should accept #{ip.inspect} as ip address" do
15
+ Validators::Ip.should be_v6(ip)
16
+ end
17
+ end
18
+ end
19
+
20
+ (VALID_IPV4 + VALID_IPV6).each do |ip|
21
+ it "should accept #{ip.inspect} as ip address" do
22
+ Validators::Ip.should be_valid(ip)
23
+ end
24
+ end
25
+ end
@@ -31,41 +31,41 @@ describe ".validates_email_format_of" do
31
31
  it "should use default error message" do
32
32
  user = User.new(:email => "invalid")
33
33
  user.should_not be_valid
34
- errors_for(user, :email).should == ["is not a valid address"]
34
+ user.errors[:email].should == ["is not a valid address"]
35
35
  end
36
36
 
37
37
  it "should reject nil value" do
38
38
  user = User.new(:email => nil)
39
39
  user.should_not be_valid
40
- errors_for(user, :email).should_not be_empty
40
+ user.errors[:email].should_not be_empty
41
41
  end
42
42
 
43
43
  it "should reject empty value" do
44
44
  user = User.new(:email => "")
45
45
  user.should_not be_valid
46
- errors_for(user, :email).should_not be_empty
46
+ user.errors[:email].should_not be_empty
47
47
  end
48
48
 
49
49
  it "should validate multiple attributes" do
50
50
  user = User.new(:corporate_email => "invalid")
51
51
  user.should_not be_valid
52
- errors_for(user, :corporate_email).should == ["is not a valid address"]
52
+ user.errors[:corporate_email].should == ["is not a valid address"]
53
53
  end
54
54
 
55
55
  it "should use custom error message as :message options" do
56
56
  buyer = Buyer.new(:email => "invalid")
57
57
  buyer.should_not be_valid
58
- errors_for(buyer, :email).should == ["is not a valid e-mail"]
58
+ buyer.errors[:email].should == ["is not a valid e-mail"]
59
59
  end
60
60
 
61
61
  it "should use I18n string as error message [pt-BR]" do
62
62
  I18n.locale = :'pt-BR'
63
63
  user = User.new(:email => "invalid")
64
64
  user.should_not be_valid
65
- errors_for(user, :email).should == ["não parece ser um e-mail válido"]
65
+ user.errors[:email].should == ["não parece ser um e-mail válido"]
66
66
  end
67
67
 
68
- def errors_for(record, attr_name)
69
- record.errors[attr_name]
68
+ it "should have alias method" do
69
+ User.should respond_to(:validates_email)
70
70
  end
71
71
  end
@@ -0,0 +1,59 @@
1
+ require "spec_helper"
2
+
3
+ describe ".validates_ip_address" do
4
+ subject { User.new }
5
+
6
+ context "IPv4" do
7
+ it "should be valid" do
8
+ User.validates_ip_address :url, :only => :v4
9
+ subject.url = "192.168.1.2"
10
+ subject.should be_valid
11
+ end
12
+
13
+ it "should not be valid" do
14
+ User.validates_ip_address :url, :only => :v4
15
+ subject.url = "FE80:0000:0000:0000:0202:B3FF:FE1E:8329"
16
+ subject.should_not be_valid
17
+ subject.errors[:url].should == ["is not a valid IPv4 address"]
18
+ end
19
+ end
20
+
21
+ context "IPv6" do
22
+ it "should be valid" do
23
+ User.validates_ip_address :url, :only => :v6
24
+ subject.url = "FE80:0000:0000:0000:0202:B3FF:FE1E:8329"
25
+ subject.should be_valid
26
+ end
27
+
28
+ it "should not be valid" do
29
+ User.validates_ip_address :url, :only => :v6
30
+ subject.url = "192.168.1.2"
31
+ subject.should_not be_valid
32
+ subject.errors[:url].should == ["is not a valid IPv6 address"]
33
+ end
34
+ end
35
+
36
+ it "should be valid with IPv4" do
37
+ User.validates_ip_address :url
38
+ subject.url = "192.168.1.2"
39
+ subject.should be_valid
40
+ end
41
+
42
+ it "should be valid with IPv6" do
43
+ User.validates_ip_address :url
44
+ subject.url = "FE80:0000:0000:0000:0202:B3FF:FE1E:8329"
45
+ subject.should be_valid
46
+ end
47
+
48
+ it "should allow blank values" do
49
+ User.validates_ip_address :url, :allow_blank => true
50
+ subject.url = ""
51
+ subject.should be_valid
52
+ end
53
+
54
+ it "should allow nil values" do
55
+ User.validates_ip_address :url, :allow_nil => true
56
+ subject.url = nil
57
+ subject.should be_valid
58
+ end
59
+ end
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+ require "spec_helper"
3
+
4
+ describe ".validates_url_format_of" do
5
+ before do
6
+ User.validates_url_format_of :url, :allow_blank => false
7
+ end
8
+
9
+ VALID_URLS.each do |url|
10
+ it "should accept #{url.inspect} as a valid url" do
11
+ user = User.new(:url => url)
12
+ user.should be_valid
13
+ end
14
+ end
15
+
16
+ INVALID_URLS.each do |url|
17
+ it "should reject #{url.inspect} as a valid url" do
18
+ user = User.new(:url => url)
19
+ user.should_not be_valid
20
+ end
21
+ end
22
+
23
+ it "should have alias method" do
24
+ User.should respond_to(:validates_url)
25
+ end
26
+
27
+ it "should use default error message" do
28
+ user = User.new(:url => "invalid")
29
+ user.should_not be_valid
30
+ user.errors[:url].should == ["is not a valid address"]
31
+ end
32
+
33
+ it "should use I18n string as error message [pt-BR]" do
34
+ I18n.locale = :'pt-BR'
35
+ user = User.new(:url => "invalid")
36
+ user.should_not be_valid
37
+ user.errors[:url].should == ["não parece ser uma URL válida"]
38
+ end
39
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 0
9
- version: 0.1.0
8
+ - 1
9
+ version: 0.1.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - Nando Vieira
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-11-10 00:00:00 -02:00
17
+ date: 2010-11-11 00:00:00 -02:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -89,16 +89,25 @@ files:
89
89
  - README.rdoc
90
90
  - Rakefile
91
91
  - lib/validators.rb
92
+ - lib/validators/constants.rb
93
+ - lib/validators/ip.rb
92
94
  - lib/validators/validates_email_format_of.rb
95
+ - lib/validators/validates_ip_address.rb
93
96
  - lib/validators/validates_ownership_of.rb
97
+ - lib/validators/validates_url_format_of.rb
94
98
  - lib/validators/version.rb
95
99
  - spec/schema.rb
96
100
  - spec/spec_helper.rb
97
101
  - spec/support/emails.rb
102
+ - spec/support/ips.rb
98
103
  - spec/support/models.rb
99
104
  - spec/support/translations.yml
105
+ - spec/support/urls.rb
106
+ - spec/validators/ip_spec.rb
100
107
  - spec/validators/validates_email_format_of_spec.rb
108
+ - spec/validators/validates_ip_address_spec.rb
101
109
  - spec/validators/validates_ownership_of_spec.rb
110
+ - spec/validators/validates_url_format_of_spec.rb
102
111
  - validators.gemspec
103
112
  has_rdoc: true
104
113
  homepage: http://rubygems.org/gems/validators
@@ -136,7 +145,12 @@ test_files:
136
145
  - spec/schema.rb
137
146
  - spec/spec_helper.rb
138
147
  - spec/support/emails.rb
148
+ - spec/support/ips.rb
139
149
  - spec/support/models.rb
140
150
  - spec/support/translations.yml
151
+ - spec/support/urls.rb
152
+ - spec/validators/ip_spec.rb
141
153
  - spec/validators/validates_email_format_of_spec.rb
154
+ - spec/validators/validates_ip_address_spec.rb
142
155
  - spec/validators/validates_ownership_of_spec.rb
156
+ - spec/validators/validates_url_format_of_spec.rb