1
+ package com.baeldung.cloningobject
2
+
3
+ import org.assertj.core.api.Assertions.assertThat
4
+ import org.junit.jupiter.api.Test
5
+
6
+ data class Address (var street : String , var city : String ) : Cloneable {
7
+
8
+ public override fun clone () = Address (this .street, this .city)
9
+
10
+ constructor (address: Address ) : this (address.street, address.city)
11
+
12
+ fun deepCopy (
13
+ street : String = this.street,
14
+ city : String = this.city,
15
+ ) = Address (street, city)
16
+ }
17
+
18
+ data class Person (var name : String , var address : Address ) : Cloneable {
19
+
20
+ public override fun clone () = Person (name, this .address.clone())
21
+
22
+ constructor (person: Person ) : this (person.name, Address (person.address))
23
+
24
+ fun deepCopy (
25
+ name : String = this.name,
26
+ address : Address = this.address.deepCopy(),
27
+ ) = Person (name, address)
28
+ }
29
+
30
+ data class Company (var name : String , var industry : String , val ceo : Person , val employees : List <Person >) : Cloneable {
31
+
32
+ public override fun clone () = Company (name, industry, ceo.clone(), employees.map { it.clone() })
33
+
34
+ constructor (company: Company ) : this (company.name,
35
+ company.industry,
36
+ Person (company.ceo),
37
+ company.employees.map { Person (it) })
38
+
39
+ fun deepCopy (
40
+ name : String = this.name,
41
+ industry : String = this.industry,
42
+ ceo : Person = this.ceo.deepCopy(),
43
+ employees : List <Person > = this.employees.map { it.deepCopy() },
44
+ ) = Company (name, industry, ceo, employees)
45
+ }
46
+
47
+ data class Organization (var name : String , val headquarters : Address , val companies : List <Company >) : Cloneable {
48
+
49
+ public override fun clone () = Organization (name, headquarters.clone(), companies.map { it.clone() })
50
+
51
+ constructor (organization: Organization ) : this (organization.name,
52
+ Address (organization.headquarters),
53
+ organization.companies.map { Company (it) })
54
+
55
+ fun deepCopy (
56
+ name : String = this.name,
57
+ headquarters : Address = this.headquarters.deepCopy(),
58
+ companies : List <Company > = this.companies.map { it.deepCopy() },
59
+ ) = Organization (name, headquarters, companies)
60
+ }
61
+
62
+ class CloningObjectUnitTest {
63
+
64
+ private val personHangga = Person (" Hangga Aji Sayekti" , Address (" Jln. Kemasan No 53" , " Yogyakarta" ))
65
+ private val personRaihan = Person (" Raihan Kusumo" , Address (" Jln. Cikapayang No. 508" , " Medan" ))
66
+ private val personLayla = Person (" Layla Hinchcliffe" , Address (" Collins Street" , " Melbourne" ))
67
+ private val companyBasen = Company (" Basen Software" , " Tech" , personHangga, listOf (personRaihan, personLayla))
68
+
69
+ private val personBima = Person (" Bima Arya" , Address (" Jl. Colombo No. 7" , " Yogyakarta" ))
70
+ private val personDina = Person (" Dina Fitriani" , Address (" Jl. Kaliurang No. 12" , " Yogyakarta" ))
71
+ private val personCindy = Person (" Cindy Claudia" , Address (" Jl. Atmosukarto No. 1" , " Yogyakarta" ))
72
+ private val companyKotagede = Company (" Kotagede Software" , " Tech" , personBima, listOf (personCindy, personDina))
73
+
74
+ private val organization = Organization (" Bekraf" , Address (" Jalan Medan Merdeka Selatan" , " Jakarta" ), listOf (companyBasen, companyKotagede))
75
+
76
+ private fun modifyOrganization () {
77
+ organization.name = " New Org Name"
78
+ organization.headquarters.city = " New City"
79
+ organization.companies.first().name = " New Company Name"
80
+ organization.companies.first().ceo.name = " New CEO Name"
81
+ organization.companies.first().ceo.address.city = " New CEO Address City Name"
82
+ organization.companies.first().employees.first().name = " New Employee Name"
83
+ organization.companies.first().employees.first().address.city = " New Employee Address City Name"
84
+ }
85
+
86
+ @Test
87
+ fun `when cloned object with secondary constructor then proves that deep copy` () {
88
+ val clonedOrganization = Organization (organization)
89
+
90
+ modifyOrganization()
91
+
92
+ assertThat(clonedOrganization)
93
+ .isNotSameAs(organization)
94
+ assertThat(clonedOrganization.headquarters.city)
95
+ .isNotEqualTo(" New City" )
96
+ assertThat(clonedOrganization.companies.first().name)
97
+ .isNotEqualTo(" New Company Name" )
98
+ assertThat(clonedOrganization.companies.first().ceo.name)
99
+ .isNotEqualTo(" New CEO Name" )
100
+ assertThat(clonedOrganization.companies.first().ceo.address.city)
101
+ .isNotEqualTo(" New CEO Address City Name" )
102
+ assertThat(clonedOrganization.companies.first().employees.first().name)
103
+ .isNotEqualTo(" New Employee Name" )
104
+ assertThat(clonedOrganization.companies.first().employees.first().address.city)
105
+ .isNotEqualTo(" New Employee Address City Name" )
106
+ }
107
+
108
+ @Test
109
+ fun `when cloned object with deepCopy() then proves that deep copy` () {
110
+ val clonedOrganization = organization.deepCopy()
111
+
112
+ modifyOrganization()
113
+
114
+ assertThat(clonedOrganization)
115
+ .isNotSameAs(organization)
116
+ assertThat(clonedOrganization.headquarters.city)
117
+ .isNotEqualTo(" New City" )
118
+ assertThat(clonedOrganization.companies.first().name)
119
+ .isNotEqualTo(" New Company Name" )
120
+ assertThat(clonedOrganization.companies.first().ceo.name)
121
+ .isNotEqualTo(" New CEO Name" )
122
+ assertThat(clonedOrganization.companies.first().ceo.address.city)
123
+ .isNotEqualTo(" New CEO Address City Name" )
124
+ assertThat(clonedOrganization.companies.first().employees.first().name)
125
+ .isNotEqualTo(" New Employee Name" )
126
+ assertThat(clonedOrganization.companies.first().employees.first().address.city)
127
+ .isNotEqualTo(" New Employee Address City Name" )
128
+ }
129
+
130
+ @Test
131
+ fun `when cloned object with clone() then proves that deep copy` () {
132
+ val clonedOrganization = organization.clone()
133
+
134
+ modifyOrganization()
135
+
136
+ assertThat(clonedOrganization)
137
+ .isNotSameAs(organization)
138
+ assertThat(clonedOrganization.headquarters.city)
139
+ .isNotEqualTo(" New City" )
140
+ assertThat(clonedOrganization.companies.first().name)
141
+ .isNotEqualTo(" New Company Name" )
142
+ assertThat(clonedOrganization.companies.first().ceo.name)
143
+ .isNotEqualTo(" New CEO Name" )
144
+ assertThat(clonedOrganization.companies.first().ceo.address.city)
145
+ .isNotEqualTo(" New CEO Address City Name" )
146
+ assertThat(clonedOrganization.companies.first().employees.first().name)
147
+ .isNotEqualTo(" New Employee Name" )
148
+ assertThat(clonedOrganization.companies.first().employees.first().address.city)
149
+ .isNotEqualTo(" New Employee Address City Name" )
150
+ }
151
+
152
+ @Test
153
+ fun `when cloned object with copy() then proves that shallow copy` () {
154
+ val clonedOrganization = organization.copy()
155
+
156
+ modifyOrganization()
157
+
158
+ assertThat(clonedOrganization)
159
+ .isNotSameAs(organization)
160
+ assertThat(clonedOrganization.headquarters.city)
161
+ .isEqualTo(" New City" )
162
+ assertThat(clonedOrganization.companies.first().name)
163
+ .isEqualTo(" New Company Name" )
164
+ assertThat(clonedOrganization.companies.first().ceo.name)
165
+ .isEqualTo(" New CEO Name" )
166
+ assertThat(clonedOrganization.companies.first().ceo.address.city)
167
+ .isEqualTo(" New CEO Address City Name" )
168
+ assertThat(clonedOrganization.companies.first().employees.first().name)
169
+ .isEqualTo(" New Employee Name" )
170
+ assertThat(clonedOrganization.companies.first().employees.first().address.city)
171
+ .isEqualTo(" New Employee Address City Name" )
172
+ }
173
+
174
+ @Test
175
+ fun `when cloned object with copy() then proves that deep copy` () {
176
+
177
+ val clonedOrganization = organization.copy(
178
+ headquarters = organization.headquarters.copy(),
179
+ companies = organization.companies.map { company ->
180
+ company.copy(
181
+ ceo = company.ceo.copy(
182
+ address = company.ceo.address.copy()
183
+ ),
184
+ employees = company.employees.map { employee ->
185
+ employee.copy(
186
+ address = employee.address.copy()
187
+ )
188
+ }
189
+ )
190
+ }
191
+ )
192
+
193
+ modifyOrganization()
194
+
195
+ assertThat(clonedOrganization)
196
+ .isNotSameAs(organization)
197
+ assertThat(clonedOrganization.headquarters.city)
198
+ .isNotEqualTo(" New City" )
199
+ assertThat(clonedOrganization.companies.first().name)
200
+ .isNotEqualTo(" New Company Name" )
201
+ assertThat(clonedOrganization.companies.first().ceo.name)
202
+ .isNotEqualTo(" New CEO Name" )
203
+ assertThat(clonedOrganization.companies.first().ceo.address.city)
204
+ .isNotEqualTo(" New CEO Address City Name" )
205
+ assertThat(clonedOrganization.companies.first().employees.first().name)
206
+ .isNotEqualTo(" New Employee Name" )
207
+ assertThat(clonedOrganization.companies.first().employees.first().address.city)
208
+ .isNotEqualTo(" New Employee Address City Name" )
209
+ }
210
+ }
0 commit comments