Unit Tests for the Python Weak Reference Object

The functionality of the Python Weak Reference extension module was tested with a help of a unit test program test.py. This program makes use of two 3-rd party unit test modules written by Steve Purcell: unittest.py and unittestgui.py.These modules can be obtained at http://pyunit.sourceforge.net/.

The following is the text of the program:

 

       1    # !/usr/local/bin/python
       2    #
       3    # Filename: test.py
       4    # Copyright (c) Alex Shindich, 2000
       5    # Author: Alex Shindich
       6    # License: The author is making this software available on an "AS IS" basis.
       7    #   There are no warranties regarding this software. Use it at your own risk!
       8    #   Permission to use, copy, modify, and distribute this software and its
       9    #   documentation for any purpose and without fee is hereby granted without
      10    #   any restrictions.
      11    #
      12    # Purpose: This file contains unit tests for WeakRef extension module
      13    #          In order to run these tests, two unit test modules have to
      14    #          be installed in python module path: unittest.py and unittestgui.py
      15    #          These modules can be obtained at http://pyunit.sourceforge.net/
      16    
      17    import unittest
      18    import unittestgui
      19    import sys
      20    import weakref
      21    
      22    class WeakRefTestCase(unittest.TestCase):
      23        """A test case for the Weak Reference class"""
      24    
      25        class Foo:
      26            instanceCount = 0
      27            def __init__(self):
      28                WeakRefTestCase.Foo.instanceCount += 1
      29            def __del__(self):
      30                WeakRefTestCase.Foo.instanceCount -= 1
      31    
      32        def setUp(self):
      33            """"""
      34            pass
      35    
      36        def __createTestObjects (self, count):
      37            """This method create a list of test objects."""
      38    
      39            # Declare a list of types we want to test
      40            factories = [lambda : 's', lambda : 1L, lambda : 20., lambda : WeakRefTestCase.Foo (),
      41                     lambda : None, lambda : 1, lambda : [], lambda : {}]
      42            # Create a whole bunch of references
      43            retList = []
      44            for x in range (count):
      45                for factory in factories:
      46                    # Create a new object
      47                    newObj = factory ()
      48                    # Add the object to the list
      49                    retList.append (newObj)
      50                    
      51            return retList
      52    
      53        def __createWeakReferences (self, testObjects):
      54            """This method create a list of weak references for every element in 
            the testObjects list."""
      56    
      57            retList = []
      58            for testObj in testObjects:
      59                newWeakRef = weakref.new (testObj)
      60                retList.append (newWeakRef)
      61    
      62            return retList
      63            
      64        def __copyFromWeakReferences (self, weakReferences):
      65            """This method create a list of new references to the test objects
            from the list of weak references."""
      67    
      68            retList = []
      69            for weakReference in weakReferences:
      70                newRef = weakReference.newref ()
      71                retList.append (newRef)
      72    
      73            return retList
      74            
      75        def check_Stress (self):
      76            """This method conducts stress testing of the weak reference object."""
      77    
      78            # Create test objects
      79            testObjects = self.__createTestObjects (1000)
      80            # Create a list of weak references
      81            weakRefList = self.__createWeakReferences (testObjects)
      82            # Copy the list from the weak references
      83            copyOfTestObjects = self.__copyFromWeakReferences (weakRefList)
      84            # Compare the lists
      85            assert (testObjects == copyOfTestObjects)
      86            # Delete the copy list
      87            del copyOfTestObjects
      88            # Delete half of the original test list
      89            midPos = len (testObjects)/2
      90            testObjects = testObjects[0:midPos]
      91            # Iterate over the list of weak references and make sure that it returns new
      92            # references for the first half of the list and None references for the weak
      93            # references to Foo for the second half of the list
      94            for index in range (len (weakRefList)):
      95                # Create a new reference from the weak reference
      96                newRef = weakRefList[index].newref ()
      97                # Check to see if this is supposed to be a stale reference
      98                if index < len (testObjects):
      99                    # This is a good reference
     100                    testRef = testObjects[index]
     101                else:
     102                    # This is a stale reference
     103                    testRef = None
     104                # Copare the object to the original object
     105                assert (type(newRef) != type (WeakRefTestCase.Foo) or testRef == newRef)
     106                assert (type(newRef) != type (WeakRefTestCase.Foo) or type(testRef) == type(newRef))
     107    
     108        def check_None (self):
     109            """This method makes sure that the weak reference implementation
            returns None if the 'weak' object has been deleted."""
     111    
     112            # Create an instance of the Foo class
     113            f = WeakRefTestCase.Foo ()
     114            # Create a weak reference
     115            wr = weakref.new (f)
     116            # Delete the test instance of Foo
     117            del f
     118            # Now create a new reference from the weak reference
     119            f2 = wr.newref ()
     120            # Make sure that the new reference is a None object
     121            assert (type(None) == type (f2))
     122            assert (None == f2)
     123    
     124        def check_Idenity (self):
     125            """This method makes sure that the weak reference implementation
            does not violate Python identity rules."""
     127    
     128            # Create an instance of the Foo class
     129            f = WeakRefTestCase.Foo ()
     130            # Create a weak reference
     131            wr = weakref.new (f)
     132            # Now create a new reference from the weak reference
     133            f2 = wr.newref ()
     134            # Make sure that f2 equals to f
     135            assert (f == f2)
     136            # Make sure that f2 is an instance of Foo
     137            assert (isinstance (f2, type(f)))
     138    
     139        def check_TestRefCount (self):
     140            """This method makes sure that reference counting rules
            have not been broken."""
     142    
     143            # Save the number of Foo instances
     144            instanceCount = WeakRefTestCase.Foo.instanceCount
     145            # Create an instance of the Foo class
     146            f = WeakRefTestCase.Foo ()
     147            # Save the reference count
     148            refCount = sys.getrefcount (f)
     149            # Create a weak reference
     150            wr = weakref.new (f)
     151            # Make sure that the reference count has not changed
     152            refCount == sys.getrefcount (f)
     153            # Now create a new reference from the weak reference
     154            f2 = wr.newref ()
     155            # Make sure that the reference count was bumped by one
     156            refCount == sys.getrefcount (f)-1
     157            # Delete the original Foo reference
     158            del f
     159            # Make sure that the object count went down by one
     160            refCount == sys.getrefcount (f2)
     161            # Delete the second Foo reference
     162            del f2
     163            # Make sure that the original test instance of Foo got detroyed
     164            assert (instanceCount == WeakRefTestCase.Foo.instanceCount)
     165    
     166        def check_TestCmp (self):
     167            """This method makes sure that comparison operator works
            correctly."""
     169    
     170            # Create an instance of the Foo class
     171            f = WeakRefTestCase.Foo ()
     172            # Create a weak reference
     173            wr = weakref.new (f)
     174            # Create another weak reference
     175            awr = weakref.new (f)
     176            # Make sure that the references are equal
     177            assert (wr == awr)
     178            # Create another instance of the Foo class
     179            f2 = WeakRefTestCase.Foo ()
     180            # Create a weak reference for f2
     181            awr = weakref.new (f2)
     182            # Make sure that the references are not equal
     183            assert (wr != awr)
     184            
     185        def check_TestHash (self):
     186            """This method makes sure that hash function works
            correctly."""
     188    
     189            # Create an instance of the Foo class
     190            f = WeakRefTestCase.Foo ()
     191            # Create a weak reference
     192            wr = weakref.new (f)
     193            # Create another weak reference
     194            awr = weakref.new (f)
     195            # Make sure that hash numbers are the same
     196            assert (hash(wr) == hash(awr))
     197            # Create another instance of the Foo class
     198            f2 = WeakRefTestCase.Foo ()
     199            # Create a weak reference for f2
     200            awr = weakref.new (f2)
     201            # Make sure that the references are not equal
     202            assert (hash(wr) != hash(awr))
     203            
     204        def check_TestGetType (self):
     205            """This method makes sure that gettype function works
            correctly."""
     207    
     208            # Create an instance of the Foo class
     209            f = WeakRefTestCase.Foo ()
     210            # Create a weak reference
     211            wr = weakref.new (f)
     212            # Create another weak reference
     213            awr = weakref.new (f)
     214            # Make sure that types are the same
     215            assert (wr.gettype () == type (f))
     216            assert (wr.gettype () == awr.gettype ())
     217            # Delete the object
     218            del f
     219            # Make sure that types are None
     220            assert (wr.gettype () == None)
     221            assert (wr.gettype () == awr.gettype ())
     222            
     223        def check_TestDict (self):
     224            """This method makes sure that dictionary objects 
            work correctly with weak references."""
     226            
     227            # Create test objects
     228            testObjects = self.__createTestObjects (1000)
     229            # Create a list of weak references
     230            weakRefList = self.__createWeakReferences (testObjects)
     231            # Create a dictionary of weak references from the list
     232            weakRefDict = {}
     233            for wr in weakRefList:
     234                weakRefDict[wr] = wr
     235            # Create another list of weak references
     236            weakRefList2 = self.__createWeakReferences (testObjects)
     237            # Make sure that map works properly
     238            for wr in weakRefList2:
     239                assert (weakRefDict[wr] == wr)
     240    
     241    def suite():
     242        return unittest.makeSuite(WeakRefTestCase, 'check')
     243    
     244    if __name__ == '__main__':
     245        unittestgui.main ('test.suite')