Mercurial > hg
diff tests/run-tests.py @ 15236:4fae5df4b1bb
tests: add support for inline doctests in test files
This adds doctest like syntax to .t files, that can be interleaved with regular
shell code:
$ echo -n a > file
>>> print open('file').read()
a
>>> open('file', 'a').write('b')
$ cat file
ab
The syntax is exactly the same as regular doctests, so multiline statements
look like this:
>>> for i in range(3):
... print i
0
1
2
Each block has its own context, i.e.:
>>> x = 0
>>> print x
0
$ echo 'foo'
foo
>>> print x
will result in a NameError.
Errors are displayed in standard doctest format:
>>> print 'foo'
bar
--- /home/idan/dev/hg/default/tests/test-test.t
+++ /home/idan/dev/hg/default/tests/test-test.t.err
@@ -2,3 +2,16 @@
> >>> print 'foo'
> bar
> EOF
+ **********************************************************************
+ File "/tmp/tmps8X_0ohg-tst", line 1, in tmps8X_0ohg-tst
+ Failed example:
+ print 'foo'
+ Expected:
+ bar
+ Got:
+ foo
+ **********************************************************************
+ 1 items had failures:
+ 1 of 1 in tmps8X_0ohg-tst
+ ***Test Failed*** 1 failures.
+ [1]
As for the implementation, it's quite simple: when the test runner sees a line
starting with '>>>' it converts it, and all subsequent lines until the next
line that begins with '$' to a 'python -m heredoctest <<EOF' call with the
proper heredoc to follow. So if we have this test file:
>>> for c in 'abcd':
... print c
a
b
c
d
$ echo foo
foo
It gets converted to:
$ python -m heredoctest <<EOF
> >>> for c in 'abcd':
> ... print c
> a
> b
> c
> d
> EOF
$ echo foo
foo
And then processed like every other test file by converting it to a sh script.
author | Idan Kamara <idankk86@gmail.com> |
---|---|
date | Wed, 12 Oct 2011 22:01:14 +0200 |
parents | 0b21ae0a2366 |
children | 3efbb5e8bf5c |
line wrap: on
line diff
--- a/tests/run-tests.py Wed Oct 12 22:01:13 2011 +0200 +++ b/tests/run-tests.py Wed Oct 12 22:01:14 2011 +0200 @@ -521,6 +521,26 @@ def stringescape(s): return escapesub(escapef, s) +def transformtst(lines): + inblock = False + for l in lines: + if inblock: + if l.startswith(' $ '): + inblock = False + yield ' > EOF\n' + yield l + else: + yield ' > ' + l[2:] + else: + if l.startswith(' >>> '): + inblock = True + yield ' $ %s -m heredoctest <<EOF\n' % PYTHON + yield ' > ' + l[2:] + else: + yield l + if inblock: + yield ' > EOF\n' + def tsttest(test, wd, options, replacements): t = open(test) out = [] @@ -530,7 +550,7 @@ pos = prepos = -1 after = {} expected = {} - for n, l in enumerate(t): + for n, l in enumerate(transformtst(t)): if not l.endswith('\n'): l += '\n' if l.startswith(' $ '): # commands @@ -833,7 +853,7 @@ refout = None # to match "out is None" elif os.path.exists(ref): f = open(ref, "r") - refout = splitnewlines(f.read()) + refout = list(transformtst(splitnewlines(f.read()))) f.close() else: refout = []