couchrest_model 1.1.2 → 1.2.0.beta
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.md +8 -2
- data/VERSION +1 -1
- data/couchrest_model.gemspec +2 -1
- data/history.md +8 -0
- data/lib/couchrest/model/base.rb +0 -20
- data/lib/couchrest/model/configuration.rb +2 -0
- data/lib/couchrest/model/core_extensions/time_parsing.rb +35 -9
- data/lib/couchrest/model/designs/design.rb +182 -0
- data/lib/couchrest/model/designs/view.rb +91 -48
- data/lib/couchrest/model/designs.rb +72 -19
- data/lib/couchrest/model/document_queries.rb +15 -45
- data/lib/couchrest/model/properties.rb +43 -2
- data/lib/couchrest/model/proxyable.rb +20 -54
- data/lib/couchrest/model/typecast.rb +1 -1
- data/lib/couchrest/model/validations/uniqueness.rb +7 -6
- data/lib/couchrest_model.rb +1 -5
- data/spec/fixtures/models/article.rb +22 -20
- data/spec/fixtures/models/base.rb +15 -7
- data/spec/fixtures/models/course.rb +7 -4
- data/spec/fixtures/models/project.rb +4 -1
- data/spec/fixtures/models/sale_entry.rb +5 -3
- data/spec/unit/base_spec.rb +51 -5
- data/spec/unit/core_extensions/time_parsing.rb +41 -0
- data/spec/unit/designs/design_spec.rb +291 -0
- data/spec/unit/designs/view_spec.rb +135 -40
- data/spec/unit/designs_spec.rb +341 -30
- data/spec/unit/dirty_spec.rb +67 -0
- data/spec/unit/inherited_spec.rb +2 -2
- data/spec/unit/property_protection_spec.rb +3 -1
- data/spec/unit/property_spec.rb +43 -3
- data/spec/unit/proxyable_spec.rb +57 -98
- data/spec/unit/subclass_spec.rb +14 -5
- data/spec/unit/validations_spec.rb +14 -12
- metadata +172 -129
- data/lib/couchrest/model/class_proxy.rb +0 -135
- data/lib/couchrest/model/collection.rb +0 -273
- data/lib/couchrest/model/design_doc.rb +0 -115
- data/lib/couchrest/model/support/couchrest_design.rb +0 -33
- data/lib/couchrest/model/views.rb +0 -148
- data/spec/unit/class_proxy_spec.rb +0 -167
- data/spec/unit/collection_spec.rb +0 -86
- data/spec/unit/design_doc_spec.rb +0 -212
- data/spec/unit/view_spec.rb +0 -352
data/spec/unit/designs_spec.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
class DesignModel < CouchRest::Model::Base
|
4
|
+
use_database DB
|
5
|
+
property :name
|
4
6
|
end
|
5
7
|
|
6
8
|
describe CouchRest::Model::Designs do
|
@@ -12,26 +14,89 @@ describe CouchRest::Model::Designs do
|
|
12
14
|
describe "class methods" do
|
13
15
|
|
14
16
|
describe ".design" do
|
15
|
-
|
16
|
-
|
17
|
-
@
|
17
|
+
|
18
|
+
before :each do
|
19
|
+
@klass = DesignModel.dup
|
18
20
|
end
|
19
21
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
describe "without block" do
|
23
|
+
it "should create design_doc and all methods" do
|
24
|
+
@klass.design
|
25
|
+
@klass.should respond_to(:design_doc)
|
26
|
+
@klass.should respond_to(:all)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should created named design_doc method and not all" do
|
30
|
+
@klass.design :stats
|
31
|
+
@klass.should respond_to(:stats_design_doc)
|
32
|
+
@klass.should_not respond_to(:all)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should have added itself to a design_blocks array" do
|
36
|
+
@klass.design
|
37
|
+
blocks = @klass.instance_variable_get(:@_design_blocks)
|
38
|
+
blocks.length.should eql(1)
|
39
|
+
blocks.first.should eql({:args => [nil], :block => nil})
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should have added itself to a design_blocks array" do
|
43
|
+
@klass.design
|
44
|
+
blocks = @klass.instance_variable_get(:@_design_blocks)
|
45
|
+
blocks.length.should eql(1)
|
46
|
+
blocks.first.should eql({:args => [nil], :block => nil})
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should have added itself to a design_blocks array with prefix" do
|
50
|
+
@klass.design :stats
|
51
|
+
blocks = @klass.instance_variable_get(:@_design_blocks)
|
52
|
+
blocks.length.should eql(1)
|
53
|
+
blocks.first.should eql({:args => [:stats], :block => nil})
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "with block" do
|
58
|
+
before :each do
|
59
|
+
@block = Proc.new do
|
60
|
+
disable_auto_update
|
61
|
+
end
|
62
|
+
@klass.design &@block
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should pass calls to mapper" do
|
66
|
+
@klass.design_doc.auto_update.should be_false
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should have added itself to a design_blocks array" do
|
70
|
+
blocks = @klass.instance_variable_get(:@_design_blocks)
|
71
|
+
blocks.length.should eql(1)
|
72
|
+
blocks.first.should eql({:args => [nil], :block => @block})
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should handle multiple designs" do
|
76
|
+
@block2 = Proc.new do
|
77
|
+
view :by_name
|
78
|
+
end
|
79
|
+
@klass.design :stats, &@block2
|
80
|
+
blocks = @klass.instance_variable_get(:@_design_blocks)
|
81
|
+
blocks.length.should eql(2)
|
82
|
+
blocks.first.should eql({:args => [nil], :block => @block})
|
83
|
+
blocks.last.should eql({:args => [:stats], :block => @block2})
|
84
|
+
end
|
25
85
|
end
|
26
86
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "inheritance" do
|
90
|
+
before :each do
|
91
|
+
klass = DesignModel.dup
|
92
|
+
klass.design do
|
93
|
+
view :by_name
|
94
|
+
end
|
95
|
+
@klass = Class.new(klass)
|
31
96
|
end
|
32
97
|
|
33
|
-
it "should
|
34
|
-
|
98
|
+
it "should add designs to sub module" do
|
99
|
+
@klass.should respond_to(:design_doc)
|
35
100
|
end
|
36
101
|
|
37
102
|
end
|
@@ -51,14 +116,85 @@ describe CouchRest::Model::Designs do
|
|
51
116
|
end
|
52
117
|
|
53
118
|
describe "DesignMapper" do
|
54
|
-
|
119
|
+
|
55
120
|
before :all do
|
56
121
|
@klass = CouchRest::Model::Designs::DesignMapper
|
57
122
|
end
|
58
123
|
|
59
|
-
|
60
|
-
|
61
|
-
|
124
|
+
describe 'initialize without prefix' do
|
125
|
+
|
126
|
+
before :all do
|
127
|
+
@object = @klass.new(DesignModel)
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should set basic variables" do
|
131
|
+
@object.send(:model).should eql(DesignModel)
|
132
|
+
@object.send(:prefix).should be_nil
|
133
|
+
@object.send(:method).should eql('design_doc')
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should add design doc to list" do
|
137
|
+
@object.model.design_docs.should include(@object.model.design_doc)
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should create a design doc method" do
|
141
|
+
@object.model.should respond_to('design_doc')
|
142
|
+
@object.design_doc.should eql(@object.model.design_doc)
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should use default for autoupdate" do
|
146
|
+
@object.design_doc.auto_update.should be_true
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
|
151
|
+
describe 'initialize with prefix' do
|
152
|
+
before :all do
|
153
|
+
@object = @klass.new(DesignModel, 'stats')
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should set basics" do
|
157
|
+
@object.send(:model).should eql(DesignModel)
|
158
|
+
@object.send(:prefix).should eql('stats')
|
159
|
+
@object.send(:method).should eql('stats_design_doc')
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should add design doc to list" do
|
163
|
+
@object.model.design_docs.should include(@object.model.stats_design_doc)
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should not create an all method" do
|
167
|
+
@object.model.should_not respond_to('all')
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should create a design doc method" do
|
171
|
+
@object.model.should respond_to('stats_design_doc')
|
172
|
+
@object.design_doc.should eql(@object.model.stats_design_doc)
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
|
177
|
+
describe "#disable_auto_update" do
|
178
|
+
it "should disable auto updates" do
|
179
|
+
@object = @klass.new(DesignModel)
|
180
|
+
@object.disable_auto_update
|
181
|
+
@object.design_doc.auto_update.should be_false
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
describe "#enable_auto_update" do
|
186
|
+
it "should enable auto updates" do
|
187
|
+
@object = @klass.new(DesignModel)
|
188
|
+
@object.enable_auto_update
|
189
|
+
@object.design_doc.auto_update.should be_true
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
describe "#model_type_key" do
|
194
|
+
it "should return models type key" do
|
195
|
+
@object = @klass.new(DesignModel)
|
196
|
+
@object.model_type_key.should eql(@object.model.model_type_key)
|
197
|
+
end
|
62
198
|
end
|
63
199
|
|
64
200
|
describe "#view" do
|
@@ -68,22 +204,20 @@ describe CouchRest::Model::Designs do
|
|
68
204
|
end
|
69
205
|
|
70
206
|
it "should call create method on view" do
|
71
|
-
CouchRest::Model::Designs::View.should_receive(:
|
207
|
+
CouchRest::Model::Designs::View.should_receive(:define).with(@object.design_doc, 'test', {})
|
72
208
|
@object.view('test')
|
73
209
|
end
|
74
210
|
|
75
211
|
it "should create a method on parent model" do
|
76
|
-
CouchRest::Model::Designs::View.stub!(:
|
212
|
+
CouchRest::Model::Designs::View.stub!(:define)
|
77
213
|
@object.view('test_view')
|
78
214
|
DesignModel.should respond_to(:test_view)
|
79
215
|
end
|
80
216
|
|
81
217
|
it "should create a method for view instance" do
|
82
|
-
|
83
|
-
@object.should_receive(:create_view_method).with('test')
|
218
|
+
@object.design_doc.should_receive(:create_view).with('test', {})
|
84
219
|
@object.view('test')
|
85
220
|
end
|
86
|
-
|
87
221
|
end
|
88
222
|
|
89
223
|
describe "#filter" do
|
@@ -97,22 +231,199 @@ describe CouchRest::Model::Designs do
|
|
97
231
|
DesignModel.design_doc['filters'].should_not be_empty
|
98
232
|
DesignModel.design_doc['filters']['important'].should_not be_blank
|
99
233
|
end
|
234
|
+
end
|
100
235
|
|
236
|
+
end
|
237
|
+
|
238
|
+
|
239
|
+
class DesignsNoAutoUpdate < CouchRest::Model::Base
|
240
|
+
use_database DB
|
241
|
+
property :title, String
|
242
|
+
design do
|
243
|
+
disable_auto_update
|
244
|
+
view :by_title_fail, :by => ['title']
|
245
|
+
view :by_title, :reduce => true
|
101
246
|
end
|
247
|
+
end
|
102
248
|
|
103
|
-
|
104
|
-
|
105
|
-
|
249
|
+
describe "Scenario testing" do
|
250
|
+
|
251
|
+
describe "with auto update disabled" do
|
252
|
+
|
253
|
+
before :all do
|
254
|
+
reset_test_db!
|
255
|
+
@mod = DesignsNoAutoUpdate
|
256
|
+
end
|
257
|
+
|
258
|
+
before(:all) do
|
259
|
+
id = @mod.to_s
|
260
|
+
doc = CouchRest::Document.new("_id" => "_design/#{id}")
|
261
|
+
doc["language"] = "javascript"
|
262
|
+
doc["views"] = {"all" => {"map" => "function(doc) { if (doc['type'] == '#{id}') { emit(doc['_id'],1); } }"},
|
263
|
+
"by_title" => {"map" =>
|
264
|
+
"function(doc) {
|
265
|
+
if ((doc['type'] == '#{id}') && (doc['title'] != null)) {
|
266
|
+
emit(doc['title'], 1);
|
267
|
+
}
|
268
|
+
}", "reduce" => "function(k,v,r) { return sum(v); }"}}
|
269
|
+
DB.save_doc doc
|
270
|
+
end
|
271
|
+
|
272
|
+
it "will fail if reduce is not specific in view" do
|
273
|
+
@mod.create(:title => 'This is a test')
|
274
|
+
lambda { @mod.by_title_fail.first }.should raise_error(RestClient::ResourceNotFound)
|
106
275
|
end
|
107
276
|
|
108
|
-
it "
|
109
|
-
|
110
|
-
@
|
111
|
-
DesignModel.test_view
|
277
|
+
it "will perform view request" do
|
278
|
+
@mod.create(:title => 'This is a test')
|
279
|
+
@mod.by_title.first.title.should eql("This is a test")
|
112
280
|
end
|
113
281
|
|
114
282
|
end
|
115
283
|
|
284
|
+
describe "using views" do
|
285
|
+
|
286
|
+
describe "to find a single item" do
|
287
|
+
|
288
|
+
before(:all) do
|
289
|
+
reset_test_db!
|
290
|
+
%w{aaa bbb ddd eee}.each do |title|
|
291
|
+
Course.new(:title => title, :active => (title == 'bbb')).save
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
it "should return single matched record with find helper" do
|
296
|
+
course = Course.find_by_title('bbb')
|
297
|
+
course.should_not be_nil
|
298
|
+
course.title.should eql('bbb') # Ensure really is a Course!
|
299
|
+
end
|
300
|
+
|
301
|
+
it "should return nil if not found" do
|
302
|
+
course = Course.find_by_title('fff')
|
303
|
+
course.should be_nil
|
304
|
+
end
|
305
|
+
|
306
|
+
it "should peform search on view with two properties" do
|
307
|
+
course = Course.find_by_title_and_active(['bbb', true])
|
308
|
+
course.should_not be_nil
|
309
|
+
course.title.should eql('bbb') # Ensure really is a Course!
|
310
|
+
end
|
311
|
+
|
312
|
+
it "should return nil if not found" do
|
313
|
+
course = Course.find_by_title_and_active(['bbb', false])
|
314
|
+
course.should be_nil
|
315
|
+
end
|
316
|
+
|
317
|
+
it "should raise exception if view not present" do
|
318
|
+
lambda { Course.find_by_foobar('123') }.should raise_error(NoMethodError)
|
319
|
+
end
|
320
|
+
|
321
|
+
end
|
322
|
+
|
323
|
+
describe "a model class with database provided manually" do
|
324
|
+
|
325
|
+
class Unattached < CouchRest::Model::Base
|
326
|
+
property :title
|
327
|
+
property :questions
|
328
|
+
property :professor
|
329
|
+
design do
|
330
|
+
view :by_title
|
331
|
+
end
|
332
|
+
|
333
|
+
# Force the database to always be nil
|
334
|
+
def self.database
|
335
|
+
nil
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
before(:all) do
|
340
|
+
reset_test_db!
|
341
|
+
@db = DB
|
342
|
+
%w{aaa bbb ddd eee}.each do |title|
|
343
|
+
u = Unattached.new(:title => title)
|
344
|
+
u.database = @db
|
345
|
+
u.save
|
346
|
+
@first_id ||= u.id
|
347
|
+
end
|
348
|
+
end
|
349
|
+
it "should barf on all if no database given" do
|
350
|
+
lambda{Unattached.all.first}.should raise_error
|
351
|
+
end
|
352
|
+
it "should query all" do
|
353
|
+
rs = Unattached.all.database(@db).all
|
354
|
+
rs.length.should == 4
|
355
|
+
end
|
356
|
+
it "should barf on query if no database given" do
|
357
|
+
lambda{Unattached.by_title.all}.should raise_error /Database must be defined/
|
358
|
+
end
|
359
|
+
it "should make the design doc upon first query" do
|
360
|
+
Unattached.by_title.database(@db)
|
361
|
+
doc = Unattached.design_doc
|
362
|
+
doc['views']['all']['map'].should include('Unattached')
|
363
|
+
end
|
364
|
+
it "should merge query params" do
|
365
|
+
rs = Unattached.by_title.database(@db).startkey("bbb").endkey("eee")
|
366
|
+
rs.length.should == 3
|
367
|
+
end
|
368
|
+
it "should return nil on get if no database given" do
|
369
|
+
Unattached.get("aaa").should be_nil
|
370
|
+
end
|
371
|
+
it "should barf on get! if no database given" do
|
372
|
+
lambda{Unattached.get!("aaa")}.should raise_error
|
373
|
+
end
|
374
|
+
it "should get from specific database" do
|
375
|
+
u = Unattached.get(@first_id, @db)
|
376
|
+
u.title.should == "aaa"
|
377
|
+
end
|
378
|
+
it "should barf on first if no database given" do
|
379
|
+
lambda{Unattached.first}.should raise_error
|
380
|
+
end
|
381
|
+
it "should get first" do
|
382
|
+
u = Unattached.all.database(@db).first
|
383
|
+
u.title.should =~ /\A...\z/
|
384
|
+
end
|
385
|
+
it "should get last" do
|
386
|
+
u = Unattached.all.database(@db).last
|
387
|
+
u.title.should == "aaa"
|
388
|
+
end
|
389
|
+
|
390
|
+
end
|
391
|
+
|
392
|
+
describe "a model with a compound key view" do
|
393
|
+
before(:all) do
|
394
|
+
reset_test_db!
|
395
|
+
written_at = Time.now - 24 * 3600 * 7
|
396
|
+
@titles = ["uniq one", "even more interesting", "less fun", "not junk"]
|
397
|
+
@user_ids = ["quentin", "aaron"]
|
398
|
+
@titles.each_with_index do |title,i|
|
399
|
+
u = i % 2
|
400
|
+
a = Article.new(:title => title, :user_id => @user_ids[u])
|
401
|
+
a.date = written_at
|
402
|
+
a.save
|
403
|
+
written_at += 24 * 3600
|
404
|
+
end
|
405
|
+
end
|
406
|
+
it "should create the design doc" do
|
407
|
+
Article.by_user_id_and_date rescue nil
|
408
|
+
doc = Article.design_doc
|
409
|
+
doc['views']['by_date'].should_not be_nil
|
410
|
+
end
|
411
|
+
it "should sort correctly" do
|
412
|
+
articles = Article.by_user_id_and_date.all
|
413
|
+
articles.collect{|a|a['user_id']}.should == ['aaron', 'aaron', 'quentin',
|
414
|
+
'quentin']
|
415
|
+
articles[1].title.should == 'not junk'
|
416
|
+
end
|
417
|
+
it "should be queryable with couchrest options" do
|
418
|
+
articles = Article.by_user_id_and_date(:limit => 1, :startkey => 'quentin').all
|
419
|
+
articles.length.should == 1
|
420
|
+
articles[0].title.should == "even more interesting"
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
|
425
|
+
end
|
426
|
+
|
116
427
|
end
|
117
428
|
|
118
429
|
end
|
data/spec/unit/dirty_spec.rb
CHANGED
@@ -99,6 +99,32 @@ describe "Dirty" do
|
|
99
99
|
@card.first_name_changed?.should be_true
|
100
100
|
end
|
101
101
|
|
102
|
+
it 'should report changes if the record is modified by attributes' do
|
103
|
+
@card = Card.new
|
104
|
+
@card.attributes = {:first_name => 'danny'}
|
105
|
+
@card.changed?.should be_true
|
106
|
+
@card.first_name_changed?.should be_true
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'should report no changes if the record is modified with an invalid property by attributes' do
|
110
|
+
@card = Card.new
|
111
|
+
@card.attributes = {:middle_name => 'danny'}
|
112
|
+
@card.changed?.should be_false
|
113
|
+
@card.first_name_changed?.should be_false
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should report no changes if the record is modified with update_attributes" do
|
117
|
+
@card = Card.new
|
118
|
+
@card.update_attributes(:first_name => 'henry')
|
119
|
+
@card.changed?.should be_false
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should report no changes if the record is modified with an invalid property by update_attributes" do
|
123
|
+
@card = Card.new
|
124
|
+
@card.update_attributes(:middle_name => 'peter')
|
125
|
+
@card.changed?.should be_false
|
126
|
+
end
|
127
|
+
|
102
128
|
it "should report no changes for unmodified records" do
|
103
129
|
card_id = Card.create!(:first_name => "matt").id
|
104
130
|
@card = Card.find(card_id)
|
@@ -433,4 +459,45 @@ describe "Dirty" do
|
|
433
459
|
|
434
460
|
end
|
435
461
|
|
462
|
+
|
463
|
+
describe "when mass_assign_any_attribute true" do
|
464
|
+
before(:each) do
|
465
|
+
# dupe Card class so that no other tests are effected
|
466
|
+
card_class = Card.dup
|
467
|
+
card_class.class_eval do
|
468
|
+
mass_assign_any_attribute true
|
469
|
+
end
|
470
|
+
@card = card_class.new(:first_name => 'Sam')
|
471
|
+
end
|
472
|
+
|
473
|
+
it "should report no changes if the record is modified with update_attributes" do
|
474
|
+
@card.update_attributes(:other_name => 'henry')
|
475
|
+
@card.changed?.should be_false
|
476
|
+
end
|
477
|
+
|
478
|
+
it "should report not new if the record is modified with update_attributes" do
|
479
|
+
@card.update_attributes(:other_name => 'henry')
|
480
|
+
@card.new?.should be_false
|
481
|
+
end
|
482
|
+
|
483
|
+
it 'should report changes when updated with attributes' do
|
484
|
+
@card.save
|
485
|
+
@card.attributes = {:testing => 'fooobar'}
|
486
|
+
@card.changed?.should be_true
|
487
|
+
end
|
488
|
+
|
489
|
+
it 'should report changes when updated with a known property' do
|
490
|
+
@card.save
|
491
|
+
@card.first_name = 'Danny'
|
492
|
+
@card.changed?.should be_true
|
493
|
+
end
|
494
|
+
|
495
|
+
it "should not report changes if property is updated with same value" do
|
496
|
+
@card.update_attributes :testing => 'fooobar'
|
497
|
+
@card.attributes = {'testing' => 'fooobar'}
|
498
|
+
@card.changed?.should be_false
|
499
|
+
end
|
500
|
+
|
501
|
+
end
|
502
|
+
|
436
503
|
end
|
data/spec/unit/inherited_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
class PlainParent
|
4
|
-
|
4
|
+
class_attribute :foo
|
5
5
|
self.foo = :bar
|
6
6
|
end
|
7
7
|
|
@@ -9,7 +9,7 @@ class PlainChild < PlainParent
|
|
9
9
|
end
|
10
10
|
|
11
11
|
class ExtendedParent < CouchRest::Model::Base
|
12
|
-
|
12
|
+
class_attribute :foo
|
13
13
|
self.foo = :bar
|
14
14
|
end
|
15
15
|
|
data/spec/unit/property_spec.rb
CHANGED
@@ -148,6 +148,26 @@ describe CouchRest::Model::Property do
|
|
148
148
|
@card['test'].should be_nil
|
149
149
|
end
|
150
150
|
|
151
|
+
it 'should not allow them to be updated with update_attributes' do
|
152
|
+
@card.update_attributes(:test => 'fooobar')
|
153
|
+
@card['test'].should be_nil
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'should not have a different revision after update_attributes' do
|
157
|
+
@card.save
|
158
|
+
rev = @card.rev
|
159
|
+
@card.update_attributes(:test => 'fooobar')
|
160
|
+
@card.rev.should eql(rev)
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'should not have a different revision after save' do
|
164
|
+
@card.save
|
165
|
+
rev = @card.rev
|
166
|
+
@card.attributes = {:test => 'fooobar'}
|
167
|
+
@card.save
|
168
|
+
@card.rev.should eql(rev)
|
169
|
+
end
|
170
|
+
|
151
171
|
end
|
152
172
|
|
153
173
|
describe "when mass_assign_any_attribute true" do
|
@@ -161,13 +181,33 @@ describe CouchRest::Model::Property do
|
|
161
181
|
end
|
162
182
|
|
163
183
|
it 'should allow them to be updated' do
|
164
|
-
@card.attributes = {:
|
165
|
-
@card['
|
184
|
+
@card.attributes = {:testing => 'fooobar'}
|
185
|
+
@card['testing'].should eql('fooobar')
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'should allow them to be updated with update_attributes' do
|
189
|
+
@card.update_attributes(:testing => 'fooobar')
|
190
|
+
@card['testing'].should eql('fooobar')
|
166
191
|
end
|
192
|
+
|
193
|
+
it 'should have a different revision after update_attributes' do
|
194
|
+
@card.save
|
195
|
+
rev = @card.rev
|
196
|
+
@card.update_attributes(:testing => 'fooobar')
|
197
|
+
@card.rev.should_not eql(rev)
|
198
|
+
end
|
199
|
+
|
200
|
+
it 'should have a different revision after save' do
|
201
|
+
@card.save
|
202
|
+
rev = @card.rev
|
203
|
+
@card.attributes = {:testing => 'fooobar'}
|
204
|
+
@card.save
|
205
|
+
@card.rev.should_not eql(rev)
|
206
|
+
end
|
207
|
+
|
167
208
|
end
|
168
209
|
end
|
169
210
|
|
170
|
-
|
171
211
|
describe "mass assignment protection" do
|
172
212
|
|
173
213
|
it "should not store protected attribute using mass assignment" do
|