[Zope3-checkins]
SVN: zope.testing/trunk/src/zope/testing/testrunner
Make --auto-color actually check whether the terminal
supports colors. Some
Marius Gedminas
marius at pov.lt
Mon Jul 23 17:40:13 EDT 2007
Log message for revision 78300:
Make --auto-color actually check whether the terminal supports colors. Some
terminals don't (e.g. the emacs built-in one), which makes some people (e.g.
my coworker Albertas) unhappy when --auto-color is present in the test script.
Changed:
U zope.testing/trunk/src/zope/testing/testrunner-colors.txt
U zope.testing/trunk/src/zope/testing/testrunner.py
-=-
Modified: zope.testing/trunk/src/zope/testing/testrunner-colors.txt
===================================================================
--- zope.testing/trunk/src/zope/testing/testrunner-colors.txt 2007-07-23 18:11:26 UTC (rev 78299)
+++ zope.testing/trunk/src/zope/testing/testrunner-colors.txt 2007-07-23 21:40:12 UTC (rev 78300)
@@ -311,12 +311,36 @@
Autodetecting colors
--------------------
-The --auto-color option will determine if stdout is a terminal, and only enable
-colorized output if so. Our ``Terminal`` wrapper pretends it is a terminal, so
-we get colors:
+The --auto-color option will determine if stdout is a terminal that supports
+colors, and only enable colorized output if so. Our ``Terminal`` wrapper
+pretends it is a terminal, but the curses module will realize it isn't:
>>> sys.argv = 'test --layer 122 --auto-color'.split()
>>> testrunner.run(defaults)
+ Running samplelayers.Layer122 tests:
+ Set up samplelayers.Layer1 in 0.000 seconds.
+ Set up samplelayers.Layer12 in 0.000 seconds.
+ Set up samplelayers.Layer122 in 0.000 seconds.
+ Ran 34 tests with 0 failures and 0 errors in 0.007 seconds.
+ Tearing down left over layers:
+ Tear down samplelayers.Layer122 in 0.000 seconds.
+ Tear down samplelayers.Layer12 in 0.000 seconds.
+ Tear down samplelayers.Layer1 in 0.000 seconds.
+ False
+
+We can fake it
+
+ >>> class FakeCurses(object):
+ ... class error(Exception):
+ ... pass
+ ... def setupterm(self):
+ ... pass
+ ... def tigetnum(self, attr):
+ ... return dict(colors=8).get(attr, -2)
+ >>> sys.modules['curses'] = FakeCurses()
+
+ >>> sys.argv = 'test --layer 122 --auto-color'.split()
+ >>> testrunner.run(defaults)
{normal}Running samplelayers.Layer122 tests:{normal}
Set up samplelayers.Layer1 in {green}0.000{normal} seconds.
Set up samplelayers.Layer12 in {green}0.000{normal} seconds.
@@ -328,6 +352,8 @@
Tear down samplelayers.Layer1 in {green}0.000{normal} seconds.
False
+ >>> del sys.modules['curses']
+
The real stdout is not a terminal in a doctest:
>>> sys.stdout = real_stdout
Modified: zope.testing/trunk/src/zope/testing/testrunner.py
===================================================================
--- zope.testing/trunk/src/zope/testing/testrunner.py 2007-07-23 18:11:26 UTC (rev 78299)
+++ zope.testing/trunk/src/zope/testing/testrunner.py 2007-07-23 21:40:12 UTC (rev 78300)
@@ -259,6 +259,33 @@
"""
+def tigetnum(attr, default=None):
+ """Return a value from the terminfo database.
+
+ Terminfo is used on Unix-like systems to report various terminal attributes
+ (such as width, height or the number of supported colors).
+
+ Returns ``default`` when the ``curses`` module is not available, or when
+ sys.stdout is not a terminal.
+ """
+ try:
+ import curses
+ except ImportError:
+ # avoid reimporting a broken module in python 2.3
+ sys.modules['curses'] = None
+ else:
+ try:
+ curses.setupterm()
+ except (curses.error, TypeError):
+ # You get curses.error when $TERM is set to an unknown name
+ # You get TypeError when sys.stdout is not a real file object
+ # (e.g. in unit tests that use various wrappers).
+ pass
+ else:
+ return curses.tigetnum(attr)
+ return default
+
+
class OutputFormatter(object):
"""Test runner output formatter."""
@@ -280,19 +307,8 @@
def compute_max_width(self):
"""Try to determine the terminal width."""
- try:
- # Note that doing this every time is more test friendly.
- import curses
- except ImportError:
- # avoid reimporting a broken module in python 2.3
- sys.modules['curses'] = None
- else:
- try:
- curses.setupterm()
- except TypeError:
- pass
- else:
- self.max_width = curses.tigetnum('cols')
+ # Note that doing this every time is more test friendly.
+ self.max_width = tigetnum('cols', self.max_width)
def getShortDescription(self, test, room):
"""Return a description of a test that fits in ``room`` characters."""
@@ -2348,14 +2364,23 @@
'--suite-name', 'test_suite',
]
+
+def terminal_has_colors():
+ """Determine whether the terminal supports colors.
+
+ Some terminals (e.g. the emacs built-in one) don't.
+ """
+ return tigetnum('colors', -1) >= 8
+
+
def get_options(args=None, defaults=None):
# Because we want to inspect stdout and decide to colorize or not, we
# replace the --auto-color option with the appropriate --color or
# --no-color option. That way the subprocess doesn't have to decide (which
- # it would do incorrectly anyway because stdout wouled be a pipe).
+ # it would do incorrectly anyway because stdout would be a pipe).
def apply_auto_color(args):
if args and '--auto-color' in args:
- if sys.stdout.isatty():
+ if sys.stdout.isatty() and terminal_has_colors():
colorization = '--color'
else:
colorization = '--no-color'
More information about the Zope3-Checkins
mailing list