summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSylvain Thenault <sylvain.thenault@logilab.fr>2008-10-16 07:54:34 +0200
committerSylvain Thenault <sylvain.thenault@logilab.fr>2008-10-16 07:54:34 +0200
commitcaeb6e6bfce040fc4939a1b28f52a27054ff378d (patch)
tree0efa868760c9b90497ae870de0ae463fc5f42d0e
parentdcbe0edcda83d5480596d2e4316d191bcbac5101 (diff)
parent361640698cf03f9447c487ec9f38628bef9b72fd (diff)
downloadlogilab-common-caeb6e6bfce040fc4939a1b28f52a27054ff378d.tar.gz
merge
-rw-r--r--decorators.py39
-rw-r--r--logging_ext.py11
-rw-r--r--test/unittest_decorators.py74
-rw-r--r--testlib.py28
4 files changed, 144 insertions, 8 deletions
diff --git a/decorators.py b/decorators.py
index 2c2834d..64b5e08 100644
--- a/decorators.py
+++ b/decorators.py
@@ -8,6 +8,7 @@ __docformat__ = "restructuredtext en"
from types import MethodType
from time import clock
+import sys, re
# XXX rewrite so we can use the decorator syntax when keyarg has to be specified
@@ -143,3 +144,41 @@ def locked(acquire, release):
return wrapper
return decorator
+def require_version(version):
+ """ Compare version of python interpretor to the given one. Skip the test
+ if older.
+ """
+ def check_require_version(f):
+ version_elements = version.split('.')
+ try:
+ compare = tuple([int(v) for v in version_elements])
+ except ValueError:
+ raise ValueError('%s is not a correct version : should be X.Y[.Z].' % version)
+ current = sys.version_info[:3]
+ #print 'comp', current, compare
+ if current < compare:
+ #print 'version too old'
+ def new_f(self, *args, **kwargs):
+ self.skip('Need at least %s version of python. Current version is %s.' % (version, '.'.join([str(element) for element in current])))
+ new_f.__name__ = f.__name__
+ return new_f
+ else:
+ #print 'version young enough'
+ return f
+ return check_require_version
+
+def require_module(module):
+ """ Check if the given module is loaded. Skip the test if not.
+ """
+ def check_require_module(f):
+ try:
+ __import__(module)
+ #print module, 'imported'
+ return f
+ except ImportError:
+ #print module, 'can not be imported'
+ def new_f(self, *args, **kwargs):
+ self.skip('%s can not be imported.' % module)
+ new_f.__name__ = f.__name__
+ return new_f
+ return check_require_module
diff --git a/logging_ext.py b/logging_ext.py
index 0012f0b..b788c00 100644
--- a/logging_ext.py
+++ b/logging_ext.py
@@ -20,8 +20,8 @@ class ColorFormatter(logging.Formatter):
"""
A color Formatter for the logging standard module.
- By default, colorize CRITICAL and ERROR in red, WARNING in orange
- and INFO in yellow.
+ By default, colorize CRITICAL and ERROR in red, WARNING in orange, INFO in
+ green and DEBUG in yellow.
self.colors is customizable via the 'color' constructor argument (dictionnary).
@@ -35,12 +35,13 @@ class ColorFormatter(logging.Formatter):
self.colors = {'CRITICAL': 'red',
'ERROR': 'red',
'WARNING': 'magenta',
- 'INFO': 'yellow',
+ 'INFO': 'green',
+ 'DEBUG': 'yellow',
}
if colors is not None:
assert isinstance(colors, dict)
- self.colors.update(colors)
-
+ self.colors.update(colors)
+
def format(self, record):
msg = logging.Formatter.format(self, record)
if record.levelname in self.colors:
diff --git a/test/unittest_decorators.py b/test/unittest_decorators.py
new file mode 100644
index 0000000..855f242
--- /dev/null
+++ b/test/unittest_decorators.py
@@ -0,0 +1,74 @@
+import sys
+from logilab.common.testlib import TestCase, unittest_main, TestSuite
+from logilab.common.decorators import require_version, require_module
+
+class DecoratorsTC(TestCase):
+ def test_require_version_good(self):
+ """ should return the same function
+ """
+ def func() :
+ pass
+ sys.version_info = (2, 5, 5, 'final', 4)
+ current = sys.version_info[:3]
+ compare = ('2.4', '2.5', '2.5.4', '2.5.5')
+ for version in compare:
+ decorator = require_version(version)
+ self.assertEquals(func, decorator(func), '%s =< %s : function \
+ return by the decorator should be the same.' % (version,
+ '.'.join([str(element) for element in current])))
+
+ def test_require_version_bad(self):
+ """ should return a different function : skipping test
+ """
+ def func() :
+ pass
+ sys.version_info = (2, 5, 5, 'final', 4)
+ current = sys.version_info[:3]
+ compare = ('2.5.6', '2.6', '2.6.5')
+ for version in compare:
+ decorator = require_version(version)
+ self.assertNotEquals(func, decorator(func), '%s >= %s : function \
+ return by the decorator should NOT be the same.'
+ % ('.'.join([str(element) for element in current]), version))
+
+ def test_require_version_exception(self):
+ """ should throw a ValueError exception
+ """
+ def func() :
+ pass
+ compare = ('2.5.a', '2.a', 'azerty')
+ for version in compare:
+ decorator = require_version(version)
+ self.assertRaises(ValueError, decorator, func)
+
+ def test_require_module_good(self):
+ """ should return the same function
+ """
+ def func() :
+ pass
+ module = 'sys'
+ decorator = require_module(module)
+ self.assertEquals(func, decorator(func), 'module %s exists : function \
+ return by the decorator should be the same.' % module)
+
+ def test_require_module_bad(self):
+ """ should return a different function : skipping test
+ """
+ def func() :
+ pass
+ modules = ('bla', 'blo', 'bli')
+ for module in modules:
+ try:
+ __import__(module)
+ pass
+ except ImportError:
+ decorator = require_module(module)
+ self.assertNotEquals(func, decorator(func), 'module %s does \
+ not exist : function return by the decorator should \
+ NOT be the same.' % module)
+ return
+ print 'all modules in %s exist. Could not test %s' % (', '.join(modules),
+ sys._getframe().f_code.co_name)
+
+if __name__ == '__main__':
+ unittest_main()
diff --git a/testlib.py b/testlib.py
index 0838653..f9cb971 100644
--- a/testlib.py
+++ b/testlib.py
@@ -55,6 +55,13 @@ except ImportError:
pass
test_support = TestSupport()
+try:
+ from pygments import highlight, lexers, formatters
+ # only print in color if executed from a terminal
+ PYGMENTS_FOUND = True
+except ImportError:
+ PYGMENTS_FOUND = False
+
from logilab.common.deprecation import class_renamed, deprecated_function, \
obsolete
# pylint: disable-msg=W0622
@@ -63,6 +70,7 @@ from logilab.common.compat import set, enumerate, any
from logilab.common.modutils import load_module_from_name
from logilab.common.debugger import Debugger
from logilab.common.decorators import cached
+from logilab.common import textutils
__all__ = ['main', 'unittest_main', 'find_tests', 'run_test', 'spawn']
@@ -401,8 +409,16 @@ class SkipAwareTestResult(unittest._TextTestResult):
def printErrorList(self, flavour, errors):
for (_, descr), (test, err) in zip(self.descrs_for(flavour), errors):
+ if PYGMENTS_FOUND and os.isatty(self.stream.fileno()):
+ err = highlight(err, lexers.PythonLexer(),
+ formatters.terminal.TerminalFormatter())
self.stream.writeln(self.separator1)
- self.stream.writeln("%s: %s" % (flavour, descr))
+ if os.isatty(self.stream.fileno()):
+ self.stream.writeln("%s: %s" % (
+ textutils.colorize_ansi(flavour, color='red'), descr))
+ else:
+ self.stream.writeln("%s: %s" % (flavour, descr))
+
self.stream.writeln(self.separator2)
self.stream.writeln("%s" % err)
try:
@@ -537,9 +553,15 @@ class SkipAwareTextTestRunner(unittest.TextTestRunner):
(run, run != 1 and "s" or "", timeTaken))
self.stream.writeln()
if not result.wasSuccessful():
- self.stream.write("FAILED")
+ if os.isatty(self.stream.fileno()):
+ self.stream.write(textutils.colorize_ansi("FAILED", color='red'))
+ else:
+ self.stream.write("FAILED")
else:
- self.stream.write("OK")
+ if os.isatty(self.stream.fileno()):
+ self.stream.write(textutils.colorize_ansi("OK", color='green'))
+ else:
+ self.stream.write("OK")
failed, errored, skipped = map(len, (result.failures, result.errors,
result.skipped))