summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2009-07-24 16:30:08 (GMT)
committerSteven Knight <knight@baldmt.com>2009-07-24 16:30:08 (GMT)
commitf1ac141da175ed8939044f9a55146980cf4634a8 (patch)
treef5b5919c4ab0244fefb6cde50eac274455c1a895
parent10dc447016536d663d6031edc04e09cc50948130 (diff)
downloadSCons-f1ac141da175ed8939044f9a55146980cf4634a8.zip
SCons-f1ac141da175ed8939044f9a55146980cf4634a8.tar.gz
SCons-f1ac141da175ed8939044f9a55146980cf4634a8.tar.bz2
Update the Test{Cmd,Common}.py 0.36, with better diff reporting
(specifically of output matches using regular expressions). Update tests for corresponding inteface changes. Add use of diff_re() to test/sconsign/script/Configure.py so we can get accurate information about its buildbot failure.
-rw-r--r--QMTest/TestCmd.py111
-rw-r--r--QMTest/TestCommon.py66
-rw-r--r--test/SConstruct.py2
-rw-r--r--test/option-n.py3
-rw-r--r--test/scons-time/run/option/quiet.py4
-rw-r--r--test/scons-time/run/option/verbose.py4
-rw-r--r--test/sconsign/script/Configure.py3
7 files changed, 114 insertions, 79 deletions
diff --git a/QMTest/TestCmd.py b/QMTest/TestCmd.py
index cff50c7..54a32bc 100644
--- a/QMTest/TestCmd.py
+++ b/QMTest/TestCmd.py
@@ -25,6 +25,7 @@ There are a bunch of keyword arguments available at instantiation:
subdir = 'subdir',
verbose = Boolean,
match = default_match_function,
+ diff = default_diff_function,
combine = Boolean)
There are a bunch of methods that let you do different things:
@@ -103,6 +104,11 @@ There are a bunch of methods that let you do different things:
test.symlink(target, link)
+ test.banner(string)
+ test.banner(string, width)
+
+ test.diff(actual, expected)
+
test.match(actual, expected)
test.match_exact("actual 1\nactual 2\n", "expected 1\nexpected 2\n")
@@ -164,6 +170,24 @@ in the same way as the match_*() methods described above.
test = TestCmd.TestCmd(match = TestCmd.match_re_dotall)
+The TestCmd module provides unbound functions that can be used for the
+"diff" argument to TestCmd.TestCmd instantiation:
+
+ import TestCmd
+
+ test = TestCmd.TestCmd(match = TestCmd.match_re,
+ diff = TestCmd.diff_re)
+
+ test = TestCmd.TestCmd(diff = TestCmd.simple_diff)
+
+The "diff" argument can also be used with standard difflib functions:
+
+ import difflib
+
+ test = TestCmd.TestCmd(diff = difflib.context_diff)
+
+ test = TestCmd.TestCmd(diff = difflib.unified_diff)
+
Lastly, the where_is() method also exists in an unbound function
version.
@@ -191,8 +215,8 @@ version.
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
__author__ = "Steven Knight <knight at baldmt dot com>"
-__revision__ = "TestCmd.py 0.35.D001 2009/02/08 07:10:39 knight"
-__version__ = "0.35"
+__revision__ = "TestCmd.py 0.36.D001 2009/07/24 08:45:26 knight"
+__version__ = "0.36"
import errno
import os
@@ -220,6 +244,11 @@ __all__ = [
'TestCmd'
]
+try:
+ import difflib
+except ImportError:
+ __all__.append('simple_diff')
+
def is_List(e):
return type(e) is types.ListType \
or isinstance(e, UserList.UserList)
@@ -424,6 +453,36 @@ def match_re_dotall(lines = None, res = None):
if expr.match(lines):
return 1
+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 diff_re(a, b, fromfile='', tofile='',
fromfiledate='', tofiledate='', n=3, lineterm='\n'):
"""
@@ -456,8 +515,11 @@ def diff_re(a, b, fromfile='', tofile='',
return result
if os.name == 'java':
+
python_executable = os.path.join(sys.prefix, 'jython')
+
else:
+
python_executable = sys.executable
if sys.platform == 'win32':
@@ -756,6 +818,7 @@ def recv_some(p, t=.1, e=1, tr=5, stderr=0):
time.sleep(max((x-time.time())/tr, 0))
return ''.join(y)
+# TODO(3.0: rewrite to use memoryview()
def send_all(p, data):
while len(data):
sent = p.send(data)
@@ -776,6 +839,7 @@ class TestCmd:
subdir = None,
verbose = None,
match = None,
+ diff = None,
combine = 0,
universal_newlines = 1):
self._cwd = os.getcwd()
@@ -791,9 +855,20 @@ class TestCmd:
self.combine = combine
self.universal_newlines = universal_newlines
if not match is None:
- self.match_func = match
+ self.match_function = match
else:
- self.match_func = match_re
+ self.match_function = match_re
+ if not diff is None:
+ self.diff_function = diff
+ else:
+ try:
+ difflib
+ except NameError:
+ pass
+ else:
+ self.diff_function = simple_diff
+ #self.diff_function = difflib.context_diff
+ #self.diff_function = difflib.unified_diff
self._dirlist = []
self._preserve = {'pass_test': 0, 'fail_test': 0, 'no_result': 0}
if os.environ.has_key('PRESERVE') and not os.environ['PRESERVE'] is '':
@@ -826,6 +901,14 @@ class TestCmd:
def __repr__(self):
return "%x" % id(self)
+ 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))
+
if os.name == 'posix':
def escape(self, arg):
@@ -930,9 +1013,21 @@ class TestCmd:
"""
self.description = description
-# def diff(self):
-# """Diff two arrays.
-# """
+ 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 fail_test(self, condition = 1, function = None, skip = 0):
"""Cause the test to fail.
@@ -954,7 +1049,7 @@ class TestCmd:
def match(self, lines, matches):
"""Compare actual and expected file contents.
"""
- return self.match_func(lines, matches)
+ return self.match_function(lines, matches)
def match_exact(self, lines, matches):
"""Compare actual and expected file contents.
diff --git a/QMTest/TestCommon.py b/QMTest/TestCommon.py
index 5431b8c..5356fac 100644
--- a/QMTest/TestCommon.py
+++ b/QMTest/TestCommon.py
@@ -87,8 +87,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.35.D001 2009/02/08 07:10:39 knight"
-__version__ = "0.35"
+__revision__ = "TestCommon.py 0.36.D001 2009/07/24 08:45:26 knight"
+__version__ = "0.36"
import copy
import os
@@ -169,36 +169,6 @@ 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)
@@ -247,38 +217,6 @@ 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.
diff --git a/test/SConstruct.py b/test/SConstruct.py
index 4b80f3e..f061728 100644
--- a/test/SConstruct.py
+++ b/test/SConstruct.py
@@ -36,7 +36,7 @@ test.run(arguments = ".",
scons: \*\*\* No SConstruct file found.
""" + TestSCons.file_expr)
-test.match_func = TestCmd.match_exact
+test.match_function = TestCmd.match_exact
wpath = test.workpath()
diff --git a/test/option-n.py b/test/option-n.py
index abb0284..b8dde0f 100644
--- a/test/option-n.py
+++ b/test/option-n.py
@@ -168,7 +168,8 @@ test.fail_test(os.path.exists(test.workpath('build', 'f4.in')))
# test Configure-calls in conjunction with -n
test.subdir('configure')
-test.match_func = TestSCons.match_re_dotall
+test.match_function = TestSCons.match_re_dotall
+test.diff_function = TestSCons.diff_re
test.write('configure/SConstruct',
"""def CustomTest(context):
def userAction(target,source,env):
diff --git a/test/scons-time/run/option/quiet.py b/test/scons-time/run/option/quiet.py
index 58b5e82..2910e8e 100644
--- a/test/scons-time/run/option/quiet.py
+++ b/test/scons-time/run/option/quiet.py
@@ -34,8 +34,8 @@ import TestSCons_time
python = TestSCons_time.python
-test = TestSCons_time.TestSCons_time(match = TestSCons_time.match_re)
-test.diff_function = TestSCons_time.diff_re
+test = TestSCons_time.TestSCons_time(match = TestSCons_time.match_re,
+ diff = TestSCons_time.diff_re)
scons_py = re.escape(test.workpath('src', 'script', 'scons.py'))
src_engine = re.escape(test.workpath('src', 'engine'))
diff --git a/test/scons-time/run/option/verbose.py b/test/scons-time/run/option/verbose.py
index 8b0be4a..7f693d1 100644
--- a/test/scons-time/run/option/verbose.py
+++ b/test/scons-time/run/option/verbose.py
@@ -35,8 +35,8 @@ import TestSCons_time
_python_ = re.escape(TestSCons_time._python_)
-test = TestSCons_time.TestSCons_time(match = TestSCons_time.match_re)
-test.diff_function = TestSCons_time.diff_re
+test = TestSCons_time.TestSCons_time(match = TestSCons_time.match_re,
+ diff = TestSCons_time.diff_re)
scons_py = re.escape(test.workpath('src', 'script', 'scons.py'))
src_engine = re.escape(test.workpath('src', 'engine'))
diff --git a/test/sconsign/script/Configure.py b/test/sconsign/script/Configure.py
index fb54dd2..865b607 100644
--- a/test/sconsign/script/Configure.py
+++ b/test/sconsign/script/Configure.py
@@ -37,7 +37,8 @@ import TestSConsign
_obj = TestSCons._obj
-test = TestSConsign.TestSConsign(match = TestSConsign.match_re)
+test = TestSConsign.TestSConsign(match = TestSConsign.match_re,
+ diff = TestSConsign.diff_re)
CC = test.detect('CC', norm=1)
CC_dir, CC_file = os.path.split(CC)