1*1fa6dee9SAndroid Build Coastguard Worker// Copyright 2015 Google Inc. All rights reserved. 2*1fa6dee9SAndroid Build Coastguard Worker// 3*1fa6dee9SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); 4*1fa6dee9SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License. 5*1fa6dee9SAndroid Build Coastguard Worker// You may obtain a copy of the License at 6*1fa6dee9SAndroid Build Coastguard Worker// 7*1fa6dee9SAndroid Build Coastguard Worker// http://www.apache.org/licenses/LICENSE-2.0 8*1fa6dee9SAndroid Build Coastguard Worker// 9*1fa6dee9SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*1fa6dee9SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, 11*1fa6dee9SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*1fa6dee9SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and 13*1fa6dee9SAndroid Build Coastguard Worker// limitations under the License. 14*1fa6dee9SAndroid Build Coastguard Worker 15*1fa6dee9SAndroid Build Coastguard Workerpackage proptools 16*1fa6dee9SAndroid Build Coastguard Worker 17*1fa6dee9SAndroid Build Coastguard Workerimport ( 18*1fa6dee9SAndroid Build Coastguard Worker "fmt" 19*1fa6dee9SAndroid Build Coastguard Worker "reflect" 20*1fa6dee9SAndroid Build Coastguard Worker "testing" 21*1fa6dee9SAndroid Build Coastguard Worker) 22*1fa6dee9SAndroid Build Coastguard Worker 23*1fa6dee9SAndroid Build Coastguard Workervar clonePropertiesTestCases = []struct { 24*1fa6dee9SAndroid Build Coastguard Worker in interface{} 25*1fa6dee9SAndroid Build Coastguard Worker out interface{} 26*1fa6dee9SAndroid Build Coastguard Worker err error 27*1fa6dee9SAndroid Build Coastguard Worker}{ 28*1fa6dee9SAndroid Build Coastguard Worker // Valid inputs 29*1fa6dee9SAndroid Build Coastguard Worker 30*1fa6dee9SAndroid Build Coastguard Worker { 31*1fa6dee9SAndroid Build Coastguard Worker // Clone bool 32*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ B1, B2 bool }{ 33*1fa6dee9SAndroid Build Coastguard Worker B1: true, 34*1fa6dee9SAndroid Build Coastguard Worker B2: false, 35*1fa6dee9SAndroid Build Coastguard Worker }, 36*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ B1, B2 bool }{ 37*1fa6dee9SAndroid Build Coastguard Worker B1: true, 38*1fa6dee9SAndroid Build Coastguard Worker B2: false, 39*1fa6dee9SAndroid Build Coastguard Worker }, 40*1fa6dee9SAndroid Build Coastguard Worker }, 41*1fa6dee9SAndroid Build Coastguard Worker { 42*1fa6dee9SAndroid Build Coastguard Worker // Clone strings 43*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S string }{ 44*1fa6dee9SAndroid Build Coastguard Worker S: "string1", 45*1fa6dee9SAndroid Build Coastguard Worker }, 46*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S string }{ 47*1fa6dee9SAndroid Build Coastguard Worker S: "string1", 48*1fa6dee9SAndroid Build Coastguard Worker }, 49*1fa6dee9SAndroid Build Coastguard Worker }, 50*1fa6dee9SAndroid Build Coastguard Worker { 51*1fa6dee9SAndroid Build Coastguard Worker // Clone slice 52*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S []string }{ 53*1fa6dee9SAndroid Build Coastguard Worker S: []string{"string1"}, 54*1fa6dee9SAndroid Build Coastguard Worker }, 55*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S []string }{ 56*1fa6dee9SAndroid Build Coastguard Worker S: []string{"string1"}, 57*1fa6dee9SAndroid Build Coastguard Worker }, 58*1fa6dee9SAndroid Build Coastguard Worker }, 59*1fa6dee9SAndroid Build Coastguard Worker { 60*1fa6dee9SAndroid Build Coastguard Worker // Clone empty slice 61*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S []string }{ 62*1fa6dee9SAndroid Build Coastguard Worker S: []string{}, 63*1fa6dee9SAndroid Build Coastguard Worker }, 64*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S []string }{ 65*1fa6dee9SAndroid Build Coastguard Worker S: []string{}, 66*1fa6dee9SAndroid Build Coastguard Worker }, 67*1fa6dee9SAndroid Build Coastguard Worker }, 68*1fa6dee9SAndroid Build Coastguard Worker { 69*1fa6dee9SAndroid Build Coastguard Worker // Clone nil slice 70*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S []string }{}, 71*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S []string }{}, 72*1fa6dee9SAndroid Build Coastguard Worker }, 73*1fa6dee9SAndroid Build Coastguard Worker { 74*1fa6dee9SAndroid Build Coastguard Worker // Clone slice of structs 75*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S []struct{ T string } }{ 76*1fa6dee9SAndroid Build Coastguard Worker S: []struct{ T string }{ 77*1fa6dee9SAndroid Build Coastguard Worker {"string1"}, {"string2"}, 78*1fa6dee9SAndroid Build Coastguard Worker }, 79*1fa6dee9SAndroid Build Coastguard Worker }, 80*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S []struct{ T string } }{ 81*1fa6dee9SAndroid Build Coastguard Worker S: []struct{ T string }{ 82*1fa6dee9SAndroid Build Coastguard Worker {"string1"}, {"string2"}, 83*1fa6dee9SAndroid Build Coastguard Worker }, 84*1fa6dee9SAndroid Build Coastguard Worker }, 85*1fa6dee9SAndroid Build Coastguard Worker }, 86*1fa6dee9SAndroid Build Coastguard Worker { 87*1fa6dee9SAndroid Build Coastguard Worker // Clone map 88*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S map[string]string }{ 89*1fa6dee9SAndroid Build Coastguard Worker S: map[string]string{"key": "string1"}, 90*1fa6dee9SAndroid Build Coastguard Worker }, 91*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S map[string]string }{ 92*1fa6dee9SAndroid Build Coastguard Worker S: map[string]string{"key": "string1"}, 93*1fa6dee9SAndroid Build Coastguard Worker }, 94*1fa6dee9SAndroid Build Coastguard Worker }, 95*1fa6dee9SAndroid Build Coastguard Worker { 96*1fa6dee9SAndroid Build Coastguard Worker // Clone empty map 97*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S map[string]string }{ 98*1fa6dee9SAndroid Build Coastguard Worker S: map[string]string{}, 99*1fa6dee9SAndroid Build Coastguard Worker }, 100*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S map[string]string }{ 101*1fa6dee9SAndroid Build Coastguard Worker S: map[string]string{}, 102*1fa6dee9SAndroid Build Coastguard Worker }, 103*1fa6dee9SAndroid Build Coastguard Worker }, 104*1fa6dee9SAndroid Build Coastguard Worker { 105*1fa6dee9SAndroid Build Coastguard Worker // Clone nil map 106*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S map[string]string }{}, 107*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S map[string]string }{}, 108*1fa6dee9SAndroid Build Coastguard Worker }, 109*1fa6dee9SAndroid Build Coastguard Worker { 110*1fa6dee9SAndroid Build Coastguard Worker // Clone pointer to bool 111*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ B1, B2 *bool }{ 112*1fa6dee9SAndroid Build Coastguard Worker B1: BoolPtr(true), 113*1fa6dee9SAndroid Build Coastguard Worker B2: BoolPtr(false), 114*1fa6dee9SAndroid Build Coastguard Worker }, 115*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ B1, B2 *bool }{ 116*1fa6dee9SAndroid Build Coastguard Worker B1: BoolPtr(true), 117*1fa6dee9SAndroid Build Coastguard Worker B2: BoolPtr(false), 118*1fa6dee9SAndroid Build Coastguard Worker }, 119*1fa6dee9SAndroid Build Coastguard Worker }, 120*1fa6dee9SAndroid Build Coastguard Worker { 121*1fa6dee9SAndroid Build Coastguard Worker // Clone pointer to string 122*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S *string }{ 123*1fa6dee9SAndroid Build Coastguard Worker S: StringPtr("string1"), 124*1fa6dee9SAndroid Build Coastguard Worker }, 125*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S *string }{ 126*1fa6dee9SAndroid Build Coastguard Worker S: StringPtr("string1"), 127*1fa6dee9SAndroid Build Coastguard Worker }, 128*1fa6dee9SAndroid Build Coastguard Worker }, 129*1fa6dee9SAndroid Build Coastguard Worker { 130*1fa6dee9SAndroid Build Coastguard Worker // Clone pointer to int64 131*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S *int64 }{ 132*1fa6dee9SAndroid Build Coastguard Worker S: Int64Ptr(5), 133*1fa6dee9SAndroid Build Coastguard Worker }, 134*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S *int64 }{ 135*1fa6dee9SAndroid Build Coastguard Worker S: Int64Ptr(5), 136*1fa6dee9SAndroid Build Coastguard Worker }, 137*1fa6dee9SAndroid Build Coastguard Worker }, 138*1fa6dee9SAndroid Build Coastguard Worker { 139*1fa6dee9SAndroid Build Coastguard Worker // Clone struct 140*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S struct{ S string } }{ 141*1fa6dee9SAndroid Build Coastguard Worker S: struct{ S string }{ 142*1fa6dee9SAndroid Build Coastguard Worker S: "string1", 143*1fa6dee9SAndroid Build Coastguard Worker }, 144*1fa6dee9SAndroid Build Coastguard Worker }, 145*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S struct{ S string } }{ 146*1fa6dee9SAndroid Build Coastguard Worker S: struct{ S string }{ 147*1fa6dee9SAndroid Build Coastguard Worker S: "string1", 148*1fa6dee9SAndroid Build Coastguard Worker }, 149*1fa6dee9SAndroid Build Coastguard Worker }, 150*1fa6dee9SAndroid Build Coastguard Worker }, 151*1fa6dee9SAndroid Build Coastguard Worker { 152*1fa6dee9SAndroid Build Coastguard Worker // Clone struct pointer 153*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S *struct{ S string } }{ 154*1fa6dee9SAndroid Build Coastguard Worker S: &struct{ S string }{ 155*1fa6dee9SAndroid Build Coastguard Worker S: "string1", 156*1fa6dee9SAndroid Build Coastguard Worker }, 157*1fa6dee9SAndroid Build Coastguard Worker }, 158*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S *struct{ S string } }{ 159*1fa6dee9SAndroid Build Coastguard Worker S: &struct{ S string }{ 160*1fa6dee9SAndroid Build Coastguard Worker S: "string1", 161*1fa6dee9SAndroid Build Coastguard Worker }, 162*1fa6dee9SAndroid Build Coastguard Worker }, 163*1fa6dee9SAndroid Build Coastguard Worker }, 164*1fa6dee9SAndroid Build Coastguard Worker { 165*1fa6dee9SAndroid Build Coastguard Worker // Clone interface 166*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S interface{} }{ 167*1fa6dee9SAndroid Build Coastguard Worker S: &struct{ S string }{ 168*1fa6dee9SAndroid Build Coastguard Worker S: "string1", 169*1fa6dee9SAndroid Build Coastguard Worker }, 170*1fa6dee9SAndroid Build Coastguard Worker }, 171*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S interface{} }{ 172*1fa6dee9SAndroid Build Coastguard Worker S: &struct{ S string }{ 173*1fa6dee9SAndroid Build Coastguard Worker S: "string1", 174*1fa6dee9SAndroid Build Coastguard Worker }, 175*1fa6dee9SAndroid Build Coastguard Worker }, 176*1fa6dee9SAndroid Build Coastguard Worker }, 177*1fa6dee9SAndroid Build Coastguard Worker { 178*1fa6dee9SAndroid Build Coastguard Worker // Clone nested interface 179*1fa6dee9SAndroid Build Coastguard Worker in: &struct { 180*1fa6dee9SAndroid Build Coastguard Worker Nested struct{ S interface{} } 181*1fa6dee9SAndroid Build Coastguard Worker }{ 182*1fa6dee9SAndroid Build Coastguard Worker Nested: struct{ S interface{} }{ 183*1fa6dee9SAndroid Build Coastguard Worker S: &struct{ S string }{ 184*1fa6dee9SAndroid Build Coastguard Worker S: "string1", 185*1fa6dee9SAndroid Build Coastguard Worker }, 186*1fa6dee9SAndroid Build Coastguard Worker }, 187*1fa6dee9SAndroid Build Coastguard Worker }, 188*1fa6dee9SAndroid Build Coastguard Worker out: &struct { 189*1fa6dee9SAndroid Build Coastguard Worker Nested struct{ S interface{} } 190*1fa6dee9SAndroid Build Coastguard Worker }{ 191*1fa6dee9SAndroid Build Coastguard Worker Nested: struct{ S interface{} }{ 192*1fa6dee9SAndroid Build Coastguard Worker S: &struct{ S string }{ 193*1fa6dee9SAndroid Build Coastguard Worker S: "string1", 194*1fa6dee9SAndroid Build Coastguard Worker }, 195*1fa6dee9SAndroid Build Coastguard Worker }, 196*1fa6dee9SAndroid Build Coastguard Worker }, 197*1fa6dee9SAndroid Build Coastguard Worker }, { 198*1fa6dee9SAndroid Build Coastguard Worker // Empty struct 199*1fa6dee9SAndroid Build Coastguard Worker in: &struct{}{}, 200*1fa6dee9SAndroid Build Coastguard Worker out: &struct{}{}, 201*1fa6dee9SAndroid Build Coastguard Worker }, 202*1fa6dee9SAndroid Build Coastguard Worker { 203*1fa6dee9SAndroid Build Coastguard Worker // Interface nil 204*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S interface{} }{ 205*1fa6dee9SAndroid Build Coastguard Worker S: nil, 206*1fa6dee9SAndroid Build Coastguard Worker }, 207*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S interface{} }{ 208*1fa6dee9SAndroid Build Coastguard Worker S: nil, 209*1fa6dee9SAndroid Build Coastguard Worker }, 210*1fa6dee9SAndroid Build Coastguard Worker }, 211*1fa6dee9SAndroid Build Coastguard Worker { 212*1fa6dee9SAndroid Build Coastguard Worker // Interface pointer to nil 213*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S interface{} }{ 214*1fa6dee9SAndroid Build Coastguard Worker S: (*struct{ S string })(nil), 215*1fa6dee9SAndroid Build Coastguard Worker }, 216*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S interface{} }{ 217*1fa6dee9SAndroid Build Coastguard Worker S: (*struct{ S string })(nil), 218*1fa6dee9SAndroid Build Coastguard Worker }, 219*1fa6dee9SAndroid Build Coastguard Worker }, 220*1fa6dee9SAndroid Build Coastguard Worker { 221*1fa6dee9SAndroid Build Coastguard Worker // Pointer nil 222*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S *struct{} }{ 223*1fa6dee9SAndroid Build Coastguard Worker S: nil, 224*1fa6dee9SAndroid Build Coastguard Worker }, 225*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S *struct{} }{ 226*1fa6dee9SAndroid Build Coastguard Worker S: nil, 227*1fa6dee9SAndroid Build Coastguard Worker }, 228*1fa6dee9SAndroid Build Coastguard Worker }, 229*1fa6dee9SAndroid Build Coastguard Worker { 230*1fa6dee9SAndroid Build Coastguard Worker // Anonymous struct 231*1fa6dee9SAndroid Build Coastguard Worker in: &struct { 232*1fa6dee9SAndroid Build Coastguard Worker EmbeddedStruct 233*1fa6dee9SAndroid Build Coastguard Worker Nested struct{ EmbeddedStruct } 234*1fa6dee9SAndroid Build Coastguard Worker }{ 235*1fa6dee9SAndroid Build Coastguard Worker EmbeddedStruct: EmbeddedStruct{ 236*1fa6dee9SAndroid Build Coastguard Worker S: "string1", 237*1fa6dee9SAndroid Build Coastguard Worker I: Int64Ptr(55), 238*1fa6dee9SAndroid Build Coastguard Worker }, 239*1fa6dee9SAndroid Build Coastguard Worker Nested: struct{ EmbeddedStruct }{ 240*1fa6dee9SAndroid Build Coastguard Worker EmbeddedStruct: EmbeddedStruct{ 241*1fa6dee9SAndroid Build Coastguard Worker S: "string2", 242*1fa6dee9SAndroid Build Coastguard Worker I: Int64Ptr(5), 243*1fa6dee9SAndroid Build Coastguard Worker }, 244*1fa6dee9SAndroid Build Coastguard Worker }, 245*1fa6dee9SAndroid Build Coastguard Worker }, 246*1fa6dee9SAndroid Build Coastguard Worker out: &struct { 247*1fa6dee9SAndroid Build Coastguard Worker EmbeddedStruct 248*1fa6dee9SAndroid Build Coastguard Worker Nested struct{ EmbeddedStruct } 249*1fa6dee9SAndroid Build Coastguard Worker }{ 250*1fa6dee9SAndroid Build Coastguard Worker EmbeddedStruct: EmbeddedStruct{ 251*1fa6dee9SAndroid Build Coastguard Worker S: "string1", 252*1fa6dee9SAndroid Build Coastguard Worker I: Int64Ptr(55), 253*1fa6dee9SAndroid Build Coastguard Worker }, 254*1fa6dee9SAndroid Build Coastguard Worker Nested: struct{ EmbeddedStruct }{ 255*1fa6dee9SAndroid Build Coastguard Worker EmbeddedStruct: EmbeddedStruct{ 256*1fa6dee9SAndroid Build Coastguard Worker S: "string2", 257*1fa6dee9SAndroid Build Coastguard Worker I: Int64Ptr(5), 258*1fa6dee9SAndroid Build Coastguard Worker }, 259*1fa6dee9SAndroid Build Coastguard Worker }, 260*1fa6dee9SAndroid Build Coastguard Worker }, 261*1fa6dee9SAndroid Build Coastguard Worker }, 262*1fa6dee9SAndroid Build Coastguard Worker { 263*1fa6dee9SAndroid Build Coastguard Worker // Anonymous interface 264*1fa6dee9SAndroid Build Coastguard Worker in: &struct { 265*1fa6dee9SAndroid Build Coastguard Worker EmbeddedInterface 266*1fa6dee9SAndroid Build Coastguard Worker Nested struct{ EmbeddedInterface } 267*1fa6dee9SAndroid Build Coastguard Worker }{ 268*1fa6dee9SAndroid Build Coastguard Worker EmbeddedInterface: &struct{ S string }{ 269*1fa6dee9SAndroid Build Coastguard Worker S: "string1", 270*1fa6dee9SAndroid Build Coastguard Worker }, 271*1fa6dee9SAndroid Build Coastguard Worker Nested: struct{ EmbeddedInterface }{ 272*1fa6dee9SAndroid Build Coastguard Worker EmbeddedInterface: &struct{ S string }{ 273*1fa6dee9SAndroid Build Coastguard Worker S: "string2", 274*1fa6dee9SAndroid Build Coastguard Worker }, 275*1fa6dee9SAndroid Build Coastguard Worker }, 276*1fa6dee9SAndroid Build Coastguard Worker }, 277*1fa6dee9SAndroid Build Coastguard Worker out: &struct { 278*1fa6dee9SAndroid Build Coastguard Worker EmbeddedInterface 279*1fa6dee9SAndroid Build Coastguard Worker Nested struct{ EmbeddedInterface } 280*1fa6dee9SAndroid Build Coastguard Worker }{ 281*1fa6dee9SAndroid Build Coastguard Worker EmbeddedInterface: &struct{ S string }{ 282*1fa6dee9SAndroid Build Coastguard Worker S: "string1", 283*1fa6dee9SAndroid Build Coastguard Worker }, 284*1fa6dee9SAndroid Build Coastguard Worker Nested: struct{ EmbeddedInterface }{ 285*1fa6dee9SAndroid Build Coastguard Worker EmbeddedInterface: &struct{ S string }{ 286*1fa6dee9SAndroid Build Coastguard Worker S: "string2", 287*1fa6dee9SAndroid Build Coastguard Worker }, 288*1fa6dee9SAndroid Build Coastguard Worker }, 289*1fa6dee9SAndroid Build Coastguard Worker }, 290*1fa6dee9SAndroid Build Coastguard Worker }, 291*1fa6dee9SAndroid Build Coastguard Worker} 292*1fa6dee9SAndroid Build Coastguard Worker 293*1fa6dee9SAndroid Build Coastguard Workertype EmbeddedStruct struct { 294*1fa6dee9SAndroid Build Coastguard Worker S string 295*1fa6dee9SAndroid Build Coastguard Worker I *int64 296*1fa6dee9SAndroid Build Coastguard Worker} 297*1fa6dee9SAndroid Build Coastguard Workertype EmbeddedInterface interface{} 298*1fa6dee9SAndroid Build Coastguard Worker 299*1fa6dee9SAndroid Build Coastguard Workerfunc isPointerToEmptyStruct(v any) bool { 300*1fa6dee9SAndroid Build Coastguard Worker t := reflect.TypeOf(v) 301*1fa6dee9SAndroid Build Coastguard Worker if t.Kind() != reflect.Ptr { 302*1fa6dee9SAndroid Build Coastguard Worker return false 303*1fa6dee9SAndroid Build Coastguard Worker } 304*1fa6dee9SAndroid Build Coastguard Worker t = t.Elem() 305*1fa6dee9SAndroid Build Coastguard Worker if t.Kind() != reflect.Struct { 306*1fa6dee9SAndroid Build Coastguard Worker return false 307*1fa6dee9SAndroid Build Coastguard Worker } 308*1fa6dee9SAndroid Build Coastguard Worker if t.NumField() > 0 { 309*1fa6dee9SAndroid Build Coastguard Worker return false 310*1fa6dee9SAndroid Build Coastguard Worker } 311*1fa6dee9SAndroid Build Coastguard Worker return true 312*1fa6dee9SAndroid Build Coastguard Worker} 313*1fa6dee9SAndroid Build Coastguard Worker 314*1fa6dee9SAndroid Build Coastguard Workerfunc TestCloneProperties(t *testing.T) { 315*1fa6dee9SAndroid Build Coastguard Worker for _, testCase := range clonePropertiesTestCases { 316*1fa6dee9SAndroid Build Coastguard Worker testString := fmt.Sprintf("%s", testCase.in) 317*1fa6dee9SAndroid Build Coastguard Worker 318*1fa6dee9SAndroid Build Coastguard Worker got := CloneProperties(reflect.ValueOf(testCase.in)).Interface() 319*1fa6dee9SAndroid Build Coastguard Worker 320*1fa6dee9SAndroid Build Coastguard Worker if !reflect.DeepEqual(testCase.out, got) { 321*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("test case %s", testString) 322*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("incorrect output") 323*1fa6dee9SAndroid Build Coastguard Worker t.Errorf(" expected: %#v", testCase.out) 324*1fa6dee9SAndroid Build Coastguard Worker t.Errorf(" got: %#v", got) 325*1fa6dee9SAndroid Build Coastguard Worker } 326*1fa6dee9SAndroid Build Coastguard Worker if testCase.out == got && !isPointerToEmptyStruct(testCase.out) { 327*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("test case %s", testString) 328*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("items should be cloned, not the original") 329*1fa6dee9SAndroid Build Coastguard Worker t.Errorf(" expected: %s", testCase.out) 330*1fa6dee9SAndroid Build Coastguard Worker t.Errorf(" got: %s", got) 331*1fa6dee9SAndroid Build Coastguard Worker } 332*1fa6dee9SAndroid Build Coastguard Worker } 333*1fa6dee9SAndroid Build Coastguard Worker} 334*1fa6dee9SAndroid Build Coastguard Worker 335*1fa6dee9SAndroid Build Coastguard Workervar cloneEmptyPropertiesTestCases = []struct { 336*1fa6dee9SAndroid Build Coastguard Worker in interface{} 337*1fa6dee9SAndroid Build Coastguard Worker out interface{} 338*1fa6dee9SAndroid Build Coastguard Worker err error 339*1fa6dee9SAndroid Build Coastguard Worker}{ 340*1fa6dee9SAndroid Build Coastguard Worker // Valid inputs 341*1fa6dee9SAndroid Build Coastguard Worker 342*1fa6dee9SAndroid Build Coastguard Worker { 343*1fa6dee9SAndroid Build Coastguard Worker // Clone bool 344*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ B1, B2 bool }{ 345*1fa6dee9SAndroid Build Coastguard Worker B1: true, 346*1fa6dee9SAndroid Build Coastguard Worker B2: false, 347*1fa6dee9SAndroid Build Coastguard Worker }, 348*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ B1, B2 bool }{}, 349*1fa6dee9SAndroid Build Coastguard Worker }, 350*1fa6dee9SAndroid Build Coastguard Worker { 351*1fa6dee9SAndroid Build Coastguard Worker // Clone strings 352*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S string }{ 353*1fa6dee9SAndroid Build Coastguard Worker S: "string1", 354*1fa6dee9SAndroid Build Coastguard Worker }, 355*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S string }{}, 356*1fa6dee9SAndroid Build Coastguard Worker }, 357*1fa6dee9SAndroid Build Coastguard Worker { 358*1fa6dee9SAndroid Build Coastguard Worker // Clone slice 359*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S []string }{ 360*1fa6dee9SAndroid Build Coastguard Worker S: []string{"string1"}, 361*1fa6dee9SAndroid Build Coastguard Worker }, 362*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S []string }{}, 363*1fa6dee9SAndroid Build Coastguard Worker }, 364*1fa6dee9SAndroid Build Coastguard Worker { 365*1fa6dee9SAndroid Build Coastguard Worker // Clone empty slice 366*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S []string }{ 367*1fa6dee9SAndroid Build Coastguard Worker S: []string{}, 368*1fa6dee9SAndroid Build Coastguard Worker }, 369*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S []string }{}, 370*1fa6dee9SAndroid Build Coastguard Worker }, 371*1fa6dee9SAndroid Build Coastguard Worker { 372*1fa6dee9SAndroid Build Coastguard Worker // Clone nil slice 373*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S []string }{}, 374*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S []string }{}, 375*1fa6dee9SAndroid Build Coastguard Worker }, 376*1fa6dee9SAndroid Build Coastguard Worker { 377*1fa6dee9SAndroid Build Coastguard Worker // Clone slice of structs 378*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S []struct{ T string } }{ 379*1fa6dee9SAndroid Build Coastguard Worker S: []struct{ T string }{ 380*1fa6dee9SAndroid Build Coastguard Worker {"string1"}, {"string2"}, 381*1fa6dee9SAndroid Build Coastguard Worker }, 382*1fa6dee9SAndroid Build Coastguard Worker }, 383*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S []struct{ T string } }{ 384*1fa6dee9SAndroid Build Coastguard Worker S: []struct{ T string }(nil), 385*1fa6dee9SAndroid Build Coastguard Worker }, 386*1fa6dee9SAndroid Build Coastguard Worker }, 387*1fa6dee9SAndroid Build Coastguard Worker { 388*1fa6dee9SAndroid Build Coastguard Worker // Clone pointer to bool 389*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ B1, B2 *bool }{ 390*1fa6dee9SAndroid Build Coastguard Worker B1: BoolPtr(true), 391*1fa6dee9SAndroid Build Coastguard Worker B2: BoolPtr(false), 392*1fa6dee9SAndroid Build Coastguard Worker }, 393*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ B1, B2 *bool }{}, 394*1fa6dee9SAndroid Build Coastguard Worker }, 395*1fa6dee9SAndroid Build Coastguard Worker { 396*1fa6dee9SAndroid Build Coastguard Worker // Clone pointer to int64 397*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ B1, B2 *int64 }{ 398*1fa6dee9SAndroid Build Coastguard Worker B1: Int64Ptr(5), 399*1fa6dee9SAndroid Build Coastguard Worker B2: Int64Ptr(4), 400*1fa6dee9SAndroid Build Coastguard Worker }, 401*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ B1, B2 *int64 }{}, 402*1fa6dee9SAndroid Build Coastguard Worker }, 403*1fa6dee9SAndroid Build Coastguard Worker { 404*1fa6dee9SAndroid Build Coastguard Worker // Clone pointer to string 405*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S *string }{ 406*1fa6dee9SAndroid Build Coastguard Worker S: StringPtr("string1"), 407*1fa6dee9SAndroid Build Coastguard Worker }, 408*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S *string }{}, 409*1fa6dee9SAndroid Build Coastguard Worker }, 410*1fa6dee9SAndroid Build Coastguard Worker { 411*1fa6dee9SAndroid Build Coastguard Worker // Clone struct 412*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S struct{ S string } }{ 413*1fa6dee9SAndroid Build Coastguard Worker S: struct{ S string }{ 414*1fa6dee9SAndroid Build Coastguard Worker S: "string1", 415*1fa6dee9SAndroid Build Coastguard Worker }, 416*1fa6dee9SAndroid Build Coastguard Worker }, 417*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S struct{ S string } }{ 418*1fa6dee9SAndroid Build Coastguard Worker S: struct{ S string }{}, 419*1fa6dee9SAndroid Build Coastguard Worker }, 420*1fa6dee9SAndroid Build Coastguard Worker }, 421*1fa6dee9SAndroid Build Coastguard Worker { 422*1fa6dee9SAndroid Build Coastguard Worker // Clone struct pointer 423*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S *struct{ S string } }{ 424*1fa6dee9SAndroid Build Coastguard Worker S: &struct{ S string }{ 425*1fa6dee9SAndroid Build Coastguard Worker S: "string1", 426*1fa6dee9SAndroid Build Coastguard Worker }, 427*1fa6dee9SAndroid Build Coastguard Worker }, 428*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S *struct{ S string } }{ 429*1fa6dee9SAndroid Build Coastguard Worker S: &struct{ S string }{}, 430*1fa6dee9SAndroid Build Coastguard Worker }, 431*1fa6dee9SAndroid Build Coastguard Worker }, 432*1fa6dee9SAndroid Build Coastguard Worker { 433*1fa6dee9SAndroid Build Coastguard Worker // Clone interface 434*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S interface{} }{ 435*1fa6dee9SAndroid Build Coastguard Worker S: &struct{ S string }{ 436*1fa6dee9SAndroid Build Coastguard Worker S: "string1", 437*1fa6dee9SAndroid Build Coastguard Worker }, 438*1fa6dee9SAndroid Build Coastguard Worker }, 439*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S interface{} }{ 440*1fa6dee9SAndroid Build Coastguard Worker S: &struct{ S string }{}, 441*1fa6dee9SAndroid Build Coastguard Worker }, 442*1fa6dee9SAndroid Build Coastguard Worker }, 443*1fa6dee9SAndroid Build Coastguard Worker { 444*1fa6dee9SAndroid Build Coastguard Worker // Clone nested interface 445*1fa6dee9SAndroid Build Coastguard Worker in: &struct { 446*1fa6dee9SAndroid Build Coastguard Worker Nested struct{ S interface{} } 447*1fa6dee9SAndroid Build Coastguard Worker }{ 448*1fa6dee9SAndroid Build Coastguard Worker Nested: struct{ S interface{} }{ 449*1fa6dee9SAndroid Build Coastguard Worker S: &struct{ S string }{ 450*1fa6dee9SAndroid Build Coastguard Worker S: "string1", 451*1fa6dee9SAndroid Build Coastguard Worker }, 452*1fa6dee9SAndroid Build Coastguard Worker }, 453*1fa6dee9SAndroid Build Coastguard Worker }, 454*1fa6dee9SAndroid Build Coastguard Worker out: &struct { 455*1fa6dee9SAndroid Build Coastguard Worker Nested struct{ S interface{} } 456*1fa6dee9SAndroid Build Coastguard Worker }{ 457*1fa6dee9SAndroid Build Coastguard Worker Nested: struct{ S interface{} }{ 458*1fa6dee9SAndroid Build Coastguard Worker S: &struct{ S string }{}, 459*1fa6dee9SAndroid Build Coastguard Worker }, 460*1fa6dee9SAndroid Build Coastguard Worker }, 461*1fa6dee9SAndroid Build Coastguard Worker }, 462*1fa6dee9SAndroid Build Coastguard Worker { 463*1fa6dee9SAndroid Build Coastguard Worker // Empty struct 464*1fa6dee9SAndroid Build Coastguard Worker in: &struct{}{}, 465*1fa6dee9SAndroid Build Coastguard Worker out: &struct{}{}, 466*1fa6dee9SAndroid Build Coastguard Worker }, 467*1fa6dee9SAndroid Build Coastguard Worker { 468*1fa6dee9SAndroid Build Coastguard Worker // Interface nil 469*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S interface{} }{ 470*1fa6dee9SAndroid Build Coastguard Worker S: nil, 471*1fa6dee9SAndroid Build Coastguard Worker }, 472*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S interface{} }{}, 473*1fa6dee9SAndroid Build Coastguard Worker }, 474*1fa6dee9SAndroid Build Coastguard Worker { 475*1fa6dee9SAndroid Build Coastguard Worker // Interface pointer to nil 476*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S interface{} }{ 477*1fa6dee9SAndroid Build Coastguard Worker S: (*struct{ S string })(nil), 478*1fa6dee9SAndroid Build Coastguard Worker }, 479*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S interface{} }{ 480*1fa6dee9SAndroid Build Coastguard Worker S: (*struct{ S string })(nil), 481*1fa6dee9SAndroid Build Coastguard Worker }, 482*1fa6dee9SAndroid Build Coastguard Worker }, 483*1fa6dee9SAndroid Build Coastguard Worker { 484*1fa6dee9SAndroid Build Coastguard Worker // Pointer nil 485*1fa6dee9SAndroid Build Coastguard Worker in: &struct{ S *struct{} }{ 486*1fa6dee9SAndroid Build Coastguard Worker S: nil, 487*1fa6dee9SAndroid Build Coastguard Worker }, 488*1fa6dee9SAndroid Build Coastguard Worker out: &struct{ S *struct{} }{}, 489*1fa6dee9SAndroid Build Coastguard Worker }, 490*1fa6dee9SAndroid Build Coastguard Worker { 491*1fa6dee9SAndroid Build Coastguard Worker // Anonymous struct 492*1fa6dee9SAndroid Build Coastguard Worker in: &struct { 493*1fa6dee9SAndroid Build Coastguard Worker EmbeddedStruct 494*1fa6dee9SAndroid Build Coastguard Worker Nested struct{ EmbeddedStruct } 495*1fa6dee9SAndroid Build Coastguard Worker }{ 496*1fa6dee9SAndroid Build Coastguard Worker EmbeddedStruct: EmbeddedStruct{ 497*1fa6dee9SAndroid Build Coastguard Worker S: "string1", 498*1fa6dee9SAndroid Build Coastguard Worker }, 499*1fa6dee9SAndroid Build Coastguard Worker Nested: struct{ EmbeddedStruct }{ 500*1fa6dee9SAndroid Build Coastguard Worker EmbeddedStruct: EmbeddedStruct{ 501*1fa6dee9SAndroid Build Coastguard Worker S: "string2", 502*1fa6dee9SAndroid Build Coastguard Worker }, 503*1fa6dee9SAndroid Build Coastguard Worker }, 504*1fa6dee9SAndroid Build Coastguard Worker }, 505*1fa6dee9SAndroid Build Coastguard Worker out: &struct { 506*1fa6dee9SAndroid Build Coastguard Worker EmbeddedStruct 507*1fa6dee9SAndroid Build Coastguard Worker Nested struct{ EmbeddedStruct } 508*1fa6dee9SAndroid Build Coastguard Worker }{ 509*1fa6dee9SAndroid Build Coastguard Worker EmbeddedStruct: EmbeddedStruct{}, 510*1fa6dee9SAndroid Build Coastguard Worker Nested: struct{ EmbeddedStruct }{ 511*1fa6dee9SAndroid Build Coastguard Worker EmbeddedStruct: EmbeddedStruct{}, 512*1fa6dee9SAndroid Build Coastguard Worker }, 513*1fa6dee9SAndroid Build Coastguard Worker }, 514*1fa6dee9SAndroid Build Coastguard Worker }, 515*1fa6dee9SAndroid Build Coastguard Worker { 516*1fa6dee9SAndroid Build Coastguard Worker // Anonymous interface 517*1fa6dee9SAndroid Build Coastguard Worker in: &struct { 518*1fa6dee9SAndroid Build Coastguard Worker EmbeddedInterface 519*1fa6dee9SAndroid Build Coastguard Worker Nested struct{ EmbeddedInterface } 520*1fa6dee9SAndroid Build Coastguard Worker }{ 521*1fa6dee9SAndroid Build Coastguard Worker EmbeddedInterface: &struct{ S string }{ 522*1fa6dee9SAndroid Build Coastguard Worker S: "string1", 523*1fa6dee9SAndroid Build Coastguard Worker }, 524*1fa6dee9SAndroid Build Coastguard Worker Nested: struct{ EmbeddedInterface }{ 525*1fa6dee9SAndroid Build Coastguard Worker EmbeddedInterface: &struct{ S string }{ 526*1fa6dee9SAndroid Build Coastguard Worker S: "string2", 527*1fa6dee9SAndroid Build Coastguard Worker }, 528*1fa6dee9SAndroid Build Coastguard Worker }, 529*1fa6dee9SAndroid Build Coastguard Worker }, 530*1fa6dee9SAndroid Build Coastguard Worker out: &struct { 531*1fa6dee9SAndroid Build Coastguard Worker EmbeddedInterface 532*1fa6dee9SAndroid Build Coastguard Worker Nested struct{ EmbeddedInterface } 533*1fa6dee9SAndroid Build Coastguard Worker }{ 534*1fa6dee9SAndroid Build Coastguard Worker EmbeddedInterface: &struct{ S string }{}, 535*1fa6dee9SAndroid Build Coastguard Worker Nested: struct{ EmbeddedInterface }{ 536*1fa6dee9SAndroid Build Coastguard Worker EmbeddedInterface: &struct{ S string }{}, 537*1fa6dee9SAndroid Build Coastguard Worker }, 538*1fa6dee9SAndroid Build Coastguard Worker }, 539*1fa6dee9SAndroid Build Coastguard Worker }, 540*1fa6dee9SAndroid Build Coastguard Worker} 541*1fa6dee9SAndroid Build Coastguard Worker 542*1fa6dee9SAndroid Build Coastguard Workerfunc TestCloneEmptyProperties(t *testing.T) { 543*1fa6dee9SAndroid Build Coastguard Worker for _, testCase := range cloneEmptyPropertiesTestCases { 544*1fa6dee9SAndroid Build Coastguard Worker testString := fmt.Sprintf("%#v", testCase.in) 545*1fa6dee9SAndroid Build Coastguard Worker 546*1fa6dee9SAndroid Build Coastguard Worker got := CloneEmptyProperties(reflect.ValueOf(testCase.in)).Interface() 547*1fa6dee9SAndroid Build Coastguard Worker 548*1fa6dee9SAndroid Build Coastguard Worker if !reflect.DeepEqual(testCase.out, got) { 549*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("test case %s", testString) 550*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("incorrect output") 551*1fa6dee9SAndroid Build Coastguard Worker t.Errorf(" expected: %#v", testCase.out) 552*1fa6dee9SAndroid Build Coastguard Worker t.Errorf(" got: %#v", got) 553*1fa6dee9SAndroid Build Coastguard Worker } 554*1fa6dee9SAndroid Build Coastguard Worker } 555*1fa6dee9SAndroid Build Coastguard Worker} 556*1fa6dee9SAndroid Build Coastguard Worker 557*1fa6dee9SAndroid Build Coastguard Workerfunc TestZeroProperties(t *testing.T) { 558*1fa6dee9SAndroid Build Coastguard Worker for _, testCase := range cloneEmptyPropertiesTestCases { 559*1fa6dee9SAndroid Build Coastguard Worker testString := fmt.Sprintf("%#v", testCase.in) 560*1fa6dee9SAndroid Build Coastguard Worker 561*1fa6dee9SAndroid Build Coastguard Worker got := CloneProperties(reflect.ValueOf(testCase.in)).Interface() 562*1fa6dee9SAndroid Build Coastguard Worker ZeroProperties(reflect.ValueOf(got)) 563*1fa6dee9SAndroid Build Coastguard Worker 564*1fa6dee9SAndroid Build Coastguard Worker if !reflect.DeepEqual(testCase.out, got) { 565*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("test case %s", testString) 566*1fa6dee9SAndroid Build Coastguard Worker t.Errorf("incorrect output") 567*1fa6dee9SAndroid Build Coastguard Worker t.Errorf(" expected: %#v", testCase.out) 568*1fa6dee9SAndroid Build Coastguard Worker t.Errorf(" got: %#v", got) 569*1fa6dee9SAndroid Build Coastguard Worker } 570*1fa6dee9SAndroid Build Coastguard Worker } 571*1fa6dee9SAndroid Build Coastguard Worker} 572