openlogic-couchrest_model 1.0.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/.gitignore +11 -0
- data/.rspec +4 -0
- data/Gemfile +4 -0
- data/LICENSE +176 -0
- data/README.md +137 -0
- data/Rakefile +38 -0
- data/THANKS.md +21 -0
- data/VERSION +1 -0
- data/benchmarks/dirty.rb +118 -0
- data/couchrest_model.gemspec +36 -0
- data/history.md +309 -0
- data/init.rb +1 -0
- data/lib/couchrest/model.rb +10 -0
- data/lib/couchrest/model/associations.rb +231 -0
- data/lib/couchrest/model/base.rb +129 -0
- data/lib/couchrest/model/callbacks.rb +28 -0
- data/lib/couchrest/model/casted_array.rb +83 -0
- data/lib/couchrest/model/casted_by.rb +33 -0
- data/lib/couchrest/model/casted_hash.rb +84 -0
- data/lib/couchrest/model/class_proxy.rb +135 -0
- data/lib/couchrest/model/collection.rb +273 -0
- data/lib/couchrest/model/configuration.rb +67 -0
- data/lib/couchrest/model/connection.rb +70 -0
- data/lib/couchrest/model/core_extensions/hash.rb +9 -0
- data/lib/couchrest/model/core_extensions/time_parsing.rb +66 -0
- data/lib/couchrest/model/design_doc.rb +128 -0
- data/lib/couchrest/model/designs.rb +91 -0
- data/lib/couchrest/model/designs/view.rb +513 -0
- data/lib/couchrest/model/dirty.rb +39 -0
- data/lib/couchrest/model/document_queries.rb +99 -0
- data/lib/couchrest/model/embeddable.rb +78 -0
- data/lib/couchrest/model/errors.rb +25 -0
- data/lib/couchrest/model/extended_attachments.rb +83 -0
- data/lib/couchrest/model/persistence.rb +178 -0
- data/lib/couchrest/model/properties.rb +228 -0
- data/lib/couchrest/model/property.rb +114 -0
- data/lib/couchrest/model/property_protection.rb +71 -0
- data/lib/couchrest/model/proxyable.rb +183 -0
- data/lib/couchrest/model/support/couchrest_database.rb +13 -0
- data/lib/couchrest/model/support/couchrest_design.rb +33 -0
- data/lib/couchrest/model/typecast.rb +154 -0
- data/lib/couchrest/model/validations.rb +80 -0
- data/lib/couchrest/model/validations/casted_model.rb +16 -0
- data/lib/couchrest/model/validations/locale/en.yml +5 -0
- data/lib/couchrest/model/validations/uniqueness.rb +69 -0
- data/lib/couchrest/model/views.rb +151 -0
- data/lib/couchrest/railtie.rb +24 -0
- data/lib/couchrest_model.rb +66 -0
- data/lib/rails/generators/couchrest_model.rb +16 -0
- data/lib/rails/generators/couchrest_model/config/config_generator.rb +18 -0
- data/lib/rails/generators/couchrest_model/config/templates/couchdb.yml +21 -0
- data/lib/rails/generators/couchrest_model/model/model_generator.rb +27 -0
- data/lib/rails/generators/couchrest_model/model/templates/model.rb +2 -0
- data/spec/.gitignore +1 -0
- data/spec/fixtures/attachments/README +3 -0
- data/spec/fixtures/attachments/couchdb.png +0 -0
- data/spec/fixtures/attachments/test.html +11 -0
- data/spec/fixtures/config/couchdb.yml +10 -0
- data/spec/fixtures/models/article.rb +36 -0
- data/spec/fixtures/models/base.rb +164 -0
- data/spec/fixtures/models/card.rb +19 -0
- data/spec/fixtures/models/cat.rb +23 -0
- data/spec/fixtures/models/client.rb +6 -0
- data/spec/fixtures/models/course.rb +27 -0
- data/spec/fixtures/models/event.rb +8 -0
- data/spec/fixtures/models/invoice.rb +14 -0
- data/spec/fixtures/models/key_chain.rb +5 -0
- data/spec/fixtures/models/membership.rb +4 -0
- data/spec/fixtures/models/person.rb +11 -0
- data/spec/fixtures/models/project.rb +6 -0
- data/spec/fixtures/models/question.rb +7 -0
- data/spec/fixtures/models/sale_entry.rb +9 -0
- data/spec/fixtures/models/sale_invoice.rb +14 -0
- data/spec/fixtures/models/service.rb +10 -0
- data/spec/fixtures/models/user.rb +22 -0
- data/spec/fixtures/views/lib.js +3 -0
- data/spec/fixtures/views/test_view/lib.js +3 -0
- data/spec/fixtures/views/test_view/only-map.js +4 -0
- data/spec/fixtures/views/test_view/test-map.js +3 -0
- data/spec/fixtures/views/test_view/test-reduce.js +3 -0
- data/spec/functional/validations_spec.rb +8 -0
- data/spec/spec_helper.rb +60 -0
- data/spec/unit/active_model_lint_spec.rb +30 -0
- data/spec/unit/assocations_spec.rb +242 -0
- data/spec/unit/attachment_spec.rb +176 -0
- data/spec/unit/base_spec.rb +537 -0
- data/spec/unit/casted_spec.rb +72 -0
- data/spec/unit/class_proxy_spec.rb +167 -0
- data/spec/unit/collection_spec.rb +86 -0
- data/spec/unit/configuration_spec.rb +77 -0
- data/spec/unit/connection_spec.rb +148 -0
- data/spec/unit/core_extensions/time_parsing.rb +77 -0
- data/spec/unit/design_doc_spec.rb +241 -0
- data/spec/unit/designs/view_spec.rb +831 -0
- data/spec/unit/designs_spec.rb +134 -0
- data/spec/unit/dirty_spec.rb +436 -0
- data/spec/unit/embeddable_spec.rb +498 -0
- data/spec/unit/inherited_spec.rb +33 -0
- data/spec/unit/persistence_spec.rb +481 -0
- data/spec/unit/property_protection_spec.rb +192 -0
- data/spec/unit/property_spec.rb +481 -0
- data/spec/unit/proxyable_spec.rb +376 -0
- data/spec/unit/subclass_spec.rb +85 -0
- data/spec/unit/typecast_spec.rb +521 -0
- data/spec/unit/validations_spec.rb +140 -0
- data/spec/unit/view_spec.rb +367 -0
- metadata +301 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
class PlainParent
|
|
4
|
+
class_inheritable_accessor :foo
|
|
5
|
+
self.foo = :bar
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
class PlainChild < PlainParent
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class ExtendedParent < CouchRest::Model::Base
|
|
12
|
+
class_inheritable_accessor :foo
|
|
13
|
+
self.foo = :bar
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
class ExtendedChild < ExtendedParent
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe "Using chained inheritance without CouchRest::Model::Base" do
|
|
20
|
+
it "should preserve inheritable attributes" do
|
|
21
|
+
PlainParent.foo.should == :bar
|
|
22
|
+
PlainChild.foo.should == :bar
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe "Using chained inheritance with CouchRest::Model::Base" do
|
|
27
|
+
it "should preserve inheritable attributes" do
|
|
28
|
+
ExtendedParent.foo.should == :bar
|
|
29
|
+
ExtendedChild.foo.should == :bar
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
|
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
describe CouchRest::Model::Persistence do
|
|
5
|
+
|
|
6
|
+
before(:each) do
|
|
7
|
+
@obj = WithDefaultValues.new
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
describe "creating a new document from database" do
|
|
11
|
+
|
|
12
|
+
it "should instantialize" do
|
|
13
|
+
doc = Article.build_from_database({'_id' => 'testitem1', '_rev' => 123, 'couchrest-type' => 'Article', 'name' => 'my test'})
|
|
14
|
+
doc.class.should eql(Article)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "should instantialize of same class if no couchrest-type included from DB" do
|
|
18
|
+
doc = Article.build_from_database({'_id' => 'testitem1', '_rev' => 123, 'name' => 'my test'})
|
|
19
|
+
doc.class.should eql(Article)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "should instantialize document of different type" do
|
|
23
|
+
doc = Article.build_from_database({'_id' => 'testitem2', '_rev' => 123, Article.model_type_key => 'WithTemplateAndUniqueID', 'name' => 'my test'})
|
|
24
|
+
doc.class.should eql(WithTemplateAndUniqueID)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
describe "basic saving and retrieving" do
|
|
30
|
+
it "should work fine" do
|
|
31
|
+
@obj.name = "should be easily saved and retrieved"
|
|
32
|
+
@obj.save!
|
|
33
|
+
saved_obj = WithDefaultValues.get!(@obj.id)
|
|
34
|
+
saved_obj.should_not be_nil
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "should parse the Time attributes automatically" do
|
|
38
|
+
@obj.name = "should parse the Time attributes automatically"
|
|
39
|
+
@obj.set_by_proc.should be_an_instance_of(Time)
|
|
40
|
+
@obj.save
|
|
41
|
+
@obj.set_by_proc.should be_an_instance_of(Time)
|
|
42
|
+
saved_obj = WithDefaultValues.get(@obj.id)
|
|
43
|
+
saved_obj.set_by_proc.should be_an_instance_of(Time)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
describe "creating a model" do
|
|
48
|
+
|
|
49
|
+
before(:each) do
|
|
50
|
+
@sobj = Basic.new
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it "should accept true or false on save for validation" do
|
|
54
|
+
@sobj.should_receive(:valid?)
|
|
55
|
+
@sobj.save(true)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "should accept hash with validation option" do
|
|
59
|
+
@sobj.should_receive(:valid?)
|
|
60
|
+
@sobj.save(:validate => true)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "should not call validation when option is false" do
|
|
64
|
+
@sobj.should_not_receive(:valid?)
|
|
65
|
+
@sobj.save(false)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "should not call validation when option :validate is false" do
|
|
69
|
+
@sobj.should_not_receive(:valid?)
|
|
70
|
+
@sobj.save(:validate => false)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it "should instantialize and save a document" do
|
|
74
|
+
article = Article.create(:title => 'my test')
|
|
75
|
+
article.title.should == 'my test'
|
|
76
|
+
article.should_not be_new
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it "yields new instance to block before saving (#create)" do
|
|
80
|
+
article = Article.create{|a| a.title = 'my create init block test'}
|
|
81
|
+
article.title.should == 'my create init block test'
|
|
82
|
+
article.should_not be_new
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it "yields new instance to block before saving (#create!)" do
|
|
86
|
+
article = Article.create{|a| a.title = 'my create bang init block test'}
|
|
87
|
+
article.title.should == 'my create bang init block test'
|
|
88
|
+
article.should_not be_new
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it "should trigger the create callbacks" do
|
|
92
|
+
doc = WithCallBacks.create(:name => 'my other test')
|
|
93
|
+
doc.run_before_create.should be_true
|
|
94
|
+
doc.run_after_create.should be_true
|
|
95
|
+
doc.run_before_save.should be_true
|
|
96
|
+
doc.run_after_save.should be_true
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
describe "saving a model" do
|
|
102
|
+
before(:all) do
|
|
103
|
+
@sobj = Basic.new
|
|
104
|
+
@sobj.save.should be_true
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "should save the doc" do
|
|
108
|
+
doc = Basic.get(@sobj.id)
|
|
109
|
+
doc['_id'].should == @sobj.id
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
it "should be set for resaving" do
|
|
113
|
+
rev = @obj.rev
|
|
114
|
+
@sobj['another-key'] = "some value"
|
|
115
|
+
@sobj.save
|
|
116
|
+
@sobj.rev.should_not == rev
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "should set the id" do
|
|
120
|
+
@sobj.id.should be_an_instance_of(String)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "should set the type" do
|
|
124
|
+
@sobj[@sobj.model_type_key].should == 'Basic'
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
it "should accept true or false on save for validation" do
|
|
128
|
+
@sobj.should_receive(:valid?)
|
|
129
|
+
@sobj.save(true)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
it "should accept hash with validation option" do
|
|
133
|
+
@sobj.should_receive(:valid?)
|
|
134
|
+
@sobj.save(:validate => true)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it "should not call validation when option is false" do
|
|
138
|
+
@sobj.should_not_receive(:valid?)
|
|
139
|
+
@sobj.save(false)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
it "should not call validation when option :validate is false" do
|
|
143
|
+
@sobj.should_not_receive(:valid?)
|
|
144
|
+
@sobj.save(:validate => false)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
describe "save!" do
|
|
148
|
+
|
|
149
|
+
before(:each) do
|
|
150
|
+
@sobj = Card.new(:first_name => "Marcos", :last_name => "Tapajós")
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
it "should return true if save the document" do
|
|
154
|
+
@sobj.save!.should be_true
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
it "should raise error if don't save the document" do
|
|
158
|
+
@sobj.first_name = nil
|
|
159
|
+
lambda { @sobj.save! }.should raise_error(CouchRest::Model::Errors::Validations)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
describe "saving a model with a unique_id configured" do
|
|
166
|
+
before(:each) do
|
|
167
|
+
@art = Article.new
|
|
168
|
+
@old = Article.database.get('this-is-the-title') rescue nil
|
|
169
|
+
Article.database.delete_doc(@old) if @old
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
it "should be a new document" do
|
|
173
|
+
@art.should be_new
|
|
174
|
+
@art.title.should be_nil
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
it "should require the title" do
|
|
178
|
+
lambda{@art.save}.should raise_error
|
|
179
|
+
@art.title = 'This is the title'
|
|
180
|
+
@art.save.should be_true
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
it "should not change the slug on update" do
|
|
184
|
+
@art.title = 'This is the title'
|
|
185
|
+
@art.save.should be_true
|
|
186
|
+
@art.title = 'new title'
|
|
187
|
+
@art.save.should be_true
|
|
188
|
+
@art.slug.should == 'this-is-the-title'
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
it "should raise an error when the slug is taken" do
|
|
192
|
+
@art.title = 'This is the title'
|
|
193
|
+
@art.save.should be_true
|
|
194
|
+
@art2 = Article.new(:title => 'This is the title!')
|
|
195
|
+
lambda{@art2.save}.should raise_error
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
it "should set the slug" do
|
|
199
|
+
@art.title = 'This is the title'
|
|
200
|
+
@art.save.should be_true
|
|
201
|
+
@art.slug.should == 'this-is-the-title'
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
it "should set the id" do
|
|
205
|
+
@art.title = 'This is the title'
|
|
206
|
+
@art.save.should be_true
|
|
207
|
+
@art.id.should == 'this-is-the-title'
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
describe "saving a model with a unique_id lambda" do
|
|
212
|
+
before(:each) do
|
|
213
|
+
@templated = WithTemplateAndUniqueID.new
|
|
214
|
+
@old = WithTemplateAndUniqueID.get('very-important') rescue nil
|
|
215
|
+
@old.destroy if @old
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
it "should require the field" do
|
|
219
|
+
lambda{@templated.save}.should raise_error
|
|
220
|
+
@templated['slug'] = 'very-important'
|
|
221
|
+
@templated.save.should be_true
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
it "should save with the id" do
|
|
225
|
+
@templated['slug'] = 'very-important'
|
|
226
|
+
@templated.save.should be_true
|
|
227
|
+
t = WithTemplateAndUniqueID.get('very-important')
|
|
228
|
+
t.should == @templated
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
it "should not change the id on update" do
|
|
232
|
+
@templated['slug'] = 'very-important'
|
|
233
|
+
@templated.save.should be_true
|
|
234
|
+
@templated['slug'] = 'not-important'
|
|
235
|
+
@templated.save.should be_true
|
|
236
|
+
t = WithTemplateAndUniqueID.get('very-important')
|
|
237
|
+
t.id.should == @templated.id
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
it "should raise an error when the id is taken" do
|
|
241
|
+
@templated['slug'] = 'very-important'
|
|
242
|
+
@templated.save.should be_true
|
|
243
|
+
lambda{WithTemplateAndUniqueID.new('slug' => 'very-important').save}.should raise_error
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
it "should set the id" do
|
|
247
|
+
@templated['slug'] = 'very-important'
|
|
248
|
+
@templated.save.should be_true
|
|
249
|
+
@templated.id.should == 'very-important'
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
describe "destroying an instance" do
|
|
254
|
+
before(:each) do
|
|
255
|
+
@dobj = Event.new
|
|
256
|
+
@dobj.save.should be_true
|
|
257
|
+
end
|
|
258
|
+
it "should return true" do
|
|
259
|
+
result = @dobj.destroy
|
|
260
|
+
result.should be_true
|
|
261
|
+
end
|
|
262
|
+
it "should make it go away" do
|
|
263
|
+
@dobj.destroy
|
|
264
|
+
lambda{Basic.get!(@dobj.id)}.should raise_error(CouchRest::Model::DocumentNotFound)
|
|
265
|
+
end
|
|
266
|
+
it "should freeze the object" do
|
|
267
|
+
@dobj.destroy
|
|
268
|
+
# In Ruby 1.9.2 this raises RuntimeError, in 1.8.7 TypeError, D'OH!
|
|
269
|
+
lambda { @dobj.subject = "Test" }.should raise_error(StandardError)
|
|
270
|
+
end
|
|
271
|
+
it "trying to save after should fail" do
|
|
272
|
+
@dobj.destroy
|
|
273
|
+
lambda { @dobj.save }.should raise_error(StandardError)
|
|
274
|
+
lambda{Basic.get!(@dobj.id)}.should raise_error(CouchRest::Model::DocumentNotFound)
|
|
275
|
+
end
|
|
276
|
+
it "should make destroyed? true" do
|
|
277
|
+
@dobj.destroyed?.should be_false
|
|
278
|
+
@dobj.destroy
|
|
279
|
+
@dobj.destroyed?.should be_true
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
describe "getting a model" do
|
|
285
|
+
before(:all) do
|
|
286
|
+
@art = Article.new(:title => 'All About Getting')
|
|
287
|
+
@art.save
|
|
288
|
+
end
|
|
289
|
+
it "should load and instantiate it" do
|
|
290
|
+
foundart = Article.get @art.id
|
|
291
|
+
foundart.title.should == "All About Getting"
|
|
292
|
+
end
|
|
293
|
+
it "should load and instantiate with find" do
|
|
294
|
+
foundart = Article.find @art.id
|
|
295
|
+
foundart.title.should == "All About Getting"
|
|
296
|
+
end
|
|
297
|
+
it "should return nil if `get` is used and the document doesn't exist" do
|
|
298
|
+
foundart = Article.get 'matt aimonetti'
|
|
299
|
+
foundart.should be_nil
|
|
300
|
+
end
|
|
301
|
+
it "should return nil if a blank id is requested" do
|
|
302
|
+
Article.get("").should be_nil
|
|
303
|
+
end
|
|
304
|
+
it "should raise an error if `get!` is used and the document doesn't exist" do
|
|
305
|
+
expect{ Article.get!('matt aimonetti') }.to raise_error
|
|
306
|
+
end
|
|
307
|
+
it "should raise an error if `get!` is requested with a blank id" do
|
|
308
|
+
expect{ Article.get!("") }.to raise_error
|
|
309
|
+
end
|
|
310
|
+
it "should raise an error if `find!` is used and the document doesn't exist" do
|
|
311
|
+
expect{ Article.find!('matt aimonetti') }.to raise_error
|
|
312
|
+
end
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
describe "getting a model with a subobjects array" do
|
|
316
|
+
before(:all) do
|
|
317
|
+
course_doc = {
|
|
318
|
+
"title" => "Metaphysics 200",
|
|
319
|
+
"questions" => [
|
|
320
|
+
{
|
|
321
|
+
"q" => "Carve the ___ of reality at the ___.",
|
|
322
|
+
"a" => ["beast","joints"]
|
|
323
|
+
},{
|
|
324
|
+
"q" => "Who layed the smack down on Leibniz's Law?",
|
|
325
|
+
"a" => "Willard Van Orman Quine"
|
|
326
|
+
}
|
|
327
|
+
]
|
|
328
|
+
}
|
|
329
|
+
r = Course.database.save_doc course_doc
|
|
330
|
+
@course = Course.get r['id']
|
|
331
|
+
end
|
|
332
|
+
it "should load the course" do
|
|
333
|
+
@course.title.should == "Metaphysics 200"
|
|
334
|
+
end
|
|
335
|
+
it "should instantiate them as such" do
|
|
336
|
+
@course["questions"][0].a[0].should == "beast"
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
describe "callbacks" do
|
|
341
|
+
|
|
342
|
+
before(:each) do
|
|
343
|
+
@doc = WithCallBacks.new
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
describe "validation" do
|
|
347
|
+
it "should run before_validation before validating" do
|
|
348
|
+
@doc.run_before_validation.should be_nil
|
|
349
|
+
@doc.should be_valid
|
|
350
|
+
@doc.run_before_validation.should be_true
|
|
351
|
+
end
|
|
352
|
+
it "should run after_validation after validating" do
|
|
353
|
+
@doc.run_after_validation.should be_nil
|
|
354
|
+
@doc.should be_valid
|
|
355
|
+
@doc.run_after_validation.should be_true
|
|
356
|
+
end
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
describe "with contextual validation on ”create”" do
|
|
360
|
+
it "should validate only within ”create” context" do
|
|
361
|
+
doc = WithContextualValidationOnCreate.new
|
|
362
|
+
doc.save.should be_false
|
|
363
|
+
doc.name = "Alice"
|
|
364
|
+
doc.save.should be_true
|
|
365
|
+
|
|
366
|
+
doc.update_attributes(:name => nil).should be_true
|
|
367
|
+
end
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
describe "with contextual validation on ”update”" do
|
|
371
|
+
it "should validate only within ”update” context" do
|
|
372
|
+
doc = WithContextualValidationOnUpdate.new
|
|
373
|
+
doc.save.should be_true
|
|
374
|
+
|
|
375
|
+
doc.update_attributes(:name => nil).should be_false
|
|
376
|
+
doc.update_attributes(:name => "Bob").should be_true
|
|
377
|
+
end
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
describe "save" do
|
|
381
|
+
it "should run the after filter after saving" do
|
|
382
|
+
@doc.run_after_save.should be_nil
|
|
383
|
+
@doc.save.should be_true
|
|
384
|
+
@doc.run_after_save.should be_true
|
|
385
|
+
end
|
|
386
|
+
it "should run the grouped callbacks before saving" do
|
|
387
|
+
@doc.run_one.should be_nil
|
|
388
|
+
@doc.run_two.should be_nil
|
|
389
|
+
@doc.run_three.should be_nil
|
|
390
|
+
@doc.save.should be_true
|
|
391
|
+
@doc.run_one.should be_true
|
|
392
|
+
@doc.run_two.should be_true
|
|
393
|
+
@doc.run_three.should be_true
|
|
394
|
+
end
|
|
395
|
+
it "should not run conditional callbacks" do
|
|
396
|
+
@doc.run_it = false
|
|
397
|
+
@doc.save.should be_true
|
|
398
|
+
@doc.conditional_one.should be_nil
|
|
399
|
+
@doc.conditional_two.should be_nil
|
|
400
|
+
end
|
|
401
|
+
it "should run conditional callbacks" do
|
|
402
|
+
@doc.run_it = true
|
|
403
|
+
@doc.save.should be_true
|
|
404
|
+
@doc.conditional_one.should be_true
|
|
405
|
+
@doc.conditional_two.should be_true
|
|
406
|
+
end
|
|
407
|
+
end
|
|
408
|
+
describe "create" do
|
|
409
|
+
it "should run the before save filter when creating" do
|
|
410
|
+
@doc.run_before_save.should be_nil
|
|
411
|
+
@doc.create.should_not be_nil
|
|
412
|
+
@doc.run_before_save.should be_true
|
|
413
|
+
end
|
|
414
|
+
it "should run the before create filter" do
|
|
415
|
+
@doc.run_before_create.should be_nil
|
|
416
|
+
@doc.create.should_not be_nil
|
|
417
|
+
@doc.create
|
|
418
|
+
@doc.run_before_create.should be_true
|
|
419
|
+
end
|
|
420
|
+
it "should run the after create filter" do
|
|
421
|
+
@doc.run_after_create.should be_nil
|
|
422
|
+
@doc.create.should_not be_nil
|
|
423
|
+
@doc.create
|
|
424
|
+
@doc.run_after_create.should be_true
|
|
425
|
+
end
|
|
426
|
+
end
|
|
427
|
+
describe "update" do
|
|
428
|
+
|
|
429
|
+
before(:each) do
|
|
430
|
+
@doc.save
|
|
431
|
+
end
|
|
432
|
+
it "should run the before update filter when updating an existing document" do
|
|
433
|
+
@doc.run_before_update.should be_nil
|
|
434
|
+
@doc.update
|
|
435
|
+
@doc.run_before_update.should be_true
|
|
436
|
+
end
|
|
437
|
+
it "should run the after update filter when updating an existing document" do
|
|
438
|
+
@doc.run_after_update.should be_nil
|
|
439
|
+
@doc.update
|
|
440
|
+
@doc.run_after_update.should be_true
|
|
441
|
+
end
|
|
442
|
+
it "should run the before update filter when saving an existing document" do
|
|
443
|
+
@doc.run_before_update.should be_nil
|
|
444
|
+
@doc.save
|
|
445
|
+
@doc.run_before_update.should be_true
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
end
|
|
449
|
+
end
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
describe "#reload" do
|
|
453
|
+
it "reloads defined attributes" do
|
|
454
|
+
i = Article.create!(:title => "Reload when changed")
|
|
455
|
+
i.title.should == "Reload when changed"
|
|
456
|
+
|
|
457
|
+
i.title = "..."
|
|
458
|
+
i.title.should == "..."
|
|
459
|
+
|
|
460
|
+
i.reload
|
|
461
|
+
i.title.should == "Reload when changed"
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
it "reloads defined attributes set to nil" do
|
|
465
|
+
i = Article.create!(:title => "Reload when nil")
|
|
466
|
+
i.title.should == "Reload when nil"
|
|
467
|
+
|
|
468
|
+
i.title = nil
|
|
469
|
+
i.title.should be_nil
|
|
470
|
+
|
|
471
|
+
i.reload
|
|
472
|
+
i.title.should == "Reload when nil"
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
it "returns self" do
|
|
476
|
+
i = Article.create!(:title => "Reload return self")
|
|
477
|
+
i.reload.should be(i)
|
|
478
|
+
end
|
|
479
|
+
end
|
|
480
|
+
|
|
481
|
+
end
|