go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/common/data/stringset/stringset_test.go (about)

     1  // Copyright 2015 The LUCI Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package stringset
    16  
    17  import (
    18  	"reflect"
    19  	"sort"
    20  	"testing"
    21  
    22  	. "github.com/smartystreets/goconvey/convey"
    23  )
    24  
    25  func TestSet(t *testing.T) {
    26  	t.Parallel()
    27  
    28  	Convey("Test Thread Unsafe Set", t, func() {
    29  		s := New(10)
    30  
    31  		Convey("Can add elements", func() {
    32  			So(s.Add("hello"), ShouldBeTrue)
    33  			So(s.Add("hello"), ShouldBeFalse)
    34  			So(s.Add("world"), ShouldBeTrue)
    35  			So(s.Len(), ShouldEqual, 2)
    36  			sl := s.ToSlice()
    37  			sort.Strings(sl)
    38  			So(sl, ShouldResemble, []string{"hello", "world"})
    39  
    40  			Convey("Can remove stuff", func() {
    41  				So(s.Del("foo"), ShouldBeFalse)
    42  				So(s.Del("world"), ShouldBeTrue)
    43  				So(s.Del("world"), ShouldBeFalse)
    44  				So(s.ToSlice(), ShouldResemble, []string{"hello"})
    45  			})
    46  
    47  			Convey("Can peek them", func() {
    48  				str, found := s.Peek()
    49  				So(found, ShouldBeTrue)
    50  				So(sl, ShouldContain, str)
    51  
    52  				_, found = New(10).Peek()
    53  				So(found, ShouldBeFalse)
    54  			})
    55  
    56  			Convey("Can pop them", func() {
    57  				var newList []string
    58  				str, found := s.Pop()
    59  				So(found, ShouldBeTrue)
    60  				newList = append(newList, str)
    61  
    62  				str, found = s.Pop()
    63  				So(found, ShouldBeTrue)
    64  				newList = append(newList, str)
    65  
    66  				_, found = s.Pop()
    67  				So(found, ShouldBeFalse)
    68  				So(s.Len(), ShouldEqual, 0)
    69  
    70  				sort.Strings(newList)
    71  
    72  				So(newList, ShouldResemble, sl)
    73  			})
    74  
    75  			Convey("Can iterate", func() {
    76  				s.Iter(func(val string) bool {
    77  					So(sl, ShouldContain, val)
    78  					return true
    79  				})
    80  			})
    81  
    82  			Convey("Can stop iteration early", func() {
    83  				foundOne := false
    84  				s.Iter(func(val string) bool {
    85  					So(foundOne, ShouldBeFalse)
    86  					foundOne = true
    87  					So(sl, ShouldContain, val)
    88  					return false
    89  				})
    90  			})
    91  
    92  			Convey("Can dup them", func() {
    93  				dup := s.Dup()
    94  				So(dup, ShouldResemble, s)
    95  				So(reflect.ValueOf(dup).Pointer(), ShouldNotEqual, reflect.ValueOf(s).Pointer())
    96  				dup.Add("panwaffles") // the best of both!
    97  				So(dup, ShouldNotResemble, s)
    98  			})
    99  		})
   100  	})
   101  
   102  	Convey("Can create with pre-set values", t, func() {
   103  		s := NewFromSlice("hi", "there", "person", "hi")
   104  		So(s.Len(), ShouldEqual, 3)
   105  		So(s.Has("hi"), ShouldBeTrue)
   106  		So(s.HasAll("hi", "person"), ShouldBeTrue)
   107  		So(s.HasAll("hi", "bye"), ShouldBeFalse)
   108  		sl := s.ToSlice()
   109  		sort.Strings(sl)
   110  		So(sl, ShouldResemble, []string{"hi", "person", "there"})
   111  	})
   112  
   113  	Convey("Can do set operations", t, func() {
   114  		s := NewFromSlice("a", "b", "c", "d", "e", "f", "z")
   115  
   116  		Convey("Union", func() {
   117  			sl := s.Union(NewFromSlice("b", "k", "g")).ToSlice()
   118  			sort.Strings(sl)
   119  			So(sl, ShouldResemble, []string{
   120  				"a", "b", "c", "d", "e", "f", "g", "k", "z"})
   121  		})
   122  
   123  		Convey("Intersect", func() {
   124  			Convey("empty", func() {
   125  				sl := s.Intersect(New(0)).ToSlice()
   126  				sort.Strings(sl)
   127  				So(sl, ShouldBeEmpty)
   128  			})
   129  
   130  			Convey("no overlap", func() {
   131  				sl := s.Intersect(NewFromSlice("beef")).ToSlice()
   132  				sort.Strings(sl)
   133  				So(sl, ShouldBeEmpty)
   134  			})
   135  
   136  			Convey("some overlap", func() {
   137  				sl := s.Intersect(NewFromSlice("c", "k", "z", "g")).ToSlice()
   138  				sort.Strings(sl)
   139  				So(sl, ShouldResemble, []string{"c", "z"})
   140  			})
   141  
   142  			Convey("total overlap", func() {
   143  				sl := s.Intersect(NewFromSlice("a", "b", "c", "d", "e", "f", "z")).ToSlice()
   144  				sort.Strings(sl)
   145  				So(sl, ShouldResemble, []string{"a", "b", "c", "d", "e", "f", "z"})
   146  			})
   147  		})
   148  
   149  		Convey("Difference", func() {
   150  			Convey("empty", func() {
   151  				sl := s.Difference(New(0)).ToSlice()
   152  				sort.Strings(sl)
   153  				So(sl, ShouldResemble, []string{"a", "b", "c", "d", "e", "f", "z"})
   154  			})
   155  
   156  			Convey("no overlap", func() {
   157  				sl := s.Difference(NewFromSlice("beef")).ToSlice()
   158  				sort.Strings(sl)
   159  				So(sl, ShouldResemble, []string{"a", "b", "c", "d", "e", "f", "z"})
   160  			})
   161  
   162  			Convey("some overlap", func() {
   163  				sl := s.Difference(NewFromSlice("c", "k", "z", "g")).ToSlice()
   164  				sort.Strings(sl)
   165  				So(sl, ShouldResemble, []string{"a", "b", "d", "e", "f"})
   166  			})
   167  
   168  			Convey("total overlap", func() {
   169  				sl := s.Difference(NewFromSlice("a", "b", "c", "d", "e", "f", "z")).ToSlice()
   170  				sort.Strings(sl)
   171  				So(sl, ShouldBeEmpty)
   172  			})
   173  		})
   174  
   175  		Convey("Contains", func() {
   176  			s1 := NewFromSlice("a", "b", "c")
   177  			s2 := NewFromSlice("a", "b")
   178  			So(s1.Contains(s2), ShouldBeTrue)
   179  			So(s2.Contains(s1), ShouldBeFalse)
   180  		})
   181  	})
   182  }