activevalidators 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
1
  *.swp
2
2
  *.gem
3
3
  *.rbc
4
+ Gemfile.lock
data/README.md CHANGED
@@ -20,6 +20,7 @@ In your models, the gem provides new validators like `email`, or `url`:
20
20
  validates :twitter_at, :twitter => { :format => :username_with_at }
21
21
  validates :twitter_url, :twitter => { :format => :url }
22
22
  validates :twitter, :twitter => true
23
+ validates :postal_code, :postal_code => { :format => :us }
23
24
  end
24
25
 
25
26
  class Article
@@ -53,13 +54,13 @@ Exhaustive list of supported validators and their implementation:
53
54
  * `credit_card` : based on the `Luhn` algorithm
54
55
  * `date` : based on the `DateValidator` gem
55
56
  * `password` : based on a set of regular expressions
57
+ * `postal_code`: based on a set of predefined masks
56
58
 
57
59
  Todo
58
60
  ----
59
61
 
60
62
  Lots of improvements can be made:
61
63
 
62
- * Add I18n specific types of error messages for each validator
63
64
  * Implement new validators
64
65
  * ...
65
66
 
@@ -81,8 +82,10 @@ Contributors
81
82
  * Oriol Gual
82
83
  * Paco Guzmán
83
84
  * Garrett Bjerkhoel
85
+ * Renato Riccieri Santos Zannon
86
+ * Brian Moseley
84
87
 
85
88
  Copyright
86
89
  ---------
87
90
 
88
- Copyright (c) 2010 Franck Verrot. MIT LICENSE. See LICENSE for details.
91
+ Copyright (c) 2010-2011 Franck Verrot. MIT LICENSE. See LICENSE for details.
@@ -4,9 +4,9 @@ $:.unshift lib unless $:.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "activevalidators"
7
- s.version = '1.3.0'
7
+ s.version = '1.4.0'
8
8
  s.platform = Gem::Platform::RUBY
9
- s.authors = ["Franck Verrot", "Paco Guzmán", "Oriol Gual", "Garrett Bjerkhoel", "Renato Riccieri Santos Zannon"]
9
+ s.authors = ["Franck Verrot", "Paco Guzmán", "Oriol Gual", "Garrett Bjerkhoel", "Renato Riccieri Santos Zannon", "Brian Moseley"]
10
10
  s.email = ["franck@verrot.fr"]
11
11
  s.homepage = "http://github.com/cesario/activevalidators"
12
12
  s.summary = %q{Collection of ActiveModel/ActiveRecord validations}
@@ -0,0 +1,30 @@
1
+ module ActiveModel
2
+ module Validations
3
+ class PostalCodeValidator < EachValidator
4
+ def validate_each(record, attribute, value)
5
+ @value = value
6
+ country = options[:country] || :us
7
+ @formats = PostalCodeValidator.known_formats[country]
8
+ raise "No known postal code formats for country #{country}" unless @formats
9
+ record.errors.add(attribute) unless matches_any?
10
+ end
11
+
12
+ def self.known_formats
13
+ @@known_formats ||= {
14
+ :us => ['#####', '#####-####'],
15
+ }
16
+ end
17
+
18
+ def matches_any?
19
+ false if @formats.nil? or not @formats.respond_to?(:detect)
20
+ @formats.detect { |format| @value.match(PostalCodeValidator.regexp_from format) }
21
+ end
22
+
23
+ private
24
+
25
+ def self.regexp_from(format)
26
+ Regexp.new "^"+(Regexp.escape format).gsub('\#','\d')+"$"
27
+ end
28
+ end
29
+ end
30
+ end
@@ -3,19 +3,29 @@ require 'active_model'
3
3
  require 'active_record'
4
4
  require 'active_support/all'
5
5
  require 'active_model/validations'
6
- #Eager autoload the library's validators into AR::Validations
6
+
7
7
  module ActiveModel
8
8
  module Validations
9
9
  extend ActiveSupport::Autoload
10
- autoload :EmailValidator
11
- autoload :UrlValidator
12
- autoload :RespondToValidator
13
- autoload :PhoneValidator
14
- autoload :SlugValidator
15
- autoload :IpValidator
16
- autoload :CreditCardValidator
17
- autoload :DateValidator, 'date_validator'
18
- autoload :PasswordValidator
19
- autoload :TwitterValidator
10
+
11
+ def self.activevalidators
12
+ ['Email','Url','RespondTo','Phone','Slug','Ip','CreditCard','Date','Password','Twitter','PostalCode']
13
+ end
14
+
15
+ #Eager autoload the library's validators into AR::Validations
16
+ activevalidators.each do |validator_name|
17
+ autoload validator_name+'Validator'
18
+ end
19
+
20
+ #Defines methods like validates_credit_card
21
+ module HelperMethods
22
+ ActiveModel::Validations.activevalidators.map(&:underscore).each do |validator|
23
+ define_method('validates_'+validator) do |*fields|
24
+ options ||= (fields.delete fields.find { |f| f.kind_of? Hash}) || true
25
+ args = fields.push({ validator => options })
26
+ validates(*args)
27
+ end
28
+ end
29
+ end
20
30
  end
21
31
  end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe "A class with active validators included" do
4
+ subject { TestRecord }
5
+
6
+ validators = ['Email','Url','RespondTo','Phone','Slug','Ip','CreditCard','Date','Password','Twitter'].map(&:underscore)
7
+ validators.each do |validator|
8
+ describe ".validates_#{validator}" do
9
+ it "is defined" do
10
+ subject.should respond_to("validates_#{validator}")
11
+ end
12
+
13
+ context "when it doesn't receive a hash with options" do
14
+ it "calls validates #{validator} => true" do
15
+ subject.should_receive('validates').with hash_including(validator => true)
16
+ subject.send("validates_#{validator}")
17
+ end
18
+
19
+ it "calls 'validates *attributes, #{validator} => true' when fed with attributes" do
20
+ subject.should_receive('validates').with(:attr1, :attr2, validator => true)
21
+ subject.send("validates_#{validator}", :attr1, :attr2)
22
+ end
23
+ end
24
+
25
+ context "when it receives a hash with options" do
26
+ it "calls validates #{validator} => options" do
27
+ subject.should_receive('validates').with hash_including(validator => {:options => :blah})
28
+ subject.send("validates_#{validator}", :options => :blah)
29
+ end
30
+
31
+ it "calls 'validates *attributes, #{validator} => options' when fed with attributes" do
32
+ subject.should_receive('validates').with(:attr1, :attr2, validator => {:options => :blah})
33
+ subject.send("validates_#{validator}", :attr1, :attr2, :options => :blah)
34
+ end
35
+ end
36
+
37
+ end
38
+ end
39
+ end
@@ -10,5 +10,6 @@ end
10
10
  class TestRecord
11
11
  include ActiveModel::Validations
12
12
  attr_accessor :ip, :url, :slug, :responder, :global_condition,
13
- :local_condition, :phone, :email, :card, :password, :twitter_username
13
+ :local_condition, :phone, :email, :card, :password, :twitter_username,
14
+ :postal_code
14
15
  end
@@ -0,0 +1,61 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
2
+
3
+ describe "Postal Code Validation" do
4
+
5
+ subject { TestRecord.new }
6
+
7
+ context "when no country is given" do
8
+ before(:each) do
9
+ TestRecord.reset_callbacks(:validate)
10
+ TestRecord.validates :postal_code, :postal_code => true
11
+ end
12
+
13
+ it 'should validate format of postal code with #####' do
14
+ subject.postal_code = '11211'
15
+ subject.should be_valid
16
+ subject.should have(0).errors
17
+ end
18
+
19
+ it 'should validate format of postal code with #####-#####' do
20
+ subject.postal_code = '94117-1234'
21
+ subject.should be_valid
22
+ subject.should have(0).errors
23
+ end
24
+ end
25
+
26
+ ActiveModel::Validations::PostalCodeValidator.known_formats.each do |country, formats|
27
+ context "when given a :#{country} country parameter" do
28
+ before(:each) do
29
+ TestRecord.reset_callbacks(:validate)
30
+ TestRecord.validates :postal_code, :postal_code => {:country => country}
31
+ end
32
+
33
+ formats.each do |format|
34
+ it "should validate format of postal code with #{format}" do
35
+ subject.postal_code = format.gsub('#','9')
36
+ subject.should be_valid
37
+ subject.should have(0).errors
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+
44
+ describe "for invalid formats" do
45
+ before :each do
46
+ TestRecord.reset_callbacks(:validate)
47
+ TestRecord.validates :postal_code, :postal_code => true
48
+ subject.postal_code = '999'
49
+ end
50
+
51
+ it "rejects invalid formats" do
52
+ subject.should_not be_valid
53
+ subject.should have(1).error
54
+ end
55
+
56
+ it "generates an error message of type invalid" do
57
+ subject.should_not be_valid
58
+ subject.errors[:postal_code].should include subject.errors.generate_message(:postal_code, :invalid)
59
+ end
60
+ end
61
+ end
metadata CHANGED
@@ -1,8 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activevalidators
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 7
4
5
  prerelease:
5
- version: 1.3.0
6
+ segments:
7
+ - 1
8
+ - 4
9
+ - 0
10
+ version: 1.4.0
6
11
  platform: ruby
7
12
  authors:
8
13
  - Franck Verrot
@@ -10,11 +15,12 @@ authors:
10
15
  - Oriol Gual
11
16
  - Garrett Bjerkhoel
12
17
  - Renato Riccieri Santos Zannon
18
+ - Brian Moseley
13
19
  autorequire:
14
20
  bindir: bin
15
21
  cert_chain: []
16
22
 
17
- date: 2011-03-20 00:00:00 -04:00
23
+ date: 2011-04-30 00:00:00 +02:00
18
24
  default_executable:
19
25
  dependencies:
20
26
  - !ruby/object:Gem::Dependency
@@ -25,6 +31,9 @@ dependencies:
25
31
  requirements:
26
32
  - - ">="
27
33
  - !ruby/object:Gem::Version
34
+ hash: 3
35
+ segments:
36
+ - 0
28
37
  version: "0"
29
38
  type: :development
30
39
  version_requirements: *id001
@@ -36,6 +45,9 @@ dependencies:
36
45
  requirements:
37
46
  - - ">="
38
47
  - !ruby/object:Gem::Version
48
+ hash: 3
49
+ segments:
50
+ - 0
39
51
  version: "0"
40
52
  type: :development
41
53
  version_requirements: *id002
@@ -47,6 +59,9 @@ dependencies:
47
59
  requirements:
48
60
  - - ">="
49
61
  - !ruby/object:Gem::Version
62
+ hash: 3
63
+ segments:
64
+ - 0
50
65
  version: "0"
51
66
  type: :development
52
67
  version_requirements: *id003
@@ -58,6 +73,9 @@ dependencies:
58
73
  requirements:
59
74
  - - ">="
60
75
  - !ruby/object:Gem::Version
76
+ hash: 3
77
+ segments:
78
+ - 0
61
79
  version: "0"
62
80
  type: :development
63
81
  version_requirements: *id004
@@ -69,6 +87,11 @@ dependencies:
69
87
  requirements:
70
88
  - - ~>
71
89
  - !ruby/object:Gem::Version
90
+ hash: 7
91
+ segments:
92
+ - 3
93
+ - 0
94
+ - 0
72
95
  version: 3.0.0
73
96
  type: :runtime
74
97
  version_requirements: *id005
@@ -80,6 +103,11 @@ dependencies:
80
103
  requirements:
81
104
  - - ~>
82
105
  - !ruby/object:Gem::Version
106
+ hash: 7
107
+ segments:
108
+ - 3
109
+ - 0
110
+ - 0
83
111
  version: 3.0.0
84
112
  type: :runtime
85
113
  version_requirements: *id006
@@ -91,6 +119,11 @@ dependencies:
91
119
  requirements:
92
120
  - - ~>
93
121
  - !ruby/object:Gem::Version
122
+ hash: 25
123
+ segments:
124
+ - 2
125
+ - 2
126
+ - 15
94
127
  version: 2.2.15
95
128
  type: :runtime
96
129
  version_requirements: *id007
@@ -102,6 +135,11 @@ dependencies:
102
135
  requirements:
103
136
  - - ~>
104
137
  - !ruby/object:Gem::Version
138
+ hash: 5
139
+ segments:
140
+ - 0
141
+ - 6
142
+ - 1
105
143
  version: 0.6.1
106
144
  type: :runtime
107
145
  version_requirements: *id008
@@ -118,7 +156,6 @@ files:
118
156
  - .bundle/config
119
157
  - .gitignore
120
158
  - Gemfile
121
- - Gemfile.lock
122
159
  - LICENSE
123
160
  - README.md
124
161
  - Rakefile
@@ -129,17 +166,20 @@ files:
129
166
  - lib/active_model/validations/ip_validator.rb
130
167
  - lib/active_model/validations/password_validator.rb
131
168
  - lib/active_model/validations/phone_validator.rb
169
+ - lib/active_model/validations/postal_code_validator.rb
132
170
  - lib/active_model/validations/respond_to_validator.rb
133
171
  - lib/active_model/validations/slug_validator.rb
134
172
  - lib/active_model/validations/twitter_validator.rb
135
173
  - lib/active_model/validations/url_validator.rb
136
174
  - lib/activevalidators.rb
175
+ - spec/activevalidators_spec.rb
137
176
  - spec/spec_helper.rb
138
177
  - spec/validations/credit_card_spec.rb
139
178
  - spec/validations/email_spec.rb
140
179
  - spec/validations/ip_spec.rb
141
180
  - spec/validations/password_spec.rb
142
181
  - spec/validations/phone_spec.rb
182
+ - spec/validations/postal_code_spec.rb
143
183
  - spec/validations/respond_to_spec.rb
144
184
  - spec/validations/slug_spec.rb
145
185
  - spec/validations/twitter_spec.rb
@@ -158,12 +198,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
158
198
  requirements:
159
199
  - - ">="
160
200
  - !ruby/object:Gem::Version
201
+ hash: 3
202
+ segments:
203
+ - 0
161
204
  version: "0"
162
205
  required_rubygems_version: !ruby/object:Gem::Requirement
163
206
  none: false
164
207
  requirements:
165
208
  - - ">="
166
209
  - !ruby/object:Gem::Version
210
+ hash: 3
211
+ segments:
212
+ - 0
167
213
  version: "0"
168
214
  requirements: []
169
215
 
@@ -173,12 +219,14 @@ signing_key:
173
219
  specification_version: 3
174
220
  summary: Collection of ActiveModel/ActiveRecord validations
175
221
  test_files:
222
+ - spec/activevalidators_spec.rb
176
223
  - spec/spec_helper.rb
177
224
  - spec/validations/credit_card_spec.rb
178
225
  - spec/validations/email_spec.rb
179
226
  - spec/validations/ip_spec.rb
180
227
  - spec/validations/password_spec.rb
181
228
  - spec/validations/phone_spec.rb
229
+ - spec/validations/postal_code_spec.rb
182
230
  - spec/validations/respond_to_spec.rb
183
231
  - spec/validations/slug_spec.rb
184
232
  - spec/validations/twitter_spec.rb
@@ -1,57 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- activevalidators (1.3.0)
5
- activemodel (~> 3.0.0)
6
- activerecord (~> 3.0.0)
7
- date_validator (~> 0.6.1)
8
- mail (~> 2.2.15)
9
-
10
- GEM
11
- remote: http://rubygems.org/
12
- specs:
13
- activemodel (3.0.5)
14
- activesupport (= 3.0.5)
15
- builder (~> 2.1.2)
16
- i18n (~> 0.4)
17
- activerecord (3.0.5)
18
- activemodel (= 3.0.5)
19
- activesupport (= 3.0.5)
20
- arel (~> 2.0.2)
21
- tzinfo (~> 0.3.23)
22
- activesupport (3.0.5)
23
- arel (2.0.9)
24
- builder (2.1.2)
25
- date_validator (0.6.1)
26
- activemodel (~> 3.0.0)
27
- diff-lcs (1.1.2)
28
- i18n (0.5.0)
29
- mail (2.2.15)
30
- activesupport (>= 2.3.6)
31
- i18n (>= 0.4.0)
32
- mime-types (~> 1.16)
33
- treetop (~> 1.4.8)
34
- mime-types (1.16)
35
- polyglot (0.3.1)
36
- rspec (2.5.0)
37
- rspec-core (~> 2.5.0)
38
- rspec-expectations (~> 2.5.0)
39
- rspec-mocks (~> 2.5.0)
40
- rspec-core (2.5.1)
41
- rspec-expectations (2.5.0)
42
- diff-lcs (~> 1.1.2)
43
- rspec-mocks (2.5.0)
44
- treetop (1.4.9)
45
- polyglot (>= 0.3.1)
46
- tzinfo (0.3.25)
47
-
48
- PLATFORMS
49
- java
50
- ruby
51
-
52
- DEPENDENCIES
53
- activevalidators!
54
- bundler
55
- rspec
56
- rspec-core
57
- rspec-expectations