1 | """ |
---|
2 | Tests for `bx.bitset`. |
---|
3 | """ |
---|
4 | |
---|
5 | import bx.bitset |
---|
6 | import unittest |
---|
7 | |
---|
8 | class AbstractTests( object ): |
---|
9 | |
---|
10 | def assert_bits( self, bits, list ): |
---|
11 | assert bits.size == len( list ), "Bitset size and verification list size do not match" |
---|
12 | for i in range( bits.size ): |
---|
13 | self.assertEquals( bits[i], list[i] ) |
---|
14 | |
---|
15 | def test_overflow_create( self ): |
---|
16 | self.assertRaises( ValueError, self.new_bits, 4000000000 ) |
---|
17 | |
---|
18 | def test_overflow_access( self ): |
---|
19 | bits = self.new_bits( 100 ) |
---|
20 | self.assertRaises( IndexError, bits.set, -5 ) |
---|
21 | self.assertRaises( IndexError, bits.set, 110 ) |
---|
22 | |
---|
23 | def test_access( self ): |
---|
24 | # Create and assert empty |
---|
25 | bits = self.new_bits( 100 ) |
---|
26 | l = [ 0 ] * 100 |
---|
27 | self.assert_bits( bits, l ) |
---|
28 | # Set some positions |
---|
29 | for pos in ( 11, 14, 70, 16 ): |
---|
30 | bits.set( pos ) |
---|
31 | l[ pos ] = 1 |
---|
32 | # Clear some positions |
---|
33 | for pos in ( 14, 80, 16 ): |
---|
34 | bits.clear( pos ) |
---|
35 | l[ pos ] = 0 |
---|
36 | self.assert_bits( bits, l ) |
---|
37 | |
---|
38 | def test_range_access( self ): |
---|
39 | # Create and assert empty |
---|
40 | bits = self.new_bits( 100 ) |
---|
41 | l = [ 0 ] * 100 |
---|
42 | self.assert_bits( bits, l ) |
---|
43 | # Set some positions |
---|
44 | for b, e in ( ( 11, 14 ), (20,75), (90,99) ): |
---|
45 | bits.set_range( b, e-b) |
---|
46 | for pos in range( b, e ): l[ pos ] = 1 |
---|
47 | self.assert_bits( bits, l ) |
---|
48 | |
---|
49 | def test_count( self ): |
---|
50 | # Create and assert empty |
---|
51 | bits = self.new_bits( 100 ) |
---|
52 | # Set some positions |
---|
53 | for b, e in ( ( 11, 14 ), (20,75), (90,100) ): |
---|
54 | bits.set_range( b, e-b) |
---|
55 | self.assertEquals( bits.count_range( 0, 0 ), 0 ) |
---|
56 | self.assertEquals( bits.count_range( 0, 20 ), 3 ) |
---|
57 | self.assertEquals( bits.count_range( 25, 25 ), 25 ) |
---|
58 | self.assertEquals( bits.count_range( 80, 20 ), 10 ) |
---|
59 | self.assertEquals( bits.count_range( 0, 100 ), 68 ) |
---|
60 | |
---|
61 | def test_find( self ): |
---|
62 | # Create and assert empty |
---|
63 | bits = self.new_bits( 100 ) |
---|
64 | # Set some positions |
---|
65 | for b, e in ( ( 11, 14 ), (20,75), (90,100) ): |
---|
66 | bits.set_range( b, e-b) |
---|
67 | # Next set |
---|
68 | self.assertEquals( bits.next_set( 0 ), 11 ) |
---|
69 | self.assertEquals( bits.next_set( 13 ), 13 ) |
---|
70 | self.assertEquals( bits.next_set( 15 ), 20 ) |
---|
71 | # Next clear |
---|
72 | self.assertEquals( bits.next_clear( 0 ), 0 ) |
---|
73 | self.assertEquals( bits.next_clear( 11 ), 14 ) |
---|
74 | self.assertEquals( bits.next_clear( 20 ), 75 ) |
---|
75 | self.assertEquals( bits.next_clear( 92 ), 100 ) |
---|
76 | |
---|
77 | def test_and( self ): |
---|
78 | bits1 = self.new_bits( 100 ) |
---|
79 | bits2 = self.new_bits( 100 ) |
---|
80 | bits1.set_range( 20, 40 ) |
---|
81 | bits2.set_range( 50, 25 ) |
---|
82 | bits1.iand( bits2 ) |
---|
83 | l = [0]*100 |
---|
84 | for i in range( 50, 60 ): l[i] = 1 |
---|
85 | self.assert_bits( bits1, l ) |
---|
86 | |
---|
87 | def test_or( self ): |
---|
88 | bits1 = self.new_bits( 100 ) |
---|
89 | bits2 = self.new_bits( 100 ) |
---|
90 | bits1.set_range( 20, 40 ) |
---|
91 | bits2.set_range( 50, 25 ) |
---|
92 | bits1.ior( bits2 ) |
---|
93 | l = [0]*100 |
---|
94 | for i in range( 20, 75 ): l[i] = 1 |
---|
95 | self.assert_bits( bits1, l ) |
---|
96 | |
---|
97 | def test_not( self ): |
---|
98 | bits = self.new_bits( 100 ) |
---|
99 | bits.set_range( 20, 40 ) |
---|
100 | bits.invert() |
---|
101 | l = [1]*100 |
---|
102 | for i in range( 20, 60 ): l[i] = 0 |
---|
103 | self.assert_bits( bits, l ) |
---|
104 | |
---|
105 | class BitSetTests( AbstractTests, unittest.TestCase ): |
---|
106 | def new_bits( self, size ): |
---|
107 | return bx.bitset.BitSet( size ) |
---|
108 | |
---|
109 | class BinnedBitSetTests( AbstractTests, unittest.TestCase ): |
---|
110 | def new_bits( self, size ): |
---|
111 | granularity = size % 11 |
---|
112 | return bx.bitset.BinnedBitSet( size, granularity ) |
---|