validatable 1.0.0 → 1.1.0
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 +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
|
-
|