Update the Test{Cmd,Common}.py 0.36, with better diff reporting
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Fri, 24 Jul 2009 16:30:08 +0000 (16:30 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Fri, 24 Jul 2009 16:30:08 +0000 (16:30 +0000)
(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.

git-svn-id: http://scons.tigris.org/svn/scons/trunk@4307 fdb21ef1-2011-0410-befe-b5e4ea1792b1

QMTest/TestCmd.py
QMTest/TestCommon.py
test/SConstruct.py
test/option-n.py
test/scons-time/run/option/quiet.py
test/scons-time/run/option/verbose.py
test/sconsign/script/Configure.py

index cff50c78cecbdac704ad4f634bc9b5151d862e37..54a32bc38e420de2c9607624f52cd248eca7bade 100644 (file)
@@ -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.
index 5431b8cab7a4b14df6106f2c9cf9d594ed0d4a2b..5356facbdd9ff8f9679f8d581754c3d7ad0accf6 100644 (file)
@@ -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.
index 4b80f3e00b4cb56881a98ae2faf34b9a74980e52..f061728df126eec9b3c535b523f7213f52136c35 100644 (file)
@@ -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()
 
index abb02845172caeecbe60a3677f18ab8a57a8bc9f..b8dde0fb2ab06fcd2dca5aed3e31481d962e049c 100644 (file)
@@ -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):
index 58b5e823c38e1f59257078aeccf48ca4ed41e43f..2910e8e869fce45ee81bf37206cf1c4dee685b7b 100644 (file)
@@ -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'))
index 8b0be4ad12f19cd3b881bb4bc594620aa928b6d6..7f693d11cb7c3dfd37234082961c09704ca280b4 100644 (file)
@@ -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'))
index fb54dd23c4dbab699b18311fdf5ca1f9c45b0bc6..865b607556bac2f47b84a5493ac9361942a4ce75 100644 (file)
@@ -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)