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  }