1. James Taylor
  2. bx-python

Commits

James Taylor  committed 33991fc

Added tests for Bitset and BinnedBitset covering set/clear, setrange, countrange, next_set/next_clear

Added a hacky test runner that adds the build directories to the pythonpath. Long term this should read possible tests from a file, and allow a command line for just running some tests.

  • Participants
  • Parent commits e32e9e5
  • Branches default

Comments (0)

Files changed (6)

File bx/bitset.pyx

View file
+cdef extern from "common.h":
+    ctypedef int boolean
+
 cdef extern from "bits.h":
 
     ctypedef unsigned char Bits
     void binBitsFree( BinBits * bb )
     int binBitsReadOne( BinBits * bb, int pos )
     void binBitsSetOne( BinBits * bb, int pos )
+    void binBitsClearOne( BinBits * bb, int pos )
     void binBitsSetRange( BinBits *bb, int start, int size )
     int binBitsCountRange( BinBits *bb, int start, int size )
     int binBitsFindSet( BinBits *bb, int start )
     def set_range( self, start, count ):   
         bitSetRange( self.bits, start, count )
 
-    ## cdef clear_range( self, int start, int count ):
-    ##    bitClearRange( self.bits, start, count )
-
     def get( self, index ):
         return bitReadOne( self.bits, index );
     
         return binBitsReadOne( self.bb, pos )
     def set( self, pos ):
         binBitsSetOne( self.bb, pos )
+    def clear( self, pos ):
+        binBitsClearOne( self.bb, pos )
     def set_range( self, int start, size ):
         binBitsSetRange( self.bb, start, size )
     def count_range( self, start, size ):

File bx/bitset_tests.py

View file
+import bx.bitset
+import unittest
+
+class AbstractTests( unittest.TestCase ):
+
+    def assert_bits( self, bits, list ):
+        assert bits.size == len( list ), "Bitset size and verification list size do not match"
+        for i in range( bits.size ):
+            self.assertEquals( bits[i], list[i] )
+
+    def test_access( self ):
+        # Create and assert empty
+        bits = self.new_bits( 100 )
+        l = [ 0 ] * 100
+        self.assert_bits( bits, l )
+        # Set some positions
+        for pos in ( 11, 14, 70, 16 ):
+            bits.set( pos )
+            l[ pos ] = 1
+        # Clear some positions
+        for pos in ( 14, 80, 16 ):
+            bits.clear( pos )
+            l[ pos ] = 0
+        self.assert_bits( bits, l )
+
+    def test_range_access( self ):
+        # Create and assert empty
+        bits = self.new_bits( 100 )
+        l = [ 0 ] * 100
+        self.assert_bits( bits, l )
+        # Set some positions
+        for b, e in ( ( 11, 14 ), (20,75), (90,99) ):
+            bits.set_range( b, e-b)
+            for pos in range( b, e ): l[ pos ] = 1
+        self.assert_bits( bits, l )
+
+    def test_count( self ):
+        # Create and assert empty
+        bits = self.new_bits( 100 )
+        # Set some positions
+        for b, e in ( ( 11, 14 ), (20,75), (90,100) ):
+            bits.set_range( b, e-b)
+        self.assertEquals( bits.count_range( 0, 20 ), 3 )
+        self.assertEquals( bits.count_range( 25, 25 ), 25 )
+        self.assertEquals( bits.count_range( 80, 20 ), 10 )
+        self.assertEquals( bits.count_range( 0, 100 ), 68 )
+
+    def test_find( self ):
+        # Create and assert empty
+        bits = self.new_bits( 100 )
+        # Set some positions
+        for b, e in ( ( 11, 14 ), (20,75), (90,100) ):
+            bits.set_range( b, e-b)
+        # Next set
+        self.assertEquals( bits.next_set( 0 ), 11 )
+        self.assertEquals( bits.next_set( 13 ), 13 )
+        self.assertEquals( bits.next_set( 15 ), 20 )
+        # Next clear
+        self.assertEquals( bits.next_clear( 0 ), 0 )
+        self.assertEquals( bits.next_clear( 11 ), 14 )
+        self.assertEquals( bits.next_clear( 20 ), 75 )
+        self.assertEquals( bits.next_clear( 92 ), 100 )
+       
+class BitsetTests( AbstractTests ):
+    def new_bits( self, size ):
+        return bx.bitset.BitSet( size ) 
+
+class BinnedBitsetTests( AbstractTests ):
+    def new_bits( self, size ):
+        granularity = size % 11 
+        return bx.bitset.BinnedBitSet( size, granularity ) 
+
+test_classes = [ BitsetTests, BinnedBitsetTests ]
+
+suite = unittest.TestSuite( [ unittest.makeSuite( c ) for c in test_classes ] )

File setup.py

View file
 py_packages = [ p[:-3] for p in all_packages if p.endswith( ".py" ) ]
 packages = [ p for p in all_packages if not p.endswith( ".py" ) ]
 
-
-JK_LIB="/home/james/projects/ucsc-genome-cvs/kent/src/lib/"
-JK_INC="/home/james/projects/ucsc-genome-cvs/kent/src/inc/"
+UCSC_CVS="/Users/james/Projects/ucsc-genome-cvs/"
+JK_LIB= UCSC_CVS + "kent/src/lib/"
+JK_INC= UCSC_CVS + "kent/src/inc/"
 
 bitset_deps = 'bits.c', 'common.c', 'memalloc.c', 'dlist.c', 'errabort.c', 'osunix.c', 'wildcmp.c'
 

File src/binBits.c

View file
     bitSetOne( bb->bins[bin], offset );
 }
 
+void binBitsClearOne( struct BinBits * bb, int pos )
+{
+    int bin = binBitsGetBin( bb, pos );  
+    int offset = binBitsGetOffset( bb, pos );
+    if ( bb->bins[bin] != NULL )
+    {
+        bitClearOne( bb->bins[bin], offset );
+    }
+}
+
 void binBitsSetRange( struct BinBits *bb, int start, int size )
 {
     int bin, offset, delta;

File src/binBits.h

View file
 void binBitsFree( struct BinBits *bb );
 boolean binBitsReadOne( struct BinBits * bb, int pos );
 void binBitsSetOne( struct BinBits * bb, int pos );
+void binBitsClearOne( struct BinBits * bb, int pos );
 void binBitsSetRange( struct BinBits *bb, int start, int size );
 int binBitsCountRange( struct BinBits *bb, int start, int size );
 int binBitsFindSet( struct BinBits *bb, int start );

File test_runner.py

View file
+#!/usr/bin/env python
+
+import unittest
+import sys
+import distutils.util
+
+lib_dir = "./build/lib.%s-%s" % ( distutils.util.get_platform(), sys.version[0:3] ) 
+sys.path = [ lib_dir ] + sys.path
+
+import bx.bitset_tests
+
+tests = [ bx.bitset_tests.suite ]
+
+if __name__ == "__main__": 
+    test_runner = unittest.TextTestRunner( verbosity=2 )
+    result = test_runner.run( unittest.TestSuite( tests ) )
+    sys.exit(not result.wasSuccessful())