github.com/wangyougui/gf/v2@v2.6.5/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/wangyougui/gf. 6 7 package gmap_test 8 9 import ( 10 "testing" 11 12 "github.com/wangyougui/gf/v2/container/garray" 13 "github.com/wangyougui/gf/v2/container/gmap" 14 "github.com/wangyougui/gf/v2/frame/g" 15 "github.com/wangyougui/gf/v2/internal/json" 16 "github.com/wangyougui/gf/v2/test/gtest" 17 "github.com/wangyougui/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(t *testing.T) { 157 gtest.C(t, func(t *gtest.T) { 158 expect := map[int]string{1: "a", 2: "b"} 159 m := gmap.NewIntStrMapFrom(expect) 160 m.Iterator(func(k int, v string) bool { 161 t.Assert(expect[k], v) 162 return true 163 }) 164 // 断言返回值对遍历控制 165 i := 0 166 j := 0 167 m.Iterator(func(k int, v string) bool { 168 i++ 169 return true 170 }) 171 m.Iterator(func(k int, v string) bool { 172 j++ 173 return false 174 }) 175 t.Assert(i, 2) 176 t.Assert(j, 1) 177 }) 178 } 179 180 func Test_IntStrMap_Lock(t *testing.T) { 181 gtest.C(t, func(t *gtest.T) { 182 expect := map[int]string{1: "a", 2: "b", 3: "c"} 183 m := gmap.NewIntStrMapFrom(expect) 184 m.LockFunc(func(m map[int]string) { 185 t.Assert(m, expect) 186 }) 187 m.RLockFunc(func(m map[int]string) { 188 t.Assert(m, expect) 189 }) 190 }) 191 } 192 193 func Test_IntStrMap_Clone(t *testing.T) { 194 gtest.C(t, func(t *gtest.T) { 195 // clone 方法是深克隆 196 m := gmap.NewIntStrMapFrom(map[int]string{1: "a", 2: "b", 3: "c"}) 197 198 m_clone := m.Clone() 199 m.Remove(1) 200 // 修改原 map,clone 后的 map 不影响 201 t.AssertIN(1, m_clone.Keys()) 202 203 m_clone.Remove(2) 204 // 修改clone map,原 map 不影响 205 t.AssertIN(2, m.Keys()) 206 }) 207 } 208 209 func Test_IntStrMap_Merge(t *testing.T) { 210 gtest.C(t, func(t *gtest.T) { 211 m1 := gmap.NewIntStrMap() 212 m2 := gmap.NewIntStrMap() 213 m1.Set(1, "a") 214 m2.Set(2, "b") 215 m1.Merge(m2) 216 t.Assert(m1.Map(), map[int]string{1: "a", 2: "b"}) 217 218 m3 := gmap.NewIntStrMapFrom(nil) 219 m3.Merge(m2) 220 t.Assert(m3.Map(), m2.Map()) 221 }) 222 } 223 224 func Test_IntStrMap_Map(t *testing.T) { 225 gtest.C(t, func(t *gtest.T) { 226 m := gmap.NewIntStrMap() 227 m.Set(1, "0") 228 m.Set(2, "2") 229 t.Assert(m.Get(1), "0") 230 t.Assert(m.Get(2), "2") 231 data := m.Map() 232 t.Assert(data[1], "0") 233 t.Assert(data[2], "2") 234 data[3] = "3" 235 t.Assert(m.Get(3), "3") 236 m.Set(4, "4") 237 t.Assert(data[4], "4") 238 }) 239 } 240 241 func Test_IntStrMap_MapCopy(t *testing.T) { 242 gtest.C(t, func(t *gtest.T) { 243 m := gmap.NewIntStrMap() 244 m.Set(1, "0") 245 m.Set(2, "2") 246 t.Assert(m.Get(1), "0") 247 t.Assert(m.Get(2), "2") 248 data := m.MapCopy() 249 t.Assert(data[1], "0") 250 t.Assert(data[2], "2") 251 data[3] = "3" 252 t.Assert(m.Get(3), "") 253 m.Set(4, "4") 254 t.Assert(data[4], "") 255 }) 256 } 257 258 func Test_IntStrMap_FilterEmpty(t *testing.T) { 259 gtest.C(t, func(t *gtest.T) { 260 m := gmap.NewIntStrMap() 261 m.Set(1, "") 262 m.Set(2, "2") 263 t.Assert(m.Size(), 2) 264 t.Assert(m.Get(2), "2") 265 m.FilterEmpty() 266 t.Assert(m.Size(), 1) 267 t.Assert(m.Get(2), "2") 268 }) 269 } 270 271 func Test_IntStrMap_Json(t *testing.T) { 272 // Marshal 273 gtest.C(t, func(t *gtest.T) { 274 data := g.MapIntStr{ 275 1: "v1", 276 2: "v2", 277 } 278 m1 := gmap.NewIntStrMapFrom(data) 279 b1, err1 := json.Marshal(m1) 280 b2, err2 := json.Marshal(data) 281 t.Assert(err1, err2) 282 t.Assert(b1, b2) 283 }) 284 // Unmarshal 285 gtest.C(t, func(t *gtest.T) { 286 data := g.MapIntStr{ 287 1: "v1", 288 2: "v2", 289 } 290 b, err := json.Marshal(data) 291 t.AssertNil(err) 292 293 m := gmap.NewIntStrMap() 294 err = json.UnmarshalUseNumber(b, m) 295 t.AssertNil(err) 296 t.Assert(m.Get(1), data[1]) 297 t.Assert(m.Get(2), data[2]) 298 }) 299 } 300 301 func Test_IntStrMap_Pop(t *testing.T) { 302 gtest.C(t, func(t *gtest.T) { 303 m := gmap.NewIntStrMapFrom(g.MapIntStr{ 304 1: "v1", 305 2: "v2", 306 }) 307 t.Assert(m.Size(), 2) 308 309 k1, v1 := m.Pop() 310 t.AssertIN(k1, g.Slice{1, 2}) 311 t.AssertIN(v1, g.Slice{"v1", "v2"}) 312 t.Assert(m.Size(), 1) 313 k2, v2 := m.Pop() 314 t.AssertIN(k2, g.Slice{1, 2}) 315 t.AssertIN(v2, g.Slice{"v1", "v2"}) 316 t.Assert(m.Size(), 0) 317 318 t.AssertNE(k1, k2) 319 t.AssertNE(v1, v2) 320 321 k3, v3 := m.Pop() 322 t.Assert(k3, 0) 323 t.Assert(v3, "") 324 }) 325 } 326 327 func Test_IntStrMap_Pops(t *testing.T) { 328 gtest.C(t, func(t *gtest.T) { 329 m := gmap.NewIntStrMapFrom(g.MapIntStr{ 330 1: "v1", 331 2: "v2", 332 3: "v3", 333 }) 334 t.Assert(m.Size(), 3) 335 336 kArray := garray.New() 337 vArray := garray.New() 338 for k, v := range m.Pops(1) { 339 t.AssertIN(k, g.Slice{1, 2, 3}) 340 t.AssertIN(v, g.Slice{"v1", "v2", "v3"}) 341 kArray.Append(k) 342 vArray.Append(v) 343 } 344 t.Assert(m.Size(), 2) 345 for k, v := range m.Pops(2) { 346 t.AssertIN(k, g.Slice{1, 2, 3}) 347 t.AssertIN(v, g.Slice{"v1", "v2", "v3"}) 348 kArray.Append(k) 349 vArray.Append(v) 350 } 351 t.Assert(m.Size(), 0) 352 353 t.Assert(kArray.Unique().Len(), 3) 354 t.Assert(vArray.Unique().Len(), 3) 355 356 v := m.Pops(1) 357 t.AssertNil(v) 358 v = m.Pops(-1) 359 t.AssertNil(v) 360 }) 361 } 362 363 func TestIntStrMap_UnmarshalValue(t *testing.T) { 364 type V struct { 365 Name string 366 Map *gmap.IntStrMap 367 } 368 // JSON 369 gtest.C(t, func(t *gtest.T) { 370 var v *V 371 err := gconv.Struct(map[string]interface{}{ 372 "name": "john", 373 "map": []byte(`{"1":"v1","2":"v2"}`), 374 }, &v) 375 t.AssertNil(err) 376 t.Assert(v.Name, "john") 377 t.Assert(v.Map.Size(), 2) 378 t.Assert(v.Map.Get(1), "v1") 379 t.Assert(v.Map.Get(2), "v2") 380 }) 381 // Map 382 gtest.C(t, func(t *gtest.T) { 383 var v *V 384 err := gconv.Struct(map[string]interface{}{ 385 "name": "john", 386 "map": g.MapIntAny{ 387 1: "v1", 388 2: "v2", 389 }, 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 } 398 399 func TestIntStrMap_Replace(t *testing.T) { 400 gtest.C(t, func(t *gtest.T) { 401 m := gmap.NewIntStrMapFrom(g.MapIntStr{ 402 1: "v1", 403 2: "v2", 404 3: "v3", 405 }) 406 407 t.Assert(m.Get(1), "v1") 408 t.Assert(m.Get(2), "v2") 409 t.Assert(m.Get(3), "v3") 410 411 m.Replace(g.MapIntStr{ 412 1: "v2", 413 2: "v3", 414 3: "v1", 415 }) 416 417 t.Assert(m.Get(1), "v2") 418 t.Assert(m.Get(2), "v3") 419 t.Assert(m.Get(3), "v1") 420 }) 421 } 422 423 func TestIntStrMap_String(t *testing.T) { 424 gtest.C(t, func(t *gtest.T) { 425 m := gmap.NewIntStrMapFrom(g.MapIntStr{ 426 1: "v1", 427 2: "v2", 428 3: "v3", 429 }) 430 t.Assert(m.String(), "{\"1\":\"v1\",\"2\":\"v2\",\"3\":\"v3\"}") 431 432 m = nil 433 t.Assert(len(m.String()), 0) 434 }) 435 } 436 437 func Test_IntStrMap_DeepCopy(t *testing.T) { 438 gtest.C(t, func(t *gtest.T) { 439 m := gmap.NewIntStrMapFrom(g.MapIntStr{ 440 1: "val1", 441 2: "val2", 442 }) 443 t.Assert(m.Size(), 2) 444 445 n := m.DeepCopy().(*gmap.IntStrMap) 446 n.Set(1, "v1") 447 t.AssertNE(m.Get(1), n.Get(1)) 448 }) 449 } 450 451 func Test_IntStrMap_IsSubOf(t *testing.T) { 452 gtest.C(t, func(t *gtest.T) { 453 m1 := gmap.NewIntStrMapFrom(g.MapIntStr{ 454 1: "v1", 455 2: "v2", 456 }) 457 m2 := gmap.NewIntStrMapFrom(g.MapIntStr{ 458 2: "v2", 459 }) 460 t.Assert(m1.IsSubOf(m2), false) 461 t.Assert(m2.IsSubOf(m1), true) 462 t.Assert(m2.IsSubOf(m2), true) 463 }) 464 } 465 466 func Test_IntStrMap_Diff(t *testing.T) { 467 gtest.C(t, func(t *gtest.T) { 468 m1 := gmap.NewIntStrMapFrom(g.MapIntStr{ 469 0: "0", 470 1: "1", 471 2: "2", 472 3: "3", 473 }) 474 m2 := gmap.NewIntStrMapFrom(g.MapIntStr{ 475 0: "0", 476 2: "2", 477 3: "31", 478 4: "4", 479 }) 480 addedKeys, removedKeys, updatedKeys := m1.Diff(m2) 481 t.Assert(addedKeys, []int{4}) 482 t.Assert(removedKeys, []int{1}) 483 t.Assert(updatedKeys, []int{3}) 484 }) 485 }