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