tests: add (?) flag for optional lines
authorMatt Mackall <mpm@selenic.com>
Sun, 31 May 2015 16:59:34 -0500
changeset 25388 6025cac3d02f
parent 25387 390a10b7843b
child 25389 d6389553b6a1
tests: add (?) flag for optional lines When the test engine fails to match output on a line marked with (?), it will simply continue to the next expected line and try again. This allows simplifying tests that have either version-specific or non-fixed behavior, for instance: $ coin-flip heads (?) tails (?) (There's no form of back-tracking attempted, so optional matches should be specific.)
tests/run-tests.py
tests/test-run-tests.t
--- a/tests/run-tests.py	Wed Apr 15 09:07:54 2015 -0700
+++ b/tests/run-tests.py	Sun May 31 16:59:34 2015 -0500
@@ -1043,7 +1043,7 @@
             if salt in l:
                 lout, lcmd = l.split(salt, 1)
 
-            if lout:
+            while lout:
                 if not lout.endswith(b'\n'):
                     lout += b' (no-eol)\n'
 
@@ -1060,6 +1060,9 @@
                     elif r == '-glob':
                         lout = ''.join(el.rsplit(' (glob)', 1))
                         r = '' # Warn only this line.
+                    elif r == "retry":
+                        postout.append(b'  ' + el)
+                        continue
                     else:
                         log('\ninfo, unknown linematch result: %r\n' % r)
                         r = False
@@ -1074,6 +1077,15 @@
                         warnonly = 3 # for sure not
                     elif warnonly == 1: # Is "not yet" and line is warn only.
                         warnonly = 2 # Yes do warn.
+                break
+
+            # clean up any optional leftovers
+            while expected.get(pos, None):
+                el = expected[pos].pop(0)
+                if not el.endswith(" (?)\n"):
+                    expected[pos].insert(0, el)
+                    break
+                postout.append(b'  ' + el)
 
             if lcmd:
                 # Add on last return code.
@@ -1136,9 +1148,13 @@
 
     @staticmethod
     def linematch(el, l):
+        retry = False
         if el == l: # perfect match (fast)
             return True
         if el:
+            if el.endswith(" (?)\n"):
+                retry = "retry"
+                el = el[:-5] + "\n"
             if el.endswith(b" (esc)\n"):
                 if PYTHON3:
                     el = el[:-7].decode('unicode_escape') + '\n'
@@ -1148,7 +1164,7 @@
             if el == l or os.name == 'nt' and el[:-1] + b'\r\n' == l:
                 return True
             if el.endswith(b" (re)\n"):
-                return TTest.rematch(el[:-6], l)
+                return TTest.rematch(el[:-6], l) or retry
             if el.endswith(b" (glob)\n"):
                 # ignore '(glob)' added to l by 'replacements'
                 if l.endswith(b" (glob)\n"):
@@ -1156,7 +1172,7 @@
                 return TTest.globmatch(el[:-8], l)
             if os.altsep and l.replace(b'\\', b'/') == el:
                 return b'+glob'
-        return False
+        return retry
 
     @staticmethod
     def parsehghaveoutput(lines):
--- a/tests/test-run-tests.t	Wed Apr 15 09:07:54 2015 -0700
+++ b/tests/test-run-tests.t	Sun May 31 16:59:34 2015 -0500
@@ -21,7 +21,9 @@
   >   $ echo babar
   >   babar
   >   $ echo xyzzy
+  >   never happens (?)
   >   xyzzy
+  >   nor this (?)
   > EOF
 
   $ $TESTDIR/run-tests.py --with-hg=`which hg`
@@ -237,8 +239,8 @@
   *SALT* 2 0 (glob)
   + echo xyzzy
   xyzzy
-  + echo *SALT* 4 0 (glob)
-  *SALT* 4 0 (glob)
+  + echo *SALT* 6 0 (glob)
+  *SALT* 6 0 (glob)
   .
   # Ran 2 tests, 0 skipped, 0 warned, 0 failed.