Hello community,

here is the log from the commit of package python-rednose for openSUSE:Factory 
checked in at 2017-11-16 14:02:53
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-rednose (Old)
 and      /work/SRC/openSUSE:Factory/.python-rednose.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-rednose"

Thu Nov 16 14:02:53 2017 rev:2 rq:542116 version:1.2.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-rednose/python-rednose.changes    
2015-06-12 20:30:18.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.python-rednose.new/python-rednose.changes       
2017-11-16 14:02:58.361367394 +0100
@@ -1,0 +2,45 @@
+Wed Nov 15 08:32:40 UTC 2017 - [email protected]
+
+- update to version 1.2.3
+  + Fix bug when switching between python 2 and 3 using node ids.
+  + Added stream flush after every write to make sure dots
+    are printed right after a test is executed.
+
+-------------------------------------------------------------------
+Tue Oct 24 10:44:28 UTC 2017 - [email protected]
+
+- convert to single spec file
+
+-------------------------------------------------------------------
+Tue Oct 24 10:31:57 UTC 2017 - [email protected]
+
+- add python-colorama to the Requires
+
+-------------------------------------------------------------------
+Tue Oct 24 10:23:33 UTC 2017 - [email protected]
+
+- Update to version 1.2.2
+  + Fix bug for skips raised in setUpClass (issue #9).
+- Update to version 1.2.1
+  + In python 2.7+ label skips as skip tests.
+  + Change skip test exception coloring to blue.
+- Update to version 1.1.1
+  + Fix for immediate broken with recent release when I switched API
+    ussage and removed an function.
+- Update to version 1.1.0
+  + Update tests for better reporting 
+  + fix for errors during module setup (issue #1)
+  + Better support for skips
+  + Introduce proper printing for skipped tests as well as the
+    ability to supress them using --hide-skips
+  + Test with python 3.4
+- Update to version 1.1.0
+  + !Major Changes!
+  + This release completely changes the way in which color test
+    results are printed. It now attmepts to override the code which
+    nose uses to print results rather than to supress those results
+    and print them seperatly.
+  + Package maintainer changes to JBKahn
+  + Use travis for testing
+
+-------------------------------------------------------------------

Old:
----
  rednose-0.4.1.tar.gz

New:
----
  rednose-1.2.3.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-rednose.spec ++++++
--- /var/tmp/diff_new_pack.JhFnA7/_old  2017-11-16 14:02:59.253335068 +0100
+++ /var/tmp/diff_new_pack.JhFnA7/_new  2017-11-16 14:02:59.261334778 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-rednose
 #
-# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
 # Copyright (c) 2012 Weberhofer GmbH, Austria
 #
 # All modifications and additions to the file contributed by third parties
@@ -17,24 +17,25 @@
 #
 
 
+%{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-rednose
-Version:        0.4.1
+Version:        1.2.3
 Release:        0
 Summary:        Pretty output formatter for python-nosetests
 License:        BSD-3-Clause
 Group:          Development/Languages/Python
 Url:            https://pypi.python.org/pypi/rednose/
-Source0:        
https://pypi.python.org/packages/source/r/rednose/rednose-%{version}.tar.gz
-BuildRequires:  python-devel
-BuildRequires:  python-setuptools
+Source0:        
https://files.pythonhosted.org/packages/source/r/rednose/rednose-%{version}.tar.gz
+BuildRequires:  %{python_module devel}
+BuildRequires:  %{python_module setuptools}
+BuildRequires:  fdupes
+BuildRequires:  python-rpm-macros
+Requires:       python-colorama
 Requires:       python-nose
 Requires:       python-termstyle
 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()")}
-%else
 BuildArch:      noarch
-%endif
+%python_subpackages
 
 %description
 Rednose is a nosetests plugin for adding colour (and readability) to nosetest 
console results.
@@ -43,13 +44,14 @@
 %setup -q -n rednose-%{version}
 
 %build
-python setup.py build
+%python_build
 
 %install
-python setup.py install --prefix=%{_prefix} --root=%{buildroot}
+%python_install
+%python_expand %fdupes %{buildroot}%{$python_sitelib}
 
-%files
+%files %{python_files}
 %defattr(-,root,root,-)
-%{python_sitelib}
+%{python_sitelib}/*
 
 %changelog

++++++ rednose-0.4.1.tar.gz -> rednose-1.2.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rednose-0.4.1/PKG-INFO new/rednose-1.2.3/PKG-INFO
--- old/rednose-0.4.1/PKG-INFO  2013-08-30 10:11:56.000000000 +0200
+++ new/rednose-1.2.3/PKG-INFO  2017-11-05 18:55:39.000000000 +0100
@@ -1,35 +1,34 @@
 Metadata-Version: 1.1
 Name: rednose
-Version: 0.4.1
+Version: 1.2.3
 Summary: coloured output for nosetests
-Home-page: http://gfxmonk.net/dist/0install/rednose.xml
+Home-page: https://github.com/JBKahn/rednose
 Author: UNKNOWN
 Author-email: UNKNOWN
 License: BSD
-Description: 
-        **Note**: This package has been built automatically by
-        `zero2pypi <http://gfxmonk.net/dist/0install/zero2pypi.xml>`_.
-        If possible, you should use the zero-install feed instead:
-        http://gfxmonk.net/dist/0install/rednose.xml
-        
-        ----------------
-        
-        =========
+Description-Content-Type: UNKNOWN
+Description: =========
         rednose
         =========
         
         rednose is a `nosetests`_
         plugin for adding colour (and readability) to nosetest console results.
         
+        .. image:: rednose_example.png
+               :scale: 50 %
+               :align: center
+        
         Installation:
         -------------
         ::
         
-               easy_install rednose
+               pip install rednose
                
         or from the source::
         
-               ./setup.py develop
+               python setup.py install
+        
+        Rednose officially supports Python 2.7, 3.4, and 3.5.
         
         Usage:
         ------
@@ -51,6 +50,22 @@
         
         (you can also control this by setting the environment variable 
NOSE_REDNOSE_COLOR to 'force' or 'no')
         
+        Rednose by default prints file paths relative to the working
+        directory. If you want the full path in the traceback then
+        use::
+        
+               nosetests --rednose --full-file-path
+        
+        Rednose by default prints error style formating for skipped tests,
+        to supress this use::
+        
+               nosetests --rednose --hide-skips
+        
+        Rednose supports printing the test results mid run as well as at
+        the end, to enable it use::
+        
+               nosetests --rednose --immediate
+        
         .. _nosetests: http://somethingaboutorange.com/mrl/projects/nose/
         
 Keywords: test nosetests nose nosetest output colour console
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rednose-0.4.1/rednose.egg-info/PKG-INFO 
new/rednose-1.2.3/rednose.egg-info/PKG-INFO
--- old/rednose-0.4.1/rednose.egg-info/PKG-INFO 2013-08-30 10:11:53.000000000 
+0200
+++ new/rednose-1.2.3/rednose.egg-info/PKG-INFO 2017-11-05 18:55:39.000000000 
+0100
@@ -1,35 +1,34 @@
 Metadata-Version: 1.1
 Name: rednose
-Version: 0.4.1
+Version: 1.2.3
 Summary: coloured output for nosetests
-Home-page: http://gfxmonk.net/dist/0install/rednose.xml
+Home-page: https://github.com/JBKahn/rednose
 Author: UNKNOWN
 Author-email: UNKNOWN
 License: BSD
-Description: 
-        **Note**: This package has been built automatically by
-        `zero2pypi <http://gfxmonk.net/dist/0install/zero2pypi.xml>`_.
-        If possible, you should use the zero-install feed instead:
-        http://gfxmonk.net/dist/0install/rednose.xml
-        
-        ----------------
-        
-        =========
+Description-Content-Type: UNKNOWN
+Description: =========
         rednose
         =========
         
         rednose is a `nosetests`_
         plugin for adding colour (and readability) to nosetest console results.
         
+        .. image:: rednose_example.png
+               :scale: 50 %
+               :align: center
+        
         Installation:
         -------------
         ::
         
-               easy_install rednose
+               pip install rednose
                
         or from the source::
         
-               ./setup.py develop
+               python setup.py install
+        
+        Rednose officially supports Python 2.7, 3.4, and 3.5.
         
         Usage:
         ------
@@ -51,6 +50,22 @@
         
         (you can also control this by setting the environment variable 
NOSE_REDNOSE_COLOR to 'force' or 'no')
         
+        Rednose by default prints file paths relative to the working
+        directory. If you want the full path in the traceback then
+        use::
+        
+               nosetests --rednose --full-file-path
+        
+        Rednose by default prints error style formating for skipped tests,
+        to supress this use::
+        
+               nosetests --rednose --hide-skips
+        
+        Rednose supports printing the test results mid run as well as at
+        the end, to enable it use::
+        
+               nosetests --rednose --immediate
+        
         .. _nosetests: http://somethingaboutorange.com/mrl/projects/nose/
         
 Keywords: test nosetests nose nosetest output colour console
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rednose-0.4.1/rednose.egg-info/SOURCES.txt 
new/rednose-1.2.3/rednose.egg-info/SOURCES.txt
--- old/rednose-0.4.1/rednose.egg-info/SOURCES.txt      2013-08-30 
10:11:53.000000000 +0200
+++ new/rednose-1.2.3/rednose.egg-info/SOURCES.txt      2017-11-05 
18:55:39.000000000 +0100
@@ -5,4 +5,11 @@
 rednose.egg-info/dependency_links.txt
 rednose.egg-info/entry_points.txt
 rednose.egg-info/requires.txt
-rednose.egg-info/top_level.txt
\ No newline at end of file
+rednose.egg-info/top_level.txt
+test_files/__init__.py
+test_files/basic_test_suite.py
+test_files/class_test_failure.py
+test_files/encoding_test.py
+test_files/encoding_test_with_literals.py
+test_files/new_tests.py
+test_files/sample_test.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rednose-0.4.1/rednose.egg-info/requires.txt 
new/rednose-1.2.3/rednose.egg-info/requires.txt
--- old/rednose-0.4.1/rednose.egg-info/requires.txt     2013-08-30 
10:11:53.000000000 +0200
+++ new/rednose-1.2.3/rednose.egg-info/requires.txt     2017-11-05 
18:55:39.000000000 +0100
@@ -1,2 +1,3 @@
 setuptools
-python-termstyle >=0.1.7
\ No newline at end of file
+termstyle>=0.1.7
+colorama
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rednose-0.4.1/rednose.egg-info/top_level.txt 
new/rednose-1.2.3/rednose.egg-info/top_level.txt
--- old/rednose-0.4.1/rednose.egg-info/top_level.txt    2013-08-30 
10:11:53.000000000 +0200
+++ new/rednose-1.2.3/rednose.egg-info/top_level.txt    2017-11-05 
18:55:39.000000000 +0100
@@ -1 +1,2 @@
 rednose
+test_files
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rednose-0.4.1/rednose.py new/rednose-1.2.3/rednose.py
--- old/rednose-0.4.1/rednose.py        2013-08-14 05:43:22.000000000 +0200
+++ new/rednose-1.2.3/rednose.py        2017-11-05 18:55:20.000000000 +0100
@@ -1,9 +1,9 @@
 # Copyright (c) 2009, Tim Cuthbertson # All rights reserved.
-# 
+#
 # Redistribution and use in source and binary forms, with or without
 # modification, are permitted provided that the following conditions
 # are met:
-# 
+#
 #     * Redistributions of source code must retain the above copyright
 #       notice, this list of conditions and the following disclaimer.
 #     * Redistributions in binary form must reproduce the above
@@ -13,7 +13,7 @@
 #     * Neither the name of the organisation nor the names of its
 #       contributors may be used to endorse or promote products derived
 #       from this software without specific prior written permission.
-# 
+#
 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
@@ -32,356 +32,423 @@
 import sys
 import linecache
 import re
-import time
 
 import nose
-
 import termstyle
 
+PY3 = sys.version_info[0] >= 3
+if PY3:
+    to_unicode = str
+else:
+    def to_unicode(s):
+        try:
+            return unicode(s)
+        except UnicodeDecodeError:
+            s = str(s)
+            try:
+                # try utf-8, the most likely case
+                return unicode(s, 'UTF-8')
+            except UnicodeDecodeError:
+                # Can't decode, just use `repr`
+                return unicode(repr(s))
+
+
 failure = 'FAILED'
 error = 'ERROR'
 success = 'passed'
 skip = 'skipped'
+expected_failure = 'expected failure'
+unexpected_success = 'unexpected success'
 line_length = 77
 
-PY3 = sys.version_info[0] >= 3
-if PY3:
-       to_unicode = str
-else:
-       def to_unicode(s):
-               try:
-                       return unicode(s)
-               except UnicodeDecodeError:
-                       return unicode(repr(str(s)))
-
-BLACKLISTED_WRITERS = [
-       'nose[\\/]result\\.pyc?$',
-       'unittest[\\/]runner\\.pyc?$'
-]
-REDNOSE_DEBUG = False
-
 
 class RedNose(nose.plugins.Plugin):
-       env_opt = 'NOSE_REDNOSE'
-       env_opt_color = 'NOSE_REDNOSE_COLOR'
-       score = 199  # just under the `coverage` module
-
-       def __init__(self, *args):
-               super(RedNose, self).__init__(*args)
-               self.reports = []
-               self.error = self.success = self.failure = self.skip = 0
-               self.total = 0
-               self.stream = None
-               self.verbose = False
-               self.enabled = False
-               self.tree = False
-
-       def options(self, parser, env=os.environ):
-               global REDNOSE_DEBUG
-               rednose_on = bool(env.get(self.env_opt, False))
-               rednose_color = env.get(self.env_opt_color, 'auto')
-               REDNOSE_DEBUG = bool(env.get('REDNOSE_DEBUG', False))
-
-               parser.add_option(
-                       "--rednose",
-                       action="store_true",
-                       default=rednose_on,
-                       dest="rednose",
-                       help="enable colour output (alternatively, set $%s=1)" 
% (self.env_opt,)
-               )
-               parser.add_option(
-                       "--no-color",
-                       action="store_false",
-                       dest="rednose",
-                       help="disable colour output"
-               )
-               parser.add_option(
-                       "--force-color",
-                       action="store_const",
-                       dest='rednose_color',
-                       default=rednose_color,
-                       const='force',
-                       help="force colour output when not using a TTY 
(alternatively, set $%s=force)" % (self.env_opt_color,)
-               )
-               parser.add_option(
-                       "--immediate",
-                       action="store_true",
-                       default=False,
-                       help="print errors and failures as they happen, as well 
as at the end"
-               )
-
-       def configure(self, options, conf):
-               if options.rednose:
-                       self.enabled = True
-                       termstyle_init = {
-                               'force': termstyle.enable,
-                               'off': termstyle.disable
-                       }.get(options.rednose_color, termstyle.auto)
-                       termstyle_init()
-
-                       self.immediate = options.immediate
-                       self.verbose = options.verbosity >= 2
-
-       def begin(self):
-               self.start_time = time.time()
-               self._in_test = False
-
-       def _format_test_name(self, test):
-               return test.shortDescription() or to_unicode(test)
-
-       def prepareTestResult(self, result):
-               result.stream = FilteringStream(self.stream, 
BLACKLISTED_WRITERS)
-
-       def beforeTest(self, test):
-               self._in_test = True
-               if self.verbose:
-                       self._out(self._format_test_name(test) + ' ... ')
-
-       def afterTest(self, test):
-               if self._in_test:
-                       self.addSkip()
-
-       def _print_test(self, type_, color):
-               self.total += 1
-               if self.verbose:
-                       self._outln(color(type_))
-               else:
-                       if type_ == failure:
-                               short_ = 'F'
-                       elif type_ == error:
-                               short_ = 'X'
-                       elif type_ == skip:
-                               short_ = '-'
-                       else:
-                               short_ = '.'
-                       self._out(color(short_))
-                       if self.total % line_length == 0:
-                               self._outln()
-               self._in_test = False
-
-       def _add_report(self, report):
-               failure_type, test, err = report
-               self.reports.append(report)
-               if self.immediate:
-                       self._outln()
-                       self._report_test(len(self.reports), *report)
-
-       def addFailure(self, test, err):
-               self.failure += 1
-               self._add_report((failure, test, err))
-               self._print_test(failure, termstyle.red)
-
-       def addError(self, test, err):
-               if err[0].__name__ == 'SkipTest':
-                       self.addSkip(test, err)
-                       return
-               self.error += 1
-               self._add_report((error, test, err))
-               self._print_test(error, termstyle.yellow)
-
-       def addSuccess(self, test):
-               self.success += 1
-               self._print_test(success, termstyle.green)
-
-       def addSkip(self, test=None, err=None):
-               self.skip += 1
-               self._print_test(skip, termstyle.blue)
-
-       def setOutputStream(self, stream):
-               self.stream = stream
-
-       def report(self, stream):
-               """report on all registered failures and errors"""
-               self._outln()
-               if self.immediate:
-                       for x in range(0, 5):
-                               self._outln()
-               report_num = 0
-               if len(self.reports) > 0:
-                       for report_num, report in enumerate(self.reports):
-                               self._report_test(report_num + 1, *report)
-                       self._outln()
-
-               self._summarize()
-
-       def _summarize(self):
-               """summarize all tests - the number of failures, errors and 
successes"""
-               self._line(termstyle.black)
-               self._out("%s test%s run in %0.1f seconds" % (
-                       self.total,
-                       self._plural(self.total),
-                       time.time() - self.start_time))
-               if self.total > self.success:
-                       self._outln(". ")
-                       additionals = []
-                       if self.failure > 0:
-                               additionals.append(termstyle.red("%s FAILED" % (
-                                       self.failure,)))
-                       if self.error > 0:
-                               additionals.append(termstyle.yellow("%s 
error%s" % (
-                                       self.error,
-                                       self._plural(self.error) )))
-                       if self.skip > 0:
-                               additionals.append(termstyle.blue("%s skipped" 
% (
-                                       self.skip)))
-                       self._out(', '.join(additionals))
-                               
-               self._out(termstyle.green(" (%s test%s passed)" % (
-                       self.success,
-                       self._plural(self.success) )))
-               self._outln()
-
-       def _report_test(self, report_num, type_, test, err):
-               """report the results of a single (failing or errored) test"""
-               self._line(termstyle.black)
-               self._out("%s) " % (report_num))
-               if type_ == failure:
-                       color = termstyle.red
-                       self._outln(color('FAIL: %s' % 
(self._format_test_name(test),)))
-               else:
-                       color = termstyle.yellow
-                       self._outln(color('ERROR: %s' % 
(self._format_test_name(test),)))
-
-               exc_type, exc_instance, exc_trace = err
-
-               self._outln()
-               self._outln(self._fmt_traceback(exc_trace))
-               self._out(color('   ', 
termstyle.bold(color(exc_type.__name__)), ": "))
-               self._outln(self._fmt_message(exc_instance, color))
-               self._outln()
-
-       def _relative_path(self, path):
-               """
-               If path is a child of the current working directory, the 
relative
-               path is returned surrounded by bold xterm escape sequences.
-               If path is not a child of the working directory, path is 
returned
-               """
-               try:
-                       here = os.path.abspath(os.path.realpath(os.getcwd()))
-                       fullpath = os.path.abspath(os.path.realpath(path))
-               except OSError:
-                       return path
-               if fullpath.startswith(here):
-                       return termstyle.bold(fullpath[len(here)+1:])
-               return path
-
-       def _file_line(self, tb):
-               """formats the file / lineno / function line of a traceback 
element"""
-               prefix = "file://"
-               prefix = ""
-
-               f = tb.tb_frame
-               if '__unittest' in f.f_globals:
-                       # this is the magical flag that prevents unittest 
internal
-                       # code from junking up the stacktrace
-                       return None
-
-               filename = f.f_code.co_filename
-               lineno = tb.tb_lineno
-               linecache.checkcache(filename)
-               function_name = f.f_code.co_name
-
-               line_contents = linecache.getline(filename, lineno, 
f.f_globals).strip()
-
-               return "    %s line %s in %s\n      %s" % (
-                       termstyle.blue(prefix, self._relative_path(filename)),
-                       lineno,
-                       termstyle.cyan(function_name),
-                       line_contents)
-
-       def _fmt_traceback(self, trace):
-               """format a traceback"""
-               ret = []
-               ret.append(termstyle.default("   Traceback (most recent call 
last):"))
-               current_trace = trace
-               while current_trace is not None:
-                       line = self._file_line(current_trace)
-                       if line is not None:
-                               ret.append(line)
-                       current_trace = current_trace.tb_next
-               return '\n'.join(ret)
-       
-       def _fmt_message(self, exception, color):
-               orig_message_lines = to_unicode(exception).splitlines()
-
-               if len(orig_message_lines) == 0:
-                       return ''
-               message_lines = [color(orig_message_lines[0])]
-               for line in orig_message_lines[1:]:
-                       match = re.match('^---.* begin captured stdout.*----$', 
line)
-                       if match:
-                               color = None
-                               message_lines.append('')
-                       line = '   ' + line
-                       message_lines.append(color(line) if color is not None 
else line)
-               return '\n'.join(message_lines)
-
-       def _out(self, msg='', newline=False):
-               self.stream.write(msg)
-               if newline:
-                       self.stream.write('\n')
-
-       def _outln(self, msg=''):
-               self._out(msg, True)
-
-       def _plural(self, num):
-               return '' if num == 1 else 's'
-
-       def _line(self, color=termstyle.reset, char='-'):
-               """
-               print a line of separator characters (default '-')
-               in the given colour (default black)
-               """
-               self._outln(color(char * line_length))
-
+    env_opt = 'NOSE_REDNOSE'
+    env_opt_color = 'NOSE_REDNOSE_COLOR'
 
-import traceback
-import sys
+    def __init__(self, *args):
+        super(RedNose, self).__init__(*args)
+        self.enabled = False
+
+    def options(self, parser, env=os.environ):
+        rednose_on = bool(env.get(self.env_opt, False))
+        rednose_color = env.get(self.env_opt_color, 'auto')
+
+        parser.add_option(
+            "--rednose",
+            action="store_true",
+            default=rednose_on,
+            dest="rednose",
+            help="enable colour output (alternatively, set $%s=1)" % 
(self.env_opt,)
+        )
+        parser.add_option(
+            "--no-color",
+            action="store_false",
+            dest="rednose",
+            help="disable colour output"
+        )
+        parser.add_option(
+            "--force-color",
+            action="store_const",
+            dest='rednose_color',
+            default=rednose_color,
+            const='force',
+            help="force colour output when not using a TTY (alternatively, set 
$%s=force)" % (self.env_opt_color,)
+        )
+        parser.add_option(
+            "--immediate",
+            action="store_true",
+            default=False,
+            help="print errors and failures as they happen, as well as at the 
end"
+        )
+        parser.add_option(
+            "--full-file-path",
+            action="store_true",
+            default=False,
+            help="print the full file path as opposed to the one relative to 
your directory (default)"
+        )
+        parser.add_option(
+            "--hide-skips",
+            action="store_true",
+            default=False,
+            help="Hide the error printing for skip cases (default is to show 
them)"
+        )
+
+    def configure(self, options, conf):
+        if options.rednose:
+            self.enabled = True
+            termstyle_init = {
+                'force': termstyle.enable,
+                'off': termstyle.disable
+            }.get(options.rednose_color, termstyle.auto)
+            termstyle_init()
+
+            self.immediate = options.immediate
+            self.verbose = options.verbosity >= 2
+            self.full_file_path = options.full_file_path
+            self.hide_skips = options.hide_skips
+
+    def prepareTestResult(self, result):  # noqa
+        """Required to prevent others from monkey patching the add methods."""
+        return result
+
+    def prepareTestRunner(self, runner):  # noqa
+        stream = runner.stream
+        if os.name == 'nt':
+            import colorama
+            stream = colorama.initialise.wrap_stream(stream, convert=True, 
strip=False, autoreset=False, wrap=True)
+        return ColourTestRunner(stream=stream, 
descriptions=runner.descriptions, verbosity=runner.verbosity, 
config=runner.config, immediate=self.immediate, use_relative_path=not 
self.full_file_path, hide_skips=self.hide_skips)
+
+
+class ColourTestRunner(nose.core.TextTestRunner):
+
+    def __init__(self, stream, descriptions, verbosity, config, immediate, 
use_relative_path, hide_skips):
+        super(ColourTestRunner, self).__init__(stream=stream, 
descriptions=descriptions, verbosity=verbosity, config=config)
+        self.immediate = immediate
+        self.use_relative_path = use_relative_path
+        self.hide_skips = hide_skips
+
+    def _makeResult(self):  # noqa
+        return ColourTextTestResult(self.stream, self.descriptions, 
self.verbosity, self.config, immediate=self.immediate, 
use_relative_path=self.use_relative_path, hide_skips=self.hide_skips)
+
+
+class ColourTextTestResult(nose.result.TextTestResult):
+    """
+    A test result class that prints colour formatted text results to the 
stream.
+    """
+
+    def __init__(self, stream, descriptions, verbosity, config, 
errorClasses=None, immediate=False, use_relative_path=False, hide_skips=False): 
 # noqa
+        super(ColourTextTestResult, self).__init__(stream=stream, 
descriptions=descriptions, verbosity=verbosity, config=config, 
errorClasses=errorClasses)
+        self.has_test_ids = getattr(config.options, "enable_plugin_id", False)
+        if self.has_test_ids:
+            self.ids = self.get_test_ids(self.config.options.testIdFile)
+        self.total = 0
+        self.immediate = immediate
+        self.use_relative_path = use_relative_path
+        self.hide_skips = hide_skips
+        self.test_failures_and_exceptions = []
+        self.error = self.success = self.failure = self.skip = 
self.expected_failure = self.unexpected_success = 0
+        self.verbose = config.verbosity >= 2
+        self.short_status_map = {
+            failure: 'F',
+            error: 'E',
+            skip: '-',
+            expected_failure: "X",
+            unexpected_success: "U",
+            success: '.',
+        }
+        self.skips = []
+
+    def get_test_ids(self, test_id_file):
+        """Returns a mapping of test to id if one exists, else an empty 
dictionary."""
+        try:
+            with open(test_id_file, 'rb') as fh:
+                try:
+                    from cPickle import load
+                except ImportError:
+                    from pickle import load
+                data = load(fh)
+
+            return dict((address, _id) for _id, address in data["ids"].items())
+        except (IOError, ValueError):
+            return {}
+
+    def printSummary(self, start, stop):  # noqa
+        """Summarize all tests - the number of failures, errors and 
successes."""
+        self._line(termstyle.black)
+        self._out("%s test%s run in %0.3f seconds" % (self.total, 
self._plural(self.total), stop - start))
+        if self.total > self.success:
+            self._outln(". ")
+
+            additionals = [
+                {"color": termstyle.red, "count": self.failure, "message": "%s 
FAILED"},
+                {"color": termstyle.yellow, "count": self.error, "message": 
"%s error%s" % ("%s", self._plural(self.error))},
+                {"color": termstyle.blue, "count": self.skip, "message": "%s 
skipped"},
+                {"color": termstyle.green, "count": self.expected_failure, 
"message": "%s expected_failures"},
+                {"color": termstyle.cyan, "count": self.unexpected_success, 
"message": "%s unexpected_successes"},
+            ]
+
+            additionals_to_print = [
+                additional["color"](additional["message"] % 
(additional["count"])) for additional in additionals if additional["count"] > 0
+            ]
+
+            self._out(', '.join(additionals_to_print))
+
+        self._out(termstyle.green(" (%s test%s passed)" % (self.success, 
self._plural(self.success))))
+        self._outln()
+
+    def _plural(self, num):
+        return '' if num == 1 else 's'
+
+    def _line(self, color=termstyle.reset, char='-'):
+        """
+        Print a line of separator characters (default '-') in the given colour 
(default black).
+        """
+        self._outln(color(char * line_length))
+
+    def _print_test(self, test, type_, color):
+        self.total += 1
+        if self.verbose:
+            self._outln(color(type_))
+        else:
+            short_ = self.short_status_map.get(type_, ".")
+            self._out(color(short_))
+            if self.total % line_length == 0:
+                self._outln()
+
+    def _out(self, msg='', newline=False):
+        try:
+            self.stream.write(msg)
+            self.stream.flush()
+        except UnicodeEncodeError:
+            self.stream.write(msg.encode('utf-8'))
+            self.stream.flush()
+        if newline:
+            self.stream.write('\n')
+
+    def _outln(self, msg=''):
+        self._out(msg=msg, newline=True)
+
+    def _generate_and_add_test_report(self, type_, test, err):
+        report = self._report_test(len(self.test_failures_and_exceptions), 
type_, test, err)
+        self.test_failures_and_exceptions.append(report)
+
+    def addFailure(self, test, err):  # noqa
+        self.failure += 1
+        self._print_test(test, failure, termstyle.red)
+        self._generate_and_add_test_report(failure, test, err)
+
+    def addError(self, test, err):  # noqa
+        if err[0].__name__ == 'SkipTest':
+            self.addSkip(test, err)
+            return
+        self.error += 1
+        self._print_test(test, error, termstyle.yellow)
+        self._generate_and_add_test_report(error, test, err)
+
+    def addSuccess(self, test):  # noqa
+        self.success += 1
+        self._print_test(test, success, termstyle.green)
+
+    def addSkip(self, test, err):  # noqa
+        if isinstance(err, Exception):
+            err = (err.__class__, err, None)
+        elif self.verbose:
+            skip_message = "#{test_id} {test_location} ... ".format(
+                test_id=self._get_id(test),
+                test_location=getattr(test.context, "__file__", 
getattr(test.context, "__module__", None))
+            )
+            self._out(termstyle.reset(skip_message))
+        self.skip += 1
+        self._print_test(test, skip, termstyle.blue)
+        if not self.hide_skips:
+            self._generate_and_add_test_report(skip, test, err)
+
+    def addExpectedFailure(self, test, err):  # noqa
+        self.expected_failure += 1
+        self._print_test(test, expected_failure, termstyle.green)
+
+    def addUnexpectedSuccess(self, test):  # noqa
+        self.unexpected_success += 1
+        self._print_test(test, unexpected_success, termstyle.cyan)
+
+    def _report_test(self, report_index_num, type_, test, err):  # noqa
+        """report the results of a single (failing or errored) test"""
+        exc_type, exc_instance, exc_trace = err
+
+        if type_ == failure:
+            color = termstyle.red
+        elif type_ == skip:
+            color = termstyle.blue
+            exc_type = nose.SkipTest
+        else:
+            color = termstyle.yellow
+
+        colored_error_text = [
+            ''.join(self.format_traceback(exc_trace)),
+            self._format_exception_message(exc_type, exc_instance, color)
+        ]
+
+        if type_ == failure:
+            self.failures.append((test, colored_error_text))
+            flavour = "FAIL"
+        elif type_ == skip:
+            self.skips.append((test, colored_error_text))
+            flavour = "SKIP"
+        else:
+            self.errors.append((test, colored_error_text))
+            flavour = "ERROR"
+
+        test_id = self._get_id(test)
+
+        if self.immediate:
+            self._outln()
+            self._printError(flavour, test, colored_error_text, test_id, True)
+
+        return (test_id, flavour, test, colored_error_text)
+
+    def _get_id(self, test):
+        report_index_num = len(self.test_failures_and_exceptions)
+        if self.has_test_ids:
+            try:
+                test_id = self.ids.get(test.address(), self.total)
+            except AttributeError:
+                test_id = report_index_num + 1
+        else:
+            test_id = report_index_num + 1
+        return test_id
+
+    def format_traceback(self, tb):
+        if tb is not None:
+            ret = [termstyle.default("   Traceback (most recent call last):")]
+        else:
+            ret = [termstyle.default("   No Traceback")]
+
+        current_trace = tb
+        while current_trace is not None:
+            line = self._format_traceback_line(current_trace)
+            if line is not None:
+                ret.append(line)
+            current_trace = current_trace.tb_next
+        return '\n'.join(ret)
+
+    def _format_traceback_line(self, tb):
+        """
+        Formats the file / lineno / function line of a traceback element.
+
+        Returns None is the line is not relevent to the user i.e. inside the 
test runner.
+        """
+        if self._is_relevant_tb_level(tb):
+            return None
+
+        f = tb.tb_frame
+        filename = f.f_code.co_filename
+        lineno = tb.tb_lineno
+        linecache.checkcache(filename)
+        function_name = f.f_code.co_name
+
+        line_contents = linecache.getline(filename, lineno, 
f.f_globals).strip()
+
+        return "    %s line %s in %s\n      %s" % (
+            termstyle.blue(self._relative_path(filename) if 
self.use_relative_path else filename),
+            termstyle.bold(termstyle.cyan(lineno)),
+            termstyle.cyan(function_name),
+            line_contents
+        )
+
+    def _format_exception_message(self, exception_type, exception_instance, 
message_color):
+        """Returns a colorized formatted exception message."""
+        orig_message_lines = to_unicode(exception_instance).splitlines()
+
+        if len(orig_message_lines) == 0:
+            return ''
+        exception_message = orig_message_lines[0]
+
+        message_lines = [message_color('   ', 
termstyle.bold(message_color(exception_type.__name__)), ": ") + 
message_color(exception_message)]
+        for line in orig_message_lines[1:]:
+            match = re.match('^---.* begin captured stdout.*----$', line)
+            if match:
+                message_color = termstyle.magenta
+                message_lines.append('')
+            line = '   ' + line
+            message_lines.append(message_color(line))
+        return '\n'.join(message_lines)
+
+    def _relative_path(self, path):
+        """
+        Returns the relative path of a file to the current working directory.
+
+        If path is a child of the current working directory, the relative
+        path is returned surrounded.
+        If path is not a child of the working directory, path is returned
+        """
+        try:
+            here = os.path.abspath(os.path.realpath(os.getcwd()))
+            fullpath = os.path.abspath(os.path.realpath(path))
+        except OSError:
+            return path
+        if fullpath.startswith(here):
+            return fullpath[len(here) + 1:]
+        return path
+
+    def printErrors(self):  # noqa
+        if not self.verbose:
+            self._outln()
+        if self.immediate:
+            self._outln()
+            for x in range(0, 4):
+                self._outln()
+
+            self._outln(termstyle.green("TEST RESULT OUTPUT:"))
+
+        for (test_id, flavour, test, coloured_output_lines) in 
(self.test_failures_and_exceptions):
+            self._printError(flavour=flavour, test=test, 
coloured_output_lines=coloured_output_lines, test_id=test_id)
+
+        # Copied from the parent function.
+        self._outln()
+        for cls in self.errorClasses.keys():
+            storage, label, isfail = self.errorClasses[cls]
+            if isfail:
+                self.printErrorList(label, storage)
+        # Might get patched into a result with no config
+        if hasattr(self, 'config'):
+            self.config.plugins.report(self.stream)
+
+    def _printError(self, flavour, test, coloured_output_lines, test_id, 
is_mid_test=False):  # noqa
+        if flavour == "FAIL":
+            color = termstyle.red
+        elif flavour == "SKIP":
+            color = termstyle.blue
+
+        else:
+            color = termstyle.yellow
+
+        self._outln(color(self.separator1))
+        self._outln(color("%s) %s: %s" % (test_id, flavour, 
self.getDescription(test))))
+        self._outln(color(self.separator2))
 
+        for err_line in coloured_output_lines:
+            self._outln("%s" % err_line)
 
-class FilteringStream(object):
-       """
-       A wrapper for a stream that will filter
-       calls to `write` and `writeln` to ignore calls
-       from blacklisted callers
-       (implemented as a regex on their filename, according
-       to traceback.extract_stack())
-
-       It's super hacky, but there seems to be no other way
-       to suppress nose's default output
-       """
-       def __init__(self, stream, excludes):
-               self.__stream = stream
-               self.__excludes = list(map(re.compile, excludes))
-
-       def __should_filter(self):
-               try:
-                       stack = traceback.extract_stack(limit=3)[0]
-                       filename = stack[0]
-                       pattern_matches_filename = lambda pattern: 
pattern.search(filename)
-                       should_filter = any(map(pattern_matches_filename, 
self.__excludes))
-                       if REDNOSE_DEBUG:
-                               print >> sys.stderr, "REDNOSE_DEBUG: got write 
call from %s, should_filter = %s" % (
-                                               filename, should_filter)
-                       return should_filter
-               except StandardError as e:
-                       if REDNOSE_DEBUG:
-                               print("\nError in rednose filtering: %s" % 
(e,), file=sys.stderr)
-                               traceback.print_exc(sys.stderr)
-                       return False
-
-       def write(self, *a):
-               if self.__should_filter():
-                       return
-               return self.__stream.write(*a)
-
-       def writeln(self, *a):
-               if self.__should_filter():
-                       return
-               return self.__stream.writeln(*a)
-
-       # pass non-known methods through to self.__stream
-       def __getattr__(self, name):
-               if REDNOSE_DEBUG:
-                       print("REDNOSE_DEBUG: getting attr %s" % (name,), 
file=sys.stderr)
-               return getattr(self.__stream, name)
+        if is_mid_test:
+            self._outln(color(self.separator2))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rednose-0.4.1/setup.cfg new/rednose-1.2.3/setup.cfg
--- old/rednose-0.4.1/setup.cfg 2013-08-30 10:11:56.000000000 +0200
+++ new/rednose-1.2.3/setup.cfg 2017-11-05 18:55:39.000000000 +0100
@@ -1,5 +1,4 @@
 [egg_info]
 tag_build = 
 tag_date = 0
-tag_svn_revision = 0
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rednose-0.4.1/setup.py new/rednose-1.2.3/setup.py
--- old/rednose-0.4.1/setup.py  2013-08-30 10:11:05.000000000 +0200
+++ new/rednose-1.2.3/setup.py  2017-11-05 18:55:20.000000000 +0100
@@ -1,29 +1,34 @@
-#!/usr/bin/env python
+from os import path
+from setuptools import setup, find_packages
 
-## NOTE: ##
-## this setup.py was generated by zero2pypi:
-## http://gfxmonk.net/dist/0install/zero2pypi.xml
 
-from setuptools import *
+def read(fname):
+    try:
+        return open(path.join(path.dirname(__file__), fname)).read()
+    except IOError:
+        return """A module for making nose pretty using colors."""
+
 setup(
-       packages = find_packages(exclude=['test', 'test.*']),
-       description='coloured output for nosetests',
-       entry_points={'nose.plugins.0.10': ['NOSETESTS_PLUGINS = 
rednose:RedNose']},
-       install_requires=['setuptools', 'python-termstyle >=0.1.7'],
-       long_description="\n**Note**: This package has been built automatically 
by\n`zero2pypi <http://gfxmonk.net/dist/0install/zero2pypi.xml>`_.\nIf 
possible, you should use the zero-install feed 
instead:\nhttp://gfxmonk.net/dist/0install/rednose.xml\n\n----------------\n\n=========\nrednose\n=========\n\nrednose
 is a `nosetests`_\nplugin for adding colour (and readability) to nosetest 
console results.\n\nInstallation:\n-------------\n::\n\n\teasy_install 
rednose\n\t\nor from the source::\n\n\t./setup.py 
develop\n\nUsage:\n------\n::\n\n\tnosetests --rednose\n\nor::\n\n\texport 
NOSE_REDNOSE=1\n\tnosetests\n\nRednose by default uses auto-colouring, which 
will only use\ncolour if you're running it on a terminal (i.e not piping it\nto 
a file). To control colouring, use one of::\n\n\tnosetests --rednose 
--force-color\n\tnosetests --no-color\n\n(you can also control this by setting 
the environment variable NOSE_REDNOSE_COLOR to 'force' or 'no')\n\n.. 
_nosetests: http://somethingaboutorange.com/mrl/projects/nose/\n";,
-       name='rednose',
-       py_modules=['rednose'],
-       url='http://gfxmonk.net/dist/0install/rednose.xml',
-       version='0.4.1',
-classifiers=[
-               "License :: OSI Approved :: BSD License",
-               "Programming Language :: Python",
-               "Programming Language :: Python :: 3",
-               "Development Status :: 4 - Beta",
-               "Intended Audience :: Developers",
-               "Topic :: Software Development :: Libraries :: Python Modules",
-               "Topic :: Software Development :: Testing",
-       ],
-       keywords='test nosetests nose nosetest output colour console',
-       license='BSD',
+    packages=find_packages(exclude=['test', 'test.*']),
+    description='coloured output for nosetests',
+    entry_points={'nose.plugins.0.10': ['NOSETESTS_PLUGINS = 
rednose:RedNose']},
+    install_requires=['setuptools', 'termstyle >=0.1.7', 'colorama'],
+    tests_require=['six==1.10.0'],
+    long_description=read('README.rst'),
+    name='rednose',
+    py_modules=['rednose'],
+    url='https://github.com/JBKahn/rednose',
+    version='1.2.3',
+    classifiers=[
+        "License :: OSI Approved :: BSD License",
+        "Programming Language :: Python",
+        "Programming Language :: Python :: 3",
+        "Development Status :: 4 - Beta",
+        "Intended Audience :: Developers",
+        "Topic :: Software Development :: Libraries :: Python Modules",
+        "Topic :: Software Development :: Testing",
+    ],
+    keywords='test nosetests nose nosetest output colour console',
+    license='BSD',
+    test_suite='test_files.new_tests',
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rednose-0.4.1/test_files/basic_test_suite.py 
new/rednose-1.2.3/test_files/basic_test_suite.py
--- old/rednose-0.4.1/test_files/basic_test_suite.py    1970-01-01 
01:00:00.000000000 +0100
+++ new/rednose-1.2.3/test_files/basic_test_suite.py    2017-11-05 
18:55:20.000000000 +0100
@@ -0,0 +1,6 @@
+import unittest
+
+
+class TC(unittest.TestCase):
+    def runTest(self):  # noqa
+        raise ValueError("I hate fancy stuff")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rednose-0.4.1/test_files/class_test_failure.py 
new/rednose-1.2.3/test_files/class_test_failure.py
--- old/rednose-0.4.1/test_files/class_test_failure.py  1970-01-01 
01:00:00.000000000 +0100
+++ new/rednose-1.2.3/test_files/class_test_failure.py  2017-11-05 
18:55:20.000000000 +0100
@@ -0,0 +1,34 @@
+from __future__ import print_function
+import unittest
+
+
+def setup_module():
+    raise unittest.SkipTest('RESI specific Nonius libs not present')
+    print(__name__, ': setup_module() ~~~~~~~~~~~~~~~~~~~~~~')
+
+
+def teardown_module():
+    print(__name__, ': teardown_module() ~~~~~~~~~~~~~~~~~~~')
+
+
+class SomeSkippedTest(unittest.TestCase):
+
+    @classmethod
+    def setup_class(cls):
+        print(__name__, ': TestClass.setup_class() ----------')
+
+    @classmethod
+    def teardown_class(cls):
+        print(__name__, ': TestClass.teardown_class() -------')
+
+    def setup(self):
+        print(__name__, ': TestClass.setup()  - - - - - - - -')
+
+    def teardown(self):
+        print(__name__, ': TestClass.teardown() - - - - - - -')
+
+    def test_method_1(self):
+        print(__name__, ': TestClass.test_method_1()')
+
+    def test_method_2(self):
+        print(__name__, ': TestClass.test_method_2()')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rednose-0.4.1/test_files/encoding_test.py 
new/rednose-1.2.3/test_files/encoding_test.py
--- old/rednose-0.4.1/test_files/encoding_test.py       1970-01-01 
01:00:00.000000000 +0100
+++ new/rednose-1.2.3/test_files/encoding_test.py       2017-11-05 
18:55:20.000000000 +0100
@@ -0,0 +1,8 @@
+# vim: fileencoding=utf-8:
+
+# NOTE: this file does *not* import unicode_literals,
+# so the assertion message is actually just utf-8 bytes
+
+
+def test():
+    assert False, "ä"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/rednose-0.4.1/test_files/encoding_test_with_literals.py 
new/rednose-1.2.3/test_files/encoding_test_with_literals.py
--- old/rednose-0.4.1/test_files/encoding_test_with_literals.py 1970-01-01 
01:00:00.000000000 +0100
+++ new/rednose-1.2.3/test_files/encoding_test_with_literals.py 2017-11-05 
18:55:20.000000000 +0100
@@ -0,0 +1,9 @@
+# vim: fileencoding=utf-8:
+from __future__ import unicode_literals
+
+import unittest
+
+
+class EncodingTest(unittest.TestCase):
+    def test_utf8(self):
+        self.assertEqual('café', 'abc')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rednose-0.4.1/test_files/new_tests.py 
new/rednose-1.2.3/test_files/new_tests.py
--- old/rednose-0.4.1/test_files/new_tests.py   1970-01-01 01:00:00.000000000 
+0100
+++ new/rednose-1.2.3/test_files/new_tests.py   2017-11-05 18:55:20.000000000 
+0100
@@ -0,0 +1,324 @@
+# -*- coding: utf-8 -*-
+
+import os
+import sys
+import unittest
+
+import nose
+from nose.plugins import PluginTester, testid
+from six import PY2, PY3
+
+from rednose import RedNose
+
+
+try:
+    from unittest import skip, skipUnless
+except ImportError:
+    def skip(f):
+        return lambda self: None
+
+    def skipUnless(condition, reason):  # noqa
+        if condition:
+            return lambda x: x
+        else:
+            return lambda x: None
+
+
+class TestRedNoseWithId(PluginTester, unittest.TestCase):
+    activate = '--rednose'
+    plugins = [RedNose(), testid.TestId()]
+    args = ['--force-color', '--with-id']
+    env = {}
+
+    def test_colored_result(self):
+        expected_lines = [
+            '\x1b[33mE\x1b[0m',
+            
'\x1b[33m======================================================================\x1b[0m',
+            '\x1b[33m1) ERROR: runTest 
(test_files.basic_test_suite.TC)\x1b[0m',
+            
'\x1b[33m----------------------------------------------------------------------\x1b[0m',
+            '\x1b[0m   Traceback (most recent call last):\x1b[0m',
+            '    \x1b[34mtest_files/basic_test_suite.py\x1b[0m line 
\x1b[1m\x1b[36m6\x1b[0m\x1b[0m in \x1b[36mrunTest\x1b[0m',
+            '      raise ValueError("I hate fancy stuff")',
+            '\x1b[33m   
\x1b[33m\x1b[1m\x1b[33mValueError\x1b[0m\x1b[0m\x1b[33m: \x1b[0m\x1b[33mI hate 
fancy stuff\x1b[0m',
+            '',
+            
'\x1b[30m-----------------------------------------------------------------------------\x1b[0m',
+            '1 test run in',
+            '\x1b[33m1 error\x1b[0m\x1b[32m (0 tests passed)\x1b[0m',
+            '',
+        ]
+        for expected_line, actual_line in zip(expected_lines, 
str(self.output).split("\n")):
+            if expected_line not in actual_line:
+                print(expected_line)
+                print(actual_line)
+                print(self.output)
+            self.assertTrue(expected_line in actual_line)
+
+    def makeSuite(self):  # noqa
+        from test_files.basic_test_suite import TC
+        return [TC('runTest')]
+
+
+class TestRedNose(PluginTester, unittest.TestCase):
+    activate = '--rednose'
+    plugins = [RedNose()]
+    args = ['--force-color']
+    env = {}
+
+    def test_colored_result(self):
+        expected_lines = [
+            '\x1b[33mE\x1b[0m',
+            
'\x1b[33m======================================================================\x1b[0m',
+            '\x1b[33m1) ERROR: runTest 
(test_files.basic_test_suite.TC)\x1b[0m',
+            
'\x1b[33m----------------------------------------------------------------------\x1b[0m',
+            '\x1b[0m   Traceback (most recent call last):\x1b[0m',
+            '    \x1b[34mtest_files/basic_test_suite.py\x1b[0m line 
\x1b[1m\x1b[36m6\x1b[0m\x1b[0m in \x1b[36mrunTest\x1b[0m',
+            '      raise ValueError("I hate fancy stuff")',
+            '\x1b[33m   
\x1b[33m\x1b[1m\x1b[33mValueError\x1b[0m\x1b[0m\x1b[33m: \x1b[0m\x1b[33mI hate 
fancy stuff\x1b[0m',
+            '',
+            
'\x1b[30m-----------------------------------------------------------------------------\x1b[0m',
+            '1 test run in',
+            '\x1b[33m1 error\x1b[0m\x1b[32m (0 tests passed)\x1b[0m',
+            '',
+        ]
+        for expected_line, actual_line in zip(expected_lines, 
str(self.output).split("\n")):
+            if expected_line not in actual_line:
+                print(expected_line)
+                print(actual_line)
+                print(self.output)
+            self.assertTrue(expected_line in actual_line)
+
+    def makeSuite(self):  # noqa
+        from test_files.basic_test_suite import TC
+        return [TC('runTest')]
+
+
+@skipUnless(sys.version_info >= (2, 7), "python 2.6 not supported")
+class TestRedNoseSkipInClass(PluginTester, unittest.TestCase):
+    activate = '--rednose'
+    plugins = [RedNose()]
+    args = ['--force-color']
+    env = {}
+    suitepath = os.path.join(os.getcwd(), 'test_files', 
'class_test_failure.py')
+
+    def test_colored_result(self):
+        expected_lines = [
+            '\x1b[34m-\x1b[0m',
+            
'\x1b[34m======================================================================\x1b[0m',
+            "\x1b[34m1) SKIP: test suite for <module 
'test_files.class_test_failure' from 
'{0}/test_files/class_test_failure.py".format(os.getcwd()),
+            
'\x1b[34m----------------------------------------------------------------------\x1b[0m',
+            '\x1b[0m   Traceback (most recent call last):\x1b[0m',
+            '    \x1b[34m{0}/suite.py\x1b[0m line 
\x1b[1m\x1b[36m'.format(nose.__path__[0]),
+            '      self.setUp()',
+            '    \x1b[34m{0}/suite.py\x1b[0m line 
\x1b[1m\x1b[36m'.format(nose.__path__[0]),
+            '      self.setupContext(ancestor)',
+            '    \x1b[34m{0}/suite.py\x1b[0m line 
\x1b[1m\x1b[36m'.format(nose.__path__[0]),
+            '      try_run(context, names)',
+            '    \x1b[34m{0}/util.py\x1b[0m line 
\x1b[1m\x1b[36m'.format(nose.__path__[0]),
+            '      return func()',
+            '    \x1b[34mtest_files/class_test_failure.py\x1b[0m line 
\x1b[1m\x1b[36m6\x1b[0m\x1b[0m in \x1b[36msetup_module\x1b[0m',
+            "      raise unittest.SkipTest('RESI specific Nonius libs not 
present')",
+            '\x1b[34m   \x1b[34m\x1b[1m\x1b[34mSkipTest\x1b[0m\x1b[0m\x1b[34m: 
\x1b[0m\x1b[34mRESI specific Nonius libs not present\x1b[0m',
+            '',
+            
'\x1b[30m-----------------------------------------------------------------------------\x1b[0m',
+            '1 test run in ',
+            '\x1b[34m1 skipped\x1b[0m\x1b[32m (0 tests passed)\x1b[0m',
+            '',
+        ]
+        for expected_line, actual_line in zip(expected_lines, 
str(self.output).split("\n")):
+            if expected_line not in actual_line:
+                print(expected_line)
+                print(actual_line)
+                print(self.output)
+            self.assertTrue(expected_line in actual_line)
+
+
+@skipUnless(sys.version_info >= (2, 7), "python 2.6 not supported")
+class TestRedNoseSampleTests(PluginTester, unittest.TestCase):
+    activate = '--rednose'
+    plugins = [RedNose()]
+    args = ['--force-color']
+    env = {}
+    suitepath = os.path.join(os.getcwd(), 'test_files', 'sample_test.py')
+
+    def test_colored_result(self):
+        expected_lines = [
+            
'\x1b[33mE\x1b[0m\x1b[31mF\x1b[0m\x1b[34m-\x1b[0m\x1b[34m-\x1b[0m\x1b[32m.\x1b[0m\x1b[31mF\x1b[0m',
+            
'\x1b[33m======================================================================\x1b[0m',
+            '\x1b[33m1) ERROR: test_error 
(test_files.sample_test.SomeTest)\x1b[0m',
+            
'\x1b[33m----------------------------------------------------------------------\x1b[0m',
+            '\x1b[0m   Traceback (most recent call last):\x1b[0m',
+            '    \x1b[34mtest_files/sample_test.py\x1b[0m line 
\x1b[1m\x1b[36m20\x1b[0m\x1b[0m in \x1b[36mtest_error\x1b[0m',
+            '      raise RuntimeError("things went south\\nand here\'s a 
second line!")',
+            '\x1b[33m   
\x1b[33m\x1b[1m\x1b[33mRuntimeError\x1b[0m\x1b[0m\x1b[33m: 
\x1b[0m\x1b[33mthings went south\x1b[0m',
+            "\x1b[33m   and here's a second line!\x1b[0m",
+            
'\x1b[31m======================================================================\x1b[0m',
+            '\x1b[31m2) FAIL: test_fail 
(test_files.sample_test.SomeTest)\x1b[0m',
+            
'\x1b[31m----------------------------------------------------------------------\x1b[0m',
+            '\x1b[0m   Traceback (most recent call last):\x1b[0m',
+            '    \x1b[34mtest_files/sample_test.py\x1b[0m line 
\x1b[1m\x1b[36m14\x1b[0m\x1b[0m in \x1b[36mtest_fail\x1b[0m',
+            "      delay_fail(lambda: self.fail('no dice'))",
+            '    \x1b[34mtest_files/sample_test.py\x1b[0m line 
\x1b[1m\x1b[36m8\x1b[0m\x1b[0m in \x1b[36mdelay_fail\x1b[0m',
+            '      f()  # fail it!',
+            '    \x1b[34mtest_files/sample_test.py\x1b[0m line 
\x1b[1m\x1b[36m14\x1b[0m\x1b[0m in \x1b[36m<lambda>\x1b[0m',
+            "      delay_fail(lambda: self.fail('no dice'))",
+            '\x1b[31m   
\x1b[31m\x1b[1m\x1b[31mAssertionError\x1b[0m\x1b[0m\x1b[31m: \x1b[0m\x1b[31mno 
dice\x1b[0m',
+            
'\x1b[34m======================================================================\x1b[0m',
+            '\x1b[34m3) SKIP: test_skip 
(test_files.sample_test.SomeTest)\x1b[0m',
+            
'\x1b[34m----------------------------------------------------------------------\x1b[0m',
+            '\x1b[0m   No Traceback\x1b[0m',
+            '',
+            
'\x1b[34m======================================================================\x1b[0m',
+            '\x1b[34m4) SKIP: test_skip_with_reason 
(test_files.sample_test.SomeTest)\x1b[0m',
+            
'\x1b[34m----------------------------------------------------------------------\x1b[0m',
+            '\x1b[0m   No Traceback\x1b[0m',
+            "\x1b[34m   \x1b[34m\x1b[1m\x1b[34mSkipTest\x1b[0m\x1b[0m\x1b[34m: 
\x1b[0m\x1b[34mLook at me, I'm skipping for a reason!!\x1b[0m",
+            
'\x1b[31m======================================================================\x1b[0m',
+            "\x1b[31m5) FAIL: It's got a long description, you see?.\x1b[0m",
+            
'\x1b[31m----------------------------------------------------------------------\x1b[0m',
+            '\x1b[0m   Traceback (most recent call last):\x1b[0m',
+            '    \x1b[34mtest_files/sample_test.py\x1b[0m line 
\x1b[1m\x1b[36m32\x1b[0m\x1b[0m in \x1b[36mtest_with_long_description\x1b[0m',
+            '      self.fail()', '\x1b[31m   
\x1b[31m\x1b[1m\x1b[31mAssertionError\x1b[0m\x1b[0m\x1b[31m: 
\x1b[0m\x1b[31mNone\x1b[0m',
+            '',
+            "\x1b[34m6) SKIP: test suite for <class 
'test_files.sample_test.TestBug'>\x1b[0m",
+            
'\x1b[34m----------------------------------------------------------------------\x1b[0m',
+            '\x1b[0m   Traceback (most recent call last):\x1b[0m',
+            'nose/suite.py\x1b[0m line',
+            '      self.setUp()',
+            'nose/suite.py\x1b[0m line',
+            '      self.setupContext(ancestor)',
+            'nose/suite.py\x1b[0m line',
+            '      try_run(context, names)',
+            'nose/util.py\x1b[0m line',
+            '      return func()',
+            '    \x1b[34mtest_files/sample_test.py\x1b[0m line 
\x1b[1m\x1b[36m39\x1b[0m\x1b[0m in \x1b[36msetUpClass\x1b[0m',
+            '      raise nose.SkipTest("SKIPPING!")',
+            '\x1b[34m   \x1b[34m\x1b[1m\x1b[34mSkipTest\x1b[0m\x1b[0m\x1b[34m: 
\x1b[0m\x1b[34mSKIPPING!\x1b[0m',
+            '',
+            
'\x1b[30m-----------------------------------------------------------------------------\x1b[0m',
+            '7 tests run in ',
+            '\x1b[31m2 FAILED\x1b[0m, \x1b[33m1 error\x1b[0m, \x1b[34m3 
skipped\x1b[0m\x1b[32m (1 test passed)\x1b[0m',
+            ''
+        ]
+        if PY2:
+            import sys
+            if sys.version_info[1] == 6:
+                expected_lines = expected_lines[:8] + expected_lines[10:]
+
+        for expected_line, actual_line in zip(expected_lines, 
str(self.output).split("\n")):
+            if expected_line not in actual_line:
+                print(expected_line)
+                print(actual_line)
+                print(self.output)
+            self.assertTrue(expected_line in actual_line)
+
+
+class TestRedNoseEncoding(PluginTester, unittest.TestCase):
+    activate = '--rednose'
+    plugins = [RedNose()]
+    args = ['--force-color']
+    env = {}
+    suitepath = os.path.join(os.getcwd(), 'test_files', 'encoding_test.py')
+
+    def setUp(self):
+        import sys
+        self.old_encoding = sys.getdefaultencoding()
+        if PY2:
+            reload(sys)
+            sys.setdefaultencoding('utf8')
+        super(TestRedNoseEncoding, self).setUp()
+
+    def tearDown(self):
+        import sys
+        if PY2:
+            reload(sys)
+            sys.setdefaultencoding(self.old_encoding)
+        super(TestRedNoseEncoding, self).tearDown()
+
+    def test_colored_result(self):
+        expected_lines = [
+            '\x1b[31mF\x1b[0m',
+            
'\x1b[31m======================================================================\x1b[0m',
+            '\x1b[31m1) FAIL: test_files.encoding_test.test\x1b[0m',
+            
'\x1b[31m----------------------------------------------------------------------\x1b[0m',
+            '\x1b[0m   Traceback (most recent call last):\x1b[0m',
+            '    \x1b[34m{0}/case.py\x1b[0m line 
\x1b[1m\x1b[36m'.format(nose.__path__[0]),
+            '      self.test(*self.arg)',
+            '    \x1b[34mtest_files/encoding_test.py\x1b[0m line 
\x1b[1m\x1b[36m8\x1b[0m\x1b[0m in \x1b[36mtest\x1b[0m',
+            '      assert False, "\xc3\xa4"',
+            '\x1b[31m   
\x1b[31m\x1b[1m\x1b[31mAssertionError\x1b[0m\x1b[0m\x1b[31m: 
\x1b[0m\x1b[31m\xc3\xa4\x1b[0m',
+            '',
+            
'\x1b[30m-----------------------------------------------------------------------------\x1b[0m',
+            '1 test run in ',
+            '\x1b[31m1 FAILED\x1b[0m\x1b[32m (0 tests passed)\x1b[0m',
+            ''
+        ]
+
+        if PY3:
+            pass
+            expected_lines[8] = '      assert False, "ä"'
+            expected_lines[9] = '\x1b[31m   
\x1b[31m\x1b[1m\x1b[31mAssertionError\x1b[0m\x1b[0m\x1b[31m: 
\x1b[0m\x1b[31mä\x1b[0m'
+
+        for expected_line, actual_line in zip(expected_lines, 
str(self.output).split("\n")):
+            if expected_line not in actual_line:
+                print(expected_line)
+                print(actual_line)
+                print(self.output)
+            self.assertTrue(expected_line in actual_line)
+
+
+class TestRedNoseEncodingWithLiterals(PluginTester, unittest.TestCase):
+    activate = '--rednose'
+    plugins = [RedNose()]
+    args = ['--force-color']
+    env = {}
+    suitepath = os.path.join(os.getcwd(), 'test_files', 
'encoding_test_with_literals.py')
+
+    def setUp(self):
+        import sys
+        self.old_encoding = sys.getdefaultencoding()
+        if PY2:
+            reload(sys)
+            sys.setdefaultencoding('utf8')
+        super(TestRedNoseEncodingWithLiterals, self).setUp()
+
+    def tearDown(self):
+        import sys
+        if PY2:
+            reload(sys)
+            sys.setdefaultencoding(self.old_encoding)
+        super(TestRedNoseEncodingWithLiterals, self).tearDown()
+
+    def test_colored_result(self):
+        expected_lines = [
+            '\x1b[31mF\x1b[0m',
+            
'\x1b[31m======================================================================\x1b[0m',
+            '\x1b[31m1) FAIL: test_utf8 
(test_files.encoding_test_with_literals.EncodingTest)\x1b[0m',
+            
'\x1b[31m----------------------------------------------------------------------\x1b[0m',
+            '\x1b[0m   Traceback (most recent call last):\x1b[0m',
+            '    \x1b[34mtest_files/encoding_test_with_literals.py\x1b[0m line 
\x1b[1m\x1b[36m9\x1b[0m\x1b[0m in \x1b[36mtest_utf8\x1b[0m',
+            "      self.assertEqual('caf\xc3\xa9', 'abc')",
+            "\x1b[31m   
\x1b[31m\x1b[1m\x1b[31mAssertionError\x1b[0m\x1b[0m\x1b[31m: 
\x1b[0m\x1b[31mu'caf\\xe9' != u'abc'\x1b[0m",
+            '\x1b[31m   - caf\xc3\xa9\x1b[0m',
+            '\x1b[31m   + abc\x1b[0m',
+            '',
+            
'\x1b[30m-----------------------------------------------------------------------------\x1b[0m',
+            '1 test run in ',
+            '\x1b[31m1 FAILED\x1b[0m\x1b[32m (0 tests passed)\x1b[0m',
+            ''
+        ]
+
+        if PY3:
+            expected_lines[6] = "      self.assertEqual('café', 'abc')"
+            expected_lines[7] = "\x1b[31m   
\x1b[31m\x1b[1m\x1b[31mAssertionError\x1b[0m\x1b[0m\x1b[31m: 
\x1b[0m\x1b[31m'café' != 'abc'\x1b[0m"
+            expected_lines[8] = "\x1b[31m   - café\x1b[0m"
+        elif PY2:
+            import sys
+            if sys.version_info[1] == 6:
+                expected_lines = expected_lines[:8] + expected_lines[10:]
+
+        for expected_line, actual_line in zip(expected_lines, 
str(self.output).split("\n")):
+            if expected_line not in actual_line:
+                print(expected_line)
+                print(actual_line)
+                print(self.output)
+            self.assertTrue(expected_line in actual_line)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/rednose-0.4.1/test_files/sample_test.py 
new/rednose-1.2.3/test_files/sample_test.py
--- old/rednose-0.4.1/test_files/sample_test.py 1970-01-01 01:00:00.000000000 
+0100
+++ new/rednose-1.2.3/test_files/sample_test.py 2017-11-05 18:55:20.000000000 
+0100
@@ -0,0 +1,42 @@
+# vim: set fileencoding=utf-8 :
+from __future__ import print_function
+from __future__ import unicode_literals
+import unittest
+
+
+def delay_fail(f):
+    f()  # fail it!
+
+
+class SomeTest(unittest.TestCase):
+    def test_fail(self):
+        print("oh noes, it's gonna blow!")
+        delay_fail(lambda: self.fail('no dice'))
+
+    def test_success(self):
+        self.assertEqual(True, True)
+
+    def test_error(self):
+        raise RuntimeError("things went south\nand here's a second line!")
+
+    def test_skip(self):
+        import nose
+        raise nose.SkipTest
+
+    def test_skip_with_reason(self):
+        import nose
+        raise nose.SkipTest("Look at me, I'm skipping for a reason!!")
+
+    def test_with_long_description(self):
+        """It's got a long description, you see?."""
+        self.fail()
+
+
+class TestBug(unittest.TestCase):
+    @classmethod
+    def setUpClass(cls):
+        import nose
+        raise nose.SkipTest("SKIPPING!")
+
+    def test_bug(self):
+        pass


Reply via email to