github.com/MetalBlockchain/metalgo@v1.11.9/utils/bag/bag_test.go (about) 1 // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 package bag 5 6 import ( 7 "testing" 8 9 "github.com/stretchr/testify/require" 10 ) 11 12 func TestBagOf(t *testing.T) { 13 tests := []struct { 14 name string 15 elements []int 16 expectedCounts map[int]int 17 }{ 18 { 19 name: "nil", 20 elements: nil, 21 expectedCounts: map[int]int{}, 22 }, 23 { 24 name: "empty", 25 elements: []int{}, 26 expectedCounts: map[int]int{}, 27 }, 28 { 29 name: "unique elements", 30 elements: []int{1, 2, 3}, 31 expectedCounts: map[int]int{ 32 1: 1, 33 2: 1, 34 3: 1, 35 }, 36 }, 37 { 38 name: "duplicate elements", 39 elements: []int{1, 2, 3, 1, 2, 3}, 40 expectedCounts: map[int]int{ 41 1: 2, 42 2: 2, 43 3: 2, 44 }, 45 }, 46 } 47 for _, tt := range tests { 48 t.Run(tt.name, func(t *testing.T) { 49 require := require.New(t) 50 51 b := Of(tt.elements...) 52 53 require.Equal(len(tt.elements), b.Len()) 54 for entry, count := range tt.expectedCounts { 55 require.Equal(count, b.Count(entry)) 56 } 57 }) 58 } 59 } 60 61 func TestBagAdd(t *testing.T) { 62 require := require.New(t) 63 64 elt0 := 0 65 elt1 := 1 66 67 bag := Bag[int]{} 68 69 require.Zero(bag.Count(elt0)) 70 require.Zero(bag.Count(elt1)) 71 require.Zero(bag.Len()) 72 require.Empty(bag.List()) 73 mode, freq := bag.Mode() 74 require.Equal(elt0, mode) 75 require.Zero(freq) 76 require.Empty(bag.Threshold()) 77 78 bag.Add(elt0) 79 80 require.Equal(1, bag.Count(elt0)) 81 require.Zero(bag.Count(elt1)) 82 require.Equal(1, bag.Len()) 83 require.Len(bag.List(), 1) 84 mode, freq = bag.Mode() 85 require.Equal(elt0, mode) 86 require.Equal(1, freq) 87 require.Len(bag.Threshold(), 1) 88 89 bag.Add(elt0) 90 91 require.Equal(2, bag.Count(elt0)) 92 require.Zero(bag.Count(elt1)) 93 require.Equal(2, bag.Len()) 94 require.Len(bag.List(), 1) 95 mode, freq = bag.Mode() 96 require.Equal(elt0, mode) 97 require.Equal(2, freq) 98 require.Len(bag.Threshold(), 1) 99 100 bag.AddCount(elt1, 3) 101 102 require.Equal(2, bag.Count(elt0)) 103 require.Equal(3, bag.Count(elt1)) 104 require.Equal(5, bag.Len()) 105 require.Len(bag.List(), 2) 106 mode, freq = bag.Mode() 107 require.Equal(elt1, mode) 108 require.Equal(3, freq) 109 require.Len(bag.Threshold(), 2) 110 } 111 112 func TestBagSetThreshold(t *testing.T) { 113 require := require.New(t) 114 115 elt0 := 0 116 elt1 := 1 117 118 bag := Bag[int]{} 119 120 bag.AddCount(elt0, 2) 121 bag.AddCount(elt1, 3) 122 123 bag.SetThreshold(0) 124 125 require.Equal(2, bag.Count(elt0)) 126 require.Equal(3, bag.Count(elt1)) 127 require.Equal(5, bag.Len()) 128 require.Len(bag.List(), 2) 129 mode, freq := bag.Mode() 130 require.Equal(elt1, mode) 131 require.Equal(3, freq) 132 require.Len(bag.Threshold(), 2) 133 134 bag.SetThreshold(3) 135 136 require.Equal(2, bag.Count(elt0)) 137 require.Equal(3, bag.Count(elt1)) 138 require.Equal(5, bag.Len()) 139 require.Len(bag.List(), 2) 140 mode, freq = bag.Mode() 141 require.Equal(elt1, mode) 142 require.Equal(3, freq) 143 require.Len(bag.Threshold(), 1) 144 } 145 146 func TestBagFilter(t *testing.T) { 147 require := require.New(t) 148 149 elt0 := 0 150 elt1 := 1 151 elt2 := 2 152 153 bag := Bag[int]{} 154 155 bag.AddCount(elt0, 1) 156 bag.AddCount(elt1, 3) 157 bag.AddCount(elt2, 5) 158 159 filterFunc := func(elt int) bool { 160 return elt%2 == 0 161 } 162 even := bag.Filter(filterFunc) 163 164 require.Equal(1, even.Count(elt0)) 165 require.Zero(even.Count(elt1)) 166 require.Equal(5, even.Count(elt2)) 167 } 168 169 func TestBagSplit(t *testing.T) { 170 require := require.New(t) 171 172 elt0 := 0 173 elt1 := 1 174 elt2 := 2 175 176 bag := Bag[int]{} 177 178 bag.AddCount(elt0, 1) 179 bag.AddCount(elt1, 3) 180 bag.AddCount(elt2, 5) 181 182 bags := bag.Split(func(i int) bool { 183 return i%2 != 0 184 }) 185 186 evens := bags[0] 187 odds := bags[1] 188 189 require.Equal(1, evens.Count(elt0)) 190 require.Zero(evens.Count(elt1)) 191 require.Equal(5, evens.Count(elt2)) 192 require.Zero(odds.Count(elt0)) 193 require.Equal(3, odds.Count(elt1)) 194 require.Zero(odds.Count(elt2)) 195 } 196 197 func TestBagString(t *testing.T) { 198 elt0 := 123 199 200 bag := Bag[int]{} 201 202 bag.AddCount(elt0, 1337) 203 204 expected := `Bag[int]: (Size = 1337) 205 123: 1337` 206 207 require.Equal(t, expected, bag.String()) 208 } 209 210 func TestBagRemove(t *testing.T) { 211 require := require.New(t) 212 213 elt0 := 0 214 elt1 := 1 215 elt2 := 2 216 217 bag := Bag[int]{} 218 219 bag.Remove(elt0) 220 require.Zero(bag.Len()) 221 222 bag.AddCount(elt0, 3) 223 bag.AddCount(elt1, 2) 224 bag.Add(elt2) 225 require.Equal(6, bag.Len()) 226 require.Len(bag.counts, 3) 227 mode, freq := bag.Mode() 228 require.Equal(elt0, mode) 229 require.Equal(3, freq) 230 231 bag.Remove(elt0) 232 233 require.Zero(bag.Count(elt0)) 234 require.Equal(2, bag.Count(elt1)) 235 require.Equal(1, bag.Count(elt2)) 236 require.Equal(3, bag.Len()) 237 require.Len(bag.counts, 2) 238 mode, freq = bag.Mode() 239 require.Equal(elt1, mode) 240 require.Equal(2, freq) 241 242 bag.Remove(elt1) 243 require.Zero(bag.Count(elt0)) 244 require.Zero(bag.Count(elt1)) 245 require.Equal(1, bag.Count(elt2)) 246 require.Equal(1, bag.Len()) 247 require.Len(bag.counts, 1) 248 mode, freq = bag.Mode() 249 require.Equal(elt2, mode) 250 require.Equal(1, freq) 251 } 252 253 func TestBagEquals(t *testing.T) { 254 require := require.New(t) 255 256 bag1 := Bag[int]{} 257 bag2 := Bag[int]{} 258 259 // Case: both empty 260 require.True(bag1.Equals(bag2)) 261 require.True(bag2.Equals(bag1)) 262 263 // Case: one empty, one not 264 bag1.Add(0) 265 require.False(bag1.Equals(bag2)) 266 require.False(bag2.Equals(bag1)) 267 268 bag2.Add(0) 269 require.True(bag1.Equals(bag2)) 270 require.True(bag2.Equals(bag1)) 271 272 // Case: both non-empty, different elements 273 bag1.Add(1) 274 require.False(bag1.Equals(bag2)) 275 require.False(bag2.Equals(bag1)) 276 277 bag2.Add(1) 278 require.True(bag1.Equals(bag2)) 279 require.True(bag2.Equals(bag1)) 280 281 // Case: both non-empty, different counts 282 bag1.Add(0) 283 require.False(bag1.Equals(bag2)) 284 require.False(bag2.Equals(bag1)) 285 286 bag2.Add(0) 287 require.True(bag1.Equals(bag2)) 288 require.True(bag2.Equals(bag1)) 289 }