summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2009-12-28 19:49:57 +0100
committerGeorg Brandl <georg@python.org>2009-12-28 19:49:57 +0100
commit6b954328bea16abf763a2d829471d6565747f1a4 (patch)
tree17299e304c5608d335c88e2eb26780ba14fafecc /tests
parent2637a7b44ad5b68412d14da5ff64b0f8ee88512f (diff)
parenta3cd1ee676757c69ae30f401b62b7a055f1e3f1a (diff)
downloadsphinx-6b954328bea16abf763a2d829471d6565747f1a4.tar.gz
merge with trunk
Diffstat (limited to 'tests')
-rw-r--r--tests/root/_templates/layout.html7
-rw-r--r--tests/root/conf.py22
-rw-r--r--tests/root/contents.txt3
-rw-r--r--tests/root/extapi.txt10
-rw-r--r--tests/root/markup.txt113
-rw-r--r--tests/root/objects.txt (renamed from tests/root/desc.txt)38
-rw-r--r--tests/test_autodoc.py35
-rw-r--r--tests/test_build.py159
-rw-r--r--tests/test_build_html.py245
-rw-r--r--tests/test_config.py2
-rw-r--r--tests/test_coverage.py1
-rw-r--r--tests/test_env.py19
-rw-r--r--tests/test_intersphinx.py112
-rw-r--r--tests/test_markup.py3
-rw-r--r--tests/util.py4
15 files changed, 549 insertions, 224 deletions
diff --git a/tests/root/_templates/layout.html b/tests/root/_templates/layout.html
index e8920025..d312238f 100644
--- a/tests/root/_templates/layout.html
+++ b/tests/root/_templates/layout.html
@@ -1,5 +1,12 @@
{% extends "!layout.html" %}
+
{% block extrahead %}
<meta name="hc" content="{{ hckey }}" />
{{ 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 fd82be7d..13b26799 100644
--- a/tests/root/conf.py
+++ b/tests/root/conf.py
@@ -25,6 +25,7 @@ today_fmt = '%B %d, %Y'
exclude_trees = ['_build']
keep_warnings = True
pygments_style = 'sphinx'
+show_authors = True
rst_epilog = '.. |subst| replace:: global substitution'
@@ -49,6 +50,7 @@ latex_additional_files = ['svgimg.svg']
value_from_conf_py = 84
coverage_c_path = ['special/*.h']
+# XXX cfunction?
coverage_c_regexes = {'cfunction': r'^PyAPI_FUNC\(.*\)\s+([^_][\w_]+)'}
autosummary_generate = ['autosummary']
@@ -56,7 +58,12 @@ autosummary_generate = ['autosummary']
# 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(':')
@@ -65,7 +72,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 6133f887..6955ec62 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/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 32b037ee..c5022b32 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
------------
@@ -179,11 +244,6 @@ Invalid index markup...
Testing öäü...
-Object markup
--------------
-
-:cfunc:`CFunction`.
-
Only directive
--------------
@@ -207,3 +267,4 @@ Only directive
.. rubric:: Footnotes
.. [#] Like footnotes.
+
diff --git a/tests/root/desc.txt b/tests/root/objects.txt
index d6915dc2..fd33a6cc 100644
--- a/tests/root/desc.txt
+++ b/tests/root/objects.txt
@@ -1,5 +1,5 @@
-Testing description units
-=========================
+Testing object descriptions
+===========================
.. function:: func_without_module(a, b, *c[, d])
@@ -43,22 +43,42 @@ Testing description units
C items
=======
-.. cfunction:: Sphinx_DoSomething()
+.. c:function:: Sphinx_DoSomething()
-.. cmember:: SphinxStruct.member
+.. c:member:: SphinxStruct.member
-.. cmacro:: SPHINX_USE_PYTHON
+.. c:macro:: SPHINX_USE_PYTHON
-.. ctype:: SphinxType
+.. c:type:: SphinxType
-.. cvar:: sphinx_global
+.. c:var:: sphinx_global
-Testing references
-==================
+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
===========
diff --git a/tests/test_autodoc.py b/tests/test_autodoc.py
index 687fbd0d..9f1e2bd9 100644
--- a/tests/test_autodoc.py
+++ b/tests/test_autodoc.py
@@ -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.doc_read_data['autodoc_module'] = 'util'
verify('function', 'raises', ('util', ['raises'], None, None))
- directive.env.autodoc_current_module = None
- directive.env.currmodule = 'util'
+ del directive.env.doc_read_data['autodoc_module']
+ directive.env.doc_read_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.doc_read_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.doc_read_data['py_module'] = 'util'
+ directive.env.doc_read_data['py_class'] = 'Foo'
+ directive.env.doc_read_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.doc_read_data['py_module']
+ del directive.env.doc_read_data['py_class']
+ del directive.env.doc_read_data['autodoc_class']
def test_format_signature():
@@ -306,7 +306,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():
@@ -353,7 +353,7 @@ def test_generate():
'function', 'util.foobar', more_content=None)
# test auto and given content mixing
- directive.env.currmodule = 'test_autodoc'
+ directive.env.doc_read_data['py_module'] = 'test_autodoc'
assert_result_contains(' Function.', 'method', 'Class.meth')
add_content = ViewList()
add_content.append('Content.', '', 0)
@@ -394,7 +394,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
@@ -403,9 +404,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', 'module', 'test_autodoc')
+ assert_result_contains('.. py:class:: Class', 'module', 'test_autodoc')
try:
- assert_result_contains('.. exception:: CustomEx',
+ assert_result_contains('.. py:exception:: CustomEx',
'module', 'test_autodoc')
except AssertionError:
pass
@@ -419,7 +420,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
@@ -433,7 +434,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.doc_read_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 47311f27..9d3210e7 100644
--- a/tests/test_build.py
+++ b/tests/test_build.py
@@ -13,28 +13,19 @@ import os
import re
import sys
import difflib
-import htmlentitydefs
from StringIO import StringIO
from subprocess import Popen, PIPE
-from util import *
-from etree13 import ElementTree as ET
-
-try:
- import pygments
-except ImportError:
- pygments = None
-
-from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.builders.latex import LaTeXBuilder
from sphinx.writers.latex import LaTeXTranslator
+from util import *
+
def teardown_module():
(test_root / '_build').rmtree(True)
-html_warnfile = StringIO()
latex_warnfile = StringIO()
ENV_WARNINGS = """\
@@ -46,157 +37,11 @@ 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''
-%(root)s/markup.txt:: WARNING: invalid pair index entry u''
-%(root)s/markup.txt:: WARNING: invalid pair index entry u'keyword; '
-"""
-
LATEX_WARNINGS = ENV_WARNINGS + """\
None:None: WARNING: no matching candidate for image URI u'foo.*'
WARNING: invalid pair index entry u''
"""
-HTML_XPATH = {
- 'images.html': {
- ".//img[@src='_images/img.png']": '',
- ".//img[@src='_images/img1.png']": '',
- ".//img[@src='_images/simg.png']": '',
- ".//object[@data='_images/svgimg.svg']": '',
- ".//embed[@src='_images/svgimg.svg']": '',
- },
- 'subdir/images.html': {
- ".//img[@src='../_images/img1.png']": '',
- ".//img[@src='../_images/rimg.png']": '',
- },
- 'subdir/includes.html': {
- ".//a[@href='../_downloads/img.png']": '',
- },
- 'includes.html': {
- ".//pre": u'Max Strauß',
- ".//a[@href='_downloads/img.png']": '',
- ".//a[@href='_downloads/img1.png']": '',
- ".//pre": u'"quotes"',
- ".//pre": u"'included'",
- },
- 'autodoc.html': {
- ".//dt[@id='test_autodoc.Class']": '',
- ".//dt[@id='test_autodoc.function']/em": r'\*\*kwds',
- ".//dd": r'Return spam\.',
- },
- 'markup.html': {
- ".//meta[@name='author'][@content='Me']": '',
- ".//meta[@name='keywords'][@content='docs, sphinx']": '',
- ".//a[@href='contents.html#ref1']": '',
- ".//div[@id='label']": '',
- ".//span[@class='option']": '--help',
- ".//p": 'A global substitution.',
- ".//p": 'In HTML.',
- ".//p": 'In both.',
- ".//p": 'Always present',
- ".//title": 'set by title directive',
- ".//span[@class='pre']": 'CFunction()',
- },
- 'desc.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']": '',
- },
- 'contents.html': {
- ".//meta[@name='hc'][@content='hcval']": '',
- ".//meta[@name='testopt'][@content='testoverride']": '',
- #".//td[@class='label']": r'\[Ref1\]', # docutils 0.5 only
- ".//td[@class='label']": '',
- ".//li[@class='toctree-l1']/a": 'Testing various markup',
- ".//li[@class='toctree-l2']/a": 'Admonitions',
- ".//title": 'Sphinx <Tests>',
- ".//div[@class='footer']": 'Georg Brandl & Team',
- ".//a[@href='http://python.org/']": '',
- },
- 'bom.html': {
- ".//title": " File with UTF-8 BOM",
- },
- '_static/statictmpl.html': {
- ".//project": 'Sphinx <Tests>',
- },
-}
-
-if pygments:
- HTML_XPATH['includes.html'].update({
- ".//pre/span[@class='s']": u'üöä',
- ".//div[@class='inc-pyobj1 highlight-text']/div/pre":
- r'^class Foo:\n pass\n\s*$',
- ".//div[@class='inc-pyobj2 highlight-text']/div/pre":
- r'^ def baz\(\):\n pass\n\s*$',
- ".//div[@class='inc-lines highlight-text']/div/pre":
- r'^class Foo:\n pass\nclass Bar:\n$',
- ".//div[@class='inc-startend highlight-text']/div/pre":
- ur'^foo = u"Including Unicode characters: üöä"\n$',
- ".//div[@class='inc-preappend highlight-text']/div/pre":
- r'(?m)^START CODE$',
- ".//div[@class='inc-pyobj-dedent highlight-python']/div/pre/span":
- r'def',
- })
- HTML_XPATH['subdir/includes.html'].update({
- ".//pre/span": 'line 1',
- ".//pre/span": 'line 2',
- })
-
-class NslessParser(ET.XMLParser):
- """XMLParser that throws away namespaces in tag names."""
-
- def _fixname(self, key):
- try:
- return self._names[key]
- except KeyError:
- name = key
- br = name.find('}')
- if br > 0:
- name = name[br+1:]
- self._names[key] = name = self._fixtext(name)
- return name
-
-
-def check_xpath(etree, fname, path, check):
- nodes = list(etree.findall(path))
- assert nodes != [], ('did not find any node matching xpath '
- '%r in file %s' % (path, fname))
- if hasattr(check, '__call__'):
- check(nodes)
- elif not check:
- # only check for node presence
- pass
- else:
- rex = re.compile(check)
- for node in nodes:
- if node.text and rex.search(node.text):
- break
- else:
- assert False, ('%r not found in any node matching '
- 'path %s in %s: %r' % (check, path, fname,
- [node.text for node in nodes]))
-
-@gen_with_app(buildername='html', warning=html_warnfile, cleanenv=True,
- tags=['testtag'])
-def test_html(app):
- app.builder.build_all()
- html_warnings = html_warnfile.getvalue().replace(os.sep, '/')
- html_warnings_exp = HTML_WARNINGS % {'root': app.srcdir}
- assert html_warnings == html_warnings_exp, 'Warnings don\'t match:\n' + \
- '\n'.join(difflib.ndiff(html_warnings_exp.splitlines(),
- html_warnings.splitlines()))
-
- for fname, paths in HTML_XPATH.iteritems():
- parser = NslessParser()
- parser.entity.update(htmlentitydefs.entitydefs)
- etree = ET.parse(os.path.join(app.outdir, fname), parser)
- for path, check in paths.iteritems():
- yield check_xpath, etree, fname, path, check
-
@with_app(buildername='latex', warning=latex_warnfile, cleanenv=True)
def test_latex(app):
diff --git a/tests/test_build_html.py b/tests/test_build_html.py
new file mode 100644
index 00000000..7079971c
--- /dev/null
+++ b/tests/test_build_html.py
@@ -0,0 +1,245 @@
+# -*- coding: utf-8 -*-
+"""
+ test_build_html
+ ~~~~~~~~~~~~~~~
+
+ Test the HTML builder and check output against XPath.
+
+ :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+import os
+import re
+import sys
+import difflib
+import htmlentitydefs
+from StringIO import StringIO
+
+try:
+ import pygments
+except ImportError:
+ pygments = None
+
+from sphinx.builders.html import StandaloneHTMLBuilder
+
+from util import *
+from test_build import ENV_WARNINGS
+from etree13 import ElementTree as ET
+
+
+def teardown_module():
+ (test_root / '_build').rmtree(True)
+
+
+html_warnfile = StringIO()
+
+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''
+%(root)s/markup.txt:: WARNING: invalid pair index entry u''
+%(root)s/markup.txt:: WARNING: invalid pair index entry u'keyword; '
+"""
+
+HTML_XPATH = {
+ 'images.html': {
+ ".//img[@src='_images/img.png']": '',
+ ".//img[@src='_images/img1.png']": '',
+ ".//img[@src='_images/simg.png']": '',
+ ".//object[@data='_images/svgimg.svg']": '',
+ ".//embed[@src='_images/svgimg.svg']": '',
+ },
+ 'subdir/images.html': {
+ ".//img[@src='../_images/img1.png']": '',
+ ".//img[@src='../_images/rimg.png']": '',
+ },
+ 'subdir/includes.html': {
+ ".//a[@href='../_downloads/img.png']": '',
+ },
+ 'includes.html': {
+ ".//pre": u'Max Strauß',
+ ".//a[@href='_downloads/img.png']": '',
+ ".//a[@href='_downloads/img1.png']": '',
+ ".//pre": u'"quotes"',
+ ".//pre": u"'included'",
+ },
+ 'autodoc.html': {
+ ".//dt[@id='test_autodoc.Class']": '',
+ ".//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 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',
+ },
+ 'objects.html': {
+ ".//dt[@id='mod.Cls.meth1']": '',
+ ".//dt[@id='errmod.Error']": '',
+ ".//a[@href='#mod.Cls']": '',
+ ".//dl[@class='userdesc']": '',
+ ".//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',
+ },
+ 'contents.html': {
+ ".//meta[@name='hc'][@content='hcval']": '',
+ ".//meta[@name='testopt'][@content='testoverride']": '',
+ #".//td[@class='label']": r'\[Ref1\]', # docutils 0.5 only
+ ".//td[@class='label']": '',
+ ".//li[@class='toctree-l1']/a": 'Testing various markup',
+ ".//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='modindex.html']/em": 'Module Index',
+ ".//li/a[@href='search.html']/em": 'Search Page',
+ },
+ 'bom.html': {
+ ".//title": " File with UTF-8 BOM",
+ },
+ '_static/statictmpl.html': {
+ ".//project": 'Sphinx <Tests>',
+ },
+}
+
+if pygments:
+ HTML_XPATH['includes.html'].update({
+ ".//pre/span[@class='s']": u'üöä',
+ ".//div[@class='inc-pyobj1 highlight-text']/div/pre":
+ r'^class Foo:\n pass\n\s*$',
+ ".//div[@class='inc-pyobj2 highlight-text']/div/pre":
+ r'^ def baz\(\):\n pass\n\s*$',
+ ".//div[@class='inc-lines highlight-text']/div/pre":
+ r'^class Foo:\n pass\nclass Bar:\n$',
+ ".//div[@class='inc-startend highlight-text']/div/pre":
+ ur'^foo = u"Including Unicode characters: üöä"\n$',
+ ".//div[@class='inc-preappend highlight-text']/div/pre":
+ r'(?m)^START CODE$',
+ ".//div[@class='inc-pyobj-dedent highlight-python']/div/pre/span":
+ r'def',
+ })
+ HTML_XPATH['subdir/includes.html'].update({
+ ".//pre/span": 'line 1',
+ ".//pre/span": 'line 2',
+ })
+
+class NslessParser(ET.XMLParser):
+ """XMLParser that throws away namespaces in tag names."""
+
+ def _fixname(self, key):
+ try:
+ return self._names[key]
+ except KeyError:
+ name = key
+ br = name.find('}')
+ if br > 0:
+ name = name[br+1:]
+ self._names[key] = name = self._fixtext(name)
+ return name
+
+
+def check_xpath(etree, fname, path, check):
+ nodes = list(etree.findall(path))
+ assert nodes != [], ('did not find any node matching xpath '
+ '%r in file %s' % (path, fname))
+ if hasattr(check, '__call__'):
+ check(nodes)
+ elif not check:
+ # only check for node presence
+ pass
+ else:
+ rex = re.compile(check)
+ for node in nodes:
+ if node.text and rex.search(node.text):
+ break
+ else:
+ assert False, ('%r not found in any node matching '
+ 'path %s in %s: %r' % (check, path, fname,
+ [node.text for node in nodes]))
+
+@gen_with_app(buildername='html', warning=html_warnfile, cleanenv=True,
+ tags=['testtag'])
+def test_html(app):
+ app.builder.build_all()
+ html_warnings = html_warnfile.getvalue().replace(os.sep, '/')
+ html_warnings_exp = HTML_WARNINGS % {'root': app.srcdir}
+ assert html_warnings == html_warnings_exp, 'Warnings don\'t match:\n' + \
+ '\n'.join(difflib.ndiff(html_warnings_exp.splitlines(),
+ html_warnings.splitlines()))
+
+ for fname, paths in HTML_XPATH.iteritems():
+ parser = NslessParser()
+ parser.entity.update(htmlentitydefs.entitydefs)
+ etree = ET.parse(os.path.join(app.outdir, fname), parser)
+ for path, check in paths.iteritems():
+ yield check_xpath, etree, fname, path, check
diff --git a/tests/test_config.py b/tests/test_config.py
index b3aa4eea..1560c257 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -32,7 +32,7 @@ def test_core_config(app):
# simple default values
assert 'exclude_dirs' not in cfg.__dict__
assert cfg.exclude_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 369788a1..bc59a815 100644
--- a/tests/test_coverage.py
+++ b/tests/test_coverage.py
@@ -36,6 +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
+ # XXX this should fail right now
assert undoc_c.values()[0] == [('cfunction', 'Py_SphinxTest')]
assert 'test_autodoc' in undoc_py
diff --git a/tests/test_env.py b/tests/test_env.py
index a06656d6..660d0e3b 100644
--- a/tests/test_env.py
+++ b/tests/test_env.py
@@ -20,8 +20,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():
@@ -51,7 +51,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]
@@ -61,7 +61,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]
@@ -92,10 +92,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
@@ -109,5 +109,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..2d521914
--- /dev/null
+++ b/tests/test_intersphinx.py
@@ -0,0 +1,112 @@
+# -*- coding: utf-8 -*-
+"""
+ test_intersphinx
+ ~~~~~~~~~~~~~~~~
+
+ Test the intersphinx extension.
+
+ :copyright: Copyright 2007-2009 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, \
+ fetch_inventory, 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 03c421a1..22481953 100644
--- a/tests/test_markup.py
+++ b/tests/test_markup.py
@@ -29,6 +29,7 @@ def setup_module():
components=(rst.Parser, HTMLWriter, LaTeXWriter))
settings = optparser.get_default_values()
settings.env = app.builder.env
+ settings.env.patch_lookup_functions()
parser = rst.Parser()
def teardown_module():
@@ -60,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)
diff --git a/tests/util.py b/tests/util.py
index 4bb6a653..ad0f6d7e 100644
--- a/tests/util.py
+++ b/tests/util.py
@@ -184,9 +184,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