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 }