couchrest_model 2.0.4 → 2.1.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +6 -2
- data/README.md +12 -3
- data/VERSION +1 -1
- data/benchmarks/Gemfile +7 -0
- data/benchmarks/connections.rb +69 -0
- data/couchrest_model.gemspec +11 -13
- data/history.md +6 -0
- data/lib/couchrest/model/design.rb +0 -2
- data/lib/couchrest/model/designs/view.rb +36 -16
- data/lib/couchrest/model/document_queries.rb +5 -9
- data/lib/couchrest/model/errors.rb +8 -0
- data/lib/couchrest/model/support/couchrest_database.rb +12 -4
- data/lib/couchrest/model/validations.rb +1 -1
- data/lib/couchrest/model/validations/uniqueness.rb +11 -1
- data/spec/fixtures/models/course.rb +1 -1
- data/spec/spec_helper.rb +2 -2
- data/spec/unit/assocations_spec.rb +1 -1
- data/spec/unit/attachment_spec.rb +1 -1
- data/spec/unit/base_spec.rb +5 -5
- data/spec/unit/casted_spec.rb +2 -2
- data/spec/unit/connection_spec.rb +3 -3
- data/spec/unit/design_spec.rb +2 -2
- data/spec/unit/designs/design_mapper_spec.rb +1 -1
- data/spec/unit/designs/migrations_spec.rb +1 -1
- data/spec/unit/designs/view_spec.rb +118 -43
- data/spec/unit/designs_spec.rb +10 -13
- data/spec/unit/embeddable_spec.rb +2 -4
- data/spec/unit/persistence_spec.rb +13 -5
- data/spec/unit/property_protection_spec.rb +5 -5
- data/spec/unit/property_spec.rb +9 -9
- data/spec/unit/proxyable_spec.rb +15 -15
- data/spec/unit/subclass_spec.rb +1 -1
- data/spec/unit/utils/migrate_spec.rb +3 -3
- data/spec/unit/validations_spec.rb +7 -7
- metadata +60 -44
@@ -83,7 +83,7 @@ describe "Model attachments" do
|
|
83
83
|
|
84
84
|
it "should use name to detect the content-type automatically if no file" do
|
85
85
|
file = File.open(FIXTURE_PATH + '/attachments/couchdb.png')
|
86
|
-
file.stub
|
86
|
+
file.stub(:path).and_return("badfilname")
|
87
87
|
@obj.create_attachment(:file => File.open(FIXTURE_PATH + '/attachments/couchdb.png'), :name => "couchdb.png")
|
88
88
|
@obj.attachments['couchdb.png']['content_type'].should == "image/png"
|
89
89
|
end
|
data/spec/unit/base_spec.rb
CHANGED
@@ -14,7 +14,7 @@ describe "Model Base" do
|
|
14
14
|
|
15
15
|
it "should override the default db" do
|
16
16
|
@obj.database = TEST_SERVER.database!('couchrest-extendedmodel-test')
|
17
|
-
@obj.database.name.
|
17
|
+
expect(@obj.database.name).to eql 'couchrest-extendedmodel-test'
|
18
18
|
@obj.database.delete!
|
19
19
|
end
|
20
20
|
end
|
@@ -177,7 +177,7 @@ describe "Model Base" do
|
|
177
177
|
it "should not be true if databases do not match" do
|
178
178
|
p = Project.create
|
179
179
|
p2 = p.dup
|
180
|
-
p2.stub
|
180
|
+
p2.stub(:database).and_return('other')
|
181
181
|
p.should_not eql(p2)
|
182
182
|
end
|
183
183
|
it "should always be false if one document not saved" do
|
@@ -223,11 +223,11 @@ describe "Model Base" do
|
|
223
223
|
end
|
224
224
|
it "should silently ignore created_at" do
|
225
225
|
@art.update_attributes_without_saving('created_at' => 'foobar')
|
226
|
-
@art['created_at'].
|
226
|
+
expect(@art['created_at'].to_s).to_not eql('foobar')
|
227
227
|
end
|
228
228
|
it "should silently ignore updated_at" do
|
229
229
|
@art.update_attributes_without_saving('updated_at' => 'foobar')
|
230
|
-
@art['updated_at'].
|
230
|
+
expect(@art['updated_at']).to_not eql('foobar')
|
231
231
|
end
|
232
232
|
it "should also work using attributes= alias" do
|
233
233
|
@art.respond_to?(:attributes=).should be_true
|
@@ -277,7 +277,7 @@ describe "Model Base" do
|
|
277
277
|
it "should automatically call a proc default at initialization" do
|
278
278
|
@obj.set_by_proc.should be_an_instance_of(Time)
|
279
279
|
@obj.set_by_proc.should == @obj.set_by_proc
|
280
|
-
@obj.set_by_proc.
|
280
|
+
expect(@obj.set_by_proc.utc).to be < Time.now.utc
|
281
281
|
end
|
282
282
|
|
283
283
|
it "should let you overwrite the default values" do
|
data/spec/unit/casted_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
class Driver < CouchRest::Model::Base
|
4
|
-
use_database
|
4
|
+
use_database DB
|
5
5
|
# You have to add a casted_by accessor if you want to reach a casted extended doc parent
|
6
6
|
attr_accessor :casted_by
|
7
7
|
|
@@ -9,7 +9,7 @@ class Driver < CouchRest::Model::Base
|
|
9
9
|
end
|
10
10
|
|
11
11
|
class Car < CouchRest::Model::Base
|
12
|
-
use_database
|
12
|
+
use_database DB
|
13
13
|
|
14
14
|
property :name
|
15
15
|
property :driver, Driver
|
@@ -90,7 +90,7 @@ describe CouchRest::Model::Connection do
|
|
90
90
|
@class.server.should be_a(CouchRest::Server)
|
91
91
|
end
|
92
92
|
it "should provide a server with default config" do
|
93
|
-
@class.server.uri.should eql("http://localhost:5984")
|
93
|
+
@class.server.uri.to_s.should eql("http://localhost:5984")
|
94
94
|
end
|
95
95
|
it "should allow the configuration to be overwritten" do
|
96
96
|
@class.connection = {
|
@@ -102,7 +102,7 @@ describe CouchRest::Model::Connection do
|
|
102
102
|
:username => 'foo',
|
103
103
|
:password => 'bar'
|
104
104
|
}
|
105
|
-
@class.server.uri.should eql("https://foo:bar@127.0.0.1:5985")
|
105
|
+
@class.server.uri.to_s.should eql("https://foo:bar@127.0.0.1:5985")
|
106
106
|
end
|
107
107
|
|
108
108
|
end
|
@@ -154,7 +154,7 @@ describe CouchRest::Model::Connection do
|
|
154
154
|
@class.connection_config_file = File.join(FIXTURE_PATH, 'config', 'couchdb.yml')
|
155
155
|
hash = @class.send(:load_connection_config_file)
|
156
156
|
hash[:development].should_not be_nil
|
157
|
-
@class.server.uri.should eql("https://test:user@sample.cloudant.com
|
157
|
+
@class.server.uri.to_s.should eql("https://test:user@sample.cloudant.com")
|
158
158
|
end
|
159
159
|
|
160
160
|
end
|
data/spec/unit/design_spec.rb
CHANGED
@@ -44,7 +44,7 @@ describe CouchRest::Model::Design do
|
|
44
44
|
describe "base methods" do
|
45
45
|
|
46
46
|
before :each do
|
47
|
-
@model =
|
47
|
+
@model = double("ModelExample")
|
48
48
|
@model.stub(:to_s).and_return("ModelExample")
|
49
49
|
@obj = CouchRest::Model::Design.new(@model)
|
50
50
|
end
|
@@ -100,7 +100,7 @@ describe CouchRest::Model::Design do
|
|
100
100
|
end
|
101
101
|
|
102
102
|
it "should not have been saved up until sync called" do
|
103
|
-
|
103
|
+
expect(@mod.database.get(@doc['_id'])).to be_nil
|
104
104
|
end
|
105
105
|
|
106
106
|
|
@@ -96,7 +96,7 @@ describe CouchRest::Model::Designs::DesignMapper do
|
|
96
96
|
end
|
97
97
|
|
98
98
|
it "should create a method on parent model" do
|
99
|
-
CouchRest::Model::Designs::View.stub
|
99
|
+
CouchRest::Model::Designs::View.stub(:define)
|
100
100
|
@object.view('test_view')
|
101
101
|
DesignModel.should respond_to(:test_view)
|
102
102
|
end
|
@@ -90,7 +90,7 @@ describe CouchRest::Model::Designs::Migrations do
|
|
90
90
|
|
91
91
|
# should be possible to perform cleanup
|
92
92
|
@callback.call
|
93
|
-
|
93
|
+
expect(@db.get(@doc_id)).to be_nil
|
94
94
|
|
95
95
|
doc = @db.get(@doc['_id'])
|
96
96
|
doc['views'].should have_key('by_name_and_surname')
|
@@ -66,7 +66,7 @@ describe "Design View" do
|
|
66
66
|
|
67
67
|
describe "with proxy in query for first initialization" do
|
68
68
|
it "should set model to proxy object and remove from query" do
|
69
|
-
proxy =
|
69
|
+
proxy = double("Proxy")
|
70
70
|
@obj = @klass.new(@mod.design_doc, @mod, {:proxy => proxy}, 'test_view')
|
71
71
|
@obj.model.should eql(proxy)
|
72
72
|
end
|
@@ -74,7 +74,7 @@ describe "Design View" do
|
|
74
74
|
|
75
75
|
describe "with proxy in query for chained instance" do
|
76
76
|
it "should set the model to proxy object instead of parents model" do
|
77
|
-
proxy =
|
77
|
+
proxy = double("Proxy")
|
78
78
|
@obj = @klass.new(@mod.design_doc, @mod, {}, 'test_view')
|
79
79
|
@obj.model.should eql(@mod)
|
80
80
|
@obj = @obj.proxy(proxy)
|
@@ -109,7 +109,7 @@ describe "Design View" do
|
|
109
109
|
|
110
110
|
before :each do
|
111
111
|
@design_doc = { }
|
112
|
-
@design_doc.stub
|
112
|
+
@design_doc.stub(:model).and_return(DesignViewModel)
|
113
113
|
end
|
114
114
|
|
115
115
|
it "should add a basic view" do
|
@@ -163,9 +163,9 @@ describe "Design View" do
|
|
163
163
|
before :each do
|
164
164
|
@model = DesignViewModel
|
165
165
|
@design_doc = { }
|
166
|
-
@design_doc.stub
|
167
|
-
@design_doc.stub
|
168
|
-
@model.stub
|
166
|
+
@design_doc.stub(:model).and_return(@model)
|
167
|
+
@design_doc.stub(:method_name).and_return("design_doc")
|
168
|
+
@model.stub('design_doc').and_return(@design_doc)
|
169
169
|
end
|
170
170
|
it "should create standard view method" do
|
171
171
|
@klass.create_model_methods(@design_doc, 'by_name')
|
@@ -176,7 +176,7 @@ describe "Design View" do
|
|
176
176
|
it "should create find_ view method" do
|
177
177
|
@klass.create_model_methods(@design_doc, 'by_name')
|
178
178
|
@model.should respond_to('find_by_name')
|
179
|
-
view =
|
179
|
+
view = double("View")
|
180
180
|
view.should_receive('key').with('fred').and_return(view)
|
181
181
|
view.should_receive('first').and_return(nil)
|
182
182
|
@design_doc.should_receive('view').and_return(view)
|
@@ -185,8 +185,8 @@ describe "Design View" do
|
|
185
185
|
it "should create find_! view method" do
|
186
186
|
@klass.create_model_methods(@design_doc, 'by_name')
|
187
187
|
@model.should respond_to('find_by_name!')
|
188
|
-
obj =
|
189
|
-
view =
|
188
|
+
obj = double("SomeKlass")
|
189
|
+
view = double("View")
|
190
190
|
view.should_receive('key').with('fred').and_return(view)
|
191
191
|
view.should_receive('first').and_return(obj)
|
192
192
|
@design_doc.should_receive('view').and_return(view)
|
@@ -194,7 +194,7 @@ describe "Design View" do
|
|
194
194
|
end
|
195
195
|
it "should create find_! view method and raise error when nil" do
|
196
196
|
@klass.create_model_methods(@design_doc, 'by_name')
|
197
|
-
view =
|
197
|
+
view = double("View")
|
198
198
|
view.should_receive('key').with('fred').and_return(view)
|
199
199
|
view.should_receive('first').and_return(nil)
|
200
200
|
@design_doc.should_receive('view').and_return(view)
|
@@ -221,9 +221,31 @@ describe "Design View" do
|
|
221
221
|
it "should wrap rows in ViewRow class" do
|
222
222
|
@obj.should_receive(:execute).and_return(true)
|
223
223
|
@obj.should_receive(:result).twice.and_return({'rows' => [{:foo => :bar}]})
|
224
|
-
CouchRest::Model::Designs::ViewRow.should_receive(:new).with({:foo => :bar}, @obj.model)
|
224
|
+
CouchRest::Model::Designs::ViewRow.should_receive(:new).with({:foo => :bar}, @obj.model, DB)
|
225
225
|
@obj.rows
|
226
226
|
end
|
227
|
+
|
228
|
+
describe "streaming" do
|
229
|
+
let :sample_data do
|
230
|
+
[
|
231
|
+
{"id" => "doc1", "key" => "doc1", "value" => {"rev" => "4324BB"}},
|
232
|
+
{"id" => "doc2", "key" => "doc2", "value" => {"rev" => "2441HF"}},
|
233
|
+
{"id" => "doc3", "key" => "doc3", "value" => {"rev" => "74EC24"}}
|
234
|
+
]
|
235
|
+
end
|
236
|
+
|
237
|
+
it "should support blocks" do
|
238
|
+
expect(@obj).to receive(:execute) do |&block|
|
239
|
+
sample_data.each { |r| block.call(r) }
|
240
|
+
end
|
241
|
+
rows = []
|
242
|
+
@obj.rows {|r| rows << r }
|
243
|
+
expect(rows.length).to eql(3)
|
244
|
+
expect(rows.first).to be_a(CouchRest::Model::Designs::ViewRow)
|
245
|
+
expect(rows.first.id).to eql('doc1')
|
246
|
+
expect(rows.last.value['rev']).to eql('74EC24')
|
247
|
+
end
|
248
|
+
end
|
227
249
|
end
|
228
250
|
|
229
251
|
describe "#all" do
|
@@ -232,6 +254,11 @@ describe "Design View" do
|
|
232
254
|
@obj.should_receive(:docs)
|
233
255
|
@obj.all
|
234
256
|
end
|
257
|
+
it "should pass on a block" do
|
258
|
+
block = lambda { }
|
259
|
+
expect(@obj).to receive(:docs).with(&block)
|
260
|
+
@obj.all(&block)
|
261
|
+
end
|
235
262
|
end
|
236
263
|
|
237
264
|
describe "#docs" do
|
@@ -244,6 +271,27 @@ describe "Design View" do
|
|
244
271
|
@obj.docs
|
245
272
|
@obj.docs
|
246
273
|
end
|
274
|
+
|
275
|
+
describe "streaming" do
|
276
|
+
let :sample_data do
|
277
|
+
[
|
278
|
+
{"id" => "doc1", "key" => "doc1", "doc" => {"_id" => "123", "type" => 'DesignViewModel', 'name' => 'Test1'}},
|
279
|
+
{"id" => "doc3", "key" => "doc3", "doc" => {"_id" => "234", "type" => 'DesignViewModel', 'name' => 'Test2'}}
|
280
|
+
]
|
281
|
+
end
|
282
|
+
|
283
|
+
it "should support blocks" do
|
284
|
+
expect(@obj).to receive(:execute) do |&block|
|
285
|
+
sample_data.each { |r| block.call(r) }
|
286
|
+
end
|
287
|
+
docs = []
|
288
|
+
@obj.docs {|d| docs << d }
|
289
|
+
expect(docs.length).to eql(2)
|
290
|
+
expect(docs.first).to be_a(DesignViewModel)
|
291
|
+
expect(docs.first.name).to eql('Test1')
|
292
|
+
expect(docs.last.id).to eql('234')
|
293
|
+
end
|
294
|
+
end
|
247
295
|
end
|
248
296
|
|
249
297
|
describe "#first" do
|
@@ -253,7 +301,7 @@ describe "Design View" do
|
|
253
301
|
@obj.first.should eql(:foo)
|
254
302
|
end
|
255
303
|
it "should perform a query if no results cached" do
|
256
|
-
view =
|
304
|
+
view = double('SubView')
|
257
305
|
@obj.should_receive(:result).and_return(nil)
|
258
306
|
@obj.should_receive(:limit).with(1).and_return(view)
|
259
307
|
view.should_receive(:all).and_return([:foo])
|
@@ -268,7 +316,7 @@ describe "Design View" do
|
|
268
316
|
@obj.first.should eql(:foo)
|
269
317
|
end
|
270
318
|
it "should perform a query if no results cached" do
|
271
|
-
view =
|
319
|
+
view = double('SubView')
|
272
320
|
@obj.should_receive(:result).and_return(nil)
|
273
321
|
@obj.should_receive(:limit).with(1).and_return(view)
|
274
322
|
view.should_receive(:descending).and_return(view)
|
@@ -291,8 +339,8 @@ describe "Design View" do
|
|
291
339
|
end
|
292
340
|
|
293
341
|
it "should return first row value if reduce possible" do
|
294
|
-
view =
|
295
|
-
row =
|
342
|
+
view = double("SubView")
|
343
|
+
row = double("Row")
|
296
344
|
@obj.should_receive(:can_reduce?).and_return(true)
|
297
345
|
@obj.should_receive(:reduce).and_return(view)
|
298
346
|
view.should_receive(:skip).with(0).and_return(view)
|
@@ -302,7 +350,7 @@ describe "Design View" do
|
|
302
350
|
@obj.count.should eql(2)
|
303
351
|
end
|
304
352
|
it "should return 0 if no rows and reduce possible" do
|
305
|
-
view =
|
353
|
+
view = double("SubView")
|
306
354
|
@obj.should_receive(:can_reduce?).and_return(true)
|
307
355
|
@obj.should_receive(:reduce).and_return(view)
|
308
356
|
view.should_receive(:skip).with(0).and_return(view)
|
@@ -312,7 +360,7 @@ describe "Design View" do
|
|
312
360
|
end
|
313
361
|
|
314
362
|
it "should perform limit request for total_rows" do
|
315
|
-
view =
|
363
|
+
view = double("SubView")
|
316
364
|
@obj.should_receive(:limit).with(0).and_return(view)
|
317
365
|
view.should_receive(:total_rows).and_return(4)
|
318
366
|
@obj.should_receive(:can_reduce?).and_return(false)
|
@@ -322,7 +370,7 @@ describe "Design View" do
|
|
322
370
|
|
323
371
|
describe "#empty?" do
|
324
372
|
it "should check the #all method for any results" do
|
325
|
-
all =
|
373
|
+
all = double("All")
|
326
374
|
all.should_receive(:empty?).and_return('win')
|
327
375
|
@obj.should_receive(:all).and_return(all)
|
328
376
|
@obj.empty?.should eql('win')
|
@@ -361,7 +409,7 @@ describe "Design View" do
|
|
361
409
|
|
362
410
|
describe "#values" do
|
363
411
|
it "should request each row and provide value" do
|
364
|
-
row =
|
412
|
+
row = double("Row")
|
365
413
|
row.should_receive(:value).twice.and_return('foo')
|
366
414
|
@obj.should_receive(:rows).and_return([row, row])
|
367
415
|
@obj.values.should eql(['foo', 'foo'])
|
@@ -433,7 +481,7 @@ describe "Design View" do
|
|
433
481
|
@obj.startkey_doc('foo')
|
434
482
|
end
|
435
483
|
it "should update query with object id if available" do
|
436
|
-
doc =
|
484
|
+
doc = double("Document")
|
437
485
|
doc.should_receive(:id).and_return(44)
|
438
486
|
@obj.should_receive(:update_query).with({:startkey_docid => 44})
|
439
487
|
@obj.startkey_doc(doc)
|
@@ -461,7 +509,7 @@ describe "Design View" do
|
|
461
509
|
@obj.endkey_doc('foo')
|
462
510
|
end
|
463
511
|
it "should update query with object id if available" do
|
464
|
-
doc =
|
512
|
+
doc = double("Document")
|
465
513
|
doc.should_receive(:id).and_return(44)
|
466
514
|
@obj.should_receive(:update_query).with({:endkey_docid => 44})
|
467
515
|
@obj.endkey_doc(doc)
|
@@ -488,7 +536,7 @@ describe "Design View" do
|
|
488
536
|
|
489
537
|
describe "#keys (without parameters)" do
|
490
538
|
it "should request each row and provide key value" do
|
491
|
-
row =
|
539
|
+
row = double("Row")
|
492
540
|
row.should_receive(:key).twice.and_return('foo')
|
493
541
|
@obj.should_receive(:rows).and_return([row, row])
|
494
542
|
@obj.keys.should eql(['foo', 'foo'])
|
@@ -676,10 +724,10 @@ describe "Design View" do
|
|
676
724
|
describe "#execute" do
|
677
725
|
before :each do
|
678
726
|
# disable real execution!
|
679
|
-
@design_doc =
|
680
|
-
@design_doc.stub
|
681
|
-
@design_doc.stub
|
682
|
-
@obj.stub
|
727
|
+
@design_doc = double("DesignDoc")
|
728
|
+
@design_doc.stub(:view_on)
|
729
|
+
@design_doc.stub(:sync)
|
730
|
+
@obj.stub(:design_doc).and_return(@design_doc)
|
683
731
|
end
|
684
732
|
|
685
733
|
it "should return previous result if set" do
|
@@ -689,7 +737,7 @@ describe "Design View" do
|
|
689
737
|
|
690
738
|
it "should raise issue if no database" do
|
691
739
|
@obj.should_receive(:query).and_return({:database => nil})
|
692
|
-
model =
|
740
|
+
model = double("SomeModel")
|
693
741
|
model.should_receive(:database).and_return(nil)
|
694
742
|
@obj.should_receive(:model).and_return(model)
|
695
743
|
lambda { @obj.send(:execute) }.should raise_error
|
@@ -716,12 +764,20 @@ describe "Design View" do
|
|
716
764
|
|
717
765
|
it "should not remove nil values from query" do
|
718
766
|
@obj.should_receive(:can_reduce?).and_return(true)
|
719
|
-
@obj.stub
|
767
|
+
@obj.stub(:use_database).and_return(@mod.database)
|
720
768
|
@obj.query = {:reduce => true, :limit => nil, :skip => nil}
|
721
769
|
@design_doc.should_receive(:view_on).with(@mod.database, 'test_view', {:reduce => true, :limit => nil, :skip => nil})
|
722
770
|
@obj.send(:execute)
|
723
771
|
end
|
724
772
|
|
773
|
+
it "should accept a block and pass to view_on" do
|
774
|
+
row = {'id' => '1234'}
|
775
|
+
expect(@design_doc).to receive(:view_on) { |db,n,q,&block| block.call(row) }
|
776
|
+
expect(@obj).to receive(:can_reduce?).and_return(true)
|
777
|
+
@obj.send(:execute) do |r|
|
778
|
+
expect(r).to eql(row)
|
779
|
+
end
|
780
|
+
end
|
725
781
|
|
726
782
|
end
|
727
783
|
|
@@ -794,13 +850,19 @@ describe "Design View" do
|
|
794
850
|
@klass = CouchRest::Model::Designs::ViewRow
|
795
851
|
end
|
796
852
|
|
853
|
+
let :model do
|
854
|
+
m = double()
|
855
|
+
m.stub(:database).and_return(DB)
|
856
|
+
m
|
857
|
+
end
|
858
|
+
|
797
859
|
describe "intialize" do
|
798
860
|
it "should store reference to model" do
|
799
|
-
obj = @klass.new({},
|
800
|
-
obj.model.should eql(
|
861
|
+
obj = @klass.new({}, model)
|
862
|
+
obj.model.should eql(model)
|
801
863
|
end
|
802
864
|
it "should copy details from hash" do
|
803
|
-
obj = @klass.new({:foo => :bar, :test => :example},
|
865
|
+
obj = @klass.new({:foo => :bar, :test => :example}, model)
|
804
866
|
obj[:foo].should eql(:bar)
|
805
867
|
obj[:test].should eql(:example)
|
806
868
|
end
|
@@ -811,53 +873,66 @@ describe "Design View" do
|
|
811
873
|
end
|
812
874
|
|
813
875
|
it "should provide id" do
|
814
|
-
obj = @klass.new({'id' => '123456'},
|
876
|
+
obj = @klass.new({'id' => '123456'}, model)
|
815
877
|
obj.id.should eql('123456')
|
816
878
|
end
|
817
879
|
|
880
|
+
it "may be instantiated with a database" do
|
881
|
+
obj = @klass.new({'id' => '123456'}, model, 'foo')
|
882
|
+
expect(obj.db).to eql('foo')
|
883
|
+
end
|
884
|
+
|
885
|
+
it "may use model's database" do
|
886
|
+
obj = @klass.new({'id' => '123456'}, model)
|
887
|
+
expect(obj.db).to eql(DB)
|
888
|
+
end
|
889
|
+
|
818
890
|
it "should provide key" do
|
819
|
-
obj = @klass.new({'key' => 'thekey'},
|
891
|
+
obj = @klass.new({'key' => 'thekey'}, model)
|
820
892
|
obj.key.should eql('thekey')
|
821
893
|
end
|
822
894
|
|
823
895
|
it "should provide the value" do
|
824
|
-
obj = @klass.new({'value' => 'thevalue'},
|
896
|
+
obj = @klass.new({'value' => 'thevalue'}, model)
|
825
897
|
obj.value.should eql('thevalue')
|
826
898
|
end
|
827
899
|
|
828
900
|
it "should provide the raw document" do
|
829
|
-
obj = @klass.new({'doc' => 'thedoc'},
|
901
|
+
obj = @klass.new({'doc' => 'thedoc'}, model)
|
830
902
|
obj.raw_doc.should eql('thedoc')
|
831
903
|
end
|
832
904
|
|
833
905
|
it "should instantiate a new document" do
|
834
906
|
hash = {'doc' => {'_id' => '12345', 'name' => 'sam'}}
|
835
907
|
obj = @klass.new(hash, DesignViewModel)
|
836
|
-
doc =
|
837
|
-
|
838
|
-
obj.
|
908
|
+
doc = double('DesignViewDoc')
|
909
|
+
doc.stub(:database).and_return(DB)
|
910
|
+
expect(obj.model).to receive(:build_from_database).with(hash['doc']).and_return(doc)
|
911
|
+
expect(obj.doc).to eql(doc)
|
839
912
|
end
|
840
913
|
|
841
914
|
it "should try to load from id if no document" do
|
842
915
|
hash = {'id' => '12345', 'value' => 5}
|
843
916
|
obj = @klass.new(hash, DesignViewModel)
|
844
|
-
doc =
|
845
|
-
|
917
|
+
doc = double('DesignViewModel')
|
918
|
+
doc.stub(:database).and_return(DB)
|
919
|
+
obj.model.should_receive(:get).with('12345', DB).and_return(doc)
|
846
920
|
obj.doc.should eql(doc)
|
847
921
|
end
|
848
922
|
|
849
923
|
it "should try to load linked document if available" do
|
850
924
|
hash = {'id' => '12345', 'value' => {'_id' => '54321'}}
|
851
925
|
obj = @klass.new(hash, DesignViewModel)
|
852
|
-
doc =
|
853
|
-
|
926
|
+
doc = double('DesignViewModel')
|
927
|
+
doc.stub(:database).and_return(DB)
|
928
|
+
obj.model.should_receive(:get).with('54321', DB).and_return(doc)
|
854
929
|
obj.doc.should eql(doc)
|
855
930
|
end
|
856
931
|
|
857
932
|
it "should try to return nil for document if none available" do
|
858
933
|
hash = {'value' => 23} # simulate reduce
|
859
934
|
obj = @klass.new(hash, DesignViewModel)
|
860
|
-
doc =
|
935
|
+
doc = double('DesignViewModel')
|
861
936
|
obj.model.should_not_receive(:get)
|
862
937
|
obj.doc.should be_nil
|
863
938
|
end
|