summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2005-10-15 13:49:37 (GMT)
committerSteven Knight <knight@baldmt.com>2005-10-15 13:49:37 (GMT)
commit9485978a050ab937ac9cff0c64273a693d19911a (patch)
tree9236576d3820a0245680a11e67df5b2f8fe584f1
parentaf962864b108d8fdd654edaf3c0300404ca07e3e (diff)
downloadSCons-9485978a050ab937ac9cff0c64273a693d19911a.zip
SCons-9485978a050ab937ac9cff0c64273a693d19911a.tar.gz
SCons-9485978a050ab937ac9cff0c64273a693d19911a.tar.bz2
Update to latest TestCommon.py with support for diffing actual/expected contents and output.
-rw-r--r--etc/TestCmd.py4
-rw-r--r--etc/TestCommon.py98
2 files changed, 78 insertions, 24 deletions
diff --git a/etc/TestCmd.py b/etc/TestCmd.py
index 83696ea..cd66245 100644
--- a/etc/TestCmd.py
+++ b/etc/TestCmd.py
@@ -176,8 +176,8 @@ version.
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
__author__ = "Steven Knight <knight at baldmt dot com>"
-__revision__ = "TestCmd.py 0.17.D001 2005/10/08 22:58:27 knight"
-__version__ = "0.17"
+__revision__ = "TestCmd.py 0.18.D001 2005/10/15 06:40:23 knight"
+__version__ = "0.18"
import os
import os.path
diff --git a/etc/TestCommon.py b/etc/TestCommon.py
index f2daf57..76ee8f0 100644
--- a/etc/TestCommon.py
+++ b/etc/TestCommon.py
@@ -80,8 +80,8 @@ The TestCommon module also provides the following variables
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
__author__ = "Steven Knight <knight at baldmt dot com>"
-__revision__ = "TestCommon.py 0.14.D001 2005/08/15 23:02:35 knight"
-__version__ = "0.14"
+__revision__ = "TestCommon.py 0.18.D001 2005/10/15 06:40:23 knight"
+__version__ = "0.18"
import os
import os.path
@@ -96,6 +96,7 @@ from TestCmd import __all__
__all__.extend([ 'TestCommon',
'TestFailed',
+ 'TestNoResult',
'exe_suffix',
'obj_suffix',
'shobj_suffix',
@@ -147,6 +148,36 @@ else:
dll_prefix = 'lib'
dll_suffix = '.so'
+try:
+ import difflib
+except ImportError:
+ pass
+else:
+ def simple_diff(a, b, fromfile='', tofile='',
+ fromfiledate='', tofiledate='', n=3, lineterm='\n'):
+ """
+ A function with the same calling signature as difflib.context_diff
+ (diff -c) and difflib.unified_diff (diff -u) but which prints
+ output like the simple, unadorned 'diff" command.
+ """
+ sm = difflib.SequenceMatcher(None, a, b)
+ def comma(x1, x2):
+ return x1+1 == x2 and str(x2) or '%s,%s' % (x1+1, x2)
+ result = []
+ for op, a1, a2, b1, b2 in sm.get_opcodes():
+ if op == 'delete':
+ result.append("%sd%d" % (comma(a1, a2), b1))
+ result.extend(map(lambda l: '< ' + l, a[a1:a2]))
+ elif op == 'insert':
+ result.append("%da%s" % (a1, comma(b1, b2)))
+ result.extend(map(lambda l: '> ' + l, b[b1:b2]))
+ elif op == 'replace':
+ result.append("%sc%s" % (comma(a1, a2), comma(b1, b2)))
+ result.extend(map(lambda l: '< ' + l, a[a1:a2]))
+ result.append('---')
+ result.extend(map(lambda l: '> ' + l, b[b1:b2]))
+ return result
+
def is_List(e):
return type(e) is types.ListType \
or isinstance(e, UserList.UserList)
@@ -212,6 +243,38 @@ class TestCommon(TestCmd):
"""
apply(TestCmd.__init__, [self], kw)
os.chdir(self.workdir)
+ try:
+ difflib
+ except NameError:
+ pass
+ else:
+ self.diff_function = simple_diff
+ #self.diff_function = difflib.context_diff
+ #self.diff_function = difflib.unified_diff
+
+ banner_char = '='
+ banner_width = 80
+
+ def banner(self, s, width=None):
+ if width is None:
+ width = self.banner_width
+ return s + self.banner_char * (width - len(s))
+
+ try:
+ difflib
+ except NameError:
+ def diff(self, a, b, name, *args, **kw):
+ print self.banner('Expected %s' % name)
+ print a
+ print self.banner('Actual %s' % name)
+ print b
+ else:
+ def diff(self, a, b, name, *args, **kw):
+ print self.banner(name)
+ args = (a.splitlines(), b.splitlines()) + args
+ lines = apply(self.diff_function, args, kw)
+ for l in lines:
+ print l
def must_be_writable(self, *files):
"""Ensures that the specified file(s) exist and are writable.
@@ -236,9 +299,9 @@ class TestCommon(TestCmd):
contains = (string.find(file_contents, required) != -1)
if not contains:
print "File `%s' does not contain required string." % file
- print "Required string ====="
+ print self.banner('Required string ')
print required
- print "%s contents =====" % file
+ print self.banner('%s contents ' % file)
print file_contents
self.fail_test(not contains)
@@ -267,10 +330,7 @@ class TestCommon(TestCmd):
raise
except:
print "Unexpected contents of `%s'" % file
- print "EXPECTED contents ======"
- print expect
- print "ACTUAL contents ========"
- print file_contents
+ self.diff(expect, file_contents, 'contents ')
raise
def must_not_exist(self, *files):
@@ -344,9 +404,9 @@ class TestCommon(TestCmd):
except KeyboardInterrupt:
raise
except:
- print "STDOUT ============"
+ print self.banner('STDOUT ')
print self.stdout()
- print "STDERR ============"
+ print self.banner('STDERR ')
print self.stderr()
raise
if _failed(self, status):
@@ -354,26 +414,20 @@ class TestCommon(TestCmd):
if status != 0:
expect = " (expected %s)" % str(status)
print "%s returned %s%s" % (self.program, str(_status(self)), expect)
- print "STDOUT ============"
+ print self.banner('STDOUT ')
print self.stdout()
- print "STDERR ============"
+ print self.banner('STDERR ')
print self.stderr()
raise TestFailed
if not stdout is None and not match(self.stdout(), stdout):
- print "Expected STDOUT =========="
- print stdout
- print "Actual STDOUT ============"
- print self.stdout()
+ self.diff(stdout, self.stdout(), 'STDOUT ')
stderr = self.stderr()
if stderr:
- print "STDERR ==================="
+ print self.banner('STDERR ')
print stderr
raise TestFailed
if not stderr is None and not match(self.stderr(), stderr):
- print "STDOUT ==================="
+ print self.banner('STDOUT ')
print self.stdout()
- print "Expected STDERR =========="
- print stderr
- print "Actual STDERR ============"
- print self.stderr()
+ self.diff(stderr, self.stderr(), 'STDERR ')
raise TestFailed