github.com/gogf/gf/v2@v2.7.4/container/gset/gset_z_unit_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 this file,
     5  // You can obtain one at https://github.com/gogf/gf.
     6  
     7  // go test *.go
     8  
     9  package gset_test
    10  
    11  import (
    12  	"strings"
    13  	"sync"
    14  	"testing"
    15  	"time"
    16  
    17  	"github.com/gogf/gf/v2/container/garray"
    18  	"github.com/gogf/gf/v2/container/gset"
    19  	"github.com/gogf/gf/v2/frame/g"
    20  	"github.com/gogf/gf/v2/internal/json"
    21  	"github.com/gogf/gf/v2/test/gtest"
    22  	"github.com/gogf/gf/v2/util/gconv"
    23  )
    24  
    25  func TestStrSet_Var(t *testing.T) {
    26  	gtest.C(t, func(t *gtest.T) {
    27  		var s gset.StrSet
    28  		s.Add("1", "1", "2")
    29  		s.Add([]string{"3", "4"}...)
    30  		t.Assert(s.Size(), 4)
    31  		t.AssertIN("1", s.Slice())
    32  		t.AssertIN("2", s.Slice())
    33  		t.AssertIN("3", s.Slice())
    34  		t.AssertIN("4", s.Slice())
    35  		t.AssertNI("0", s.Slice())
    36  		t.Assert(s.Contains("4"), true)
    37  		t.Assert(s.Contains("5"), false)
    38  		s.Remove("1")
    39  		t.Assert(s.Size(), 3)
    40  		s.Clear()
    41  		t.Assert(s.Size(), 0)
    42  	})
    43  }
    44  
    45  func TestStrSet_Basic(t *testing.T) {
    46  	gtest.C(t, func(t *gtest.T) {
    47  		s := gset.NewStrSet()
    48  		s.Add("1", "1", "2")
    49  		s.Add([]string{"3", "4"}...)
    50  		t.Assert(s.Size(), 4)
    51  		t.AssertIN("1", s.Slice())
    52  		t.AssertIN("2", s.Slice())
    53  		t.AssertIN("3", s.Slice())
    54  		t.AssertIN("4", s.Slice())
    55  		t.AssertNI("0", s.Slice())
    56  		t.Assert(s.Contains("4"), true)
    57  		t.Assert(s.Contains("5"), false)
    58  		s.Remove("1")
    59  		t.Assert(s.Size(), 3)
    60  		s.Clear()
    61  		t.Assert(s.Size(), 0)
    62  	})
    63  }
    64  
    65  func TestStrSet_ContainsI(t *testing.T) {
    66  	gtest.C(t, func(t *gtest.T) {
    67  		s := gset.NewStrSet()
    68  		s.Add("a", "b", "C")
    69  		t.Assert(s.Contains("A"), false)
    70  		t.Assert(s.Contains("a"), true)
    71  		t.Assert(s.ContainsI("A"), true)
    72  		t.Assert(s.ContainsI("d"), false)
    73  	})
    74  }
    75  
    76  func TestStrSet_Iterator_Deadlock(t *testing.T) {
    77  	gtest.C(t, func(t *gtest.T) {
    78  		set := gset.NewStrSetFrom([]string{"1", "2", "3", "4", "5"}, true)
    79  		set.Iterator(func(k string) bool {
    80  			if gconv.Int(k)%2 == 0 {
    81  				set.Remove(k)
    82  			}
    83  			return true
    84  		})
    85  		t.Assert(set.Contains("1"), true)
    86  		t.Assert(set.Contains("2"), false)
    87  		t.Assert(set.Contains("3"), true)
    88  		t.Assert(set.Contains("4"), false)
    89  		t.Assert(set.Contains("5"), true)
    90  	})
    91  }
    92  
    93  func TestStrSet_Iterator(t *testing.T) {
    94  	gtest.C(t, func(t *gtest.T) {
    95  		s := gset.NewStrSet()
    96  		s.Add("1", "2", "3")
    97  		t.Assert(s.Size(), 3)
    98  
    99  		a1 := garray.New(true)
   100  		a2 := garray.New(true)
   101  		s.Iterator(func(v string) bool {
   102  			a1.Append("1")
   103  			return false
   104  		})
   105  		s.Iterator(func(v string) bool {
   106  			a2.Append("1")
   107  			return true
   108  		})
   109  		t.Assert(a1.Len(), 1)
   110  		t.Assert(a2.Len(), 3)
   111  	})
   112  }
   113  
   114  func TestStrSet_LockFunc(t *testing.T) {
   115  	gtest.C(t, func(t *gtest.T) {
   116  		s := gset.NewStrSet()
   117  		s.Add("1", "2", "3")
   118  		t.Assert(s.Size(), 3)
   119  		s.LockFunc(func(m map[string]struct{}) {
   120  			delete(m, "1")
   121  		})
   122  		t.Assert(s.Size(), 2)
   123  		s.RLockFunc(func(m map[string]struct{}) {
   124  			t.Assert(m, map[string]struct{}{
   125  				"3": {},
   126  				"2": {},
   127  			})
   128  		})
   129  	})
   130  }
   131  
   132  func TestStrSet_Equal(t *testing.T) {
   133  	gtest.C(t, func(t *gtest.T) {
   134  		s1 := gset.NewStrSet()
   135  		s2 := gset.NewStrSet()
   136  		s3 := gset.NewStrSet()
   137  		s4 := gset.NewStrSet()
   138  		s1.Add("1", "2", "3")
   139  		s2.Add("1", "2", "3")
   140  		s3.Add("1", "2", "3", "4")
   141  		s4.Add("4", "5", "6")
   142  		t.Assert(s1.Equal(s2), true)
   143  		t.Assert(s1.Equal(s3), false)
   144  		t.Assert(s1.Equal(s4), false)
   145  		s5 := s1
   146  		t.Assert(s1.Equal(s5), true)
   147  	})
   148  }
   149  
   150  func TestStrSet_IsSubsetOf(t *testing.T) {
   151  	gtest.C(t, func(t *gtest.T) {
   152  		s1 := gset.NewStrSet()
   153  		s2 := gset.NewStrSet()
   154  		s3 := gset.NewStrSet()
   155  		s1.Add("1", "2")
   156  		s2.Add("1", "2", "3")
   157  		s3.Add("1", "2", "3", "4")
   158  		t.Assert(s1.IsSubsetOf(s2), true)
   159  		t.Assert(s2.IsSubsetOf(s3), true)
   160  		t.Assert(s1.IsSubsetOf(s3), true)
   161  		t.Assert(s2.IsSubsetOf(s1), false)
   162  		t.Assert(s3.IsSubsetOf(s2), false)
   163  
   164  		s4 := s1
   165  		t.Assert(s1.IsSubsetOf(s4), true)
   166  	})
   167  }
   168  
   169  func TestStrSet_Union(t *testing.T) {
   170  	gtest.C(t, func(t *gtest.T) {
   171  		s1 := gset.NewStrSet()
   172  		s2 := gset.NewStrSet()
   173  		s1.Add("1", "2")
   174  		s2.Add("3", "4")
   175  		s3 := s1.Union(s2)
   176  		t.Assert(s3.Contains("1"), true)
   177  		t.Assert(s3.Contains("2"), true)
   178  		t.Assert(s3.Contains("3"), true)
   179  		t.Assert(s3.Contains("4"), true)
   180  	})
   181  }
   182  
   183  func TestStrSet_Diff(t *testing.T) {
   184  	gtest.C(t, func(t *gtest.T) {
   185  		s1 := gset.NewStrSet()
   186  		s2 := gset.NewStrSet()
   187  		s1.Add("1", "2", "3")
   188  		s2.Add("3", "4", "5")
   189  		s3 := s1.Diff(s2)
   190  		t.Assert(s3.Contains("1"), true)
   191  		t.Assert(s3.Contains("2"), true)
   192  		t.Assert(s3.Contains("3"), false)
   193  		t.Assert(s3.Contains("4"), false)
   194  
   195  		s4 := s1
   196  		s5 := s1.Diff(s2, s4)
   197  		t.Assert(s5.Contains("1"), true)
   198  		t.Assert(s5.Contains("2"), true)
   199  		t.Assert(s5.Contains("3"), false)
   200  		t.Assert(s5.Contains("4"), false)
   201  	})
   202  }
   203  
   204  func TestStrSet_Intersect(t *testing.T) {
   205  	gtest.C(t, func(t *gtest.T) {
   206  		s1 := gset.NewStrSet()
   207  		s2 := gset.NewStrSet()
   208  		s1.Add("1", "2", "3")
   209  		s2.Add("3", "4", "5")
   210  		s3 := s1.Intersect(s2)
   211  		t.Assert(s3.Contains("1"), false)
   212  		t.Assert(s3.Contains("2"), false)
   213  		t.Assert(s3.Contains("3"), true)
   214  		t.Assert(s3.Contains("4"), false)
   215  	})
   216  }
   217  
   218  func TestStrSet_Complement(t *testing.T) {
   219  	gtest.C(t, func(t *gtest.T) {
   220  		s1 := gset.NewStrSet()
   221  		s2 := gset.NewStrSet()
   222  		s1.Add("1", "2", "3")
   223  		s2.Add("3", "4", "5")
   224  		s3 := s1.Complement(s2)
   225  		t.Assert(s3.Contains("1"), false)
   226  		t.Assert(s3.Contains("2"), false)
   227  		t.Assert(s3.Contains("4"), true)
   228  		t.Assert(s3.Contains("5"), true)
   229  	})
   230  }
   231  
   232  func TestNewIntSetFrom(t *testing.T) {
   233  	gtest.C(t, func(t *gtest.T) {
   234  		s1 := gset.NewIntSetFrom([]int{1, 2, 3, 4})
   235  		s2 := gset.NewIntSetFrom([]int{5, 6, 7, 8})
   236  		t.Assert(s1.Contains(3), true)
   237  		t.Assert(s1.Contains(5), false)
   238  		t.Assert(s2.Contains(3), false)
   239  		t.Assert(s2.Contains(5), true)
   240  	})
   241  }
   242  
   243  func TestStrSet_Merge(t *testing.T) {
   244  	gtest.C(t, func(t *gtest.T) {
   245  		s1 := gset.NewStrSet()
   246  		s2 := gset.NewStrSet()
   247  		s1.Add("1", "2", "3")
   248  		s2.Add("3", "4", "5")
   249  		s3 := s1.Merge(s2)
   250  		t.Assert(s3.Contains("1"), true)
   251  		t.Assert(s3.Contains("6"), false)
   252  		t.Assert(s3.Contains("4"), true)
   253  		t.Assert(s3.Contains("5"), true)
   254  	})
   255  }
   256  
   257  func TestNewStrSetFrom(t *testing.T) {
   258  	gtest.C(t, func(t *gtest.T) {
   259  		s1 := gset.NewStrSetFrom([]string{"a", "b", "c"}, true)
   260  		t.Assert(s1.Contains("b"), true)
   261  		t.Assert(s1.Contains("d"), false)
   262  	})
   263  }
   264  
   265  func TestStrSet_Join(t *testing.T) {
   266  	gtest.C(t, func(t *gtest.T) {
   267  		s1 := gset.NewStrSetFrom([]string{"a", "b", "c"}, true)
   268  		str1 := s1.Join(",")
   269  		t.Assert(strings.Contains(str1, "b"), true)
   270  		t.Assert(strings.Contains(str1, "d"), false)
   271  	})
   272  
   273  	gtest.C(t, func(t *gtest.T) {
   274  		s1 := gset.NewStrSet()
   275  		t.Assert(s1.Join(","), "")
   276  		s1.Add("a", `"b"`, `\c`)
   277  		str1 := s1.Join(",")
   278  		t.Assert(strings.Contains(str1, `"b"`), true)
   279  		t.Assert(strings.Contains(str1, `\c`), true)
   280  		t.Assert(strings.Contains(str1, `a`), true)
   281  	})
   282  }
   283  
   284  func TestStrSet_String(t *testing.T) {
   285  	gtest.C(t, func(t *gtest.T) {
   286  		s1 := gset.NewStrSetFrom([]string{"a", "b", "c"}, true)
   287  		str1 := s1.String()
   288  		t.Assert(strings.Contains(str1, "b"), true)
   289  		t.Assert(strings.Contains(str1, "d"), false)
   290  		s1 = nil
   291  		t.Assert(s1.String(), "")
   292  	})
   293  
   294  	gtest.C(t, func(t *gtest.T) {
   295  		s1 := gset.New(true)
   296  		s1.Add("a", "a2", "b", "c")
   297  		str1 := s1.String()
   298  		t.Assert(strings.Contains(str1, "["), true)
   299  		t.Assert(strings.Contains(str1, "]"), true)
   300  		t.Assert(strings.Contains(str1, "a2"), true)
   301  	})
   302  }
   303  
   304  func TestStrSet_Sum(t *testing.T) {
   305  	gtest.C(t, func(t *gtest.T) {
   306  		s1 := gset.NewStrSetFrom([]string{"a", "b", "c"}, true)
   307  		s2 := gset.NewIntSetFrom([]int{2, 3, 4}, true)
   308  		t.Assert(s1.Sum(), 0)
   309  		t.Assert(s2.Sum(), 9)
   310  	})
   311  }
   312  
   313  func TestStrSet_Size(t *testing.T) {
   314  	gtest.C(t, func(t *gtest.T) {
   315  		s1 := gset.NewStrSetFrom([]string{"a", "b", "c"}, true)
   316  		t.Assert(s1.Size(), 3)
   317  
   318  	})
   319  }
   320  
   321  func TestStrSet_Remove(t *testing.T) {
   322  	gtest.C(t, func(t *gtest.T) {
   323  		s1 := gset.NewStrSetFrom([]string{"a", "b", "c"}, true)
   324  		s1.Remove("b")
   325  		t.Assert(s1.Contains("b"), false)
   326  		t.Assert(s1.Contains("c"), true)
   327  	})
   328  }
   329  
   330  func TestStrSet_Pop(t *testing.T) {
   331  	gtest.C(t, func(t *gtest.T) {
   332  		a := []string{"a", "b", "c", "d"}
   333  		s := gset.NewStrSetFrom(a, true)
   334  		t.Assert(s.Size(), 4)
   335  		t.AssertIN(s.Pop(), a)
   336  		t.Assert(s.Size(), 3)
   337  		t.AssertIN(s.Pop(), a)
   338  		t.Assert(s.Size(), 2)
   339  
   340  		s1 := gset.StrSet{}
   341  		t.Assert(s1.Pop(), "")
   342  	})
   343  }
   344  
   345  func TestStrSet_Pops(t *testing.T) {
   346  	gtest.C(t, func(t *gtest.T) {
   347  		a := []string{"a", "b", "c", "d"}
   348  		s := gset.NewStrSetFrom(a, true)
   349  		array := s.Pops(2)
   350  		t.Assert(len(array), 2)
   351  		t.Assert(s.Size(), 2)
   352  		t.AssertIN(array, a)
   353  		t.Assert(s.Pops(0), nil)
   354  		t.AssertIN(s.Pops(2), a)
   355  		t.Assert(s.Size(), 0)
   356  	})
   357  
   358  	gtest.C(t, func(t *gtest.T) {
   359  		s := gset.NewStrSet(true)
   360  		a := []string{"1", "2", "3", "4"}
   361  		s.Add(a...)
   362  		t.Assert(s.Size(), 4)
   363  		t.Assert(s.Pops(-2), nil)
   364  		t.AssertIN(s.Pops(-1), a)
   365  	})
   366  }
   367  
   368  func TestStrSet_AddIfNotExist(t *testing.T) {
   369  	gtest.C(t, func(t *gtest.T) {
   370  		s := gset.NewStrSet(true)
   371  		s.Add("1")
   372  		t.Assert(s.Contains("1"), true)
   373  		t.Assert(s.AddIfNotExist("1"), false)
   374  		t.Assert(s.AddIfNotExist("2"), true)
   375  		t.Assert(s.Contains("2"), true)
   376  		t.Assert(s.AddIfNotExist("2"), false)
   377  		t.Assert(s.Contains("2"), true)
   378  	})
   379  	gtest.C(t, func(t *gtest.T) {
   380  		s := gset.StrSet{}
   381  		t.Assert(s.AddIfNotExist("1"), true)
   382  	})
   383  }
   384  
   385  func TestStrSet_AddIfNotExistFunc(t *testing.T) {
   386  	gtest.C(t, func(t *gtest.T) {
   387  		s := gset.NewStrSet(true)
   388  		s.Add("1")
   389  		t.Assert(s.Contains("1"), true)
   390  		t.Assert(s.Contains("2"), false)
   391  		t.Assert(s.AddIfNotExistFunc("2", func() bool { return false }), false)
   392  		t.Assert(s.Contains("2"), false)
   393  		t.Assert(s.AddIfNotExistFunc("2", func() bool { return true }), true)
   394  		t.Assert(s.Contains("2"), true)
   395  		t.Assert(s.AddIfNotExistFunc("2", func() bool { return true }), false)
   396  		t.Assert(s.Contains("2"), true)
   397  	})
   398  	gtest.C(t, func(t *gtest.T) {
   399  		s := gset.NewStrSet(true)
   400  		wg := sync.WaitGroup{}
   401  		wg.Add(1)
   402  		go func() {
   403  			defer wg.Done()
   404  			r := s.AddIfNotExistFunc("1", func() bool {
   405  				time.Sleep(100 * time.Millisecond)
   406  				return true
   407  			})
   408  			t.Assert(r, false)
   409  		}()
   410  		s.Add("1")
   411  		wg.Wait()
   412  	})
   413  	gtest.C(t, func(t *gtest.T) {
   414  		s := gset.StrSet{}
   415  		t.Assert(s.AddIfNotExistFunc("1", func() bool { return true }), true)
   416  	})
   417  }
   418  
   419  func TestStrSet_AddIfNotExistFuncLock(t *testing.T) {
   420  	gtest.C(t, func(t *gtest.T) {
   421  		s := gset.NewStrSet(true)
   422  		wg := sync.WaitGroup{}
   423  		wg.Add(2)
   424  		go func() {
   425  			defer wg.Done()
   426  			r := s.AddIfNotExistFuncLock("1", func() bool {
   427  				time.Sleep(500 * time.Millisecond)
   428  				return true
   429  			})
   430  			t.Assert(r, true)
   431  		}()
   432  		time.Sleep(100 * time.Millisecond)
   433  		go func() {
   434  			defer wg.Done()
   435  			r := s.AddIfNotExistFuncLock("1", func() bool {
   436  				return true
   437  			})
   438  			t.Assert(r, false)
   439  		}()
   440  		wg.Wait()
   441  	})
   442  	gtest.C(t, func(t *gtest.T) {
   443  		s := gset.StrSet{}
   444  		t.Assert(s.AddIfNotExistFuncLock("1", func() bool { return true }), true)
   445  	})
   446  }
   447  
   448  func TestStrSet_Json(t *testing.T) {
   449  	gtest.C(t, func(t *gtest.T) {
   450  		s1 := []string{"a", "b", "d", "c"}
   451  		a1 := gset.NewStrSetFrom(s1)
   452  		b1, err1 := json.Marshal(a1)
   453  		b2, err2 := json.Marshal(s1)
   454  		t.Assert(len(b1), len(b2))
   455  		t.Assert(err1, err2)
   456  
   457  		a2 := gset.NewStrSet()
   458  		err2 = json.UnmarshalUseNumber(b2, &a2)
   459  		t.Assert(err2, nil)
   460  		t.Assert(a2.Contains("a"), true)
   461  		t.Assert(a2.Contains("b"), true)
   462  		t.Assert(a2.Contains("c"), true)
   463  		t.Assert(a2.Contains("d"), true)
   464  		t.Assert(a2.Contains("e"), false)
   465  
   466  		var a3 gset.StrSet
   467  		err := json.UnmarshalUseNumber(b2, &a3)
   468  		t.AssertNil(err)
   469  		t.Assert(a3.Contains("a"), true)
   470  		t.Assert(a3.Contains("b"), true)
   471  		t.Assert(a3.Contains("c"), true)
   472  		t.Assert(a3.Contains("d"), true)
   473  		t.Assert(a3.Contains("e"), false)
   474  	})
   475  }
   476  
   477  func TestStrSet_Walk(t *testing.T) {
   478  	gtest.C(t, func(t *gtest.T) {
   479  		var (
   480  			set    gset.StrSet
   481  			names  = g.SliceStr{"user", "user_detail"}
   482  			prefix = "gf_"
   483  		)
   484  		set.Add(names...)
   485  		// Add prefix for given table names.
   486  		set.Walk(func(item string) string {
   487  			return prefix + item
   488  		})
   489  		t.Assert(set.Size(), 2)
   490  		t.Assert(set.Contains("gf_user"), true)
   491  		t.Assert(set.Contains("gf_user_detail"), true)
   492  	})
   493  }
   494  
   495  func TestStrSet_UnmarshalValue(t *testing.T) {
   496  	type V struct {
   497  		Name string
   498  		Set  *gset.StrSet
   499  	}
   500  	// JSON
   501  	gtest.C(t, func(t *gtest.T) {
   502  		var v *V
   503  		err := gconv.Struct(g.Map{
   504  			"name": "john",
   505  			"set":  []byte(`["1","2","3"]`),
   506  		}, &v)
   507  		t.AssertNil(err)
   508  		t.Assert(v.Name, "john")
   509  		t.Assert(v.Set.Size(), 3)
   510  		t.Assert(v.Set.Contains("1"), true)
   511  		t.Assert(v.Set.Contains("2"), true)
   512  		t.Assert(v.Set.Contains("3"), true)
   513  		t.Assert(v.Set.Contains("4"), false)
   514  	})
   515  	// Map
   516  	gtest.C(t, func(t *gtest.T) {
   517  		var v *V
   518  		err := gconv.Struct(g.Map{
   519  			"name": "john",
   520  			"set":  g.SliceStr{"1", "2", "3"},
   521  		}, &v)
   522  		t.AssertNil(err)
   523  		t.Assert(v.Name, "john")
   524  		t.Assert(v.Set.Size(), 3)
   525  		t.Assert(v.Set.Contains("1"), true)
   526  		t.Assert(v.Set.Contains("2"), true)
   527  		t.Assert(v.Set.Contains("3"), true)
   528  		t.Assert(v.Set.Contains("4"), false)
   529  	})
   530  }
   531  
   532  func TestStrSet_DeepCopy(t *testing.T) {
   533  	gtest.C(t, func(t *gtest.T) {
   534  		set := gset.NewStrSet()
   535  		set.Add("1", "2", "3")
   536  
   537  		copySet := set.DeepCopy().(*gset.StrSet)
   538  		copySet.Add("4")
   539  		t.AssertNE(set.Size(), copySet.Size())
   540  		t.AssertNE(set.String(), copySet.String())
   541  
   542  		set = nil
   543  		t.AssertNil(set.DeepCopy())
   544  	})
   545  }