deep_cloneable 2.3.2 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,476 +0,0 @@
1
- require 'test_helper'
2
-
3
- class TestDeepCloneable < MiniTest::Unit::TestCase
4
-
5
- def setup
6
- @jack = Pirate.create(:name => 'Jack Sparrow', :nick_name => 'Captain Jack', :age => 30)
7
- @polly = Parrot.create(:name => 'Polly', :age => 2, :pirate => @jack)
8
- @john = Matey.create(:name => 'John', :pirate => @jack)
9
- @treasure = Treasure.create(:found_at => 'Isla del Muerte', :pirate => @jack, :matey => @john)
10
- @gold_piece = GoldPiece.create(:treasure => @treasure)
11
- @ship = BattleShip.create(:name => 'Black Pearl', :pirates => [@jack])
12
- end
13
-
14
- def test_single_deep_clone_exception
15
- deep_clone = @jack.deep_clone(:except => :name)
16
- assert deep_clone.new_record?
17
- assert deep_clone.save
18
- assert_equal @jack.name, @jack.deep_clone.name
19
- assert_nil deep_clone.name
20
- assert_equal @jack.nick_name, deep_clone.nick_name
21
- end
22
-
23
- def test_multiple_deep_clone_exception
24
- deep_clone = @jack.deep_clone(:except => [:name, :nick_name])
25
- assert deep_clone.new_record?
26
- assert deep_clone.save
27
- assert_nil deep_clone.name
28
- assert_equal 'no nickname', deep_clone.nick_name
29
- assert_equal @jack.age, deep_clone.age
30
- end
31
-
32
- def test_single_deep_clone_onliness
33
- deep_clone = @jack.deep_clone(:only => :name)
34
- assert deep_clone.new_record?
35
- assert deep_clone.piastres, []
36
- assert deep_clone.save
37
- assert_equal @jack.name, deep_clone.name
38
- assert_equal 'no nickname', deep_clone.nick_name
39
- assert_nil deep_clone.age
40
- assert_nil deep_clone.ship_id
41
- assert_nil deep_clone.ship_type
42
- end
43
-
44
- def test_multiple_deep_clone_onliness
45
- deep_clone = @jack.deep_clone(:only => [:name, :nick_name])
46
- assert deep_clone.new_record?
47
- assert deep_clone.piastres, []
48
- assert deep_clone.save
49
- assert_equal @jack.name, deep_clone.name
50
- assert_equal @jack.nick_name, deep_clone.nick_name
51
- assert_nil deep_clone.age
52
- assert_nil deep_clone.ship_id
53
- assert_nil deep_clone.ship_type
54
- end
55
-
56
- def test_single_include_association
57
- deep_clone = @jack.deep_clone(:include => :mateys)
58
- assert deep_clone.new_record?
59
- assert deep_clone.save
60
- assert_equal 1, deep_clone.mateys.size
61
- end
62
-
63
- def test_single_include_belongs_to_polymorphic_association
64
- deep_clone = @jack.deep_clone(:include => :ship)
65
- assert deep_clone.new_record?
66
- assert deep_clone.save
67
- refute_nil deep_clone.ship
68
- refute_equal @jack.ship, deep_clone.ship
69
- end
70
-
71
- def test_single_include_has_many_polymorphic_association
72
- deep_clone = @ship.deep_clone(:include => :pirates)
73
- assert deep_clone.new_record?
74
- assert deep_clone.save
75
- assert deep_clone.pirates.any?
76
- end
77
-
78
- def test_multiple_include_association
79
- deep_clone = @jack.deep_clone(:include => [:mateys, :treasures])
80
- assert deep_clone.new_record?
81
- assert deep_clone.save
82
- assert_equal 1, deep_clone.mateys.size
83
- assert_equal 1, deep_clone.treasures.size
84
- end
85
-
86
- def test_deep_include_association
87
- deep_clone = @jack.deep_clone(:include => {:treasures => :gold_pieces})
88
- assert deep_clone.new_record?
89
- assert deep_clone.save
90
- assert_equal 1, deep_clone.treasures.size
91
- assert_equal 1, deep_clone.gold_pieces.size
92
- end
93
-
94
- def test_include_association_assignments
95
- deep_clone = @jack.deep_clone(:include => :treasures)
96
- assert deep_clone.new_record?
97
-
98
- deep_clone.treasures.each do |treasure|
99
- assert_equal deep_clone, treasure.pirate
100
- end
101
- end
102
-
103
- def test_include_association_assignments_with_inverse_of
104
- @jack.pirate_cages.build
105
- deep_clone = @jack.deep_clone(:include => :pirate_cages)
106
- assert deep_clone.new_record?
107
- deep_clone.pirate_cages.each do |cage|
108
- assert_equal deep_clone, cage.pirate
109
- end
110
- end
111
-
112
- def test_multiple_and_deep_include_association
113
- deep_clone = @jack.deep_clone(:include => {:treasures => :gold_pieces, :mateys => {}})
114
- assert deep_clone.new_record?
115
- assert deep_clone.save
116
- assert_equal 1, deep_clone.treasures.size
117
- assert_equal 1, deep_clone.gold_pieces.size
118
- assert_equal 1, deep_clone.mateys.size
119
- end
120
-
121
- def test_multiple_and_deep_include_association_with_array
122
- deep_clone = @jack.deep_clone(:include => [{:treasures => :gold_pieces}, :mateys])
123
- assert deep_clone.new_record?
124
- assert deep_clone.save
125
- assert_equal 1, deep_clone.treasures.size
126
- assert_equal 1, deep_clone.gold_pieces.size
127
- assert_equal 1, deep_clone.mateys.size
128
- end
129
-
130
- def test_multiple_and_deep_include_association_with_array_and_multikey_hash
131
- deep_clone = @jack.deep_clone(:include => [:parrot, {:treasures => :gold_pieces, :mateys => {}}])
132
- assert deep_clone.new_record?
133
- assert deep_clone.save
134
- assert_equal 1, deep_clone.treasures.size
135
- assert_equal 1, deep_clone.gold_pieces.size
136
- assert_equal 1, deep_clone.mateys.size
137
- end
138
-
139
- def test_with_belongs_to_relation
140
- deep_clone = @jack.deep_clone(:include => :parrot)
141
- assert deep_clone.new_record?
142
- assert deep_clone.save
143
- refute_equal deep_clone.parrot, @jack.parrot
144
- end
145
-
146
- def test_should_pass_nested_exceptions
147
- deep_clone = @jack.deep_clone(:include => :parrot, :except => [:name, { :parrot => [:name] }])
148
- assert deep_clone.new_record?
149
- assert deep_clone.save
150
- refute_equal deep_clone.parrot, @jack.parrot
151
- assert_equal deep_clone.parrot.age, @jack.parrot.age
152
- refute_nil @jack.parrot.name
153
- assert_nil deep_clone.parrot.name
154
- end
155
-
156
- def test_should_pass_nested_onlinesses
157
- deep_clone = @jack.deep_clone(:include => :parrot, :only => [:name, { :parrot => [:name] }])
158
- assert deep_clone.new_record?
159
- assert deep_clone.piastres, []
160
- assert deep_clone.save
161
- refute_equal deep_clone.parrot, @jack.parrot
162
- assert_equal deep_clone.parrot.name, @jack.parrot.name
163
- assert_nil deep_clone.parrot.age
164
- end
165
-
166
- def test_should_not_double_deep_clone_when_using_dictionary
167
- current_matey_count = Matey.count
168
- deep_clone = @jack.deep_clone(:include => [:mateys, { :treasures => :matey }], :use_dictionary => true)
169
- assert deep_clone.new_record?
170
- deep_clone.save!
171
-
172
- assert_equal current_matey_count + 1, Matey.count
173
- end
174
-
175
- def test_should_not_double_deep_clone_when_using_manual_dictionary
176
- current_matey_count = Matey.count
177
-
178
- dict = { :mateys => {} }
179
- @jack.mateys.each{|m| dict[:mateys][m] = m.deep_clone }
180
-
181
- deep_clone = @jack.deep_clone(:include => [:mateys, { :treasures => :matey }], :dictionary => dict)
182
- assert deep_clone.new_record?
183
- deep_clone.save!
184
-
185
- assert_equal current_matey_count + 1, Matey.count
186
- end
187
-
188
- def test_should_support_ar_class_under_module
189
- @human = Animal::Human.create :name => "Michael"
190
- @pig = Animal::Pig.create :human => @human, :name => 'big pig'
191
-
192
- deep_clone_human = @human.deep_clone(:include => [:pigs])
193
- assert deep_clone_human.new_record?
194
- assert deep_clone_human.save
195
- assert_equal 1, deep_clone_human.pigs.count
196
-
197
- @human2 = Animal::Human.create :name => "John"
198
- @pig2 = @human2.pigs.create :name => 'small pig'
199
-
200
- deep_clone_human_2 = @human.deep_clone(:include => [:pigs])
201
- assert deep_clone_human_2.new_record?
202
- assert deep_clone_human_2.save
203
- assert_equal 1, deep_clone_human_2.pigs.count
204
- end
205
-
206
- def test_should_deep_clone_many_to_many_associations
207
- @human = Animal::Human.create :name => "Michael"
208
- @human2 = Animal::Human.create :name => "Jack"
209
- @chicken1 = Animal::Chicken.create :name => 'Chick1'
210
- @chicken2 = Animal::Chicken.create :name => 'Chick2'
211
- @human.chickens << [@chicken1, @chicken2]
212
- @human2.chickens << [@chicken1, @chicken2]
213
-
214
- deep_clone_human = @human.deep_clone(:include => :ownerships)
215
- assert deep_clone_human.new_record?
216
- assert deep_clone_human.save
217
- assert_equal 2, deep_clone_human.chickens.count
218
- end
219
-
220
- def test_should_skip_missing_associations
221
- @earth = Animal::Planet.create :name => 'Earth'
222
- @human = Animal::Human.create :name => "Michael"
223
- @chicken = Animal::Chicken.create :name => 'Chick', :humans => [@human], :planet => @earth, :humans => [@human]
224
- @dove = Animal::Dove.create :name => 'Dovey', :planet => @earth
225
-
226
- assert_raises ActiveRecord::Base::DeepCloneable::AssociationNotFoundException do
227
- @earth.deep_clone(:include => { :birds => :ownerships })
228
- end
229
-
230
- deep_clone_earth = @earth.deep_clone(:include => { :birds => :ownerships }, :skip_missing_associations => true)
231
- assert_equal 2, deep_clone_earth.birds.size
232
- assert deep_clone_earth.birds.detect{|bird| bird.is_a?(Animal::Chicken) }.ownerships.any?
233
- end
234
-
235
- def test_should_deep_clone_with_block
236
- deep_clone = @jack.deep_clone(:include => :parrot) do |original, kopy|
237
- kopy.cloned_from_id = original.id
238
- end
239
-
240
- assert deep_clone.new_record?
241
- assert deep_clone.save
242
- assert_equal @jack.id, deep_clone.cloned_from_id
243
- assert_equal @jack.parrot.id, deep_clone.parrot.cloned_from_id
244
- end
245
-
246
- def test_should_deep_clone_habtm_associations
247
- @person1 = Person.create :name => "Bill"
248
- @person2 = Person.create :name => "Ted"
249
- @car1 = Car.create :name => 'Mustang'
250
- @car2 = Car.create :name => 'Camaro'
251
- @person1.cars << [@car1, @car2]
252
- @person2.cars << [@car1, @car2]
253
-
254
- deep_clone_person = @person1.deep_clone :include => :cars
255
-
256
- assert deep_clone_person.new_record?
257
- assert_equal [@person1, @person2, deep_clone_person], @car1.people
258
- assert_equal [@person1, @person2, deep_clone_person], @car2.people
259
-
260
- assert deep_clone_person.save
261
-
262
- # did NOT deep_clone the Car instances
263
- assert_equal 2, Car.all.count
264
-
265
- # did deep_clone the correct join table rows
266
- assert_equal @person1.cars, deep_clone_person.cars
267
- assert_equal 2, deep_clone_person.cars.count
268
- end
269
-
270
- def test_should_deep_clone_habtm_associations_with_missing_reverse_association
271
- @coin = Coin.create :value => 1
272
- @person = Person.create :name => "Bill"
273
- @coin.people << @person
274
-
275
- deep_clone = @coin.deep_clone :include => :people
276
- assert deep_clone.new_record?
277
- assert_equal [@person], @coin.people
278
- assert deep_clone.save
279
- end
280
-
281
- def test_should_deep_clone_joined_association
282
- subject1 = Subject.create(:name => 'subject 1')
283
- subject2 = Subject.create(:name => 'subject 2')
284
- student = Student.create(:name => 'Parent', :subjects => [subject1, subject2])
285
-
286
- deep_clone = student.deep_clone :include => { :student_assignments => :subject }
287
- deep_clone.save # Subjects will have been set after save
288
- assert_equal 2, deep_clone.subjects.size
289
- [subject1, subject2].each{|subject| assert !deep_clone.subjects.include?(subject) }
290
- end
291
-
292
- def test_parent_validations_run_on_save_after_clone
293
- child = ChildWithValidation.create :name => 'Jimmy'
294
- parent = ParentWithValidation.new :children => [child]
295
- parent.save :validate => false
296
-
297
- deep_clone_parent = parent.deep_clone :include => :children
298
-
299
- assert !deep_clone_parent.save
300
- assert deep_clone_parent.new_record?
301
- assert !deep_clone_parent.valid?
302
- assert deep_clone_parent.children.first.valid?
303
- assert_equal deep_clone_parent.errors.messages, :name => ["can't be blank"]
304
- end
305
-
306
- def test_parent_validations_dont_run_on_save_after_clone
307
- child = ChildWithValidation.create :name => 'Jimmy'
308
- parent = ParentWithValidation.new :children => [child]
309
- parent.save :validate => false
310
-
311
- deep_clone_parent = parent.deep_clone :include => :children, :validate => false
312
-
313
- assert deep_clone_parent.save
314
- assert !deep_clone_parent.new_record?
315
- assert !deep_clone_parent.valid?
316
- assert deep_clone_parent.children.first.valid?
317
- assert_equal deep_clone_parent.errors.messages, :name => ["can't be blank"]
318
- end
319
-
320
- def test_child_validations_run_on_save_after_clone
321
- child = ChildWithValidation.new
322
- child.save :validate => false
323
- parent = ParentWithValidation.create :name => 'John', :children => [child]
324
-
325
- deep_clone_parent = parent.deep_clone :include => :children
326
-
327
- assert !deep_clone_parent.save
328
- assert deep_clone_parent.new_record?
329
- assert !deep_clone_parent.valid?
330
- assert !deep_clone_parent.children.first.valid?
331
- assert_equal deep_clone_parent.errors.messages, :children => ["is invalid"]
332
- end
333
-
334
- def test_child_validations_run_on_save_after_clone_without_validation
335
- child = ChildWithValidation.new
336
- child.save :validate => false
337
- parent = ParentWithValidation.create :name => 'John', :children => [child]
338
-
339
- deep_clone_parent = parent.deep_clone :include => :children, :validate => false
340
-
341
- assert deep_clone_parent.save
342
- assert !deep_clone_parent.new_record?
343
- assert !deep_clone_parent.valid?
344
- assert !deep_clone_parent.children.first.valid?
345
- assert_equal deep_clone_parent.errors.messages, :children => ["is invalid"]
346
- end
347
-
348
- def test_self_join_has_many
349
- parent_part = Part.create(:name => 'Parent')
350
- child1 = Part.create(:name => 'Child 1', :parent_part_id => parent_part.id)
351
- child2 = Part.create(:name => 'Child 2', :parent_part_id => parent_part.id)
352
-
353
- deep_clone_part = parent_part.deep_clone :include => :child_parts
354
- assert deep_clone_part.save
355
- assert_equal 2, deep_clone_part.child_parts.size
356
- end
357
-
358
- def test_should_include_has_many_through_associations
359
- subject1 = Subject.create(:name => 'subject 1')
360
- subject2 = Subject.create(:name => 'subject 2')
361
- student = Student.create(:name => 'Parent', :subjects => [subject1, subject2])
362
-
363
- deep_clone = student.deep_clone :include => :subjects
364
- assert_equal 2, deep_clone.subjects.size
365
- assert_equal [[student, deep_clone],[student, deep_clone]], deep_clone.subjects.map{|subject| subject.students }
366
- end
367
-
368
- def test_should_deep_clone_unsaved_objects
369
- jack = Pirate.new(:name => 'Jack Sparrow', :nick_name => 'Captain Jack', :age => 30)
370
- jack.mateys.build(:name => 'John')
371
-
372
- deep_clone = jack.deep_clone(:include => :mateys)
373
- assert deep_clone.new_record?
374
- assert_equal 1, deep_clone.mateys.size
375
- assert_equal 'John', deep_clone.mateys.first.name
376
- end
377
-
378
- def test_should_reject_copies_if_conditionals_are_passed
379
- subject1 = Subject.create(:name => 'subject 1')
380
- subject2 = Subject.create(:name => 'subject 2')
381
- student = Student.create(:name => 'Parent', :subjects => [subject1, subject2])
382
-
383
- deep_clone = student.deep_clone :include => { :subjects => { :if => lambda{|subject| subject.name == 'subject 2' } } }
384
- assert_equal 1, deep_clone.subjects.size
385
- assert_equal 'subject 2', deep_clone.subjects.first.name
386
-
387
- deep_clone = @jack.deep_clone(:include => {
388
- :treasures => { :gold_pieces => { :unless => lambda{|piece| piece.is_a?(Parrot) } } },
389
- :mateys => { :if => lambda{|matey| matey.is_a?(GoldPiece) } }
390
- })
391
-
392
- assert deep_clone.new_record?
393
- assert deep_clone.save
394
- assert_equal 1, deep_clone.treasures.size
395
- assert_equal 1, deep_clone.gold_pieces.size
396
- assert_equal 0, deep_clone.mateys.size
397
- end
398
-
399
- def test_should_properly_read_conditions_in_arrays
400
- subject1 = Subject.create(:name => 'subject 1')
401
- subject2 = Subject.create(:name => 'subject 2')
402
- student = Student.create(:name => 'Parent', :subjects => [subject1, subject2])
403
-
404
- deep_clone = student.deep_clone(:include => [:subjects => [:if => lambda{|subject| false }] ])
405
- assert deep_clone.subjects.none?
406
-
407
- deep_clone = student.deep_clone(:include => [:subjects => [:if => lambda{|subject| true }] ])
408
- assert_equal 2, deep_clone.subjects.size
409
- end
410
-
411
- def test_should_reject_copies_if_conditionals_are_passed_with_associations
412
- deep_clone = @ship.deep_clone(:include => [:pirates => [:treasures, :mateys, { :unless => lambda {|pirate| pirate.name == 'Jack Sparrow'} }]])
413
-
414
- assert deep_clone.new_record?
415
- assert deep_clone.save
416
- assert_equal 0, deep_clone.pirates.size
417
-
418
- deep_clone = @ship.deep_clone(:include => [:pirates => [:treasures, :mateys, { :if => lambda {|pirate| pirate.name == 'Jack Sparrow'} }]])
419
- assert deep_clone.new_record?
420
- assert deep_clone.save
421
- assert_equal 1, deep_clone.pirates.size
422
- end
423
-
424
- def test_should_reject_copies_if_conditionals_are_passed_with_nested_many_to_many_associations
425
- @user = User.create :name => 'Jack'
426
- @order1 = Order.create
427
- @order2 = Order.create
428
- @product1 = Product.create :name => 'Paper'
429
- @product2 = Product.create :name => 'Ink'
430
- @order2.products << [@product1, @product2]
431
- @user.orders << [@order1, @order2]
432
-
433
- deep_clone = @user.deep_clone(:include => [:orders => [:products => [{ :unless => lambda {|product| product.name == 'Ink' }}]]])
434
-
435
- assert deep_clone.new_record?
436
- assert deep_clone.save
437
- assert_equal 1, deep_clone.orders.second.products.size
438
-
439
- deep_clone = @user.deep_clone(:include => [:orders => [:products => [{ :if => lambda {|product| product.name == 'Ink'}}]]])
440
- assert deep_clone.new_record?
441
- assert deep_clone.save
442
- assert_equal 1, deep_clone.orders.second.products.size
443
- end
444
-
445
- def test_should_find_in_dict_for_habtm
446
- apt = Apartment.create(:number => "101")
447
- contractor = Contractor.create(:name => "contractor", :apartments => [apt])
448
-
449
- apt.contractors = [contractor]
450
- apt.save!
451
-
452
- building = Building.create(:name => "Tall Building", :contractors => [contractor], :apartments => [apt])
453
-
454
- deep_clone = building.deep_clone(:include => [
455
- :apartments,
456
- {
457
- :contractors => [
458
- :apartments
459
- ]
460
- }
461
- ],
462
- :use_dictionary => true)
463
-
464
- deep_clone.save!
465
-
466
- assert_equal deep_clone.contractors.first.apartments.first.id, deep_clone.apartments.first.id
467
- assert_equal deep_clone.apartments.first.contractors.first.id, deep_clone.contractors.first.id
468
- end
469
-
470
- def test_should_not_make_attributes_dirty_for_exceptions
471
- deep_clone = @jack.deep_clone(:except => :name)
472
- assert_nil deep_clone.name
473
- refute deep_clone.name_changed?
474
- end
475
-
476
- end
data/test/test_helper.rb DELETED
@@ -1,36 +0,0 @@
1
- require 'rubygems'
2
- require 'yaml'
3
- require 'sqlite3'
4
-
5
- gem 'minitest'
6
- require 'minitest/autorun'
7
-
8
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
9
- $LOAD_PATH.unshift(File.dirname(__FILE__))
10
-
11
- require 'active_record'
12
-
13
- I18n.enforce_available_locales = true
14
-
15
- def load_schema
16
- config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
17
-
18
- if defined?(ActiveSupport::BufferedLogger)
19
- ActiveRecord::Base.logger = ActiveSupport::BufferedLogger.new(File.dirname(__FILE__) + "/debug.log")
20
- else
21
- ActiveRecord::Base.logger = ActiveSupport::Logger.new(File.dirname(__FILE__) + "/debug.log")
22
- end
23
-
24
- db_adapter = ENV['DB']
25
- db_adapter ||= 'sqlite3'
26
-
27
- if db_adapter.nil?
28
- raise "No DB Adapter selected. Pass the DB= option to pick one, or install Sqlite or Sqlite3."
29
- end
30
- ActiveRecord::Base.establish_connection(config[db_adapter])
31
- load(File.dirname(__FILE__) + "/schema.rb")
32
- end
33
-
34
- load_schema
35
- require File.dirname(__FILE__) + '/../init.rb'
36
- require 'models'