bitset_test.gno
9.86 Kb · 572 lines
1package bitset_test
2
3import (
4 "testing"
5
6 "gno.land/p/jeronimoalbi/bitset"
7)
8
9func TestBitSetSet(t *testing.T) {
10 cases := []struct {
11 name string
12 bits []uint64
13 want string
14 }{
15 {
16 name: "single bit 0",
17 bits: []uint64{0},
18 want: "1",
19 },
20 {
21 name: "single bit 5",
22 bits: []uint64{5},
23 want: "100000",
24 },
25 {
26 name: "multiple bits in same word",
27 bits: []uint64{0, 3, 7},
28 want: "10001001",
29 },
30 {
31 name: "bit at word boundary",
32 bits: []uint64{63},
33 want: "1000000000000000000000000000000000000000000000000000000000000000",
34 },
35 {
36 name: "bit across word boundary",
37 bits: []uint64{63, 64},
38 want: "11000000000000000000000000000000000000000000000000000000000000000",
39 },
40 {
41 name: "set same bit twice",
42 bits: []uint64{2, 2},
43 want: "100",
44 },
45 }
46
47 for _, tc := range cases {
48 t.Run(tc.name, func(t *testing.T) {
49 // Arrange
50 var b bitset.BitSet
51
52 // Act
53 for _, v := range tc.bits {
54 b.Set(v)
55 }
56
57 // Assert
58 if got := b.String(); got != tc.want {
59 t.Errorf("expected %s, got %s", tc.want, got)
60 }
61 })
62 }
63}
64
65func TestBitSetIsSet(t *testing.T) {
66 var (
67 b bitset.BitSet
68 values = []uint64{0, 5, 63, 64, 200}
69 )
70
71 for _, v := range values {
72 b.Set(v)
73 }
74
75 for _, v := range values {
76 if !b.IsSet(v) {
77 t.Errorf("bit %d should be set", v)
78 }
79 }
80
81 if b.IsSet(999) {
82 t.Error("bit 999 should not be set")
83 }
84}
85
86func TestBitSetClear(t *testing.T) {
87 var b bitset.BitSet
88 b.Set(10)
89 b.Clear(10)
90
91 if b.IsSet(10) {
92 t.Error("bit 10 should be cleared")
93 }
94
95 // Clearing a bit beyond the slice should not panic
96 b.Clear(999)
97}
98
99func TestBitSetClearAll(t *testing.T) {
100 // Arrange
101 var b bitset.BitSet
102 b.Set(1)
103 b.Set(64)
104 b.Set(200)
105
106 // Act
107 b.ClearAll()
108
109 // Assert
110 if b.Len() != 0 {
111 t.Errorf("expected len 0 after ClearAll, got %d", b.Len())
112 }
113
114 if b.IsSet(1) || b.IsSet(64) || b.IsSet(200) {
115 t.Error("no bits should be set after ClearAll")
116 }
117}
118
119func TestBitSetCompact(t *testing.T) {
120 cases := []struct {
121 name string
122 setup func() bitset.BitSet
123 wantSize int
124 }{
125 {
126 name: "clear all",
127 setup: func() bitset.BitSet {
128 var b bitset.BitSet
129 b.Set(1)
130 b.Set(64)
131 b.Set(200)
132 b.ClearAll()
133 return b
134 },
135 wantSize: 0,
136 },
137 {
138 name: "trailing zeros",
139 setup: func() bitset.BitSet {
140 var a, other bitset.BitSet
141 a.Set(1)
142 a.Set(128)
143 other.Set(1)
144 a.And(other)
145 return a
146 },
147 wantSize: 64,
148 },
149 {
150 name: "no trailing zeros",
151 setup: func() bitset.BitSet {
152 var b bitset.BitSet
153 b.Set(1)
154 b.Set(64)
155 return b
156 },
157 wantSize: 128,
158 },
159 }
160
161 for _, tc := range cases {
162 t.Run(tc.name, func(t *testing.T) {
163 // Arrange
164 b := tc.setup()
165
166 // Act
167 b.Compact()
168
169 // Assert
170 if got := b.Size(); got != tc.wantSize {
171 t.Errorf("expected size %d after Compact, got %d", tc.wantSize, got)
172 }
173 })
174 }
175}
176
177func TestBitSetSize(t *testing.T) {
178 cases := []struct {
179 name string
180 setup func() bitset.BitSet
181 want int
182 }{
183 {
184 name: "empty",
185 setup: func() bitset.BitSet { return bitset.BitSet{} },
186 want: 0,
187 },
188 {
189 name: "new 128",
190 setup: func() bitset.BitSet { return bitset.New(128) },
191 want: 128,
192 },
193 {
194 name: "set bit 0",
195 setup: func() bitset.BitSet {
196 var b bitset.BitSet
197 b.Set(0)
198 return b
199 },
200 want: 64,
201 },
202 {
203 name: "set bit 200",
204 setup: func() bitset.BitSet {
205 var b bitset.BitSet
206 b.Set(200)
207 return b
208 },
209 want: 256,
210 },
211 }
212
213 for _, tc := range cases {
214 t.Run(tc.name, func(t *testing.T) {
215 // Arrange
216 b := tc.setup()
217
218 // Act
219 got := b.Size()
220
221 // Assert
222 if got != tc.want {
223 t.Errorf("expected size %d, got %d", tc.want, got)
224 }
225 })
226 }
227}
228
229func TestBitSetLen(t *testing.T) {
230 var b bitset.BitSet
231 if b.Len() != 0 {
232 t.Error("empty bitset should have len 0")
233 }
234
235 b.Set(0)
236 b.Set(1)
237 b.Set(100)
238 if b.Len() != 3 {
239 t.Errorf("expected len 3, got %d", b.Len())
240 }
241}
242
243func TestBitSetNew(t *testing.T) {
244 b := bitset.New(0)
245 if b.Size() != 0 {
246 t.Errorf("expected size 0, got %d", b.Size())
247 }
248
249 b = bitset.New(128)
250 if b.Size() != 128 {
251 t.Errorf("expected size 128, got %d", b.Size())
252 }
253}
254
255func TestBitSetOr(t *testing.T) {
256 cases := []struct {
257 name string
258 current []uint64
259 other []uint64
260 want string
261 }{
262 {
263 name: "empty sets",
264 current: []uint64{},
265 other: []uint64{},
266 want: "",
267 },
268 {
269 name: "equal sets",
270 current: []uint64{1, 4, 8},
271 other: []uint64{1, 4, 8},
272 want: "100010010",
273 },
274 {
275 name: "different sets",
276 current: []uint64{1, 4, 8},
277 other: []uint64{2, 3, 5},
278 want: "100111110",
279 },
280 {
281 name: "current smaller than other",
282 current: []uint64{1, 4},
283 other: []uint64{2, 3, 5, 8},
284 want: "100111110",
285 },
286 {
287 name: "current bigger than other",
288 current: []uint64{2, 3, 5, 8},
289 other: []uint64{1, 4},
290 want: "100111110",
291 },
292 }
293
294 for _, tc := range cases {
295 t.Run(tc.name, func(t *testing.T) {
296 // Arrange
297 var a, b bitset.BitSet
298
299 for _, v := range tc.current {
300 a.Set(v)
301 }
302
303 for _, v := range tc.other {
304 b.Set(v)
305 }
306
307 // Act
308 a.Or(b)
309
310 // Assert
311 if got := a.String(); got != tc.want {
312 t.Errorf("expected %s, got %s", tc.want, got)
313 }
314 })
315 }
316}
317
318func TestBitSetAnd(t *testing.T) {
319 cases := []struct {
320 name string
321 current []uint64
322 other []uint64
323 want string
324 }{
325 {
326 name: "empty sets",
327 current: []uint64{},
328 other: []uint64{},
329 want: "",
330 },
331 {
332 name: "equal sets",
333 current: []uint64{1, 4, 8},
334 other: []uint64{1, 4, 8},
335 want: "100010010",
336 },
337 {
338 name: "different sets",
339 current: []uint64{1, 4, 8},
340 other: []uint64{2, 3, 5},
341 want: "0",
342 },
343 {
344 name: "current smaller than other",
345 current: []uint64{1, 4},
346 other: []uint64{1, 4, 5, 8},
347 want: "10010",
348 },
349 {
350 name: "current bigger than other",
351 current: []uint64{0, 3, 5, 8},
352 other: []uint64{0, 3},
353 want: "1001",
354 },
355 }
356
357 for _, tc := range cases {
358 t.Run(tc.name, func(t *testing.T) {
359 // Arrange
360 var a, b bitset.BitSet
361
362 for _, v := range tc.current {
363 a.Set(v)
364 }
365
366 for _, v := range tc.other {
367 b.Set(v)
368 }
369
370 // Act
371 a.And(b)
372
373 // Assert
374 if got := a.String(); got != tc.want {
375 t.Errorf("expected %s, got %s", tc.want, got)
376 }
377 })
378 }
379}
380
381func TestBitSetXor(t *testing.T) {
382 cases := []struct {
383 name string
384 current []uint64
385 other []uint64
386 want string
387 }{
388 {
389 name: "empty sets",
390 current: []uint64{},
391 other: []uint64{},
392 want: "",
393 },
394 {
395 name: "equal sets",
396 current: []uint64{1, 4, 8},
397 other: []uint64{1, 4, 8},
398 want: "0",
399 },
400 {
401 name: "different sets",
402 current: []uint64{1, 3, 8},
403 other: []uint64{2, 3, 5},
404 want: "100100110",
405 },
406 {
407 name: "current smaller than other",
408 current: []uint64{1, 3, 4},
409 other: []uint64{2, 3, 5, 8},
410 want: "100110110",
411 },
412 {
413 name: "current bigger than other",
414 current: []uint64{2, 3, 5, 8},
415 other: []uint64{1, 3},
416 want: "100100110",
417 },
418 }
419
420 for _, tc := range cases {
421 t.Run(tc.name, func(t *testing.T) {
422 // Arrange
423 var a, b bitset.BitSet
424
425 for _, v := range tc.current {
426 a.Set(v)
427 }
428
429 for _, v := range tc.other {
430 b.Set(v)
431 }
432
433 // Act
434 a.Xor(b)
435
436 // Assert
437 if got := a.String(); got != tc.want {
438 t.Errorf("expected %s, got %s", tc.want, got)
439 }
440 })
441 }
442}
443
444func TestBitSetEqual(t *testing.T) {
445 cases := []struct {
446 name string
447 setup func() (a, b bitset.BitSet)
448 want bool
449 }{
450 {
451 name: "empty",
452 setup: func() (a, b bitset.BitSet) { return a, b },
453 want: true,
454 },
455 {
456 name: "equal",
457 setup: func() (a, b bitset.BitSet) {
458 a.Set(1)
459 a.Set(100)
460 b.Set(1)
461 b.Set(100)
462 return a, b
463 },
464 want: true,
465 },
466 {
467 name: "equal with different sizes",
468 setup: func() (a, b bitset.BitSet) {
469 b = bitset.New(256)
470 b.Set(5)
471 a.Set(5)
472 return a, b
473 },
474 want: true,
475 },
476 {
477 name: "not equal",
478 setup: func() (a, b bitset.BitSet) {
479 a.Set(1)
480 b.Set(1)
481 b.Set(50)
482 return a, b
483 },
484 want: false,
485 },
486 }
487
488 for _, tc := range cases {
489 t.Run(tc.name, func(t *testing.T) {
490 // Arrange
491 a, b := tc.setup()
492
493 // Act
494 got := a.Equal(b)
495
496 // Assert
497 if tc.want == got {
498 return
499 }
500
501 if tc.want {
502 t.Error("bitsets should be equal")
503 } else {
504 t.Error("bitsets should not be equal")
505 }
506 })
507 }
508}
509
510func TestBitSetString(t *testing.T) {
511 cases := []struct {
512 name string
513 values []uint64
514 want string
515 }{
516 {"empty", nil, ""},
517 {"single bit", []uint64{0}, "1"},
518 {"max word value", []uint64{63}, "1000000000000000000000000000000000000000000000000000000000000000"},
519 {"multiple sequential bits", []uint64{0, 1, 2, 3}, "1111"},
520 {"multiple non sequential bits", []uint64{0, 2, 4}, "10101"},
521 }
522
523 for _, tc := range cases {
524 t.Run(tc.name, func(t *testing.T) {
525 // Arrange
526 var b bitset.BitSet
527 for _, v := range tc.values {
528 b.Set(v)
529 }
530
531 // Act
532 got := b.String()
533
534 // Assert
535 if got != tc.want {
536 t.Errorf("expected %q, got %q", tc.want, got)
537 }
538 })
539 }
540}
541
542func TestBitSetPaddedString(t *testing.T) {
543 cases := []struct {
544 name string
545 values []uint64
546 want string
547 }{
548 {"empty", nil, ""},
549 {"single bit", []uint64{0}, "0000000000000000000000000000000000000000000000000000000000000001"},
550 {"max word value", []uint64{63}, "1000000000000000000000000000000000000000000000000000000000000000"},
551 {"multiple sequential bits", []uint64{0, 1, 2, 3}, "0000000000000000000000000000000000000000000000000000000000001111"},
552 {"multiple non sequential bits", []uint64{0, 2, 4}, "0000000000000000000000000000000000000000000000000000000000010101"},
553 }
554
555 for _, tc := range cases {
556 t.Run(tc.name, func(t *testing.T) {
557 // Arrange
558 var b bitset.BitSet
559 for _, v := range tc.values {
560 b.Set(v)
561 }
562
563 // Act
564 got := b.PaddedString()
565
566 // Assert
567 if got != tc.want {
568 t.Errorf("expected %q, got %q", tc.want, got)
569 }
570 })
571 }
572}