github.com/gogf/gf/v2@v2.7.4/container/gmap/gmap_z_unit_hash_int_str_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 gm file, 5 // You can obtain one at https://github.com/gogf/gf. 6 7 package gmap_test 8 9 import ( 10 "testing" 11 12 "github.com/gogf/gf/v2/container/garray" 13 "github.com/gogf/gf/v2/container/gmap" 14 "github.com/gogf/gf/v2/frame/g" 15 "github.com/gogf/gf/v2/internal/json" 16 "github.com/gogf/gf/v2/test/gtest" 17 "github.com/gogf/gf/v2/util/gconv" 18 ) 19 20 func getStr() string { 21 return "z" 22 } 23 24 func Test_IntStrMap_Var(t *testing.T) { 25 gtest.C(t, func(t *gtest.T) { 26 var m gmap.IntStrMap 27 m.Set(1, "a") 28 29 t.Assert(m.Get(1), "a") 30 t.Assert(m.Size(), 1) 31 t.Assert(m.IsEmpty(), false) 32 33 t.Assert(m.GetOrSet(2, "b"), "b") 34 t.Assert(m.SetIfNotExist(2, "b"), false) 35 36 t.Assert(m.SetIfNotExist(3, "c"), true) 37 38 t.Assert(m.Remove(2), "b") 39 t.Assert(m.Contains(2), false) 40 41 t.AssertIN(3, m.Keys()) 42 t.AssertIN(1, m.Keys()) 43 t.AssertIN("a", m.Values()) 44 t.AssertIN("c", m.Values()) 45 46 m_f := gmap.NewIntStrMap() 47 m_f.Set(1, "2") 48 m_f.Flip() 49 t.Assert(m_f.Map(), map[int]string{2: "1"}) 50 51 m.Clear() 52 t.Assert(m.Size(), 0) 53 t.Assert(m.IsEmpty(), true) 54 }) 55 } 56 57 func Test_IntStrMap_Basic(t *testing.T) { 58 gtest.C(t, func(t *gtest.T) { 59 m := gmap.NewIntStrMap() 60 m.Set(1, "a") 61 62 t.Assert(m.Get(1), "a") 63 t.Assert(m.Size(), 1) 64 t.Assert(m.IsEmpty(), false) 65 66 t.Assert(m.GetOrSet(1, "a"), "a") 67 t.Assert(m.GetOrSet(2, "b"), "b") 68 t.Assert(m.SetIfNotExist(2, "b"), false) 69 70 t.Assert(m.SetIfNotExist(3, "c"), true) 71 72 t.Assert(m.Remove(2), "b") 73 t.Assert(m.Contains(2), false) 74 75 t.AssertIN(3, m.Keys()) 76 t.AssertIN(1, m.Keys()) 77 t.AssertIN("a", m.Values()) 78 t.AssertIN("c", m.Values()) 79 80 // 反转之后不成为以下 map,flip 操作只是翻转原 map 81 // t.Assert(m.Map(), map[string]int{"a": 1, "c": 3}) 82 m_f := gmap.NewIntStrMap() 83 m_f.Set(1, "2") 84 m_f.Flip() 85 t.Assert(m_f.Map(), map[int]string{2: "1"}) 86 87 m.Clear() 88 t.Assert(m.Size(), 0) 89 t.Assert(m.IsEmpty(), true) 90 91 m2 := gmap.NewIntStrMapFrom(map[int]string{1: "a", 2: "b"}) 92 t.Assert(m2.Map(), map[int]string{1: "a", 2: "b"}) 93 }) 94 95 gtest.C(t, func(t *gtest.T) { 96 m := gmap.NewIntStrMap(true) 97 m.Set(1, "val1") 98 t.Assert(m.Map(), map[int]string{1: "val1"}) 99 }) 100 } 101 102 func TestIntStrMap_MapStrAny(t *testing.T) { 103 gtest.C(t, func(t *gtest.T) { 104 m := gmap.NewIntStrMap() 105 m.GetOrSetFunc(1, getStr) 106 m.GetOrSetFuncLock(2, getStr) 107 t.Assert(m.MapStrAny(), g.MapStrAny{"1": "z", "2": "z"}) 108 }) 109 } 110 111 func TestIntStrMap_Sets(t *testing.T) { 112 gtest.C(t, func(t *gtest.T) { 113 m := gmap.NewIntStrMapFrom(nil) 114 m.Sets(g.MapIntStr{1: "z", 2: "z"}) 115 t.Assert(len(m.Map()), 2) 116 }) 117 } 118 119 func Test_IntStrMap_Set_Fun(t *testing.T) { 120 gtest.C(t, func(t *gtest.T) { 121 m := gmap.NewIntStrMap() 122 m.GetOrSetFunc(1, getStr) 123 m.GetOrSetFuncLock(2, getStr) 124 t.Assert(m.GetOrSetFunc(1, getStr), "z") 125 t.Assert(m.GetOrSetFuncLock(2, getStr), "z") 126 t.Assert(m.Get(1), "z") 127 t.Assert(m.Get(2), "z") 128 t.Assert(m.SetIfNotExistFunc(1, getStr), false) 129 t.Assert(m.SetIfNotExistFunc(3, getStr), true) 130 131 t.Assert(m.SetIfNotExistFuncLock(2, getStr), false) 132 t.Assert(m.SetIfNotExistFuncLock(4, getStr), true) 133 }) 134 135 gtest.C(t, func(t *gtest.T) { 136 m := gmap.NewIntStrMapFrom(nil) 137 t.Assert(m.GetOrSetFuncLock(1, getStr), "z") 138 }) 139 140 gtest.C(t, func(t *gtest.T) { 141 m := gmap.NewIntStrMapFrom(nil) 142 t.Assert(m.SetIfNotExistFuncLock(1, getStr), true) 143 }) 144 } 145 146 func Test_IntStrMap_Batch(t *testing.T) { 147 gtest.C(t, func(t *gtest.T) { 148 m := gmap.NewIntStrMap() 149 m.Sets(map[int]string{1: "a", 2: "b", 3: "c"}) 150 t.Assert(m.Map(), map[int]string{1: "a", 2: "b", 3: "c"}) 151 m.Removes([]int{1, 2}) 152 t.Assert(m.Map(), map[int]interface{}{3: "c"}) 153 }) 154 } 155 156 func Test_IntStrMap_Iterator_Deadlock(t *testing.T) { 157 gtest.C(t, func(t *gtest.T) { 158 m := gmap.NewIntStrMapFrom(map[int]string{1: "1", 2: "2", 3: "3", 4: "4"}, true) 159 m.Iterator(func(k int, _ string) bool { 160 if k%2 == 0 { 161 m.Remove(k) 162 } 163 return true 164 }) 165 t.Assert(m.Map(), map[int]string{ 166 1: "1", 167 3: "3", 168 }) 169 }) 170 } 171 172 func Test_IntStrMap_Iterator(t *testing.T) { 173 gtest.C(t, func(t *gtest.T) { 174 expect := map[int]string{1: "a", 2: "b"} 175 m := gmap.NewIntStrMapFrom(expect) 176 m.Iterator(func(k int, v string) bool { 177 t.Assert(expect[k], v) 178 return true 179 }) 180 // 断言返回值对遍历控制 181 i := 0 182 j := 0 183 m.Iterator(func(k int, v string) bool { 184 i++ 185 return true 186 }) 187 m.Iterator(func(k int, v string) bool { 188 j++ 189 return false 190 }) 191 t.Assert(i, 2) 192 t.Assert(j, 1) 193 }) 194 } 195 196 func Test_IntStrMap_Lock(t *testing.T) { 197 gtest.C(t, func(t *gtest.T) { 198 expect := map[int]string{1: "a", 2: "b", 3: "c"} 199 m := gmap.NewIntStrMapFrom(expect) 200 m.LockFunc(func(m map[int]string) { 201 t.Assert(m, expect) 202 }) 203 m.RLockFunc(func(m map[int]string) { 204 t.Assert(m, expect) 205 }) 206 }) 207 } 208 209 func Test_IntStrMap_Clone(t *testing.T) { 210 gtest.C(t, func(t *gtest.T) { 211 // clone 方法是深克隆 212 m := gmap.NewIntStrMapFrom(map[int]string{1: "a", 2: "b", 3: "c"}) 213 214 m_clone := m.Clone() 215 m.Remove(1) 216 // 修改原 map,clone 后的 map 不影响 217 t.AssertIN(1, m_clone.Keys()) 218 219 m_clone.Remove(2) 220 // 修改clone map,原 map 不影响 221 t.AssertIN(2, m.Keys()) 222 }) 223 } 224 225 func Test_IntStrMap_Merge(t *testing.T) { 226 gtest.C(t, func(t *gtest.T) { 227 m1 := gmap.NewIntStrMap() 228 m2 := gmap.NewIntStrMap() 229 m1.Set(1, "a") 230 m2.Set(2, "b") 231 m1.Merge(m2) 232 t.Assert(m1.Map(), map[int]string{1: "a", 2: "b"}) 233 234 m3 := gmap.NewIntStrMapFrom(nil) 235 m3.Merge(m2) 236 t.Assert(m3.Map(), m2.Map()) 237 }) 238 } 239 240 func Test_IntStrMap_Map(t *testing.T) { 241 gtest.C(t, func(t *gtest.T) { 242 m := gmap.NewIntStrMap() 243 m.Set(1, "0") 244 m.Set(2, "2") 245 t.Assert(m.Get(1), "0") 246 t.Assert(m.Get(2), "2") 247 data := m.Map() 248 t.Assert(data[1], "0") 249 t.Assert(data[2], "2") 250 data[3] = "3" 251 t.Assert(m.Get(3), "3") 252 m.Set(4, "4") 253 t.Assert(data[4], "4") 254 }) 255 } 256 257 func Test_IntStrMap_MapCopy(t *testing.T) { 258 gtest.C(t, func(t *gtest.T) { 259 m := gmap.NewIntStrMap() 260 m.Set(1, "0") 261 m.Set(2, "2") 262 t.Assert(m.Get(1), "0") 263 t.Assert(m.Get(2), "2") 264 data := m.MapCopy() 265 t.Assert(data[1], "0") 266 t.Assert(data[2], "2") 267 data[3] = "3" 268 t.Assert(m.Get(3), "") 269 m.Set(4, "4") 270 t.Assert(data[4], "") 271 }) 272 } 273 274 func Test_IntStrMap_FilterEmpty(t *testing.T) { 275 gtest.C(t, func(t *gtest.T) { 276 m := gmap.NewIntStrMap() 277 m.Set(1, "") 278 m.Set(2, "2") 279 t.Assert(m.Size(), 2) 280 t.Assert(m.Get(2), "2") 281 m.FilterEmpty() 282 t.Assert(m.Size(), 1) 283 t.Assert(m.Get(2), "2") 284 }) 285 } 286 287 func Test_IntStrMap_Json(t *testing.T) { 288 // Marshal 289 gtest.C(t, func(t *gtest.T) { 290 data := g.MapIntStr{ 291 1: "v1", 292 2: "v2", 293 } 294 m1 := gmap.NewIntStrMapFrom(data) 295 b1, err1 := json.Marshal(m1) 296 b2, err2 := json.Marshal(data) 297 t.Assert(err1, err2) 298 t.Assert(b1, b2) 299 }) 300 // Unmarshal 301 gtest.C(t, func(t *gtest.T) { 302 data := g.MapIntStr{ 303 1: "v1", 304 2: "v2", 305 } 306 b, err := json.Marshal(data) 307 t.AssertNil(err) 308 309 m := gmap.NewIntStrMap() 310 err = json.UnmarshalUseNumber(b, m) 311 t.AssertNil(err) 312 t.Assert(m.Get(1), data[1]) 313 t.Assert(m.Get(2), data[2]) 314 }) 315 } 316 317 func Test_IntStrMap_Pop(t *testing.T) { 318 gtest.C(t, func(t *gtest.T) { 319 m := gmap.NewIntStrMapFrom(g.MapIntStr{ 320 1: "v1", 321 2: "v2", 322 }) 323 t.Assert(m.Size(), 2) 324 325 k1, v1 := m.Pop() 326 t.AssertIN(k1, g.Slice{1, 2}) 327 t.AssertIN(v1, g.Slice{"v1", "v2"}) 328 t.Assert(m.Size(), 1) 329 k2, v2 := m.Pop() 330 t.AssertIN(k2, g.Slice{1, 2}) 331 t.AssertIN(v2, g.Slice{"v1", "v2"}) 332 t.Assert(m.Size(), 0) 333 334 t.AssertNE(k1, k2) 335 t.AssertNE(v1, v2) 336 337 k3, v3 := m.Pop() 338 t.Assert(k3, 0) 339 t.Assert(v3, "") 340 }) 341 } 342 343 func Test_IntStrMap_Pops(t *testing.T) { 344 gtest.C(t, func(t *gtest.T) { 345 m := gmap.NewIntStrMapFrom(g.MapIntStr{ 346 1: "v1", 347 2: "v2", 348 3: "v3", 349 }) 350 t.Assert(m.Size(), 3) 351 352 kArray := garray.New() 353 vArray := garray.New() 354 for k, v := range m.Pops(1) { 355 t.AssertIN(k, g.Slice{1, 2, 3}) 356 t.AssertIN(v, g.Slice{"v1", "v2", "v3"}) 357 kArray.Append(k) 358 vArray.Append(v) 359 } 360 t.Assert(m.Size(), 2) 361 for k, v := range m.Pops(2) { 362 t.AssertIN(k, g.Slice{1, 2, 3}) 363 t.AssertIN(v, g.Slice{"v1", "v2", "v3"}) 364 kArray.Append(k) 365 vArray.Append(v) 366 } 367 t.Assert(m.Size(), 0) 368 369 t.Assert(kArray.Unique().Len(), 3) 370 t.Assert(vArray.Unique().Len(), 3) 371 372 v := m.Pops(1) 373 t.AssertNil(v) 374 v = m.Pops(-1) 375 t.AssertNil(v) 376 }) 377 } 378 379 func TestIntStrMap_UnmarshalValue(t *testing.T) { 380 type V struct { 381 Name string 382 Map *gmap.IntStrMap 383 } 384 // JSON 385 gtest.C(t, func(t *gtest.T) { 386 var v *V 387 err := gconv.Struct(map[string]interface{}{ 388 "name": "john", 389 "map": []byte(`{"1":"v1","2":"v2"}`), 390 }, &v) 391 t.AssertNil(err) 392 t.Assert(v.Name, "john") 393 t.Assert(v.Map.Size(), 2) 394 t.Assert(v.Map.Get(1), "v1") 395 t.Assert(v.Map.Get(2), "v2") 396 }) 397 // Map 398 gtest.C(t, func(t *gtest.T) { 399 var v *V 400 err := gconv.Struct(map[string]interface{}{ 401 "name": "john", 402 "map": g.MapIntAny{ 403 1: "v1", 404 2: "v2", 405 }, 406 }, &v) 407 t.AssertNil(err) 408 t.Assert(v.Name, "john") 409 t.Assert(v.Map.Size(), 2) 410 t.Assert(v.Map.Get(1), "v1") 411 t.Assert(v.Map.Get(2), "v2") 412 }) 413 } 414 415 func TestIntStrMap_Replace(t *testing.T) { 416 gtest.C(t, func(t *gtest.T) { 417 m := gmap.NewIntStrMapFrom(g.MapIntStr{ 418 1: "v1", 419 2: "v2", 420 3: "v3", 421 }) 422 423 t.Assert(m.Get(1), "v1") 424 t.Assert(m.Get(2), "v2") 425 t.Assert(m.Get(3), "v3") 426 427 m.Replace(g.MapIntStr{ 428 1: "v2", 429 2: "v3", 430 3: "v1", 431 }) 432 433 t.Assert(m.Get(1), "v2") 434 t.Assert(m.Get(2), "v3") 435 t.Assert(m.Get(3), "v1") 436 }) 437 } 438 439 func TestIntStrMap_String(t *testing.T) { 440 gtest.C(t, func(t *gtest.T) { 441 m := gmap.NewIntStrMapFrom(g.MapIntStr{ 442 1: "v1", 443 2: "v2", 444 3: "v3", 445 }) 446 t.Assert(m.String(), "{\"1\":\"v1\",\"2\":\"v2\",\"3\":\"v3\"}") 447 448 m = nil 449 t.Assert(len(m.String()), 0) 450 }) 451 } 452 453 func Test_IntStrMap_DeepCopy(t *testing.T) { 454 gtest.C(t, func(t *gtest.T) { 455 m := gmap.NewIntStrMapFrom(g.MapIntStr{ 456 1: "val1", 457 2: "val2", 458 }) 459 t.Assert(m.Size(), 2) 460 461 n := m.DeepCopy().(*gmap.IntStrMap) 462 n.Set(1, "v1") 463 t.AssertNE(m.Get(1), n.Get(1)) 464 }) 465 } 466 467 func Test_IntStrMap_IsSubOf(t *testing.T) { 468 gtest.C(t, func(t *gtest.T) { 469 m1 := gmap.NewIntStrMapFrom(g.MapIntStr{ 470 1: "v1", 471 2: "v2", 472 }) 473 m2 := gmap.NewIntStrMapFrom(g.MapIntStr{ 474 2: "v2", 475 }) 476 t.Assert(m1.IsSubOf(m2), false) 477 t.Assert(m2.IsSubOf(m1), true) 478 t.Assert(m2.IsSubOf(m2), true) 479 }) 480 } 481 482 func Test_IntStrMap_Diff(t *testing.T) { 483 gtest.C(t, func(t *gtest.T) { 484 m1 := gmap.NewIntStrMapFrom(g.MapIntStr{ 485 0: "0", 486 1: "1", 487 2: "2", 488 3: "3", 489 }) 490 m2 := gmap.NewIntStrMapFrom(g.MapIntStr{ 491 0: "0", 492 2: "2", 493 3: "31", 494 4: "4", 495 }) 496 addedKeys, removedKeys, updatedKeys := m1.Diff(m2) 497 t.Assert(addedKeys, []int{4}) 498 t.Assert(removedKeys, []int{1}) 499 t.Assert(updatedKeys, []int{3}) 500 }) 501 }