amoeba 3.3.0 → 3.4.1

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.
@@ -1,418 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'amoeba' do
4
- context 'dup' do
5
- before do
6
- require ::File.dirname(__FILE__) + '/../support/data.rb'
7
- end
8
-
9
- let(:first_product) { Product.find(1) }
10
-
11
- it 'duplicates associated child records' do
12
- # Posts {{{
13
- old_post = ::Post.find(1)
14
- expect(old_post.comments.map(&:contents).include?('I love it!')).to be_truthy
15
-
16
- old_post.class.amoeba do
17
- prepend contents: "Here's a copy: "
18
- end
19
-
20
- new_post = old_post.amoeba_dup
21
-
22
- start_account_count = Account.all.count
23
- start_history_count = History.all.count
24
- start_cat_count = Category.all.count
25
- start_supercat_count = Supercat.all.count
26
- start_tag_count = Tag.all.count
27
- start_note_count = Note.all.count
28
- start_widget_count = Widget.all.count
29
- start_post_count = Post.all.count
30
- start_comment_count = Comment.all.count
31
- start_rating_count = Rating.all.count
32
- start_postconfig_count = PostConfig.all.count
33
- start_postwidget_count = PostWidget.all.count
34
- start_superkitten_count = Superkitten.all.count
35
- start_posttag_count = Post.tag_count
36
- start_postnote_count = Post.note_count
37
-
38
- expect(new_post.save!).to be_truthy
39
- expect(new_post.title).to eq("Copy of #{old_post.title}")
40
-
41
- end_account_count = Account.count
42
- end_history_count = History.count
43
- end_cat_count = Category.count
44
- end_supercat_count = Supercat.count
45
- end_tag_count = Tag.all.count
46
- end_note_count = Note.all.count
47
- end_widget_count = Widget.all.count
48
- end_post_count = Post.all.count
49
- end_comment_count = Comment.all.count
50
- end_rating_count = Rating.all.count
51
- end_postconfig_count = PostConfig.all.count
52
- end_postwidget_count = PostWidget.all.count
53
- end_superkitten_count = Superkitten.all.count
54
- end_posttag_count = Post.tag_count
55
- end_postnote_count = Post.note_count
56
-
57
- expect(end_tag_count).to eq(start_tag_count)
58
- expect(end_cat_count).to eq(start_cat_count)
59
- expect(end_account_count).to eq(start_account_count * 2)
60
- expect(end_history_count).to eq(start_history_count * 2)
61
- expect(end_supercat_count).to eq(start_supercat_count * 2)
62
- expect(end_post_count).to eq(start_post_count * 2)
63
- expect(end_comment_count).to eq((start_comment_count * 2) + 2)
64
- expect(end_rating_count).to eq(start_rating_count * 2)
65
- expect(end_postconfig_count).to eq(start_postconfig_count * 2)
66
- expect(end_posttag_count).to eq(start_posttag_count * 2)
67
- expect(end_widget_count).to eq(start_widget_count * 2)
68
- expect(end_postwidget_count).to eq(start_postwidget_count * 2)
69
- expect(end_note_count).to eq(start_note_count * 2)
70
- expect(end_postnote_count).to eq(start_postnote_count * 2)
71
- expect(end_superkitten_count).to eq(start_superkitten_count * 2)
72
-
73
- expect(new_post.supercats.map(&:ramblings)).to include('Copy of zomg')
74
- expect(new_post.supercats.map(&:other_ramblings).uniq.length).to eq(1)
75
- expect(new_post.supercats.map(&:other_ramblings).uniq).to include('La la la')
76
- expect(new_post.contents).to eq("Here's a copy: #{old_post.contents.gsub(/dog/,
77
- 'cat')} (copied version)")
78
- expect(new_post.comments.length).to eq(5)
79
- expect(new_post.comments.select do |c|
80
- c.nerf == 'ratatat' && c.contents.nil?
81
- end.length).to eq(1)
82
- expect(new_post.comments.select { |c| c.nerf == 'ratatat' }.length).to eq(2)
83
- expect(new_post.comments.select { |c| c.nerf == 'bonk' }.length).to eq(1)
84
- expect(new_post.comments.select do |c|
85
- c.nerf == 'bonkers' && c.contents.nil?
86
- end.length).to eq(1)
87
-
88
- new_post.widgets.map(&:id).each do |id|
89
- expect(old_post.widgets.map(&:id)).not_to include(id)
90
- end
91
-
92
- expect(new_post.custom_things.length).to eq(3)
93
- expect(new_post.custom_things.select { |ct| ct.value == [] }.length).to eq(1)
94
- expect(new_post.custom_things.select { |ct| ct.value == [1, 2] }.length).to eq(1)
95
- expect(new_post.custom_things.select { |ct| ct.value == [78] }.length).to eq(1)
96
- # }}}
97
- # Author {{{
98
- old_author = Author.find(1)
99
- new_author = old_author.amoeba_dup
100
- new_author.save!
101
- expect(new_author.errors.messages).to be_empty
102
- expect(new_author.posts.first.custom_things.length).to eq(3)
103
- expect(new_author.posts.first.custom_things.select { |ct| ct.value == [] }.length).to eq(1)
104
- expect(new_author.posts.first.custom_things.select do |ct|
105
- ct.value == [1, 2]
106
- end.length).to eq(1)
107
- expect(new_author.posts.first.custom_things.select { |ct| ct.value == [78] }.length).to eq(1)
108
- # }}}
109
- # Products {{{
110
- # Base Class {{{
111
-
112
- start_image_count = first_product.images.count
113
- start_section_count = Section.all.length
114
- start_prodsection_count = first_product.section_count
115
-
116
- new_product = first_product.amoeba_dup
117
- new_product.save
118
- expect(new_product.errors.messages).to be_empty
119
-
120
- end_image_count = first_product.images.count
121
- end_newimage_count = new_product.images.count
122
- end_section_count = Section.all.length
123
- end_prodsection_count = first_product.section_count
124
- end_newprodsection_count = new_product.section_count
125
-
126
- expect(end_image_count).to eq(start_image_count)
127
- expect(end_newimage_count).to eq(start_image_count)
128
- expect(end_section_count).to eq(start_section_count)
129
- expect(end_prodsection_count).to eq(start_prodsection_count)
130
- expect(end_newprodsection_count).to eq(start_prodsection_count)
131
- # }}}
132
-
133
- # Inherited Class {{{
134
- # Shirt {{{
135
- old_product = Shirt.find(2)
136
-
137
- start_image_count = old_product.images.count
138
- start_section_count = Section.count
139
- start_prodsection_count = old_product.section_count
140
-
141
- new_product = old_product.amoeba_dup
142
- new_product.save
143
- expect(new_product.errors.messages).to be_empty
144
-
145
- end_image_count = old_product.images.count
146
- end_newimage_count = new_product.images.count
147
- end_section_count = Section.count
148
- end_prodsection_count = first_product.section_count
149
- end_newprodsection_count = new_product.section_count
150
-
151
- expect(end_image_count).to eq(start_image_count)
152
- expect(end_newimage_count).to eq(start_image_count)
153
- expect(end_section_count).to eq(start_section_count)
154
- expect(end_prodsection_count).to eq(start_prodsection_count)
155
- expect(end_newprodsection_count).to eq(start_prodsection_count)
156
- # }}}
157
-
158
- # Necklace {{{
159
- old_product = Necklace.find(3)
160
-
161
- start_image_count = old_product.images.count
162
- start_section_count = Section.count
163
- start_prodsection_count = old_product.section_count
164
-
165
- new_product = old_product.amoeba_dup
166
- new_product.save
167
- expect(new_product.errors.messages).to be_empty
168
-
169
- end_image_count = old_product.images.count
170
- end_newimage_count = new_product.images.count
171
- end_section_count = Section.count
172
- end_prodsection_count = first_product.section_count
173
- end_newprodsection_count = new_product.section_count
174
-
175
- expect(end_image_count).to eq(start_image_count)
176
- expect(end_newimage_count).to eq(start_image_count)
177
- expect(end_section_count).to eq(start_section_count)
178
- expect(end_prodsection_count).to eq(start_prodsection_count)
179
- expect(end_newprodsection_count).to eq(start_prodsection_count)
180
- # }}}
181
- # }}}
182
- # }}}
183
- end
184
- end
185
-
186
- context 'Using a if condition' do
187
- subject { post.amoeba_dup.save! }
188
-
189
- before(:all) do
190
- require ::File.dirname(__FILE__) + '/../support/data.rb'
191
- end
192
-
193
- before { ::Post.fresh_amoeba }
194
-
195
- let(:post) { Post.first }
196
-
197
- it 'includes an association with truthy condition' do
198
- ::Post.amoeba do
199
- include_association :comments, if: :truthy?
200
- end
201
- expect { subject }.to change(Comment, :count).by(3)
202
- end
203
-
204
- it 'does not include an association with a falsey condition' do
205
- ::Post.amoeba do
206
- include_association :comments, if: :falsey?
207
- end
208
- expect { subject }.not_to change(Comment, :count)
209
- end
210
-
211
- it 'excludes an association with a truthy condition' do
212
- ::Post.amoeba do
213
- exclude_association :comments, if: :truthy?
214
- end
215
- expect { subject }.not_to change(Comment, :count)
216
- end
217
-
218
- it 'does not exclude an association with a falsey condition' do
219
- ::Post.amoeba do
220
- exclude_association :comments, if: :falsey?
221
- end
222
- expect { subject }.to change(Comment, :count).by(3)
223
- end
224
-
225
- it 'includes associations from a given array with a truthy condition' do
226
- ::Post.amoeba do
227
- include_association [:comments], if: :truthy?
228
- end
229
- expect { subject }.to change(Comment, :count).by(3)
230
- end
231
-
232
- it 'does not include associations from a given array with a falsey condition' do
233
- ::Post.amoeba do
234
- include_association [:comments], if: :falsey?
235
- end
236
- expect { subject }.not_to change(Comment, :count)
237
- end
238
-
239
- it 'does exclude associations from a given array with a truthy condition' do
240
- ::Post.amoeba do
241
- exclude_association [:comments], if: :truthy?
242
- end
243
- expect { subject }.not_to change(Comment, :count)
244
- end
245
-
246
- it 'does not exclude associations from a given array with a falsey condition' do
247
- ::Post.amoeba do
248
- exclude_association [:comments], if: :falsey?
249
- end
250
- expect { subject }.to change(Comment, :count).by(3)
251
- end
252
- end
253
-
254
- context 'override' do
255
- before do
256
- ::Image.fresh_amoeba
257
- ::Image.amoeba do
258
- override ->(old, new) { new.product_id = 13 if old.filename == 'test.jpg' }
259
- end
260
- end
261
-
262
- it 'overrides fields' do
263
- image = ::Image.create(filename: 'test.jpg', product_id: 12)
264
- image_dup = image.amoeba_dup
265
- expect(image_dup.save).to be_truthy
266
- expect(image_dup.product_id).to eq(13)
267
- end
268
-
269
- it 'does not override fields' do
270
- image = ::Image.create(filename: 'test2.jpg', product_id: 12)
271
- image_dup = image.amoeba_dup
272
- expect(image_dup.save).to be_truthy
273
- expect(image_dup.product_id).to eq(12)
274
- end
275
- end
276
-
277
- context 'nullify' do
278
- before do
279
- ::Image.fresh_amoeba
280
- ::Image.amoeba do
281
- nullify :product_id
282
- end
283
- end
284
-
285
- let(:image) { ::Image.create(filename: 'test.jpg', product_id: 12) }
286
- let(:image_dup) { image.amoeba_dup }
287
-
288
- it 'nullifies fields' do
289
- expect(image_dup.save).to be_truthy
290
- expect(image_dup.product_id).to be_nil
291
- end
292
- end
293
-
294
- context 'strict propagate' do
295
- it 'calls #reset_amoeba' do
296
- expect(::SuperBlackBox).to receive(:reset_amoeba).and_call_original
297
- box = ::SuperBlackBox.create(title: 'Super Black Box', price: 9.99, length: 1, metal: '1')
298
- new_box = box.amoeba_dup
299
- expect(new_box.save).to be_truthy
300
- end
301
- end
302
-
303
- context 'remapping and custom dup method' do
304
- let(:prototype) { ObjectPrototype.new }
305
-
306
- context 'through' do
307
- it do
308
- real_object = prototype.amoeba_dup
309
- expect(real_object).to be_a(::RealObject)
310
- end
311
- end
312
-
313
- context 'remapper' do
314
- it do
315
- prototype.subobject_prototypes << SubobjectPrototype.new
316
- real_object = prototype.amoeba_dup
317
- expect(real_object.subobjects.length).to eq(1)
318
- end
319
- end
320
- end
321
-
322
- context 'preprocessing fields' do
323
- subject { super_admin.amoeba_dup }
324
-
325
- let(:super_admin) do
326
- ::SuperAdmin.create!(email: 'user@example.com', active: true, password: 'password')
327
- end
328
-
329
- it 'accepts "set" to set false to attribute' do
330
- expect(subject.active).to be false
331
- end
332
-
333
- it 'skips "prepend" if it equal to false' do
334
- expect(subject.password).to eq('password')
335
- end
336
- end
337
-
338
- context 'inheritance' do
339
- let(:box) { Box.create }
340
-
341
- it 'does not fail with a deep inheritance' do
342
- sub_sub_product = BoxSubSubProduct.create(title: 'Awesome shoes')
343
- another_product = BoxAnotherProduct.create(title: 'Cleaning product')
344
- sub_sub_product.update(box: box, another_product: another_product)
345
- expect(box.sub_products.first.another_product.title).to eq('Cleaning product')
346
- expect(box.amoeba_dup.sub_products.first.another_product.title).to eq('Cleaning product')
347
- end
348
- end
349
-
350
- context 'inheritance extended' do
351
- subject { stage.amoeba_dup }
352
-
353
- let(:stage) do
354
- stage = CustomStage.new(title: 'My Stage', external_id: 213)
355
- stage.listeners.build(name: 'John')
356
- stage.listeners.build(name: 'Helen')
357
- stage.specialists.build(name: 'Jack')
358
- stage.custom_rules.build(description: 'Kill all humans')
359
- stage.save!
360
- stage
361
- end
362
-
363
- it 'contains parent association and own associations', :aggregate_failures do
364
- subject
365
- expect { subject.save! }.to change(Listener, :count).by(2)
366
- .and change(Specialist, :count).by(1)
367
- .and change(
368
- CustomRule, :count
369
- ).by(1)
370
-
371
- expect(subject.title).to eq 'My Stage'
372
- expect(subject.external_id).to be_nil
373
- expect(subject.listeners.find_by(name: 'John')).not_to be_nil
374
- expect(subject.listeners.find_by(name: 'Helen')).not_to be_nil
375
- expect(subject.specialists.find_by(name: 'Jack')).not_to be_nil
376
- expect(subject.custom_rules.first.description).to eq 'Kill all humans'
377
- end
378
- end
379
-
380
- context 'polymorphic' do
381
- let(:company) { Company.find_by(name: 'ABC Industries') }
382
- let(:new_company) { company.amoeba_dup }
383
-
384
- it 'does not fail with a deep inheritance' do
385
- # employee = company.employees.where(name:'Joe').first
386
- start_company_count = Company.count
387
- start_customer_count = Customer.count
388
- start_employee_count = Employee.count
389
- start_address_count = Address.count
390
- start_photo_count = Photo.count
391
- new_company.name = "Copy of #{new_company.name}"
392
- new_company.save
393
- expect(Company.count).to eq(start_company_count + 1)
394
- expect(Customer.count).to eq(start_customer_count + 1)
395
- expect(Employee.count).to eq(start_employee_count + 1)
396
- expect(Address.count).to eq(start_address_count + 4)
397
- expect(Photo.count).to eq(start_photo_count + 2)
398
-
399
- new_company.reload # fully reload from database
400
- new_company_employees = new_company.employees
401
- expect(new_company_employees.count).to eq(1)
402
- new_company_employee_joe = new_company_employees.find_by(name: 'Joe')
403
- expect(new_company_employee_joe.photos.count).to eq(1)
404
- expect(new_company_employee_joe.photos.first.size).to eq(12_345)
405
- expect(new_company_employee_joe.addresses.count).to eq(2)
406
- expect(new_company_employee_joe.addresses.where(street: '123 My Street').count).to eq(1)
407
- expect(new_company_employee_joe.addresses.where(street: '124 My Street').count).to eq(1)
408
- new_company_customers = new_company.customers
409
- expect(new_company_customers.count).to eq(1)
410
- new_company_customer_my = new_company_customers.where(email: 'my@email.address').first
411
- expect(new_company_customer_my.photos.count).to eq(1)
412
- expect(new_company_customer_my.photos.first.size).to eq(54_321)
413
- expect(new_company_customer_my.addresses.count).to eq(2)
414
- expect(new_company_customer_my.addresses.where(street: '321 My Street').count).to eq(1)
415
- expect(new_company_customer_my.addresses.where(street: '321 My Drive').count).to eq(1)
416
- end
417
- end
418
- end
data/spec/spec_helper.rb DELETED
@@ -1,37 +0,0 @@
1
- require 'simplecov'
2
-
3
- SimpleCov.start do
4
- add_filter 'spec'
5
- minimum_coverage(76)
6
-
7
- if ENV['CI']
8
- require 'simplecov-lcov'
9
-
10
- SimpleCov::Formatter::LcovFormatter.config do |c|
11
- c.report_with_single_file = true
12
- c.single_report_path = 'coverage/lcov.info'
13
- end
14
-
15
- formatter SimpleCov::Formatter::LcovFormatter
16
- end
17
- end
18
-
19
- require 'active_record'
20
- require 'amoeba'
21
-
22
- adapter = if defined?(JRuby)
23
- require 'activerecord-jdbcsqlite3-adapter'
24
- 'jdbcsqlite3'
25
- else
26
- require 'sqlite3'
27
- 'sqlite3'
28
- end
29
-
30
- ActiveRecord::Base.establish_connection(adapter: adapter, database: ':memory:')
31
-
32
- ::RSpec.configure do |config|
33
- config.order = :default
34
- end
35
-
36
- load File.dirname(__FILE__) + '/support/schema.rb'
37
- load File.dirname(__FILE__) + '/support/models.rb'
data/spec/support/data.rb DELETED
@@ -1,106 +0,0 @@
1
- u1 = User.create(name: 'Robert Johnson', email: 'bob@crossroads.com')
2
- u2 = User.create(name: 'Miles Davis', email: 'miles@kindofblue.com')
3
-
4
- a1 = Author.create(full_name: 'Kermit The Vonnegut', nickname: 'kvsoitgoes')
5
- a2 = Author.create(full_name: 'Arthur Sees Clarck', nickname: 'strangewater')
6
-
7
- t = Topic.create(title: 'Ponies', description: 'Lets talk about my ponies.')
8
-
9
- # First Post {{{
10
- p1 = t.posts.create(owner: u1, author: a1, title: 'My little pony',
11
- contents: 'Lorum ipsum dolor rainbow bright. I like dogs, dogs are awesome.')
12
- f1 = p1.create_post_config(is_visible: true, is_open: false, password: 'abcdefg123')
13
- a1 = p1.create_account(title: 'Foo')
14
- h1 = p1.account.create_history(some_stuff: 'Bar')
15
- c1 = p1.comments.create(contents: 'I love it!', nerf: 'ratatat')
16
- [5, 5, 4, 3, 5, 5].each { |stars| c1.ratings.create(num_stars: stars) }
17
-
18
- c2 = p1.comments.create(contents: 'I hate it!', nerf: 'whapaow')
19
- [3, 1, 4, 1, 1, 2].each { |stars| c2.ratings.create(num_stars: stars) }
20
-
21
- c3 = p1.comments.create(contents: 'kthxbbq!!11!!!1!eleven!!', nerf: 'bonk')
22
- [0, 0, 1, 2, 1, 0].each { |stars| c3.ratings.create(num_stars: stars) }
23
-
24
- %w[funny wtf cats].each { |value| p1.tags << Tag.create(value: value) }
25
-
26
- ['My Sidebar', 'Photo Gallery', 'Share & Like'].each do |value|
27
- p1.widgets << Widget.create(value: value)
28
- end
29
-
30
- ['This is important', "You've been warned", "Don't forget"].each do |value|
31
- p1.notes << Note.create(value: value)
32
- end
33
-
34
- p1.save
35
-
36
- c1 = Category.create(title: 'Umbrellas', description: 'Clown fart')
37
- c2 = Category.create(title: 'Widgets', description: 'Humpty dumpty')
38
- c3 = Category.create(title: 'Wombats', description: 'Slushy mushy')
39
-
40
- s1 = Supercat.create(post: p1, category: c1, ramblings: 'zomg', other_ramblings: 'nerp')
41
- s2 = Supercat.create(post: p1, category: c2, ramblings: 'why', other_ramblings: 'narp')
42
- s3 = Supercat.create(post: p1, category: c3, ramblings: 'ohnoes', other_ramblings: 'blap')
43
-
44
- s1.superkittens.create(value: 'Fluffy')
45
- s1.superkittens.create(value: 'Buffy')
46
- s1.superkittens.create(value: 'Fuzzy')
47
-
48
- s2.superkittens.create(value: 'Hairball')
49
- s2.superkittens.create(value: 'Crosseye')
50
- s2.superkittens.create(value: 'Spot')
51
-
52
- s3.superkittens.create(value: 'Dopey')
53
- s3.superkittens.create(value: 'Sneezy')
54
- s3.superkittens.create(value: 'Sleepy')
55
-
56
- p1.custom_things.create([{ value: [1, 2] }, { value: [] }, { value: [78] }])
57
- # }}}
58
-
59
- # Product {{{
60
- product1 = Product.create(title: 'Sticky Notes 5-Pak', price: 5.99, weight: 0.56)
61
- shirt1 = Shirt.create(title: 'Fancy Shirt', price: 48.95, sleeve: 32, collar: 15.5)
62
- necklace1 = Necklace.create(title: 'Pearl Necklace', price: 2995.99, length: 18, metal: '14k')
63
-
64
- img1 = product1.images.create(filename: 'sticky.jpg')
65
- img2 = product1.images.create(filename: 'notes.jpg')
66
-
67
- img1 = shirt1.images.create(filename: '02948u31.jpg')
68
- img2 = shirt1.images.create(filename: 'zsif8327.jpg')
69
-
70
- img1 = necklace1.images.create(filename: 'ae02x9f1.jpg')
71
- img2 = necklace1.images.create(filename: 'cba9f912.jpg')
72
-
73
- office = Section.create(name: 'Office', num_employees: 2, total_sales: '1234.56')
74
- supplies = Section.create(name: 'Supplies', num_employees: 1, total_sales: '543.21')
75
- mens = Section.create(name: 'Mens', num_employees: 3, total_sales: '11982.63')
76
- apparel = Section.create(name: 'Apparel', num_employees: 5, total_sales: '1315.20')
77
- accessories = Section.create(name: 'Accessories', num_employees: 1, total_sales: '8992.34')
78
- jewelry = Section.create(name: 'Jewelry', num_employees: 3, total_sales: '25481.77')
79
-
80
- product1.sections << office
81
- product1.sections << supplies
82
- product1.save
83
-
84
- shirt1.sections << mens
85
- shirt1.sections << apparel
86
- shirt1.save
87
-
88
- necklace1.sections << jewelry
89
- necklace1.sections << accessories
90
- necklace1.save
91
-
92
- company = Company.create(name: 'ABC Industries')
93
- employee = company.employees.create(name: 'Joe', ssn: '1111111111', salary: 10_000.0)
94
- employee_address = employee.addresses.create(street: '123 My Street', unit: '103', city: 'Hollywood',
95
- state: 'CA', zip: '90210')
96
- employee_address_2 = employee.addresses.create(street: '124 My Street', unit: '103', city: 'Follywood',
97
- state: 'CA', zip: '90210')
98
- employee_photo = employee.photos.create(name: 'Portrait', size: 12_345)
99
- customer = company.customers.create(email: 'my@email.address', password: 'password')
100
- customer_address = customer.addresses.create(street: '321 My Street', unit: '301', city: 'Bollywood',
101
- state: 'IN', zip: '11111')
102
- customer_address_2 = customer.addresses.create(street: '321 My Drive', unit: '311', city: 'Mollywood',
103
- state: 'IN', zip: '21111')
104
- customer_photo = customer.photos.create(name: 'Mug Shot', size: 54_321)
105
-
106
- # }}}