github.com/gogf/gf/v2@v2.7.4/util/gconv/gconv_z_unit_scan_test.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/gogf/gf. 6 7 package gconv_test 8 9 import ( 10 "fmt" 11 "testing" 12 13 "github.com/gogf/gf/v2/container/gvar" 14 "github.com/gogf/gf/v2/errors/gerror" 15 "github.com/gogf/gf/v2/frame/g" 16 "github.com/gogf/gf/v2/os/gtime" 17 "github.com/gogf/gf/v2/test/gtest" 18 "github.com/gogf/gf/v2/util/gconv" 19 ) 20 21 type scanStructTest struct { 22 Name string 23 Place string 24 } 25 26 type scanExpectTest struct { 27 mapStrStr map[string]string 28 mapStrAny map[string]interface{} 29 mapAnyAny map[interface{}]interface{} 30 31 structSub scanStructTest 32 structSubPtr *scanStructTest 33 } 34 35 var scanValueMapsTest = []map[string]interface{}{ 36 {"Name": false, "Place": true}, 37 {"Name": int(0), "Place": int(1)}, 38 {"Name": int8(0), "Place": int8(1)}, 39 {"Name": int16(0), "Place": int16(1)}, 40 {"Name": int32(0), "Place": int32(1)}, 41 {"Name": int64(0), "Place": int64(1)}, 42 {"Name": uint(0), "Place": uint(1)}, 43 {"Name": uint8(0), "Place": uint8(1)}, 44 {"Name": uint16(0), "Place": uint16(1)}, 45 {"Name": uint32(0), "Place": uint32(1)}, 46 {"Name": uint64(0), "Place": uint64(1)}, 47 {"Name": float32(0), "Place": float32(1)}, 48 {"Name": float64(0), "Place": float64(1)}, 49 {"Name": "Mercury", "Place": "卡罗利斯盆地"}, 50 {"Name": []byte("Saturn"), "Place": []byte("土星环")}, 51 {"Name": complex64(0), "Place": complex64(1 + 2i)}, 52 {"Name": complex128(0), "Place": complex128(1 + 2i)}, 53 {"Name": interface{}(0), "Place": interface{}("1")}, 54 {"Name": gvar.New("Jupiter"), "Place": gvar.New("大红斑")}, 55 {"Name": gtime.New("2024-01-01 01:01:01"), "Place": gtime.New("2021-01-01 01:01:01")}, 56 {"Name": map[string]string{"Name": "Sun"}, "Place": map[string]string{"Place": "太阳黑子"}}, 57 {"Name": []string{"Earth", "Moon"}, "Place": []string{"好望角", "万户环形山"}}, 58 } 59 60 var scanValueStructsTest = []scanStructTest{ 61 {"Venus", "阿佛洛狄特高原"}, 62 } 63 64 var scanValueJsonTest = []string{ 65 `{"Name": "Mars", "Place": "奥林帕斯山"}`, 66 } 67 68 var scanExpects = scanExpectTest{ 69 mapStrStr: make(map[string]string), 70 mapStrAny: make(map[string]interface{}), 71 mapAnyAny: make(map[interface{}]interface{}), 72 73 structSub: scanStructTest{}, 74 structSubPtr: &scanStructTest{}, 75 } 76 77 func TestScan(t *testing.T) { 78 // Test for map converting. 79 gtest.C(t, func(t *gtest.T) { 80 scanValuesTest := scanValueMapsTest 81 for _, test := range scanValuesTest { 82 var ( 83 err error 84 scanExpects = scanExpects 85 ) 86 87 err = gconv.Scan(test, &scanExpects.mapStrStr) 88 t.AssertNil(err) 89 t.Assert(test["Name"], scanExpects.mapStrStr["Name"]) 90 t.Assert(test["Place"], scanExpects.mapStrStr["Place"]) 91 92 err = gconv.Scan(test, &scanExpects.mapStrAny) 93 t.AssertNil(err) 94 t.Assert(test["Name"], scanExpects.mapStrAny["Name"]) 95 t.Assert(test["Place"], scanExpects.mapStrAny["Place"]) 96 97 err = gconv.Scan(test, &scanExpects.mapAnyAny) 98 t.AssertNil(err) 99 t.Assert(test["Name"], scanExpects.mapAnyAny["Name"]) 100 t.Assert(test["Place"], scanExpects.mapAnyAny["Place"]) 101 102 err = gconv.Scan(test, &scanExpects.structSub) 103 t.AssertNil(err) 104 t.Assert(test["Name"], scanExpects.structSub.Name) 105 t.Assert(test["Place"], scanExpects.structSub.Place) 106 107 err = gconv.Scan(test, &scanExpects.structSubPtr) 108 t.AssertNil(err) 109 t.Assert(test["Name"], scanExpects.structSubPtr.Name) 110 t.Assert(test["Place"], scanExpects.structSubPtr.Place) 111 112 } 113 }) 114 115 // Test for slice map converting. 116 gtest.C(t, func(t *gtest.T) { 117 scanValuesTest := scanValueMapsTest 118 for _, test := range scanValuesTest { 119 var ( 120 err error 121 scanExpects = scanExpects 122 maps = []map[string]interface{}{test, test} 123 ) 124 125 var mss = []map[string]string{scanExpects.mapStrStr, scanExpects.mapStrStr} 126 err = gconv.Scan(maps, &mss) 127 t.AssertNil(err) 128 t.Assert(len(mss), len(maps)) 129 for k, _ := range maps { 130 t.Assert(maps[k]["Name"], mss[k]["Name"]) 131 t.Assert(maps[k]["Place"], mss[k]["Place"]) 132 } 133 134 var msa = []map[string]interface{}{scanExpects.mapStrAny, scanExpects.mapStrAny} 135 err = gconv.Scan(maps, &msa) 136 t.AssertNil(err) 137 t.Assert(len(msa), len(maps)) 138 for k, _ := range maps { 139 t.Assert(maps[k]["Name"], msa[k]["Name"]) 140 t.Assert(maps[k]["Place"], msa[k]["Place"]) 141 } 142 143 var maa = []map[interface{}]interface{}{scanExpects.mapAnyAny, scanExpects.mapAnyAny} 144 err = gconv.Scan(maps, &maa) 145 t.AssertNil(err) 146 t.Assert(len(maa), len(maps)) 147 for k, _ := range maps { 148 t.Assert(maps[k]["Name"], maa[k]["Name"]) 149 t.Assert(maps[k]["Place"], maa[k]["Place"]) 150 } 151 152 var ss = []scanStructTest{scanExpects.structSub, scanExpects.structSub} 153 err = gconv.Scan(maps, &ss) 154 t.AssertNil(err) 155 t.Assert(len(ss), len(maps)) 156 for k, _ := range maps { 157 t.Assert(maps[k]["Name"], ss[k].Name) 158 t.Assert(maps[k]["Place"], ss[k].Place) 159 } 160 161 var ssp = []*scanStructTest{scanExpects.structSubPtr, scanExpects.structSubPtr} 162 err = gconv.Scan(maps, &ssp) 163 t.AssertNil(err) 164 t.Assert(len(ssp), len(maps)) 165 for k, _ := range maps { 166 t.Assert(maps[k]["Name"], ssp[k].Name) 167 t.Assert(maps[k]["Place"], ssp[k].Place) 168 } 169 } 170 }) 171 172 // Test for struct converting. 173 gtest.C(t, func(t *gtest.T) { 174 scanValuesTest := scanValueStructsTest 175 for _, test := range scanValuesTest { 176 var ( 177 err error 178 scanExpects = scanExpects 179 ) 180 181 err = gconv.Scan(test, &scanExpects.mapStrStr) 182 t.AssertNil(err) 183 t.Assert(test.Name, scanExpects.mapStrStr["Name"]) 184 t.Assert(test.Place, scanExpects.mapStrStr["Place"]) 185 186 err = gconv.Scan(test, &scanExpects.mapStrAny) 187 t.AssertNil(err) 188 t.Assert(test.Name, scanExpects.mapStrAny["Name"]) 189 t.Assert(test.Place, scanExpects.mapStrAny["Place"]) 190 191 err = gconv.Scan(test, &scanExpects.mapAnyAny) 192 t.AssertNil(err) 193 t.Assert(test.Name, scanExpects.mapAnyAny["Name"]) 194 t.Assert(test.Place, scanExpects.mapAnyAny["Place"]) 195 196 err = gconv.Scan(test, &scanExpects.structSub) 197 t.AssertNil(err) 198 t.Assert(test.Name, scanExpects.structSub.Name) 199 t.Assert(test.Place, scanExpects.structSub.Place) 200 201 err = gconv.Scan(test, &scanExpects.structSubPtr) 202 t.AssertNil(err) 203 t.Assert(test.Name, scanExpects.structSubPtr.Name) 204 t.Assert(test.Place, scanExpects.structSubPtr.Place) 205 } 206 }) 207 208 // Test for slice struct converting. 209 gtest.C(t, func(t *gtest.T) { 210 scanValuesTest := scanValueStructsTest 211 for _, test := range scanValuesTest { 212 var ( 213 err error 214 scanExpects = scanExpects 215 structs = []scanStructTest{test, test} 216 ) 217 218 var mss = []map[string]string{scanExpects.mapStrStr, scanExpects.mapStrStr} 219 err = gconv.Scan(structs, &mss) 220 t.AssertNil(err) 221 t.Assert(len(mss), len(structs)) 222 for k, _ := range structs { 223 t.Assert(structs[k].Name, mss[k]["Name"]) 224 t.Assert(structs[k].Place, mss[k]["Place"]) 225 } 226 227 var msa = []map[string]interface{}{scanExpects.mapStrAny, scanExpects.mapStrAny} 228 err = gconv.Scan(structs, &msa) 229 t.AssertNil(err) 230 t.Assert(len(msa), len(structs)) 231 for k, _ := range structs { 232 t.Assert(structs[k].Name, msa[k]["Name"]) 233 t.Assert(structs[k].Place, msa[k]["Place"]) 234 } 235 236 var maa = []map[interface{}]interface{}{scanExpects.mapAnyAny, scanExpects.mapAnyAny} 237 err = gconv.Scan(structs, &maa) 238 t.AssertNil(err) 239 t.Assert(len(maa), len(structs)) 240 for k, _ := range structs { 241 t.Assert(structs[k].Name, maa[k]["Name"]) 242 t.Assert(structs[k].Place, maa[k]["Place"]) 243 } 244 245 var ss = []scanStructTest{scanExpects.structSub, scanExpects.structSub} 246 err = gconv.Scan(structs, &ss) 247 t.AssertNil(err) 248 t.Assert(len(ss), len(structs)) 249 for k, _ := range structs { 250 t.Assert(structs[k].Name, ss[k].Name) 251 t.Assert(structs[k].Place, ss[k].Place) 252 } 253 254 var ssp = []*scanStructTest{scanExpects.structSubPtr, scanExpects.structSubPtr} 255 err = gconv.Scan(structs, &ssp) 256 t.AssertNil(err) 257 t.Assert(len(ssp), len(structs)) 258 for k, _ := range structs { 259 t.Assert(structs[k].Name, ssp[k].Name) 260 t.Assert(structs[k].Place, ssp[k].Place) 261 } 262 } 263 }) 264 265 // Test for json converting. 266 gtest.C(t, func(t *gtest.T) { 267 scanValuesTest := scanValueJsonTest 268 for _, test := range scanValuesTest { 269 var ( 270 err error 271 scanExpects = scanExpects 272 ) 273 274 err = gconv.Scan(test, &scanExpects.mapStrStr) 275 t.AssertNil(err) 276 t.Assert("Mars", scanExpects.mapStrStr["Name"]) 277 t.Assert("奥林帕斯山", scanExpects.mapStrStr["Place"]) 278 279 err = gconv.Scan(test, &scanExpects.mapStrAny) 280 t.AssertNil(err) 281 t.Assert("Mars", scanExpects.mapStrAny["Name"]) 282 t.Assert("奥林帕斯山", scanExpects.mapStrAny["Place"]) 283 284 err = gconv.Scan(test, &scanExpects.mapAnyAny) 285 t.Assert(err, gerror.New( 286 "json.UnmarshalUseNumber failed: json: cannot unmarshal object into Go value of type map[interface {}]interface {}", 287 )) 288 289 err = gconv.Scan(test, &scanExpects.structSub) 290 t.AssertNil(err) 291 t.Assert("Mars", scanExpects.structSub.Name) 292 t.Assert("奥林帕斯山", scanExpects.structSub.Place) 293 294 err = gconv.Scan(test, &scanExpects.structSubPtr) 295 t.AssertNil(err) 296 t.Assert("Mars", scanExpects.structSubPtr.Name) 297 t.Assert("奥林帕斯山", scanExpects.structSubPtr.Place) 298 } 299 }) 300 301 // Test for slice json converting. 302 gtest.C(t, func(t *gtest.T) { 303 scanValuesTest := scanValueJsonTest 304 for _, test := range scanValuesTest { 305 var ( 306 err error 307 scanExpects = scanExpects 308 jsons = fmt.Sprintf("[%s, %s]", test, test) 309 ) 310 311 var mss = []map[string]string{scanExpects.mapStrStr, scanExpects.mapStrStr} 312 err = gconv.Scan(jsons, &mss) 313 t.AssertNil(err) 314 t.Assert(len(mss), 2) 315 for k, _ := range mss { 316 t.Assert("Mars", mss[k]["Name"]) 317 t.Assert("奥林帕斯山", mss[k]["Place"]) 318 } 319 320 var msa = []map[string]interface{}{scanExpects.mapStrAny, scanExpects.mapStrAny} 321 err = gconv.Scan(jsons, &msa) 322 t.AssertNil(err) 323 t.Assert(len(msa), 2) 324 for k, _ := range msa { 325 t.Assert("Mars", msa[k]["Name"]) 326 t.Assert("奥林帕斯山", msa[k]["Place"]) 327 } 328 329 var maa = []map[interface{}]interface{}{scanExpects.mapAnyAny, scanExpects.mapAnyAny} 330 err = gconv.Scan(jsons, &maa) 331 t.Assert(err, gerror.New( 332 "json.UnmarshalUseNumber failed: json: cannot unmarshal object into Go value of type map[interface {}]interface {}", 333 )) 334 335 var ss = []scanStructTest{scanExpects.structSub, scanExpects.structSub} 336 err = gconv.Scan(jsons, &ss) 337 t.AssertNil(err) 338 t.Assert(len(ss), 2) 339 for k, _ := range ss { 340 t.Assert("Mars", ss[k].Name) 341 t.Assert("奥林帕斯山", ss[k].Place) 342 } 343 344 var ssp = []*scanStructTest{scanExpects.structSubPtr, scanExpects.structSubPtr} 345 err = gconv.Scan(jsons, &ssp) 346 t.AssertNil(err) 347 t.Assert(len(ssp), 2) 348 for k, _ := range ssp { 349 t.Assert("Mars", ssp[k].Name) 350 t.Assert("奥林帕斯山", ssp[k].Place) 351 } 352 } 353 }) 354 355 // Test for paramKeyToAttrMap 356 gtest.C(t, func(t *gtest.T) { 357 scanValuesTest := scanValueMapsTest 358 for _, test := range scanValuesTest { 359 var ( 360 err error 361 scanExpects = scanExpects 362 mapParameter = map[string]string{"Name": "Place", "Place": "Name"} 363 ) 364 365 // TODO: The following test cases should be working, but they are not. 366 //err = gconv.Scan(test, &scanExpects.mapStrStr, mapParameter) 367 //t.AssertNil(err) 368 //t.Assert(test["Name"], scanExpects.mapStrStr["Place"]) 369 //t.Assert(test["Place"], scanExpects.mapStrStr["Name"]) 370 // 371 //err = gconv.Scan(test, &scanExpects.mapStrAny, mapParameter) 372 //t.AssertNil(err) 373 //t.Assert(test["Name"], scanExpects.mapStrAny["Place"]) 374 //t.Assert(test["Place"], scanExpects.mapStrAny["Name"]) 375 // 376 //err = gconv.Scan(test, &scanExpects.mapAnyAny, mapParameter) 377 //t.AssertNil(err) 378 //t.Assert(test["Name"], scanExpects.mapAnyAny["Place"]) 379 //t.Assert(test["Place"], scanExpects.mapAnyAny["Name"]) 380 381 err = gconv.Scan(test, &scanExpects.structSub, mapParameter) 382 t.AssertNil(err) 383 t.Assert(test["Name"], scanExpects.structSub.Place) 384 t.Assert(test["Place"], scanExpects.structSub.Name) 385 386 err = gconv.Scan(test, &scanExpects.structSubPtr, mapParameter) 387 t.AssertNil(err) 388 t.Assert(test["Name"], scanExpects.structSubPtr.Place) 389 t.Assert(test["Place"], scanExpects.structSubPtr.Name) 390 } 391 }) 392 393 // Test for special types. 394 gtest.C(t, func(t *gtest.T) { 395 var ( 396 err error 397 src = "Sun" 398 dst = "日冕" 399 ) 400 401 err = gconv.Scan(nil, &dst) 402 t.AssertNil(err) 403 t.Assert(dst, "日冕") 404 405 err = gconv.Scan(src, nil) 406 t.Assert(err, gerror.New("destination pointer should not be nil")) 407 408 // Test for non-pointer. 409 err = gconv.Scan(src, dst) 410 t.Assert(err, gerror.New( 411 "destination pointer should be type of pointer, but got type: string", 412 )) 413 }) 414 } 415 416 func TestScanEmptyStringToCustomType(t *testing.T) { 417 gtest.C(t, func(t *gtest.T) { 418 type Status string 419 type Req struct { 420 Name string 421 Statuses []Status 422 Types []string 423 } 424 var ( 425 req *Req 426 data = g.Map{ 427 "Name": "john", 428 "Statuses": "", 429 "Types": "", 430 } 431 ) 432 err := gconv.Scan(data, &req) 433 t.AssertNil(err) 434 t.Assert(len(req.Statuses), 0) 435 t.Assert(len(req.Types), 0) 436 }) 437 }