not_naughty 0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,5 @@
1
+ --colour
2
+ --backtrace
3
+ --format
4
+ specdoc
5
+ --diff
@@ -0,0 +1,7 @@
1
+ require File.dirname(__FILE__) + '/../lib/not_naughty.rb'
2
+
3
+ def subject() ::NotNaughty end
4
+ def h(something)
5
+ puts '<pre>%s</pre>' %
6
+ something.inspect.gsub(/[<>]/) {|m| (m == '<')? '&lt;': '&gt;'}
7
+ end
@@ -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