couch_potato 1.7.0 → 1.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ruby.yml +50 -0
  3. data/.gitignore +3 -0
  4. data/CHANGES.md +180 -130
  5. data/Gemfile +4 -0
  6. data/README.md +61 -85
  7. data/Rakefile +11 -10
  8. data/couch_potato-rspec.gemspec +2 -1
  9. data/couch_potato.gemspec +9 -7
  10. data/gemfiles/active_support_5_0 +6 -0
  11. data/gemfiles/active_support_5_1 +7 -0
  12. data/gemfiles/active_support_5_2 +6 -0
  13. data/gemfiles/active_support_6_0 +6 -0
  14. data/gemfiles/active_support_6_1 +6 -0
  15. data/gemfiles/active_support_7_0 +6 -0
  16. data/lib/couch_potato/database.rb +170 -71
  17. data/lib/couch_potato/persistence/dirty_attributes.rb +3 -21
  18. data/lib/couch_potato/persistence/magic_timestamps.rb +3 -3
  19. data/lib/couch_potato/persistence/properties.rb +15 -10
  20. data/lib/couch_potato/persistence/simple_property.rb +0 -4
  21. data/lib/couch_potato/persistence/type_caster.rb +11 -6
  22. data/lib/couch_potato/persistence.rb +0 -1
  23. data/lib/couch_potato/railtie.rb +6 -11
  24. data/lib/couch_potato/validation.rb +8 -0
  25. data/lib/couch_potato/version.rb +2 -2
  26. data/lib/couch_potato/view/base_view_spec.rb +8 -32
  27. data/lib/couch_potato/view/custom_views.rb +4 -3
  28. data/lib/couch_potato/view/flex_view_spec.rb +121 -0
  29. data/lib/couch_potato/view/view_parameters.rb +34 -0
  30. data/lib/couch_potato.rb +37 -16
  31. data/spec/callbacks_spec.rb +45 -19
  32. data/spec/conflict_handling_spec.rb +1 -2
  33. data/spec/property_spec.rb +12 -3
  34. data/spec/railtie_spec.rb +10 -0
  35. data/spec/spec_helper.rb +4 -3
  36. data/spec/unit/active_model_compliance_spec.rb +7 -3
  37. data/spec/unit/attributes_spec.rb +54 -1
  38. data/spec/unit/caching_spec.rb +105 -0
  39. data/spec/unit/couch_potato_spec.rb +70 -5
  40. data/spec/unit/create_spec.rb +5 -4
  41. data/spec/unit/database_spec.rb +239 -135
  42. data/spec/unit/dirty_attributes_spec.rb +5 -26
  43. data/spec/unit/flex_view_spec_spec.rb +17 -0
  44. data/spec/unit/model_view_spec_spec.rb +1 -1
  45. data/spec/unit/rspec_stub_db_spec.rb +31 -0
  46. data/spec/unit/validation_spec.rb +42 -2
  47. data/spec/unit/view_query_spec.rb +12 -7
  48. data/spec/views_spec.rb +214 -103
  49. data/vendor/pouchdb-collate/LICENSE +202 -0
  50. data/vendor/pouchdb-collate/pouchdb-collate.js +430 -0
  51. metadata +47 -36
  52. data/.ruby-version +0 -1
  53. data/.travis.yml +0 -21
  54. data/gemfiles/active_support_4_0 +0 -11
  55. data/gemfiles/active_support_4_1 +0 -11
  56. data/gemfiles/active_support_4_2 +0 -11
  57. data/lib/couch_potato/persistence/deep_dirty_attributes.rb +0 -180
  58. data/spec/unit/deep_dirty_attributes_spec.rb +0 -434
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  class DbTestUser
@@ -20,68 +22,67 @@ describe CouchPotato::Database, 'full_url_to_database' do
20
22
  CouchPotato::Config.database_name = @database_url
21
23
  end
22
24
 
23
- it "should return the full URL when it starts with https" do
24
- CouchPotato::Config.database_name = "https://example.com/database"
25
+ it 'should return the full URL when it starts with https' do
26
+ CouchPotato::Config.database_name = 'https://example.com/database'
25
27
  expect(CouchPotato.full_url_to_database).to eq('https://example.com/database')
26
28
  end
27
29
 
28
- it "should return the full URL when it starts with http" do
29
- CouchPotato::Config.database_name = "http://example.com/database"
30
+ it 'should return the full URL when it starts with http' do
31
+ CouchPotato::Config.database_name = 'http://example.com/database'
30
32
  expect(CouchPotato.full_url_to_database).to eq('http://example.com/database')
31
33
  end
32
34
 
33
- it "should use localhost when no protocol was specified" do
34
- CouchPotato::Config.database_name = "database"
35
+ it 'should use localhost when no protocol was specified' do
36
+ CouchPotato::Config.database_name = 'database'
35
37
  expect(CouchPotato.full_url_to_database).to eq('http://127.0.0.1:5984/database')
36
38
  end
37
39
  end
38
40
 
39
41
  describe CouchPotato::Database, 'load' do
40
-
41
- let(:couchrest_db) { double('couchrest db', :info => nil).as_null_object }
42
+ let(:couchrest_db) { double('couchrest db', info: nil).as_null_object }
42
43
  let(:db) { CouchPotato::Database.new couchrest_db }
43
44
 
44
- it "should raise an exception if nil given" do
45
- expect {
45
+ it 'should raise an exception if nil given' do
46
+ expect do
46
47
  db.load nil
47
- }.to raise_error("Can't load a document without an id (got nil)")
48
+ end.to raise_error("Can't load a document without an id (got nil)")
48
49
  end
49
50
 
50
- it "should set itself on the model" do
51
+ it 'should set itself on the model' do
51
52
  user = double('user').as_null_object
52
53
  allow(DbTestUser).to receive(:new).and_return(user)
53
- allow(couchrest_db).to receive(:get).and_return DbTestUser.json_create({JSON.create_id => 'DbTestUser'})
54
+ allow(couchrest_db).to receive(:get).and_return DbTestUser.json_create({ JSON.create_id => 'DbTestUser' })
54
55
  expect(user).to receive(:database=).with(db)
55
56
  db.load '1'
56
57
  end
57
58
 
58
- it "should load namespaced models" do
59
- allow(couchrest_db).to receive(:get).and_return Parent::Child.json_create({JSON.create_id => 'Parent::Child'})
59
+ it 'should load namespaced models' do
60
+ allow(couchrest_db).to receive(:get).and_return Parent::Child.json_create({ JSON.create_id => 'Parent::Child' })
60
61
  expect(db.load('1').class).to eq(Parent::Child)
61
62
  end
62
63
 
63
- context "when several ids given" do
64
+ context 'when several ids given' do
64
65
  let(:doc1) { DbTestUser.new }
65
66
  let(:doc2) { DbTestUser.new }
66
67
  let(:response) do
67
- {"rows" => [{'doc' => nil}, {"doc" => doc1}, {"doc" => doc2}]}
68
+ { 'rows' => [{ 'doc' => nil }, { 'doc' => doc1 }, { 'doc' => doc2 }] }
68
69
  end
69
70
 
70
71
  before(:each) do
71
72
  allow(couchrest_db).to receive(:bulk_load) { response }
72
73
  end
73
74
 
74
- it "requests the couchrest bulk method" do
75
- expect(couchrest_db).to receive(:bulk_load).with(['1', '2', '3'])
76
- db.load ['1', '2', '3']
75
+ it 'requests the couchrest bulk method' do
76
+ expect(couchrest_db).to receive(:bulk_load).with(%w[1 2 3])
77
+ db.load %w[1 2 3]
77
78
  end
78
79
 
79
- it "returns only found documents" do
80
- expect(db.load(['1', '2', '3']).size).to eq(2)
80
+ it 'returns only found documents' do
81
+ expect(db.load(%w[1 2 3]).size).to eq(2)
81
82
  end
82
83
 
83
- it "writes itself to each of the documents" do
84
- db.load(['1', '2', '3']).each do |doc|
84
+ it 'writes itself to each of the documents' do
85
+ db.load(%w[1 2 3]).each do |doc|
85
86
  expect(doc.database).to eql(db)
86
87
  end
87
88
  end
@@ -90,39 +91,41 @@ describe CouchPotato::Database, 'load' do
90
91
  doc1 = double(:doc1)
91
92
  allow(doc1).to receive(:respond_to?).with(:database=) { false }
92
93
  allow(couchrest_db).to receive(:bulk_load) do
93
- {"rows" => [{'doc' => doc1}]}
94
+ { 'rows' => [{ 'doc' => doc1 }] }
94
95
  end
95
96
 
96
97
  expect(doc1).not_to receive(:database=)
97
98
 
98
99
  db.load(['1'])
99
100
  end
101
+
102
+ it 'returns an empty array when passing an empty array' do
103
+ expect(db.load([])).to eq([])
104
+ end
100
105
  end
101
106
  end
102
107
 
103
108
  describe CouchPotato::Database, 'load!' do
109
+ let(:db) { CouchPotato::Database.new(double('couchrest db', info: nil).as_null_object) }
104
110
 
105
- let(:db) { CouchPotato::Database.new(double('couchrest db', :info => nil).as_null_object) }
106
-
107
- it "should raise an error if no document found" do
111
+ it 'should raise an error if no document found' do
108
112
  allow(db.couchrest_database).to receive(:get).and_return(nil)
109
- expect {
113
+ expect do
110
114
  db.load! '1'
111
- }.to raise_error(CouchPotato::NotFound)
115
+ end.to raise_error(CouchPotato::NotFound)
112
116
  end
113
117
 
114
118
  it 'returns the found document' do
115
119
  doc = double(:doc).as_null_object
116
- allow(db.couchrest_database).to receive(:get) {doc}
120
+ allow(db.couchrest_database).to receive(:get) { doc }
117
121
  expect(db.load!('1')).to eq(doc)
118
122
  end
119
123
 
120
- context "when several ids given" do
121
-
124
+ context 'when several ids given' do
122
125
  let(:docs) do
123
126
  [
124
- DbTestUser.new(:id => '1'),
125
- DbTestUser.new(:id => '2')
127
+ DbTestUser.new(id: '1'),
128
+ DbTestUser.new(id: '2')
126
129
  ]
127
130
  end
128
131
 
@@ -130,17 +133,17 @@ describe CouchPotato::Database, 'load!' do
130
133
  allow(db).to receive(:load).and_return(docs)
131
134
  end
132
135
 
133
- it "raises an exception when not all documents could be found" do
134
- expect {
135
- db.load! ['1', '2', '3', '4']
136
- }.to raise_error(CouchPotato::NotFound, '3, 4')
136
+ it 'raises an exception when not all documents could be found' do
137
+ expect do
138
+ db.load! %w[1 2 3 4]
139
+ end.to raise_error(CouchPotato::NotFound, '3, 4')
137
140
  end
138
141
 
139
- it "raises no exception when all documents are found" do
140
- docs << DbTestUser.new(:id => '3')
141
- expect {
142
- db.load! ['1', '2', '3']
143
- }.not_to raise_error
142
+ it 'raises no exception when all documents are found' do
143
+ docs << DbTestUser.new(id: '3')
144
+ expect do
145
+ db.load! %w[1 2 3]
146
+ end.not_to raise_error
144
147
  end
145
148
  end
146
149
  end
@@ -150,9 +153,9 @@ describe CouchPotato::Database, 'save_document' do
150
153
  @db = CouchPotato::Database.new(double('couchrest db').as_null_object)
151
154
  end
152
155
 
153
- it "should set itself on the model for a new object before doing anything else" do
156
+ it 'should set itself on the model for a new object before doing anything else' do
154
157
  allow(@db).to receive(:valid_document?).and_return false
155
- user = double('user', :new? => true).as_null_object
158
+ user = double('user', new?: true).as_null_object
156
159
  expect(user).to receive(:database=).with(@db)
157
160
  @db.save_document user
158
161
  end
@@ -163,68 +166,68 @@ describe CouchPotato::Database, 'save_document' do
163
166
  validates_presence_of :name
164
167
  end
165
168
 
166
- it "should return false when creating a new document and the validations failed" do
169
+ it 'should return false when creating a new document and the validations failed' do
167
170
  expect(CouchPotato.database.save_document(Category.new)).to eq(false)
168
171
  end
169
172
 
170
- it "should return false when saving an existing document and the validations failed" do
171
- category = Category.new(:name => "pizza")
173
+ it 'should return false when saving an existing document and the validations failed' do
174
+ category = Category.new(name: 'pizza')
172
175
  expect(CouchPotato.database.save_document(category)).to eq(true)
173
176
  category.name = nil
174
177
  expect(CouchPotato.database.save_document(category)).to eq(false)
175
178
  end
176
179
 
177
- describe "when creating with validate options" do
178
- it "should not run the validations when saved with false" do
180
+ describe 'when creating with validate options' do
181
+ it 'should not run the validations when saved with false' do
179
182
  category = Category.new
180
183
  @db.save_document(category, false)
181
184
  expect(category.new?).to eq(false)
182
185
  end
183
186
 
184
- it "should run the validations when saved with true" do
187
+ it 'should run the validations when saved with true' do
185
188
  category = Category.new
186
189
  @db.save_document(category, true)
187
190
  expect(category.new?).to eq(true)
188
191
  end
189
192
 
190
- it "should run the validations when saved with default" do
193
+ it 'should run the validations when saved with default' do
191
194
  category = Category.new
192
195
  @db.save_document(category)
193
196
  expect(category.new?).to eq(true)
194
197
  end
195
198
  end
196
199
 
197
- describe "when updating with validate options" do
198
- it "should not run the validations when saved with false" do
199
- category = Category.new(:name => 'food')
200
+ describe 'when updating with validate options' do
201
+ it 'should not run the validations when saved with false' do
202
+ category = Category.new(name: 'food')
200
203
  @db.save_document(category)
201
204
  expect(category.new?).to be_falsey
202
205
  category.name = nil
203
206
  @db.save_document(category, false)
204
- expect(category.dirty?).to be_falsey
207
+ expect(category.changed?).to be_falsey
205
208
  end
206
209
 
207
- it "should run the validations when saved with true" do
208
- category = Category.new(:name => "food")
210
+ it 'should run the validations when saved with true' do
211
+ category = Category.new(name: 'food')
209
212
  @db.save_document(category)
210
213
  expect(category.new?).to eq(false)
211
214
  category.name = nil
212
215
  @db.save_document(category, true)
213
- expect(category.dirty?).to eq(true)
216
+ expect(category.changed?).to eq(true)
214
217
  expect(category.valid?).to eq(false)
215
218
  end
216
219
 
217
- it "should run the validations when saved with default" do
218
- category = Category.new(:name => "food")
220
+ it 'should run the validations when saved with default' do
221
+ category = Category.new(name: 'food')
219
222
  @db.save_document(category)
220
223
  expect(category.new?).to eq(false)
221
224
  category.name = nil
222
225
  @db.save_document(category)
223
- expect(category.dirty?).to eq(true)
226
+ expect(category.changed?).to eq(true)
224
227
  end
225
228
  end
226
229
 
227
- describe "when saving documents with errors set in callbacks" do
230
+ describe 'when saving documents with errors set in callbacks' do
228
231
  class Vulcan
229
232
  include CouchPotato::Persistence
230
233
  before_validation_on_create :set_errors
@@ -234,18 +237,18 @@ describe CouchPotato::Database, 'save_document' do
234
237
  validates_presence_of :name
235
238
 
236
239
  def set_errors
237
- errors.add(:validation, "failed")
240
+ errors.add(:validation, 'failed')
238
241
  end
239
242
  end
240
243
 
241
- it "should keep errors added in before_validation_on_* callbacks when creating a new object" do
242
- spock = Vulcan.new(:name => 'spock')
244
+ it 'should keep errors added in before_validation_on_* callbacks when creating a new object' do
245
+ spock = Vulcan.new(name: 'spock')
243
246
  @db.save_document(spock)
244
247
  expect(spock.errors[:validation]).to eq(['failed'])
245
248
  end
246
249
 
247
- it "should keep errors added in before_validation_on_* callbacks when creating a new object" do
248
- spock = Vulcan.new(:name => 'spock')
250
+ it 'should keep errors added in before_validation_on_* callbacks when creating a new object' do
251
+ spock = Vulcan.new(name: 'spock')
249
252
  @db.save_document(spock, false)
250
253
  expect(spock.new?).to eq(false)
251
254
  spock.name = "spock's father"
@@ -253,14 +256,14 @@ describe CouchPotato::Database, 'save_document' do
253
256
  expect(spock.errors[:validation]).to eq(['failed'])
254
257
  end
255
258
 
256
- it "should keep errors generated from normal validations together with errors set in normal validations" do
259
+ it 'should keep errors generated from normal validations together with errors set in normal validations' do
257
260
  spock = Vulcan.new
258
261
  @db.save_document(spock)
259
262
  expect(spock.errors[:validation]).to eq(['failed'])
260
263
  expect(spock.errors[:name].first).to match(/can't be (empty|blank)/)
261
264
  end
262
265
 
263
- it "should clear errors on subsequent, valid saves when creating" do
266
+ it 'should clear errors on subsequent, valid saves when creating' do
264
267
  spock = Vulcan.new
265
268
  @db.save_document(spock)
266
269
 
@@ -269,8 +272,8 @@ describe CouchPotato::Database, 'save_document' do
269
272
  expect(spock.errors[:name]).to eq([])
270
273
  end
271
274
 
272
- it "should clear errors on subsequent, valid saves when updating" do
273
- spock = Vulcan.new(:name => 'spock')
275
+ it 'should clear errors on subsequent, valid saves when updating' do
276
+ spock = Vulcan.new(name: 'spock')
274
277
  @db.save_document(spock, false)
275
278
 
276
279
  spock.name = nil
@@ -281,7 +284,6 @@ describe CouchPotato::Database, 'save_document' do
281
284
  @db.save_document(spock)
282
285
  expect(spock.errors[:name]).to eq([])
283
286
  end
284
-
285
287
  end
286
288
  end
287
289
 
@@ -290,16 +292,16 @@ describe CouchPotato::Database, 'first' do
290
292
  @couchrest_db = double('couchrest db').as_null_object
291
293
  @db = CouchPotato::Database.new(@couchrest_db)
292
294
  @result = double('result')
293
- @spec = double('view spec', :process_results => [@result]).as_null_object
294
- allow(CouchPotato::View::ViewQuery).to receive_messages(:new => double('view query', :query_view! => {'rows' => [@result]}))
295
+ @spec = double('view spec', process_results: [@result]).as_null_object
296
+ allow(CouchPotato::View::ViewQuery).to receive_messages(new: double('view query', query_view!: { 'rows' => [@result] }))
295
297
  end
296
298
 
297
- it "should return the first result from a view query" do
299
+ it 'should return the first result from a view query' do
298
300
  expect(@db.first(@spec)).to eq(@result)
299
301
  end
300
302
 
301
- it "should return nil if there are no results" do
302
- allow(@spec).to receive_messages(:process_results => [])
303
+ it 'should return nil if there are no results' do
304
+ allow(@spec).to receive_messages(process_results: [])
303
305
  expect(@db.first(@spec)).to be_nil
304
306
  end
305
307
  end
@@ -309,19 +311,19 @@ describe CouchPotato::Database, 'first!' do
309
311
  @couchrest_db = double('couchrest db').as_null_object
310
312
  @db = CouchPotato::Database.new(@couchrest_db)
311
313
  @result = double('result')
312
- @spec = double('view spec', :process_results => [@result]).as_null_object
313
- allow(CouchPotato::View::ViewQuery).to receive_messages(:new => double('view query', :query_view! => {'rows' => [@result]}))
314
+ @spec = double('view spec', process_results: [@result]).as_null_object
315
+ allow(CouchPotato::View::ViewQuery).to receive_messages(new: double('view query', query_view!: { 'rows' => [@result] }))
314
316
  end
315
317
 
316
- it "returns the first result from a view query" do
318
+ it 'returns the first result from a view query' do
317
319
  expect(@db.first!(@spec)).to eq(@result)
318
320
  end
319
321
 
320
- it "raises an error if there are no results" do
321
- allow(@spec).to receive_messages(:process_results => [])
322
- expect {
322
+ it 'raises an error if there are no results' do
323
+ allow(@spec).to receive_messages(process_results: [])
324
+ expect do
323
325
  @db.first!(@spec)
324
- }.to raise_error(CouchPotato::NotFound)
326
+ end.to raise_error(CouchPotato::NotFound)
325
327
  end
326
328
  end
327
329
 
@@ -330,76 +332,80 @@ describe CouchPotato::Database, 'view' do
330
332
  @couchrest_db = double('couchrest db').as_null_object
331
333
  @db = CouchPotato::Database.new(@couchrest_db)
332
334
  @result = double('result')
333
- @spec = double('view spec', :process_results => [@result]).as_null_object
334
- allow(CouchPotato::View::ViewQuery).to receive_messages(:new => double('view query', :query_view! => {'rows' => [@result]}))
335
+ @spec = double('view spec', process_results: [@result]).as_null_object
336
+ allow(CouchPotato::View::ViewQuery).to receive_messages(new: double('view query', query_view!: { 'rows' => [@result] }))
335
337
  end
336
338
 
337
- it "initialzes a view query with map/reduce/list/lib funtions" do
338
- allow(@spec).to receive_messages(:design_document => 'design_doc', :view_name => 'my_view',
339
- :map_function => '<map_code>', :reduce_function => '<reduce_code>',
340
- :lib => {:test => '<test_code>'},
341
- :list_name => 'my_list', :list_function => '<list_code>', :language => 'javascript')
339
+ it 'initialzes a view query with map/reduce/list/lib funtions' do
340
+ allow(@spec).to receive_messages(design_document: 'design_doc', view_name: 'my_view',
341
+ map_function: '<map_code>', reduce_function: '<reduce_code>',
342
+ lib: { test: '<test_code>' },
343
+ list_name: 'my_list', list_function: '<list_code>', language: 'javascript')
342
344
  expect(CouchPotato::View::ViewQuery).to receive(:new).with(
343
345
  @couchrest_db,
344
346
  'design_doc',
345
- {'my_view' => {
346
- :map => '<map_code>',
347
- :reduce => '<reduce_code>'
348
- }},
349
- {'my_list' => '<list_code>'},
350
- {:test => '<test_code>'},
351
- 'javascript')
347
+ { 'my_view' => {
348
+ map: '<map_code>',
349
+ reduce: '<reduce_code>'
350
+ } },
351
+ { 'my_list' => '<list_code>' },
352
+ { test: '<test_code>' },
353
+ 'javascript'
354
+ )
352
355
  @db.view(@spec)
353
356
  end
354
357
 
355
- it "initialzes a view query with map/reduce/list funtions" do
356
- allow(@spec).to receive_messages(:design_document => 'design_doc', :view_name => 'my_view',
357
- :map_function => '<map_code>', :reduce_function => '<reduce_code>',
358
- :lib => nil, :list_name => 'my_list', :list_function => '<list_code>',
359
- :language => 'javascript')
358
+ it 'initialzes a view query with map/reduce/list funtions' do
359
+ allow(@spec).to receive_messages(design_document: 'design_doc', view_name: 'my_view',
360
+ map_function: '<map_code>', reduce_function: '<reduce_code>',
361
+ lib: nil, list_name: 'my_list', list_function: '<list_code>',
362
+ language: 'javascript')
360
363
  expect(CouchPotato::View::ViewQuery).to receive(:new).with(
361
364
  @couchrest_db,
362
365
  'design_doc',
363
- {'my_view' => {
364
- :map => '<map_code>',
365
- :reduce => '<reduce_code>'
366
- }},
367
- {'my_list' => '<list_code>'},
366
+ { 'my_view' => {
367
+ map: '<map_code>',
368
+ reduce: '<reduce_code>'
369
+ } },
370
+ { 'my_list' => '<list_code>' },
368
371
  nil,
369
- 'javascript')
372
+ 'javascript'
373
+ )
370
374
  @db.view(@spec)
371
375
  end
372
376
 
373
- it "initialzes a view query with only map/reduce/lib functions" do
374
- allow(@spec).to receive_messages(:design_document => 'design_doc', :view_name => 'my_view',
375
- :map_function => '<map_code>', :reduce_function => '<reduce_code>',
376
- :list_name => nil, :list_function => nil,
377
- :lib => {:test => '<test_code>'})
377
+ it 'initialzes a view query with only map/reduce/lib functions' do
378
+ allow(@spec).to receive_messages(design_document: 'design_doc', view_name: 'my_view',
379
+ map_function: '<map_code>', reduce_function: '<reduce_code>',
380
+ list_name: nil, list_function: nil,
381
+ lib: { test: '<test_code>' })
378
382
  expect(CouchPotato::View::ViewQuery).to receive(:new).with(
379
383
  @couchrest_db,
380
384
  'design_doc',
381
- {'my_view' => {
382
- :map => '<map_code>',
383
- :reduce => '<reduce_code>'
384
- }}, nil, {:test => '<test_code>'}, anything)
385
+ { 'my_view' => {
386
+ map: '<map_code>',
387
+ reduce: '<reduce_code>'
388
+ } }, nil, { test: '<test_code>' }, anything
389
+ )
385
390
  @db.view(@spec)
386
391
  end
387
392
 
388
- it "initialzes a view query with only map/reduce functions" do
389
- allow(@spec).to receive_messages(:design_document => 'design_doc', :view_name => 'my_view',
390
- :map_function => '<map_code>', :reduce_function => '<reduce_code>',
391
- :lib => nil, :list_name => nil, :list_function => nil)
393
+ it 'initialzes a view query with only map/reduce functions' do
394
+ allow(@spec).to receive_messages(design_document: 'design_doc', view_name: 'my_view',
395
+ map_function: '<map_code>', reduce_function: '<reduce_code>',
396
+ lib: nil, list_name: nil, list_function: nil)
392
397
  expect(CouchPotato::View::ViewQuery).to receive(:new).with(
393
398
  @couchrest_db,
394
399
  'design_doc',
395
- {'my_view' => {
396
- :map => '<map_code>',
397
- :reduce => '<reduce_code>'
398
- }}, nil, nil, anything)
400
+ { 'my_view' => {
401
+ map: '<map_code>',
402
+ reduce: '<reduce_code>'
403
+ } }, nil, nil, anything
404
+ )
399
405
  @db.view(@spec)
400
406
  end
401
407
 
402
- it "sets itself on returned results that have an accessor" do
408
+ it 'sets itself on returned results that have an accessor' do
403
409
  allow(@result).to receive(:respond_to?).with(:database=).and_return(true)
404
410
  expect(@result).to receive(:database=).with(@db)
405
411
  @db.view(@spec)
@@ -411,15 +417,51 @@ describe CouchPotato::Database, 'view' do
411
417
  @db.view(@spec)
412
418
  end
413
419
 
414
- it "does not try to set itself on result sets that are not collections" do
415
- expect {
416
- allow(@spec).to receive_messages(:process_results => 1)
417
- }.not_to raise_error
420
+ it 'does not try to set itself on result sets that are not collections' do
421
+ expect do
422
+ allow(@spec).to receive_messages(process_results: 1)
423
+ end.not_to raise_error
418
424
 
419
425
  @db.view(@spec)
420
426
  end
421
427
  end
422
428
 
429
+ describe CouchPotato::Database, '#view_in_batches' do
430
+ let(:view_query) do
431
+ instance_double(
432
+ CouchPotato::View::ViewQuery,
433
+ query_view!: { 'rows' => [result] }
434
+ )
435
+ end
436
+ let(:result) { double('result') }
437
+ let(:spec) { double('view spec', process_results: [result]).as_null_object }
438
+ let(:couchrest_db) { double('couchrest db').as_null_object }
439
+ let(:db) { CouchPotato::Database.new(couchrest_db) }
440
+
441
+ before(:each) do
442
+ allow(CouchPotato::View::ViewQuery)
443
+ .to receive_messages(new: view_query)
444
+ end
445
+
446
+ it 'sets skip/limit for each batch' do
447
+ allow(spec).to receive(:process_results).and_return([result, result], [result]) # run twice
448
+ allow(spec).to receive(:view_parameters) { { key: 'x' } }
449
+
450
+ expect(spec).to receive(:view_parameters=)
451
+ .with({key: 'x', skip: 0, limit: 2})
452
+ expect(spec).to receive(:view_parameters=)
453
+ .with({key: 'x', skip: 2, limit: 2})
454
+
455
+ db.view_in_batches(spec, batch_size: 2) { |results| }
456
+ end
457
+
458
+ it 'yields batches until running out of data' do
459
+ allow(spec).to receive(:process_results).and_return([result, result], [result])
460
+
461
+ expect { |b| db.view_in_batches(spec, batch_size: 2, &b) }.to yield_successive_args([result, result], [result])
462
+ end
463
+ end
464
+
423
465
  describe CouchPotato::Database, '#destroy' do
424
466
  it 'does not try to delete an already deleted document' do
425
467
  couchrest_db = double(:couchrest_db)
@@ -428,8 +470,70 @@ describe CouchPotato::Database, '#destroy' do
428
470
  document = double(:document, reload: nil).as_null_object
429
471
  allow(document).to receive(:run_callbacks).and_yield
430
472
 
431
- expect {
473
+ expect do
432
474
  db.destroy document
433
- }.to_not raise_error
475
+ end.to_not raise_error
476
+ end
477
+ end
478
+
479
+ describe CouchPotato::Database, '#switch_to' do
480
+ let(:couchrest_db) { instance_double(CouchRest::Database) }
481
+ let(:db) { CouchPotato::Database.new couchrest_db }
482
+
483
+ it 'returns the database with the given name' do
484
+ new_db = db.switch_to('db2')
485
+
486
+ expect(new_db.couchrest_database.name).to eq('db2')
487
+ end
488
+
489
+ it 'adds a cleared cache to the new database if the original has one' do
490
+ db.cache = { key: 'value' }
491
+ new_db = db.switch_to('db2')
492
+
493
+ expect(new_db.cache).to be_empty
494
+ end
495
+
496
+ it 'does not clear the cache of the original database' do
497
+ db.cache = { key: 'value' }
498
+ _new_db = db.switch_to('db2')
499
+
500
+ expect(db.cache).to have_key(:key)
501
+ end
502
+
503
+ it 'adds no cache to the new database if the original has none' do
504
+ new_db = db.switch_to('db2')
505
+
506
+ expect(new_db.cache).to be_nil
507
+ end
508
+ end
509
+
510
+ describe CouchPotato::Database, '#switch_to_default' do
511
+ let(:couchrest_db) { instance_double(CouchRest::Database) }
512
+ let(:db) { CouchPotato::Database.new couchrest_db }
513
+
514
+ it 'returns the default database' do
515
+ new_db = db.switch_to_default
516
+
517
+ expect(new_db.couchrest_database.name).to eq('couch_potato_test')
518
+ end
519
+
520
+ it 'adds a cleared cache to the new database if the original has one' do
521
+ db.cache = { key: 'value' }
522
+ new_db = db.switch_to_default
523
+
524
+ expect(new_db.cache).to be_empty
525
+ end
526
+
527
+ it 'does not clear the cache of the original database' do
528
+ db.cache = { key: 'value' }
529
+ _new_db = db.switch_to_default
530
+
531
+ expect(db.cache).to have_key(:key)
532
+ end
533
+
534
+ it 'adds no cache to the new database if the original has none' do
535
+ new_db = db.switch_to_default
536
+
537
+ expect(new_db.cache).to be_nil
434
538
  end
435
539
  end