github.com/litesolutions/justifay-api@v1.0.0-2.0.20220707114139-46f28a909481/internal/pkg/structs/merge_test.go (about) 1 package structs_test 2 3 import ( 4 "testing" 5 6 "github.com/litesolutions/justifay-api/internal/pkg/structs" 7 "github.com/stretchr/testify/assert" 8 ) 9 10 type carID int64 11 12 type mergeStruct struct { 13 Name string 14 Surname string 15 SomeID int64 16 Cars []string 17 CarIDs []carID 18 CustomStruct customStruct 19 CustomStructSlice []customStruct 20 IgnoredField string 21 PointerField *string 22 SkipField map[string]string 23 } 24 25 type customStruct struct { 26 isLoved bool 27 isHated bool 28 } 29 30 type mergeCmd struct { 31 Name *string 32 Surname *string 33 SomeID *int64 34 Cars []string 35 CarIDs []carID 36 CustomStruct *customStruct 37 CustomStructSlice []customStruct 38 IgnoredField *string `structs:"-"` 39 PointerField *string 40 SkipField map[string]string 41 } 42 43 func TestMerge(t *testing.T) { 44 cases := map[string]struct { 45 mstruct mergeStruct 46 cmd func() mergeCmd 47 mergedStruct mergeStruct 48 notPointer bool 49 }{ 50 "basic merge": { 51 mstruct: mergeStruct{ 52 Name: "Name", 53 }, 54 cmd: func() mergeCmd { 55 surname := "Surname" 56 return mergeCmd{ 57 Surname: &surname, 58 } 59 }, 60 mergedStruct: mergeStruct{ 61 Name: "Name", 62 Surname: "Surname", 63 }, 64 }, 65 "not a pointer": { 66 mstruct: mergeStruct{ 67 Name: "Name", 68 }, 69 cmd: func() mergeCmd { 70 surname := "Surname" 71 return mergeCmd{ 72 Surname: &surname, 73 } 74 }, 75 mergedStruct: mergeStruct{ 76 Name: "Name", 77 Surname: "Surname", 78 }, 79 notPointer: true, 80 }, 81 "skipping field": { 82 mstruct: mergeStruct{ 83 Name: "Name", 84 }, 85 cmd: func() mergeCmd { 86 surname := "Surname" 87 88 return mergeCmd{ 89 Surname: &surname, 90 SkipField: map[string]string{ 91 "name": "surname", 92 }, 93 } 94 }, 95 mergedStruct: mergeStruct{ 96 Name: "Name", 97 Surname: "Surname", 98 }, 99 }, 100 "pointer field": { 101 mstruct: mergeStruct{ 102 Name: "Name", 103 PointerField: ptrString("Pointer"), 104 }, 105 cmd: func() mergeCmd { 106 surname := "Surname" 107 ptrField := "Pointer" 108 109 return mergeCmd{ 110 Surname: &surname, 111 PointerField: &ptrField, 112 } 113 }, 114 mergedStruct: mergeStruct{ 115 Name: "Name", 116 Surname: "Surname", 117 PointerField: ptrString("Pointer"), 118 }, 119 }, 120 "basic slice merge": { 121 mstruct: mergeStruct{ 122 Name: "Dz", 123 }, 124 cmd: func() mergeCmd { 125 surname := "G" 126 return mergeCmd{ 127 Surname: &surname, 128 Cars: []string{"peugeot", "citroen"}, 129 } 130 }, 131 mergedStruct: mergeStruct{ 132 Name: "Dz", 133 Surname: "G", 134 Cars: []string{"peugeot", "citroen"}, 135 }, 136 }, 137 "custom slice merge": { 138 mstruct: mergeStruct{ 139 Name: "Dz", 140 }, 141 cmd: func() mergeCmd { 142 surname := "G" 143 return mergeCmd{ 144 Surname: &surname, 145 Cars: []string{"peugeot", "citroen"}, 146 CarIDs: []carID{1, 2}, 147 } 148 }, 149 mergedStruct: mergeStruct{ 150 Name: "Dz", 151 Surname: "G", 152 Cars: []string{"peugeot", "citroen"}, 153 CarIDs: []carID{1, 2}, 154 }, 155 }, 156 "merge slice": { 157 mstruct: mergeStruct{ 158 Name: "Name", 159 SomeID: 5, 160 CarIDs: []carID{1, 2, 3}, 161 }, 162 cmd: func() mergeCmd { 163 surname := "Surname" 164 someID := int64(3) 165 return mergeCmd{ 166 Surname: &surname, 167 SomeID: &someID, 168 CarIDs: []carID{6, 7, 8}, 169 } 170 }, 171 mergedStruct: mergeStruct{ 172 Name: "Name", 173 Surname: "Surname", 174 SomeID: 3, 175 CarIDs: []carID{6, 7, 8}, 176 }, 177 }, 178 "test ignored fields": { 179 mstruct: mergeStruct{ 180 Name: "Name", 181 SomeID: 5, 182 IgnoredField: "ignored", 183 CarIDs: []carID{1, 2, 3}, 184 }, 185 cmd: func() mergeCmd { 186 surname := "Surname" 187 someID := int64(3) 188 ignored := "ignored-update" 189 return mergeCmd{ 190 Surname: &surname, 191 SomeID: &someID, 192 IgnoredField: &ignored, 193 CarIDs: []carID{6, 7, 8}, 194 } 195 }, 196 mergedStruct: mergeStruct{ 197 Name: "Name", 198 Surname: "Surname", 199 SomeID: 3, 200 IgnoredField: "ignored", 201 CarIDs: []carID{6, 7, 8}, 202 }, 203 }, 204 "custom struct merge": { 205 mstruct: mergeStruct{ 206 Name: "Name", 207 SomeID: 5, 208 IgnoredField: "ignored", 209 CarIDs: []carID{1, 2, 3}, 210 CustomStruct: customStruct{ 211 isLoved: true, 212 isHated: false, 213 }, 214 }, 215 cmd: func() mergeCmd { 216 surname := "Surname" 217 someID := int64(3) 218 ignored := "ignored-update" 219 return mergeCmd{ 220 Surname: &surname, 221 SomeID: &someID, 222 IgnoredField: &ignored, 223 CarIDs: []carID{6, 7, 8}, 224 CustomStruct: &customStruct{ 225 isLoved: false, 226 isHated: false, 227 }, 228 } 229 }, 230 mergedStruct: mergeStruct{ 231 Name: "Name", 232 Surname: "Surname", 233 SomeID: 3, 234 IgnoredField: "ignored", 235 CarIDs: []carID{6, 7, 8}, 236 CustomStruct: customStruct{ 237 isLoved: false, 238 isHated: false, 239 }, 240 }, 241 }, 242 "custom struct slice merge": { 243 mstruct: mergeStruct{ 244 Name: "Name", 245 SomeID: 5, 246 IgnoredField: "ignored", 247 CarIDs: []carID{1, 2, 3}, 248 CustomStructSlice: []customStruct{ 249 { 250 isLoved: true, 251 isHated: true, 252 }, 253 { 254 isLoved: false, 255 isHated: false, 256 }, 257 }, 258 }, 259 cmd: func() mergeCmd { 260 surname := "Surname" 261 someID := int64(3) 262 ignored := "ignored-update" 263 return mergeCmd{ 264 Surname: &surname, 265 SomeID: &someID, 266 IgnoredField: &ignored, 267 CarIDs: []carID{6, 7, 8}, 268 CustomStructSlice: []customStruct{ 269 { 270 isLoved: false, 271 isHated: true, 272 }, 273 }, 274 } 275 }, 276 mergedStruct: mergeStruct{ 277 Name: "Name", 278 Surname: "Surname", 279 SomeID: 3, 280 IgnoredField: "ignored", 281 CarIDs: []carID{6, 7, 8}, 282 CustomStructSlice: []customStruct{ 283 { 284 isLoved: false, 285 isHated: true, 286 }, 287 }, 288 }, 289 }, 290 "nil struct merge": { 291 mstruct: mergeStruct{ 292 Name: "Name", 293 SomeID: 5, 294 IgnoredField: "ignored", 295 CarIDs: []carID{1, 2, 3}, 296 }, 297 cmd: func() mergeCmd { 298 surname := "Surname" 299 someID := int64(3) 300 ignored := "ignored-update" 301 return mergeCmd{ 302 Surname: &surname, 303 SomeID: &someID, 304 IgnoredField: &ignored, 305 CarIDs: []carID{6, 7, 8}, 306 CustomStruct: nil, 307 } 308 }, 309 mergedStruct: mergeStruct{ 310 Name: "Name", 311 Surname: "Surname", 312 SomeID: 3, 313 IgnoredField: "ignored", 314 CarIDs: []carID{6, 7, 8}, 315 }, 316 }, 317 "empty slice merge": { 318 mstruct: mergeStruct{ 319 Name: "Name", 320 SomeID: 5, 321 IgnoredField: "ignored", 322 CarIDs: []carID{1, 2, 3}, 323 }, 324 cmd: func() mergeCmd { 325 surname := "Surname" 326 someID := int64(3) 327 ignored := "ignored-update" 328 return mergeCmd{ 329 Surname: &surname, 330 SomeID: &someID, 331 IgnoredField: &ignored, 332 CarIDs: []carID{6, 7, 8}, 333 CustomStructSlice: []customStruct{}, 334 } 335 }, 336 mergedStruct: mergeStruct{ 337 Name: "Name", 338 Surname: "Surname", 339 SomeID: 3, 340 IgnoredField: "ignored", 341 CarIDs: []carID{6, 7, 8}, 342 CustomStructSlice: []customStruct{}, 343 }, 344 }, 345 } 346 for name, c := range cases { 347 t.Run(name, func(t *testing.T) { 348 cmd := c.cmd() 349 if c.notPointer { 350 structs.Merge(c.mstruct, &cmd) 351 assert.NotEqual(t, c.mstruct, c.mergedStruct) 352 return 353 } 354 structs.Merge(&c.mstruct, &cmd) 355 assert.Equal(t, c.mstruct, c.mergedStruct) 356 }) 357 } 358 } 359 360 func ptrString(s string) *string { 361 return &s 362 }