From f4da14806c69fd1eb90a30ace625edc01d2ca5fc Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sat, 2 Jan 2010 14:59:27 +0100 Subject: [PATCH] #310: support exception messages in the ``testoutput`` blocks of the ``doctest`` extension. Also add minimal test cases for the doctest extension. --- CHANGES | 3 + doc/ext/doctest.rst | 28 +++++++++- sphinx/ext/doctest.py | 7 +++ tests/root/conf.py | 2 +- tests/root/contents.txt | 1 + tests/root/doctest.txt | 120 ++++++++++++++++++++++++++++++++++++++++ tests/test_doctest.py | 24 ++++++++ 7 files changed, 182 insertions(+), 3 deletions(-) create mode 100644 tests/root/doctest.txt create mode 100644 tests/test_doctest.py diff --git a/CHANGES b/CHANGES index 9a6a5e456..b6a2d3843 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,9 @@ Release 0.6.4 (in development) ============================== +* #310: support exception messages in the ``testoutput`` blocks of + the ``doctest`` extension. + * #293: line blocks are styled properly in HTML output. * #285: make the ``locale_dirs`` config value work again. diff --git a/doc/ext/doctest.rst b/doc/ext/doctest.rst index 19905dc7d..0c64f17a0 100644 --- a/doc/ext/doctest.rst +++ b/doc/ext/doctest.rst @@ -87,10 +87,30 @@ names. * ``hide``, a flag option, hides the code block in other builders. By default it is shown as a highlighted code block. + .. note:: + + Code in a ``testcode`` block is always executed all at once, no matter how + many statements it contains. Therefore, output will *not* be generated + for bare expressions -- use ``print``. Example:: + + .. testcode:: + + 1+1 # this will give no output! + print 2+2 # this will give output + + .. testoutput:: + + 4 + + Also, please be aware that since the doctest module does not support + mixing regular output and an exception message in the same snippet, this + applies to testcode/testoutput as well. + .. directive:: .. testoutput:: [group] - The corresponding output for the last :dir:`testcode` block. + The corresponding output, or the exception message, for the last + :dir:`testcode` block. This directive supports two options: @@ -102,6 +122,10 @@ names. Example:: + .. testcode:: + + print 'Output text.' + .. testoutput:: :hide: :options: -ELLIPSIS, +NORMALIZE_WHITESPACE @@ -111,7 +135,7 @@ names. The following is an example for the usage of the directives. The test via :dir:`doctest` and the test via :dir:`testcode` and :dir:`testoutput` are -completely equivalent. :: +equivalent. :: The parrot module ================= diff --git a/sphinx/ext/doctest.py b/sphinx/ext/doctest.py index 9132dd815..a424bdfec 100644 --- a/sphinx/ext/doctest.py +++ b/sphinx/ext/doctest.py @@ -355,7 +355,14 @@ Doctest summary options = code[1] and code[1].options or {} # disable processing as it is not needed options[doctest.DONT_ACCEPT_BLANKLINE] = True + # find out if we're testing an exception + m = parser._EXCEPTION_RE.match(output) + if m: + exc_msg = m.group('msg') + else: + exc_msg = None example = doctest.Example(code[0].code, output, + exc_msg=exc_msg, lineno=code[0].lineno, options=options) test = doctest.DocTest([example], {}, group.name, diff --git a/tests/root/conf.py b/tests/root/conf.py index 192a18832..6657714d7 100644 --- a/tests/root/conf.py +++ b/tests/root/conf.py @@ -6,7 +6,7 @@ sys.path.append(os.path.abspath('.')) extensions = ['ext', 'sphinx.ext.autodoc', 'sphinx.ext.jsmath', 'sphinx.ext.coverage', 'sphinx.ext.todo', - 'sphinx.ext.autosummary'] + 'sphinx.ext.autosummary', 'sphinx.ext.doctest'] jsmath_path = 'dummy.js' diff --git a/tests/root/contents.txt b/tests/root/contents.txt index 9891c64ef..aeca6a587 100644 --- a/tests/root/contents.txt +++ b/tests/root/contents.txt @@ -21,6 +21,7 @@ Contents: math autodoc autosummary + doctest Python diff --git a/tests/root/doctest.txt b/tests/root/doctest.txt new file mode 100644 index 000000000..35cdd589c --- /dev/null +++ b/tests/root/doctest.txt @@ -0,0 +1,120 @@ +Testing the doctest extension +============================= + +Simple doctest blocks +--------------------- + +>>> 1+1 +2 +>>> 1/0 +Traceback (most recent call last): + ... +ZeroDivisionError: integer division or modulo by zero + + +Special directives +------------------ + +* doctest + + .. doctest:: + + >>> 1+1 + 2 + >>> 1/0 + Traceback (most recent call last): + ... + ZeroDivisionError: integer division or modulo by zero + +* testcode/testoutput + + .. testcode:: + + print 1+1 + + .. testoutput:: + + 2 + + .. testcode:: + + 1/0 + + .. testoutput:: + + Traceback (most recent call last): + ... + ZeroDivisionError: integer division or modulo by zero + +* testsetup + + .. testsetup:: * + + from math import floor + + .. doctest:: + + >>> floor(1.2) + 1.0 + + .. testcode:: + + print floor(1.2) + + .. testoutput:: + + 1.0 + + >>> floor(1.2) + 1.0 + +* options for testcode/testoutput blocks + + .. testcode:: + :hide: + + print 'Output text.' + + .. testoutput:: + :hide: + :options: +NORMALIZE_WHITESPACE + + Output text. + +* grouping + + .. testsetup:: group1 + + from math import ceil + + ``ceil`` is now known in "group1", but not in others. + + .. doctest:: group1 + + >>> ceil(0.8) + 1.0 + + .. doctest:: group2 + + >>> ceil(0.8) + Traceback (most recent call last): + ... + NameError: name 'ceil' is not defined + + Interleaving testcode/testoutput: + + .. testcode:: group1 + + print ceil(0.8) + + .. testcode:: group2 + + print floor(0.8) + + .. testoutput:: group1 + + 1.0 + + .. testoutput:: group2 + + 0.0 diff --git a/tests/test_doctest.py b/tests/test_doctest.py new file mode 100644 index 000000000..b4b6bbe21 --- /dev/null +++ b/tests/test_doctest.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +""" + test_doctest + ~~~~~~~~~~~~ + + Test the doctest extension. + + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import sys +import StringIO + +from util import * + +status = StringIO.StringIO() + +@with_app(buildername='doctest', status=status) +def test_build(app): + app.builder.build_all() + if app.statuscode != 0: + print >>sys.stderr, status.getvalue() + assert False, 'failures in doctests'