mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge branch 'master' into add_override_option
This commit is contained in:
@@ -0,0 +1 @@
|
||||
"foo"
|
||||
2
tests/roots/test-need-escaped/bar.rst
Normal file
2
tests/roots/test-need-escaped/bar.rst
Normal file
@@ -0,0 +1,2 @@
|
||||
bar
|
||||
===
|
||||
2
tests/roots/test-need-escaped/baz.rst
Normal file
2
tests/roots/test-need-escaped/baz.rst
Normal file
@@ -0,0 +1,2 @@
|
||||
baz
|
||||
===
|
||||
5
tests/roots/test-need-escaped/conf.py
Normal file
5
tests/roots/test-need-escaped/conf.py
Normal file
@@ -0,0 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
master_doc = 'index'
|
||||
project = 'need <b>"escaped"</b> project'
|
||||
smartquotes = False
|
||||
15
tests/roots/test-need-escaped/foo.rst
Normal file
15
tests/roots/test-need-escaped/foo.rst
Normal file
@@ -0,0 +1,15 @@
|
||||
<foo>
|
||||
=====
|
||||
|
||||
.. toctree::
|
||||
|
||||
quux
|
||||
|
||||
foo "1"
|
||||
-------
|
||||
|
||||
foo.1-1
|
||||
^^^^^^^
|
||||
|
||||
foo.2
|
||||
-----
|
||||
30
tests/roots/test-need-escaped/index.rst
Normal file
30
tests/roots/test-need-escaped/index.rst
Normal file
@@ -0,0 +1,30 @@
|
||||
.. Sphinx Tests documentation master file, created by sphinx-quickstart on Wed Jun 4 23:49:58 2008.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Welcome to Sphinx Tests's documentation!
|
||||
========================================
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:numbered:
|
||||
:caption: Table of Contents
|
||||
:name: mastertoc
|
||||
|
||||
foo
|
||||
bar
|
||||
http://sphinx-doc.org/
|
||||
baz
|
||||
qux
|
||||
|
||||
.. index::
|
||||
pair: "subsection"; <subsection>
|
||||
|
||||
----------
|
||||
subsection
|
||||
----------
|
||||
|
||||
subsubsection
|
||||
-------------
|
||||
2
tests/roots/test-need-escaped/quux.rst
Normal file
2
tests/roots/test-need-escaped/quux.rst
Normal file
@@ -0,0 +1,2 @@
|
||||
quux
|
||||
====
|
||||
1
tests/roots/test-need-escaped/qux.rst
Normal file
1
tests/roots/test-need-escaped/qux.rst
Normal file
@@ -0,0 +1 @@
|
||||
qux.rst has no section title
|
||||
@@ -11,13 +11,15 @@
|
||||
"""
|
||||
|
||||
import sys
|
||||
from warnings import catch_warnings
|
||||
|
||||
import pytest
|
||||
from docutils.statemachine import ViewList
|
||||
from six import PY3
|
||||
|
||||
from sphinx.ext.autodoc import AutoDirective, add_documenter, \
|
||||
ModuleLevelDocumenter, FunctionDocumenter, cut_lines, between, ALL
|
||||
from sphinx.ext.autodoc import (
|
||||
AutoDirective, ModuleLevelDocumenter, FunctionDocumenter, cut_lines, between, ALL
|
||||
)
|
||||
from sphinx.testing.util import SphinxTestApp, Struct # NOQA
|
||||
from sphinx.util import logging
|
||||
|
||||
@@ -550,7 +552,7 @@ def test_new_documenter():
|
||||
def document_members(self, all_members=False):
|
||||
return
|
||||
|
||||
add_documenter(MyDocumenter)
|
||||
app.add_autodocumenter(MyDocumenter)
|
||||
|
||||
def assert_result_contains(item, objtype, name, **kw):
|
||||
app._warning.truncate(0)
|
||||
@@ -591,12 +593,13 @@ def test_attrgetter_using():
|
||||
assert fullname not in documented_members, \
|
||||
'%r was not hooked by special_attrgetter function' % fullname
|
||||
|
||||
options.members = ALL
|
||||
options.inherited_members = False
|
||||
assert_getter_works('class', 'target.Class', Class, ['meth'])
|
||||
with catch_warnings(record=True):
|
||||
options.members = ALL
|
||||
options.inherited_members = False
|
||||
assert_getter_works('class', 'target.Class', Class, ['meth'])
|
||||
|
||||
options.inherited_members = True
|
||||
assert_getter_works('class', 'target.Class', Class, ['meth', 'inheritedmeth'])
|
||||
options.inherited_members = True
|
||||
assert_getter_works('class', 'target.Class', Class, ['meth', 'inheritedmeth'])
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('setup_test')
|
||||
|
||||
@@ -19,17 +19,17 @@ import pytest
|
||||
# check given command is runnable
|
||||
def runnable(command):
|
||||
try:
|
||||
p = Popen(command, stdout=PIPE)
|
||||
p = Popen(command, stdout=PIPE, stderr=PIPE)
|
||||
except OSError:
|
||||
# command not found
|
||||
return False
|
||||
else:
|
||||
p.communicate()
|
||||
return p.returncode
|
||||
return p.returncode == 0
|
||||
|
||||
|
||||
class EPUBElementTree(object):
|
||||
"""Test helper for content.opf and tox.ncx"""
|
||||
"""Test helper for content.opf and toc.ncx"""
|
||||
namespaces = {
|
||||
'idpf': 'http://www.idpf.org/2007/opf',
|
||||
'dc': 'http://purl.org/dc/elements/1.1/',
|
||||
@@ -226,6 +226,62 @@ def test_nested_toc(app):
|
||||
assert navinfo(grandchild[0]) == ('foo.xhtml#foo-1-1', 'foo.1-1')
|
||||
|
||||
|
||||
@pytest.mark.sphinx('epub', testroot='need-escaped')
|
||||
def test_escaped_toc(app):
|
||||
app.build()
|
||||
|
||||
# toc.ncx
|
||||
toc = EPUBElementTree.fromstring((app.outdir / 'toc.ncx').bytes())
|
||||
assert toc.find("./ncx:docTitle/ncx:text").text == ('need <b>"escaped"</b> '
|
||||
'project documentation')
|
||||
|
||||
# toc.ncx / navPoint
|
||||
def navinfo(elem):
|
||||
label = elem.find("./ncx:navLabel/ncx:text")
|
||||
content = elem.find("./ncx:content")
|
||||
return (elem.get('id'), elem.get('playOrder'),
|
||||
content.get('src'), label.text)
|
||||
|
||||
navpoints = toc.findall("./ncx:navMap/ncx:navPoint")
|
||||
assert len(navpoints) == 4
|
||||
assert navinfo(navpoints[0]) == ('navPoint1', '1', 'index.xhtml',
|
||||
u"Welcome to Sphinx Tests's documentation!")
|
||||
assert navpoints[0].findall("./ncx:navPoint") == []
|
||||
|
||||
# toc.ncx / nested navPoints
|
||||
assert navinfo(navpoints[1]) == ('navPoint2', '2', 'foo.xhtml', '<foo>')
|
||||
navchildren = navpoints[1].findall("./ncx:navPoint")
|
||||
assert len(navchildren) == 4
|
||||
assert navinfo(navchildren[0]) == ('navPoint3', '2', 'foo.xhtml', '<foo>')
|
||||
assert navinfo(navchildren[1]) == ('navPoint4', '3', 'quux.xhtml', 'quux')
|
||||
assert navinfo(navchildren[2]) == ('navPoint5', '4', 'foo.xhtml#foo-1', u'foo “1”')
|
||||
assert navinfo(navchildren[3]) == ('navPoint8', '6', 'foo.xhtml#foo-2', 'foo.2')
|
||||
|
||||
# nav.xhtml / nav
|
||||
def navinfo(elem):
|
||||
anchor = elem.find("./xhtml:a")
|
||||
return (anchor.get('href'), anchor.text)
|
||||
|
||||
nav = EPUBElementTree.fromstring((app.outdir / 'nav.xhtml').bytes())
|
||||
toc = nav.findall("./xhtml:body/xhtml:nav/xhtml:ol/xhtml:li")
|
||||
assert len(toc) == 4
|
||||
assert navinfo(toc[0]) == ('index.xhtml',
|
||||
"Welcome to Sphinx Tests's documentation!")
|
||||
assert toc[0].findall("./xhtml:ol") == []
|
||||
|
||||
# nav.xhtml / nested toc
|
||||
assert navinfo(toc[1]) == ('foo.xhtml', '<foo>')
|
||||
tocchildren = toc[1].findall("./xhtml:ol/xhtml:li")
|
||||
assert len(tocchildren) == 3
|
||||
assert navinfo(tocchildren[0]) == ('quux.xhtml', 'quux')
|
||||
assert navinfo(tocchildren[1]) == ('foo.xhtml#foo-1', u'foo “1”')
|
||||
assert navinfo(tocchildren[2]) == ('foo.xhtml#foo-2', 'foo.2')
|
||||
|
||||
grandchild = tocchildren[1].findall("./xhtml:ol/xhtml:li")
|
||||
assert len(grandchild) == 1
|
||||
assert navinfo(grandchild[0]) == ('foo.xhtml#foo-1-1', 'foo.1-1')
|
||||
|
||||
|
||||
@pytest.mark.sphinx('epub', testroot='basic')
|
||||
def test_epub_writing_mode(app):
|
||||
# horizontal (default)
|
||||
@@ -266,7 +322,7 @@ def test_run_epubcheck(app):
|
||||
app.build()
|
||||
|
||||
epubcheck = os.environ.get('EPUBCHECK_PATH', '/usr/share/java/epubcheck.jar')
|
||||
if runnable('java') and os.path.exists(epubcheck):
|
||||
if runnable(['java', '-version']) and os.path.exists(epubcheck):
|
||||
p = Popen(['java', '-jar', epubcheck, app.outdir / 'SphinxTests.epub'],
|
||||
stdout=PIPE, stderr=PIPE)
|
||||
stdout, stderr = p.communicate()
|
||||
|
||||
@@ -13,16 +13,107 @@
|
||||
|
||||
import pytest
|
||||
|
||||
from sphinx.testing.util import etree_parse
|
||||
|
||||
|
||||
@pytest.mark.sphinx('qthelp', testroot='basic')
|
||||
def test_qthelp_basic(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
qhp = (app.outdir / 'Python.qhp').text()
|
||||
assert '<customFilter name="Python ">' in qhp
|
||||
assert '<filterAttribute>Python</filterAttribute>' in qhp
|
||||
assert '<filterAttribute></filterAttribute>' in qhp
|
||||
assert '<section title="Python documentation" ref="index.html">' in qhp
|
||||
assert '<file>genindex.html</file>' in qhp
|
||||
assert '<file>index.html</file>' in qhp
|
||||
assert '<file>_static/basic.css</file>' in qhp
|
||||
assert '<file>_static/down.png</file>' in qhp
|
||||
|
||||
qhcp = (app.outdir / 'Python.qhcp').text()
|
||||
assert '<title>Python documentation</title>' in qhcp
|
||||
assert '<homePage>qthelp://org.sphinx.python/doc/index.html</homePage>' in qhcp
|
||||
assert '<startPage>qthelp://org.sphinx.python/doc/index.html</startPage>' in qhcp
|
||||
assert '<input>Python.qhp</input>' in qhcp
|
||||
assert '<output>Python.qch</output>' in qhcp
|
||||
assert '<file>Python.qch</file>' in qhcp
|
||||
|
||||
|
||||
@pytest.mark.sphinx('qthelp', testroot='need-escaped')
|
||||
def test_qthelp_escaped(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
et = etree_parse(app.outdir / 'needbescapedbproject.qhp')
|
||||
customFilter = et.find('.//customFilter')
|
||||
assert len(customFilter) == 2
|
||||
assert customFilter.attrib == {'name': 'need <b>"escaped"</b> project '}
|
||||
assert customFilter[0].text == 'needbescapedbproject'
|
||||
assert customFilter[1].text is None
|
||||
|
||||
toc = et.find('.//toc')
|
||||
assert len(toc) == 1
|
||||
assert toc[0].attrib == {'title': 'need <b>"escaped"</b> project documentation',
|
||||
'ref': 'index.html'}
|
||||
assert len(toc[0]) == 4
|
||||
assert toc[0][0].attrib == {'title': '<foo>', 'ref': 'foo.html'}
|
||||
assert toc[0][0][0].attrib == {'title': 'quux', 'ref': 'quux.html'}
|
||||
assert toc[0][0][1].attrib == {'title': 'foo "1"', 'ref': 'foo.html#foo-1'}
|
||||
assert toc[0][0][1][0].attrib == {'title': 'foo.1-1', 'ref': 'foo.html#foo-1-1'}
|
||||
assert toc[0][0][2].attrib == {'title': 'foo.2', 'ref': 'foo.html#foo-2'}
|
||||
assert toc[0][1].attrib == {'title': 'bar', 'ref': 'bar.html'}
|
||||
assert toc[0][2].attrib == {'title': 'http://sphinx-doc.org/',
|
||||
'ref': 'http://sphinx-doc.org/'}
|
||||
assert toc[0][3].attrib == {'title': 'baz', 'ref': 'baz.html'}
|
||||
|
||||
keywords = et.find('.//keywords')
|
||||
assert len(keywords) == 2
|
||||
assert keywords[0].attrib == {'name': '<subsection>', 'ref': 'index.html#index-0'}
|
||||
assert keywords[1].attrib == {'name': '"subsection"', 'ref': 'index.html#index-0'}
|
||||
|
||||
|
||||
@pytest.mark.sphinx('qthelp', testroot='basic')
|
||||
def test_qthelp_namespace(app, status, warning):
|
||||
# default namespace
|
||||
app.builder.build_all()
|
||||
|
||||
qhp = (app.outdir / 'Python.qhp').text()
|
||||
assert '<namespace>org.sphinx.python</namespace>' in qhp
|
||||
|
||||
qhcp = (app.outdir / 'Python.qhcp').text()
|
||||
assert '<homePage>qthelp://org.sphinx.python/doc/index.html</homePage>' in qhcp
|
||||
assert '<startPage>qthelp://org.sphinx.python/doc/index.html</startPage>' in qhcp
|
||||
|
||||
# give a namespace
|
||||
app.config.qthelp_namespace = 'org.sphinx-doc.sphinx'
|
||||
app.builder.build_all()
|
||||
|
||||
qhp = (app.outdir / 'Python.qhp').text()
|
||||
assert '<namespace>org.sphinxdoc.sphinx</namespace>' in qhp
|
||||
|
||||
qhcp = (app.outdir / 'Python.qhcp').text()
|
||||
assert '<homePage>qthelp://org.sphinxdoc.sphinx/doc/index.html</homePage>' in qhcp
|
||||
assert '<startPage>qthelp://org.sphinxdoc.sphinx/doc/index.html</startPage>' in qhcp
|
||||
|
||||
|
||||
@pytest.mark.sphinx('qthelp', testroot='basic')
|
||||
def test_qthelp_title(app, status, warning):
|
||||
# default title
|
||||
app.builder.build_all()
|
||||
|
||||
qhp = (app.outdir / 'Python.qhp').text()
|
||||
assert '<section title="Python documentation" ref="index.html">' in qhp
|
||||
|
||||
qhcp = (app.outdir / 'Python.qhcp').text()
|
||||
assert '<title>Python documentation</title>' in qhcp
|
||||
|
||||
# give a title
|
||||
app.config.html_title = 'Sphinx <b>"full"</b> title'
|
||||
app.config.html_short_title = 'Sphinx <b>"short"</b> title'
|
||||
app.builder.build_all()
|
||||
|
||||
qhp = (app.outdir / 'Python.qhp').text()
|
||||
assert ('<section title="Sphinx <b>"full"</b> title" ref="index.html">'
|
||||
in qhp)
|
||||
|
||||
qhcp = (app.outdir / 'Python.qhcp').text()
|
||||
assert '<title>Sphinx <b>"short"</b> title</title>' in qhcp
|
||||
|
||||
@@ -211,7 +211,7 @@ def test_trailing_underscore(make_app, apidoc):
|
||||
|
||||
@pytest.mark.apidoc(
|
||||
coderoot='test-apidoc-pep420/a',
|
||||
excludes=["b/c/d.py", "b/e/f.py"],
|
||||
excludes=["b/c/d.py", "b/e/f.py", "b/e/__init__.py"],
|
||||
options=["--implicit-namespaces", "--separate"],
|
||||
)
|
||||
def test_excludes(apidoc):
|
||||
@@ -223,6 +223,45 @@ def test_excludes(apidoc):
|
||||
assert (outdir / 'a.b.x.y.rst').isfile()
|
||||
|
||||
|
||||
@pytest.mark.apidoc(
|
||||
coderoot='test-apidoc-pep420/a',
|
||||
excludes=["b/e"],
|
||||
options=["--implicit-namespaces", "--separate"],
|
||||
)
|
||||
def test_excludes_subpackage_should_be_skipped(apidoc):
|
||||
"""Subpackage exclusion should work."""
|
||||
outdir = apidoc.outdir
|
||||
assert (outdir / 'conf.py').isfile()
|
||||
assert (outdir / 'a.b.c.rst').isfile() # generated because not empty
|
||||
assert not (outdir / 'a.b.e.f.rst').isfile() # skipped because 'b/e' subpackage is skipped
|
||||
|
||||
|
||||
@pytest.mark.apidoc(
|
||||
coderoot='test-apidoc-pep420/a',
|
||||
excludes=["b/e/f.py"],
|
||||
options=["--implicit-namespaces", "--separate"],
|
||||
)
|
||||
def test_excludes_module_should_be_skipped(apidoc):
|
||||
"""Module exclusion should work."""
|
||||
outdir = apidoc.outdir
|
||||
assert (outdir / 'conf.py').isfile()
|
||||
assert (outdir / 'a.b.c.rst').isfile() # generated because not empty
|
||||
assert not (outdir / 'a.b.e.f.rst').isfile() # skipped because of empty after excludes
|
||||
|
||||
|
||||
@pytest.mark.apidoc(
|
||||
coderoot='test-apidoc-pep420/a',
|
||||
excludes=[],
|
||||
options=["--implicit-namespaces", "--separate"],
|
||||
)
|
||||
def test_excludes_module_should_not_be_skipped(apidoc):
|
||||
"""Module should be included if no excludes are used."""
|
||||
outdir = apidoc.outdir
|
||||
assert (outdir / 'conf.py').isfile()
|
||||
assert (outdir / 'a.b.c.rst').isfile() # generated because not empty
|
||||
assert (outdir / 'a.b.e.f.rst').isfile() # skipped because of empty after excludes
|
||||
|
||||
|
||||
@pytest.mark.apidoc(
|
||||
coderoot='test-root',
|
||||
options=[
|
||||
@@ -339,3 +378,29 @@ def extract_toc(path):
|
||||
toctree = rst[start_idx + len(toctree_start):end_idx]
|
||||
|
||||
return toctree
|
||||
|
||||
|
||||
@pytest.mark.apidoc(
|
||||
coderoot='test-apidoc-subpackage-in-toc',
|
||||
options=['--separate']
|
||||
)
|
||||
|
||||
|
||||
def test_subpackage_in_toc(make_app, apidoc):
|
||||
"""Make sure that empty subpackages with non-empty subpackages in them
|
||||
are not skipped (issue #4520)
|
||||
"""
|
||||
outdir = apidoc.outdir
|
||||
assert (outdir / 'conf.py').isfile()
|
||||
|
||||
assert (outdir / 'parent.rst').isfile()
|
||||
with open(outdir / 'parent.rst') as f:
|
||||
parent = f.read()
|
||||
assert 'parent.child' in parent
|
||||
|
||||
assert (outdir / 'parent.child.rst').isfile()
|
||||
with open(outdir / 'parent.child.rst') as f:
|
||||
parent_child = f.read()
|
||||
assert 'parent.child.foo' in parent_child
|
||||
|
||||
assert (outdir / 'parent.child.foo.rst').isfile()
|
||||
|
||||
Reference in New Issue
Block a user