1
- // Copyright © 2021 Kaleido, Inc.
1
+ // Copyright © 2024 Kaleido, Inc.
2
2
//
3
3
// SPDX-License-Identifier: Apache-2.0
4
4
//
@@ -18,6 +18,7 @@ package core
18
18
19
19
import (
20
20
"context"
21
+ "reflect"
21
22
"testing"
22
23
23
24
"github.com/hyperledger/firefly-common/pkg/fftypes"
@@ -97,6 +98,63 @@ func TestOperationTypes(t *testing.T) {
97
98
assert .False (t , op .IsBlockchainOperation ())
98
99
}
99
100
101
+ func TestOperationDeepCopy (t * testing.T ) {
102
+ op := & Operation {
103
+ ID : fftypes .NewUUID (),
104
+ Namespace : "ns1" ,
105
+ Transaction : fftypes .NewUUID (),
106
+ Type : OpTypeBlockchainInvoke ,
107
+ Status : OpStatusInitialized ,
108
+ Plugin : "fake" ,
109
+ Input : fftypes.JSONObject {"key" : "value" },
110
+ Output : fftypes.JSONObject {"result" : "success" },
111
+ Error : "error message" ,
112
+ Created : fftypes .Now (),
113
+ Updated : fftypes .Now (),
114
+ Retry : fftypes .NewUUID (),
115
+ }
116
+
117
+ copyOp := op .DeepCopy ()
118
+ shallowCopy := op // Shallow copy for showcasing that DeepCopy is a deep copy
119
+
120
+ // Ensure the data was copied correctly
121
+ assert .Equal (t , op .ID , copyOp .ID )
122
+ assert .Equal (t , op .Namespace , copyOp .Namespace )
123
+ assert .Equal (t , op .Transaction , copyOp .Transaction )
124
+ assert .Equal (t , op .Type , copyOp .Type )
125
+ assert .Equal (t , op .Status , copyOp .Status )
126
+ assert .Equal (t , op .Plugin , copyOp .Plugin )
127
+ assert .Equal (t , op .Input , copyOp .Input )
128
+ assert .Equal (t , op .Output , copyOp .Output )
129
+ assert .Equal (t , op .Error , copyOp .Error )
130
+ assert .Equal (t , op .Created , copyOp .Created )
131
+ assert .Equal (t , op .Updated , copyOp .Updated )
132
+ assert .Equal (t , op .Retry , copyOp .Retry )
133
+
134
+ // Modify the original and ensure the copy is not modified
135
+ * op .ID = * fftypes .NewUUID ()
136
+ assert .NotEqual (t , copyOp .ID , op .ID )
137
+
138
+ * op .Created = * fftypes .Now ()
139
+ assert .NotEqual (t , copyOp .Created , op .Created )
140
+
141
+ // Ensure the copy is a deep copy by comparing the pointers of the fields
142
+ assert .NotSame (t , copyOp .ID , op .ID )
143
+ assert .NotSame (t , copyOp .Created , op .Created )
144
+ assert .NotSame (t , copyOp .Updated , op .Updated )
145
+ assert .NotSame (t , copyOp .Transaction , op .Transaction )
146
+ assert .NotSame (t , copyOp .Retry , op .Retry )
147
+ assert .NotSame (t , copyOp .Input , op .Input )
148
+ assert .NotSame (t , copyOp .Output , op .Output )
149
+
150
+ // showcasing that the shallow copy is a shallow copy and the copied object value changed as well the pointer has the same address as the original
151
+ assert .Equal (t , shallowCopy .ID , op .ID )
152
+ assert .Same (t , shallowCopy .ID , op .ID )
153
+
154
+ // Ensure no new fields are added to the Operation struct
155
+ // If a new field is added, this test will fail and the DeepCopy function should be updated
156
+ assert .Equal (t , 12 , reflect .TypeOf (Operation {}).NumField ())
157
+ }
100
158
func TestParseNamespacedOpID (t * testing.T ) {
101
159
102
160
ctx := context .Background ()
@@ -124,3 +182,113 @@ func TestParseNamespacedOpID(t *testing.T) {
124
182
assert .Equal (t , "ns1" , ns )
125
183
126
184
}
185
+
186
+ func TestDeepCopyMapNil (t * testing.T ) {
187
+ original := map [string ]interface {}(nil )
188
+ copy := deepCopyMap (original )
189
+ assert .Nil (t , copy )
190
+ }
191
+
192
+ func TestDeepCopyMapEmpty (t * testing.T ) {
193
+ original := map [string ]interface {}{}
194
+ copy := deepCopyMap (original )
195
+ assert .NotNil (t , copy )
196
+ assert .Empty (t , copy )
197
+ }
198
+
199
+ func TestDeepCopyMapSimple (t * testing.T ) {
200
+ original := map [string ]interface {}{
201
+ "key1" : "value1" ,
202
+ "key2" : 42 ,
203
+ }
204
+ copy := deepCopyMap (original )
205
+ assert .Equal (t , original , copy )
206
+ }
207
+
208
+ func TestDeepCopyMapNestedMap (t * testing.T ) {
209
+ original := map [string ]interface {}{
210
+ "key1" : map [string ]interface {}{
211
+ "nestedKey1" : "nestedValue1" ,
212
+ },
213
+ }
214
+ copy := deepCopyMap (original )
215
+ assert .Equal (t , original , copy )
216
+ assert .NotSame (t , original ["key1" ], copy ["key1" ])
217
+ }
218
+
219
+ func TestDeepCopyMapNestedSlice (t * testing.T ) {
220
+ original := map [string ]interface {}{
221
+ "key1" : []interface {}{"value1" , 42 },
222
+ }
223
+ copy := deepCopyMap (original )
224
+ assert .Equal (t , original , copy )
225
+ assert .NotSame (t , original ["key1" ], copy ["key1" ])
226
+ }
227
+
228
+ func TestDeepCopyMapMixed (t * testing.T ) {
229
+ original := map [string ]interface {}{
230
+ "key1" : "value1" ,
231
+ "key2" : map [string ]interface {}{
232
+ "nestedKey1" : "nestedValue1" ,
233
+ },
234
+ "key3" : []interface {}{"value1" , 42 },
235
+ }
236
+ copy := deepCopyMap (original )
237
+ assert .Equal (t , original , copy )
238
+ assert .NotSame (t , original ["key2" ], copy ["key2" ])
239
+ assert .NotSame (t , original ["key3" ], copy ["key3" ])
240
+ }
241
+
242
+ func TestDeepCopySliceNil (t * testing.T ) {
243
+ original := []interface {}(nil )
244
+ copy := deepCopySlice (original )
245
+ assert .Nil (t , copy )
246
+ }
247
+
248
+ func TestDeepCopySliceEmpty (t * testing.T ) {
249
+ original := []interface {}{}
250
+ copy := deepCopySlice (original )
251
+ assert .NotNil (t , copy )
252
+ assert .Empty (t , copy )
253
+ }
254
+
255
+ func TestDeepCopySliceSimple (t * testing.T ) {
256
+ original := []interface {}{"value1" , 42 }
257
+ copy := deepCopySlice (original )
258
+ assert .Equal (t , original , copy )
259
+ }
260
+
261
+ func TestDeepCopySliceNestedMap (t * testing.T ) {
262
+ original := []interface {}{
263
+ map [string ]interface {}{
264
+ "nestedKey1" : "nestedValue1" ,
265
+ },
266
+ }
267
+ copy := deepCopySlice (original )
268
+ assert .Equal (t , original , copy )
269
+ assert .NotSame (t , original [0 ], copy [0 ])
270
+ }
271
+
272
+ func TestDeepCopySliceNestedSlice (t * testing.T ) {
273
+ original := []interface {}{
274
+ []interface {}{"value1" , 42 },
275
+ }
276
+ copy := deepCopySlice (original )
277
+ assert .Equal (t , original , copy )
278
+ assert .NotSame (t , original [0 ], copy [0 ])
279
+ }
280
+
281
+ func TestDeepCopySliceMixed (t * testing.T ) {
282
+ original := []interface {}{
283
+ "value1" ,
284
+ 42 ,
285
+ map [string ]interface {}{
286
+ "nestedKey1" : "nestedValue1" ,
287
+ },
288
+ []interface {}{"value2" , 43 },
289
+ }
290
+ copy := deepCopySlice (original )
291
+ assert .Equal (t , original , copy )
292
+ assert .NotSame (t , original [2 ], copy [2 ])
293
+ assert .NotSame (t , original [3 ], copy [3 ])
294
+ }
0 commit comments