Commits

Anonymous committed 2853e5f

Added more unit tests. Removed --incomplete flag from test runner. Removed ignore leftovers. Added unit test decorators for interactive unit tests which require user feedback.

  • Participants
  • Parent commits 9a6a112
  • Branches pgreloaded

Comments (0)

Files changed (12)

 
 This also will create a set of bundled docs to be distributed.
 
+Once all packages are built (see below) the revision control tree can be tagged
+with the new version, the packages be published and an announcement sent to the
+mailing list.
+
 Win32 installers
 ----------------
 For Win32 platforms, binary builds (MSI packages) for the Python versions
-*2.4*, *2.5*, *2.6* and *3.0* have to be made, based on one of the source
+*2.4*, *2.5*, *2.6* and *3.1* have to be made, based on one of the source
 packages, which were just created. ::
 
   # For Python 2.4
   
   Instructions for Mac OS X platforms*
 
-Once all packages are built the revision control tree can be tagged with the
-new version, the packages be published and an announcement sent to the mailing
-list.
-
 Postprocessing
 ==============
 Right after a release has been made and the tree was tagged correctly, the

examples/import.py

     import pygame2.mask
 
     try:
+        import pygame2.midi
+    except ImportError:
+        print (sys.exc_info()[1])
+    
+    try:
         import pygame2.sdl
         import pygame2.sdl.audio
         import pygame2.sdl.cdrom

test/base_color_test.py

 ################################################################################
 
     def test_correct_gamma__verified_against_python_implementation(self):
-        "|tags:slow|"
         # gamma_correct defined at top of page
 
         gammas = list (map(lambda i: i / 10.0, range(1, 31))) # [0.1 .. 3.0]

test/font_test.py

 
 class FontTest (unittest.TestCase):
     
-    def todo_test_pygame2_font_find_font(self):
+    def test_pygame2_font_find_font(self):
 
         # __doc__ (as of 2009-12-10) for pygame2.font.find_font:
 
         # types, such as bdf or ttf fonts.
 
         # name, bold, italic = font.find_font ('sans')
-        self.fail() 
+        retval = font.find_font ("invalidfont")
+        self.assertEqual (retval, None)
+        
+        retval = font.find_font ("sans")
+        self.assertEqual (len (retval), 3)
+        self.assertEqual (type (retval[0]), str)
+        self.assertEqual (type (retval[1]), bool)
+        self.assertEqual (type (retval[2]), bool)
 
     def todo_test_pygame2_font_find_fonts(self):
 
         # Gets the list of available font families.
 
         self.fail() 
+
+if __name__ == '__main__':
+    unittest.main()

test/mask_test.py

     m = Mask(size)
     for i in range(size[0] * size[1] // 2):
         x, y = random.randint(0,size[0] - 1), random.randint(0, size[1] - 1)
-        m.set_at((x,y))
+        m.set_at(x, y)
     return m
 
 class MaskTest (unittest.TestCase):
         self.assertEqual(m1.size, m2.size)
         for i in range(m1.size[0]):
             for j in range(m1.size[1]):
-                self.assertEqual(m1.get_at((i,j)), m2.get_at((i,j)))
+                self.assertEqual(m1.get_at(i, j), m2.get_at(i, j))
 
     def todo_test_pygame2_mask_Mask_angle(self):
 
 
         self.fail() 
 
-    def todo_test_pygame2_mask_Mask_clear(self):
+    def test_pygame2_mask_Mask_clear(self):
 
         # __doc__ (as of 2008-11-03) for pygame2.mask.Mask.clear:
 
         # 
         # Clears all bits in the Mask.
         # 
-        # Resets the state of all bits in the Mask to 0..
-
-        self.fail() 
+        # Resets the state of all bits in the Mask to 0.
+        m = random_mask ()
+        self.assertNotEqual (m.count, 0)
+        m.clear ()
+        self.assertEqual (m.count, 0)
 
     def todo_test_pygame2_mask_Mask_connected_component(self):
 
         # returned. In the event the pixel at that location is not set,
         # the returned Mask will be empty. The Mask returned is the same
         # size as the original Mask.
-
+        
         self.fail() 
 
     def test_pygame2_mask_Mask_connected_components(self):
         self.assertEqual(len(comps3), 0)
 
 
-    def todo_test_pygame2_mask_Mask_count(self):
+    def test_pygame2_mask_Mask_count(self):
 
         # __doc__ (as of 2008-11-03) for pygame2.mask.Mask.count:
 
         # Gets the amount of bits in the Mask.
-
-        self.fail()
+        m = Mask (10, 10)
+        for x in range (10):
+            for y in range (10):
+                m.set_at (x, y)
+        self.assertEqual (m.count, 100)
+        m.clear ()
+        self.assertEqual (m.count, 0)
 
     def test_pygame2_mask_Mask_convolve(self):
 
         # Mask.fill () -> None
         # 
         # Sets all bits to 1 within the Mask.
-        m = Mask((100,100))
+        m = Mask(100, 100)
         self.assertEqual(m.count, 0)
         
         m.fill()
         m = Mask (100, 343)
         self.assertEqual (m.height, 343)
 
-    def todo_test_pygame2_mask_Mask_invert(self):
+    def test_pygame2_mask_Mask_invert(self):
 
         # __doc__ (as of 2008-11-03) for pygame2.mask.Mask.invert:
 
         # Mask.invert () -> None
         # 
         # Inverts all bits in the Mask.
-
-        self.fail() 
+        m = Mask (10, 10)
+        for x in range (10):
+            for y in range (10):
+                m.set_at (x, y)
+        self.assertEqual (m.count, 100)
+        m.invert ()
+        self.assertEqual (m.count, 0)
+        m.set_at (4, 4)
+        m.invert ()
+        self.assertEqual (m.count, 99)
+        self.assertEqual (m.get_at (4, 4), 0)
+        for x in range (10):
+            for y in range (10):
+                if x == y == 4:
+                    self.assertEqual (m.get_at (x, y), 0)
+                else:
+                    self.assertEqual (m.get_at (x, y), 1)
 
     def test_pygame2_mask_Mask_outline(self):
 

test/pgtestutils.py

+#
+# This file is under the public domain.
+#
+
+import os
+
+try:
+    getinput = raw_input
+except NameError:
+    getinput = input
+
+def getanswer (question):
+    answer = getinput ("%s [y/n]: " % question)
+    return answer.lower ().strip () == 'y'
+
+def doprint (text):
+    getinput ("%s (press enter to continue) " % text)
+
+class interactive (object):
+    """Simple interactive question decorator for unit test methods.
+    """
+    def __init__ (self, question):
+        self.question = question
+
+    def __call__ (self, func):
+        def wrapper (*fargs, **kw):
+            if fargs and getattr (fargs[0], "__class__", None):
+                instance = fargs[0]
+                funcargs = fargs[1:]
+                print (os.linesep)
+                func (instance, *funcargs, **kw)
+                if not getanswer (self.question):
+                    instance.fail ()
+
+        wrapper.__name__ = func.__name__
+        wrapper.__dict__.update (func.__dict__)
+        wrapper.__tags__ = [ 'interactive' ]
+        return wrapper
+
+class ignore (object):
+    """Simple ignore flag decorator."""
+    def __init__ (self, func):
+        self.func = func
+    
+    def __call__ (self):
+        pass

test/pgunittest.py

 import os
 import types
 
+#
+# pygame specific enhancement
+#
+try:
+    from pygame2.test.pgtestutils import *
+except:
+    from pgtestutils import *
+
+#
+# pygame specific enhancement END
+#
+
 ##############################################################################
 # Exported classes and functions
 ##############################################################################

test/run_tests.py

     # Defaults:
     #    See optparse options below for more options (test_runner.py)
     #
-
-    # Any tests in IGNORE will not be ran
-    IGNORE = set ([
-        "scrap_test",
-        ])
-
-    # Subprocess has less of a need to worry about interference between tests
-    SUBPROCESS_IGNORE = set ([
-        "scrap_test",
-        ])
-
     #######################################################################
     # Set the command line options
     #
             m.endswith('_test') and m or ('%s_test' % m) for m in args
             ]
     else:
-        if options.subprocess:
-            ignore = SUBPROCESS_IGNORE
-        else:
-            ignore = IGNORE
 
         test_modules = []
         for f in sorted(os.listdir(test_subdir)):
             for match in TEST_MODULE_RE.findall(f):
-                if match not in ignore:
-                    test_modules.append(match)
+                test_modules.append(match)
 
     #######################################################################
     # Meta results

test/sdl_cdrom_test.py

 import sys
 try:
     import pygame2.test.pgunittest as unittest
+    from pygame2.test.pgunittest import doprint, interactive
 except:
     import pgunittest as unittest
+    from pgunittest import doprint, interactive
 
 import pygame2
-import pygame2.sdl.wm as wm
+import pygame2.sdl.cdrom as cdrom
 import pygame2.sdl.constants as constants
 
 class SDLCDRomTest (unittest.TestCase):
         # Gets the track type (data or audio).
 
         self.fail() 
-
-    def todo_test_pygame2_sdl_cdrom_get_name(self):
-
+
+    @interactive ("Are the shown CD/DVD drive names correct?")
+    def test_pygame2_sdl_cdrom_get_name(self):
+        #
         # __doc__ (as of 2009-12-14) for pygame2.sdl.cdrom.get_name:
 
         # get_name (index) -> str
         # 
         # Gets the system-dependent drive name (e.g. "/dev/cdrom" or "D:")
         # for the CD- or DVD-Rom specified by the passed *index*.
+        cdrom.init ()
+        self.assertRaises (ValueError, cdrom.get_name, -4)
+        self.assertRaises (ValueError, cdrom.get_name, cdrom.num_drives ())
+        
+        for i in range (cdrom.num_drives ()):
+            doprint ("Drive %d: %s" % (i, cdrom.get_name (i)))
+        cdrom.quit ()
 
-        self.fail() 
-
-    def todo_test_pygame2_sdl_cdrom_init(self):
+    def test_pygame2_sdl_cdrom_init(self):
 
         # __doc__ (as of 2009-12-14) for pygame2.sdl.cdrom.init:
 
         # init () -> None
         # 
         # Initializes the CD-ROM subsystem of the SDL library.
-
-        self.fail() 
-
-    def todo_test_pygame2_sdl_cdrom_num_drives(self):
-
+        self.assertEqual (cdrom.init (), None)
+        self.assertTrue (cdrom.was_init ())
+        self.assertEqual (cdrom.quit (), None)
+        self.assertFalse (cdrom.was_init ())
+
+    @interactive ("Does the shown number match your CD and DVD drives?")
+    def test_pygame2_sdl_cdrom_num_drives(self):
         # __doc__ (as of 2009-12-14) for pygame2.sdl.cdrom.num_drives:
 
-        # um_drives () -> int
+        # num_drives () -> int
         # 
         # Gets the number of accessible CD- and DVD-ROM drives for the system.
+        cdrom.init ()
+        doprint ("Found CD/DVD drives: %d" % cdrom.num_drives ())
+        cdrom.quit ()
 
-        self.fail() 
-
-    def todo_test_pygame2_sdl_cdrom_quit(self):
+    def test_pygame2_sdl_cdrom_quit(self):
 
         # __doc__ (as of 2009-12-14) for pygame2.sdl.cdrom.quit:
 
         # After calling this function, you should not invoke any class,
         # method or function related to the CD-ROM subsystem as they are
         # likely to fail or might give unpredictable results.
+        self.assertEqual (cdrom.quit (), None)
 
-        self.fail() 
-
-    def todo_test_pygame2_sdl_cdrom_was_init(self):
+    def test_pygame2_sdl_cdrom_was_init(self):
 
         # __doc__ (as of 2009-12-14) for pygame2.sdl.cdrom.was_init:
 
         # was_init () -> bool
         # 
         # Returns, whether the CD-ROM subsystem of the SDL library is initialized.
-
-        self.fail() 
+        self.assertFalse (cdrom.was_init ())
+        self.assertEqual (cdrom.init (), None)
+        self.assertTrue (cdrom.was_init ())
+        self.assertEqual (cdrom.quit (), None)
+        self.assertFalse (cdrom.was_init ())
 
 if __name__ == "__main__":
     unittest.main ()

test/sdl_keyboard_test.py

 try:
     import pygame2.test.pgunittest as unittest
+    from pygame2.test.pgunittest import doprint, interactive
 except:
     import pgunittest as unittest
+    from pgunittest import doprint, interactive
 
 import pygame2
 import pygame2.sdl.keyboard as keyboard
         self.assertEqual (keyboard.get_key_name (constants.K_4), '4')
         video.quit ()
 
-    def todo_test_pygame2_sdl_keyboard_get_mod_state(self):
+    def test_pygame2_sdl_keyboard_get_mod_state(self):
 
         # __doc__ (as of 2009-05-13) for pygame2.sdl.keyboard.get_mod_state:
 
         # if specific shift keys are pressed, the state of the capslock
         # button, and more.  The bitmask will consist of the various
         # KMOD_* flags as specified in the constants.
-
-        self.fail() 
+        video.init ()
+        self.assertEqual (keyboard.get_mod_state (), 0)
+        kstate = constants.KMOD_LALT|constants.KMOD_NUM
+        keyboard.set_mod_state (kstate)
+        self.assertEqual (keyboard.get_mod_state (), kstate)
+        keyboard.set_mod_state (constants.KMOD_CAPS)
+        self.assertEqual (keyboard.get_mod_state (), constants.KMOD_CAPS)
+        keyboard.set_mod_state (kstate)
+        self.assertEqual (keyboard.get_mod_state (), kstate)
+        video.quit ()
 
     def test_pygame2_sdl_keyboard_get_repeat(self):
 
         self.assert_ (constants.K_KP4 in keyboard.get_state ().keys ())
         video.quit ()
 
-    def todo_test_pygame2_sdl_keyboard_set_mod_state(self):
+    def test_pygame2_sdl_keyboard_set_mod_state(self):
 
         # __doc__ (as of 2009-05-13) for pygame2.sdl.keyboard.set_mod_state:
 
         # Sets the current modifier key state. mod has to be a bitwise OR'd
         # combination of the KMOD_* flags as they are specified in the
         # constants.
-
-        self.fail() 
+        video.init ()
+        self.assertEqual (keyboard.get_mod_state (), 0)
+        kstate = constants.KMOD_LALT|constants.KMOD_NUM
+        keyboard.set_mod_state (kstate)
+        self.assertEqual (keyboard.get_mod_state (), kstate)
+        keyboard.set_mod_state (constants.KMOD_CAPS)
+        self.assertEqual (keyboard.get_mod_state (), constants.KMOD_CAPS)
+        keyboard.set_mod_state (kstate)
+        self.assertEqual (keyboard.get_mod_state (), kstate)
+        video.quit ()
 
 if __name__ == "__main__":
     unittest.main ()

test/test_runner.py

 opt_parser = optparse.OptionParser()
 
 opt_parser.add_option (
-     "-i",  "--incomplete", action = 'store_true',
-     help   = "fail incomplete tests" )
-
-opt_parser.add_option (
      "-s",  "--subprocess", action = 'store_true',
      help   = "run everything in an own subprocess (default: single process)" )
 

test/unittest_patch.py

             parent_class  = obj.__class__
             parent_module = self.get_parent_module(parent_class)
 
+            obj_tags = getattr (obj, '__tags__', [])
             module_tags = getattr(parent_module, '__tags__', [])
             class_tags  = getattr(parent_class,  '__tags__', [])
 
             tags = TAGS_RE.search(getdoc(obj) or '')
-            if tags: test_tags = [t.strip() for t in tags.group(1).split(',')]
-            else:    test_tags = []
+            if tags:
+                test_tags = [t.strip() for t in tags.group(1).split(',')]
+            else:
+                test_tags = []
         
             combined = set()
-            for tags in (module_tags, class_tags, test_tags):
-                if not tags: continue
+            for tags in (obj_tags, module_tags, class_tags, test_tags):
+                if not tags:
+                    continue
         
                 add    = set(t for t in tags if not t.startswith('-'))
                 remove = set(t[1:] for t in tags if t not in add)
         
-                if add:     combined.update(add)
-                if remove:  combined.difference_update(remove)
+                if add:
+                    combined.update(add)
+                if remove:
+                    combined.difference_update(remove)
     
             self.memoized[obj] = combined
 
 #
 def getTestCaseNames(self, testCaseClass):
     def test_wanted(attrname, testCaseClass=testCaseClass,
-                              prefix=self.testMethodPrefix):
-        if not attrname.startswith(prefix): return False
+                    prefix=self.testMethodPrefix):
+        if not attrname.startswith(prefix):
+            return False
         else:
             actual_attr = getattr(testCaseClass, attrname)
             if sys.version_info >= (3, 0, 0):
 ################################################################################
 
 def patch(options):
-    # Incomplete todo_xxx tests
-    if options.incomplete:
-        unittest.TestLoader.testMethodPrefix = (
-            unittest.TestLoader.testMethodPrefix, 'todo_'
-        )
     
     # Randomizing    
     unittest.TestLoader.randomize_tests = options.randomize or options.seed