validatable 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +50 -73
- data/lib/base.rb +60 -20
- data/lib/validatable.rb +6 -6
- data/lib/{validates_acceptance_of.rb → validations/validates_acceptance_of.rb} +4 -0
- data/lib/{validates_confirmation_of.rb → validations/validates_confirmation_of.rb} +4 -0
- data/lib/validations/validates_format_of.rb +13 -0
- data/lib/{validates_length_of.rb → validations/validates_length_of.rb} +4 -5
- data/lib/{validates_presence_of.rb → validations/validates_presence_of.rb} +4 -0
- data/lib/validations/validation_base.rb +24 -0
- data/rakefile.rb +1 -1
- data/test/all_tests.rb +1 -1
- data/test/functional/validatable_test.rb +60 -0
- data/test/functional/validates_acceptance_of_test.rb +16 -0
- data/test/functional/validates_confirmation_of_test.rb +18 -0
- data/test/functional/validates_format_of_test.rb +34 -0
- data/test/functional/validates_length_of_test.rb +16 -0
- data/test/functional/validates_presence_of_test.rb +16 -0
- data/test/test_helper.rb +6 -0
- data/test/unit/errors_test.rb +9 -0
- data/test/unit/validatable_test.rb +47 -0
- data/test/{validates_acceptance_of_test.rb → unit/validates_acceptance_of_test.rb} +3 -3
- data/test/{validates_confirmation_of_test.rb → unit/validates_confirmation_of_test.rb} +3 -3
- data/test/{validates_format_of_test.rb → unit/validates_format_of_test.rb} +5 -3
- data/test/unit/validates_length_of_test.rb +28 -0
- data/test/{validates_presence_of_test.rb → unit/validates_presence_of_test.rb} +3 -3
- data/test/unit/validation_base_test.rb +35 -0
- metadata +22 -16
- data/lib/validates_format_of.rb +0 -13
- data/lib/validation_base.rb +0 -9
- data/test/errors_test.rb +0 -9
- data/test/functional_test.rb +0 -80
- data/test/validatable_test.rb +0 -44
- data/test/validates_length_of_test.rb +0 -23
data/README
CHANGED
@@ -16,8 +16,6 @@ You may use, copy and redistribute this library under the same terms as Ruby its
|
|
16
16
|
|
17
17
|
== Examples
|
18
18
|
|
19
|
-
See the tests for more examples
|
20
|
-
|
21
19
|
=== Test Helper
|
22
20
|
|
23
21
|
require 'test/unit'
|
@@ -31,87 +29,66 @@ See the tests for more examples
|
|
31
29
|
raise ArgumentError, "#{test_name} is already defined" if self.instance_methods.include? test_name.to_s
|
32
30
|
define_method test_name, &block
|
33
31
|
end
|
32
|
+
|
33
|
+
def expect(expected_value, &block)
|
34
|
+
define_method :"test_#{caller.first.split("/").last}" do
|
35
|
+
assert_equal expected_value, instance_eval(&block)
|
36
|
+
end
|
37
|
+
end
|
34
38
|
end
|
35
39
|
|
36
|
-
===
|
40
|
+
=== Validations
|
37
41
|
|
38
|
-
require File.expand_path(File.dirname(__FILE__) + '
|
42
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
39
43
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
44
|
+
module Functional
|
45
|
+
class ValidatesPresenceOfTest < Test::Unit::TestCase
|
46
|
+
test "given no name, when validated, then error is in the objects error collection" do
|
47
|
+
klass = Class.new do
|
48
|
+
include Validatable
|
49
|
+
attr_accessor :name
|
50
|
+
validates_presence_of :name
|
51
|
+
end
|
52
|
+
instance = klass.new
|
53
|
+
instance.valid?
|
54
|
+
assert_equal "can't be empty", instance.errors.on(:name)
|
46
55
|
end
|
47
|
-
instance = klass.new
|
48
|
-
instance.valid?
|
49
|
-
assert_equal "can't be empty", instance.errors.on(:name)
|
50
56
|
end
|
57
|
+
end
|
58
|
+
|
59
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
51
60
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
test "given no acceptance, when validated, then error is in the objects error collection" do
|
64
|
-
klass = Class.new do
|
65
|
-
include Validatable
|
66
|
-
attr_accessor :name
|
67
|
-
validates_acceptance_of :name
|
68
|
-
end
|
69
|
-
instance = klass.new
|
70
|
-
instance.valid?
|
71
|
-
assert_equal "must be accepted", instance.errors.on(:name)
|
72
|
-
end
|
73
|
-
|
74
|
-
test "given non matching attributes, when validated, then error is in the objects error collection" do
|
75
|
-
klass = Class.new do
|
76
|
-
include Validatable
|
77
|
-
attr_accessor :name, :name_confirmation
|
78
|
-
validates_confirmation_of :name
|
61
|
+
module Functional
|
62
|
+
class ValidatesFormatOfTest < Test::Unit::TestCase
|
63
|
+
test "given invalid name format, when validated, then error is in the objects error collection" do
|
64
|
+
klass = Class.new do
|
65
|
+
include Validatable
|
66
|
+
attr_accessor :name
|
67
|
+
validates_format_of :name, :with => /.+/
|
68
|
+
end
|
69
|
+
instance = klass.new
|
70
|
+
instance.valid?
|
71
|
+
assert_equal "is invalid", instance.errors.on(:name)
|
79
72
|
end
|
80
|
-
instance = klass.new
|
81
|
-
instance.name = "foo"
|
82
|
-
instance.name_confirmation = "bar"
|
83
|
-
instance.valid?
|
84
|
-
assert_equal "doesn't match confirmation", instance.errors.on(:name)
|
85
|
-
end
|
86
73
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
instance.valid?
|
95
|
-
assert_equal "is invalid", instance.errors.on(:name)
|
96
|
-
end
|
97
|
-
|
98
|
-
test "given a child class with validations, when parent class is validated, then the error is in the parent objects error collection" do
|
99
|
-
child_class = Class.new do
|
100
|
-
include Validatable
|
101
|
-
attr_accessor :name, :address
|
102
|
-
validates_presence_of :name
|
103
|
-
validates_format_of :address, :with => /.+/
|
74
|
+
test "given invalid name format and nil name, when validated, then error is in the objects error collection" do
|
75
|
+
klass = Class.new do
|
76
|
+
include Validatable
|
77
|
+
attr_accessor :name
|
78
|
+
validates_format_of :name, :with => /.+/, :if => Proc.new { !name.nil? }
|
79
|
+
end
|
80
|
+
assert_equal true, klass.new.valid?
|
104
81
|
end
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
82
|
+
|
83
|
+
test "given invalid name format and a name, when validated, then error is in the objects error collection" do
|
84
|
+
klass = Class.new do
|
85
|
+
include Validatable
|
86
|
+
attr_accessor :name
|
87
|
+
validates_format_of :name, :with => /.+/, :if => Proc.new { name.nil? }
|
110
88
|
end
|
89
|
+
assert_equal false, klass.new.valid?
|
111
90
|
end
|
112
|
-
instance = klass.new
|
113
|
-
instance.valid?
|
114
|
-
assert_equal "is invalid", instance.errors.on(:address)
|
115
|
-
assert_equal "can't be empty", instance.errors.on(:name)
|
116
91
|
end
|
117
|
-
end
|
92
|
+
end
|
93
|
+
|
94
|
+
See the tests for more examples
|
data/lib/base.rb
CHANGED
@@ -4,35 +4,69 @@ module Validatable
|
|
4
4
|
#
|
5
5
|
# Validates whether the value of the specified attribute is of the correct form by matching it against the regular expression provided.
|
6
6
|
#
|
7
|
-
# class Person
|
7
|
+
# class Person
|
8
|
+
# include Validatable
|
8
9
|
# validates_format_of :first_name, :with => /[ A-Za-z]/
|
9
10
|
# end
|
10
11
|
#
|
11
12
|
# A regular expression must be provided or else an exception will be raised.
|
12
13
|
def validates_format_of(*args)
|
13
|
-
|
14
|
-
|
14
|
+
add_validations(args, ValidatesFormatOf) do |validation, options|
|
15
|
+
validation.with = options[:with]
|
15
16
|
end
|
16
17
|
end
|
17
18
|
|
19
|
+
# call-seq: validates_length_of(*args)
|
20
|
+
#
|
21
|
+
# Validates that the specified attribute matches the length restrictions supplied.
|
22
|
+
#
|
23
|
+
# class Person
|
24
|
+
# include Validatable
|
25
|
+
# validates_length_of :first_name, :maximum=>30
|
26
|
+
# validates_length_of :last_name, :minimum=>30
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# Configuration options:
|
30
|
+
#
|
31
|
+
# * minimum - The minimum size of the attribute
|
32
|
+
# * maximum - The maximum size of the attribute
|
18
33
|
def validates_length_of(*args)
|
19
|
-
|
20
|
-
|
34
|
+
add_validations(args, ValidatesLengthOf) do |validation, options|
|
35
|
+
validation.minimum = options[:minimum]
|
36
|
+
validation.maximum = options[:maximum]
|
21
37
|
end
|
22
38
|
end
|
23
|
-
|
39
|
+
|
40
|
+
# call-seq: validates_acceptance_of(*args)
|
41
|
+
#
|
42
|
+
# Encapsulates the pattern of wanting to validate the acceptance of a terms of service check box (or similar agreement). Example:
|
43
|
+
#
|
44
|
+
# class Person
|
45
|
+
# include Validatable
|
46
|
+
# validates_acceptance_of :terms_of_service
|
47
|
+
# validates_acceptance_of :eula, :message => "must be abided"
|
48
|
+
# end
|
24
49
|
def validates_acceptance_of(*args)
|
25
|
-
|
26
|
-
self.validations << ValidatesAcceptanceOf.new(attribute, message || "must be accepted")
|
27
|
-
end
|
50
|
+
add_validations(args, ValidatesAcceptanceOf)
|
28
51
|
end
|
29
52
|
|
53
|
+
# call-seq: validates_confirmation_of(*args)
|
54
|
+
#
|
55
|
+
# Encapsulates the pattern of wanting to validate a password or email address field with a confirmation. Example:
|
56
|
+
#
|
57
|
+
# Class:
|
58
|
+
# class PersonPresenter
|
59
|
+
# include Validatable
|
60
|
+
# validates_confirmation_of :user_name, :password
|
61
|
+
# validates_confirmation_of :email_address, :message => "should match confirmation"
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
# View:
|
65
|
+
# <%= password_field "person", "password" %>
|
66
|
+
# <%= password_field "person", "password_confirmation" %>
|
30
67
|
def validates_confirmation_of(*args)
|
31
|
-
|
32
|
-
self.validations << ValidatesConfirmationOf.new(attribute, message || "doesn't match confirmation")
|
33
|
-
end
|
68
|
+
add_validations(args, ValidatesConfirmationOf)
|
34
69
|
end
|
35
|
-
|
36
70
|
|
37
71
|
# call-seq: validates_presence_of(*args)
|
38
72
|
#
|
@@ -45,9 +79,7 @@ module Validatable
|
|
45
79
|
#
|
46
80
|
# The first_name attribute must be in the object and it cannot be nil or empty.
|
47
81
|
def validates_presence_of(*args)
|
48
|
-
|
49
|
-
self.validations << ValidatesPresenceOf.new(attribute, message || "can't be empty")
|
50
|
-
end
|
82
|
+
add_validations(args, ValidatesPresenceOf)
|
51
83
|
end
|
52
84
|
|
53
85
|
# call-seq: include_validations_for(*args)
|
@@ -70,8 +102,14 @@ module Validatable
|
|
70
102
|
end
|
71
103
|
|
72
104
|
def validate(instance) #:nodoc:
|
73
|
-
self.validations.
|
74
|
-
|
105
|
+
levels = self.validations.collect { |validation| validation.level }.uniq
|
106
|
+
levels.sort.each do |level|
|
107
|
+
self.validations.select { |validation| validation.level == level }.each do |validation|
|
108
|
+
if validation.should_validate?(instance)
|
109
|
+
instance.errors.add(validation.attribute, validation.message) unless validation.valid?(instance)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
return unless instance.errors.empty?
|
75
113
|
end
|
76
114
|
end
|
77
115
|
|
@@ -86,10 +124,12 @@ module Validatable
|
|
86
124
|
end
|
87
125
|
|
88
126
|
protected
|
89
|
-
def
|
127
|
+
def add_validations(args, klass) #:nodoc:
|
90
128
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
91
129
|
args.each do |attribute|
|
92
|
-
|
130
|
+
new_validation = klass.new(attribute, options)
|
131
|
+
yield new_validation, options if block_given?
|
132
|
+
self.validations << new_validation
|
93
133
|
end
|
94
134
|
end
|
95
135
|
|
data/lib/validatable.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
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__) + '/validation_base')
|
5
|
-
require File.expand_path(File.dirname(__FILE__) + '/validates_format_of')
|
6
|
-
require File.expand_path(File.dirname(__FILE__) + '/validates_presence_of')
|
7
|
-
require File.expand_path(File.dirname(__FILE__) + '/validates_acceptance_of')
|
8
|
-
require File.expand_path(File.dirname(__FILE__) + '/validates_confirmation_of')
|
9
|
-
require File.expand_path(File.dirname(__FILE__) + '/validates_length_of')
|
4
|
+
require File.expand_path(File.dirname(__FILE__) + '/validations/validation_base')
|
5
|
+
require File.expand_path(File.dirname(__FILE__) + '/validations/validates_format_of')
|
6
|
+
require File.expand_path(File.dirname(__FILE__) + '/validations/validates_presence_of')
|
7
|
+
require File.expand_path(File.dirname(__FILE__) + '/validations/validates_acceptance_of')
|
8
|
+
require File.expand_path(File.dirname(__FILE__) + '/validations/validates_confirmation_of')
|
9
|
+
require File.expand_path(File.dirname(__FILE__) + '/validations/validates_length_of')
|
@@ -1,10 +1,9 @@
|
|
1
1
|
module Validatable
|
2
2
|
class ValidatesLengthOf < ValidationBase #:nodoc:
|
3
|
-
attr_accessor :
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
super attribute, message
|
3
|
+
attr_accessor :minimum, :maximum
|
4
|
+
|
5
|
+
def message
|
6
|
+
super || "is invalid"
|
8
7
|
end
|
9
8
|
|
10
9
|
def valid?(instance)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Validatable
|
2
|
+
class ValidationBase #:nodoc:
|
3
|
+
attr_accessor :attribute, :message
|
4
|
+
attr_reader :level
|
5
|
+
|
6
|
+
def initialize(attribute, options={})
|
7
|
+
@attribute = attribute
|
8
|
+
@message = options[:message]
|
9
|
+
@conditional = options[:if] || Proc.new { true }
|
10
|
+
@times = options[:times]
|
11
|
+
@level = options[:level] || 1
|
12
|
+
end
|
13
|
+
|
14
|
+
def should_validate?(instance)
|
15
|
+
instance.instance_eval(&@conditional) && validate_this_time?
|
16
|
+
end
|
17
|
+
|
18
|
+
def validate_this_time?
|
19
|
+
return true if @times.nil?
|
20
|
+
@times -= 1
|
21
|
+
@times >= 0
|
22
|
+
end
|
23
|
+
end
|
24
|
+
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.
|
32
|
+
s.version = "1.1.0"
|
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'
|
data/test/all_tests.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
Dir['
|
1
|
+
Dir['test/**/*_test.rb'].each { |test_case| require test_case }
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
module Functional
|
4
|
+
class ValidatableTest < Test::Unit::TestCase
|
5
|
+
test "given a child class with validations, when parent class is validated, then the error is in the parent objects error collection" do
|
6
|
+
child_class = Class.new do
|
7
|
+
include Validatable
|
8
|
+
attr_accessor :name, :address
|
9
|
+
validates_presence_of :name
|
10
|
+
validates_format_of :address, :with => /.+/
|
11
|
+
end
|
12
|
+
klass = Class.new do
|
13
|
+
include Validatable
|
14
|
+
include_validations_for :child
|
15
|
+
define_method :child do
|
16
|
+
child_class.new
|
17
|
+
end
|
18
|
+
end
|
19
|
+
instance = klass.new
|
20
|
+
instance.valid?
|
21
|
+
assert_equal "is invalid", instance.errors.on(:address)
|
22
|
+
assert_equal "can't be empty", instance.errors.on(:name)
|
23
|
+
end
|
24
|
+
|
25
|
+
expect true do
|
26
|
+
klass = Class.new do
|
27
|
+
include Validatable
|
28
|
+
validates_presence_of :name, :times => 1
|
29
|
+
attr_accessor :name
|
30
|
+
end
|
31
|
+
instance = klass.new
|
32
|
+
instance.valid?
|
33
|
+
instance.valid?
|
34
|
+
end
|
35
|
+
|
36
|
+
expect "name message" do
|
37
|
+
klass = Class.new do
|
38
|
+
include Validatable
|
39
|
+
validates_presence_of :name, :level => 1, :message => "name message"
|
40
|
+
validates_presence_of :address, :level => 2
|
41
|
+
attr_accessor :name, :address
|
42
|
+
end
|
43
|
+
instance = klass.new
|
44
|
+
instance.valid?
|
45
|
+
instance.errors.on(:name)
|
46
|
+
end
|
47
|
+
|
48
|
+
expect nil do
|
49
|
+
klass = Class.new do
|
50
|
+
include Validatable
|
51
|
+
validates_presence_of :name, :level => 1, :message => "name message"
|
52
|
+
validates_presence_of :address, :level => 2
|
53
|
+
attr_accessor :name, :address
|
54
|
+
end
|
55
|
+
instance = klass.new
|
56
|
+
instance.valid?
|
57
|
+
instance.errors.on(:address)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
module Functional
|
4
|
+
class ValidatesAcceptanceOfTest < Test::Unit::TestCase
|
5
|
+
test "given no acceptance, 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_acceptance_of :name
|
10
|
+
end
|
11
|
+
instance = klass.new
|
12
|
+
instance.valid?
|
13
|
+
assert_equal "must be accepted", instance.errors.on(:name)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
module Functional
|
4
|
+
class ValidatesConfirmationOfTest < Test::Unit::TestCase
|
5
|
+
test "given non matching attributes, when validated, then error is in the objects error collection" do
|
6
|
+
klass = Class.new do
|
7
|
+
include Validatable
|
8
|
+
attr_accessor :name, :name_confirmation
|
9
|
+
validates_confirmation_of :name
|
10
|
+
end
|
11
|
+
instance = klass.new
|
12
|
+
instance.name = "foo"
|
13
|
+
instance.name_confirmation = "bar"
|
14
|
+
instance.valid?
|
15
|
+
assert_equal "doesn't match confirmation", instance.errors.on(:name)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,34 @@
|
|
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 format, 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_format_of :name, :with => /.+/
|
10
|
+
end
|
11
|
+
instance = klass.new
|
12
|
+
instance.valid?
|
13
|
+
assert_equal "is invalid", instance.errors.on(:name)
|
14
|
+
end
|
15
|
+
|
16
|
+
test "given invalid name format and nil name, when validated, then error is in the objects error collection" do
|
17
|
+
klass = Class.new do
|
18
|
+
include Validatable
|
19
|
+
attr_accessor :name
|
20
|
+
validates_format_of :name, :with => /.+/, :if => Proc.new { !name.nil? }
|
21
|
+
end
|
22
|
+
assert_equal true, klass.new.valid?
|
23
|
+
end
|
24
|
+
|
25
|
+
test "given invalid name format and a name, when validated, then error is in the objects error collection" do
|
26
|
+
klass = Class.new do
|
27
|
+
include Validatable
|
28
|
+
attr_accessor :name
|
29
|
+
validates_format_of :name, :with => /.+/, :if => Proc.new { name.nil? }
|
30
|
+
end
|
31
|
+
assert_equal false, klass.new.valid?
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
module Functional
|
4
|
+
class ValidatesLengthOfTest < Test::Unit::TestCase
|
5
|
+
test "given short value, 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_length_of :name, :minimum => 2
|
10
|
+
end
|
11
|
+
instance = klass.new
|
12
|
+
instance.valid?
|
13
|
+
assert_equal "is invalid", instance.errors.on(:name)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
module Functional
|
4
|
+
class ValidatesPresenceOfTest < Test::Unit::TestCase
|
5
|
+
test "given no 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_presence_of :name
|
10
|
+
end
|
11
|
+
instance = klass.new
|
12
|
+
instance.valid?
|
13
|
+
assert_equal "can't be empty", instance.errors.on(:name)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -9,4 +9,10 @@ class << Test::Unit::TestCase
|
|
9
9
|
raise ArgumentError, "#{test_name} is already defined" if self.instance_methods.include? test_name.to_s
|
10
10
|
define_method test_name, &block
|
11
11
|
end
|
12
|
+
|
13
|
+
def expect(expected_value, &block)
|
14
|
+
define_method :"test_#{caller.first.split("/").last}" do
|
15
|
+
assert_equal expected_value, instance_eval(&block)
|
16
|
+
end
|
17
|
+
end
|
12
18
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
module Unit
|
4
|
+
class ValidatableTest < Test::Unit::TestCase
|
5
|
+
expect false do
|
6
|
+
validation = stub(:valid? => false, :should_validate? => true, :attribute => "attribute", :message => "message", :level => 1)
|
7
|
+
klass = Class.new do
|
8
|
+
include Validatable
|
9
|
+
validations << validation
|
10
|
+
end
|
11
|
+
klass.new.valid?
|
12
|
+
end
|
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
|
+
test "when validate is executed, then messages are added for each validation that fails" do
|
23
|
+
klass = Class.new do
|
24
|
+
include Validatable
|
25
|
+
end
|
26
|
+
klass.send(:validations) << stub(:valid? => false, :should_validate? => true, :attribute => 'attribute', :message => 'message', :level => 1)
|
27
|
+
klass.send(:validations) << stub(:valid? => false, :should_validate? => true, :attribute => 'attribute2', :message => 'message2', :level => 1)
|
28
|
+
instance=mock
|
29
|
+
instance.expects(:errors).returns(errors=mock).times 3
|
30
|
+
errors.expects(:add).with('attribute', 'message')
|
31
|
+
errors.expects(:add).with('attribute2', 'message2')
|
32
|
+
errors.expects(:empty?).returns true
|
33
|
+
klass.validate(instance)
|
34
|
+
end
|
35
|
+
|
36
|
+
expect true do
|
37
|
+
klass = Class.new do
|
38
|
+
include Validatable
|
39
|
+
end
|
40
|
+
instance = klass.new
|
41
|
+
instance.errors.add(:attribute, "message")
|
42
|
+
instance.valid?
|
43
|
+
instance.errors.empty?
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
@@ -1,14 +1,14 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
2
|
|
3
3
|
class ValidatesAcceptanceOfTest < Test::Unit::TestCase
|
4
4
|
test "valid acceptance" do
|
5
|
-
validation = Validatable::ValidatesAcceptanceOf.new
|
5
|
+
validation = Validatable::ValidatesAcceptanceOf.new :acceptance
|
6
6
|
instance = stub(:acceptance=>'true')
|
7
7
|
assert_equal true, validation.valid?(instance)
|
8
8
|
end
|
9
9
|
|
10
10
|
test "invalid acceptance" do
|
11
|
-
validation = Validatable::ValidatesAcceptanceOf.new
|
11
|
+
validation = Validatable::ValidatesAcceptanceOf.new :acceptance
|
12
12
|
instance = stub(:acceptance=>'false')
|
13
13
|
assert_equal false, validation.valid?(instance)
|
14
14
|
end
|
@@ -1,14 +1,14 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
2
|
|
3
3
|
class ValidatesConfirmationOfTest < Test::Unit::TestCase
|
4
4
|
test "valid confirmation" do
|
5
|
-
validation = Validatable::ValidatesConfirmationOf.new
|
5
|
+
validation = Validatable::ValidatesConfirmationOf.new :username
|
6
6
|
instance = stub(:username=>"username", :username_confirmation=>"username")
|
7
7
|
assert_equal true, validation.valid?(instance)
|
8
8
|
end
|
9
9
|
|
10
10
|
test "invalid confirmation" do
|
11
|
-
validation = Validatable::ValidatesConfirmationOf.new
|
11
|
+
validation = Validatable::ValidatesConfirmationOf.new :username
|
12
12
|
instance = stub(:username=>"username", :username_confirmation=>"usessrname")
|
13
13
|
assert_equal false, validation.valid?(instance)
|
14
14
|
end
|
@@ -1,13 +1,15 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
2
|
|
3
3
|
class ValidatesFormatOfTest < Test::Unit::TestCase
|
4
4
|
test "when attribute value does not match the given regex, then valid is false" do
|
5
|
-
validation = Validatable::ValidatesFormatOf.new
|
5
|
+
validation = Validatable::ValidatesFormatOf.new :name
|
6
|
+
validation.with = /book/
|
6
7
|
assert_equal false, validation.valid?(stub_everything)
|
7
8
|
end
|
8
9
|
|
9
10
|
test "when attribute value does match the given regex, then valid is true" do
|
10
|
-
validation = Validatable::ValidatesFormatOf.new
|
11
|
+
validation = Validatable::ValidatesFormatOf.new :name
|
12
|
+
validation.with = /book/
|
11
13
|
assert_equal true, validation.valid?(stub(:name=>"book"))
|
12
14
|
end
|
13
15
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
module Unit
|
4
|
+
class ValidatesLengthOfTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
test "max length" do
|
7
|
+
validation = Validatable::ValidatesLengthOf.new :username
|
8
|
+
validation.maximum = 8
|
9
|
+
instance = stub(:username=>"usernamefdfd")
|
10
|
+
assert_equal false, validation.valid?(instance)
|
11
|
+
end
|
12
|
+
|
13
|
+
test "min length" do
|
14
|
+
validation = Validatable::ValidatesLengthOf.new :username
|
15
|
+
validation.minimum = 2
|
16
|
+
instance = stub(:username=>"u")
|
17
|
+
assert_equal false, validation.valid?(instance)
|
18
|
+
end
|
19
|
+
|
20
|
+
test "valid length" do
|
21
|
+
validation = Validatable::ValidatesLengthOf.new :username
|
22
|
+
validation.minimum = 2
|
23
|
+
validation.maximum = 8
|
24
|
+
instance = stub(:username=>"udfgdf")
|
25
|
+
assert_equal true, validation.valid?(instance)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -1,13 +1,13 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
2
|
|
3
3
|
class ValidatesPresenceOfTest < Test::Unit::TestCase
|
4
4
|
test "when attribute value does not match the given regex, then valid is false" do
|
5
|
-
validation = Validatable::ValidatesPresenceOf.new
|
5
|
+
validation = Validatable::ValidatesPresenceOf.new :name
|
6
6
|
assert_equal false, validation.valid?(stub_everything)
|
7
7
|
end
|
8
8
|
|
9
9
|
test "when attribute value does match the given regex, then valid is true" do
|
10
|
-
validation = Validatable::ValidatesPresenceOf.new
|
10
|
+
validation = Validatable::ValidatesPresenceOf.new :name
|
11
11
|
assert_equal true, validation.valid?(stub(:name=>"book"))
|
12
12
|
end
|
13
13
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
2
|
+
|
3
|
+
class ValidationBaseTest < Test::Unit::TestCase
|
4
|
+
expect true do
|
5
|
+
validation = Validatable::ValidationBase.new :base
|
6
|
+
validation.should_validate? Object.new
|
7
|
+
end
|
8
|
+
|
9
|
+
expect true do
|
10
|
+
validation = Validatable::ValidationBase.new :base, :times => 1
|
11
|
+
validation.validate_this_time?
|
12
|
+
end
|
13
|
+
|
14
|
+
expect true do
|
15
|
+
validation = Validatable::ValidationBase.new :base
|
16
|
+
validation.validate_this_time?
|
17
|
+
end
|
18
|
+
|
19
|
+
expect true do
|
20
|
+
validation = Validatable::ValidationBase.new :base, :times => 2
|
21
|
+
validation.validate_this_time?
|
22
|
+
validation.validate_this_time?
|
23
|
+
end
|
24
|
+
|
25
|
+
expect false do
|
26
|
+
validation = Validatable::ValidationBase.new :base, :times => 1
|
27
|
+
validation.validate_this_time?
|
28
|
+
validation.validate_this_time?
|
29
|
+
end
|
30
|
+
|
31
|
+
expect 1 do
|
32
|
+
validation = Validatable::ValidationBase.new :base
|
33
|
+
validation.level
|
34
|
+
end
|
35
|
+
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: validatable
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.
|
7
|
-
date: 2007-02-
|
6
|
+
version: 1.1.0
|
7
|
+
date: 2007-02-11 00:00:00 -05:00
|
8
8
|
summary: Validatable is a library for adding validations.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -31,22 +31,28 @@ files:
|
|
31
31
|
- lib/base.rb
|
32
32
|
- lib/errors.rb
|
33
33
|
- lib/validatable.rb
|
34
|
-
- lib/validates_acceptance_of.rb
|
35
|
-
- lib/validates_confirmation_of.rb
|
36
|
-
- lib/validates_format_of.rb
|
37
|
-
- lib/validates_length_of.rb
|
38
|
-
- lib/validates_presence_of.rb
|
39
|
-
- lib/validation_base.rb
|
34
|
+
- lib/validations/validates_acceptance_of.rb
|
35
|
+
- lib/validations/validates_confirmation_of.rb
|
36
|
+
- lib/validations/validates_format_of.rb
|
37
|
+
- lib/validations/validates_length_of.rb
|
38
|
+
- lib/validations/validates_presence_of.rb
|
39
|
+
- lib/validations/validation_base.rb
|
40
40
|
- test/all_tests.rb
|
41
|
-
- test/errors_test.rb
|
42
|
-
- test/functional_test.rb
|
43
41
|
- test/test_helper.rb
|
44
|
-
- test/validatable_test.rb
|
45
|
-
- test/validates_acceptance_of_test.rb
|
46
|
-
- test/validates_confirmation_of_test.rb
|
47
|
-
- test/validates_format_of_test.rb
|
48
|
-
- test/validates_length_of_test.rb
|
49
|
-
- test/validates_presence_of_test.rb
|
42
|
+
- test/functional/validatable_test.rb
|
43
|
+
- test/functional/validates_acceptance_of_test.rb
|
44
|
+
- test/functional/validates_confirmation_of_test.rb
|
45
|
+
- test/functional/validates_format_of_test.rb
|
46
|
+
- test/functional/validates_length_of_test.rb
|
47
|
+
- test/functional/validates_presence_of_test.rb
|
48
|
+
- test/unit/errors_test.rb
|
49
|
+
- test/unit/validatable_test.rb
|
50
|
+
- test/unit/validates_acceptance_of_test.rb
|
51
|
+
- test/unit/validates_confirmation_of_test.rb
|
52
|
+
- test/unit/validates_format_of_test.rb
|
53
|
+
- test/unit/validates_length_of_test.rb
|
54
|
+
- test/unit/validates_presence_of_test.rb
|
55
|
+
- test/unit/validation_base_test.rb
|
50
56
|
- rakefile.rb
|
51
57
|
- README
|
52
58
|
test_files:
|
data/lib/validates_format_of.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
module Validatable
|
2
|
-
class ValidatesFormatOf < ValidationBase #:nodoc:
|
3
|
-
attr_accessor :regex
|
4
|
-
def initialize(attribute, regex, message)
|
5
|
-
self.regex = regex
|
6
|
-
super attribute, message
|
7
|
-
end
|
8
|
-
|
9
|
-
def valid?(instance)
|
10
|
-
instance.send(self.attribute) =~ self.regex && true
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
data/lib/validation_base.rb
DELETED
data/test/errors_test.rb
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
2
|
-
|
3
|
-
class ErrorsTest < Test::Unit::TestCase
|
4
|
-
test "when an error is added, then it can be returned from on" do
|
5
|
-
errors = Validatable::Errors.new
|
6
|
-
errors.add(:attribute, "message")
|
7
|
-
assert_equal "message", errors.on(:attribute)
|
8
|
-
end
|
9
|
-
end
|
data/test/functional_test.rb
DELETED
@@ -1,80 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
2
|
-
|
3
|
-
class FunctionalTest < Test::Unit::TestCase
|
4
|
-
test "given no name, when validated, then error is in the objects error collection" do
|
5
|
-
klass = Class.new do
|
6
|
-
include Validatable
|
7
|
-
attr_accessor :name
|
8
|
-
validates_presence_of :name
|
9
|
-
end
|
10
|
-
instance = klass.new
|
11
|
-
instance.valid?
|
12
|
-
assert_equal "can't be empty", instance.errors.on(:name)
|
13
|
-
end
|
14
|
-
|
15
|
-
test "given invalid name format, when validated, then error is in the objects error collection" do
|
16
|
-
klass = Class.new do
|
17
|
-
include Validatable
|
18
|
-
attr_accessor :name
|
19
|
-
validates_format_of :name, :with => /.+/
|
20
|
-
end
|
21
|
-
instance = klass.new
|
22
|
-
instance.valid?
|
23
|
-
assert_equal "is invalid", instance.errors.on(:name)
|
24
|
-
end
|
25
|
-
|
26
|
-
test "given no acceptance, when validated, then error is in the objects error collection" do
|
27
|
-
klass = Class.new do
|
28
|
-
include Validatable
|
29
|
-
attr_accessor :name
|
30
|
-
validates_acceptance_of :name
|
31
|
-
end
|
32
|
-
instance = klass.new
|
33
|
-
instance.valid?
|
34
|
-
assert_equal "must be accepted", instance.errors.on(:name)
|
35
|
-
end
|
36
|
-
|
37
|
-
test "given non matching attributes, when validated, then error is in the objects error collection" do
|
38
|
-
klass = Class.new do
|
39
|
-
include Validatable
|
40
|
-
attr_accessor :name, :name_confirmation
|
41
|
-
validates_confirmation_of :name
|
42
|
-
end
|
43
|
-
instance = klass.new
|
44
|
-
instance.name = "foo"
|
45
|
-
instance.name_confirmation = "bar"
|
46
|
-
instance.valid?
|
47
|
-
assert_equal "doesn't match confirmation", instance.errors.on(:name)
|
48
|
-
end
|
49
|
-
|
50
|
-
test "given short value, when validated, then error is in the objects error collection" do
|
51
|
-
klass = Class.new do
|
52
|
-
include Validatable
|
53
|
-
attr_accessor :name
|
54
|
-
validates_length_of :name, :minimum => 2
|
55
|
-
end
|
56
|
-
instance = klass.new
|
57
|
-
instance.valid?
|
58
|
-
assert_equal "is invalid", instance.errors.on(:name)
|
59
|
-
end
|
60
|
-
|
61
|
-
test "given a child class with validations, when parent class is validated, then the error is in the parent objects error collection" do
|
62
|
-
child_class = Class.new do
|
63
|
-
include Validatable
|
64
|
-
attr_accessor :name, :address
|
65
|
-
validates_presence_of :name
|
66
|
-
validates_format_of :address, :with => /.+/
|
67
|
-
end
|
68
|
-
klass = Class.new do
|
69
|
-
include Validatable
|
70
|
-
include_validations_for :child
|
71
|
-
define_method :child do
|
72
|
-
child_class.new
|
73
|
-
end
|
74
|
-
end
|
75
|
-
instance = klass.new
|
76
|
-
instance.valid?
|
77
|
-
assert_equal "is invalid", instance.errors.on(:address)
|
78
|
-
assert_equal "can't be empty", instance.errors.on(:name)
|
79
|
-
end
|
80
|
-
end
|
data/test/validatable_test.rb
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
2
|
-
|
3
|
-
class ValidatableTest < Test::Unit::TestCase
|
4
|
-
test "given a validation that returns false when object is validated then valid returns false" do
|
5
|
-
validation = stub(:valid? => false, :attribute => "attribute", :message => "message")
|
6
|
-
klass = Class.new do
|
7
|
-
include Validatable
|
8
|
-
validations << validation
|
9
|
-
end
|
10
|
-
assert_equal false, klass.new.valid?
|
11
|
-
end
|
12
|
-
|
13
|
-
test "when validations are included for a child, then the list is maintained as an array of args" do
|
14
|
-
klass = Class.new do
|
15
|
-
include Validatable
|
16
|
-
include_validations_for :anything, :else
|
17
|
-
end
|
18
|
-
assert_equal [:anything, :else], klass.send(:children_to_validate)
|
19
|
-
end
|
20
|
-
|
21
|
-
test "when validate is executed, then messages are added for each validation that fails" do
|
22
|
-
klass = Class.new do
|
23
|
-
include Validatable
|
24
|
-
end
|
25
|
-
klass.send(:validations) << stub(:valid? => false, :attribute => 'attribute', :message => 'message')
|
26
|
-
klass.send(:validations) << stub(:valid? => false, :attribute => 'attribute2', :message => 'message2')
|
27
|
-
instance=mock
|
28
|
-
instance.expects(:errors).returns(errors=mock).times 2
|
29
|
-
errors.expects(:add).with('attribute', 'message')
|
30
|
-
errors.expects(:add).with('attribute2', 'message2')
|
31
|
-
klass.validate(instance)
|
32
|
-
end
|
33
|
-
|
34
|
-
test "when valid is called, then the errors collection is cleared and reinitialized" do
|
35
|
-
klass = Class.new do
|
36
|
-
include Validatable
|
37
|
-
end
|
38
|
-
instance = klass.new
|
39
|
-
instance.errors.add(:attribute, "message")
|
40
|
-
instance.valid?
|
41
|
-
assert_equal true, instance.errors.empty?
|
42
|
-
end
|
43
|
-
|
44
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
2
|
-
|
3
|
-
class ValidatesLengthOfTest < Test::Unit::TestCase
|
4
|
-
|
5
|
-
test "max length" do
|
6
|
-
validation = Validatable::ValidatesLengthOf.new(:username, nil, 8, :message)
|
7
|
-
instance = stub(:username=>"usernamefdfd")
|
8
|
-
assert_equal false, validation.valid?(instance)
|
9
|
-
end
|
10
|
-
|
11
|
-
test "min length" do
|
12
|
-
validation = Validatable::ValidatesLengthOf.new(:username, 2, nil, :message)
|
13
|
-
instance = stub(:username=>"u")
|
14
|
-
assert_equal false, validation.valid?(instance)
|
15
|
-
end
|
16
|
-
|
17
|
-
test "valid length" do
|
18
|
-
validation = Validatable::ValidatesLengthOf.new(:username, 2, 8, :message)
|
19
|
-
instance = stub(:username=>"udfgdf")
|
20
|
-
assert_equal true, validation.valid?(instance)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|