]> arthur.barton.de Git - bup.git/commitdiff
Import new wvtest.py.
authorAvery Pennarun <apenwarr@gmail.com>
Tue, 14 Aug 2012 07:16:09 +0000 (03:16 -0400)
committerAvery Pennarun <apenwarr@gmail.com>
Tue, 14 Aug 2012 07:16:09 +0000 (03:16 -0400)
From wvtest project commit c2197e2caeda8dd8c2dc3dbe5df1eaa7cd177aa1.

wvtest.py

index 86c37a3ccdd18e9ba1d1833592c31a1550220f21..833cfc403c6fddef36a3ff8dca2f7a94f2f9551c 100755 (executable)
--- a/wvtest.py
+++ b/wvtest.py
@@ -1,19 +1,44 @@
 #!/usr/bin/env python
-import traceback
+#
+# WvTest:
+#   Copyright (C)2007-2012 Versabanq Innovations Inc. and contributors.
+#       Licensed under the GNU Library General Public License, version 2.
+#       See the included file named LICENSE for license information.
+#       You can get wvtest from: http://github.com/apenwarr/wvtest
+#
+import atexit
+import inspect
 import os
 import re
 import sys
+import traceback
 
-if __name__ != "__main__":   # we're imported as a module
+# NOTE
+# Why do we do we need the "!= main" check?  Because if you run
+# wvtest.py as a main program and it imports your test files, then
+# those test files will try to import the wvtest module recursively.
+# That actually *works* fine, because we don't run this main program
+# when we're imported as a module.  But you end up with two separate
+# wvtest modules, the one that gets imported, and the one that's the
+# main program.  Each of them would have duplicated global variables
+# (most importantly, wvtest._registered), and so screwy things could
+# happen.  Thus, we make the main program module *totally* different
+# from the imported module.  Then we import wvtest (the module) into
+# wvtest (the main program) here and make sure to refer to the right
+# versions of global variables.
+#
+# All this is done just so that wvtest.py can be a single file that's
+# easy to import into your own applications.
+if __name__ != '__main__':   # we're imported as a module
     _registered = []
     _tests = 0
     _fails = 0
 
     def wvtest(func):
-        """ Use this decorator (@wvtest) in front of any function you want to run
-            as part of the unit test suite.  Then run:
-                python wvtest.py path/to/yourtest.py
-            to run all the @wvtest functions in that file.
+        """ Use this decorator (@wvtest) in front of any function you want to
+            run as part of the unit test suite.  Then run:
+                python wvtest.py path/to/yourtest.py [other test.py files...]
+            to run all the @wvtest functions in the given file(s).
         """
         _registered.append(func)
         return func
@@ -96,59 +121,76 @@ if __name__ != "__main__":   # we're imported as a module
         else:
             return _check(False, 'EXCEPT(%s)' % _code())
 
-else:  # we're the main program
-    # NOTE
-    # Why do we do this in such a convoluted way?  Because if you run
-    # wvtest.py as a main program and it imports your test files, then
-    # those test files will try to import the wvtest module recursively.
-    # That actually *works* fine, because we don't run this main program
-    # when we're imported as a module.  But you end up with two separate
-    # wvtest modules, the one that gets imported, and the one that's the
-    # main program.  Each of them would have duplicated global variables
-    # (most importantly, wvtest._registered), and so screwy things could
-    # happen.  Thus, we make the main program module *totally* different
-    # from the imported module.  Then we import wvtest (the module) into
-    # wvtest (the main program) here and make sure to refer to the right
-    # versions of global variables.
-    #
-    # All this is done just so that wvtest.py can be a single file that's
-    # easy to import into your own applications.
-    import wvtest
-
-    def _runtest(modname, fname, f):
+
+    def _check_unfinished():
+        if _registered:
+            for func in _registered:
+                print 'WARNING: not run: %r' % (func,)
+            WVFAIL('wvtest_main() not called')
+        if _fails:
+            sys.exit(1)
+
+    atexit.register(_check_unfinished)
+
+
+def _run_in_chdir(path, func, *args, **kwargs):
+    oldwd = os.getcwd()
+    oldpath = sys.path
+    try:
+        os.chdir(path)
+        sys.path += [path, os.path.split(path)[0]]
+        return func(*args, **kwargs)
+    finally:
+        os.chdir(oldwd)
+        sys.path = oldpath
+
+
+def _runtest(fname, f):
+    mod = inspect.getmodule(f)
+    relpath = os.path.relpath(mod.__file__, os.getcwd()).replace('.pyc', '.py')
+    print
+    print 'Testing "%s" in %s:' % (fname, relpath)
+    sys.stdout.flush()
+    try:
+        _run_in_chdir(os.path.split(mod.__file__)[0], f)
+    except Exception, e:
         print
-        print 'Testing "%s" in %s.py:' % (fname, modname)
-        sys.stdout.flush()
-        try:
-            f()
-        except Exception, e:
-            print
-            print traceback.format_exc()
-            tb = sys.exc_info()[2]
-            wvtest._result(e, traceback.extract_tb(tb)[1], 'EXCEPTION')
-
-    # main code
-    for modname in sys.argv[1:]:
+        print traceback.format_exc()
+        tb = sys.exc_info()[2]
+        wvtest._result(e, traceback.extract_tb(tb)[1], 'EXCEPTION')
+
+
+def _run_registered_tests():
+    import wvtest as _wvtestmod
+    while _wvtestmod._registered:
+        t = _wvtestmod._registered.pop(0)
+        _runtest(t.func_name, t)
+        print
+
+
+def wvtest_main(extra_testfiles=[]):
+    import wvtest as _wvtestmod
+    _run_registered_tests()
+    for modname in extra_testfiles:
         if not os.path.exists(modname):
             print 'Skipping: %s' % modname
             continue
         if modname.endswith('.py'):
             modname = modname[:-3]
         print 'Importing: %s' % modname
-        wvtest._registered = []
-        oldwd = os.getcwd()
-        oldpath = sys.path
-        try:
-            path, mod = os.path.split(os.path.abspath(modname))
-            os.chdir(path)
-            sys.path += [path, os.path.split(path)[0]]
-            mod = __import__(modname.replace(os.path.sep, '.'), None, None, [])
-            for t in wvtest._registered:
-                _runtest(modname, t.func_name, t)
-                print
-        finally:
-            os.chdir(oldwd)
-            sys.path = oldpath
-
+        path, mod = os.path.split(os.path.abspath(modname))
+        nicename = modname.replace(os.path.sep, '.')
+        while nicename.startswith('.'):
+            nicename = modname[1:]
+        _run_in_chdir(path, __import__, nicename, None, None, [])
+        _run_registered_tests()
     print
-    print 'WvTest: %d tests, %d failures.' % (wvtest._tests, wvtest._fails)
+    print 'WvTest: %d tests, %d failures.' % (_wvtestmod._tests,
+                                              _wvtestmod._fails)
+
+
+if __name__ == '__main__':
+    import wvtest as _wvtestmod
+    sys.modules['wvtest'] = _wvtestmod
+    sys.modules['wvtest.wvtest'] = _wvtestmod
+    wvtest_main(sys.argv[1:])