Hello community, here is the log from the commit of package python-testtools for openSUSE:Factory checked in at 2014-12-09 09:14:26 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-testtools (Old) and /work/SRC/openSUSE:Factory/.python-testtools.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-testtools" Changes: -------- --- /work/SRC/openSUSE:Factory/python-testtools/python-testtools.changes 2014-09-17 17:27:24.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.python-testtools.new/python-testtools.changes 2014-12-09 09:14:02.000000000 +0100 @@ -1,0 +2,39 @@ +Mon Dec 1 22:48:47 UTC 2014 - [email protected] + +- fix typo in last change + +------------------------------------------------------------------- +Mon Dec 1 17:04:18 UTC 2014 - [email protected] + +- Update to version 1.5.0: + * When an import error happens ``testtools.run`` will now show the full + error rather than just the name of the module that failed to import. + (Robert Collins) + * ``testtools.TestCase`` now inherits from unittest2.TestCase, which + provides a ``setUpClass`` for upcalls on Python 2.6. + (Robert Collins, #1393283) + * Fixed our setup.py to use setup_requires to ensure the import dependencies + for testtools are present before setup.py runs (as setup.py imports testtools + to read out the version number). (Robert Collins) + * Support setUpClass skipping with self.skipException. Previously this worked + with unittest from 2.7 and above but was not supported by testtools - it was + a happy accident. Since we now hard depend on unittest2, we need to invert + our exception lookup priorities to support it. Regular skips done through + raise self.skipException will continue to work, since they were always caught + in our code - its because the suite type being used to implement setUpClass + has changed that an issue occured. + (Robert Collins, #1393068) + * Correctly express our unittest2 dependency: we don't work with old releases. + (Robert Collins) + * Depends on unittest2 for discovery functionality and the ``TestProgram`` base + class. This brings in many fixes made to discovery where previously we were + only using the discovery package or the version in the release of Python + that the test execution was occuring on. (Robert Collins, #1271133) + * Fixed unit tests which were failing under pypy due to a change in the way + pypy formats tracebacks. (Thomi Richards) + * Fixed the testtools test suite to run correctly when run via ``unit2`` + or ``testtools.run discover``. + * Make `testtools.content.text_content` error if anything other than text + is given as content. (Thomi Richards) + +------------------------------------------------------------------- Old: ---- testtools-1.1.0.tar.gz New: ---- testtools-1.5.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-testtools.spec ++++++ --- /var/tmp/diff_new_pack.J454HH/_old 2014-12-09 09:14:03.000000000 +0100 +++ /var/tmp/diff_new_pack.J454HH/_new 2014-12-09 09:14:03.000000000 +0100 @@ -21,7 +21,7 @@ %bcond_with tests Name: python-testtools -Version: 1.1.0 +Version: 1.5.0 Release: 0 Summary: Extensions to the Python Standard Library Unit Testing Framework License: MIT @@ -29,15 +29,14 @@ Url: https://launchpad.net/testtools Source: https://pypi.python.org/packages/source/t/testtools/testtools-%{version}.tar.gz BuildRequires: python-devel -# Documentation requirements: -BuildRequires: python-Sphinx -# Test requirements: -%if %{with tests} BuildRequires: python-extras BuildRequires: python-python-mimeparse -%endif +BuildRequires: python-unittest2 >= 0.8.0 +# Documentation requirements: +BuildRequires: python-Sphinx Requires: python-extras Requires: python-python-mimeparse +Requires: python-unittest2 >= 0.8.0 BuildRoot: %{_tmppath}/%{name}-%{version}-build %if 0%{?suse_version} && 0%{?suse_version} <= 1110 %{!?python_sitelib: %global python_sitelib %(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} ++++++ testtools-1.1.0.tar.gz -> testtools-1.5.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-1.1.0/Makefile new/testtools-1.5.0/Makefile --- old/testtools-1.1.0/Makefile 2013-02-05 10:58:30.000000000 +0100 +++ new/testtools-1.5.0/Makefile 2014-10-31 03:10:59.000000000 +0100 @@ -21,11 +21,11 @@ -rm MANIFEST release: - ./setup.py sdist upload --sign + ./setup.py sdist bdist_wheel upload --sign $(PYTHON) scripts/_lp_release.py snapshot: prerelease - ./setup.py sdist + ./setup.py sdist bdist_wheel ### Documentation ### diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-1.1.0/NEWS new/testtools-1.5.0/NEWS --- old/testtools-1.1.0/NEWS 2014-09-14 00:51:43.000000000 +0200 +++ new/testtools-1.5.0/NEWS 2014-11-21 00:20:13.000000000 +0100 @@ -7,6 +7,76 @@ NEXT ~~~~ +1.5.0 +~~~~~ + +Improvements +------------ + +* When an import error happens ``testtools.run`` will now show the full + error rather than just the name of the module that failed to import. + (Robert Collins) + +1.4.0 +~~~~~ + +Changes +------- + +* ``testtools.TestCase`` now inherits from unittest2.TestCase, which + provides a ``setUpClass`` for upcalls on Python 2.6. + (Robert Collins, #1393283) + +1.3.0 +~~~~~ + +Changes +------- + +* Fixed our setup.py to use setup_requires to ensure the import dependencies + for testtools are present before setup.py runs (as setup.py imports testtools + to read out the version number). (Robert Collins) + +* Support setUpClass skipping with self.skipException. Previously this worked + with unittest from 2.7 and above but was not supported by testtools - it was + a happy accident. Since we now hard depend on unittest2, we need to invert + our exception lookup priorities to support it. Regular skips done through + raise self.skipException will continue to work, since they were always caught + in our code - its because the suite type being used to implement setUpClass + has changed that an issue occured. + (Robert Collins, #1393068) + +1.2.1 +~~~~~ + +Changes +------- + +* Correctly express our unittest2 dependency: we don't work with old releases. + (Robert Collins) + +1.2.0 +~~~~~ + +Changes +------- + +* Depends on unittest2 for discovery functionality and the ``TestProgram`` base + class. This brings in many fixes made to discovery where previously we were + only using the discovery package or the version in the release of Python + that the test execution was occuring on. (Robert Collins, #1271133) + +* Fixed unit tests which were failing under pypy due to a change in the way + pypy formats tracebacks. (Thomi Richards) + +* Fixed the testtools test suite to run correctly when run via ``unit2`` + or ``testtools.run discover``. + +* Make `testtools.content.text_content` error if anything other than text + is given as content. (Thomi Richards) + +* We now publish wheels of testtools. (Robert Collins, #issue84) + 1.1.0 ~~~~~ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-1.1.0/PKG-INFO new/testtools-1.5.0/PKG-INFO --- old/testtools-1.1.0/PKG-INFO 2014-09-14 00:54:43.000000000 +0200 +++ new/testtools-1.5.0/PKG-INFO 2014-11-21 00:20:56.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: testtools -Version: 1.1.0 +Version: 1.5.0 Summary: Extensions to the Python standard library unit testing framework Home-page: https://github.com/testing-cabal/testtools Author: Jonathan M. Lange diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-1.1.0/README.rst new/testtools-1.5.0/README.rst --- old/testtools-1.1.0/README.rst 2013-10-13 06:03:38.000000000 +0200 +++ new/testtools-1.5.0/README.rst 2014-11-15 20:24:03.000000000 +0100 @@ -31,7 +31,7 @@ Required Dependencies --------------------- - * Python 2.6+ or 3.0+ + * Python 2.6+ or 3.0+ / pypy (2.x+) If you would like to use testtools for earlier Python's, please use testtools 0.9.15. @@ -39,6 +39,9 @@ * extras (helpers that we intend to push into Python itself in the near future). + * The most recent unittest2 (backports of the latest unittest API from + cPython, which we use to avoid code duplication). + Optional Dependencies --------------------- Files old/testtools-1.1.0/doc/.hacking.rst.swp and new/testtools-1.5.0/doc/.hacking.rst.swp differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-1.1.0/setup.cfg new/testtools-1.5.0/setup.cfg --- old/testtools-1.1.0/setup.cfg 2014-09-14 00:54:43.000000000 +0200 +++ new/testtools-1.5.0/setup.cfg 2014-11-21 00:20:56.000000000 +0100 @@ -3,6 +3,9 @@ buffer = 1 catch = 1 +[bdist_wheel] +universal = 1 + [egg_info] tag_build = tag_date = 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-1.1.0/setup.py new/testtools-1.5.0/setup.py --- old/testtools-1.1.0/setup.py 2014-09-03 06:08:31.000000000 +0200 +++ new/testtools-1.5.0/setup.py 2014-11-15 22:33:08.000000000 +0100 @@ -48,7 +48,7 @@ # Apparently if we just say "snapshot" then distribute won't accept it # as satisfying versioned dependencies. This is a problem for the # daily build version. - return "snapshot-%s" % (version,) + return "%s.0dev0" % (version,) def get_long_description(): @@ -56,6 +56,16 @@ os.path.dirname(__file__), 'doc/overview.rst') return open(manual_path).read() +# Since we import testtools in setup.py, our setup requirements are our install +# requirements. +deps = [ + 'extras', + # 'mimeparse' has not been uploaded by the maintainer with Python3 compat + # but someone kindly uploaded a fixed version as 'python-mimeparse'. + 'python-mimeparse', + 'unittest2>=0.8.0', + ] + setup(name='testtools', author='Jonathan M. Lange', @@ -77,10 +87,6 @@ ], cmdclass=cmd_class, zip_safe=False, - install_requires=[ - 'extras', - # 'mimeparse' has not been uploaded by the maintainer with Python3 compat - # but someone kindly uploaded a fixed version as 'python-mimeparse'. - 'python-mimeparse', - ], + install_requires=deps, + setup_requires=deps, ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-1.1.0/testtools/__init__.py new/testtools-1.5.0/testtools/__init__.py --- old/testtools-1.1.0/testtools/__init__.py 2014-09-14 00:52:14.000000000 +0200 +++ new/testtools-1.5.0/testtools/__init__.py 2014-11-21 00:20:00.000000000 +0100 @@ -122,4 +122,4 @@ # If the releaselevel is 'final', then the tarball will be major.minor.micro. # Otherwise it is major.minor.micro~$(revno). -__version__ = (1, 1, 0, 'final', 0) +__version__ = (1, 5, 0, 'final', 0) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-1.1.0/testtools/compat.py new/testtools-1.5.0/testtools/compat.py --- old/testtools-1.1.0/testtools/compat.py 2014-01-29 10:53:19.000000000 +0100 +++ new/testtools-1.5.0/testtools/compat.py 2014-11-15 10:08:40.000000000 +0100 @@ -7,10 +7,8 @@ '_b', '_u', 'advance_iterator', - 'all', 'BytesIO', 'classtypes', - 'isbaseexception', 'istext', 'str_is_unicode', 'StringIO', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-1.1.0/testtools/content.py new/testtools-1.5.0/testtools/content.py --- old/testtools-1.1.0/testtools/content.py 2014-08-21 04:57:56.000000000 +0200 +++ new/testtools-1.5.0/testtools/content.py 2014-10-20 04:16:48.000000000 +0200 @@ -25,9 +25,9 @@ _b, _format_exception_only, _format_stack_list, - _isbytes, _TB_HEADER, _u, + istext, str_is_unicode, ) from testtools.content_type import ContentType, JSON, UTF8_TEXT @@ -63,11 +63,11 @@ class Content(object): """A MIME-like Content object. - Content objects can be serialised to bytes using the iter_bytes method. - If the Content-Type is recognised by other code, they are welcome to + 'Content' objects can be serialised to bytes using the iter_bytes method. + If the 'Content-Type' is recognised by other code, they are welcome to look for richer contents that mere byte serialisation - for example in memory object graphs etc. However, such code MUST be prepared to receive - a generic Content object that has been reconstructed from a byte stream. + a generic 'Content' object that has been reconstructed from a byte stream. :ivar content_type: The content type of this Content. """ @@ -128,7 +128,7 @@ class StackLinesContent(Content): """Content object for stack lines. - This adapts a list of "preprocessed" stack lines into a content object. + This adapts a list of "preprocessed" stack lines into a 'Content' object. The stack lines are most likely produced from ``traceback.extract_stack`` or ``traceback.extract_tb``. @@ -180,8 +180,8 @@ def TracebackContent(err, test): """Content object for tracebacks. - This adapts an exc_info tuple to the Content interface. - text/x-traceback;language=python is used for the mime type, in order to + This adapts an exc_info tuple to the 'Content' interface. + 'text/x-traceback;language=python' is used for the mime type, in order to provide room for other languages to format their tracebacks differently. """ if err is None: @@ -223,7 +223,7 @@ def StacktraceContent(prefix_content="", postfix_content=""): """Content object for stack traces. - This function will create and return a content object that contains a + This function will create and return a 'Content' object that contains a stack trace. The mime type is set to 'text/x-traceback;language=python', so other @@ -251,7 +251,7 @@ def json_content(json_data): - """Create a JSON `Content` object from JSON-encodeable data.""" + """Create a JSON Content object from JSON-encodeable data.""" data = json.dumps(json_data) if str_is_unicode: # The json module perversely returns native str not bytes @@ -260,12 +260,14 @@ def text_content(text): - """Create a `Content` object from some text. + """Create a Content object from some text. This is useful for adding details which are short strings. """ - if _isbytes(text): - raise TypeError('text_content must be given a string, not bytes.') + if not istext(text): + raise TypeError( + "text_content must be given text, not '%s'." % type(text).__name__ + ) return Content(UTF8_TEXT, lambda: [text.encode('utf8')]) @@ -278,9 +280,9 @@ def content_from_file(path, content_type=None, chunk_size=DEFAULT_CHUNK_SIZE, buffer_now=False, seek_offset=None, seek_whence=0): - """Create a `Content` object from a file on disk. + """Create a Content object from a file on disk. - Note that unless 'read_now' is explicitly passed in as True, the file + Note that unless ``buffer_now`` is explicitly passed in as True, the file will only be read from when ``iter_bytes`` is called. :param path: The path to the file to be used as content. @@ -291,7 +293,7 @@ :param buffer_now: If True, read the file from disk now and keep it in memory. Otherwise, only read when the content is serialized. :param seek_offset: If non-None, seek within the stream before reading it. - :param seek_whence: If supplied, pass to stream.seek() when seeking. + :param seek_whence: If supplied, pass to ``stream.seek()`` when seeking. """ if content_type is None: content_type = UTF8_TEXT @@ -308,13 +310,13 @@ def content_from_stream(stream, content_type=None, chunk_size=DEFAULT_CHUNK_SIZE, buffer_now=False, seek_offset=None, seek_whence=0): - """Create a `Content` object from a file-like stream. + """Create a Content object from a file-like stream. - Note that the stream will only be read from when ``iter_bytes`` is - called. + Note that unless ``buffer_now`` is explicitly passed in as True, the stream + will only be read from when ``iter_bytes`` is called. :param stream: A file-like object to read the content from. The stream - is not closed by this function or the content object it returns. + is not closed by this function or the 'Content' object it returns. :param content_type: The type of content. If not specified, defaults to UTF8-encoded text/plain. :param chunk_size: The size of chunks to read from the file. @@ -322,7 +324,7 @@ :param buffer_now: If True, reads from the stream right now. Otherwise, only reads when the content is serialized. Defaults to False. :param seek_offset: If non-None, seek within the stream before reading it. - :param seek_whence: If supplied, pass to stream.seek() when seeking. + :param seek_whence: If supplied, pass to ``stream.seek()`` when seeking. """ if content_type is None: content_type = UTF8_TEXT @@ -353,9 +355,9 @@ This is a convenience method wrapping around ``addDetail``. - Note that unless 'read_now' is explicitly passed in as True, the file - *must* exist when the test result is called with the results of this - test, after the test has been torn down. + Note that by default the contents of the file will be read immediately. If + ``buffer_now`` is False, then the file *must* exist when the test result is + called with the results of this test, after the test has been torn down. :param detailed: An object with details :param path: The path to the file to attach. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-1.1.0/testtools/run.py new/testtools-1.5.0/testtools/run.py --- old/testtools-1.1.0/testtools/run.py 2014-09-12 00:21:19.000000000 +0200 +++ new/testtools-1.5.0/testtools/run.py 2014-11-18 22:55:29.000000000 +0100 @@ -8,9 +8,10 @@ $ python -m testtools.run testtools.tests.test_suite """ +import argparse from functools import partial import os.path -import unittest +import unittest2 as unittest import sys from extras import safe_hasattr @@ -22,21 +23,14 @@ defaultTestLoader = unittest.defaultTestLoader defaultTestLoaderCls = unittest.TestLoader +have_discover = True +discover_impl = unittest.loader -if getattr(defaultTestLoader, 'discover', None) is None: - try: - import discover - defaultTestLoader = discover.DiscoveringTestLoader() - defaultTestLoaderCls = discover.DiscoveringTestLoader - have_discover = True - discover_impl = discover - except ImportError: - have_discover = False -else: - have_discover = True - discover_impl = unittest.loader -discover_fixed = False - +# Kept for API compatibility, but no longer used. +BUFFEROUTPUT = "" +CATCHBREAK = "" +FAILFAST = "" +USAGE_AS_MAIN = "" def list_test(test): """Return the test ids that would be run if test() was run. @@ -52,7 +46,9 @@ describing things that failed to import. """ unittest_import_strs = set([ - 'unittest.loader.ModuleImportFailure.', 'discover.ModuleImportFailure.' + 'unittest2.loader.ModuleImportFailure.', + 'unittest.loader.ModuleImportFailure.', + 'discover.ModuleImportFailure.' ]) test_ids = [] errors = [] @@ -84,13 +80,13 @@ stdout = sys.stdout self.stdout = stdout - def list(self, test): + def list(self, test, loader): """List the tests that would be run if test() was run.""" - test_ids, errors = list_test(test) + test_ids, _ = list_test(test) for test_id in test_ids: self.stdout.write('%s\n' % test_id) + errors = loader.errors if errors: - self.stdout.write('Failed to import\n') for test_id in errors: self.stdout.write('%s\n' % test_id) sys.exit(2) @@ -110,75 +106,23 @@ # Taken from python 2.7 and slightly modified for compatibility with # older versions. Delete when 2.7 is the oldest supported version. # Modifications: -# - Use have_discover to raise an error if the user tries to use -# discovery on an old version and doesn't have discover installed. -# - If --catch is given check that installHandler is available, as -# it won't be on old python versions. -# - print calls have been been made single-source python3 compatibile. -# - exception handling likewise. -# - The default help has been changed to USAGE_AS_MAIN and USAGE_FROM_MODULE -# removed. -# - A tweak has been added to detect 'python -m *.run' and use a -# better progName in that case. -# - self.module is more comprehensively set to None when being invoked from -# the commandline - __name__ is used as a sentinel value. +# - If --catch is given, check that installHandler is available, as +# it won't be on old python versions or python builds without signals. # - --list has been added which can list tests (should be upstreamed). # - --load-list has been added which can reduce the tests used (should be # upstreamed). -# - The limitation of using getopt is declared to the user. -# - http://bugs.python.org/issue16709 is worked around, by sorting tests when -# discover is used. -# - We monkey-patch the discover and unittest loaders to address -# http://bugs.python.org/issue16662 with the proposed upstream patch. - -FAILFAST = " -f, --failfast Stop on first failure\n" -CATCHBREAK = " -c, --catch Catch control-C and display results\n" -BUFFEROUTPUT = " -b, --buffer Buffer stdout and stderr during test runs\n" - -USAGE_AS_MAIN = """\ -Usage: %(progName)s [options] [tests] - -Options: - -h, --help Show this message - -v, --verbose Verbose output - -q, --quiet Minimal output - -l, --list List tests rather than executing them. - --load-list Specifies a file containing test ids, only tests matching - those ids are executed. -%(failfast)s%(catchbreak)s%(buffer)s -Examples: - %(progName)s test_module - run tests from test_module - %(progName)s module.TestClass - run tests from module.TestClass - %(progName)s module.Class.test_method - run specified test method - -All options must come before [tests]. [tests] can be a list of any number of -test modules, classes and test methods. - -Alternative Usage: %(progName)s discover [options] - -Options: - -v, --verbose Verbose output -%(failfast)s%(catchbreak)s%(buffer)s -s directory Directory to start discovery ('.' default) - -p pattern Pattern to match test files ('test*.py' default) - -t directory Top level directory of project (default to - start directory) - -l, --list List tests rather than executing them. - --load-list Specifies a file containing test ids, only tests matching - those ids are executed. - -For test discovery all test modules must be importable from the top -level directory of the project. -""" -class TestProgram(object): +class TestProgram(unittest.TestProgram): """A command-line program that runs a set of tests; this is primarily for making test modules conveniently executable. """ - USAGE = USAGE_AS_MAIN # defaults for testing + module=None + verbosity = 1 failfast = catchbreak = buffer = progName = None + _discovery_parser = None def __init__(self, module=__name__, defaultTest=None, argv=None, testRunner=None, testLoader=defaultTestLoader, @@ -204,6 +148,7 @@ self.verbosity = verbosity self.buffer = buffer self.defaultTest = defaultTest + # XXX: Local edit (see http://bugs.python.org/issue22860) self.listtests = False self.load_list = None self.testRunner = testRunner @@ -216,6 +161,7 @@ progName = os.path.basename(argv[0]) self.progName = progName self.parseArgs(argv) + # XXX: Local edit (see http://bugs.python.org/issue22860) if self.load_list: # TODO: preserve existing suites (like testresources does in # OptimisingTestSuite.add, but with a standard protocol). @@ -228,155 +174,38 @@ source.close() test_ids = set(line.strip().decode('utf-8') for line in lines) self.test = filter_by_ids(self.test, test_ids) + # XXX: Local edit (see http://bugs.python.org/issue22860) if not self.listtests: self.runTests() else: runner = self._get_runner() if safe_hasattr(runner, 'list'): - runner.list(self.test) + try: + runner.list(self.test, loader=self.testLoader) + except TypeError: + runner.list(self.test) else: for test in iterate_tests(self.test): self.stdout.write('%s\n' % test.id()) + del self.testLoader.errors[:] - def usageExit(self, msg=None): - if msg: - print(msg) - usage = {'progName': self.progName, 'catchbreak': '', 'failfast': '', - 'buffer': ''} - if self.failfast != False: - usage['failfast'] = FAILFAST - if self.catchbreak != False: - usage['catchbreak'] = CATCHBREAK - if self.buffer != False: - usage['buffer'] = BUFFEROUTPUT - print(self.USAGE % usage) - sys.exit(2) - - def parseArgs(self, argv): - if len(argv) > 1 and argv[1].lower() == 'discover': - self._do_discovery(argv[2:]) - return - - import getopt - long_opts = ['help', 'verbose', 'quiet', 'failfast', 'catch', 'buffer', - 'list', 'load-list='] - try: - options, args = getopt.getopt(argv[1:], 'hHvqfcbl', long_opts) - for opt, value in options: - if opt in ('-h','-H','--help'): - self.usageExit() - if opt in ('-q','--quiet'): - self.verbosity = 0 - if opt in ('-v','--verbose'): - self.verbosity = 2 - if opt in ('-f','--failfast'): - if self.failfast is None: - self.failfast = True - # Should this raise an exception if -f is not valid? - if opt in ('-c','--catch'): - if self.catchbreak is None: - self.catchbreak = True - # Should this raise an exception if -c is not valid? - if opt in ('-b','--buffer'): - if self.buffer is None: - self.buffer = True - # Should this raise an exception if -b is not valid? - if opt in ('-l', '--list'): - self.listtests = True - if opt == '--load-list': - self.load_list = value - if len(args) == 0 and self.defaultTest is None: - # createTests will load tests from self.module - self.testNames = None - elif len(args) > 0: - self.testNames = args - else: - self.testNames = (self.defaultTest,) - self.createTests() - except getopt.error: - self.usageExit(sys.exc_info()[1]) - - def createTests(self): - if self.testNames is None: - self.test = self.testLoader.loadTestsFromModule(self.module) - else: - self.test = self.testLoader.loadTestsFromNames(self.testNames, - self.module) - - def _do_discovery(self, argv, Loader=defaultTestLoaderCls): - # handle command line args for test discovery - if not have_discover: - raise AssertionError("Unable to use discovery, must use python 2.7 " - "or greater, or install the discover package.") - _fix_discovery() - self.progName = '%s discover' % self.progName - import optparse - parser = optparse.OptionParser() - parser.prog = self.progName - parser.add_option('-v', '--verbose', dest='verbose', default=False, - help='Verbose output', action='store_true') - if self.failfast != False: - parser.add_option('-f', '--failfast', dest='failfast', default=False, - help='Stop on first fail or error', - action='store_true') - if self.catchbreak != False: - parser.add_option('-c', '--catch', dest='catchbreak', default=False, - help='Catch ctrl-C and display results so far', - action='store_true') - if self.buffer != False: - parser.add_option('-b', '--buffer', dest='buffer', default=False, - help='Buffer stdout and stderr during tests', - action='store_true') - parser.add_option('-s', '--start-directory', dest='start', default='.', - help="Directory to start discovery ('.' default)") - parser.add_option('-p', '--pattern', dest='pattern', default='test*.py', - help="Pattern to match tests ('test*.py' default)") - parser.add_option('-t', '--top-level-directory', dest='top', default=None, - help='Top level directory of project (defaults to start directory)') - parser.add_option('-l', '--list', dest='listtests', default=False, action="store_true", - help='List tests rather than running them.') - parser.add_option('--load-list', dest='load_list', default=None, - help='Specify a filename containing the test ids to use.') - - options, args = parser.parse_args(argv) - if len(args) > 3: - self.usageExit() - - for name, value in zip(('start', 'pattern', 'top'), args): - setattr(options, name, value) - - # only set options from the parsing here - # if they weren't set explicitly in the constructor - if self.failfast is None: - self.failfast = options.failfast - if self.catchbreak is None: - self.catchbreak = options.catchbreak - if self.buffer is None: - self.buffer = options.buffer - self.listtests = options.listtests - self.load_list = options.load_list - - if options.verbose: - self.verbosity = 2 - - start_dir = options.start - pattern = options.pattern - top_level_dir = options.top - - loader = Loader() - # See http://bugs.python.org/issue16709 - # While sorting here is intrusive, its better than being random. - # Rules for the sort: - # - standard suites are flattened, and the resulting tests sorted by - # id. - # - non-standard suites are preserved as-is, and sorted into position - # by the first test found by iterating the suite. - # We do this by a DSU process: flatten and grab a key, sort, strip the - # keys. - loaded = loader.discover(start_dir, pattern, top_level_dir) - self.test = sorted_tests(loaded) + def _getParentArgParser(self): + parser = super(TestProgram, self)._getParentArgParser() + # XXX: Local edit (see http://bugs.python.org/issue22860) + parser.add_argument('-l', '--list', dest='listtests', default=False, + action='store_true', help='List tests rather than executing them') + parser.add_argument('--load-list', dest='load_list', default=None, + help='Specifies a file containing test ids, only tests matching ' + 'those ids are executed') + return parser + + def _do_discovery(self, argv, Loader=None): + super(TestProgram, self)._do_discovery(argv, Loader=Loader) + # XXX: Local edit (see http://bugs.python.org/issue22860) + self.test = sorted_tests(self.test) def runTests(self): + # XXX: Local edit (see http://bugs.python.org/issue22860) if (self.catchbreak and getattr(unittest, 'installHandler', None) is not None): unittest.installHandler() @@ -386,6 +215,7 @@ sys.exit(not self.result.wasSuccessful()) def _get_runner(self): + # XXX: Local edit (see http://bugs.python.org/issue22860) if self.testRunner is None: self.testRunner = TestToolsTestRunner try: @@ -410,120 +240,6 @@ return testRunner -def _fix_discovery(): - # Monkey patch in the bugfix from http://bugs.python.org/issue16662 - # - the code here is a straight copy from the Python core tree - # with the patch applied. - global discover_fixed - if discover_fixed: - return - # Do we have a fixed Python? - # (not committed upstream yet - so we can't uncomment this code, - # but when it gets committed, the next version to be released won't - # need monkey patching. - # if sys.version_info[:2] > (3, 4): - # discover_fixed = True - # return - if not have_discover: - return - if safe_hasattr(discover_impl, '_jython_aware_splitext'): - _jython_aware_splitext = discover_impl._jython_aware_splitext - else: - def _jython_aware_splitext(path): - if path.lower().endswith('$py.class'): - return path[:-9] - return os.path.splitext(path)[0] - def loadTestsFromModule(self, module, use_load_tests=True, pattern=None): - """Return a suite of all tests cases contained in the given module""" - # use_load_tests is preserved for compatability though it was never - # an official API. - # pattern is not an official API either; it is used in discovery to - # chain the requested pattern down. - tests = [] - for name in dir(module): - obj = getattr(module, name) - if isinstance(obj, type) and issubclass(obj, unittest.TestCase): - tests.append(self.loadTestsFromTestCase(obj)) - - load_tests = getattr(module, 'load_tests', None) - tests = self.suiteClass(tests) - if use_load_tests and load_tests is not None: - try: - return load_tests(self, tests, pattern) - except Exception as e: - return discover_impl._make_failed_load_tests( - module.__name__, e, self.suiteClass) - return tests - def _find_tests(self, start_dir, pattern, namespace=False): - """Used by discovery. Yields test suites it loads.""" - paths = sorted(os.listdir(start_dir)) - - for path in paths: - full_path = os.path.join(start_dir, path) - if os.path.isfile(full_path): - if not discover_impl.VALID_MODULE_NAME.match(path): - # valid Python identifiers only - continue - if not self._match_path(path, full_path, pattern): - continue - # if the test file matches, load it - name = self._get_name_from_path(full_path) - try: - module = self._get_module_from_name(name) - except testcase.TestSkipped as e: - yield discover_impl._make_skipped_test( - name, e, self.suiteClass) - except: - yield discover_impl._make_failed_import_test( - name, self.suiteClass) - else: - mod_file = os.path.abspath(getattr(module, '__file__', full_path)) - realpath = _jython_aware_splitext( - os.path.realpath(mod_file)) - fullpath_noext = _jython_aware_splitext( - os.path.realpath(full_path)) - if realpath.lower() != fullpath_noext.lower(): - module_dir = os.path.dirname(realpath) - mod_name = _jython_aware_splitext( - os.path.basename(full_path)) - expected_dir = os.path.dirname(full_path) - msg = ("%r module incorrectly imported from %r. Expected %r. " - "Is this module globally installed?") - raise ImportError(msg % (mod_name, module_dir, expected_dir)) - yield self.loadTestsFromModule(module, pattern=pattern) - elif os.path.isdir(full_path): - if (not namespace and - not os.path.isfile(os.path.join(full_path, '__init__.py'))): - continue - - load_tests = None - tests = None - name = self._get_name_from_path(full_path) - try: - package = self._get_module_from_name(name) - except testcase.TestSkipped as e: - yield discover_impl._make_skipped_test( - name, e, self.suiteClass) - except: - yield discover_impl._make_failed_import_test( - name, self.suiteClass) - else: - load_tests = getattr(package, 'load_tests', None) - tests = self.loadTestsFromModule(package, pattern=pattern) - if tests is not None: - # tests loaded from package file - yield tests - - if load_tests is not None: - # loadTestsFromModule(package) has load_tests for us. - continue - # recurse into the package - pkg_tests = self._find_tests( - full_path, pattern, namespace=namespace) - for test in pkg_tests: - yield test - defaultTestLoaderCls.loadTestsFromModule = loadTestsFromModule - defaultTestLoaderCls._find_tests = _find_tests ################ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-1.1.0/testtools/testcase.py new/testtools-1.5.0/testtools/testcase.py --- old/testtools-1.1.0/testtools/testcase.py 2014-09-12 00:40:41.000000000 +0200 +++ new/testtools-1.5.0/testtools/testcase.py 2014-11-17 19:40:37.000000000 +0100 @@ -20,12 +20,12 @@ import itertools import sys import types -import unittest from extras import ( safe_hasattr, try_import, ) +import unittest2 as unittest from testtools import ( content, @@ -57,8 +57,8 @@ class TestSkipped(Exception): """Raised within TestCase.run() when a test is skipped.""" -TestSkipped = try_import('unittest2.case.SkipTest', TestSkipped) TestSkipped = try_import('unittest.case.SkipTest', TestSkipped) +TestSkipped = try_import('unittest2.case.SkipTest', TestSkipped) class _UnexpectedSuccess(Exception): @@ -68,9 +68,9 @@ module. """ _UnexpectedSuccess = try_import( - 'unittest2.case._UnexpectedSuccess', _UnexpectedSuccess) -_UnexpectedSuccess = try_import( 'unittest.case._UnexpectedSuccess', _UnexpectedSuccess) +_UnexpectedSuccess = try_import( + 'unittest2.case._UnexpectedSuccess', _UnexpectedSuccess) class _ExpectedFailure(Exception): """An expected failure occured. @@ -79,9 +79,9 @@ module. """ _ExpectedFailure = try_import( - 'unittest2.case._ExpectedFailure', _ExpectedFailure) -_ExpectedFailure = try_import( 'unittest.case._ExpectedFailure', _ExpectedFailure) +_ExpectedFailure = try_import( + 'unittest2.case._ExpectedFailure', _ExpectedFailure) # Copied from unittest before python 3.4 release. Used to maintain diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-1.1.0/testtools/tests/__init__.py new/testtools-1.5.0/testtools/tests/__init__.py --- old/testtools-1.1.0/testtools/tests/__init__.py 2014-09-12 00:21:19.000000000 +0200 +++ new/testtools-1.5.0/testtools/tests/__init__.py 2014-11-15 10:08:40.000000000 +0100 @@ -25,6 +25,7 @@ test_testcase, test_testresult, test_testsuite, + test_with_with, ) modules = [ matchers, @@ -44,6 +45,7 @@ test_testcase, test_testresult, test_testsuite, + test_with_with, ] suites = map(lambda x: x.test_suite(), modules) return TestSuite(suites) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-1.1.0/testtools/tests/test_content.py new/testtools-1.5.0/testtools/tests/test_content.py --- old/testtools-1.1.0/testtools/tests/test_content.py 2014-08-21 04:57:56.000000000 +0200 +++ new/testtools-1.5.0/testtools/tests/test_content.py 2014-10-20 04:16:48.000000000 +0200 @@ -196,6 +196,17 @@ data = _b("Some Bytes") self.assertRaises(TypeError, text_content, data) + def test_text_content_raises_TypeError_when_passed_non_text(self): + bad_values = (None, list(), dict(), 42, 1.23) + for value in bad_values: + self.assertThat( + lambda: text_content(value), + raises( + TypeError("text_content must be given text, not '%s'." % + type(value).__name__) + ), + ) + def test_json_content(self): data = {'foo': 'bar'} expected = Content(JSON, lambda: [_b('{"foo": "bar"}')]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-1.1.0/testtools/tests/test_deferredruntest.py new/testtools-1.5.0/testtools/tests/test_deferredruntest.py --- old/testtools-1.1.0/testtools/tests/test_deferredruntest.py 2014-09-02 13:20:23.000000000 +0200 +++ new/testtools-1.5.0/testtools/tests/test_deferredruntest.py 2014-11-15 10:08:40.000000000 +0100 @@ -771,7 +771,10 @@ def test_suite(): - from unittest import TestLoader, TestSuite - return TestSuite( - [TestLoader().loadTestsFromName(__name__), - make_integration_tests()]) + from unittest2 import TestLoader, TestSuite + return TestLoader().loadTestsFromName(__name__) + + +def load_tests(loader, tests, pattern): + tests.addTest(make_integration_tests()) + return tests diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-1.1.0/testtools/tests/test_run.py new/testtools-1.5.0/testtools/tests/test_run.py --- old/testtools-1.1.0/testtools/tests/test_run.py 2014-09-12 00:21:19.000000000 +0200 +++ new/testtools-1.5.0/testtools/tests/test_run.py 2014-11-18 22:59:06.000000000 +0100 @@ -2,6 +2,7 @@ """Tests for the test runner logic.""" +import doctest from unittest import TestSuite import sys from textwrap import dedent @@ -9,6 +10,7 @@ from extras import try_import fixtures = try_import('fixtures') testresources = try_import('testresources') +import unittest2 import testtools from testtools import TestCase, run, skipUnless @@ -19,6 +21,7 @@ ) from testtools.matchers import ( Contains, + DocTestMatches, MatchesRegex, ) @@ -105,7 +108,7 @@ testtools.__path__.append(self.package.base) -if fixtures and run.have_discover: +if fixtures: class SampleLoadTestsPackage(fixtures.Fixture): """Creates a test suite package using load_tests.""" @@ -155,6 +158,27 @@ self.assertEqual([set(['testtools.runexample.TestFoo.test_bar', 'testtools.runexample.TestFoo.test_quux'])], tests) + def test_run_list_with_loader(self): + # list() is attempted with a loader first. + self.useFixture(SampleTestFixture()) + tests = [] + class CaptureList(run.TestToolsTestRunner): + def list(self, test, loader=None): + tests.append(set([case.id() for case + in testtools.testsuite.iterate_tests(test)])) + tests.append(loader) + out = StringIO() + try: + program = run.TestProgram( + argv=['prog', '-l', 'testtools.runexample.test_suite'], + stdout=out, testRunner=CaptureList) + except SystemExit: + exc_info = sys.exc_info() + raise AssertionError("-l tried to exit. %r" % exc_info[1]) + self.assertEqual([set(['testtools.runexample.TestFoo.test_bar', + 'testtools.runexample.TestFoo.test_quux']), program.testLoader], + tests) + def test_run_list(self): self.useFixture(SampleTestFixture()) out = StringIO() @@ -168,17 +192,27 @@ """, out.getvalue()) def test_run_list_failed_import(self): - if not run.have_discover: - self.skipTest("Need discover") broken = self.useFixture(SampleTestFixture(broken=True)) out = StringIO() + # XXX: http://bugs.python.org/issue22811 + unittest2.defaultTestLoader._top_level_dir = None exc = self.assertRaises( SystemExit, run.main, ['prog', 'discover', '-l', broken.package.base, '*.py'], out) self.assertEqual(2, exc.args[0]) - self.assertEqual("""Failed to import -runexample -""", out.getvalue()) + self.assertThat(out.getvalue(), DocTestMatches("""\ +Failed to import test module: runexample +Traceback (most recent call last): + File ".../loader.py", line ..., in _find_test_path + package = self._get_module_from_name(name) + File ".../loader.py", line ..., in _get_module_from_name + __import__(name) + File ".../runexample/__init__.py", line 1 + class not in +...^... +SyntaxError: invalid syntax + +""", doctest.ELLIPSIS)) def test_run_orders_tests(self): self.useFixture(SampleTestFixture()) @@ -201,7 +235,8 @@ 'testtools.runexample.test_suite'], out) except SystemExit: exc_info = sys.exc_info() - raise AssertionError("-l tried to exit. %r" % exc_info[1]) + raise AssertionError( + "-l --load-list tried to exit. %r" % exc_info[1]) self.assertEqual("""testtools.runexample.TestFoo.test_bar """, out.getvalue()) @@ -226,7 +261,8 @@ 'testtools.runexample.test_suite'], out) except SystemExit: exc_info = sys.exc_info() - raise AssertionError("-l tried to exit. %r" % exc_info[1]) + raise AssertionError( + "-l --load-list tried to exit. %r" % exc_info[1]) self.assertEqual("""testtools.runexample.TestFoo.test_bar """, out.getvalue()) @@ -287,7 +323,6 @@ OK """))) - @skipUnless(run.have_discover, "discovery not present") @skipUnless(fixtures, "fixtures not present") def test_issue_16662(self): # unittest's discover implementation didn't handle load_tests on @@ -296,6 +331,8 @@ # See http://bugs.python.org/issue16662 pkg = self.useFixture(SampleLoadTestsPackage()) out = StringIO() + # XXX: http://bugs.python.org/issue22811 + unittest2.defaultTestLoader._top_level_dir = None self.assertEqual(None, run.main( ['prog', 'discover', '-l', pkg.package.base], out)) self.assertEqual(dedent("""\ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-1.1.0/testtools/tests/test_testcase.py new/testtools-1.5.0/testtools/tests/test_testcase.py --- old/testtools-1.1.0/testtools/tests/test_testcase.py 2014-09-02 13:20:23.000000000 +0200 +++ new/testtools-1.5.0/testtools/tests/test_testcase.py 2014-11-17 19:40:37.000000000 +0100 @@ -51,12 +51,6 @@ FullStackRunTest, LoggingResult, ) -try: - exec('from __future__ import with_statement') -except SyntaxError: - pass -else: - from testtools.tests.test_with_with import * class TestPlaceHolder(TestCase): @@ -1608,40 +1602,43 @@ self.assertRaises(ZeroDivisionError, wrapped) +class Attributes(WithAttributes, TestCase): + @attr('foo') + def simple(self): + pass + + # Not sorted here, forward or backwards. + @attr('foo', 'quux', 'bar') + def many(self): + pass + + # Not sorted here, forward or backwards. + @attr('bar') + @attr('quux') + @attr('foo') + def decorated(self): + pass + + class TestAttributes(TestCase): def test_simple_attr(self): # Adding an attr to a test changes its id(). - class MyTest(WithAttributes, TestCase): - @attr('foo') - def test_bar(self): - pass - case = MyTest('test_bar') - self.assertEqual('testtools.tests.test_testcase.MyTest.test_bar[foo]', + case = Attributes('simple') + self.assertEqual( + 'testtools.tests.test_testcase.Attributes.simple[foo]', case.id()) def test_multiple_attributes(self): - class MyTest(WithAttributes, TestCase): - # Not sorted here, forward or backwards. - @attr('foo', 'quux', 'bar') - def test_bar(self): - pass - case = MyTest('test_bar') + case = Attributes('many') self.assertEqual( - 'testtools.tests.test_testcase.MyTest.test_bar[bar,foo,quux]', + 'testtools.tests.test_testcase.Attributes.many[bar,foo,quux]', case.id()) def test_multiple_attr_decorators(self): - class MyTest(WithAttributes, TestCase): - # Not sorted here, forward or backwards. - @attr('bar') - @attr('quux') - @attr('foo') - def test_bar(self): - pass - case = MyTest('test_bar') + case = Attributes('decorated') self.assertEqual( - 'testtools.tests.test_testcase.MyTest.test_bar[bar,foo,quux]', + 'testtools.tests.test_testcase.Attributes.decorated[bar,foo,quux]', case.id()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-1.1.0/testtools/tests/test_testresult.py new/testtools-1.5.0/testtools/tests/test_testresult.py --- old/testtools-1.1.0/testtools/tests/test_testresult.py 2014-09-03 06:08:31.000000000 +0200 +++ new/testtools-1.5.0/testtools/tests/test_testresult.py 2014-10-20 04:16:48.000000000 +0200 @@ -9,6 +9,7 @@ import doctest from itertools import chain, combinations import os +import re import shutil import sys import tempfile @@ -69,6 +70,7 @@ HasLength, MatchesAny, MatchesException, + MatchesRegex, Raises, ) from testtools.tests.helpers import ( @@ -2547,13 +2549,18 @@ self._write_module("bad", "iso-8859-5", "# coding: iso-8859-5\n%% = 0 # %s\n" % text) textoutput = self._run_external_case() - self.assertIn(self._as_output(_u( - #'bad.py", line 2\n' - ' %% = 0 # %s\n' - + ' ' * self._error_on_character + - ' ^\n' - 'SyntaxError: ') % - (text,)), textoutput) + self.assertThat( + textoutput, + MatchesRegex( + self._as_output(_u( + #'bad.py", line 2\n' + '.*%% = 0 # %s\n' + + ' ' * self._error_on_character + + '\\s*\\^\n' + 'SyntaxError:.*') % + (text,)), + re.MULTILINE | re.DOTALL) + ) def test_syntax_error_line_euc_jp(self): """Syntax error on a euc_jp line shows the line decoded""" @@ -2579,13 +2586,17 @@ textoutput = self._setup_external_case("import bad") self._write_module("bad", "utf-8", _u("\ufeff^ = 0 # %s\n") % text) textoutput = self._run_external_case() - self.assertIn(self._as_output(_u( - 'bad.py", line 1\n' - ' ^ = 0 # %s\n' - + ' ' * self._error_on_character + - ' ^\n' - 'SyntaxError: ') % - text), textoutput) + self.assertThat( + textoutput, + MatchesRegex( + self._as_output(_u( + '.*bad.py", line 1\n' + '\\s*\\^ = 0 # %s\n' + + ' ' * self._error_on_character + + '\\s*\\^\n' + 'SyntaxError:.*') % text), + re.M | re.S) + ) class TestNonAsciiResultsWithUnittest(TestNonAsciiResults): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-1.1.0/testtools/tests/test_testsuite.py new/testtools-1.5.0/testtools/tests/test_testsuite.py --- old/testtools-1.1.0/testtools/tests/test_testsuite.py 2014-08-24 07:10:42.000000000 +0200 +++ new/testtools-1.5.0/testtools/tests/test_testsuite.py 2014-11-17 19:40:37.000000000 +0100 @@ -8,6 +8,7 @@ from functools import partial import sys import unittest +import unittest2 from extras import try_import @@ -200,6 +201,42 @@ tests = list(enumerate(iterate_tests(suite))) return [(test, _u(str(pos))) for pos, test in tests] + def test_setupclass_skip(self): + # We should support setupclass skipping using cls.skipException. + # Because folk have used that. + class Skips(TestCase): + @classmethod + def setUpClass(cls): + raise cls.skipException('foo') + def test_notrun(self): + pass + # Test discovery uses the default suite from unittest2 (unless users + # deliberately change things, in which case they keep both pieces). + suite = unittest2.TestSuite([Skips("test_notrun")]) + log = [] + result = LoggingResult(log) + suite.run(result) + self.assertEqual(['addSkip'], [item[0] for item in log]) + + def test_setupclass_upcall(self): + # Note that this is kindof-a-case-test, kindof-suite, because + # setUpClass is linked between them. + class Simples(TestCase): + @classmethod + def setUpClass(cls): + super(Simples, cls).setUpClass() + def test_simple(self): + pass + # Test discovery uses the default suite from unittest2 (unless users + # deliberately change things, in which case they keep both pieces). + suite = unittest2.TestSuite([Simples("test_simple")]) + log = [] + result = LoggingResult(log) + suite.run(result) + self.assertEqual( + ['startTest', 'addSuccess', 'stopTest'], + [item[0] for item in log]) + class TestFixtureSuite(TestCase): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-1.1.0/testtools/tests/test_with_with.py new/testtools-1.5.0/testtools/tests/test_with_with.py --- old/testtools-1.1.0/testtools/tests/test_with_with.py 2013-04-20 07:10:07.000000000 +0200 +++ new/testtools-1.5.0/testtools/tests/test_with_with.py 2014-11-15 10:08:40.000000000 +0100 @@ -86,3 +86,8 @@ pass exc = self.assertRaises(AssertionError, die) self.assertThat(exc.args[0], EndsWith(': foo')) + + +def test_suite(): + from unittest import TestLoader + return TestLoader().loadTestsFromName(__name__) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-1.1.0/testtools/testsuite.py new/testtools-1.5.0/testtools/testsuite.py --- old/testtools-1.1.0/testtools/testsuite.py 2014-08-25 03:43:46.000000000 +0200 +++ new/testtools-1.5.0/testtools/testsuite.py 2014-11-15 21:44:58.000000000 +0100 @@ -14,6 +14,7 @@ import sys import threading import unittest +import unittest2 from extras import safe_hasattr, try_imports @@ -34,7 +35,7 @@ yield subtest -class ConcurrentTestSuite(unittest.TestSuite): +class ConcurrentTestSuite(unittest2.TestSuite): """A TestSuite whose run() calls out to a concurrency strategy.""" def __init__(self, suite, make_tests, wrap_result=None): @@ -197,7 +198,7 @@ process_result.stopTestRun() -class FixtureSuite(unittest.TestSuite): +class FixtureSuite(unittest2.TestSuite): def __init__(self, fixture, tests): super(FixtureSuite, self).__init__(tests) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-1.1.0/testtools.egg-info/PKG-INFO new/testtools-1.5.0/testtools.egg-info/PKG-INFO --- old/testtools-1.1.0/testtools.egg-info/PKG-INFO 2014-09-14 00:54:43.000000000 +0200 +++ new/testtools-1.5.0/testtools.egg-info/PKG-INFO 2014-11-21 00:20:56.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: testtools -Version: 1.1.0 +Version: 1.5.0 Summary: Extensions to the Python standard library unit testing framework Home-page: https://github.com/testing-cabal/testtools Author: Jonathan M. Lange diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-1.1.0/testtools.egg-info/requires.txt new/testtools-1.5.0/testtools.egg-info/requires.txt --- old/testtools-1.1.0/testtools.egg-info/requires.txt 2014-09-14 00:54:43.000000000 +0200 +++ new/testtools-1.5.0/testtools.egg-info/requires.txt 2014-11-21 00:20:56.000000000 +0100 @@ -1,2 +1,3 @@ extras -python-mimeparse \ No newline at end of file +python-mimeparse +unittest2>=0.8.0 \ No newline at end of file -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
