561 def tsttest(test, wd, options, replacements): |
561 def tsttest(test, wd, options, replacements): |
562 # We generate a shell script which outputs unique markers to line |
562 # We generate a shell script which outputs unique markers to line |
563 # up script results with our source. These markers include input |
563 # up script results with our source. These markers include input |
564 # line number and the last return code |
564 # line number and the last return code |
565 salt = "SALT" + str(time.time()) |
565 salt = "SALT" + str(time.time()) |
566 def addsalt(line): |
566 def addsalt(line, inpython): |
567 script.append('echo %s %s $?\n' % (salt, line)) |
567 if inpython: |
|
568 script.append('%s %d 0\n' % (salt, line)) |
|
569 else: |
|
570 script.append('echo %s %s $?\n' % (salt, line)) |
568 |
571 |
569 # After we run the shell script, we re-unify the script output |
572 # After we run the shell script, we re-unify the script output |
570 # with non-active parts of the source, with synchronization by our |
573 # with non-active parts of the source, with synchronization by our |
571 # SALT line number markers. The after table contains the |
574 # SALT line number markers. The after table contains the |
572 # non-active components, ordered by line number |
575 # non-active components, ordered by line number |
587 script = [] |
590 script = [] |
588 for n, l in enumerate(t): |
591 for n, l in enumerate(t): |
589 if not l.endswith('\n'): |
592 if not l.endswith('\n'): |
590 l += '\n' |
593 l += '\n' |
591 if l.startswith(' >>> '): # python inlines |
594 if l.startswith(' >>> '): # python inlines |
|
595 after.setdefault(pos, []).append(l) |
|
596 prepos = pos |
|
597 pos = n |
592 if not inpython: |
598 if not inpython: |
593 # we've just entered a Python block, add the header |
599 # we've just entered a Python block, add the header |
594 inpython = True |
600 inpython = True |
595 addsalt(n) |
601 addsalt(prepos, False) # make sure we report the exit code |
596 script.append('%s -m heredoctest <<EOF\n' % PYTHON) |
602 script.append('%s -m heredoctest <<EOF\n' % PYTHON) |
597 prepos = pos |
603 addsalt(n, True) |
598 pos = n |
604 script.append(l[2:]) |
|
605 if l.startswith(' ... '): # python inlines |
599 after.setdefault(prepos, []).append(l) |
606 after.setdefault(prepos, []).append(l) |
600 script.append(l[2:]) |
607 script.append(l[2:]) |
601 elif l.startswith(' $ '): # commands |
608 elif l.startswith(' $ '): # commands |
602 if inpython: |
609 if inpython: |
603 script.append("EOF\n") |
610 script.append("EOF\n") |
604 inpython = False |
611 inpython = False |
605 after.setdefault(pos, []).append(l) |
612 after.setdefault(pos, []).append(l) |
606 prepos = pos |
613 prepos = pos |
607 pos = n |
614 pos = n |
608 addsalt(n) |
615 addsalt(n, False) |
609 script.append(l[4:]) |
616 script.append(l[4:]) |
610 elif l.startswith(' > '): # continuations |
617 elif l.startswith(' > '): # continuations |
611 after.setdefault(prepos, []).append(l) |
618 after.setdefault(prepos, []).append(l) |
612 script.append(l[4:]) |
619 script.append(l[4:]) |
613 elif l.startswith(' '): # results |
620 elif l.startswith(' '): # results |
614 if inpython: |
621 # queue up a list of expected results |
615 script.append(l[2:]) |
622 expected.setdefault(pos, []).append(l[2:]) |
616 after.setdefault(prepos, []).append(l) |
|
617 else: |
|
618 # queue up a list of expected results |
|
619 expected.setdefault(pos, []).append(l[2:]) |
|
620 else: |
623 else: |
621 if inpython: |
624 if inpython: |
622 script.append("EOF\n") |
625 script.append("EOF\n") |
623 inpython = False |
626 inpython = False |
624 # non-command/result - queue up for merged output |
627 # non-command/result - queue up for merged output |
625 after.setdefault(pos, []).append(l) |
628 after.setdefault(pos, []).append(l) |
626 |
629 |
627 if inpython: |
630 if inpython: |
628 script.append("EOF\n") |
631 script.append("EOF\n") |
629 addsalt(n + 1) |
632 addsalt(n + 1, False) |
630 |
633 |
631 # Write out the script and execute it |
634 # Write out the script and execute it |
632 fd, name = tempfile.mkstemp(suffix='hg-tst') |
635 fd, name = tempfile.mkstemp(suffix='hg-tst') |
633 try: |
636 try: |
634 for l in script: |
637 for l in script: |