diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/root/_templates/layout.html | 7 | ||||
| -rw-r--r-- | tests/root/conf.py | 26 | ||||
| -rw-r--r-- | tests/root/contents.txt | 3 | ||||
| -rw-r--r-- | tests/root/desc.txt | 71 | ||||
| -rw-r--r-- | tests/root/extapi.txt | 10 | ||||
| -rw-r--r-- | tests/root/markup.txt | 113 | ||||
| -rw-r--r-- | tests/root/objects.txt | 110 | ||||
| -rw-r--r-- | tests/test_autodoc.py | 37 | ||||
| -rw-r--r-- | tests/test_build.py | 98 | ||||
| -rw-r--r-- | tests/test_build_html.py | 90 | ||||
| -rw-r--r-- | tests/test_build_latex.py | 94 | ||||
| -rw-r--r-- | tests/test_config.py | 2 | ||||
| -rw-r--r-- | tests/test_coverage.py | 2 | ||||
| -rw-r--r-- | tests/test_env.py | 20 | ||||
| -rw-r--r-- | tests/test_intersphinx.py | 112 | ||||
| -rw-r--r-- | tests/test_markup.py | 25 | ||||
| -rw-r--r-- | tests/test_metadata.py | 5 | ||||
| -rw-r--r-- | tests/test_quickstart.py | 6 | ||||
| -rw-r--r-- | tests/test_search.py | 4 | ||||
| -rw-r--r-- | tests/util.py | 5 |
20 files changed, 595 insertions, 245 deletions
diff --git a/tests/root/_templates/layout.html b/tests/root/_templates/layout.html index 7f290fc1..82125df8 100644 --- a/tests/root/_templates/layout.html +++ b/tests/root/_templates/layout.html @@ -1,4 +1,5 @@ {% extends "!layout.html" %} + {% block extrahead %} {# html_context variable from conf.py #} <meta name="hc" content="{{ hckey }}" /> @@ -6,3 +7,9 @@ <meta name="hc_co" content="{{ hckey_co }}" /> {{ super() }} {% endblock %} + +{% block sidebartoc %} +{# display global TOC in addition to local TOC #} +{{ super() }} +{{ toctree(collapse=False, maxdepth=-1) }} +{% endblock %}
\ No newline at end of file diff --git a/tests/root/conf.py b/tests/root/conf.py index a3783511..71f48ce6 100644 --- a/tests/root/conf.py +++ b/tests/root/conf.py @@ -25,13 +25,15 @@ today_fmt = '%B %d, %Y' exclude_patterns = ['_build', '**/excluded.*'] keep_warnings = True pygments_style = 'sphinx' +show_authors = True rst_epilog = '.. |subst| replace:: global substitution' html_theme = 'testtheme' html_theme_path = ['.'] html_theme_options = {'testopt': 'testoverride'} -html_sidebars = {'**': 'customsb.html', 'contents': 'contentssb.html'} +html_sidebars = {'**': 'customsb.html', + 'contents': ['contentssb.html', 'localtoc.html'] } html_style = 'default.css' html_static_path = ['_static', 'templated.css_t'] html_last_updated_fmt = '%b %d, %Y' @@ -49,7 +51,7 @@ latex_additional_files = ['svgimg.svg'] value_from_conf_py = 84 coverage_c_path = ['special/*.h'] -coverage_c_regexes = {'cfunction': r'^PyAPI_FUNC\(.*\)\s+([^_][\w_]+)'} +coverage_c_regexes = {'function': r'^PyAPI_FUNC\(.*\)\s+([^_][\w_]+)'} autosummary_generate = ['autosummary'] @@ -59,7 +61,12 @@ extlinks = {'issue': ('http://bugs.python.org/issue%s', 'issue '), # modify tags from conf.py tags.add('confpytag') + +# -- extension API + +from docutils import nodes from sphinx import addnodes +from sphinx.util.compat import Directive def userdesc_parse(env, sig, signode): x, y = sig.split(':') @@ -68,7 +75,18 @@ def userdesc_parse(env, sig, signode): signode[-1] += addnodes.desc_parameter(y, y) return x +def functional_directive(name, arguments, options, content, lineno, + content_offset, block_text, state, state_machine): + return [nodes.strong(text='from function: %s' % options['opt'])] + +class ClassDirective(Directive): + option_spec = {'opt': lambda x: x} + def run(self): + return [nodes.strong(text='from class: %s' % self.options['opt'])] + def setup(app): app.add_config_value('value_from_conf_py', 42, False) - app.add_description_unit('userdesc', 'userdescrole', '%s (userdesc)', - userdesc_parse) + app.add_directive('funcdir', functional_directive, opt=lambda x: x) + app.add_directive('clsdir', ClassDirective) + app.add_object_type('userdesc', 'userdescrole', '%s (userdesc)', + userdesc_parse, objname='user desc') diff --git a/tests/root/contents.txt b/tests/root/contents.txt index c9005d57..e052e04b 100644 --- a/tests/root/contents.txt +++ b/tests/root/contents.txt @@ -11,12 +11,13 @@ Contents: :maxdepth: 2 :numbered: + extapi images subdir/images subdir/includes includes markup - desc + objects bom math autodoc diff --git a/tests/root/desc.txt b/tests/root/desc.txt deleted file mode 100644 index d6915dc2..00000000 --- a/tests/root/desc.txt +++ /dev/null @@ -1,71 +0,0 @@ -Testing description units -========================= - -.. function:: func_without_module(a, b, *c[, d]) - - Does something. - -.. function:: func_without_body() - -.. function:: func_noindex - :noindex: - - -.. module:: mod - :synopsis: Module synopsis. - :platform: UNIX - -.. function:: func_in_module - -.. class:: Cls - - .. method:: meth1 - - .. staticmethod:: meths - - .. attribute:: attr - -.. explicit class given -.. method:: Cls.meth2 - -.. explicit module given -.. exception:: Error(arg1, arg2) - :module: errmod - -.. data:: var - - -.. currentmodule:: None - -.. function:: func_without_module2() -> annotation - - -C items -======= - -.. cfunction:: Sphinx_DoSomething() - -.. cmember:: SphinxStruct.member - -.. cmacro:: SPHINX_USE_PYTHON - -.. ctype:: SphinxType - -.. cvar:: sphinx_global - - -Testing references -================== - -Referencing :class:`mod.Cls` or :Class:`mod.Cls` should be the same. - - -User markup -=========== - -.. userdesc:: myobj:parameter - - Description of userdesc. - - -Referencing :userdescrole:`myobj`. diff --git a/tests/root/extapi.txt b/tests/root/extapi.txt new file mode 100644 index 00000000..4728e3de --- /dev/null +++ b/tests/root/extapi.txt @@ -0,0 +1,10 @@ +Extension API tests +=================== + +Testing directives: + +.. funcdir:: + :opt: Foo + +.. clsdir:: + :opt: Bar diff --git a/tests/root/markup.txt b/tests/root/markup.txt index cdb8c5fc..65156e7e 100644 --- a/tests/root/markup.txt +++ b/tests/root/markup.txt @@ -5,7 +5,11 @@ Testing various markup ====================== +Meta markup +----------- + .. sectionauthor:: Georg Brandl +.. moduleauthor:: Georg Brandl .. contents:: TOC @@ -13,7 +17,11 @@ Testing various markup :author: Me :keywords: docs, sphinx -A |subst|. + +Generic reST +------------ + +A |subst| (the definition is in rst_epilog). .. _label: @@ -21,22 +29,14 @@ A |subst|. some code -Admonitions ------------ - -.. note:: Note - Note text. - -.. warning:: Warning - - Warning text. +Option list: -.. tip:: - Tip text. +-h help +--help also help Body directives ---------------- +^^^^^^^^^^^^^^^ .. topic:: Title @@ -69,7 +69,67 @@ Body directives b - + +Admonitions +^^^^^^^^^^^ + +.. admonition:: My Admonition + + Admonition text. + +.. note:: + Note text. + +.. warning:: + + Warning text. + +.. tip:: + Tip text. + + +Inline markup +------------- + +*Generic inline markup* + +* :command:`command` +* :dfn:`dfn` +* :guilabel:`guilabel` +* :kbd:`kbd` +* :mailheader:`mailheader` +* :makevar:`makevar` +* :manpage:`manpage` +* :mimetype:`mimetype` +* :newsgroup:`newsgroup` +* :program:`program` +* :regexp:`regexp` +* :menuselection:`File --> Close` +* :file:`a/{varpart}/b` +* :samp:`print {i}` + +*Linking inline markup* + +* :pep:`8` +* :rfc:`1` +* :envvar:`HOME` +* :keyword:`with` +* :token:`try statement <try_stmt>` +* :doc:`subdir/includes` +* ``:download:`` is tested in includes.txt +* :option:`Python -c option <python -c>` + +Test :abbr:`abbr (abbreviation)` and another :abbr:`abbr (abbreviation)`. + + +.. _with: + +With +---- + +(Empty section.) + + Tables ------ @@ -96,6 +156,17 @@ Version markup Boring stuff. +Code blocks +----------- + +.. code-block:: ruby + :linenos: + + def ruby? + false + end + + Misc stuff ---------- @@ -124,11 +195,6 @@ This is a side note. This tests :CLASS:`role names in uppercase`. -Option list: - --h help ---help also help - .. centered:: LICENSE AGREEMENT .. acks:: @@ -146,7 +212,7 @@ Option list: Particle with half-integer spin. .. productionlist:: - try_stmt: try1_stmt | try2_stmt + try_stmt: `try1_stmt` | `try2_stmt` try1_stmt: "try" ":" `suite` : ("except" [`expression` ["," `target`]] ":" `suite`)+ : ["else" ":" `suite`] @@ -154,7 +220,6 @@ Option list: try2_stmt: "try" ":" `suite` : "finally" ":" `suite` -Test :abbr:`abbr (abbreviation)` and another :abbr:`abbr (abbreviation)`. Index markup ------------ @@ -180,11 +245,6 @@ Invalid index markup... Testing öäü... -Object markup -------------- - -:cfunc:`CFunction`. - Only directive -------------- @@ -208,3 +268,4 @@ Only directive .. rubric:: Footnotes .. [#] Like footnotes. + diff --git a/tests/root/objects.txt b/tests/root/objects.txt new file mode 100644 index 00000000..7a93aeed --- /dev/null +++ b/tests/root/objects.txt @@ -0,0 +1,110 @@ +Testing object descriptions +=========================== + +.. function:: func_without_module(a, b, *c[, d]) + + Does something. + +.. function:: func_without_body() + +.. function:: func_noindex + :noindex: + +.. function:: func_with_module + :module: foolib + +.. module:: mod + :synopsis: Module synopsis. + :platform: UNIX + +.. function:: func_in_module + +.. class:: Cls + + .. method:: meth1 + + .. staticmethod:: meths + + .. attribute:: attr + +.. explicit class given +.. method:: Cls.meth2 + +.. explicit module given +.. exception:: Error(arg1, arg2) + :module: errmod + +.. data:: var + + +.. currentmodule:: None + +.. function:: func_without_module2() -> annotation + +.. class:: TimeInt + +.. class:: Time(hour, minute, isdst) + + :param hour: The year. + :type hour: TimeInt + :param TimeInt minute: The minute. + :param isdst: whether it's DST + :type isdst: * some complex + * expression + :returns: a new :class:`Time` instance + :rtype: :class:`Time` + :raises ValueError: if the values are out of range + :ivar int hour: like *hour* + :ivar minute: like *minute* + :vartype minute: int + + +C items +======= + +.. c:function:: Sphinx_DoSomething() + +.. c:member:: SphinxStruct.member + +.. c:macro:: SPHINX_USE_PYTHON + +.. c:type:: SphinxType + +.. c:var:: sphinx_global + + +References +========== + +Referencing :class:`mod.Cls` or :Class:`mod.Cls` should be the same. + +With target: :c:func:`Sphinx_DoSomething()` (parentheses are handled), +:c:member:`SphinxStruct.member`, :c:macro:`SPHINX_USE_PYTHON`, +:c:type:`SphinxType *` (pointer is handled), :c:data:`sphinx_global`. + +Without target: :c:func:`CFunction`. :c:func:`!malloc`. + + +Others +====== + +.. envvar:: HOME + +.. program:: python + +.. cmdoption:: -c command + +.. program:: perl + +.. cmdoption:: -c + + +User markup +=========== + +.. userdesc:: myobj:parameter + + Description of userdesc. + + +Referencing :userdescrole:`myobj`. diff --git a/tests/test_autodoc.py b/tests/test_autodoc.py index 58bdfaef..ea41dcaa 100644 --- a/tests/test_autodoc.py +++ b/tests/test_autodoc.py @@ -14,7 +14,7 @@ from util import * from docutils.statemachine import ViewList -from sphinx.ext.autodoc import AutoDirective, Documenter, add_documenter, \ +from sphinx.ext.autodoc import AutoDirective, add_documenter, \ ModuleLevelDocumenter, FunctionDocumenter, cut_lines, between, ALL @@ -97,28 +97,28 @@ def test_parse_name(): verify('function', 'util.raises', ('util', ['raises'], None, None)) verify('function', 'util.raises(exc) -> None', ('util', ['raises'], 'exc', 'None')) - directive.env.autodoc_current_module = 'util' + directive.env.temp_data['autodoc:module'] = 'util' verify('function', 'raises', ('util', ['raises'], None, None)) - directive.env.autodoc_current_module = None - directive.env.currmodule = 'util' + del directive.env.temp_data['autodoc:module'] + directive.env.temp_data['py:module'] = 'util' verify('function', 'raises', ('util', ['raises'], None, None)) verify('class', 'TestApp', ('util', ['TestApp'], None, None)) # for members - directive.env.currmodule = 'foo' + directive.env.temp_data['py:module'] = 'foo' verify('method', 'util.TestApp.cleanup', ('util', ['TestApp', 'cleanup'], None, None)) - directive.env.currmodule = 'util' - directive.env.currclass = 'Foo' - directive.env.autodoc_current_class = 'TestApp' + directive.env.temp_data['py:module'] = 'util' + directive.env.temp_data['py:class'] = 'Foo' + directive.env.temp_data['autodoc:class'] = 'TestApp' verify('method', 'cleanup', ('util', ['TestApp', 'cleanup'], None, None)) verify('method', 'TestApp.cleanup', ('util', ['TestApp', 'cleanup'], None, None)) # and clean up - directive.env.currmodule = None - directive.env.currclass = None - directive.env.autodoc_current_class = None + del directive.env.temp_data['py:module'] + del directive.env.temp_data['py:class'] + del directive.env.temp_data['autodoc:class'] def test_format_signature(): @@ -307,7 +307,7 @@ def test_new_documenter(): del directive.result[:] options.members = ['integer'] - assert_result_contains('.. data:: integer', 'module', 'test_autodoc') + assert_result_contains('.. py:data:: integer', 'module', 'test_autodoc') def test_generate(): @@ -354,7 +354,7 @@ def test_generate(): 'function', 'util.foobar', more_content=None) # test auto and given content mixing - directive.env.currmodule = 'test_autodoc' + directive.env.temp_data['py:module'] = 'test_autodoc' assert_result_contains(' Function.', 'method', 'Class.meth') add_content = ViewList() add_content.append('Content.', '', 0) @@ -398,7 +398,8 @@ def test_generate(): options.members = [] # test module flags - assert_result_contains('.. module:: test_autodoc', 'module', 'test_autodoc') + assert_result_contains('.. py:module:: test_autodoc', + 'module', 'test_autodoc') options.synopsis = 'Synopsis' assert_result_contains(' :synopsis: Synopsis', 'module', 'test_autodoc') options.deprecated = True @@ -407,9 +408,9 @@ def test_generate(): assert_result_contains(' :platform: Platform', 'module', 'test_autodoc') # test if __all__ is respected for modules options.members = ALL - assert_result_contains('.. class:: Class(arg)', 'module', 'test_autodoc') + assert_result_contains('.. py:class:: Class(arg)', 'module', 'test_autodoc') try: - assert_result_contains('.. exception:: CustomEx', + assert_result_contains('.. py:exception:: CustomEx', 'module', 'test_autodoc') except AssertionError: pass @@ -423,7 +424,7 @@ def test_generate(): assert_result_contains(' :noindex:', 'class', 'Base') # okay, now let's get serious about mixing Python and C signature stuff - assert_result_contains('.. class:: CustomDict', 'class', 'CustomDict', + assert_result_contains('.. py:class:: CustomDict', 'class', 'CustomDict', all_members=True) # test inner class handling @@ -437,7 +438,7 @@ def test_generate(): 'attribute', 'test_autodoc.Class.descr') # test generation for C modules (which have no source file) - directive.env.currmodule = 'time' + directive.env.temp_data['py:module'] = 'time' assert_processes([('function', 'time.asctime')], 'function', 'asctime') assert_processes([('function', 'time.asctime')], 'function', 'asctime') diff --git a/tests/test_build.py b/tests/test_build.py index 4cd7bc0c..f18ff175 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -3,105 +3,18 @@ test_build ~~~~~~~~~~ - Test the entire build process with the test root. + Test all builders that have no special checks. :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ -import os -import re -import sys -import difflib -from StringIO import StringIO -from subprocess import Popen, PIPE - -from sphinx.builders.latex import LaTeXBuilder -from sphinx.writers.latex import LaTeXTranslator - from util import * def teardown_module(): (test_root / '_build').rmtree(True) - -latex_warnfile = StringIO() - -ENV_WARNINGS = """\ -%(root)s/images.txt:9: WARNING: image file not readable: foo.png -%(root)s/images.txt:23: WARNING: nonlocal image URI found: \ -http://www.python.org/logo.png -%(root)s/includes.txt:: (WARNING/2) Encoding 'utf-8-sig' used for reading \ -included file u'wrongenc.inc' seems to be wrong, try giving an :encoding: option -%(root)s/includes.txt:4: WARNING: download file not readable: nonexisting.png -""" - -LATEX_WARNINGS = ENV_WARNINGS + """\ -None:None: WARNING: no matching candidate for image URI u'foo.*' -WARNING: invalid pair index entry u'' -""" - - -@with_app(buildername='latex', warning=latex_warnfile, cleanenv=True) -def test_latex(app): - LaTeXTranslator.ignore_missing_images = True - app.builder.build_all() - latex_warnings = latex_warnfile.getvalue().replace(os.sep, '/') - latex_warnings_exp = LATEX_WARNINGS % {'root': app.srcdir} - assert latex_warnings == latex_warnings_exp, 'Warnings don\'t match:\n' + \ - '\n'.join(difflib.ndiff(latex_warnings_exp.splitlines(), - latex_warnings.splitlines())) - # file from latex_additional_files - assert (app.outdir / 'svgimg.svg').isfile() - - # only run latex if all needed packages are there - def kpsetest(filename): - try: - p = Popen(['kpsewhich', filename], stdout=PIPE) - except OSError, err: - # no kpsewhich... either no tex distribution is installed or it is - # a "strange" one -- don't bother running latex - return None - else: - p.communicate() - if p.returncode != 0: - # not found - return False - # found - return True - - if kpsetest('article.sty') is None: - print >>sys.stderr, \ - 'info: not running latex, it doesn\'t seem to be installed' - return - for filename in ['fancyhdr.sty', 'fancybox.sty', 'titlesec.sty', - 'amsmath.sty', 'framed.sty', 'color.sty', 'fancyvrb.sty', - 'threeparttable.sty']: - if not kpsetest(filename): - print >>sys.stderr, \ - 'info: not running latex, the %s package doesn\'t ' \ - 'seem to be installed' % filename - return - - # now, try to run latex over it - cwd = os.getcwd() - os.chdir(app.outdir) - try: - try: - p = Popen(['pdflatex', '--interaction=nonstopmode', - 'SphinxTests.tex'], stdout=PIPE, stderr=PIPE) - except OSError, err: - pass # most likely pdflatex was not found - else: - stdout, stderr = p.communicate() - if p.returncode != 0: - print stdout - del app.cleanup_trees[:] - assert False, 'latex exited with error' - finally: - os.chdir(cwd) - # just let the remaining ones run for now @with_app(buildername='pickle') @@ -132,6 +45,15 @@ def test_epub(app): def test_changes(app): app.builder.build_all() +try: + from docutils.writers.manpage import Writer +except ImportError: + pass +else: + @with_app(buildername='man') + def test_man(app): + app.builder.build_all() + @with_app(buildername='singlehtml', cleanenv=True) def test_singlehtml(app): app.builder.build_all() diff --git a/tests/test_build_html.py b/tests/test_build_html.py index 25f733a4..bfa0f1cf 100644 --- a/tests/test_build_html.py +++ b/tests/test_build_html.py @@ -22,7 +22,6 @@ except ImportError: from sphinx import __version__ from util import * -from test_build import ENV_WARNINGS from etree13 import ElementTree as ET @@ -32,6 +31,15 @@ def teardown_module(): html_warnfile = StringIO() +ENV_WARNINGS = """\ +%(root)s/images.txt:9: WARNING: image file not readable: foo.png +%(root)s/images.txt:23: WARNING: nonlocal image URI found: \ +http://www.python.org/logo.png +%(root)s/includes.txt:: (WARNING/2) Encoding 'utf-8-sig' used for reading \ +included file u'wrongenc.inc' seems to be wrong, try giving an :encoding: option +%(root)s/includes.txt:4: WARNING: download file not readable: nonexisting.png +""" + HTML_WARNINGS = ENV_WARNINGS + """\ %(root)s/images.txt:20: WARNING: no matching candidate for image URI u'foo.*' %(root)s/markup.txt:: WARNING: invalid index entry u'' @@ -66,26 +74,87 @@ HTML_XPATH = { ".//dt[@id='test_autodoc.function']/em": r'\*\*kwds', ".//dd": r'Return spam\.', }, + 'extapi.html': { + ".//strong": 'from function: Foo', + ".//strong": 'from class: Bar', + }, 'markup.html': { + ".//title": 'set by title directive', + ".//p/em": 'Section author: Georg Brandl', + ".//p/em": 'Module author: Georg Brandl', + # created by the meta directive ".//meta[@name='author'][@content='Me']": '', ".//meta[@name='keywords'][@content='docs, sphinx']": '', - ".//a[@href='contents.html#ref1']": '', + # a label created by ``.. _label:`` ".//div[@id='label']": '', + # code with standard code blocks + ".//pre": '^some code$', + # an option list ".//span[@class='option']": '--help', + # admonitions + ".//p[@class='first admonition-title']": 'My Admonition', + ".//p[@class='last']": 'Note text.', + ".//p[@class='last']": 'Warning text.', + # inline markup + ".//li/strong": '^command$', + ".//li/strong": '^program$', + ".//li/em": '^dfn$', + ".//li/tt/span[@class='pre']": '^kbd$', + ".//li/em": u'File \N{TRIANGULAR BULLET} Close', + ".//li/tt/span[@class='pre']": '^a/$', + ".//li/tt/em/span[@class='pre']": '^varpart$', + ".//li/tt/em/span[@class='pre']": '^i$', + ".//a[@href='http://www.python.org/dev/peps/pep-0008']/strong": 'PEP 8', + ".//a[@href='http://tools.ietf.org/html/rfc1.html']/strong": 'RFC 1', + ".//a[@href='objects.html#envvar-HOME']/tt/span[@class='pre']": 'HOME', + ".//a[@href='#with']/tt/span[@class='pre']": '^with$', + ".//a[@href='#grammar-token-try_stmt']/tt/span": '^statement$', + ".//a[@href='subdir/includes.html']/em": 'Including in subdir', + ".//a[@href='objects.html#cmdoption-python-c']/em": 'Python -c option', + # abbreviations + ".//abbr[@title='abbreviation']": '^abbr$', + # version stuff + ".//span[@class='versionmodified']": 'New in version 0.6', + # footnote reference + ".//a[@class='footnote-reference']": r'\[1\]', + # created by reference lookup + ".//a[@href='contents.html#ref1']": '', + # ``seealso`` directive + ".//div/p[@class='first admonition-title']": 'See also', + # a ``hlist`` directive + ".//table[@class='hlist']/tr/td/ul/li": '^This$', + # a ``centered`` directive + ".//p[@class='centered']/strong": 'LICENSE', + # a glossary + ".//dl/dt[@id='term-boson']": 'boson', + # a production list + ".//pre/strong": 'try_stmt', + ".//pre/a[@href='#grammar-token-try1_stmt']/tt/span": 'try1_stmt', + # tests for ``only`` directive ".//p": 'A global substitution.', ".//p": 'In HTML.', ".//p": 'In both.', ".//p": 'Always present', - ".//title": 'set by title directive', - ".//span[@class='pre']": 'CFunction()', }, - 'desc.html': { + 'objects.html': { ".//dt[@id='mod.Cls.meth1']": '', ".//dt[@id='errmod.Error']": '', ".//a[@href='#mod.Cls']": '', ".//dl[@class='userdesc']": '', - ".//dt[@id='userdescrole-myobj']": '', - ".//a[@href='#userdescrole-myobj']": '', + ".//dt[@id='userdesc-myobj']": '', + ".//a[@href='#userdesc-myobj']": '', + # C references + ".//span[@class='pre']": 'CFunction()', + ".//a[@href='#Sphinx_DoSomething']": '', + ".//a[@href='#SphinxStruct.member']": '', + ".//a[@href='#SPHINX_USE_PYTHON']": '', + ".//a[@href='#SphinxType']": '', + ".//a[@href='#sphinx_global']": '', + # test global TOC created by toctree() + ".//ul[@class='current']/li[@class='toctree-l1 current']/a[@href='']": + 'Testing object descriptions', + ".//li[@class='toctree-l1']/a[@href='markup.html']": + 'Testing various markup', # custom sidebar ".//h4": 'Custom sidebar', }, @@ -93,13 +162,16 @@ HTML_XPATH = { ".//meta[@name='hc'][@content='hcval']": '', ".//meta[@name='hc_co'][@content='hcval_co']": '', ".//meta[@name='testopt'][@content='testoverride']": '', - #".//td[@class='label']": r'\[Ref1\]', # docutils 0.5 only + ".//td[@class='label']": r'\[Ref1\]', ".//td[@class='label']": '', ".//li[@class='toctree-l1']/a": 'Testing various markup', - ".//li[@class='toctree-l2']/a": 'Admonitions', + ".//li[@class='toctree-l2']/a": 'Inline markup', ".//title": 'Sphinx <Tests>', ".//div[@class='footer']": 'Georg Brandl & Team', ".//a[@href='http://python.org/']": '', + ".//li/a[@href='genindex.html']/em": 'Index', + ".//li/a[@href='py-modindex.html']/em": 'Module Index', + ".//li/a[@href='search.html']/em": 'Search Page', # custom sidebar only for contents ".//h4": 'Contents sidebar', }, diff --git a/tests/test_build_latex.py b/tests/test_build_latex.py new file mode 100644 index 00000000..4f40cc11 --- /dev/null +++ b/tests/test_build_latex.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- +""" + test_build_latex + ~~~~~~~~~~~~~~~~ + + Test the build process with LaTeX builder with the test root. + + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import os +import sys +import difflib +from StringIO import StringIO +from subprocess import Popen, PIPE + +from sphinx.writers.latex import LaTeXTranslator + +from util import * +from test_build_html import ENV_WARNINGS + + +def teardown_module(): + (test_root / '_build').rmtree(True) + + +latex_warnfile = StringIO() + +LATEX_WARNINGS = ENV_WARNINGS + """\ +None:None: WARNING: no matching candidate for image URI u'foo.*' +WARNING: invalid pair index entry u'' +""" + + +@with_app(buildername='latex', warning=latex_warnfile, cleanenv=True) +def test_latex(app): + LaTeXTranslator.ignore_missing_images = True + app.builder.build_all() + latex_warnings = latex_warnfile.getvalue().replace(os.sep, '/') + latex_warnings_exp = LATEX_WARNINGS % {'root': app.srcdir} + assert latex_warnings == latex_warnings_exp, 'Warnings don\'t match:\n' + \ + '\n'.join(difflib.ndiff(latex_warnings_exp.splitlines(), + latex_warnings.splitlines())) + # file from latex_additional_files + assert (app.outdir / 'svgimg.svg').isfile() + + # only run latex if all needed packages are there + def kpsetest(filename): + try: + p = Popen(['kpsewhich', filename], stdout=PIPE) + except OSError: + # no kpsewhich... either no tex distribution is installed or it is + # a "strange" one -- don't bother running latex + return None + else: + p.communicate() + if p.returncode != 0: + # not found + return False + # found + return True + + if kpsetest('article.sty') is None: + print >>sys.stderr, \ + 'info: not running latex, it doesn\'t seem to be installed' + return + for filename in ['fancyhdr.sty', 'fancybox.sty', 'titlesec.sty', + 'amsmath.sty', 'framed.sty', 'color.sty', 'fancyvrb.sty', + 'threeparttable.sty']: + if not kpsetest(filename): + print >>sys.stderr, \ + 'info: not running latex, the %s package doesn\'t ' \ + 'seem to be installed' % filename + return + + # now, try to run latex over it + cwd = os.getcwd() + os.chdir(app.outdir) + try: + try: + p = Popen(['pdflatex', '--interaction=nonstopmode', + 'SphinxTests.tex'], stdout=PIPE, stderr=PIPE) + except OSError: + pass # most likely pdflatex was not found + else: + stdout, stderr = p.communicate() + if p.returncode != 0: + print stdout + print stderr + del app.cleanup_trees[:] + assert False, 'latex exited with return code %s' % p.returncode + finally: + os.chdir(cwd) diff --git a/tests/test_config.py b/tests/test_config.py index 0d18bf7f..cb4e1105 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -34,7 +34,7 @@ def test_core_config(app): # simple default values assert 'locale_dirs' not in cfg.__dict__ assert cfg.locale_dirs == [] - assert cfg.show_authors == False + assert cfg.trim_footnote_reference_space == False # complex default values assert 'html_title' not in cfg.__dict__ diff --git a/tests/test_coverage.py b/tests/test_coverage.py index 282db677..1262ebf5 100644 --- a/tests/test_coverage.py +++ b/tests/test_coverage.py @@ -36,7 +36,7 @@ def test_build(app): undoc_py, undoc_c = pickle.loads((app.outdir / 'undoc.pickle').text()) assert len(undoc_c) == 1 # the key is the full path to the header file, which isn't testable - assert undoc_c.values()[0] == [('cfunction', 'Py_SphinxTest')] + assert undoc_c.values()[0] == [('function', 'Py_SphinxTest')] assert 'test_autodoc' in undoc_py assert 'funcs' in undoc_py['test_autodoc'] diff --git a/tests/test_env.py b/tests/test_env.py index 0090d6b6..4ecbaac4 100644 --- a/tests/test_env.py +++ b/tests/test_env.py @@ -11,7 +11,6 @@ from util import * -from sphinx.environment import BuildEnvironment from sphinx.builders.html import StandaloneHTMLBuilder from sphinx.builders.latex import LaTeXBuilder @@ -20,8 +19,8 @@ warnings = [] def setup_module(): global app, env - app = TestApp(srcdir='(temp)') - env = BuildEnvironment(app.srcdir, app.doctreedir, app.config) + app = TestApp(srcdir='(temp)', freshenv=True) + env = app.env env.set_warnfunc(lambda *args: warnings.append(args)) def teardown_module(): @@ -53,7 +52,7 @@ def test_images(): tree = env.get_doctree('images') app._warning.reset() - htmlbuilder = StandaloneHTMLBuilder(app, env) + htmlbuilder = StandaloneHTMLBuilder(app) htmlbuilder.post_process_images(tree) assert "no matching candidate for image URI u'foo.*'" in \ app._warning.content[-1] @@ -63,7 +62,7 @@ def test_images(): set(['img.png', 'img1.png', 'simg.png', 'svgimg.svg']) app._warning.reset() - latexbuilder = LaTeXBuilder(app, env) + latexbuilder = LaTeXBuilder(app) latexbuilder.post_process_images(tree) assert "no matching candidate for image URI u'foo.*'" in \ app._warning.content[-1] @@ -94,10 +93,10 @@ def test_second_update(): assert 'autodoc' not in env.found_docs def test_object_inventory(): - refs = env.descrefs + refs = env.domaindata['py']['objects'] assert 'func_without_module' in refs - assert refs['func_without_module'] == ('desc', 'function') + assert refs['func_without_module'] == ('objects', 'function') assert 'func_without_module2' in refs assert 'mod.func_in_module' in refs assert 'mod.Cls' in refs @@ -111,5 +110,8 @@ def test_object_inventory(): assert 'func_in_module' not in refs assert 'func_noindex' not in refs - assert 'mod' in env.modules - assert env.modules['mod'] == ('desc', 'Module synopsis.', 'UNIX', False) + assert env.domaindata['py']['modules']['mod'] == \ + ('objects', 'Module synopsis.', 'UNIX', False) + + assert env.domains['py'].data is env.domaindata['py'] + assert env.domains['c'].data is env.domaindata['c'] diff --git a/tests/test_intersphinx.py b/tests/test_intersphinx.py new file mode 100644 index 00000000..5263d724 --- /dev/null +++ b/tests/test_intersphinx.py @@ -0,0 +1,112 @@ +# -*- coding: utf-8 -*- +""" + test_intersphinx + ~~~~~~~~~~~~~~~~ + + Test the intersphinx extension. + + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import zlib +import posixpath +from cStringIO import StringIO + +from docutils import nodes + +from sphinx import addnodes +from sphinx.ext.intersphinx import read_inventory_v1, read_inventory_v2, \ + load_mappings, missing_reference + +from util import * + + +inventory_v1 = '''\ +# Sphinx inventory version 1 +# Project: foo +# Version: 1.0 +module mod foo.html +module.cls class foo.html +''' + +inventory_v2 = '''\ +# Sphinx inventory version 2 +# Project: foo +# Version: 2.0 +# The remainder of this file is compressed with zlib. +''' + zlib.compress('''\ +module1 py:module 0 foo.html#module-module1 +module2 py:module 0 foo.html#module-$ +module1.func py:function 1 sub/foo.html#$ +CFunc c:function 2 cfunc.html#CFunc +''') + + +def test_read_inventory_v1(): + f = StringIO(inventory_v1) + f.readline() + invdata = read_inventory_v1(f, '/util', posixpath.join) + assert invdata['py:module']['module'] == \ + ('foo', '1.0', '/util/foo.html#module-module') + assert invdata['py:class']['module.cls'] == \ + ('foo', '1.0', '/util/foo.html#module.cls') + + +def test_read_inventory_v2(): + f = StringIO(inventory_v2) + f.readline() + invdata1 = read_inventory_v2(f, '/util', posixpath.join) + + # try again with a small buffer size to test the chunking algorithm + f = StringIO(inventory_v2) + f.readline() + invdata2 = read_inventory_v2(f, '/util', posixpath.join, bufsize=5) + + assert invdata1 == invdata2 + + assert len(invdata1['py:module']) == 2 + assert invdata1['py:module']['module1'] == \ + ('foo', '2.0', '/util/foo.html#module-module1') + assert invdata1['py:module']['module2'] == \ + ('foo', '2.0', '/util/foo.html#module-module2') + assert invdata1['py:function']['module1.func'][2] == \ + '/util/sub/foo.html#module1.func' + assert invdata1['c:function']['CFunc'][2] == '/util/cfunc.html#CFunc' + + +@with_app(confoverrides={'extensions': 'sphinx.ext.intersphinx'}) +@with_tempdir +def test_missing_reference(tempdir, app): + inv_file = tempdir / 'inventory' + write_file(inv_file, inventory_v2) + app.config.intersphinx_mapping = {'http://docs.python.org/': inv_file} + app.config.intersphinx_cache_limit = 0 + + # load the inventory and check if it's done correctly + load_mappings(app) + inv = app.env.intersphinx_inventory + + assert inv['py:module']['module2'] == \ + ('foo', '2.0', 'http://docs.python.org/foo.html#module-module2') + + # create fake nodes and check referencing + contnode = nodes.emphasis('foo') + refnode = addnodes.pending_xref('') + refnode['reftarget'] = 'module1.func' + refnode['reftype'] = 'func' + refnode['refdomain'] = 'py' + + rn = missing_reference(app, app.env, refnode, contnode) + assert isinstance(rn, nodes.reference) + assert rn['refuri'] == 'http://docs.python.org/sub/foo.html#module1.func' + assert rn['reftitle'] == '(in foo v2.0)' + assert rn[0] is contnode + + # create unresolvable nodes and check None return value + refnode['reftype'] = 'foo' + assert missing_reference(app, app.env, refnode, contnode) is None + + refnode['reftype'] = 'function' + refnode['reftarget'] = 'foo.func' + assert missing_reference(app, app.env, refnode, contnode) is None diff --git a/tests/test_markup.py b/tests/test_markup.py index 899fedf7..a8ced747 100644 --- a/tests/test_markup.py +++ b/tests/test_markup.py @@ -28,6 +28,8 @@ def setup_module(): components=(rst.Parser, HTMLWriter, LaTeXWriter)) settings = optparser.get_default_values() settings.env = app.builder.env + settings.env.patch_lookup_functions() + settings.env.temp_data['docname'] = 'dummy' parser = rst.Parser() def teardown_module(): @@ -59,7 +61,7 @@ def verify_re(rst, html_expected, latex_expected): html_translator = ForgivingHTMLTranslator(app.builder, document) document.walkabout(html_translator) html_translated = ''.join(html_translator.fragment).strip() - assert re.match(html_expected, html_translated), 'from' + rst + assert re.match(html_expected, html_translated), 'from ' + rst if latex_expected: latex_translator = ForgivingLaTeXTranslator(document, app.builder) @@ -78,26 +80,26 @@ def verify(rst, html_expected, latex_expected): def test_inline(): # correct interpretation of code with whitespace - _html = ('<p><tt class="docutils literal"><span class="pre">' + _html = ('<p><tt class="(samp )?docutils literal"><span class="pre">' 'code</span> <span class="pre">sample</span></tt></p>') - yield verify, '``code sample``', _html, '\\code{code sample}' - yield verify, ':samp:`code sample`', _html, '\\samp{code sample}' + yield verify_re, '``code sample``', _html, r'\\code{code sample}' + yield verify_re, ':samp:`code sample`', _html, r'\\samp{code sample}' # interpolation of braces in samp and file roles (HTML only) yield (verify, ':samp:`a{b}c`', - '<p><tt class="docutils literal"><span class="pre">a</span>' + '<p><tt class="samp docutils literal"><span class="pre">a</span>' '<em><span class="pre">b</span></em>' '<span class="pre">c</span></tt></p>', '\\samp{abc}') # interpolation of arrows in menuselection yield (verify, ':menuselection:`a --> b`', - u'<p><em>a \N{TRIANGULAR BULLET} b</em></p>', + u'<p><em class="menuselection">a \N{TRIANGULAR BULLET} b</em></p>', '\\emph{a \\(\\rightarrow\\) b}') # non-interpolation of dashes in option role yield (verify_re, ':option:`--with-option`', - '<p><em( class="xref")?>--with-option</em></p>$', + '<p><em( class="xref std-option")?>--with-option</em></p>$', r'\\emph{\\texttt{-{-}with-option}}$') # verify smarty-pants quotes @@ -108,6 +110,11 @@ def test_inline(): '"John"</span></tt></p>', '\\code{"John"}') + # verify classes for inline roles + yield (verify, ':manpage:`mp(1)`', + '<p><em class="manpage">mp(1)</em></p>', + '\\emph{\\texttt{mp(1)}}') + def test_latex_escaping(): # correct escaping in normal mode yield (verify, u'Γ\\\\∞$', None, @@ -118,5 +125,5 @@ def test_latex_escaping(): u'@PYGZat[]@(@Gamma@)\\@(@infty@)@$@PYGZlb[]@PYGZrb[]\n' u'\\end{Verbatim}') # in URIs - yield (verify, u'`test <http://example.com/~me/>`_', None, - u'\\href{http://example.com/~me/}{test}') + yield (verify_re, u'`test <http://example.com/~me/>`_', None, + ur'\\href{http://example.com/~me/}{test}.*') diff --git a/tests/test_metadata.py b/tests/test_metadata.py index a6b0e7f5..8fb6cb21 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -16,7 +16,6 @@ from util import * from nose.tools import assert_equals -from sphinx.environment import BuildEnvironment app = env = None warnings = [] @@ -25,9 +24,7 @@ def setup_module(): # Is there a better way of generating this doctree than manually iterating? global app, env app = TestApp(srcdir='(temp)') - env = BuildEnvironment(app.srcdir, app.doctreedir, app.config) - # Huh. Why do I need to do this? - env.set_warnfunc(lambda *args: warnings.append(args)) + env = app.env msg, num, it = env.update(app.config, app.srcdir, app.doctreedir, app) for docname in it: pass diff --git a/tests/test_quickstart.py b/tests/test_quickstart.py index 11782fb6..cb40d27c 100644 --- a/tests/test_quickstart.py +++ b/tests/test_quickstart.py @@ -126,8 +126,10 @@ def test_quickstart_all_answers(tempdir): 'pngmath': 'N', 'jsmath': 'no', 'ifconfig': 'no', + 'viewcode': 'no', 'Create Makefile': 'no', 'Create Windows command file': 'no', + 'Do you want to use the epub builder': 'yes', } qs.raw_input = mock_raw_input(answers, needanswer=True) qs.TERM_ENCODING = 'utf-8' @@ -150,6 +152,10 @@ def test_quickstart_all_answers(tempdir): assert ns['latex_documents'] == [ ('contents', 'STASI.tex', u'STASI™ Documentation', u'Wolfgang Schäuble \\& G\'Beckstein', 'manual')] + assert ns['epub_author'] == u'Wolfgang Schäuble & G\'Beckstein' + assert ns['man_pages'] == [ + ('contents', 'stasi', u'STASI™ Documentation', + [u'Wolfgang Schäuble & G\'Beckstein'], 1)] assert (tempdir / 'build').isdir() assert (tempdir / 'source' / '.static').isdir() diff --git a/tests/test_search.py b/tests/test_search.py index 15257aeb..0b5b158b 100644 --- a/tests/test_search.py +++ b/tests/test_search.py @@ -9,12 +9,14 @@ :license: BSD, see LICENSE for details. """ -from docutils import frontend, utils, nodes +from docutils import frontend, utils from docutils.parsers import rst from sphinx.search import IndexBuilder +settings = parser = None + def setup_module(): global settings, parser optparser = frontend.OptionParser(components=(rst.Parser,)) diff --git a/tests/util.py b/tests/util.py index 2b380722..1b24af0e 100644 --- a/tests/util.py +++ b/tests/util.py @@ -8,7 +8,6 @@ """ import sys -import os import StringIO import tempfile import shutil @@ -184,9 +183,9 @@ def gen_with_app(*args, **kwargs): def with_tempdir(func): - def new_func(): + def new_func(*args, **kwds): tempdir = path(tempfile.mkdtemp()) - func(tempdir) + func(tempdir, *args, **kwds) tempdir.rmtree() new_func.__name__ = func.__name__ return new_func |
