| 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 ) |
|---|