deep_cloneable 2.3.0 → 3.1.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.
@@ -1,89 +0,0 @@
1
- GEM
2
- remote: http://rubygems.org/
3
- specs:
4
- activemodel (5.0.0.1)
5
- activesupport (= 5.0.0.1)
6
- activerecord (5.0.0.1)
7
- activemodel (= 5.0.0.1)
8
- activesupport (= 5.0.0.1)
9
- arel (~> 7.0)
10
- activesupport (5.0.0.1)
11
- concurrent-ruby (~> 1.0, >= 1.0.2)
12
- i18n (~> 0.7)
13
- minitest (~> 5.1)
14
- tzinfo (~> 1.1)
15
- addressable (2.4.0)
16
- appraisal (2.1.0)
17
- bundler
18
- rake
19
- thor (>= 0.14.0)
20
- arel (7.1.1)
21
- builder (3.2.2)
22
- concurrent-ruby (1.0.2)
23
- descendants_tracker (0.0.4)
24
- thread_safe (~> 0.3, >= 0.3.1)
25
- faraday (0.9.2)
26
- multipart-post (>= 1.2, < 3)
27
- git (1.2.9.1)
28
- github_api (0.14.5)
29
- addressable (~> 2.4.0)
30
- descendants_tracker (~> 0.0.4)
31
- faraday (~> 0.8, < 0.10)
32
- hashie (>= 3.4)
33
- oauth2 (~> 1.0)
34
- hashie (3.4.6)
35
- highline (1.6.21)
36
- i18n (0.7.0)
37
- jeweler (2.1.1)
38
- builder
39
- bundler (>= 1.0)
40
- git (>= 1.2.5)
41
- github_api
42
- highline (>= 1.6.15)
43
- nokogiri (>= 1.5.10)
44
- rake
45
- rdoc
46
- semver
47
- json (1.8.3)
48
- jwt (1.5.4)
49
- minitest (5.9.0)
50
- multi_json (1.12.1)
51
- multi_xml (0.5.5)
52
- multipart-post (2.0.0)
53
- nokogiri (1.5.11)
54
- oauth2 (1.2.0)
55
- faraday (>= 0.8, < 0.10)
56
- jwt (~> 1.0)
57
- multi_json (~> 1.3)
58
- multi_xml (~> 0.5)
59
- rack (>= 1.2, < 3)
60
- rack (1.6.4)
61
- rake (10.5.0)
62
- rdoc (4.2.2)
63
- json (~> 1.4)
64
- semver (1.0.1)
65
- sqlite3 (1.3.11)
66
- thor (0.19.1)
67
- thread_safe (0.3.5)
68
- tzinfo (1.2.2)
69
- thread_safe (~> 0.1)
70
-
71
- PLATFORMS
72
- ruby
73
-
74
- DEPENDENCIES
75
- activerecord (~> 5.0.0)
76
- appraisal
77
- git (~> 1.2.9)
78
- highline (~> 1.6.0)
79
- i18n (~> 0.7.0)
80
- jeweler
81
- minitest
82
- nokogiri (~> 1.5.0)
83
- rack (~> 1.6)
84
- rake (~> 10.4)
85
- rdoc (>= 2.4.2)
86
- sqlite3
87
-
88
- BUNDLED WITH
89
- 1.11.2
data/test/database.yml DELETED
@@ -1,6 +0,0 @@
1
- sqlite:
2
- adapter: sqlite
3
- database: ":memory:"
4
- sqlite3:
5
- adapter: sqlite3
6
- database: ":memory:"
data/test/models.rb DELETED
@@ -1,129 +0,0 @@
1
- module Animal
2
- class Human < ActiveRecord::Base
3
- has_many :pigs
4
-
5
- has_many :ownerships
6
- has_many :chickens, :through => :ownerships
7
- end
8
-
9
- class Pig < ActiveRecord::Base
10
- belongs_to :human
11
- end
12
-
13
- class Bird < ActiveRecord::Base
14
- belongs_to :planet
15
- end
16
-
17
- class Chicken < Bird
18
- has_many :ownerships
19
- has_many :humans, :through => :ownerships
20
- end
21
-
22
- class Dove < Bird
23
- end
24
-
25
- class Planet < ActiveRecord::Base
26
- has_many :birds
27
- end
28
-
29
-
30
- class Ownership < ActiveRecord::Base
31
- belongs_to :human
32
- belongs_to :chicken
33
-
34
- validates_uniqueness_of :chicken_id, :scope => :human_id
35
- end
36
-
37
- end
38
-
39
- class GoldPiece < ActiveRecord::Base; belongs_to :treasure end
40
- class Matey < ActiveRecord::Base; belongs_to :pirate end
41
- class BattleShip < ActiveRecord::Base; has_many :pirates, :as => :ship end
42
-
43
- class Parrot < ActiveRecord::Base
44
- belongs_to :pirate
45
- has_many :parrot_cages, :foreign_key => :owner_id, :inverse_of => :parrot, :class_name => 'Cage'
46
- attr_accessor :cloned_from_id
47
- end
48
-
49
- class Cage < ActiveRecord::Base
50
- belongs_to :parrot, :foreign_key => :owner_id, :inverse_of => :parrot_cages
51
- belongs_to :pirate, :foreign_key => :owner_id, :inverse_of => :pirate_cages
52
- end
53
-
54
- class Pirate < ActiveRecord::Base
55
- belongs_to :ship, :polymorphic => true
56
-
57
- has_many :mateys
58
- has_many :treasures, :foreign_key => 'owner'
59
- has_many :gold_pieces, :through => :treasures
60
- has_one :parrot
61
- has_many :pirate_cages, :inverse_of => :pirate, :foreign_key => :owner_id, :class_name => 'Cage'
62
-
63
- serialize :piastres
64
-
65
- attr_accessor :cloned_from_id
66
- end
67
-
68
- class Treasure < ActiveRecord::Base
69
- belongs_to :pirate, :foreign_key => :owner
70
- belongs_to :matey
71
- has_many :gold_pieces
72
- end
73
-
74
- class Person < ActiveRecord::Base
75
- has_and_belongs_to_many :cars
76
- end
77
-
78
- class Car < ActiveRecord::Base
79
- has_and_belongs_to_many :people
80
- end
81
-
82
- class Coin < ActiveRecord::Base
83
- has_and_belongs_to_many :people
84
- end
85
-
86
- class ChildWithValidation < ActiveRecord::Base
87
- belongs_to :parent, :class_name => 'ParentWithValidation'
88
- validates :name, :presence => true
89
- end
90
-
91
- class ParentWithValidation < ActiveRecord::Base
92
- has_many :children, :class_name => 'ChildWithValidation'
93
- validates :name, :presence => true
94
- end
95
-
96
- class Part < ActiveRecord::Base
97
- # belongs_to :parent_part, :class_name => 'Part'
98
- has_many :child_parts, :class_name => 'Part', :foreign_key => 'parent_part_id'
99
- end
100
-
101
- class Student < ActiveRecord::Base
102
- has_many :student_assignments, :dependent => :destroy
103
- has_many :subjects, :through => :student_assignments
104
- end
105
-
106
- class Subject < ActiveRecord::Base
107
- has_many :student_assignments, :dependent => :destroy
108
- has_many :students, :through => :student_assignments
109
- end
110
-
111
- class StudentAssignment < ActiveRecord::Base
112
- belongs_to :subject
113
- belongs_to :student
114
- end
115
-
116
- class Building < ActiveRecord::Base
117
- has_many :apartments
118
- has_many :contractors
119
- end
120
-
121
- class Apartment < ActiveRecord::Base
122
- belongs_to :building
123
- has_and_belongs_to_many :contractors
124
- end
125
-
126
- class Contractor < ActiveRecord::Base
127
- belongs_to :building
128
- has_and_belongs_to_many :apartments
129
- end
data/test/schema.rb DELETED
@@ -1,132 +0,0 @@
1
- ActiveRecord::Schema.define(:version => 1) do
2
- create_table :pirates, :force => true do |t|
3
- t.column :name, :string
4
- t.column :nick_name, :string, :default => 'no nickname'
5
- t.column :age, :string
6
- t.column :ship_id, :integer
7
- t.column :ship_type, :string
8
- t.column :piastres, :text, :default => [].to_yaml
9
- end
10
-
11
- create_table :parrots, :force => true do |t|
12
- t.column :name, :string
13
- t.column :age, :integer
14
- t.column :pirate_id, :integer
15
- end
16
-
17
- create_table :mateys, :force => true do |t|
18
- t.column :name, :string
19
- t.column :pirate_id, :integer
20
- end
21
-
22
- create_table :treasures, :force => true do |t|
23
- t.column :found_at, :string
24
- t.column :owner, :integer
25
- t.column :matey_id, :integer
26
- end
27
-
28
- create_table :cages, :force => true do |t|
29
- t.column :name, :string
30
- t.column :owner_id, :integer
31
- end
32
-
33
- create_table :gold_pieces, :force => true do |t|
34
- t.column :treasure_id, :integer
35
- end
36
-
37
- create_table :battle_ships, :force => true do |t|
38
- t.column :name, :string
39
- end
40
-
41
- create_table :pigs, :force => true do |t|
42
- t.column :name, :string
43
- t.column :human_id, :integer
44
- end
45
-
46
- create_table :humen, :force => true do |t|
47
- t.column :name, :string
48
- end
49
-
50
- create_table :planets, :force => true do |t|
51
- t.column :name, :string
52
- end
53
-
54
- create_table :birds, :force => true do |t|
55
- t.column :name, :string
56
- t.column :type, :string
57
- t.column :planet_id, :integer
58
- end
59
-
60
- create_table :ownerships, :force => true do |t|
61
- t.column :human_id, :integer
62
- t.column :chicken_id, :integer
63
- end
64
-
65
- create_table :cars, :force => true do |t|
66
- t.column :name, :string
67
- end
68
-
69
- create_table :coins, :force => true do |t|
70
- t.column :value, :integer
71
- end
72
-
73
- create_table :people, :force => true do |t|
74
- t.column :name, :string
75
- end
76
-
77
- create_table :cars_people, :id => false, :force => true do |t|
78
- t.column :car_id, :integer
79
- t.column :person_id, :integer
80
- end
81
-
82
- create_table :coins_people, :id => false, :force => true do |t|
83
- t.column :coin_id, :integer
84
- t.column :person_id, :integer
85
- end
86
-
87
- create_table :parent_with_validations, :force => true do |t|
88
- t.column :name, :string
89
- end
90
-
91
- create_table :child_with_validations, :force => true do |t|
92
- t.column :name, :string
93
- t.column :parent_with_validation_id, :integer
94
- end
95
-
96
- create_table :parts, :force => true do |t|
97
- t.column :name, :string
98
- t.column :parent_part_id, :integer
99
- end
100
-
101
- create_table :students, :force => true do |t|
102
- t.column :name, :string
103
- end
104
-
105
- create_table :subjects, :force => true do |t|
106
- t.column :name, :string
107
- end
108
-
109
- create_table :student_assignments, :force => true do |t|
110
- t.column :student_id, :integer
111
- t.column :subject_id, :integer
112
- end
113
-
114
- create_table :buildings, :force => true do |t|
115
- t.column :name, :string
116
- end
117
-
118
- create_table :apartments, :force => true do |t|
119
- t.column :number, :string
120
- t.column :building_id, :integer
121
- end
122
-
123
- create_table :contractors, :force => true do |t|
124
- t.column :name, :string
125
- t.column :building_id, :integer
126
- end
127
-
128
- create_table :apartments_contractors, :force => true do |t|
129
- t.column :apartment_id, :integer
130
- t.column :contractor_id, :integer
131
- end
132
- end
@@ -1,455 +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_find_in_dict_for_habtm
425
- apt = Apartment.create(:number => "101")
426
- contractor = Contractor.create(:name => "contractor", :apartments => [apt])
427
-
428
- apt.contractors = [contractor]
429
- apt.save!
430
-
431
- building = Building.create(:name => "Tall Building", :contractors => [contractor], :apartments => [apt])
432
-
433
- deep_clone = building.deep_clone(:include => [
434
- :apartments,
435
- {
436
- :contractors => [
437
- :apartments
438
- ]
439
- }
440
- ],
441
- :use_dictionary => true)
442
-
443
- deep_clone.save!
444
-
445
- assert_equal deep_clone.contractors.first.apartments.first.id, deep_clone.apartments.first.id
446
- assert_equal deep_clone.apartments.first.contractors.first.id, deep_clone.contractors.first.id
447
- end
448
-
449
- def test_should_not_make_attributes_dirty_for_exceptions
450
- deep_clone = @jack.deep_clone(:except => :name)
451
- assert_nil deep_clone.name
452
- refute deep_clone.name_changed?
453
- end
454
-
455
- end