Commits

Lennart Regebro committed 5f301e9

Runs tests properly now

  • Participants
  • Parent commits 50900d5

Comments (0)

Files changed (3)

pyroma/projectdata.py

 # Extracts information from a project that has a distutils setup.py file.
-
 import os
 import re
 import sys
-#import ast
 from collections import defaultdict
 
 IMPORTS = re.compile('^import (.*)$|^from (.*?) import .*$', re.MULTILINE)
 
-class SetupMonkey(object):
+class FakeContext(object):
     
     def __init__(self, path):
         self._path = path
     
+    def __enter__(self):
+        self._old_path = os.path.abspath(os.curdir)
+        if self._old_path in sys.path:
+            sys.path.remove(self._old_path)
+        os.chdir(self._path)
+        
+        if self._path not in sys.path:
+            sys.path.insert(0, self._path)
+            self._path_appended = True
+        else:    
+            self._path_appended = False
+            
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        if self._path_appended:
+            sys.path.remove(self._path)
+        sys.path.append(self._old_path)
+        
+        os.chdir(self._old_path)
+
+    
+class SetupMonkey(object):
+    
     def setup_replacement(self, **kw):
         self._kw = kw
         
             setuptools.setup = self.setup_replacement
         except ImportError:
             self._setuptools_setup = None
-
-        self._old_path = os.path.abspath(os.curdir)
-        if self._old_path in sys.path:
-            sys.path.remove(self._old_path)
-        os.chdir(self._path)
-        
-        if self._path not in sys.path:
-            sys.path.insert(0, self._path)
-            self._path_appended = True
-        else:    
-            self._path_appended = False
             
         return self
-            
+    
     def __exit__(self, exc_type, exc_val, exc_tb):
         import distutils.core
         distutils.core.setup = self._distutils_setup
         if self._setuptools_setup is not None:
             import setuptools
             setuptools.setup = self._setuptools_setup
-            
-        if self._path_appended:
-            sys.path.remove(self._path)
-        sys.path.append(self._old_path)
+
+
+def _specified_versions(data):
+    classifiers = data.get('classifiers', [])
+    for classifier in classifiers:
+        parts = [p.strip() for p in classifier.split('::')]
+        if parts[0] == 'Programming Language' and parts[1] == 'Python':
+            if len(parts) == 2:
+                # Specified Python, but no version.
+                continue
+            version = parts[2]
+            try:
+                int(version)
+                # This is just specifying 2 or 3, not which version
+                continue
+            except ValueError:
+                pass
+            try:
+                float(version)
+                # This version is good!
+                yield version
+            except ValueError:
+                # Not a proper Python version
+                continue
         
-        os.chdir(self._old_path)
-            
 def get_data(path):
     """
     Returns data from a package directory. 
     'path' should be an absolute path.
     """
     # Run the imported setup to get the metadata.
-    with SetupMonkey(path) as sm:
-        import setup
-        metadata = sm.get_data()
-        del sys.modules['setup']
+    with FakeContext(path):
+        with SetupMonkey() as sm:
+            import setup
+            metadata = sm.get_data()
+            del sys.modules['setup']
 
-    metadata['_path'] = path
+        # See if we can run the tests.
+        if not 'test_suite' in metadata:
+            metadata['_testresult'] = "NoTests"
+    
+        else:
+            use_python = None
+            this_version = sys.version[:3]
+            versions = list(_specified_versions(metadata))
+            if this_version in versions:
+                res = os.system(sys.executable + ' setup.py -q test')
+                if res:
+                    metadata['_testresult'] = "Failure"
+                else:
+                    # Success!
+                    metadata['_testresult'] = "Success"
+
+            else:
+                metadata['_testresult'] = "WrongPython"
+        
     return metadata
     

pyroma/ratings.py

           "Cottage Cheese",
           "Your cheese is so fresh most people think it's a cream: Mascarpone"]
 
-# All modules in stdlib. No attempt to differentiate between different
-# versions is made at the moment, but this test is made here rather than in
-# the projectdata.py so that it is possible to extend the test to differentiate
-# on Python version if so desired.
-# __main__ is not strictly a part of stdlib, but it's importable...
-STDLIB = set([
-'_abcoll', 'abc', 'aifc', 'antigravity', 'anydbm', 'argparse', 'ast', 
-'asynchat', 'asyncore', 'atexit', 'audiodev', 'base64', 'BaseHTTPServer', 
-'Bastion', 'bdb', 'binhex', 'bisect', 'calendar', 'CGIHTTPServer', 'cgi', 
-'cgitb', 'chunk', 'cmd', 'codecs', 'codeop', 'code', 'collections', 'colorsys',
-'commands', 'compileall', 'ConfigParser', 'contextlib', 'cookielib', 'Cookie',
-'copy', 'copy_reg', 'cProfile', 'csv', 'dbhash', 'decimal', 'difflib',
-'dircache', 'dis', 'doctest', 'DocXMLRPCServer', 'dumbdbm', 'dummy_threading',
-'dummy_thread', 'filecmp', 'fileinput', 'fnmatch', 'formatter', 'fpformat',
-'fractions', 'ftplib', 'functools', '__future__', 'genericpath', 'getopt',
-'getpass', 'gettext', 'glob', 'gzip', 'hashlib', 'heapq', 'hmac',
-'htmlentitydefs', 'htmllib', 'HTMLParser', 'httplib', 'ihooks', 'imaplib',
-'imghdr', 'imputil', 'inspect', 'io', 'keyword', 'linecache', 'locale',
-'_LWPCookieJar', 'macpath', 'macurl2path', 'mailbox', 'mailcap', 'markupbase',
-'md5', 'mhlib', 'mimetools', 'mimetypes', 'MimeWriter', 'mimify',
-'modulefinder', '_MozillaCookieJar', 'multifile', 'mutex', 'netrc', 'new',
-'nntplib', 'ntpath', 'nturl2path', 'numbers', 'opcode', 'optparse',
-'os2emxpath', 'os', 'pdb', 'pickle', 'pickletools', 'pipes', 'pkgutil', 
-'platform', 'plistlib', 'popen2', 'poplib', 'posixfile', 'posixpath', 'pprint',
-'profile', 'pstats', 'pty', 'pyclbr', 'py_compile', 'pydoc', '_pyio', 'Queue',
-'quopri', 'random', 'repr', 're', 'rexec', 'rfc822', 'rlcompleter',
-'robotparser', 'runpy', 'sched', 'sets', 'sgmllib', 'sha', 'shelve', 'shlex',
-'shutil', 'SimpleHTTPServer', 'SimpleXMLRPCServer', 'site', 'smtpd', 'smtplib',
-'sndhdr', 'socket', 'SocketServer', 'sre_compile', 'sre_constants', 'sre_parse',
-'sre', 'ssl', 'stat', 'statvfs', 'StringIO', 'stringold', 'stringprep', 
-'string', '_strptime', 'struct', 'subprocess', 'sunaudio', 'sunau', 'symbol', 
-'symtable', 'sys', 'sysconfig', 'tabnanny', 'tarfile', 'telnetlib', 'tempfile',
-'textwrap', 'this', '_threading_local', 'threading', 'timeit', 'toaiff', 
-'tokenize', 'token', 'traceback', 'trace', 'tty', 'types', 'unittest', 
-'urllib2', 'urllib', 'urlparse', 'UserDict', 'UserList', 'user', 'UserString', 
-'uuid', 'uu', 'warnings', 'wave', 'weakref', '_weakrefset', 'webbrowser', 
-'whichdb', 'xdrlib', 'xmllib', 'xmlrpclib', 'zipfile', 'dl', 'zipimport', 
-'logging', 'lib2to3', 'distutils', 'multiprocessing', 'imp', 'email',
-'bdist_egg', 'time', 'operator', 'array', 'marshal', 'cStringIO', 'datetime',
-'__main__'])
-
-# Some packages will install other modules. This is bad form, but it happens.
-# If you install setuptools you also get a 'pkg_resources' module, for example.
-ALIASES = {'setuptools': ['pkg_resources'],
-           }
-
 class BaseTest(object):
     fatal = False
     
     
 class RunnableTests(BaseTest):
     
-    weight = 100
-
-    def _specified_versions(self, data):
-        classifiers = data.get('classifiers', [])
-        for classifier in classifiers:
-            parts = [p.strip() for p in classifier.split('::')]
-            if parts[0] == 'Programming Language' and parts[1] == 'Python':
-                if len(parts) == 2:
-                    # Specified Python, but no version.
-                    continue
-                version = parts[2]
-                try:
-                    int(version)
-                    # This is just specifying 2 or 3, not which version
-                    continue
-                except ValueError:
-                    pass
-                try:
-                    float(version)
-                    # This version is good!
-                    yield version
-                except ValueError:
-                    # Not a proper Python version
-                    continue
+    def test(self, data):
+        if not '_testresult' in data:
+            return None
+        
+        if data['_testresult']== 'Failure':
+            self.weight = 100
+            self._msg = "The test suite failed!"
+            return False
+        if data['_testresult'] == 'WrongPython':
+            self.weight = 0
+            self._msg = "This project doesn't support this version of Python; tests not run."
+            return False
+        if data['_testresult'] == 'NoTests':
+            self.weight = 0
+            self._msg = "This package is not set up to run tests."
+            return False
+        if data['_testresult'] == 'Success':
+            self.weight = 100
+            self._msg = ""
+            return True
+        self.fatal = True
+        self._msg = "Uknown error, this is likely a Pyroma bug."
+        return False
     
-    def test(self, data):
-        # See if we can run the tests.
-        if not TestSuite().test(data):
-            self._cause = "NoTests"
-            return None
-
-        use_python = None
-        this_version = sys.version[:3]
-        versions = list(self._specified_versions(data))
-        if this_version in versions:
-            sys.path.insert(0, data['_path'])
-            os.chdir(data['_path'])
-            try:
-                sys.argv = ['setup.py', '-q', 'test']
-                import setup
-                del sys.modules['setup']
-            except SystemExit, e:
-                if e.args[0]:
-                    # Failure
-                    self._cause = "Failure"
-                    return False
-                # Success!
-            finally:
-                sys.path.pop(0)
-            
-            return True
-        
-        self._cause = "WrongPython"
-        return None
-        
     def message(self):
-        if self._cause == 'Failure':
-            self.weight = 100
-            return "The test suite failed!"
-        if self._cause == 'WrongPython':
-            self.weight = 0
-            return "This project doesn't support this version of Python."
-        if self._cause == 'NoTests':
-            self.weight = 0
-            return "This package is not set up to run tests."
-        self.fatal = True
-        return "Uknown error, this is likely a Pyroma bug."
+        return self._msg
 
 class PackageDocs(BaseTest):
     weight = 0 # Just a recommendation
         try:
             parts = publish_parts(source=source, writer_name='html4css1')
         except SystemMessage, e:
-            import pdb;pdb.set_trace()
             self._message = e.args[0].strip()
             return False
         
             'include_package_data': True,
             'zip_safe': True,
             'test_suite': "complete",
+            '_testresult': 'Success',
             }
 
 
         
 class RatingsTest(unittest.TestCase):
     
-    def test_complete(self):
+    def test_complete1(self):
         directory = resource_filename(
             __name__, os.path.join('testdata', 'complete'))
         data = projectdata.get_data(directory)
             'Your package does not have license data.', 
             "It's not specified if this package is zip_safe or not, which is usually an oversight. You should specify it, as it defaults to True, which you probably do not want.",
             "Setuptools and Distribute support running tests. By specifying a test suite, it's easy to find and run tests both for automated tools and humans.",
+            'This package is not set up to run tests.',
         ]))
 
     def test_distribute(self):
             
             self.assertEqual(rating, (9, [
                 'The classifiers should specify what minor versions of Python you support as well as what major version.',
+                "This project doesn't support this version of Python; tests not run.",
                 'You should have three or more owners of the project on PyPI.'
             ]))
         finally:
         
 class ProjectDataTest(unittest.TestCase):
     
-    def test_complete(self):
+    def test_complete2(self):
         directory = resource_filename(
             __name__, os.path.join('testdata', 'complete'))
         
         data = projectdata.get_data(directory)
         # The path is dynamic, and needs not be tested anyway:
-        del data['_path']
         self.assertEqual(data, COMPLETE)
 
 
 class DistroDataTest(unittest.TestCase):
     
-    def test_complete(self):
-        
+    def test_complete3(self):
         directory = resource_filename(
             __name__, os.path.join('testdata', 'distributions'))
 
             if filename.startswith('complete'):
                 data = distributiondata.get_data(os.path.join(directory,
                                                               filename))
-                # The path is dynamic, and needs not be tested anyway:
-                del data['_path']
                 self.assertEqual(data, COMPLETE)