github.com/gogf/gf/v2@v2.7.4/container/gmap/gmap_z_unit_hash_str_int_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 "strconv" 11 "testing" 12 13 "github.com/gogf/gf/v2/container/garray" 14 "github.com/gogf/gf/v2/container/gmap" 15 "github.com/gogf/gf/v2/frame/g" 16 "github.com/gogf/gf/v2/internal/json" 17 "github.com/gogf/gf/v2/test/gtest" 18 "github.com/gogf/gf/v2/util/gconv" 19 ) 20 21 func Test_StrIntMap_Var(t *testing.T) { 22 gtest.C(t, func(t *gtest.T) { 23 var m gmap.StrIntMap 24 m.Set("a", 1) 25 26 t.Assert(m.Get("a"), 1) 27 t.Assert(m.Size(), 1) 28 t.Assert(m.IsEmpty(), false) 29 30 t.Assert(m.GetOrSet("b", 2), 2) 31 t.Assert(m.SetIfNotExist("b", 2), false) 32 33 t.Assert(m.SetIfNotExist("c", 3), true) 34 35 t.Assert(m.Remove("b"), 2) 36 t.Assert(m.Contains("b"), false) 37 38 t.AssertIN("c", m.Keys()) 39 t.AssertIN("a", m.Keys()) 40 t.AssertIN(3, m.Values()) 41 t.AssertIN(1, m.Values()) 42 43 m_f := gmap.NewStrIntMap() 44 m_f.Set("1", 2) 45 m_f.Flip() 46 t.Assert(m_f.Map(), map[string]int{"2": 1}) 47 48 m.Clear() 49 t.Assert(m.Size(), 0) 50 t.Assert(m.IsEmpty(), true) 51 }) 52 } 53 54 func Test_StrIntMap_Basic(t *testing.T) { 55 gtest.C(t, func(t *gtest.T) { 56 m := gmap.NewStrIntMap() 57 m.Set("a", 1) 58 59 t.Assert(m.Get("a"), 1) 60 t.Assert(m.Size(), 1) 61 t.Assert(m.IsEmpty(), false) 62 63 t.Assert(m.GetOrSet("b", 2), 2) 64 t.Assert(m.SetIfNotExist("b", 2), false) 65 66 t.Assert(m.SetIfNotExist("c", 3), true) 67 68 t.Assert(m.Remove("b"), 2) 69 t.Assert(m.Contains("b"), false) 70 71 t.AssertIN("c", m.Keys()) 72 t.AssertIN("a", m.Keys()) 73 t.AssertIN(3, m.Values()) 74 t.AssertIN(1, m.Values()) 75 76 m_f := gmap.NewStrIntMap() 77 m_f.Set("1", 2) 78 m_f.Flip() 79 t.Assert(m_f.Map(), map[string]int{"2": 1}) 80 81 m.Clear() 82 t.Assert(m.Size(), 0) 83 t.Assert(m.IsEmpty(), true) 84 85 m2 := gmap.NewStrIntMapFrom(map[string]int{"a": 1, "b": 2}) 86 t.Assert(m2.Map(), map[string]int{"a": 1, "b": 2}) 87 }) 88 } 89 90 func Test_StrIntMap_Set_Fun(t *testing.T) { 91 gtest.C(t, func(t *gtest.T) { 92 m := gmap.NewStrIntMap() 93 94 m.GetOrSetFunc("a", getInt) 95 m.GetOrSetFuncLock("b", getInt) 96 t.Assert(m.Get("a"), 123) 97 t.Assert(m.Get("b"), 123) 98 t.Assert(m.SetIfNotExistFunc("a", getInt), false) 99 t.Assert(m.SetIfNotExistFunc("c", getInt), true) 100 101 t.Assert(m.SetIfNotExistFuncLock("b", getInt), false) 102 t.Assert(m.SetIfNotExistFuncLock("d", getInt), true) 103 }) 104 105 gtest.C(t, func(t *gtest.T) { 106 m := gmap.NewStrIntMapFrom(nil) 107 t.Assert(m.GetOrSetFuncLock("a", getInt), 123) 108 }) 109 } 110 111 func Test_StrIntMap_Batch(t *testing.T) { 112 gtest.C(t, func(t *gtest.T) { 113 m := gmap.NewStrIntMap() 114 115 m.Sets(map[string]int{"a": 1, "b": 2, "c": 3}) 116 t.Assert(m.Map(), map[string]int{"a": 1, "b": 2, "c": 3}) 117 m.Removes([]string{"a", "b"}) 118 t.Assert(m.Map(), map[string]int{"c": 3}) 119 }) 120 } 121 122 func Test_StrIntMap_Iterator_Deadlock(t *testing.T) { 123 gtest.C(t, func(t *gtest.T) { 124 m := gmap.NewStrIntMapFrom(map[string]int{"1": 1, "2": 2, "3": 3, "4": 4}, true) 125 m.Iterator(func(k string, _ int) bool { 126 kInt, _ := strconv.Atoi(k) 127 if kInt%2 == 0 { 128 m.Remove(k) 129 } 130 return true 131 }) 132 t.Assert(m.Size(), 2) 133 }) 134 } 135 136 func Test_StrIntMap_Iterator(t *testing.T) { 137 gtest.C(t, func(t *gtest.T) { 138 expect := map[string]int{"a": 1, "b": 2} 139 m := gmap.NewStrIntMapFrom(expect) 140 m.Iterator(func(k string, v int) bool { 141 t.Assert(expect[k], v) 142 return true 143 }) 144 // 断言返回值对遍历控制 145 i := 0 146 j := 0 147 m.Iterator(func(k string, v int) bool { 148 i++ 149 return true 150 }) 151 m.Iterator(func(k string, v int) bool { 152 j++ 153 return false 154 }) 155 t.Assert(i, 2) 156 t.Assert(j, 1) 157 }) 158 } 159 160 func Test_StrIntMap_Lock(t *testing.T) { 161 gtest.C(t, func(t *gtest.T) { 162 expect := map[string]int{"a": 1, "b": 2} 163 164 m := gmap.NewStrIntMapFrom(expect) 165 m.LockFunc(func(m map[string]int) { 166 t.Assert(m, expect) 167 }) 168 m.RLockFunc(func(m map[string]int) { 169 t.Assert(m, expect) 170 }) 171 }) 172 } 173 174 func Test_StrIntMap_Clone(t *testing.T) { 175 gtest.C(t, func(t *gtest.T) { 176 // clone 方法是深克隆 177 m := gmap.NewStrIntMapFrom(map[string]int{"a": 1, "b": 2, "c": 3}) 178 179 m_clone := m.Clone() 180 m.Remove("a") 181 // 修改原 map,clone 后的 map 不影响 182 t.AssertIN("a", m_clone.Keys()) 183 184 m_clone.Remove("b") 185 // 修改clone map,原 map 不影响 186 t.AssertIN("b", m.Keys()) 187 }) 188 } 189 190 func Test_StrIntMap_Merge(t *testing.T) { 191 gtest.C(t, func(t *gtest.T) { 192 m1 := gmap.NewStrIntMap() 193 m2 := gmap.NewStrIntMap() 194 m1.Set("a", 1) 195 m2.Set("b", 2) 196 m1.Merge(m2) 197 t.Assert(m1.Map(), map[string]int{"a": 1, "b": 2}) 198 m3 := gmap.NewStrIntMapFrom(nil) 199 m3.Merge(m2) 200 t.Assert(m3.Map(), m2.Map()) 201 }) 202 } 203 204 func Test_StrIntMap_Map(t *testing.T) { 205 gtest.C(t, func(t *gtest.T) { 206 m := gmap.NewStrIntMap() 207 m.Set("1", 1) 208 m.Set("2", 2) 209 t.Assert(m.Get("1"), 1) 210 t.Assert(m.Get("2"), 2) 211 data := m.Map() 212 t.Assert(data["1"], 1) 213 t.Assert(data["2"], 2) 214 data["3"] = 3 215 t.Assert(m.Get("3"), 3) 216 m.Set("4", 4) 217 t.Assert(data["4"], 4) 218 }) 219 } 220 221 func Test_StrIntMap_MapCopy(t *testing.T) { 222 gtest.C(t, func(t *gtest.T) { 223 m := gmap.NewStrIntMap() 224 m.Set("1", 1) 225 m.Set("2", 2) 226 t.Assert(m.Get("1"), 1) 227 t.Assert(m.Get("2"), 2) 228 data := m.MapCopy() 229 t.Assert(data["1"], 1) 230 t.Assert(data["2"], 2) 231 data["3"] = 3 232 t.Assert(m.Get("3"), 0) 233 m.Set("4", 4) 234 t.Assert(data["4"], 0) 235 }) 236 } 237 238 func Test_StrIntMap_FilterEmpty(t *testing.T) { 239 gtest.C(t, func(t *gtest.T) { 240 m := gmap.NewStrIntMap() 241 m.Set("1", 0) 242 m.Set("2", 2) 243 t.Assert(m.Size(), 2) 244 t.Assert(m.Get("1"), 0) 245 t.Assert(m.Get("2"), 2) 246 m.FilterEmpty() 247 t.Assert(m.Size(), 1) 248 t.Assert(m.Get("2"), 2) 249 }) 250 } 251 252 func Test_StrIntMap_Json(t *testing.T) { 253 // Marshal 254 gtest.C(t, func(t *gtest.T) { 255 data := g.MapStrInt{ 256 "k1": 1, 257 "k2": 2, 258 } 259 m1 := gmap.NewStrIntMapFrom(data) 260 b1, err1 := json.Marshal(m1) 261 b2, err2 := json.Marshal(data) 262 t.Assert(err1, err2) 263 t.Assert(b1, b2) 264 }) 265 // Unmarshal 266 gtest.C(t, func(t *gtest.T) { 267 data := g.MapStrInt{ 268 "k1": 1, 269 "k2": 2, 270 } 271 b, err := json.Marshal(data) 272 t.AssertNil(err) 273 274 m := gmap.NewStrIntMap() 275 err = json.UnmarshalUseNumber(b, m) 276 t.AssertNil(err) 277 t.Assert(m.Get("k1"), data["k1"]) 278 t.Assert(m.Get("k2"), data["k2"]) 279 }) 280 gtest.C(t, func(t *gtest.T) { 281 data := g.MapStrInt{ 282 "k1": 1, 283 "k2": 2, 284 } 285 b, err := json.Marshal(data) 286 t.AssertNil(err) 287 288 var m gmap.StrIntMap 289 err = json.UnmarshalUseNumber(b, &m) 290 t.AssertNil(err) 291 t.Assert(m.Get("k1"), data["k1"]) 292 t.Assert(m.Get("k2"), data["k2"]) 293 }) 294 } 295 296 func Test_StrIntMap_Pop(t *testing.T) { 297 gtest.C(t, func(t *gtest.T) { 298 m := gmap.NewStrIntMapFrom(g.MapStrInt{ 299 "k1": 11, 300 "k2": 22, 301 }) 302 t.Assert(m.Size(), 2) 303 304 k1, v1 := m.Pop() 305 t.AssertIN(k1, g.Slice{"k1", "k2"}) 306 t.AssertIN(v1, g.Slice{11, 22}) 307 t.Assert(m.Size(), 1) 308 k2, v2 := m.Pop() 309 t.AssertIN(k2, g.Slice{"k1", "k2"}) 310 t.AssertIN(v2, g.Slice{11, 22}) 311 t.Assert(m.Size(), 0) 312 313 t.AssertNE(k1, k2) 314 t.AssertNE(v1, v2) 315 316 k3, v3 := m.Pop() 317 t.Assert(k3, "") 318 t.Assert(v3, 0) 319 }) 320 } 321 322 func Test_StrIntMap_Pops(t *testing.T) { 323 gtest.C(t, func(t *gtest.T) { 324 m := gmap.NewStrIntMapFrom(g.MapStrInt{ 325 "k1": 11, 326 "k2": 22, 327 "k3": 33, 328 }) 329 t.Assert(m.Size(), 3) 330 331 kArray := garray.New() 332 vArray := garray.New() 333 for k, v := range m.Pops(1) { 334 t.AssertIN(k, g.Slice{"k1", "k2", "k3"}) 335 t.AssertIN(v, g.Slice{11, 22, 33}) 336 kArray.Append(k) 337 vArray.Append(v) 338 } 339 t.Assert(m.Size(), 2) 340 for k, v := range m.Pops(2) { 341 t.AssertIN(k, g.Slice{"k1", "k2", "k3"}) 342 t.AssertIN(v, g.Slice{11, 22, 33}) 343 kArray.Append(k) 344 vArray.Append(v) 345 } 346 t.Assert(m.Size(), 0) 347 348 t.Assert(kArray.Unique().Len(), 3) 349 t.Assert(vArray.Unique().Len(), 3) 350 351 v := m.Pops(1) 352 t.AssertNil(v) 353 v = m.Pops(-1) 354 t.AssertNil(v) 355 }) 356 } 357 358 func TestStrIntMap_UnmarshalValue(t *testing.T) { 359 type V struct { 360 Name string 361 Map *gmap.StrIntMap 362 } 363 // JSON 364 gtest.C(t, func(t *gtest.T) { 365 var v *V 366 err := gconv.Struct(map[string]interface{}{ 367 "name": "john", 368 "map": []byte(`{"k1":1,"k2":2}`), 369 }, &v) 370 t.AssertNil(err) 371 t.Assert(v.Name, "john") 372 t.Assert(v.Map.Size(), 2) 373 t.Assert(v.Map.Get("k1"), 1) 374 t.Assert(v.Map.Get("k2"), 2) 375 }) 376 // Map 377 gtest.C(t, func(t *gtest.T) { 378 var v *V 379 err := gconv.Struct(map[string]interface{}{ 380 "name": "john", 381 "map": g.Map{ 382 "k1": 1, 383 "k2": 2, 384 }, 385 }, &v) 386 t.AssertNil(err) 387 t.Assert(v.Name, "john") 388 t.Assert(v.Map.Size(), 2) 389 t.Assert(v.Map.Get("k1"), 1) 390 t.Assert(v.Map.Get("k2"), 2) 391 }) 392 } 393 394 func Test_StrIntMap_DeepCopy(t *testing.T) { 395 gtest.C(t, func(t *gtest.T) { 396 m := gmap.NewStrIntMapFrom(g.MapStrInt{ 397 "key1": 1, 398 "key2": 2, 399 }) 400 t.Assert(m.Size(), 2) 401 402 n := m.DeepCopy().(*gmap.StrIntMap) 403 n.Set("key1", 2) 404 t.AssertNE(m.Get("key1"), n.Get("key1")) 405 }) 406 } 407 408 func Test_StrIntMap_IsSubOf(t *testing.T) { 409 gtest.C(t, func(t *gtest.T) { 410 m1 := gmap.NewStrIntMapFrom(g.MapStrInt{ 411 "k1": 1, 412 "k2": 2, 413 }) 414 m2 := gmap.NewStrIntMapFrom(g.MapStrInt{ 415 "k2": 2, 416 }) 417 t.Assert(m1.IsSubOf(m2), false) 418 t.Assert(m2.IsSubOf(m1), true) 419 t.Assert(m2.IsSubOf(m2), true) 420 }) 421 } 422 423 func Test_StrIntMap_Diff(t *testing.T) { 424 gtest.C(t, func(t *gtest.T) { 425 m1 := gmap.NewStrIntMapFrom(g.MapStrInt{ 426 "0": 0, 427 "1": 1, 428 "2": 2, 429 "3": 3, 430 }) 431 m2 := gmap.NewStrIntMapFrom(g.MapStrInt{ 432 "0": 0, 433 "2": 2, 434 "3": 31, 435 "4": 4, 436 }) 437 addedKeys, removedKeys, updatedKeys := m1.Diff(m2) 438 t.Assert(addedKeys, []string{"4"}) 439 t.Assert(removedKeys, []string{"1"}) 440 t.Assert(updatedKeys, []string{"3"}) 441 }) 442 }