couch_potato 1.7.1 → 1.9.0

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