validatable 1.1.2 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -72,8 +72,37 @@ Similar to Rails, Validatable also supports conditional validation.
72
72
  validates_format_of :name, :with => /.+/, :if => Proc.new { !name.nil? }
73
73
  end
74
74
  Person.new.valid? #=> true
75
+
76
+ Validatable also exposes an after_validate hook method.
77
+
78
+ class Person
79
+ include Validatable
80
+ validates_presence_of :name
81
+ attr_accessor :name
82
+ end
83
+
84
+ class ValidatesPresenceOf
85
+ after_validate do |result, instance, attribute|
86
+ instance.errors.add("#{attribute} can't be blank") unless result
87
+ end
88
+ end
89
+
90
+ person = Person.new
91
+ person.valid? #=> false
92
+ person.errors.on(:name) #=> "name can't be blank"
93
+
94
+ The after_validate hook yields the result of the validation being run,
95
+ the instance the validation was run on, and the attribute that was validate
96
+
97
+ In the above example the attribute "name" is appended to the message.
75
98
 
76
99
  See the tests for more examples
77
100
 
78
101
  == Contributors
79
- Rick Bradley (Revision 25)
102
+ Rick Bradley (Revision 25)
103
+
104
+ Zak Tamsen (Revision 29)
105
+
106
+ Jason Miller (Revision 31)
107
+
108
+ Ali Aghareza (Revision 45)
data/lib/base.rb CHANGED
@@ -18,6 +18,7 @@ module Validatable
18
18
  # * level - The level at which the validation should occur
19
19
  # * if - A block that when executed must return true of the validation will not occur
20
20
  # * with - The regular expression used to validate the format
21
+ # * group - The group that this validation belongs to. A validation can belong to multiple groups
21
22
  def validates_format_of(*args)
22
23
  add_validations(args, ValidatesFormatOf) do |validation, options|
23
24
  validation.with = options[:with]
@@ -42,6 +43,7 @@ module Validatable
42
43
  # * if - A block that when executed must return true of the validation will not occur
43
44
  # * minimum - The minimum size of the attribute
44
45
  # * maximum - The maximum size of the attribute
46
+ # * group - The group that this validation belongs to. A validation can belong to multiple groups
45
47
  def validates_length_of(*args)
46
48
  add_validations(args, ValidatesLengthOf) do |validation, options|
47
49
  validation.minimum = options[:minimum]
@@ -49,6 +51,26 @@ module Validatable
49
51
  end
50
52
  end
51
53
 
54
+ # call-seq: validates_numericality_of(*args)
55
+ #
56
+ # Validates that the specified attribute is numeric.
57
+ #
58
+ # class Person
59
+ # include Validatable
60
+ # validates_numericality_of :age
61
+ # end
62
+ #
63
+ # Configuration options:
64
+ #
65
+ # * message - The message to add to the errors collection when the validation fails
66
+ # * times - The number of times the validation applies
67
+ # * level - The level at which the validation should occur
68
+ # * if - A block that when executed must return true of the validation will not occur
69
+ # * group - The group that this validation belongs to. A validation can belong to multiple groups
70
+ def validates_numericality_of(*args)
71
+ add_validations(args, ValidatesNumericalityOf)
72
+ end
73
+
52
74
  # call-seq: validates_acceptance_of(*args)
53
75
  #
54
76
  # Encapsulates the pattern of wanting to validate the acceptance of a terms of service check box (or similar agreement). Example:
@@ -65,6 +87,7 @@ module Validatable
65
87
  # * times - The number of times the validation applies
66
88
  # * level - The level at which the validation should occur
67
89
  # * if - A block that when executed must return true of the validation will not occur
90
+ # * group - The group that this validation belongs to. A validation can belong to multiple groups
68
91
  def validates_acceptance_of(*args)
69
92
  add_validations(args, ValidatesAcceptanceOf)
70
93
  end
@@ -86,12 +109,20 @@ module Validatable
86
109
  #
87
110
  # Configuration options:
88
111
  #
112
+ # * case_sensitive - Whether or not to apply case-sensitivity on the comparison. Defaults to true.
89
113
  # * message - The message to add to the errors collection when the validation fails
90
114
  # * times - The number of times the validation applies
91
115
  # * level - The level at which the validation should occur
92
116
  # * if - A block that when executed must return true of the validation will not occur
117
+ # * group - The group that this validation belongs to. A validation can belong to multiple groups
93
118
  def validates_confirmation_of(*args)
94
- add_validations(args, ValidatesConfirmationOf)
119
+ add_validations(args, ValidatesConfirmationOf) do |validation, options|
120
+ validation.case_sensitive = if options.has_key? :case_sensitive
121
+ options[:case_sensitive]
122
+ else
123
+ true
124
+ end
125
+ end
95
126
  end
96
127
 
97
128
  # call-seq: validates_presence_of(*args)
@@ -111,11 +142,37 @@ module Validatable
111
142
  # * times - The number of times the validation applies
112
143
  # * level - The level at which the validation should occur
113
144
  # * if - A block that when executed must return true of the validation will not occur
145
+ # * group - The group that this validation belongs to. A validation can belong to multiple groups
114
146
  def validates_presence_of(*args)
115
147
  add_validations(args, ValidatesPresenceOf)
116
148
  end
117
149
 
118
- # call-seq: include_validations_for(*args)
150
+ # call-seq: validates_true_for(*args)
151
+ #
152
+ # Validates that the logic evaluates to true
153
+ #
154
+ # class Person
155
+ # include Validatable
156
+ # validates_true_for :first_name, :logic => lambda { first_name == 'Jamie' }
157
+ # end
158
+ #
159
+ # The logic option is required.
160
+ #
161
+ # Configuration options:
162
+ #
163
+ # * message - The message to add to the errors collection when the validation fails
164
+ # * times - The number of times the validation applies
165
+ # * level - The level at which the validation should occur
166
+ # * if - A block that when executed must return true of the validation will not occur
167
+ # * group - The group that this validation belongs to. A validation can belong to multiple groups
168
+ # * logic - A block that executes to perform the validation
169
+ def validates_true_for(*args)
170
+ add_validations(args, ValidatesTrueFor) do |validation, options|
171
+ validation.logic = options[:logic]
172
+ end
173
+ end
174
+
175
+ # call-seq: include_validations_for(attribute_to_validate, options = {})
119
176
  #
120
177
  # Validates the specified attributes.
121
178
  # class Person
@@ -126,7 +183,7 @@ module Validatable
126
183
  #
127
184
  # class PersonPresenter
128
185
  # include Validatable
129
- # include_validations_for :person
186
+ # include_validations_for :person, :map => { :name => :namen }, :if => lambda { not person.nil? }
130
187
  # attr_accessor :person
131
188
  #
132
189
  # def initialize(person)
@@ -136,11 +193,16 @@ module Validatable
136
193
  #
137
194
  # presenter = PersonPresenter.new(Person.new)
138
195
  # presenter.valid? #=> false
139
- # presenter.errors.on(:name) #=> "can't be blank"
196
+ # presenter.errors.on(:namen) #=> "can't be blank"
140
197
  #
141
198
  # The person attribute will be validated. If person is invalid the errors will be added to the PersonPresenter errors collection.
142
- def include_validations_for(*args)
143
- children_to_validate.concat args
199
+ #
200
+ # Configuration options:
201
+ #
202
+ # * map - A hash that maps attributes of the child to attributes of the parent.
203
+ # * if - A block that when executed must return true of the validation will not occur.
204
+ def include_validations_for(attribute_to_validate, options = {})
205
+ children_to_validate << ChildValidation.new(attribute_to_validate, options[:map] || {}, options[:if] || lambda { true })
144
206
  end
145
207
 
146
208
  def validate(instance) #:nodoc:
@@ -155,12 +217,13 @@ module Validatable
155
217
  end
156
218
  end
157
219
 
158
- def validate_children(instance) #:nodoc:
159
- self.children_to_validate.each do |child_name|
160
- child = instance.send child_name
161
- child.valid?
220
+ def validate_children(instance, groups) #:nodoc:
221
+ self.children_to_validate.each do |child_validation|
222
+ next unless child_validation.should_validate?(instance)
223
+ child = instance.send child_validation.attribute
224
+ child.valid?(*groups)
162
225
  child.errors.each do |attribute, message|
163
- instance.errors.add(attribute, message)
226
+ instance.errors.add(child_validation.map[attribute.to_sym] || attribute, message)
164
227
  end
165
228
  end
166
229
  end
@@ -191,10 +254,10 @@ module Validatable
191
254
  # call-seq: valid?
192
255
  #
193
256
  # Returns true if no errors were added otherwise false.
194
- def valid?
257
+ def valid?(*groups)
195
258
  errors.clear
196
- self.class.validate_children(self)
197
- self.validate
259
+ self.class.validate_children(self, groups)
260
+ self.validate(groups)
198
261
  errors.empty?
199
262
  end
200
263
 
@@ -206,17 +269,25 @@ module Validatable
206
269
  end
207
270
 
208
271
  protected
209
- def validate #:nodoc:
210
- validation_levels.sort.each do |level|
211
- validations_for_level(level).each do |validation|
212
- if validation.should_validate?(self)
213
- self.errors.add(validation.attribute, validation.message) unless validation.valid?(self)
272
+ def validate(groups) #:nodoc:
273
+ validations_for_groups(groups).each do |validation|
274
+ validation_levels.sort.each do |level|
275
+ validations_for_level(level).each do |validation|
276
+ if validation.should_validate?(self)
277
+ run_validation(validation)
278
+ end
214
279
  end
280
+ return unless self.errors.empty?
215
281
  end
216
- return unless self.errors.empty?
217
282
  end
218
283
  end
219
284
 
285
+ def run_validation(validation) #:nodoc:
286
+ validation_result = validation.valid?(self)
287
+ self.errors.add(validation.attribute, validation.message) unless validation_result
288
+ validation.run_after_validate(validation_result, self, validation.attribute)
289
+ end
290
+
220
291
  def validation_levels #:nodoc:
221
292
  self.validations.collect { |validation| validation.level }.uniq
222
293
  end
@@ -225,6 +296,11 @@ module Validatable
225
296
  self.validations.select { |validation| validation.level == level }
226
297
  end
227
298
 
299
+ def validations_for_groups(groups) #:nodoc:
300
+ return self.validations if groups.empty?
301
+ self.validations.select { |validation| (groups & validation.groups).any? }
302
+ end
303
+
228
304
  def validations #:nodoc:
229
305
  @validations ||= self.class.validations.collect { |validation| validation.dup }
230
306
  end
@@ -0,0 +1,15 @@
1
+ module Validatable
2
+ class ChildValidation #:nodoc:
3
+ attr_accessor :attribute, :map, :should_validate_proc
4
+
5
+ def initialize(attribute, map, should_validate_proc)
6
+ @attribute = attribute
7
+ @map = map
8
+ @should_validate_proc = should_validate_proc
9
+ end
10
+
11
+ def should_validate?(instance)
12
+ instance.instance_eval &should_validate_proc
13
+ end
14
+ end
15
+ end
data/lib/errors.rb CHANGED
@@ -2,7 +2,7 @@ module Validatable
2
2
  class Errors
3
3
  extend Forwardable
4
4
 
5
- def_delegators :errors, :empty?, :clear, :each
5
+ def_delegators :errors, :any?, :clear, :each, :each_pair, :empty?, :length, :size
6
6
 
7
7
  # call-seq: on(attribute)
8
8
  #
@@ -15,6 +15,11 @@ module Validatable
15
15
  def add(attribute, message) #:nodoc:
16
16
  errors[attribute.to_sym] = message
17
17
  end
18
+
19
+ def merge!(errors) #:nodoc:
20
+ errors.each_pair{|k, v| add(k,v)}
21
+ self
22
+ end
18
23
 
19
24
  def errors #:nodoc:
20
25
  @errors ||= {}
data/lib/validatable.rb CHANGED
@@ -1,9 +1,12 @@
1
1
  require 'forwardable'
2
2
  require File.expand_path(File.dirname(__FILE__) + '/errors')
3
3
  require File.expand_path(File.dirname(__FILE__) + '/base')
4
+ require File.expand_path(File.dirname(__FILE__) + '/child_validation')
4
5
  require File.expand_path(File.dirname(__FILE__) + '/validations/validation_base')
5
6
  require File.expand_path(File.dirname(__FILE__) + '/validations/validates_format_of')
6
7
  require File.expand_path(File.dirname(__FILE__) + '/validations/validates_presence_of')
7
8
  require File.expand_path(File.dirname(__FILE__) + '/validations/validates_acceptance_of')
8
9
  require File.expand_path(File.dirname(__FILE__) + '/validations/validates_confirmation_of')
9
- require File.expand_path(File.dirname(__FILE__) + '/validations/validates_length_of')
10
+ require File.expand_path(File.dirname(__FILE__) + '/validations/validates_length_of')
11
+ require File.expand_path(File.dirname(__FILE__) + '/validations/validates_true_for')
12
+ require File.expand_path(File.dirname(__FILE__) + '/validations/validates_numericality_of')
@@ -1,7 +1,10 @@
1
1
  module Validatable
2
2
  class ValidatesConfirmationOf < ValidationBase #:nodoc:
3
+ attr_accessor :case_sensitive
4
+
3
5
  def valid?(instance)
4
- instance.send(self.attribute) == instance.send("#{self.attribute}_confirmation".to_sym)
6
+ return instance.send(self.attribute) == instance.send("#{self.attribute}_confirmation".to_sym) if case_sensitive
7
+ instance.send(self.attribute).to_s.casecmp(instance.send("#{self.attribute}_confirmation".to_sym).to_s) == 0
5
8
  end
6
9
 
7
10
  def message
@@ -0,0 +1,13 @@
1
+ module Validatable
2
+ class ValidatesNumericalityOf < ValidationBase #:nodoc:
3
+
4
+ def valid?(instance)
5
+ not (instance.send(self.attribute).to_s =~ /^\d*\.{0,1}\d+$/).nil?
6
+ end
7
+
8
+ def message
9
+ super || "must be a number"
10
+ end
11
+ end
12
+ end
13
+
@@ -0,0 +1,13 @@
1
+ module Validatable
2
+ class ValidatesTrueFor < ValidationBase #:nodoc:
3
+ attr_accessor :logic
4
+
5
+ def valid?(instance)
6
+ instance.instance_eval(&logic) == true
7
+ end
8
+
9
+ def message
10
+ super || "is invalid"
11
+ end
12
+ end
13
+ end
@@ -1,7 +1,7 @@
1
1
  module Validatable
2
2
  class ValidationBase #:nodoc:
3
- attr_accessor :attribute, :message
4
- attr_reader :level
3
+ attr_accessor :attribute, :message, :times
4
+ attr_reader :level, :groups
5
5
 
6
6
  def initialize(attribute, options={})
7
7
  @attribute = attribute
@@ -9,6 +9,7 @@ module Validatable
9
9
  @conditional = options[:if] || Proc.new { true }
10
10
  @times = options[:times]
11
11
  @level = options[:level] || 1
12
+ @groups = options[:groups].is_a?(Array) ? options[:groups] : [options[:groups]]
12
13
  end
13
14
 
14
15
  def should_validate?(instance)
@@ -17,8 +18,29 @@ module Validatable
17
18
 
18
19
  def validate_this_time?
19
20
  return true if @times.nil?
20
- @times -= 1
21
- @times >= 0
21
+ self.times -= 1
22
+ self.times >= 0
23
+ end
24
+
25
+ def run_after_validate(result, instance, attribute)
26
+ self.class.all_after_validations.each do |block|
27
+ block.call result, instance, attribute
28
+ end
29
+ end
30
+
31
+ class << self
32
+ def after_validate(&block)
33
+ after_validations << block
34
+ end
35
+
36
+ def after_validations
37
+ @after_validations ||= []
38
+ end
39
+
40
+ def all_after_validations
41
+ return after_validations + self.superclass.after_validations if self.superclass.respond_to? :after_validations
42
+ after_validations
43
+ end
22
44
  end
23
45
  end
24
46
  end
data/rakefile.rb CHANGED
@@ -29,7 +29,7 @@ Gem::manage_gems
29
29
  specification = Gem::Specification.new do |s|
30
30
  s.name = "validatable"
31
31
  s.summary = "Validatable is a library for adding validations."
32
- s.version = "1.1.2"
32
+ s.version = "1.2.1"
33
33
  s.author = 'Jay Fields'
34
34
  s.description = "Validatable is a library for adding validations."
35
35
  s.email = 'validatable-developer@rubyforge.org'
@@ -22,6 +22,135 @@ module Functional
22
22
  assert_equal "can't be empty", instance.errors.on(:name)
23
23
  end
24
24
 
25
+ test "given a child class with validations, the error is in the parent objects error collection as the mapped attribute" do
26
+ child_class = Class.new do
27
+ include Validatable
28
+ attr_accessor :name, :address
29
+ validates_presence_of :name
30
+ end
31
+ klass = Class.new do
32
+ include Validatable
33
+ include_validations_for :child, :map => {:name => :namen}
34
+ define_method :child do
35
+ child_class.new
36
+ end
37
+ end
38
+ instance = klass.new
39
+ instance.valid?
40
+ assert_equal "can't be empty", instance.errors.on(:namen)
41
+ end
42
+
43
+ test "given a child class with validations, the error is in the parent objects error collection when the 'if' evals to true" do
44
+ child_class = Class.new do
45
+ include Validatable
46
+ attr_accessor :name, :address
47
+ validates_presence_of :name
48
+ end
49
+ klass = Class.new do
50
+ include Validatable
51
+ include_validations_for :child, :if => lambda { true }
52
+ define_method :child do
53
+ child_class.new
54
+ end
55
+ end
56
+ instance = klass.new
57
+ instance.valid?
58
+ assert_equal "can't be empty", instance.errors.on(:name)
59
+ end
60
+
61
+ test "given a child class with validations, the error is not in the parent objects error collection when the if evals to false" do
62
+ child_class = Class.new do
63
+ include Validatable
64
+ attr_accessor :name, :address
65
+ validates_presence_of :name
66
+ end
67
+ klass = Class.new do
68
+ include Validatable
69
+ include_validations_for :child, :if => lambda { false }
70
+ define_method :child do
71
+ child_class.new
72
+ end
73
+ end
74
+ instance = klass.new
75
+ assert_equal true, instance.valid?
76
+ end
77
+
78
+ test "nonmatching groups are not used as validations" do
79
+ klass = Class.new do
80
+ include Validatable
81
+ validates_presence_of :name, :groups => :group_one
82
+ attr_accessor :name
83
+ end
84
+ instance = klass.new
85
+ assert_equal true, instance.valid?(:group_two)
86
+ end
87
+
88
+ test "after validate is called following a validation" do
89
+ klass = Class.new do
90
+ include Validatable
91
+ validates_presence_of :name
92
+ attr_accessor :name
93
+ end
94
+
95
+ Validatable::ValidationBase.class_eval do
96
+ after_validate do |result, instance, attribute|
97
+ instance.errors.add(attribute, instance.errors.on(attribute) + " changed message")
98
+ end
99
+ end
100
+ Validatable::ValidatesPresenceOf.class_eval do
101
+ after_validate do |result, instance, attribute|
102
+ instance.errors.add(attribute, instance.errors.on(attribute) + " twice")
103
+ end
104
+ end
105
+ instance = klass.new
106
+ instance.valid?
107
+ assert_equal "can't be empty twice changed message", instance.errors.on(:name)
108
+ Validatable::ValidatesPresenceOf.after_validations.clear
109
+ Validatable::ValidationBase.after_validations.clear
110
+ end
111
+
112
+ test "matching groups are used as validations when multiple groups are given to valid" do
113
+ klass = Class.new do
114
+ include Validatable
115
+ validates_presence_of :name, :groups => :group_one
116
+ attr_accessor :name
117
+ end
118
+ instance = klass.new
119
+ assert_equal false, instance.valid?(:group_one)
120
+ end
121
+
122
+ test "matching groups are used as validations when validations are part of multiple groups" do
123
+ klass = Class.new do
124
+ include Validatable
125
+ validates_presence_of :name, :groups => [:group_one, :group_two]
126
+ attr_accessor :name
127
+ end
128
+ instance = klass.new
129
+ assert_equal false, instance.valid?(:group_one)
130
+ end
131
+
132
+ test "no group given then all validations are used" do
133
+ klass = Class.new do
134
+ include Validatable
135
+ validates_presence_of :name, :groups => :group_one
136
+ attr_accessor :name
137
+ end
138
+ instance = klass.new
139
+ assert_equal false, instance.valid?
140
+ end
141
+
142
+ test "matching multiple groups for validations" do
143
+ klass = Class.new do
144
+ include Validatable
145
+ validates_presence_of :name, :groups => :group_one
146
+ validates_presence_of :address, :groups => :group_two
147
+ attr_accessor :name, :address
148
+ end
149
+ instance = klass.new
150
+ instance.valid?(:group_one, :group_two)
151
+ assert_equal 2, instance.errors.size
152
+ end
153
+
25
154
  expect true do
26
155
  klass = Class.new do
27
156
  include Validatable
@@ -14,5 +14,43 @@ module Functional
14
14
  instance.valid?
15
15
  assert_equal "doesn't match confirmation", instance.errors.on(:name)
16
16
  end
17
+
18
+ test "given matching attributes, when validated, then no error is in the objects error collection" do
19
+ klass = Class.new do
20
+ include Validatable
21
+ attr_accessor :name, :name_confirmation
22
+ validates_confirmation_of :name
23
+ end
24
+ instance = klass.new
25
+ instance.name = "foo"
26
+ instance.name_confirmation = "foo"
27
+ assert_equal true, instance.valid?
28
+ end
29
+
30
+ test "given matching attributes of different case, when validated with case sensitive false, then no error is in the objects error collection" do
31
+ klass = Class.new do
32
+ include Validatable
33
+ attr_accessor :name, :name_confirmation
34
+ validates_confirmation_of :name, :case_sensitive => false
35
+ end
36
+ instance = klass.new
37
+ instance.name = "foo"
38
+ instance.name_confirmation = "FOO"
39
+ assert_equal true, instance.valid?
40
+ end
41
+
42
+ test "given matching attributes of different case, when validated with case sensitive true, then error is in the objects error collection" do
43
+ klass = Class.new do
44
+ include Validatable
45
+ attr_accessor :name, :name_confirmation
46
+ validates_confirmation_of :name
47
+ end
48
+ instance = klass.new
49
+ instance.name = "foo"
50
+ instance.name_confirmation = "FOO"
51
+ assert_equal false, instance.valid?
52
+ assert_equal "doesn't match confirmation", instance.errors.on(:name)
53
+
54
+ end
17
55
  end
18
56
  end
@@ -0,0 +1,45 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ module Functional
4
+ class ValidatesNumericalityOfTest < Test::Unit::TestCase
5
+ test "when validating numericality and the value is nil an error should exist on the instance" do
6
+ klass = Class.new do
7
+ include Validatable
8
+ attr_accessor :nothing
9
+ validates_numericality_of :nothing
10
+ end
11
+ instance = klass.new
12
+ instance.valid?
13
+ assert_equal "must be a number", instance.errors.on(:nothing)
14
+ end
15
+
16
+ test "when validating numericality and the value has a non numeric character an error should exist on the instance" do
17
+ klass = Class.new do
18
+ include Validatable
19
+ validates_numericality_of :some_string
20
+
21
+ def some_string
22
+ "some_string"
23
+ end
24
+ end
25
+ instance = klass.new
26
+ instance.valid?
27
+ assert_equal "must be a number", instance.errors.on(:some_string)
28
+ end
29
+
30
+ test "when validating a number no error will be in the instance" do
31
+ klass = Class.new do
32
+ include Validatable
33
+ validates_numericality_of :valid_number
34
+
35
+ def valid_number
36
+ 1.23
37
+ end
38
+ end
39
+ instance = klass.new
40
+ instance.valid?
41
+ assert_equal nil, instance.errors.on(:valid_number)
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,27 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ module Functional
4
+ class ValidatesFormatOfTest < Test::Unit::TestCase
5
+ test "given invalid name, when validated, then error is in the objects error collection" do
6
+ klass = Class.new do
7
+ include Validatable
8
+ attr_accessor :name
9
+ validates_true_for :name, :logic => lambda { name == "nombre" }
10
+ end
11
+ instance = klass.new
12
+ instance.valid?
13
+ assert_equal "is invalid", instance.errors.on(:name)
14
+ end
15
+
16
+ test "given valid name, when validated, then no error is in the objects error collection" do
17
+ klass = Class.new do
18
+ include Validatable
19
+ attr_accessor :name
20
+ validates_true_for :name, :logic => lambda { name == "nombre" }
21
+ end
22
+ instance = klass.new
23
+ instance.name = "nombre"
24
+ assert_equal true, instance.valid?
25
+ end
26
+ end
27
+ end
@@ -3,7 +3,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
3
3
  module Unit
4
4
  class ValidatableTest < Test::Unit::TestCase
5
5
  expect false do
6
- validation = stub(:valid? => false, :should_validate? => true, :attribute => "attribute", :message => "message", :level => 1)
6
+ validation = stub(:valid? => false, :should_validate? => true, :attribute => "attribute", :message => "message", :level => 1, :run_after_validate => nil)
7
7
  klass = Class.new do
8
8
  include Validatable
9
9
  validations << validation
@@ -11,14 +11,6 @@ module Unit
11
11
  klass.new.valid?
12
12
  end
13
13
 
14
- expect [:anything, :else] do
15
- klass = Class.new do
16
- include Validatable
17
- include_validations_for :anything, :else
18
- end
19
- klass.send(:children_to_validate)
20
- end
21
-
22
14
  test "when validate is executed, then messages are added for each validation that fails" do
23
15
  klass = Class.new do
24
16
  include Validatable
@@ -12,4 +12,54 @@ class ValidatesConfirmationOfTest < Test::Unit::TestCase
12
12
  instance = stub(:username=>"username", :username_confirmation=>"usessrname")
13
13
  assert_equal false, validation.valid?(instance)
14
14
  end
15
+
16
+ test "valid confirmation with case insensitive" do
17
+ validation = Validatable::ValidatesConfirmationOf.new :username
18
+ validation.case_sensitive = false
19
+ instance = stub(:username=>"username", :username_confirmation=>"USERNAME")
20
+ assert_equal true, validation.valid?(instance)
21
+ end
22
+
23
+ test "invalid confirmation with case sensitive" do
24
+ validation = Validatable::ValidatesConfirmationOf.new :username
25
+ validation.case_sensitive = true
26
+ instance = stub(:username=>"username", :username_confirmation=>"USERNAME")
27
+ assert_equal false, validation.valid?(instance)
28
+ end
29
+
30
+ test "invalid confirmation if value is nil and confirmation is not with case sensitive true" do
31
+ validation = Validatable::ValidatesConfirmationOf.new :username
32
+ validation.case_sensitive = true
33
+ assert_equal false, validation.valid?(stub(:username => nil, :username_confirmation => 'something'))
34
+ end
35
+
36
+ test "invalid confirmation if confirmation is nil and value is not with case sensitive true" do
37
+ validation = Validatable::ValidatesConfirmationOf.new :username
38
+ validation.case_sensitive = true
39
+ assert_equal false, validation.valid?(stub(:username => 'something', :username_confirmation => nil))
40
+ end
41
+
42
+ test "valid confirmation if value and confirmation are nil with case sensitive true" do
43
+ validation = Validatable::ValidatesConfirmationOf.new :username
44
+ validation.case_sensitive = true
45
+ assert_equal true, validation.valid?(stub(:username => nil, :username_confirmation => nil))
46
+ end
47
+
48
+ test "invalid confirmation if value is nil and confirmation is not with case sensitive false" do
49
+ validation = Validatable::ValidatesConfirmationOf.new :username
50
+ validation.case_sensitive = false
51
+ assert_equal false, validation.valid?(stub(:username => nil, :username_confirmation => 'something'))
52
+ end
53
+
54
+ test "invalid confirmation if confirmation is nil and value is not with case sensitive false" do
55
+ validation = Validatable::ValidatesConfirmationOf.new :username
56
+ validation.case_sensitive = false
57
+ assert_equal false, validation.valid?(stub(:username => 'something', :username_confirmation => nil))
58
+ end
59
+
60
+ test "valid confirmation if value and confirmation are nil with case sensitive false" do
61
+ validation = Validatable::ValidatesConfirmationOf.new :username
62
+ validation.case_sensitive = false
63
+ assert_equal true, validation.valid?(stub(:username => nil, :username_confirmation => nil))
64
+ end
15
65
  end
@@ -0,0 +1,36 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ module Unit
4
+ class ValidatesNumericalityOfTest < Test::Unit::TestCase
5
+
6
+ test "when the value is nil then valid is false" do
7
+ validation = Validatable::ValidatesNumericalityOf.new :nothing
8
+ instance = stub(:nothing => nil)
9
+ assert_equal false, validation.valid?(instance)
10
+ end
11
+
12
+ test "when value is an integer then valid is true" do
13
+ validation = Validatable::ValidatesNumericalityOf.new :some_int
14
+ instance = stub(:some_int => 50)
15
+ assert_equal true, validation.valid?(instance)
16
+ end
17
+
18
+ test "when value is an decimal then valid is true" do
19
+ validation = Validatable::ValidatesNumericalityOf.new :some_decimal
20
+ instance = stub(:some_decimal => 1.23)
21
+ assert_equal true, validation.valid?(instance)
22
+ end
23
+
24
+ test "when value has non numeric characters then valid is false" do
25
+ validation = Validatable::ValidatesNumericalityOf.new :some_non_numeric
26
+ instance = stub(:some_non_numeric => "50F")
27
+ assert_equal false, validation.valid?(instance)
28
+ end
29
+
30
+ test "when value is a string with multiple dots then valid is false" do
31
+ validation = Validatable::ValidatesNumericalityOf.new :multiple_dots
32
+ instance = stub(:multiple_dots => "50.0.0")
33
+ assert_equal false, validation.valid?(instance)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,16 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ class ValidatesTrueForTest < Test::Unit::TestCase
4
+ test "when block returns false for attribute value, then valid is false" do
5
+ validation = Validatable::ValidatesTrueFor.new :name
6
+ validation.logic = lambda { false }
7
+ assert_equal false, validation.valid?(stub_everything)
8
+ end
9
+
10
+ test "when block returns true for attribute value, then valid is false" do
11
+ validation = Validatable::ValidatesTrueFor.new :name
12
+ validation.logic = lambda { true }
13
+ assert_equal true, validation.valid?(stub_everything)
14
+ end
15
+
16
+ end
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.8.11
2
+ rubygems_version: 0.9.2
3
3
  specification_version: 1
4
4
  name: validatable
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.1.2
7
- date: 2007-03-25 00:00:00 -04:00
6
+ version: 1.2.1
7
+ date: 2007-04-26 00:00:00 -04:00
8
8
  summary: Validatable is a library for adding validations.
9
9
  require_paths:
10
10
  - lib
@@ -25,17 +25,21 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
25
25
  platform: ruby
26
26
  signing_key:
27
27
  cert_chain:
28
+ post_install_message:
28
29
  authors:
29
30
  - Jay Fields
30
31
  files:
31
32
  - lib/base.rb
33
+ - lib/child_validation.rb
32
34
  - lib/errors.rb
33
35
  - lib/validatable.rb
34
36
  - lib/validations/validates_acceptance_of.rb
35
37
  - lib/validations/validates_confirmation_of.rb
36
38
  - lib/validations/validates_format_of.rb
37
39
  - lib/validations/validates_length_of.rb
40
+ - lib/validations/validates_numericality_of.rb
38
41
  - lib/validations/validates_presence_of.rb
42
+ - lib/validations/validates_true_for.rb
39
43
  - lib/validations/validation_base.rb
40
44
  - test/all_tests.rb
41
45
  - test/test_helper.rb
@@ -44,14 +48,18 @@ files:
44
48
  - test/functional/validates_confirmation_of_test.rb
45
49
  - test/functional/validates_format_of_test.rb
46
50
  - test/functional/validates_length_of_test.rb
51
+ - test/functional/validates_numericality_of_test.rb
47
52
  - test/functional/validates_presence_of_test.rb
53
+ - test/functional/validates_true_for_test.rb
48
54
  - test/unit/errors_test.rb
49
55
  - test/unit/validatable_test.rb
50
56
  - test/unit/validates_acceptance_of_test.rb
51
57
  - test/unit/validates_confirmation_of_test.rb
52
58
  - test/unit/validates_format_of_test.rb
53
59
  - test/unit/validates_length_of_test.rb
60
+ - test/unit/validates_numericality_of_test.rb
54
61
  - test/unit/validates_presence_of_test.rb
62
+ - test/unit/validates_true_for_test.rb
55
63
  - test/unit/validation_base_test.rb
56
64
  - rakefile.rb
57
65
  - README