validatable 1.1.2 → 1.2.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 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