couchrest_model 2.0.4 → 2.1.0.beta1
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.
- 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
|