Search Apps Documentation Source Content File Folder Download Copy Actions Download

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}