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  }