Hello community, here is the log from the commit of package python-testtools for openSUSE:Factory checked in at 2014-01-16 15:13:12 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 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 2013-11-18 10:54:07.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.python-testtools.new/python-testtools.changes 2014-01-16 15:13:13.000000000 +0100 @@ -1,0 +2,14 @@ +Mon Jan 13 13:44:49 UTC 2014 - dmueller@suse.com + +- update to 0.9.34: + * Added ability for ``testtools.TestCase`` instances to force a test to + fail, even if no assertions failed. (Thomi Richards) + * Added ``testtools.content.StacktraceContent``, a content object that + automatically creates a ``StackLinesContent`` object containing the current + stack trace. (Thomi Richards) + * ``AnyMatch`` is now exported properly in ``testtools.matchers``. + (Robert Collins, Rob Kennedy, github #44) + * Network tests now bind to 127.0.0.1 to avoid (even temporary) network + visible ports. (Benedikt Morbach, github #46) + +------------------------------------------------------------------- @@ -11,0 +26,11 @@ + +------------------------------------------------------------------- +Thu Aug 8 13:47:56 UTC 2013 - speilicke@suse.com + +- Revert back + +------------------------------------------------------------------- +Thu Aug 8 13:22:20 UTC 2013 - speilicke@suse.com + +- Totally disable testing to bootstrap ppc64. Actually the build conditional is + supposed to do just that. Old: ---- testtools-0.9.33.tar.gz New: ---- testtools-0.9.34.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-testtools.spec ++++++ --- /var/tmp/diff_new_pack.Xqq9DU/_old 2014-01-16 15:13:14.000000000 +0100 +++ /var/tmp/diff_new_pack.Xqq9DU/_new 2014-01-16 15:13:14.000000000 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-testtools # -# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -21,7 +21,7 @@ %bcond_with tests Name: python-testtools -Version: 0.9.33 +Version: 0.9.34 Release: 0 Summary: Extensions to the Python Standard Library Unit Testing Framework License: MIT ++++++ testtools-0.9.33.tar.gz -> testtools-0.9.34.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-0.9.33/NEWS new/testtools-0.9.34/NEWS --- old/testtools-0.9.33/NEWS 2013-11-06 00:25:07.000000000 +0100 +++ new/testtools-0.9.34/NEWS 2013-11-30 01:57:16.000000000 +0100 @@ -7,6 +7,41 @@ NEXT ~~~~ +0.9.34 +~~~~~~ + +Improvements +------------ + +* Added ability for ``testtools.TestCase`` instances to force a test to + fail, even if no assertions failed. (Thomi Richards) + +* Added ``testtools.content.StacktraceContent``, a content object that + automatically creates a ``StackLinesContent`` object containing the current + stack trace. (Thomi Richards) + +* ``AnyMatch`` is now exported properly in ``testtools.matchers``. + (Robert Collins, Rob Kennedy, github #44) + +* In Python 3.3, if there are duplicate test ids, tests.sort() will + fail and raise TypeError. Detect the duplicate test ids firstly in + sorted_tests() to ensure that all test ids are unique. + (Kui Shi, #1243922) + +* ``json_content`` is now in the ``__all__`` attribute for + ``testtools.content``. (Robert Collins) + +* Network tests now bind to 127.0.0.1 to avoid (even temporary) network + visible ports. (Benedikt Morbach, github #46) + +* Test listing now explicitly indicates by printing 'Failed to import' and + exiting (2) when an import has failed rather than only signalling through the + test name. (Robert Collins, #1245672) + +* ``test_compat.TestDetectEncoding.test_bom`` now works on Python 3.3 - the + corner case with euc_jp is no longer permitted in Python 3.3 so we can + skip it. (Martin [gz], #1251962) + 0.9.33 ~~~~~~ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-0.9.33/PKG-INFO new/testtools-0.9.34/PKG-INFO --- old/testtools-0.9.33/PKG-INFO 2013-11-06 00:29:12.000000000 +0100 +++ new/testtools-0.9.34/PKG-INFO 2013-11-30 02:00:56.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: testtools -Version: 0.9.33 +Version: 0.9.34 Summary: Extensions to the Python standard library unit testing framework Home-page: https://github.com/testing-cabal/testtools Author: Jonathan M. Lange Files old/testtools-0.9.33/doc/.hacking.rst.swp and new/testtools-0.9.34/doc/.hacking.rst.swp differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-0.9.33/doc/for-framework-folk.rst new/testtools-0.9.34/doc/for-framework-folk.rst --- old/testtools-0.9.33/doc/for-framework-folk.rst 2013-04-03 13:32:49.000000000 +0200 +++ new/testtools-0.9.34/doc/for-framework-folk.rst 2013-11-28 09:32:58.000000000 +0100 @@ -82,6 +82,15 @@ instance to one with a new name. This is helpful for implementing test parameterization. +.. _force_failure: + +Delayed Test Failure +-------------------- + +Setting the ``testtools.TestCase.force_failure`` instance variable to True will +cause ``testtools.RunTest`` to fail the test case after the test has finished. +This is useful when you want to cause a test to fail, but don't want to +prevent the remainder of the test code from being executed. Test placeholders ================= @@ -420,6 +429,8 @@ should sort their tests. An example implementation can be seen at ``FixtureSuite.sorted_tests``. +If there are duplicate test ids in a suite, ValueError will be raised. + filter_by_ids ------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-0.9.33/doc/for-framework-folk.rst~ new/testtools-0.9.34/doc/for-framework-folk.rst~ --- old/testtools-0.9.33/doc/for-framework-folk.rst~ 2013-04-01 06:35:03.000000000 +0200 +++ new/testtools-0.9.34/doc/for-framework-folk.rst~ 2013-11-28 09:28:37.000000000 +0100 @@ -82,6 +82,15 @@ instance to one with a new name. This is helpful for implementing test parameterization. +.. _force_failure: + +Delayed Test Failure +-------------------- + +Setting the ``testtools.TestCase.force_failure`` instance variable to True will +cause ``testtools.RunTest`` to fail the test case after the test has finished. +This is useful when you want to cause a test to fail, but don't want to +prevent the remainder of the test code from being executed. Test placeholders ================= @@ -266,7 +275,7 @@ >>> router = StreamResultRouter() >>> sink = doubles.StreamResult() - >>> router.map(sink, 'route_code_prefix', route_prefix='0', + >>> router.add_rule(sink, 'route_code_prefix', route_prefix='0', ... consume_route=True) >>> router.status(test_id='foo', route_code='0/1', test_status='uxsuccess') @@ -411,6 +420,10 @@ sorted_tests ------------ +In Python 3.3, if there are duplicate test ids, tests.sort() will fail and +raise TypeError. Detect the duplicate test ids firstly in sorted_tests() +to ensure that all test ids are unique. + Given the composite structure of TestSuite / TestCase, sorting tests is problematic - you can't tell what functionality is embedded into custom Suite implementations. In order to deliver consistent test orders when using test diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-0.9.33/doc/for-test-authors.rst new/testtools-0.9.34/doc/for-test-authors.rst --- old/testtools-0.9.33/doc/for-test-authors.rst 2013-10-18 04:14:17.000000000 +0200 +++ new/testtools-0.9.34/doc/for-test-authors.rst 2013-11-28 09:28:37.000000000 +0100 @@ -1243,6 +1243,13 @@ ``AsynchronousDeferredRunTest`` does not. If you rely on this behavior, use ``AsynchronousDeferredRunTestForBrokenTwisted``. +force_failure +------------- + +Setting the ``testtools.TestCase.force_failure`` instance variable to ``True`` +will cause the test to be marked as a failure, but won't stop the test code +from running (see :ref:`force_failure`). + Test helpers ============ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-0.9.33/doc/for-test-authors.rst~ new/testtools-0.9.34/doc/for-test-authors.rst~ --- old/testtools-0.9.33/doc/for-test-authors.rst~ 2013-04-04 10:39:03.000000000 +0200 +++ new/testtools-0.9.34/doc/for-test-authors.rst~ 2013-11-28 08:54:45.000000000 +0100 @@ -163,7 +163,8 @@ expect to see raised. The second argument is optional, and can be either a regular expression or a matcher. If it is a regular expression, the ``str()`` of the raised exception must match the regular expression. If it is a matcher, -then the raised exception object must match it. +then the raised exception object must match it. The optional third argument +``msg`` will cause the raised error to be annotated with that message. assertIn, assertNotIn @@ -445,6 +446,18 @@ self.assertThat('foo', MatchesRegex('fo+')) +HasLength +~~~~~~~~~ + +Check the length of a collection. The following assertion will fail:: + + self.assertThat([1, 2, 3], HasLength(2)) + +But this one won't:: + + self.assertThat([1, 2, 3], HasLength(3)) + + File- and path-related matchers ------------------------------- @@ -521,18 +534,6 @@ self.assertThat('greetings.txt', FileContains(matcher=Contains('!'))) -HasLength -~~~~~~~~~ - -Check the length of a collection. The following assertion will fail:: - - self.assertThat([1, 2, 3], HasLength(2)) - -But this one won't:: - - self.assertThat([1, 2, 3], HasLength(3)) - - HasPermissions ~~~~~~~~~~~~~~ @@ -625,7 +626,7 @@ example:: def test_after_preprocessing_example(self): - def HasFileContent(content): + def PathHasFileContent(content): def _read(path): return open(path).read() return AfterPreprocessing(_read, Equals(content)) @@ -806,7 +807,7 @@ matcher based on it:: def test_divisible_numbers(self): - IsDisivibleBy = MatchesPredicateWithParams( + IsDivisibleBy = MatchesPredicateWithParams( divisible, '{0} is not divisible by {1}') self.assertThat(7, IsDivisibleBy(1)) self.assertThat(7, IsDivisibleBy(7)) @@ -879,9 +880,9 @@ def test_is_divisible_by_example(self): # This succeeds, since IsDivisibleBy(5).match(10) returns None. - self.assertThat(10, IsDivisbleBy(5)) + self.assertThat(10, IsDivisibleBy(5)) # This fails, since IsDivisibleBy(7).match(10) returns a mismatch. - self.assertThat(10, IsDivisbleBy(7)) + self.assertThat(10, IsDivisibleBy(7)) The mismatch is responsible for what sort of error message the failing test generates. Here's an example mismatch:: @@ -1242,6 +1243,11 @@ ``AsynchronousDeferredRunTest`` does not. If you rely on this behavior, use ``AsynchronousDeferredRunTestForBrokenTwisted``. +force_failure +------------- + +Setting the ``testtools.TestCase.force_failure`` instance variable to ``True`` will cause the test to be marked as a failure, but won't stop the test code from running (see :ref:`force_failure`). + Test helpers ============ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-0.9.33/doc/hacking.rst new/testtools-0.9.34/doc/hacking.rst --- old/testtools-0.9.33/doc/hacking.rst 2013-02-05 10:58:30.000000000 +0100 +++ new/testtools-0.9.34/doc/hacking.rst 2013-11-28 09:28:37.000000000 +0100 @@ -49,6 +49,21 @@ ``run_tests_with = FullStackRunTest`` to the top of a test's class definition. +Discussion +---------- + +When submitting a patch, it will help the review process a lot if there's a +clear explanation of what the change does and why you think the change is a +good idea. For crasher bugs, this is generally a no-brainer, but for UI bugs +& API tweaks, the reason something is an improvement might not be obvious, so +it's worth spelling out. + +If you are thinking of implementing a new feature, you might want to have that +discussion on the [mailing list](testtools-dev@lists.launchpad.net) before the +patch goes up for review. This is not at all mandatory, but getting feedback +early can help avoid dead ends. + + Documentation ------------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-0.9.33/setup.cfg new/testtools-0.9.34/setup.cfg --- old/testtools-0.9.33/setup.cfg 2013-11-06 00:29:12.000000000 +0100 +++ new/testtools-0.9.34/setup.cfg 2013-11-30 02:00:56.000000000 +0100 @@ -5,6 +5,6 @@ [egg_info] tag_build = -tag_svn_revision = 0 tag_date = 0 +tag_svn_revision = 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-0.9.33/testtools/__init__.py new/testtools-0.9.34/testtools/__init__.py --- old/testtools-0.9.33/testtools/__init__.py 2013-11-06 00:24:48.000000000 +0100 +++ new/testtools-0.9.34/testtools/__init__.py 2013-11-30 01:56:29.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__ = (0, 9, 33, 'final', 0) +__version__ = (0, 9, 34, 'final', 0) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-0.9.33/testtools/content.py new/testtools-0.9.34/testtools/content.py --- old/testtools-0.9.33/testtools/content.py 2013-11-05 01:17:14.000000000 +0100 +++ new/testtools-0.9.34/testtools/content.py 2013-11-28 09:28:37.000000000 +0100 @@ -7,11 +7,13 @@ 'Content', 'content_from_file', 'content_from_stream', + 'json_content', 'text_content', 'TracebackContent', ] import codecs +import inspect import json import os import sys @@ -223,6 +225,36 @@ return StackLinesContent(stack_lines, prefix, postfix) +def StacktraceContent(prefix_content="", postfix_content=""): + """Content object for stack traces. + + 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 + languages can format their stack traces differently. + + :param prefix_content: A unicode string to add before the stack lines. + :param postfix_content: A unicode string to add after the stack lines. + """ + stack = inspect.stack()[1:] + + if StackLinesContent.HIDE_INTERNAL_STACK: + limit = 1 + while limit < len(stack) and '__unittest' not in stack[limit][0].f_globals: + limit += 1 + else: + limit = -1 + + frames_only = [line[0] for line in stack[:limit]] + processed_stack = [ ] + for frame in reversed(frames_only): + filename, line, function, context, _ = inspect.getframeinfo(frame) + context = ''.join(context) + processed_stack.append((filename, line, function, context)) + return StackLinesContent(processed_stack, prefix_content, postfix_content) + + def json_content(json_data): """Create a JSON `Content` object from JSON-encodeable data.""" data = json.dumps(json_data) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-0.9.33/testtools/matchers/__init__.py new/testtools-0.9.34/testtools/matchers/__init__.py --- old/testtools-0.9.33/testtools/matchers/__init__.py 2013-01-26 18:18:27.000000000 +0100 +++ new/testtools-0.9.34/testtools/matchers/__init__.py 2013-11-28 09:28:37.000000000 +0100 @@ -16,6 +16,7 @@ 'AfterPreprocessing', 'AllMatch', 'Annotate', + 'AnyMatch', 'Contains', 'ContainsAll', 'ContainedByDict', @@ -101,6 +102,7 @@ AfterPreprocessing, AllMatch, Annotate, + AnyMatch, MatchesAll, MatchesAny, MatchesPredicate, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-0.9.33/testtools/matchers/_higherorder.py new/testtools-0.9.34/testtools/matchers/_higherorder.py --- old/testtools-0.9.33/testtools/matchers/_higherorder.py 2013-01-26 18:18:32.000000000 +0100 +++ new/testtools-0.9.34/testtools/matchers/_higherorder.py 2013-11-28 09:28:37.000000000 +0100 @@ -4,6 +4,7 @@ 'AfterPreprocessing', 'AllMatch', 'Annotate', + 'AnyMatch', 'MatchesAny', 'MatchesAll', 'Not', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-0.9.33/testtools/run.py new/testtools-0.9.34/testtools/run.py --- old/testtools-0.9.33/testtools/run.py 2013-04-03 13:32:49.000000000 +0200 +++ new/testtools-0.9.34/testtools/run.py 2013-11-28 09:28:37.000000000 +0100 @@ -35,6 +35,31 @@ have_discover = True +def list_test(test): + """Return the test ids that would be run if test() was run. + + When things fail to import they can be represented as well, though + we use an ugly hack (see http://bugs.python.org/issue19746 for details) + to determine that. The difference matters because if a user is + filtering tests to run on the returned ids, a failed import can reduce + the visible tests but it can be impossible to tell that the selected + test would have been one of the imported ones. + + :return: A tuple of test ids that would run and error strings + describing things that failed to import. + """ + unittest_import_str = 'unittest.loader.ModuleImportFailure.' + test_ids = [] + errors = [] + for test in iterate_tests(test): + # to this ugly. + if test.id().startswith(unittest_import_str): + errors.append(test.id()[len(unittest_import_str):]) + else: + test_ids.append(test.id()) + return test_ids, errors + + class TestToolsTestRunner(object): """ A thunk object to support unittest.TestProgram.""" @@ -52,8 +77,14 @@ def list(self, test): """List the tests that would be run if test() was run.""" - for test in iterate_tests(test): - self.stdout.write('%s\n' % test.id()) + test_ids, errors = list_test(test) + for test_id in test_ids: + self.stdout.write('%s\n' % test_id) + if errors: + self.stdout.write('Failed to import\n') + for test_id in errors: + self.stdout.write('%s\n' % test_id) + sys.exit(2) def run(self, test): "Run the given test case or test suite." diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-0.9.33/testtools/runtest.py new/testtools-0.9.34/testtools/runtest.py --- old/testtools-0.9.33/testtools/runtest.py 2013-10-18 04:14:17.000000000 +0200 +++ new/testtools-0.9.34/testtools/runtest.py 2013-11-28 09:28:37.000000000 +0100 @@ -135,6 +135,9 @@ self._run_cleanups, self.result): failed = True finally: + if getattr(self.case, 'force_failure', None): + self._run_user(_raise_force_fail_error) + failed = True if not failed: self.result.addSuccess(self.case, details=self.case.getDetails()) @@ -200,6 +203,10 @@ raise e +def _raise_force_fail_error(): + raise AssertionError("Forced Test Failure") + + # Signal that this is part of the testing framework, and that code from this # should not normally appear in tracebacks. __unittest = True diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-0.9.33/testtools/testcase.py new/testtools-0.9.34/testtools/testcase.py --- old/testtools-0.9.33/testtools/testcase.py 2013-10-18 04:14:44.000000000 +0200 +++ new/testtools-0.9.34/testtools/testcase.py 2013-11-28 09:28:37.000000000 +0100 @@ -155,6 +155,8 @@ :ivar exception_handlers: Exceptions to catch from setUp, runTest and tearDown. This list is able to be modified at any time and consists of (exception_class, handler(case, result, exception_value)) pairs. + :ivar force_failure: Force testtools.RunTest to fail the test after the + test has completed. :cvar run_tests_with: A factory to make the ``RunTest`` to run tests with. Defaults to ``RunTest``. The factory is expected to take a test case and an optional list of exception handlers. @@ -924,7 +926,7 @@ def __getattr__(self, name): return getattr(self.decorated, name) - + def __delattr__(self, name): delattr(self.decorated, name) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-0.9.33/testtools/testresult/real.py new/testtools-0.9.34/testtools/testresult/real.py --- old/testtools-0.9.33/testtools/testresult/real.py 2013-11-05 01:17:27.000000000 +0100 +++ new/testtools-0.9.34/testtools/testresult/real.py 2013-11-28 09:28:37.000000000 +0100 @@ -377,7 +377,7 @@ and discarded. Ignored unless file_name has been supplied. :param mime_type: An optional MIME type for the file. stdout and stderr will generally be "text/plain; charset=utf8". If None, - defaults to application/octet-stream. Ignores unless file_name + defaults to application/octet-stream. Ignored unless file_name has been supplied. """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-0.9.33/testtools/tests/test_compat.py new/testtools-0.9.34/testtools/tests/test_compat.py --- old/testtools-0.9.33/testtools/tests/test_compat.py 2013-10-26 09:34:54.000000000 +0200 +++ new/testtools-0.9.34/testtools/tests/test_compat.py 2013-11-29 23:52:10.000000000 +0100 @@ -113,7 +113,8 @@ '\xef\xbb\xbfThose should be latin-1 bytes"""\n')) self._check_encoding("utf-8", ( "\xef\xbb\xbf# Is the coding: utf-8 or coding: euc-jp instead?\n", - '"""Module docstring say \xe2\x98\x86"""\n')) + '"""Module docstring say \xe2\x98\x86"""\n'), + possibly_invalid=True) def test_multiple_coding_comments(self): """Test only the first of multiple coding declarations counts""" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-0.9.33/testtools/tests/test_content.py new/testtools-0.9.34/testtools/tests/test_content.py --- old/testtools-0.9.33/testtools/tests/test_content.py 2013-11-05 01:17:14.000000000 +0100 +++ new/testtools-0.9.34/testtools/tests/test_content.py 2013-11-28 09:28:37.000000000 +0100 @@ -20,6 +20,7 @@ JSON, json_content, StackLinesContent, + StacktraceContent, TracebackContent, text_content, ) @@ -254,6 +255,33 @@ self.assertEqual(expected, ''.join(list(content.iter_text()))) +class TestStacktraceContent(TestCase): + + def test___init___sets_ivars(self): + content = StacktraceContent() + content_type = ContentType("text", "x-traceback", + {"language": "python", "charset": "utf8"}) + + self.assertEqual(content_type, content.content_type) + + def test_prefix_is_used(self): + prefix = self.getUniqueString() + actual = StacktraceContent(prefix_content=prefix).as_text() + + self.assertTrue(actual.startswith(prefix)) + + def test_postfix_is_used(self): + postfix = self.getUniqueString() + actual = StacktraceContent(postfix_content=postfix).as_text() + + self.assertTrue(actual.endswith(postfix)) + + def test_top_frame_is_skipped_when_no_stack_is_specified(self): + actual = StacktraceContent().as_text() + + self.assertTrue('testtools/content.py' not in actual) + + class TestAttachFile(TestCase): def make_file(self, data): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-0.9.33/testtools/tests/test_deferredruntest.py new/testtools-0.9.34/testtools/tests/test_deferredruntest.py --- old/testtools-0.9.33/testtools/tests/test_deferredruntest.py 2013-01-26 18:18:27.000000000 +0100 +++ new/testtools-0.9.34/testtools/tests/test_deferredruntest.py 2013-11-28 09:28:37.000000000 +0100 @@ -546,7 +546,7 @@ self.addCleanup(lambda: 3 / 0) # Dirty the reactor. from twisted.internet.protocol import ServerFactory - reactor.listenTCP(0, ServerFactory()) + reactor.listenTCP(0, ServerFactory(), interface='127.0.0.1') # Unhandled error. defer.maybeDeferred(lambda: 2 / 0) # Actual error. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-0.9.33/testtools/tests/test_run.py new/testtools-0.9.34/testtools/tests/test_run.py --- old/testtools-0.9.33/testtools/tests/test_run.py 2013-04-03 13:32:49.000000000 +0200 +++ new/testtools-0.9.34/testtools/tests/test_run.py 2013-11-28 09:28:37.000000000 +0100 @@ -3,6 +3,7 @@ """Tests for the test runner logic.""" from unittest import TestSuite +import sys from extras import try_import fixtures = try_import('fixtures') @@ -21,9 +22,13 @@ class SampleTestFixture(fixtures.Fixture): """Creates testtools.runexample temporarily.""" - def __init__(self): - self.package = fixtures.PythonPackage( - 'runexample', [('__init__.py', _b(""" + def __init__(self, broken=False): + """Create a SampleTestFixture. + + :param broken: If True, the sample file will not be importable. + """ + if not broken: + init_contents = _b("""\ from testtools import TestCase class TestFoo(TestCase): @@ -34,13 +39,18 @@ def test_suite(): from unittest import TestLoader return TestLoader().loadTestsFromName(__name__) -"""))]) +""") + else: + init_contents = b"class not in\n" + self.package = fixtures.PythonPackage( + 'runexample', [('__init__.py', init_contents)]) def setUp(self): super(SampleTestFixture, self).setUp() self.useFixture(self.package) testtools.__path__.append(self.package.base) self.addCleanup(testtools.__path__.remove, self.package.base) + self.addCleanup(sys.modules.pop, 'testtools.runexample', None) if fixtures and testresources: @@ -105,20 +115,41 @@ tests.append(set([case.id() for case in testtools.testsuite.iterate_tests(test)])) out = StringIO() - program = run.TestProgram( - argv=['prog', '-l', 'testtools.runexample.test_suite'], - stdout=out, testRunner=CaptureList) + 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'])], tests) def test_run_list(self): self.useFixture(SampleTestFixture()) out = StringIO() - run.main(['prog', '-l', 'testtools.runexample.test_suite'], out) + try: + run.main(['prog', '-l', 'testtools.runexample.test_suite'], out) + except SystemExit: + exc_info = sys.exc_info() + raise AssertionError("-l tried to exit. %r" % exc_info[1]) self.assertEqual("""testtools.runexample.TestFoo.test_bar testtools.runexample.TestFoo.test_quux """, 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() + 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.__init__ +""", out.getvalue()) + def test_run_orders_tests(self): self.useFixture(SampleTestFixture()) out = StringIO() @@ -135,8 +166,12 @@ """)) finally: f.close() - run.main(['prog', '-l', '--load-list', tempname, - 'testtools.runexample.test_suite'], out) + try: + run.main(['prog', '-l', '--load-list', tempname, + 'testtools.runexample.test_suite'], out) + except SystemExit: + exc_info = sys.exc_info() + raise AssertionError("-l tried to exit. %r" % exc_info[1]) self.assertEqual("""testtools.runexample.TestFoo.test_bar """, out.getvalue()) @@ -156,8 +191,12 @@ """)) finally: f.close() - run.main(['prog', '-l', '--load-list', tempname, - 'testtools.runexample.test_suite'], out) + try: + run.main(['prog', '-l', '--load-list', tempname, + 'testtools.runexample.test_suite'], out) + except SystemExit: + exc_info = sys.exc_info() + raise AssertionError("-l tried to exit. %r" % exc_info[1]) self.assertEqual("""testtools.runexample.TestFoo.test_bar """, out.getvalue()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-0.9.33/testtools/tests/test_spinner.py new/testtools-0.9.34/testtools/tests/test_spinner.py --- old/testtools-0.9.33/testtools/tests/test_spinner.py 2013-01-26 18:18:27.000000000 +0100 +++ new/testtools-0.9.34/testtools/tests/test_spinner.py 2013-11-28 09:28:37.000000000 +0100 @@ -232,7 +232,7 @@ from twisted.internet.protocol import ServerFactory reactor = self.make_reactor() spinner = self.make_spinner(reactor) - port = reactor.listenTCP(0, ServerFactory()) + port = reactor.listenTCP(0, ServerFactory(), interface='127.0.0.1') spinner.run(self.make_timeout(), lambda: None) results = spinner.get_junk() self.assertThat(results, Equals([port])) @@ -262,7 +262,7 @@ reactor = self.make_reactor() spinner = self.make_spinner(reactor) port = spinner.run( - self.make_timeout(), reactor.listenTCP, 0, ServerFactory()) + self.make_timeout(), reactor.listenTCP, 0, ServerFactory(), interface='127.0.0.1') self.assertThat(spinner.get_junk(), Equals([port])) def test_will_not_run_with_previous_junk(self): @@ -272,7 +272,7 @@ reactor = self.make_reactor() spinner = self.make_spinner(reactor) timeout = self.make_timeout() - spinner.run(timeout, reactor.listenTCP, 0, ServerFactory()) + spinner.run(timeout, reactor.listenTCP, 0, ServerFactory(), interface='127.0.0.1') self.assertThat(lambda: spinner.run(timeout, lambda: None), Raises(MatchesException(_spinner.StaleJunkError))) @@ -283,7 +283,7 @@ reactor = self.make_reactor() spinner = self.make_spinner(reactor) timeout = self.make_timeout() - port = spinner.run(timeout, reactor.listenTCP, 0, ServerFactory()) + port = spinner.run(timeout, reactor.listenTCP, 0, ServerFactory(), interface='127.0.0.1') junk = spinner.clear_junk() self.assertThat(junk, Equals([port])) self.assertThat(spinner.get_junk(), Equals([])) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-0.9.33/testtools/tests/test_testcase.py new/testtools-0.9.34/testtools/tests/test_testcase.py --- old/testtools-0.9.33/testtools/tests/test_testcase.py 2013-10-18 04:14:44.000000000 +0200 +++ new/testtools-0.9.34/testtools/tests/test_testcase.py 2013-11-28 09:28:37.000000000 +0100 @@ -569,6 +569,16 @@ self.assertFails( expected, self.assertThat, matchee, matcher, verbose=True) + def test__force_failure_fails_test(self): + class Test(TestCase): + def test_foo(self): + self.force_failure = True + self.remaining_code_run = True + test = Test('test_foo') + result = test.run() + self.assertFalse(result.wasSuccessful()) + self.assertTrue(test.remaining_code_run) + def get_error_string(self, e): """Get the string showing how 'e' would be formatted in test output. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-0.9.33/testtools/tests/test_testsuite.py new/testtools-0.9.34/testtools/tests/test_testsuite.py --- old/testtools-0.9.33/testtools/tests/test_testsuite.py 2013-04-03 07:55:59.000000000 +0200 +++ new/testtools-0.9.34/testtools/tests/test_testsuite.py 2013-11-28 09:32:58.000000000 +0100 @@ -224,6 +224,19 @@ suite.run(LoggingResult([])) self.assertEqual(['setUp', 1, 2, 'tearDown'], log) + def test_fixture_suite_sort(self): + log = [] + class Sample(TestCase): + def test_one(self): + log.append(1) + def test_two(self): + log.append(2) + fixture = FunctionFixture( + lambda: log.append('setUp'), + lambda fixture: log.append('tearDown')) + suite = FixtureSuite(fixture, [Sample('test_one'), Sample('test_one')]) + self.assertRaises(ValueError, suite.sort_tests) + class TestSortedTests(TestCase): @@ -253,6 +266,13 @@ suite = sorted_tests(unittest.TestSuite([b, a])) self.assertEqual([a, b], list(iterate_tests(suite))) + def test_duplicate_simple_suites(self): + a = PlaceHolder('a') + b = PlaceHolder('b') + c = PlaceHolder('a') + self.assertRaises( + ValueError, sorted_tests, unittest.TestSuite([a, b, c])) + def test_suite(): from unittest import TestLoader diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-0.9.33/testtools/testsuite.py new/testtools-0.9.34/testtools/testsuite.py --- old/testtools-0.9.33/testtools/testsuite.py 2013-04-03 07:55:59.000000000 +0200 +++ new/testtools-0.9.34/testtools/testsuite.py 2013-11-28 09:32:58.000000000 +0100 @@ -303,6 +303,15 @@ def sorted_tests(suite_or_case, unpack_outer=False): """Sort suite_or_case while preserving non-vanilla TestSuites.""" + # Duplicate test id can induce TypeError in Python 3.3. + # Detect the duplicate test id, raise exception when found. + seen = set() + for test_case in iterate_tests(suite_or_case): + test_id = test_case.id() + if test_id not in seen: + seen.add(test_id) + else: + raise ValueError('Duplicate test id detected: %s' % (test_id,)) tests = _flatten_tests(suite_or_case, unpack_outer=unpack_outer) tests.sort() return unittest.TestSuite([test for (sort_key, test) in tests]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/testtools-0.9.33/testtools.egg-info/PKG-INFO new/testtools-0.9.34/testtools.egg-info/PKG-INFO --- old/testtools-0.9.33/testtools.egg-info/PKG-INFO 2013-11-06 00:29:12.000000000 +0100 +++ new/testtools-0.9.34/testtools.egg-info/PKG-INFO 2013-11-30 02:00:56.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: testtools -Version: 0.9.33 +Version: 0.9.34 Summary: Extensions to the Python standard library unit testing framework Home-page: https://github.com/testing-cabal/testtools Author: Jonathan M. Lange -- To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org