not_naughty 0.3
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/CHANGELOG +22 -0
- data/COPYING +18 -0
- data/README +62 -0
- data/Rakefile +130 -0
- data/lib/not_naughty/builder.rb +68 -0
- data/lib/not_naughty/errors.rb +61 -0
- data/lib/not_naughty/instance_methods.rb +20 -0
- data/lib/not_naughty/validation.rb +126 -0
- data/lib/not_naughty/validations/acceptance_validation.rb +39 -0
- data/lib/not_naughty/validations/confirmation_validation.rb +41 -0
- data/lib/not_naughty/validations/format_validation.rb +45 -0
- data/lib/not_naughty/validations/length_validation.rb +95 -0
- data/lib/not_naughty/validations/numericality_validation.rb +43 -0
- data/lib/not_naughty/validations/presence_validation.rb +31 -0
- data/lib/not_naughty/validator.rb +119 -0
- data/lib/not_naughty.rb +85 -0
- data/lib/sequel_not_naughty.rb +106 -0
- data/spec/builder_spec.rb +69 -0
- data/spec/errors_spec.rb +61 -0
- data/spec/not_naughty_spec.rb +80 -0
- data/spec/rcov.opts +4 -0
- data/spec/sequel_spec_helper.rb +17 -0
- data/spec/sequel_validated_spec.rb +97 -0
- data/spec/spec.opts +5 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/validation_spec.rb +118 -0
- data/spec/validations_spec.rb +267 -0
- data/spec/validator_spec.rb +123 -0
- metadata +84 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
require 'sequel_not_naughty'
|
3
|
+
|
4
|
+
DB = Sequel::Model.db = Sequel.sqlite
|
5
|
+
|
6
|
+
Sequel::Model.instance_eval do
|
7
|
+
%w[validate valid?].
|
8
|
+
each {|m| undef_method m.to_sym}
|
9
|
+
end
|
10
|
+
|
11
|
+
(class << Sequel::Model; self; end).module_eval do
|
12
|
+
%w[validate validates validates_acceptance_of validates_confirmation_of
|
13
|
+
validates_each validates_format_of validates_length_of
|
14
|
+
validates_numericality_of validates_presence_of validations
|
15
|
+
has_validations?].
|
16
|
+
each {|m| undef_method m.to_sym}
|
17
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require "#{ File.dirname(__FILE__) }/sequel_spec_helper.rb"
|
2
|
+
|
3
|
+
describe Sequel::Plugins::NotNaughty do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@obj = Class.new(Sequel::Model) { is :not_naughty }
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should delegate validation methods in receiver" do
|
10
|
+
@instance = @obj.new
|
11
|
+
|
12
|
+
@obj.validator.should be_an_instance_of(Sequel::Plugins::NotNaughty)
|
13
|
+
@obj.validator.should_receive(:states).and_return({})
|
14
|
+
@obj.validator.should_receive(:has_validations?)
|
15
|
+
@obj.validator.should_receive(:invoke).with(@instance)
|
16
|
+
|
17
|
+
@instance.errors.should be_an_instance_of(subject::Errors)
|
18
|
+
@instance.should respond_to(:validate)
|
19
|
+
@instance.should respond_to(:valid?)
|
20
|
+
@instance.should respond_to(:save_without_validations)
|
21
|
+
|
22
|
+
@obj.validations
|
23
|
+
@obj.has_validations?
|
24
|
+
@obj.validate @instance
|
25
|
+
end
|
26
|
+
it "should return validations" do
|
27
|
+
@obj.validations.should be_an_instance_of(Hash)
|
28
|
+
end
|
29
|
+
it "should not have validations" do
|
30
|
+
@obj.has_validations?.should == false
|
31
|
+
end
|
32
|
+
it "should add_validation instance of validation" do
|
33
|
+
validation = Class.new(subject::Validation)
|
34
|
+
|
35
|
+
@obj.validator.add_validation validation, :attribute
|
36
|
+
|
37
|
+
validations = @obj.validator.states[:create][:attribute]
|
38
|
+
validations.length.should == 1
|
39
|
+
validations.first.should be_an_instance_of(validation)
|
40
|
+
|
41
|
+
validations = @obj.validator.states[:update][:attribute]
|
42
|
+
validations.length.should == 1
|
43
|
+
validations.first.should be_an_instance_of(validation)
|
44
|
+
|
45
|
+
@obj.validator.add_validation validation, :attribute, :on => :create
|
46
|
+
|
47
|
+
validations = @obj.validator.states[:create][:attribute]
|
48
|
+
validations.length.should == 2
|
49
|
+
validations[0].should be_an_instance_of(validation)
|
50
|
+
validations[1].should be_an_instance_of(validation)
|
51
|
+
|
52
|
+
validations = @obj.validator.states[:update][:attribute]
|
53
|
+
validations.length.should == 1
|
54
|
+
validations.first.should be_an_instance_of(validation)
|
55
|
+
end
|
56
|
+
it "should have validations" do
|
57
|
+
validation = Class.new(subject::Validation)
|
58
|
+
@obj.validator.add_validation validation, :attribute
|
59
|
+
|
60
|
+
@obj.has_validations?.should == true
|
61
|
+
end
|
62
|
+
it "should add_validation blocks as Validation" do
|
63
|
+
@obj.validator.add_validation(:attribute) { |o, a, v| }
|
64
|
+
|
65
|
+
@obj.validator.states[:create][:attribute].first.
|
66
|
+
should be_kind_of(subject::Validation)
|
67
|
+
@obj.validator.states[:update][:attribute].first.
|
68
|
+
should be_kind_of(subject::Validation)
|
69
|
+
end
|
70
|
+
it "should run validations on object when it's invoked" do
|
71
|
+
probe = mock 'Probe', :new? => true
|
72
|
+
probe.should_receive(:attribute).and_return(1)
|
73
|
+
probe.should_receive(:test).with(:attribute, 1)
|
74
|
+
|
75
|
+
@obj.validator.add_validation(:attribute) { |o, a, v| o.test a, v }
|
76
|
+
@obj.validate probe
|
77
|
+
end
|
78
|
+
it "should validate if saved" do
|
79
|
+
instance = @obj.new
|
80
|
+
instance.stub!(:save_without_validations).and_return(false)
|
81
|
+
@obj.validator.should_receive(:invoke).with(instance)
|
82
|
+
instance.save.should be_false
|
83
|
+
end
|
84
|
+
it "should run hooks if validated" do
|
85
|
+
instance = @obj.new
|
86
|
+
instance.should_receive(:before_validate)
|
87
|
+
instance.should_receive(:after_validate)
|
88
|
+
instance.validate
|
89
|
+
end
|
90
|
+
it "should not run hooks if validated" do
|
91
|
+
i = Class.new(Sequel::Model) { is :not_naughty, :without => :hooks }.new
|
92
|
+
i.should_not_receive(:before_validate)
|
93
|
+
i.should_not_receive(:after_validate)
|
94
|
+
i.validate
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
require "#{ File.dirname(__FILE__) }/spec_helper.rb"
|
2
|
+
|
3
|
+
describe subject::Validation do
|
4
|
+
|
5
|
+
it "should register validations if inherited" do
|
6
|
+
subject::Builder.
|
7
|
+
should_receive(:update).any_number_of_times.
|
8
|
+
with Class.new(subject::Validation)
|
9
|
+
pending 'This one kinda sucks...'
|
10
|
+
end
|
11
|
+
it "should build validations with block" do
|
12
|
+
block = proc {|o, a, v|}
|
13
|
+
validation = subject::Validation.new({}, &block)
|
14
|
+
|
15
|
+
validation.instance_variable_get(:@block).should == block
|
16
|
+
end
|
17
|
+
it "should alias call to call_without_conditions" do
|
18
|
+
validation = subject::Validation.new({}) {|o, a, v|}
|
19
|
+
|
20
|
+
validation.method(:call).
|
21
|
+
should == validation.method(:call_without_conditions)
|
22
|
+
end
|
23
|
+
it "should not build conditions" do
|
24
|
+
validation = subject::Validation.
|
25
|
+
new({:if => nil, :unless => nil}) {|o, a, v|}
|
26
|
+
|
27
|
+
validation.instance_variable_get(:@conditions).should be_empty
|
28
|
+
end
|
29
|
+
it "should build conditions" do
|
30
|
+
validation = subject::Validation.new({:if => :nil?}) {|o, a, v|}
|
31
|
+
validation.instance_variable_get(:@conditions).should_not be_empty
|
32
|
+
|
33
|
+
validation.instance_variable_get(:@conditions).
|
34
|
+
first.instance_variable_get(:@condition).
|
35
|
+
should == :nil?
|
36
|
+
end
|
37
|
+
it "should alias call to call_with_conditions" do
|
38
|
+
validation = subject::Validation.new({:if => :nil?}) {|o, a, v|}
|
39
|
+
|
40
|
+
validation.method(:call).
|
41
|
+
should == validation.method(:call_with_conditions)
|
42
|
+
end
|
43
|
+
it "should call" do
|
44
|
+
probe = mock 'Probe'
|
45
|
+
probe.should_receive(:test).exactly(3).times
|
46
|
+
|
47
|
+
validation = subject::Validation.
|
48
|
+
new({}) { |o, a, v| [o, a, v].each { |p| p.test } }
|
49
|
+
|
50
|
+
validation.call probe, probe, probe
|
51
|
+
end
|
52
|
+
it "should call unless a condition passes" do
|
53
|
+
probe = mock 'Probe'
|
54
|
+
probe.stub!(:nil?).and_return(true)
|
55
|
+
|
56
|
+
validation = subject::Validation.
|
57
|
+
new({:unless => :nil?}) { |o, a, v| [o, a, v].each { |p| p.test } }
|
58
|
+
|
59
|
+
validation.call probe, probe, probe
|
60
|
+
|
61
|
+
probe.should_receive(:test).exactly(3).times
|
62
|
+
probe.stub!(:nil?).and_return(false)
|
63
|
+
|
64
|
+
validation.call probe, probe, probe
|
65
|
+
end
|
66
|
+
it "should not call" do
|
67
|
+
probe = mock 'Probe'
|
68
|
+
probe.should_not_receive(:test)
|
69
|
+
|
70
|
+
validation = subject::Validation.
|
71
|
+
new({:if => :nil?}) { |o, a, v| [o, a, v].each { |p| p.test } }
|
72
|
+
|
73
|
+
validation.call probe, probe, probe
|
74
|
+
|
75
|
+
end
|
76
|
+
it "should have validated attributes accessable" do
|
77
|
+
validation = subject::Validation.new(:probe)
|
78
|
+
validation.attributes.should include(:probe)
|
79
|
+
end
|
80
|
+
it "should clone observer peers to descendant" do
|
81
|
+
peers = subject::Validation.instance_variable_get :@observer_peers
|
82
|
+
peers.should_receive(:clone).and_return(true)
|
83
|
+
descendant = Class.new(subject::Validation)
|
84
|
+
descendant.instance_variable_get(:@observer_peers).should be_true
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
describe subject::Validation::Condition do
|
90
|
+
|
91
|
+
it "should evaluate positive callable" do
|
92
|
+
condition = subject::Validation::Condition.new proc {|o| o.nil?}
|
93
|
+
condition.evaluate(nil).should be_true
|
94
|
+
end
|
95
|
+
it "should evaluate negative callable" do
|
96
|
+
condition = subject::Validation::Condition.new proc {|o| o.nil?}, false
|
97
|
+
condition.evaluate(nil).should be_false
|
98
|
+
end
|
99
|
+
it "should evaluate positive Symbol" do
|
100
|
+
condition = subject::Validation::Condition.new :nil?
|
101
|
+
condition.evaluate(nil).should be_true
|
102
|
+
end
|
103
|
+
it "should evaluate negative Symbol" do
|
104
|
+
condition = subject::Validation::Condition.new :nil?, false
|
105
|
+
condition.evaluate(nil).should be_false
|
106
|
+
end
|
107
|
+
it "should evaluate positive UnboundMethod" do
|
108
|
+
um = NilClass.instance_method :nil?
|
109
|
+
condition = subject::Validation::Condition.new um
|
110
|
+
condition.evaluate(nil).should be_true
|
111
|
+
end
|
112
|
+
it "should evaluate negative UnboundMethod" do
|
113
|
+
um = NilClass.instance_method :nil?
|
114
|
+
condition = subject::Validation::Condition.new um, false
|
115
|
+
condition.evaluate(nil).should be_false
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
@@ -0,0 +1,267 @@
|
|
1
|
+
require "#{ File.dirname(__FILE__) }/spec_helper.rb"
|
2
|
+
|
3
|
+
::NotNaughty::Validation.load(
|
4
|
+
:acceptance, :confirmation, :format,
|
5
|
+
:length, :numericality, :presence
|
6
|
+
)
|
7
|
+
|
8
|
+
describe subject::LengthValidation do
|
9
|
+
|
10
|
+
before(:each) { @receiver, @errors = mock('Receiver'), mock('Errors') }
|
11
|
+
|
12
|
+
it "should return the 'precise' block" do
|
13
|
+
validation = subject::LengthValidation.new :is => 8, :within => 10..12
|
14
|
+
|
15
|
+
probe = mock 'Probe', :length => 8, :nil? => false
|
16
|
+
validation.call @receiver, :probe, probe
|
17
|
+
|
18
|
+
@receiver.should_receive(:errors).and_return(@errors)
|
19
|
+
@errors.should_receive(:add).with(:probe, an_instance_of(String))
|
20
|
+
|
21
|
+
probe = mock 'Probe', :length => 11, :nil? => false
|
22
|
+
validation.call @receiver, :probe, probe
|
23
|
+
end
|
24
|
+
it "should return the 'range' block" do
|
25
|
+
validation = subject::LengthValidation.
|
26
|
+
new :within => 10..12, :maximum => 9
|
27
|
+
|
28
|
+
probe = mock 'Probe', :length => 10, :nil? => false
|
29
|
+
validation.call @receiver, :probe, probe
|
30
|
+
|
31
|
+
@receiver.should_receive(:errors).and_return(@errors)
|
32
|
+
@errors.should_receive(:add).with(:probe, an_instance_of(String))
|
33
|
+
|
34
|
+
probe = mock 'Probe', :length => 9, :nil? => false
|
35
|
+
validation.call @receiver, :probe, probe
|
36
|
+
end
|
37
|
+
it "should return the 'maximum' block" do
|
38
|
+
validation = subject::LengthValidation.
|
39
|
+
new :maximum => 9
|
40
|
+
|
41
|
+
probe = mock 'Probe', :length => 9, :nil? => false
|
42
|
+
validation.call @receiver, :probe, probe
|
43
|
+
|
44
|
+
@receiver.should_receive(:errors).and_return(@errors)
|
45
|
+
@errors.should_receive(:add).with(:probe, an_instance_of(String))
|
46
|
+
|
47
|
+
probe = mock 'Probe', :length => 10, :nil? => false
|
48
|
+
validation.call @receiver, :probe, probe
|
49
|
+
end
|
50
|
+
it "should return the 'minimum' block" do
|
51
|
+
validation = subject::LengthValidation.
|
52
|
+
new :minimum => 9
|
53
|
+
|
54
|
+
probe = mock 'Probe', :length => 9, :nil? => false
|
55
|
+
validation.call @receiver, :probe, probe
|
56
|
+
|
57
|
+
@receiver.should_receive(:errors).and_return(@errors)
|
58
|
+
@errors.should_receive(:add).with(:probe, an_instance_of(String))
|
59
|
+
|
60
|
+
probe = mock 'Probe', :length => 8, :nil? => false
|
61
|
+
validation.call @receiver, :probe, probe
|
62
|
+
end
|
63
|
+
it "should raise an ArgumentError" do
|
64
|
+
lambda { subject::LengthValidation.new }.
|
65
|
+
should raise_error(ArgumentError)
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
LengthExample = Struct.new(:name).extend(subject)
|
71
|
+
describe LengthExample do
|
72
|
+
|
73
|
+
before(:each) { @example = LengthExample.clone }
|
74
|
+
|
75
|
+
it "should always allow nil " do
|
76
|
+
@example.validates_length_of :name, :is => 1, :allow_nil => false
|
77
|
+
@example.new(nil).should be_valid
|
78
|
+
@example.new('').should_not be_valid
|
79
|
+
@example.new('a').should be_valid
|
80
|
+
@example.new('ab').should_not be_valid
|
81
|
+
end
|
82
|
+
it "should allow blank" do
|
83
|
+
@example.validates_length_of :name, :is => 1, :allow_blank => true
|
84
|
+
@example.new(nil).should be_valid
|
85
|
+
@example.new('').should be_valid
|
86
|
+
@example.new('a').should be_valid
|
87
|
+
@example.new('ab').should_not be_valid
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
FormatExample = Struct.new(:email).extend(subject)
|
93
|
+
describe FormatExample do
|
94
|
+
|
95
|
+
before(:each) { @example = FormatExample.clone }
|
96
|
+
|
97
|
+
it "claims to match 99% of all e-mail addresses out there..." do
|
98
|
+
# Regexp was taken from: http://www.regular-expressions.info/email.html
|
99
|
+
@example.validates_format_of :email,
|
100
|
+
:with => /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b/i
|
101
|
+
@example.new('"Foo Bar" <foo@bar.com>').should be_valid
|
102
|
+
@example.new('foo@bar.com').should be_valid
|
103
|
+
@example.new('foobarcom').should_not be_valid
|
104
|
+
@example.new(nil).should_not be_valid
|
105
|
+
@example.new('').should_not be_valid
|
106
|
+
end
|
107
|
+
it "should allow nil e-mail addresses" do
|
108
|
+
@example.validates_format_of :email, :allow_nil => true,
|
109
|
+
:with => /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b/i
|
110
|
+
@example.new('"Foo Bar" <foo@bar.com>').should be_valid
|
111
|
+
@example.new('foo@bar.com').should be_valid
|
112
|
+
@example.new('foobarcom').should_not be_valid
|
113
|
+
@example.new(nil).should be_valid
|
114
|
+
@example.new('').should_not be_valid
|
115
|
+
end
|
116
|
+
it "should allow blank e-mail addresses" do
|
117
|
+
@example.validates_format_of :email, :allow_blank => true,
|
118
|
+
:with => /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b/i
|
119
|
+
@example.new('"Foo Bar" <foo@bar.com>').should be_valid
|
120
|
+
@example.new('foo@bar.com').should be_valid
|
121
|
+
@example.new('foobarcom').should_not be_valid
|
122
|
+
@example.new(nil).should be_valid
|
123
|
+
@example.new('').should be_valid
|
124
|
+
end
|
125
|
+
it "should raise an ArgumentError if format does not respond to :match" do
|
126
|
+
lambda { @example.validates_format_of :email }.
|
127
|
+
should raise_error(ArgumentError)
|
128
|
+
lambda { @example.validates_format_of :email, :with => 1 }.
|
129
|
+
should raise_error(ArgumentError)
|
130
|
+
lambda { @example.validates_format_of :email, :with => '' }.
|
131
|
+
should_not raise_error(ArgumentError)
|
132
|
+
lambda { @example.validates_format_of :email, :with => // }.
|
133
|
+
should_not raise_error(ArgumentError)
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
PresenceExample = Struct.new(:name).extend(subject)
|
139
|
+
describe PresenceExample do
|
140
|
+
|
141
|
+
before(:each) { @example = PresenceExample.clone }
|
142
|
+
|
143
|
+
it "should be present" do
|
144
|
+
@example.validates_presence_of :name
|
145
|
+
@example.new(0).should be_valid
|
146
|
+
@example.new([0]).should be_valid
|
147
|
+
@example.new('0').should be_valid
|
148
|
+
end
|
149
|
+
it "should not be present" do
|
150
|
+
@example.validates_presence_of :name
|
151
|
+
@example.new(nil).should_not be_valid
|
152
|
+
@example.new([]).should_not be_valid
|
153
|
+
@example.new('').should_not be_valid
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
|
158
|
+
AcceptanceExample = Struct.new(:conditions).extend(subject)
|
159
|
+
describe AcceptanceExample do
|
160
|
+
|
161
|
+
before(:each) { @example = AcceptanceExample.clone }
|
162
|
+
|
163
|
+
it "should accept '1' and allows nil by default" do
|
164
|
+
@example.validates_acceptance_of :conditions
|
165
|
+
@example.new(nil).should be_valid
|
166
|
+
@example.new('').should_not be_valid
|
167
|
+
@example.new(true).should_not be_valid
|
168
|
+
@example.new(false).should_not be_valid
|
169
|
+
@example.new('0').should_not be_valid
|
170
|
+
@example.new('1').should be_valid
|
171
|
+
end
|
172
|
+
it "should accept true and allows nil by default" do
|
173
|
+
@example.validates_acceptance_of :conditions, :accept => true
|
174
|
+
@example.new(nil).should be_valid
|
175
|
+
@example.new('').should_not be_valid
|
176
|
+
@example.new(true).should be_valid
|
177
|
+
@example.new(false).should_not be_valid
|
178
|
+
@example.new('0').should_not be_valid
|
179
|
+
@example.new('1').should_not be_valid
|
180
|
+
end
|
181
|
+
it "should accept '1' and disallows nil" do
|
182
|
+
@example.validates_acceptance_of :conditions, :accept => true,
|
183
|
+
:allow_nil => false
|
184
|
+
|
185
|
+
@example.new(nil).should_not be_valid
|
186
|
+
@example.new('').should_not be_valid
|
187
|
+
@example.new(true).should be_valid
|
188
|
+
@example.new(false).should_not be_valid
|
189
|
+
@example.new('0').should_not be_valid
|
190
|
+
@example.new('1').should_not be_valid
|
191
|
+
end
|
192
|
+
it "should accept '1' and allow blank" do
|
193
|
+
@example.validates_acceptance_of :conditions, :accept => true,
|
194
|
+
:allow_blank => true
|
195
|
+
|
196
|
+
@example.new(nil).should be_valid
|
197
|
+
@example.new('').should be_valid
|
198
|
+
@example.new(true).should be_valid
|
199
|
+
@example.new(false).should be_valid
|
200
|
+
@example.new('0').should_not be_valid
|
201
|
+
@example.new('1').should_not be_valid
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
205
|
+
|
206
|
+
ConfirmationExample = Struct.new(:name, :name_confirmation).extend(subject)
|
207
|
+
describe ConfirmationExample do
|
208
|
+
|
209
|
+
before(:each) { @example = ConfirmationExample.clone }
|
210
|
+
|
211
|
+
it "should be confirmed without allowing neither :nil nor :blank" do
|
212
|
+
@example.validates_confirmation_of :name
|
213
|
+
|
214
|
+
@example.new(nil, 'foo').should_not be_valid
|
215
|
+
@example.new('', 'foo').should_not be_valid
|
216
|
+
|
217
|
+
@example.new('foo', 'foo').should be_valid
|
218
|
+
@example.new('foo', 'bar').should_not be_valid
|
219
|
+
end
|
220
|
+
it "should be confirmed with allowing :nil" do
|
221
|
+
@example.validates_confirmation_of :name, :allow_nil => true
|
222
|
+
|
223
|
+
@example.new(nil, 'foo').should be_valid
|
224
|
+
@example.new('', 'foo').should_not be_valid
|
225
|
+
|
226
|
+
@example.new('foo', 'foo').should be_valid
|
227
|
+
@example.new('foo', 'bar').should_not be_valid
|
228
|
+
end
|
229
|
+
it "should be confirmed with allowing :blank" do
|
230
|
+
@example.validates_confirmation_of :name, :allow_blank => true
|
231
|
+
|
232
|
+
@example.new(nil, 'foo').should be_valid
|
233
|
+
@example.new('', 'foo').should be_valid
|
234
|
+
|
235
|
+
@example.new('foo', 'foo').should be_valid
|
236
|
+
@example.new('foo', 'bar').should_not be_valid
|
237
|
+
end
|
238
|
+
|
239
|
+
end
|
240
|
+
|
241
|
+
NumericalityExample = Struct.new(:weight).extend(subject)
|
242
|
+
describe NumericalityExample do
|
243
|
+
|
244
|
+
before(:each) { @example = NumericalityExample.clone }
|
245
|
+
|
246
|
+
it "should be matched with number pattern" do
|
247
|
+
@example.validates_numericality_of :weight
|
248
|
+
|
249
|
+
@example.new('-123.56').should be_valid
|
250
|
+
|
251
|
+
@example.new('+123').should be_valid
|
252
|
+
@example.new('-123').should be_valid
|
253
|
+
@example.new('123').should be_valid
|
254
|
+
@example.new('abc').should_not be_valid
|
255
|
+
end
|
256
|
+
it "should be matched with integer pattern" do
|
257
|
+
@example.validates_numericality_of :weight, :only_integer => true
|
258
|
+
|
259
|
+
@example.new('-123.45').should_not be_valid
|
260
|
+
|
261
|
+
@example.new('+123').should be_valid
|
262
|
+
@example.new('-123').should be_valid
|
263
|
+
@example.new('123').should be_valid
|
264
|
+
@example.new('abc').should_not be_valid
|
265
|
+
end
|
266
|
+
|
267
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require "#{ File.dirname(__FILE__) }/spec_helper.rb"
|
2
|
+
|
3
|
+
describe subject::Validator, 'with default state' do
|
4
|
+
|
5
|
+
before(:each) { @validator = subject::Validator.new }
|
6
|
+
|
7
|
+
it "should have atleast the default state" do
|
8
|
+
@validator.instance_variable_get(:@states).keys.should include(:default)
|
9
|
+
end
|
10
|
+
it "should shoult return default state" do
|
11
|
+
@validator.get_state(nil).name.should == :default
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
describe NotNaughty::Validator, 'with custom states' do
|
17
|
+
|
18
|
+
before(:each) do
|
19
|
+
@states = [:create, :update]
|
20
|
+
@validator = subject::Validator.new(*@states)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should assign states dynamically" do
|
24
|
+
@validator.states.keys.should include(*@states)
|
25
|
+
end
|
26
|
+
it "should have an initial state" do
|
27
|
+
@validator.instance_variable_get(:@initial_state).name.
|
28
|
+
should == @states[0]
|
29
|
+
end
|
30
|
+
it "should add validations to all states" do
|
31
|
+
@validator.add_validation :firstname, :lastname
|
32
|
+
|
33
|
+
@validator.states.each do |name, state|
|
34
|
+
state.validations.should include(:firstname, :lastname)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
it "should add validations to :create state" do
|
38
|
+
@validator.add_validation :firstname, :lastname, :on => :create
|
39
|
+
|
40
|
+
@validator.states[:create].validations.keys.
|
41
|
+
should include(:firstname, :lastname)
|
42
|
+
@validator.states[:update].validations.keys.
|
43
|
+
should_not include(:firstname, :lastname)
|
44
|
+
end
|
45
|
+
it "should add validations to :create and :update states" do
|
46
|
+
@validator.add_validation :firstname, :lastname, :on => [:create, :update]
|
47
|
+
|
48
|
+
@validator.states.each do |name, state|
|
49
|
+
state.validations.should include(:firstname, :lastname)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
it "should return initial state" do
|
53
|
+
@validator.get_state(nil).name.should == :create
|
54
|
+
end
|
55
|
+
it "should not have validations" do
|
56
|
+
@validator.should_not have_validations
|
57
|
+
end
|
58
|
+
it "should have validations" do
|
59
|
+
@validator.add_validation :firstname, :lastname
|
60
|
+
@validator.should have_validations
|
61
|
+
end
|
62
|
+
it "should have validations on initial state" do
|
63
|
+
@validator.add_validation :firstname, :lastname, :on => :create
|
64
|
+
@validator.should have_validations('')
|
65
|
+
end
|
66
|
+
it "should not have validations on initial state" do
|
67
|
+
@validator.add_validation :firstname, :lastname, :on => :update
|
68
|
+
@validator.should_not have_validations('')
|
69
|
+
end
|
70
|
+
it "should send! attributes to probe if invoked" do
|
71
|
+
block = proc {|o, a, v|}
|
72
|
+
|
73
|
+
probe = mock 'Probe'
|
74
|
+
probe.should_receive(:send!).with(:firstname)
|
75
|
+
probe.should_receive(:send!).with(:lastname)
|
76
|
+
|
77
|
+
@validator.add_validation :firstname, :lastname, &block
|
78
|
+
@validator.invoke probe
|
79
|
+
end
|
80
|
+
it "should call validations with object, attribute and value if invoked" do
|
81
|
+
block = proc {|o, a, v|}
|
82
|
+
|
83
|
+
probe = mock 'Probe'
|
84
|
+
value = mock 'Value'
|
85
|
+
probe.stub!(:send!).and_return(value)
|
86
|
+
|
87
|
+
@validator.add_validation :firstname, :lastname, &block
|
88
|
+
@validator.get_state.validations
|
89
|
+
@validator.invoke probe
|
90
|
+
end
|
91
|
+
it "should clone states as well" do
|
92
|
+
validator_clone = @validator.clone
|
93
|
+
validator_clone.states.length == @validator.states.length
|
94
|
+
validator_clone.states.should_not != @validator.states
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
describe NotNaughty::Validator::State do
|
100
|
+
|
101
|
+
before(:each) { @state = NotNaughty::Validator::State.new }
|
102
|
+
|
103
|
+
it "should initialize with name and validations" do
|
104
|
+
@state.name.should == :default
|
105
|
+
@state.validations.should be_an_instance_of(Hash)
|
106
|
+
|
107
|
+
@state = NotNaughty::Validator::State.new :foo
|
108
|
+
@state.name.should == :foo
|
109
|
+
end
|
110
|
+
it "should add validation" do
|
111
|
+
@state.add_validation(:firstname, :lastname, :on => :default) {|o, a, v|}
|
112
|
+
@state.validations.keys.should include(:firstname, :lastname)
|
113
|
+
end
|
114
|
+
it "should return validation for an attribute" do
|
115
|
+
@state.validations[:foo] = :bar
|
116
|
+
@state[:foo].should == :bar
|
117
|
+
end
|
118
|
+
it "should have validations" do
|
119
|
+
@state.validations[:foo] = [:bar]
|
120
|
+
@state.should have_validations
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|