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,434 +0,0 @@
1
- require 'spec_helper'
2
-
3
- class Cover
4
- include CouchPotato::Persistence
5
-
6
- def initialize(*args)
7
- self._id = SecureRandom.uuid
8
- super
9
- end
10
-
11
- property :color
12
- end
13
-
14
- class Page
15
- include CouchPotato::Persistence
16
-
17
- def initialize(*args)
18
- self._id = SecureRandom.uuid
19
- super
20
- end
21
-
22
- property :number
23
- property :headline
24
- end
25
-
26
- class Book
27
- include CouchPotato::Persistence
28
- include CouchPotato::Persistence::DeepDirtyAttributes
29
-
30
- property :title
31
- property :cover, :type => Cover
32
- property :authors, :type => [String]
33
- property :pages, :type => [Page]
34
- end
35
-
36
- class TextBook < Book
37
- property :edition
38
- end
39
-
40
- describe "deep dirty attribute tracking" do
41
- describe "standard dirty checking" do
42
- describe "_changed?" do
43
- it "should return true if only root simple properties have changed" do
44
- book = Book.new(:title => "A")
45
- book.title = "B"
46
- expect(book).to be_title_changed
47
- expect(book).to be_changed
48
- end
49
- end
50
-
51
- describe "_was" do
52
- it "gives access to old values of simple root properties" do
53
- book = Book.new(:title => "A")
54
- book.title = "B"
55
- expect(book.title_was).to eq("A")
56
- expect(book.title_change).to eq(["A", "B"])
57
- end
58
- end
59
-
60
- describe "_change" do
61
- it "returns standard _change" do
62
- book = Book.new(:title => "A")
63
- book.title = "B"
64
- expect(book.title_change).to eq(["A", "B"])
65
- end
66
- end
67
- end
68
-
69
- describe "single nested document" do
70
- describe "_changed?" do
71
- it "should return true if a nested attribute has changed" do
72
- book = Book.new(:cover => Cover.new(:color => "red"))
73
- book.cover.color = "blue"
74
- expect(book).to be_cover_changed
75
- expect(book).to be_changed
76
- end
77
-
78
- it "should return true if changed to a different document" do
79
- book = Book.new(:cover => Cover.new(:color => "red"))
80
- book.cover = Cover.new(:color => "blue")
81
- expect(book).to be_cover_changed
82
- expect(book).to be_changed
83
- end
84
-
85
- it "should return false if changed to a clone of the original document" do
86
- book = Book.new(:cover => Cover.new(:color => "red"))
87
- book.cover = book.cover.clone
88
- expect(book).not_to be_cover_changed
89
- expect(book).not_to be_changed
90
- end
91
-
92
- it "should return false if set to nil and unchanged" do
93
- book = Book.new
94
- expect(book).not_to be_cover_changed
95
- expect(book).not_to be_changed
96
- end
97
-
98
- it "should return true when reassigned with changes but the same _id" do
99
- book = Book.new(:cover => Cover.new(:_id => "cid", :color => "red"))
100
- book.cover = Cover.new(:_id => "cid", :color => "blue")
101
- expect(book).to be_cover_changed
102
- expect(book).to be_changed
103
- end
104
- end
105
-
106
- describe "_was" do
107
- it "gives access to the old value" do
108
- book = Book.new(:cover => Cover.new(:color => "red"))
109
- book.cover.color = "blue"
110
- expect(book.cover_was.color).to eq("red")
111
- end
112
- end
113
-
114
- describe "_change" do
115
- it "should return the standard changes when a nested document is reassigned" do
116
- book = Book.new(:cover => Cover.new(:color => "red"))
117
- book.cover = Cover.new(:color => "blue")
118
- expect(book.cover_change[0]).to be_a Cover
119
- expect(book.cover_change[0].color).to eq("red")
120
- expect(book.cover_change[1]).to be_a Cover
121
- expect(book.cover_change[1].color).to eq("blue")
122
- end
123
-
124
- it "should return the standard changes when a nested document is reassigned from nil" do
125
- book = Book.new
126
- book.cover = Cover.new
127
- expect(book.cover_change[0]).to eq(nil)
128
- expect(book.cover_change[1]).to eq(book.cover)
129
- end
130
-
131
- it "should return the standard changes when a nested document is reassigned to nil" do
132
- cover = Cover.new
133
- book = Book.new(:cover => cover)
134
- book.cover = nil
135
- expect(book.cover_change[0]).to eq(cover)
136
- expect(book.cover_change[1]).to eq(nil)
137
- end
138
-
139
- it "should return the nested changes when a nested document is changed" do
140
- book = Book.new(:cover => Cover.new(:color => "red"))
141
- book.cover.color = "blue"
142
- expect(book.cover_change[0]).to be_a Cover
143
- expect(book.cover_change[0].color).to eq("red")
144
- expect(book.cover_change[1]).to eq(book.cover.changes)
145
- end
146
-
147
- it "should return the nested changes when reassigned with changes but the same _id" do
148
- book = Book.new(:cover => Cover.new(:_id => "cid", :color => "red"))
149
- book.cover = Cover.new(:_id => "cid", :color => "blue")
150
- expect(book.cover_change[0]).to be_a Cover
151
- expect(book.cover_change[0].color).to eq("red")
152
- expect(book.cover_change[1]).to eq({"color" => ["red", "blue"]})
153
- end
154
- end
155
- end
156
-
157
- describe "simple array" do
158
- describe "_changed?" do
159
- it "returns true if the array is reassigned" do
160
- book = Book.new(:authors => ["Sarah"])
161
- book.authors = ["Jane"]
162
- expect(book).to be_authors_changed
163
- end
164
-
165
- it "returns true if an item is added" do
166
- book = Book.new(:authors => ["Jane"])
167
- book.authors << "Sue"
168
- expect(book).to be_authors_changed
169
- expect(book).to be_changed
170
- end
171
-
172
- it "returns true if an item is removed" do
173
- book = Book.new(:authors => ["Sue"])
174
- book.authors.delete "Sue"
175
- expect(book).to be_authors_changed
176
- expect(book).to be_changed
177
- end
178
-
179
- it "returns false if an empty array is unchanged" do
180
- book = Book.new(:authors => [])
181
- book.authors = []
182
- expect(book).not_to be_authors_changed
183
- expect(book).not_to be_changed
184
- end
185
- end
186
-
187
- describe "_was" do
188
- it "gives access to the old values" do
189
- book = Book.new(:authors => ["Jane"])
190
- book.authors << "Sue"
191
- expect(book.authors_was).to eq(["Jane"])
192
- end
193
- end
194
-
195
- describe "_change" do
196
- it "returns a hash of added and removed items" do
197
- book = Book.new(:authors => ["Jane"])
198
- book.authors << "Sue"
199
- book.authors.delete "Jane"
200
- expect(book.authors_change[0]).to eq(["Jane"])
201
- expect(book.authors_change[1]).to be_a HashWithIndifferentAccess
202
- expect(book.authors_change[1][:added]).to eq(["Sue"])
203
- expect(book.authors_change[1][:removed]).to eq(["Jane"])
204
- end
205
-
206
- it "returns a hash of added and removed items when the array is reassigned" do
207
- book = Book.new(:authors => ["Jane"])
208
- book.authors = ["Sue"]
209
- expect(book.authors_change[0]).to eq(["Jane"])
210
- expect(book.authors_change[1]).to be_a HashWithIndifferentAccess
211
- expect(book.authors_change[1][:added]).to eq(["Sue"])
212
- expect(book.authors_change[1][:removed]).to eq(["Jane"])
213
- end
214
-
215
- it "returns a hash of added items when the value is changed from nil to an array" do
216
- book = Book.new
217
- book.authors = ["Sue"]
218
- expect(book.authors_change[0]).to eq([])
219
- expect(book.authors_change[1]).to be_a HashWithIndifferentAccess
220
- expect(book.authors_change[1][:added]).to eq(["Sue"])
221
- expect(book.authors_change[1][:removed]).to eq([])
222
- end
223
-
224
- it "returns a hash of removed items when the value is changed from an array to nil" do
225
- book = Book.new(:authors => ["Jane"])
226
- book.authors = nil
227
- expect(book.authors_change[0]).to eq(["Jane"])
228
- expect(book.authors_change[1]).to be_a HashWithIndifferentAccess
229
- expect(book.authors_change[1][:added]).to eq([])
230
- expect(book.authors_change[1][:removed]).to eq(["Jane"])
231
- end
232
- end
233
- end
234
-
235
- describe "document array" do
236
- describe "_changed?" do
237
- it "returns true if an item is changed" do
238
- book = Book.new(:pages => [Page.new(:number => 1)])
239
- book.pages[0].number = 2
240
- expect(book).to be_pages_changed
241
- expect(book).to be_changed
242
- end
243
-
244
- it "returns true if an item is added" do
245
- book = Book.new(:pages => [Page.new(:number => 1)])
246
- book.pages << Page.new(:number => 2)
247
- expect(book).to be_pages_changed
248
- expect(book).to be_changed
249
- end
250
-
251
- it "returns true if an items is removed" do
252
- book = Book.new(:pages => [Page.new(:number => 1)])
253
- book.pages.delete_at 0
254
- expect(book).to be_pages_changed
255
- expect(book).to be_changed
256
- end
257
-
258
- it "returns true if an item is replaced" do
259
- book = Book.new(:pages => [Page.new(:number => 1)])
260
- book.pages[0] = Page.new(:number => 2)
261
- expect(book).to be_pages_changed
262
- expect(book).to be_changed
263
- end
264
-
265
- it "returns false if an item is replaced with a clone" do
266
- book = Book.new(:pages => [Page.new(:number => 1)])
267
- book.pages[0] = book.pages[0].clone
268
- expect(book).not_to be_pages_changed
269
- expect(book).not_to be_changed
270
- end
271
-
272
- it "returns true if an item is replaced with changes but the same _id" do
273
- book = Book.new(:pages => [Page.new(:_id => "pid", :number => 1)])
274
- book.pages[0] = Page.new(:_id => "pid", :number => 2)
275
- expect(book).to be_pages_changed
276
- expect(book).to be_changed
277
- end
278
-
279
- it "returns false if an empty array is unchanged" do
280
- book = Book.new(:pages => [])
281
- book.pages = []
282
- expect(book).not_to be_authors_changed
283
- expect(book).not_to be_changed
284
- end
285
- end
286
-
287
- describe "_was" do
288
- it "gives access to the old values" do
289
- book = Book.new(:pages => [Page.new(:number => 1)])
290
- book.pages[0].number = 2
291
- expect(book.pages_was[0].number).to eq(1)
292
- end
293
- end
294
-
295
- describe "_change" do
296
- it "returns a changes hash with added, removed, and changed items" do
297
- p1 = Page.new
298
- p2 = Page.new(:headline => "A")
299
- p3 = Page.new
300
- book = Book.new(:pages => [p1, p2])
301
- pages = book.pages.clone
302
- book.pages = [p2]
303
- p2.headline = "B"
304
- book.pages << p3
305
- expect(book.pages_change[0]).to eq(pages)
306
- expect(book.pages_change[1]).to be_a HashWithIndifferentAccess
307
- expect(book.pages_change[1][:added]).to eq([p3])
308
- expect(book.pages_change[1][:removed]).to eq([p1])
309
- expect(book.pages_change[1][:changed][0][0]).to be_a Page
310
- expect(book.pages_change[1][:changed][0][0].headline).to eq("A")
311
- expect(book.pages_change[1][:changed][0][1]).to eq(p2.changes)
312
- end
313
-
314
- it "returns added items when changing from nil to an array" do
315
- p1 = Page.new
316
- p2 = Page.new(:headline => "A")
317
- book = Book.new
318
- book.pages = [p1, p2]
319
- expect(book.pages_change[0]).to eq([])
320
- expect(book.pages_change[1]).to be_a HashWithIndifferentAccess
321
- expect(book.pages_change[1][:added]).to eq([p1, p2])
322
- expect(book.pages_change[1][:removed]).to eq([])
323
- expect(book.pages_change[1][:changed]).to eq([])
324
- end
325
-
326
- it "does not return unchanged cloned items as changes" do
327
- book = Book.new(:pages => [Page.new(:number => 1)])
328
- book.pages[0] = book.pages[0].clone
329
- expect(book.pages_change).to be_nil
330
- end
331
-
332
- it "returns changes if an item is replaced with changes but the same _id" do
333
- book = Book.new(:pages => [Page.new(:_id => "pid", :number => 1)])
334
- pages = book.pages.clone
335
- book.pages[0] = Page.new(:_id => "pid", :number => 2)
336
- expect(book.pages_change[0]).to eq(pages)
337
- expect(book.pages_change[1]).to be_a HashWithIndifferentAccess
338
- expect(book.pages_change[1][:added]).to eq([])
339
- expect(book.pages_change[1][:removed]).to eq([])
340
- expect(book.pages_change[1][:changed]).to eq([[pages[0], {"number" => [1, 2]}]])
341
- end
342
- end
343
- end
344
-
345
- describe "changes" do
346
- it "includes simple property changes" do
347
- book = Book.new(:title => "Title A")
348
- book.title = "Title B"
349
- expect(book.changes[:title]).to eq(book.title_change)
350
- end
351
-
352
- it "includes embedded document changes" do
353
- book = Book.new(:cover => Cover.new(:color => "red"))
354
- cover = book.cover.clone
355
- book.cover.color = "blue"
356
- expect(book.changes[:cover]).to eq(book.cover_change)
357
- end
358
-
359
- it "does not include unchanged embedded documents" do
360
- book = Book.new(:cover => Cover.new(:color => "red"))
361
- expect(book.changes).not_to have_key :cover
362
- end
363
-
364
- it "includes simple array changes" do
365
- book = Book.new(:authors => ["Sarah"])
366
- book.authors = ["Jane"]
367
- expect(book.changes[:authors]).to eq(book.authors_change)
368
- end
369
-
370
- it "does not include unchanged simple arrays" do
371
- book = Book.new(:authors => ["Sarah"])
372
- expect(book.changes).not_to have_key :authors
373
- end
374
-
375
- it "includes document array changes" do
376
- book = Book.new(:pages => [Page.new(:number => 1)])
377
- book.pages = [Page.new(:number => 2)]
378
- expect(book.changes[:pages]).to eq(book.pages_change)
379
- end
380
-
381
- it "does not include unchanged document arrays" do
382
- book = Book.new(:pages => [Page.new(:number => 1)])
383
- expect(book.changes).not_to have_key :pages
384
- end
385
- end
386
-
387
- describe "after save" do
388
- before :each do
389
- book = Book.json_create(:_id => "1", :title => "A", :cover => {:color => "red"}, :pages => [{:_id => "p1", :number => 1}, {:_id => "p2", :number => 2}])
390
- @couchrest_db = double('database', :info => nil, :save_doc => {}, :get => book)
391
- @db = CouchPotato::Database.new(@couchrest_db)
392
- @book = @db.load_document "1"
393
- end
394
-
395
- it "should reset all attributes to not dirty" do
396
- @book.title = "B"
397
- @book.cover.color = "blue"
398
- @db.save! @book
399
- expect(@book).not_to be_dirty
400
- expect(@book.cover).not_to be_dirty
401
- end
402
-
403
- it "should reset all elements in a document array" do
404
- @book.pages.each(&:is_dirty)
405
- @db.save! @book
406
- expect(@book).not_to be_dirty
407
- @book.pages.each do |page|
408
- expect(page).not_to be_dirty
409
- end
410
- end
411
-
412
- it "should reset a forced dirty state" do
413
- @book.is_dirty
414
- @db.save! @book
415
- expect(@book).not_to be_dirty
416
- end
417
-
418
- it "clears old values" do
419
- @book.cover.color = "blue"
420
- @db.save! @book
421
- expect(@book.cover_was).to be_nil
422
- expect(@book.cover_change).to be_nil
423
- end
424
- end
425
-
426
- describe "on inherited models" do
427
- it "still uses deep dirty tracking" do
428
- book = TextBook.new(:pages => [Page.new(:number => 1)])
429
- book.pages[0].number = 2
430
- expect(book).to be_pages_changed
431
- expect(book).to be_changed
432
- end
433
- end
434
- end