Merge branch 'master' into cpp-attributes
@@ -472,10 +472,9 @@ class coverage:
|
||||
def save(self):
|
||||
if self.usecache and self.cache:
|
||||
self.canonicalize_filenames()
|
||||
cache = open(self.cache, 'wb')
|
||||
import marshal
|
||||
marshal.dump(self.cexecuted, cache)
|
||||
cache.close()
|
||||
with open(self.cache, 'wb') as cache:
|
||||
marshal.dump(self.cexecuted, cache)
|
||||
|
||||
# restore(). Restore coverage data from the coverage cache (if it exists).
|
||||
|
||||
@@ -488,10 +487,9 @@ class coverage:
|
||||
|
||||
def restore_file(self, file_name):
|
||||
try:
|
||||
cache = open(file_name, 'rb')
|
||||
import marshal
|
||||
cexecuted = marshal.load(cache)
|
||||
cache.close()
|
||||
with open(file_name, 'rb') as cache:
|
||||
cexecuted = marshal.load(cache)
|
||||
if isinstance(cexecuted, dict):
|
||||
return cexecuted
|
||||
else:
|
||||
@@ -614,8 +612,8 @@ class coverage:
|
||||
)
|
||||
filename = filename[:-1]
|
||||
if not source:
|
||||
sourcef = open(filename, 'rU')
|
||||
source = sourcef.read()
|
||||
with open(filename, 'rU') as sourcef:
|
||||
source = sourcef.read()
|
||||
try:
|
||||
lines, excluded_lines, line_map = self.find_executable_statements(
|
||||
source, exclude=self.exclude_re
|
||||
@@ -625,8 +623,6 @@ class coverage:
|
||||
"Couldn't parse '%s' as Python source: '%s' at line %d" %
|
||||
(filename, synerr.msg, synerr.lineno)
|
||||
)
|
||||
if sourcef:
|
||||
sourcef.close()
|
||||
result = filename, lines, excluded_lines, line_map
|
||||
self.analysis_cache[morf] = result
|
||||
return result
|
||||
|
||||
@@ -53,9 +53,3 @@ footenotes
|
||||
.. [#] footnotes in table caption
|
||||
|
||||
.. [#] footnotes in table
|
||||
|
||||
|
||||
missing target
|
||||
--------------------
|
||||
[missing]_ citation
|
||||
|
||||
|
||||
@@ -15,9 +15,6 @@ Sphinx image handling
|
||||
.. an image with unspecified extension
|
||||
.. image:: img.*
|
||||
|
||||
.. a non-existing image with .*
|
||||
.. image:: foo.*
|
||||
|
||||
.. a non-local image URI
|
||||
.. image:: http://www.python.org/logo.png
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 65 KiB |
@@ -15,10 +15,6 @@ Test file and literal inclusion
|
||||
.. literalinclude:: literal.inc
|
||||
:language: python
|
||||
|
||||
.. should give a warning
|
||||
.. literalinclude:: wrongenc.inc
|
||||
:language: none
|
||||
|
||||
.. should succeed
|
||||
.. literalinclude:: wrongenc.inc
|
||||
:encoding: latin-1
|
||||
|
||||
@@ -161,7 +161,6 @@ Adding \n to test unescaping.
|
||||
* :doc:`subdir/includes`
|
||||
* ``:download:`` is tested in includes.txt
|
||||
* :option:`Python -c option <python -c>`
|
||||
* This used to crash: :option:`&option`
|
||||
|
||||
Test :abbr:`abbr (abbreviation)` and another :abbr:`abbr (abbreviation)`.
|
||||
|
||||
@@ -295,13 +294,6 @@ Code blocks
|
||||
false
|
||||
end
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
import sys
|
||||
|
||||
sys.stdout.write('hello world!\n')
|
||||
|
||||
|
||||
Misc stuff
|
||||
----------
|
||||
|
||||
@@ -381,13 +373,6 @@ Index markup
|
||||
see: from; to
|
||||
seealso: fromalso; toalso
|
||||
|
||||
Invalid index markup...
|
||||
|
||||
.. index::
|
||||
single:
|
||||
pair:
|
||||
keyword:
|
||||
|
||||
.. index::
|
||||
!Main, !Other
|
||||
!single: entry; pair
|
||||
|
||||
@@ -93,7 +93,7 @@ Referring to :func:`nothing <>`.
|
||||
* expression
|
||||
:returns: a new :class:`Time` instance
|
||||
:rtype: Time
|
||||
:raises ValueError: if the values are out of range
|
||||
:raises Error: if the values are out of range
|
||||
:ivar int hour: like *hour*
|
||||
:ivar minute: like *minute*
|
||||
:vartype minute: int
|
||||
|
||||
|
Before Width: | Height: | Size: 218 B After Width: | Height: | Size: 120 B |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 218 B After Width: | Height: | Size: 120 B |
|
Before Width: | Height: | Size: 218 B After Width: | Height: | Size: 120 B |
7
tests/roots/test-basic/conf.py
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
master_doc = 'index'
|
||||
|
||||
latex_documents = [
|
||||
(master_doc, 'test.tex', 'The basic Sphinx documentation for testing', 'Sphinx', 'report')
|
||||
]
|
||||
29
tests/roots/test-basic/index.rst
Normal file
@@ -0,0 +1,29 @@
|
||||
The basic Sphinx documentation for testing
|
||||
==========================================
|
||||
|
||||
Sphinx is a tool that makes it easy to create intelligent and beautiful
|
||||
documentation for Python projects (or other documents consisting of multiple
|
||||
reStructuredText sources), written by Georg Brandl. It was originally created
|
||||
for the new Python documentation, and has excellent facilities for Python
|
||||
project documentation, but C/C++ is supported as well, and more languages are
|
||||
planned.
|
||||
|
||||
Sphinx uses reStructuredText as its markup language, and many of its strengths
|
||||
come from the power and straightforwardness of reStructuredText and its parsing
|
||||
and translating suite, the Docutils.
|
||||
|
||||
Among its features are the following:
|
||||
|
||||
* Output formats: HTML (including derivative formats such as HTML Help, Epub
|
||||
and Qt Help), plain text, manual pages and LaTeX or direct PDF output
|
||||
using rst2pdf
|
||||
* Extensive cross-references: semantic markup and automatic links
|
||||
for functions, classes, glossary terms and similar pieces of information
|
||||
* Hierarchical structure: easy definition of a document tree, with automatic
|
||||
links to siblings, parents and children
|
||||
* Automatic indices: general index as well as a module index
|
||||
* Code handling: automatic highlighting using the Pygments highlighter
|
||||
* Flexible HTML output using the Jinja 2 templating engine
|
||||
* Various extensions are available, e.g. for automatic testing of snippets
|
||||
and inclusion of appropriately formatted docstrings
|
||||
* Setuptools integration
|
||||
@@ -1,4 +1,4 @@
|
||||
from sphinx.config import string_classes
|
||||
from sphinx.config import string_classes, ENUM
|
||||
|
||||
value1 = 123 # wrong type
|
||||
value2 = 123 # lambda with wrong type
|
||||
@@ -45,3 +45,4 @@ def setup(app):
|
||||
app.add_config_value('value14', None, False, string_classes)
|
||||
app.add_config_value('value15', u'unicode', False)
|
||||
app.add_config_value('value16', u'unicode', False)
|
||||
app.add_config_value('value17', 'default', False, ENUM('default', 'one', 'two'))
|
||||
|
||||
6
tests/roots/test-ext-math-simple/conf.py
Normal file
@@ -0,0 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
master_doc = 'index'
|
||||
|
||||
latex_documents = [
|
||||
(master_doc, 'test.tex', 'Math Extension Testing', 'Sphinx', 'report')]
|
||||
4
tests/roots/test-ext-math-simple/index.rst
Normal file
@@ -0,0 +1,4 @@
|
||||
Test Math
|
||||
=========
|
||||
|
||||
.. math:: a^2+b^2=c^2
|
||||
31
tests/roots/test-ext-math/math.rst
Normal file
@@ -0,0 +1,31 @@
|
||||
Test math extensions :math:`E = m c^2`
|
||||
======================================
|
||||
|
||||
This is inline math: :math:`a^2 + b^2 = c^2`.
|
||||
|
||||
.. math:: a^2 + b^2 = c^2
|
||||
|
||||
.. math::
|
||||
|
||||
a + 1 < b
|
||||
|
||||
.. math::
|
||||
:label: foo
|
||||
|
||||
e^{i\pi} = 1
|
||||
|
||||
.. math::
|
||||
:label:
|
||||
|
||||
e^{ix} = \cos x + i\sin x
|
||||
|
||||
.. math::
|
||||
|
||||
n \in \mathbb N
|
||||
|
||||
.. math::
|
||||
:nowrap:
|
||||
|
||||
a + 1 < b
|
||||
|
||||
Referencing equation :eq:`foo`.
|
||||
4
tests/roots/test-ext-todo/bar.rst
Normal file
@@ -0,0 +1,4 @@
|
||||
bar
|
||||
===
|
||||
|
||||
.. todo:: todo in bar
|
||||
4
tests/roots/test-ext-todo/conf.py
Normal file
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
extensions = ['sphinx.ext.todo']
|
||||
master_doc = 'index'
|
||||
4
tests/roots/test-ext-todo/foo.rst
Normal file
@@ -0,0 +1,4 @@
|
||||
foo
|
||||
===
|
||||
|
||||
.. todo:: todo in foo
|
||||
9
tests/roots/test-ext-todo/index.rst
Normal file
@@ -0,0 +1,9 @@
|
||||
test for sphinx.ext.todo
|
||||
========================
|
||||
|
||||
.. toctree::
|
||||
|
||||
foo
|
||||
bar
|
||||
|
||||
.. todolist::
|
||||
|
Before Width: | Height: | Size: 218 B After Width: | Height: | Size: 120 B |
@@ -1,6 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
master_doc = 'index'
|
||||
project = 'Sphinx'
|
||||
version = '1.4.4'
|
||||
|
||||
html_static_path = ['static', 'subdir']
|
||||
html_extra_path = ['extra', 'subdir']
|
||||
exclude_patterns = ['**/_build', '**/.htpasswd']
|
||||
1
tests/roots/test-html_assets/extra/API.html_t
Normal file
@@ -0,0 +1 @@
|
||||
{{ project }}-{{ version }}
|
||||
BIN
tests/roots/test-html_assets/extra/rimg.png
Normal file
|
After Width: | Height: | Size: 120 B |
0
tests/roots/test-html_assets/static/.htaccess
Normal file
0
tests/roots/test-html_assets/static/.htpasswd
Normal file
1
tests/roots/test-html_assets/static/API.html_t
Normal file
@@ -0,0 +1 @@
|
||||
{{ project }}-{{ version }}
|
||||
0
tests/roots/test-html_assets/static/css/style.css
Normal file
BIN
tests/roots/test-html_assets/static/rimg.png
Normal file
|
After Width: | Height: | Size: 120 B |
BIN
tests/roots/test-html_assets/subdir/background.png
Normal file
|
After Width: | Height: | Size: 120 B |
|
Before Width: | Height: | Size: 218 B |
|
Before Width: | Height: | Size: 218 B |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 218 B After Width: | Height: | Size: 120 B |
|
Before Width: | Height: | Size: 218 B After Width: | Height: | Size: 120 B |
|
Before Width: | Height: | Size: 218 B After Width: | Height: | Size: 120 B |
|
Before Width: | Height: | Size: 218 B After Width: | Height: | Size: 120 B |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 218 B After Width: | Height: | Size: 120 B |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 218 B After Width: | Height: | Size: 120 B |
@@ -5,4 +5,10 @@ meta keywords
|
||||
:keywords lang=en: findthiskey, thistoo, notgerman
|
||||
:keywords: thisonetoo
|
||||
:keywords lang=de: onlygerman, onlytoogerman
|
||||
:description: thisnoteither
|
||||
:description: thisnoteither
|
||||
|
||||
Stemmer
|
||||
=======
|
||||
|
||||
zfs
|
||||
findthisstemmedkey
|
||||
4
tests/roots/test-searchadapters/conf.py
Normal file
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
master_doc = 'markup'
|
||||
source_suffix = '.txt'
|
||||
447
tests/roots/test-searchadapters/markup.txt
Normal file
@@ -0,0 +1,447 @@
|
||||
:tocdepth: 2
|
||||
|
||||
.. title:: set by title directive
|
||||
|
||||
Testing various markup
|
||||
======================
|
||||
|
||||
Meta markup
|
||||
-----------
|
||||
|
||||
.. sectionauthor:: Georg Brandl
|
||||
.. moduleauthor:: Georg Brandl
|
||||
|
||||
.. contents:: TOC
|
||||
|
||||
.. meta::
|
||||
:author: Me
|
||||
:keywords: docs, sphinx
|
||||
|
||||
|
||||
Generic reST
|
||||
------------
|
||||
|
||||
A |subst| (the definition is in rst_epilog).
|
||||
|
||||
.. highlight:: none
|
||||
|
||||
.. _label:
|
||||
|
||||
::
|
||||
|
||||
some code
|
||||
|
||||
Option list:
|
||||
|
||||
-h help
|
||||
--help also help
|
||||
|
||||
Line block:
|
||||
|
||||
| line1
|
||||
| line2
|
||||
| line3
|
||||
| line4
|
||||
| line5
|
||||
| line6
|
||||
| line7
|
||||
|
||||
|
||||
Body directives
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
.. topic:: Title
|
||||
|
||||
Topic body.
|
||||
|
||||
.. sidebar:: Sidebar
|
||||
:subtitle: Sidebar subtitle
|
||||
|
||||
Sidebar body.
|
||||
|
||||
.. rubric:: Test rubric
|
||||
|
||||
.. epigraph:: Epigraph title
|
||||
|
||||
Epigraph body.
|
||||
|
||||
-- Author
|
||||
|
||||
.. highlights:: Highlights
|
||||
|
||||
Highlights body.
|
||||
|
||||
.. pull-quote:: Pull-quote
|
||||
|
||||
Pull quote body.
|
||||
|
||||
.. compound::
|
||||
|
||||
a
|
||||
|
||||
b
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
with some *markup* inside
|
||||
|
||||
|
||||
.. _admonition-section:
|
||||
|
||||
Admonitions
|
||||
^^^^^^^^^^^
|
||||
|
||||
.. admonition:: My Admonition
|
||||
|
||||
Admonition text.
|
||||
|
||||
.. note::
|
||||
Note text.
|
||||
|
||||
.. warning::
|
||||
|
||||
Warning text.
|
||||
|
||||
.. _some-label:
|
||||
|
||||
.. tip::
|
||||
Tip text.
|
||||
|
||||
Indirect hyperlink targets
|
||||
|
||||
.. _other-label: some-label_
|
||||
|
||||
Inline markup
|
||||
-------------
|
||||
|
||||
*Generic inline markup*
|
||||
|
||||
Adding \n to test unescaping.
|
||||
|
||||
* :command:`command\\n`
|
||||
* :dfn:`dfn\\n`
|
||||
* :guilabel:`guilabel with &accelerator and \\n`
|
||||
* :kbd:`kbd\\n`
|
||||
* :mailheader:`mailheader\\n`
|
||||
* :makevar:`makevar\\n`
|
||||
* :manpage:`manpage\\n`
|
||||
* :mimetype:`mimetype\\n`
|
||||
* :newsgroup:`newsgroup\\n`
|
||||
* :program:`program\\n`
|
||||
* :regexp:`regexp\\n`
|
||||
* :menuselection:`File --> Close\\n`
|
||||
* :menuselection:`&File --> &Print`
|
||||
* :file:`a/{varpart}/b\\n`
|
||||
* :samp:`print {i}\\n`
|
||||
|
||||
*Linking inline markup*
|
||||
|
||||
* :pep:`8`
|
||||
* :pep:`Python Enhancement Proposal #8 <8>`
|
||||
* :rfc:`1`
|
||||
* :rfc:`Request for Comments #1 <1>`
|
||||
* :envvar:`HOME`
|
||||
* :keyword:`with`
|
||||
* :token:`try statement <try_stmt>`
|
||||
* :ref:`admonition-section`
|
||||
* :ref:`here <some-label>`
|
||||
* :ref:`there <other-label>`
|
||||
* :ref:`my-figure`
|
||||
* :ref:`my-figure-name`
|
||||
* :ref:`my-table`
|
||||
* :ref:`my-table-name`
|
||||
* :ref:`my-code-block`
|
||||
* :ref:`my-code-block-name`
|
||||
* :numref:`my-figure`
|
||||
* :numref:`my-figure-name`
|
||||
* :numref:`my-table`
|
||||
* :numref:`my-table-name`
|
||||
* :numref:`my-code-block`
|
||||
* :numref:`my-code-block-name`
|
||||
* :doc:`subdir/includes`
|
||||
* ``:download:`` is tested in includes.txt
|
||||
* :option:`Python -c option <python -c>`
|
||||
* This used to crash: :option:`&option`
|
||||
|
||||
Test :abbr:`abbr (abbreviation)` and another :abbr:`abbr (abbreviation)`.
|
||||
|
||||
Testing the :index:`index` role, also available with
|
||||
:index:`explicit <pair: title; explicit>` title.
|
||||
|
||||
.. _with:
|
||||
|
||||
With
|
||||
----
|
||||
|
||||
(Empty section.)
|
||||
|
||||
|
||||
Tables
|
||||
------
|
||||
|
||||
.. tabularcolumns:: |L|p{5cm}|R|
|
||||
|
||||
.. _my-table:
|
||||
|
||||
.. table:: my table
|
||||
:name: my-table-name
|
||||
|
||||
+----+----------------+----+
|
||||
| 1 | * Block elems | x |
|
||||
| | * In table | |
|
||||
+----+----------------+----+
|
||||
| 2 | Empty cells: | |
|
||||
+----+----------------+----+
|
||||
|
||||
.. table:: empty cell in table header
|
||||
|
||||
===== ======
|
||||
\
|
||||
===== ======
|
||||
1 2
|
||||
3 4
|
||||
===== ======
|
||||
|
||||
Tables with multirow and multicol:
|
||||
|
||||
.. only:: latex
|
||||
|
||||
+----+----------------+---------+
|
||||
| 1 | test! | c |
|
||||
+----+---------+------+ |
|
||||
| 2 | col | col | |
|
||||
| y +---------+------+----+----+
|
||||
| x | multi-column cell | x |
|
||||
+----+---------------------+----+
|
||||
|
||||
+----+
|
||||
| 1 |
|
||||
+ +
|
||||
| |
|
||||
+----+
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 0
|
||||
|
||||
* - .. figure:: img.png
|
||||
|
||||
figure in table
|
||||
|
||||
|
||||
Figures
|
||||
-------
|
||||
|
||||
.. _my-figure:
|
||||
|
||||
.. figure:: img.png
|
||||
:name: my-figure-name
|
||||
|
||||
My caption of the figure
|
||||
|
||||
My description paragraph of the figure.
|
||||
|
||||
Description paragraph is wraped with legend node.
|
||||
|
||||
.. figure:: rimg.png
|
||||
:align: right
|
||||
|
||||
figure with align option
|
||||
|
||||
.. figure:: rimg.png
|
||||
:align: right
|
||||
:figwidth: 50%
|
||||
|
||||
figure with align & figwidth option
|
||||
|
||||
.. figure:: rimg.png
|
||||
:align: right
|
||||
:width: 3cm
|
||||
|
||||
figure with align & width option
|
||||
|
||||
Version markup
|
||||
--------------
|
||||
|
||||
.. versionadded:: 0.6
|
||||
Some funny **stuff**.
|
||||
|
||||
.. versionchanged:: 0.6
|
||||
Even more funny stuff.
|
||||
|
||||
.. deprecated:: 0.6
|
||||
Boring stuff.
|
||||
|
||||
.. versionadded:: 1.2
|
||||
|
||||
First paragraph of versionadded.
|
||||
|
||||
.. versionchanged:: 1.2
|
||||
First paragraph of versionchanged.
|
||||
|
||||
Second paragraph of versionchanged.
|
||||
|
||||
|
||||
Code blocks
|
||||
-----------
|
||||
|
||||
.. _my-code-block:
|
||||
|
||||
.. code-block:: ruby
|
||||
:linenos:
|
||||
:caption: my ruby code
|
||||
:name: my-code-block-name
|
||||
|
||||
def ruby?
|
||||
false
|
||||
end
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
import sys
|
||||
|
||||
sys.stdout.write('hello world!\n')
|
||||
|
||||
|
||||
Misc stuff
|
||||
----------
|
||||
|
||||
Stuff [#]_
|
||||
|
||||
Reference lookup: [Ref1]_ (defined in another file).
|
||||
Reference lookup underscore: [Ref_1]_
|
||||
|
||||
.. seealso:: something, something else, something more
|
||||
|
||||
`Google <http://www.google.com>`_
|
||||
For everything.
|
||||
|
||||
.. hlist::
|
||||
:columns: 4
|
||||
|
||||
* This
|
||||
* is
|
||||
* a horizontal
|
||||
* list
|
||||
* with several
|
||||
* items
|
||||
|
||||
.. rubric:: Side note
|
||||
|
||||
This is a side note.
|
||||
|
||||
This tests :CLASS:`role names in uppercase`.
|
||||
|
||||
.. centered:: LICENSE AGREEMENT
|
||||
|
||||
.. acks::
|
||||
|
||||
* Terry Pratchett
|
||||
* J. R. R. Tolkien
|
||||
* Monty Python
|
||||
|
||||
.. glossary::
|
||||
:sorted:
|
||||
|
||||
boson
|
||||
Particle with integer spin.
|
||||
|
||||
*fermion*
|
||||
Particle with half-integer spin.
|
||||
|
||||
tauon
|
||||
myon
|
||||
electron
|
||||
Examples for fermions.
|
||||
|
||||
über
|
||||
Gewisse
|
||||
|
||||
änhlich
|
||||
Dinge
|
||||
|
||||
.. productionlist::
|
||||
try_stmt: `try1_stmt` | `try2_stmt`
|
||||
try1_stmt: "try" ":" `suite`
|
||||
: ("except" [`expression` ["," `target`]] ":" `suite`)+
|
||||
: ["else" ":" `suite`]
|
||||
: ["finally" ":" `suite`]
|
||||
try2_stmt: "try" ":" `suite`
|
||||
: "finally" ":" `suite`
|
||||
|
||||
|
||||
Index markup
|
||||
------------
|
||||
|
||||
.. index::
|
||||
single: entry
|
||||
pair: entry; pair
|
||||
double: entry; double
|
||||
triple: index; entry; triple
|
||||
keyword: with
|
||||
see: from; to
|
||||
seealso: fromalso; toalso
|
||||
|
||||
Invalid index markup...
|
||||
|
||||
.. index::
|
||||
single:
|
||||
pair:
|
||||
keyword:
|
||||
|
||||
.. index::
|
||||
!Main, !Other
|
||||
!single: entry; pair
|
||||
|
||||
:index:`!Main`
|
||||
|
||||
.. _ölabel:
|
||||
|
||||
Ö... Some strange characters
|
||||
----------------------------
|
||||
|
||||
Testing öäü...
|
||||
|
||||
|
||||
Only directive
|
||||
--------------
|
||||
|
||||
.. only:: html
|
||||
|
||||
In HTML.
|
||||
|
||||
.. only:: latex
|
||||
|
||||
In LaTeX.
|
||||
|
||||
.. only:: html or latex
|
||||
|
||||
In both.
|
||||
|
||||
.. only:: confpytag and (testtag or nonexisting_tag)
|
||||
|
||||
Always present, because set through conf.py/command line.
|
||||
|
||||
|
||||
Any role
|
||||
--------
|
||||
|
||||
.. default-role:: any
|
||||
|
||||
Test referencing to `headings <with>` and `objects <func_without_body>`.
|
||||
Also `modules <mod>` and `classes <Time>`.
|
||||
|
||||
More domains:
|
||||
|
||||
* `JS <bar.baz>`
|
||||
* `C <SphinxType>`
|
||||
* `myobj` (user markup)
|
||||
* `n::Array`
|
||||
* `perl -c`
|
||||
|
||||
.. default-role::
|
||||
|
||||
|
||||
.. rubric:: Footnotes
|
||||
|
||||
.. [#] Like footnotes.
|
||||
|
||||
7
tests/roots/test-warnings/autodoc_fodder.py
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
class MarkupError(object):
|
||||
"""
|
||||
.. note:: This is a docstring with a
|
||||
small markup error which should have
|
||||
correct location information.
|
||||
"""
|
||||
12
tests/roots/test-warnings/conf.py
Normal file
@@ -0,0 +1,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import sys
|
||||
sys.path.append(os.path.abspath('.'))
|
||||
|
||||
master_doc = 'index'
|
||||
extensions = ['sphinx.ext.autodoc']
|
||||
|
||||
latex_documents = [
|
||||
(master_doc, 'test.tex', 'test-warnings', 'Sphinx', 'report')
|
||||
]
|
||||
48
tests/roots/test-warnings/index.rst
Normal file
@@ -0,0 +1,48 @@
|
||||
test-warnings
|
||||
=============
|
||||
|
||||
.. automodule:: autodoc_fodder
|
||||
:noindex:
|
||||
|
||||
.. autoclass:: MarkupError
|
||||
|
||||
.. a non-existing image with direct filename
|
||||
.. image:: foo.png
|
||||
|
||||
.. a non-existing image with .*
|
||||
.. image:: foo.*
|
||||
|
||||
.. an SVG image (for HTML at least)
|
||||
.. image:: svgimg.*
|
||||
|
||||
.. a non-local image URI
|
||||
.. image:: http://www.python.org/logo.png
|
||||
|
||||
.. should give a warning
|
||||
.. literalinclude:: wrongenc.inc
|
||||
:language: none
|
||||
|
||||
.. a non-existing download
|
||||
|
||||
Don't download :download:`this <nonexisting.png>`.
|
||||
|
||||
.. Invalid index markup
|
||||
.. index::
|
||||
single:
|
||||
pair:
|
||||
keyword:
|
||||
|
||||
.. Invalid code-block
|
||||
.. code-block:: c
|
||||
|
||||
import sys
|
||||
|
||||
sys.stdout.write('hello world!\n')
|
||||
|
||||
.. unknown option
|
||||
|
||||
This used to crash: :option:`&option`
|
||||
|
||||
.. missing citation
|
||||
|
||||
[missing]_ citation
|
||||
BIN
tests/roots/test-warnings/svgimg.pdf
Normal file
158
tests/roots/test-warnings/svgimg.svg
Normal file
@@ -0,0 +1,158 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://web.resource.org/cc/"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
height="60"
|
||||
width="60"
|
||||
_SVGFile__filename="oldscale/apps/warning.svg"
|
||||
version="1.0"
|
||||
y="0"
|
||||
x="0"
|
||||
id="svg1"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.41"
|
||||
sodipodi:docname="exclamation.svg"
|
||||
sodipodi:docbase="/home/danny/work/icons/primary/scalable/actions">
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0000000"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="7.5136000"
|
||||
inkscape:cx="42.825186"
|
||||
inkscape:cy="24.316071"
|
||||
inkscape:window-width="1020"
|
||||
inkscape:window-height="691"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:current-layer="svg1" />
|
||||
<defs
|
||||
id="defs3">
|
||||
<linearGradient
|
||||
id="linearGradient1160">
|
||||
<stop
|
||||
style="stop-color: #000000;stop-opacity: 1.0;"
|
||||
id="stop1161"
|
||||
offset="0" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
id="stop1162"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient1160"
|
||||
id="linearGradient1163" />
|
||||
</defs>
|
||||
<metadata
|
||||
id="metadata12">
|
||||
<RDF
|
||||
id="RDF13">
|
||||
<Work
|
||||
about=""
|
||||
id="Work14">
|
||||
<title
|
||||
id="title15">Part of the Flat Icon Collection (Thu Aug 26 14:31:40 2004)</title>
|
||||
<description
|
||||
id="description17" />
|
||||
<subject
|
||||
id="subject18">
|
||||
<Bag
|
||||
id="Bag19">
|
||||
<li
|
||||
id="li20" />
|
||||
</Bag>
|
||||
</subject>
|
||||
<publisher
|
||||
id="publisher21">
|
||||
<Agent
|
||||
about=""
|
||||
id="Agent22">
|
||||
<title
|
||||
id="title23" />
|
||||
</Agent>
|
||||
</publisher>
|
||||
<creator
|
||||
id="creator24">
|
||||
<Agent
|
||||
about=""
|
||||
id="Agent25">
|
||||
<title
|
||||
id="title26">Danny Allen</title>
|
||||
</Agent>
|
||||
</creator>
|
||||
<rights
|
||||
id="rights28">
|
||||
<Agent
|
||||
about=""
|
||||
id="Agent29">
|
||||
<title
|
||||
id="title30">Danny Allen</title>
|
||||
</Agent>
|
||||
</rights>
|
||||
<date
|
||||
id="date32" />
|
||||
<format
|
||||
id="format33">image/svg+xml</format>
|
||||
<type
|
||||
id="type35"
|
||||
resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<license
|
||||
id="license36"
|
||||
resource="http://creativecommons.org/licenses/LGPL/2.1/">
|
||||
<date
|
||||
id="date37" />
|
||||
</license>
|
||||
<language
|
||||
id="language38">en</language>
|
||||
</Work>
|
||||
</RDF>
|
||||
<rdf:RDF
|
||||
id="RDF40">
|
||||
<cc:Work
|
||||
rdf:about=""
|
||||
id="Work41">
|
||||
<dc:format
|
||||
id="format42">image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
id="type44"
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="g2099">
|
||||
<path
|
||||
style="color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:8.1250000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none"
|
||||
d="M 55.311891,51.920745 L 4.6880989,51.920744 L 29.999995,8.0792542 L 55.311891,51.920745 z "
|
||||
id="path1724" />
|
||||
<path
|
||||
style="color:#000000;fill:#ffe940;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:3.1250010;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none"
|
||||
d="M 55.311891,51.920745 L 4.6880989,51.920744 L 29.999995,8.0792542 L 55.311891,51.920745 z "
|
||||
id="path1722" />
|
||||
<path
|
||||
style="font-size:12.000000;font-weight:900;fill:none;fill-opacity:1.0000000;stroke:#ffffff;stroke-width:8.1250000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
|
||||
d="M 34.944960,10.779626 L 34.944960,33.186510 C 34.944960,34.752415 34.501979,36.081368 33.616007,37.173380 C 32.750636,38.265402 31.545298,38.811408 29.999995,38.811408 C 28.475302,38.811408 27.269965,38.265402 26.383993,37.173380 C 25.498020,36.060767 25.055030,34.731804 25.055030,33.186510 L 25.055030,10.779626 C 25.055030,9.1931155 25.498020,7.8641562 26.383993,6.7927462 C 27.269965,5.7007332 28.475302,5.1547262 29.999995,5.1547262 C 31.009593,5.1547262 31.885265,5.4019740 32.627010,5.8964706 C 33.389356,6.3909681 33.966274,7.0709005 34.357752,7.9362696 C 34.749221,8.7810349 34.944960,9.7288200 34.944960,10.779626 z "
|
||||
id="path1099" />
|
||||
<path
|
||||
style="font-size:12.000000;font-weight:900;fill:#e71c02;fill-opacity:1.0000000;stroke:none;stroke-width:3.1249981;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1.0000000"
|
||||
d="M 29.999995,3.5986440 C 28.102272,3.5986440 26.318514,4.3848272 25.156245,5.8173940 C 24.028906,7.1806889 23.499995,8.9087770 23.499995,10.786144 L 23.499995,33.192394 C 23.499995,35.036302 24.050685,36.772771 25.156245,38.161144 C 26.318514,39.593721 28.102273,40.379893 29.999995,40.379894 C 31.913354,40.379894 33.697195,39.576736 34.843745,38.129894 C 35.959941,36.754118 36.499995,35.052976 36.499995,33.192394 L 36.499995,10.786144 C 36.499995,9.5413010 36.276626,8.3551469 35.781245,7.2861440 C 35.278844,6.1755772 34.477762,5.2531440 33.468745,4.5986440 C 32.454761,3.9226545 31.264694,3.5986439 29.999995,3.5986440 z "
|
||||
id="path835"
|
||||
sodipodi:nodetypes="cccccccccccc" />
|
||||
<path
|
||||
style="color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:5.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none"
|
||||
d="M 36.506243,49.901522 C 36.506243,53.492972 33.591442,56.407773 29.999991,56.407773 C 26.408541,56.407773 23.493739,53.492972 23.493739,49.901522 C 23.493739,46.310071 26.408541,43.395270 29.999991,43.395270 C 33.591442,43.395270 36.506243,46.310071 36.506243,49.901522 z "
|
||||
id="path1727" />
|
||||
<path
|
||||
style="color:#000000;fill:#e71c02;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:3.1250000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none"
|
||||
d="M 36.506243,49.901522 C 36.506243,53.492972 33.591442,56.407773 29.999991,56.407773 C 26.408541,56.407773 23.493739,53.492972 23.493739,49.901522 C 23.493739,46.310071 26.408541,43.395270 29.999991,43.395270 C 33.591442,43.395270 36.506243,46.310071 36.506243,49.901522 z "
|
||||
id="path1725" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.2 KiB |
3
tests/roots/test-warnings/wrongenc.inc
Normal file
@@ -0,0 +1,3 @@
|
||||
This file is encoded in latin-1 but at first read as utf-8.
|
||||
|
||||
Max Strau<EFBFBD> a<EFBFBD> in M<EFBFBD>nchen eine Leberk<EFBFBD>ssemmel.
|
||||
@@ -17,7 +17,7 @@ from textwrap import dedent
|
||||
from sphinx.errors import SphinxError
|
||||
import sphinx.builders.linkcheck
|
||||
|
||||
from util import with_app, rootdir, tempdir, SkipTest, TestApp
|
||||
from util import with_app, with_tempdir, rootdir, tempdir, SkipTest, TestApp
|
||||
|
||||
try:
|
||||
from docutils.writers.manpage import Writer as ManWriter
|
||||
@@ -76,16 +76,19 @@ def test_build_all():
|
||||
yield verify_build, buildername, srcdir
|
||||
|
||||
|
||||
@with_app(buildername='text')
|
||||
def test_master_doc_not_found(app, status, warning):
|
||||
(app.srcdir / 'contents.txt').move(app.srcdir / 'contents.txt.bak')
|
||||
@with_tempdir
|
||||
def test_master_doc_not_found(tmpdir):
|
||||
(tmpdir / 'conf.py').write_text('master_doc = "index"')
|
||||
assert tmpdir.listdir() == ['conf.py']
|
||||
|
||||
try:
|
||||
app = TestApp(buildername='dummy', srcdir=tmpdir)
|
||||
app.builder.build_all()
|
||||
assert False # SphinxError not raised
|
||||
except Exception as exc:
|
||||
assert isinstance(exc, SphinxError)
|
||||
finally:
|
||||
(app.srcdir / 'contents.txt.bak').move(app.srcdir / 'contents.txt')
|
||||
app.cleanup()
|
||||
|
||||
|
||||
@with_app(buildername='text', testroot='circular')
|
||||
|
||||
@@ -43,8 +43,12 @@ def check_localization(outdir):
|
||||
assert (lprojdir / 'localized.txt').isfile()
|
||||
|
||||
|
||||
@with_app(buildername='applehelp')
|
||||
@with_app(buildername='applehelp', testroot='basic', srcdir='applehelp_output',
|
||||
confoverrides={'applehelp_bundle_id': 'org.sphinx-doc.Sphinx.help',
|
||||
'applehelp_disable_external_tools': True})
|
||||
def test_applehelp_output(app, status, warning):
|
||||
(app.srcdir / 'en.lproj').makedirs()
|
||||
(app.srcdir / 'en.lproj' / 'localized.txt').write_text('')
|
||||
app.builder.build_all()
|
||||
|
||||
# Have to use bundle_path, not outdir, because we alter the latter
|
||||
|
||||
@@ -24,26 +24,26 @@ TREE_BUILDER = getTreeBuilder('etree', implementation=ElementTree)
|
||||
HTML_PARSER = HTMLParser(TREE_BUILDER, namespaceHTMLElements=False)
|
||||
|
||||
ENV_WARNINGS = """\
|
||||
(%(root)s/autodoc_fodder.py:docstring of autodoc_fodder\\.MarkupError:2: \
|
||||
WARNING: Explicit markup ends without a blank line; unexpected \
|
||||
unindent\\.\\n?
|
||||
)?%(root)s/images.txt:\\d+: WARNING: image file not readable: foo.png
|
||||
%(root)s/images.txt:\\d+3: WARNING: nonlocal image URI found: \
|
||||
http://www.python.org/logo.png
|
||||
%(root)s/includes.txt:\\d+: WARNING: Encoding 'utf-8-sig' used for \
|
||||
reading included file u'.*?wrongenc.inc' seems to be wrong, try giving an \
|
||||
:encoding: option\\n?
|
||||
%(root)s/includes.txt:\\d+: WARNING: download file not readable: .*?nonexisting.png
|
||||
(%(root)s/markup.txt:\\d+: WARNING: invalid single index entry u'')?
|
||||
(%(root)s/undecodable.txt:\\d+: WARNING: undecodable source characters, replacing \
|
||||
(%(root)s/autodoc_fodder.py:docstring of autodoc_fodder.MarkupError:\\d+: \
|
||||
WARNING: duplicate object description of autodoc_fodder.MarkupError, other \
|
||||
instance in %(root)s/autodoc.rst, use :noindex: for one of them
|
||||
)?%(root)s/autodoc_fodder.py:docstring of autodoc_fodder.MarkupError:\\d+: \
|
||||
WARNING: Explicit markup ends without a blank line; unexpected unindent.
|
||||
%(root)s/index.rst:\\d+: WARNING: Encoding 'utf-8-sig' used for reading included \
|
||||
file u'%(root)s/wrongenc.inc' seems to be wrong, try giving an :encoding: option
|
||||
%(root)s/index.rst:\\d+: WARNING: image file not readable: foo.png
|
||||
%(root)s/index.rst:\\d+: WARNING: nonlocal image URI found: http://www.python.org/logo.png
|
||||
%(root)s/index.rst:\\d+: WARNING: download file not readable: %(root)s/nonexisting.png
|
||||
%(root)s/index.rst:\\d+: WARNING: invalid single index entry u''
|
||||
%(root)s/undecodable.rst:\\d+: WARNING: undecodable source characters, replacing \
|
||||
with "\\?": b?'here: >>>(\\\\|/)xbb<<<'
|
||||
)?"""
|
||||
"""
|
||||
|
||||
HTML_WARNINGS = ENV_WARNINGS + """\
|
||||
%(root)s/images.txt:\\d+: WARNING: no matching candidate for image URI u'foo.\\*'
|
||||
%(root)s/markup.txt:\\d+: WARNING: Could not lex literal_block as "c". Highlighting skipped.
|
||||
%(root)s/footnote.txt:\\d+: WARNING: citation not found: missing
|
||||
%(root)s/markup.txt:\\d+: WARNING: unknown option: &option
|
||||
%(root)s/index.rst:\\d+: WARNING: no matching candidate for image URI u'foo.\\*'
|
||||
%(root)s/index.rst:\\d+: WARNING: Could not lex literal_block as "c". Highlighting skipped.
|
||||
%(root)s/index.rst:\\d+: WARNING: unknown option: &option
|
||||
%(root)s/index.rst:\\d+: WARNING: citation not found: missing
|
||||
"""
|
||||
|
||||
if PY3:
|
||||
@@ -68,6 +68,7 @@ HTML_XPATH = {
|
||||
(".//img[@src='_images/img1.png']", ''),
|
||||
(".//img[@src='_images/simg.png']", ''),
|
||||
(".//img[@src='_images/svgimg.svg']", ''),
|
||||
(".//a[@href='_sources/images.txt']", ''),
|
||||
],
|
||||
'subdir/images.html': [
|
||||
(".//img[@src='../_images/img1.png']", ''),
|
||||
@@ -206,6 +207,7 @@ HTML_XPATH = {
|
||||
# docfields
|
||||
(".//a[@class='reference internal'][@href='#TimeInt']/em", 'TimeInt'),
|
||||
(".//a[@class='reference internal'][@href='#Time']", 'Time'),
|
||||
(".//a[@class='reference internal'][@href='#errmod.Error']/strong", 'Error'),
|
||||
# C references
|
||||
(".//span[@class='pre']", 'CFunction()'),
|
||||
(".//a[@href='#c.Sphinx_DoSomething']", ''),
|
||||
@@ -318,6 +320,7 @@ HTML_XPATH = {
|
||||
],
|
||||
'otherext.html': [
|
||||
(".//h1", "Generated section"),
|
||||
(".//a[@href='_sources/otherext.foo.txt']", ''),
|
||||
]
|
||||
}
|
||||
|
||||
@@ -379,10 +382,8 @@ def check_extra_entries(outdir):
|
||||
assert (outdir / 'robots.txt').isfile()
|
||||
|
||||
|
||||
@gen_with_app(buildername='html', freshenv=True, # use freshenv to check warnings
|
||||
confoverrides={'html_context.hckey_co': 'hcval_co'},
|
||||
tags=['testtag'])
|
||||
def test_html_output(app, status, warning):
|
||||
@with_app(buildername='html', testroot='warnings', freshenv=True)
|
||||
def test_html_warnings(app, status, warning):
|
||||
app.builder.build_all()
|
||||
html_warnings = strip_escseq(warning.getvalue().replace(os.sep, '/'))
|
||||
html_warnings_exp = HTML_WARNINGS % {
|
||||
@@ -392,6 +393,11 @@ def test_html_output(app, status, warning):
|
||||
'--- Expected (regex):\n' + html_warnings_exp + \
|
||||
'--- Got:\n' + html_warnings
|
||||
|
||||
|
||||
@gen_with_app(buildername='html', tags=['testtag'],
|
||||
confoverrides={'html_context.hckey_co': 'hcval_co'})
|
||||
def test_html_output(app, status, warning):
|
||||
app.builder.build_all()
|
||||
for fname, paths in iteritems(HTML_XPATH):
|
||||
with (app.outdir / fname).open('rb') as fp:
|
||||
etree = HTML_PARSER.parse(fp)
|
||||
@@ -959,25 +965,23 @@ def test_enumerable_node(app, status, warning):
|
||||
yield check_xpath, etree, fname, xpath, check, be_found
|
||||
|
||||
|
||||
@with_app(buildername='html')
|
||||
def test_jsmath(app, status, warning):
|
||||
app.builder.build_all()
|
||||
content = (app.outdir / 'math.html').text()
|
||||
|
||||
assert '<div class="math">\na^2 + b^2 = c^2</div>' in content
|
||||
assert '<div class="math">\n\\begin{split}a + 1 < b\\end{split}</div>' in content
|
||||
assert ('<span class="eqno">(1)</span><div class="math" id="equation-foo">\n'
|
||||
'e^{i\\pi} = 1</div>' in content)
|
||||
assert ('<span class="eqno">(2)</span><div class="math">\n'
|
||||
'e^{ix} = \\cos x + i\\sin x</div>' in content)
|
||||
assert '<div class="math">\nn \\in \\mathbb N</div>' in content
|
||||
assert '<div class="math">\na + 1 < b</div>' in content
|
||||
|
||||
|
||||
@with_app(buildername='html', testroot='html_extra_path')
|
||||
def test_html_extra_path(app, status, warning):
|
||||
@with_app(buildername='html', testroot='html_assets')
|
||||
def test_html_assets(app, status, warning):
|
||||
app.builder.build_all()
|
||||
|
||||
# html_static_path
|
||||
assert not (app.outdir / '_static' / '.htaccess').exists()
|
||||
assert not (app.outdir / '_static' / '.htpasswd').exists()
|
||||
assert (app.outdir / '_static' / 'API.html').exists()
|
||||
assert (app.outdir / '_static' / 'API.html').text() == 'Sphinx-1.4.4'
|
||||
assert (app.outdir / '_static' / 'css/style.css').exists()
|
||||
assert (app.outdir / '_static' / 'rimg.png').exists()
|
||||
assert not (app.outdir / '_static' / '_build/index.html').exists()
|
||||
assert (app.outdir / '_static' / 'background.png').exists()
|
||||
assert not (app.outdir / '_static' / 'subdir' / '.htaccess').exists()
|
||||
assert not (app.outdir / '_static' / 'subdir' / '.htpasswd').exists()
|
||||
|
||||
# html_extra_path
|
||||
assert (app.outdir / '.htaccess').exists()
|
||||
assert not (app.outdir / '.htpasswd').exists()
|
||||
assert (app.outdir / 'API.html_t').exists()
|
||||
@@ -985,3 +989,17 @@ def test_html_extra_path(app, status, warning):
|
||||
assert (app.outdir / 'rimg.png').exists()
|
||||
assert not (app.outdir / '_build/index.html').exists()
|
||||
assert (app.outdir / 'background.png').exists()
|
||||
assert (app.outdir / 'subdir' / '.htaccess').exists()
|
||||
assert not (app.outdir / 'subdir' / '.htpasswd').exists()
|
||||
|
||||
|
||||
@with_app(buildername='html', confoverrides={'html_sourcelink_suffix': ''})
|
||||
def test_html_sourcelink_suffix(app, status, warning):
|
||||
app.builder.build_all()
|
||||
content_otherext = (app.outdir / 'otherext.html').text()
|
||||
content_images = (app.outdir / 'images.html').text()
|
||||
|
||||
assert '<a href="_sources/otherext.foo"' in content_otherext
|
||||
assert '<a href="_sources/images.txt"' in content_images
|
||||
assert (app.outdir / '_sources' / 'otherext.foo').exists()
|
||||
assert (app.outdir / '_sources' / 'images.txt').exists()
|
||||
|
||||
@@ -12,99 +12,87 @@ from __future__ import print_function
|
||||
|
||||
import os
|
||||
import re
|
||||
from itertools import product
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
from six import PY3
|
||||
|
||||
from sphinx.errors import SphinxError
|
||||
from sphinx.util.osutil import cd, ensuredir
|
||||
from sphinx.writers.latex import LaTeXTranslator
|
||||
|
||||
from util import SkipTest, remove_unicode_literals, with_app, strip_escseq
|
||||
from test_build_html import ENV_WARNINGS
|
||||
|
||||
|
||||
LATEX_ENGINES = ['pdflatex', 'lualatex', 'xelatex']
|
||||
DOCCLASSES = ['howto', 'manual']
|
||||
STYLEFILES = ['article.sty', 'fancyhdr.sty', 'fancybox.sty', 'titlesec.sty', 'amsmath.sty',
|
||||
'framed.sty', 'color.sty', 'fancyvrb.sty', 'threeparttable.sty']
|
||||
|
||||
LATEX_WARNINGS = ENV_WARNINGS + """\
|
||||
%(root)s/markup.txt:\\d+: WARNING: unknown option: &option
|
||||
%(root)s/footnote.txt:\\d+: WARNING: citation not found: missing
|
||||
%(root)s/images.txt:\\d+: WARNING: no matching candidate for image URI u'foo.\\*'
|
||||
%(root)s/markup.txt:\\d+: WARNING: Could not lex literal_block as "c". Highlighting skipped.
|
||||
%(root)s/index.rst:\\d+: WARNING: unknown option: &option
|
||||
%(root)s/index.rst:\\d+: WARNING: citation not found: missing
|
||||
%(root)s/index.rst:\\d+: WARNING: no matching candidate for image URI u'foo.\\*'
|
||||
%(root)s/index.rst:\\d+: WARNING: Could not lex literal_block as "c". Highlighting skipped.
|
||||
"""
|
||||
|
||||
if PY3:
|
||||
LATEX_WARNINGS = remove_unicode_literals(LATEX_WARNINGS)
|
||||
|
||||
|
||||
def run_latex(outdir):
|
||||
"""Run pdflatex, xelatex, and lualatex in the outdir"""
|
||||
cwd = os.getcwd()
|
||||
os.chdir(outdir)
|
||||
# only run latex if all needed packages are there
|
||||
def kpsetest(*filenames):
|
||||
try:
|
||||
latexes = ('pdflatex', 'xelatex', 'lualatex')
|
||||
available_latexes = len(latexes)
|
||||
for latex in latexes:
|
||||
try:
|
||||
os.mkdir(latex)
|
||||
p = Popen([latex, '--interaction=nonstopmode',
|
||||
'-output-directory=%s' % latex, 'SphinxTests.tex'],
|
||||
stdout=PIPE, stderr=PIPE)
|
||||
except OSError: # most likely the latex executable was not found
|
||||
available_latexes -= 1
|
||||
else:
|
||||
stdout, stderr = p.communicate()
|
||||
if p.returncode != 0:
|
||||
print(stdout)
|
||||
print(stderr)
|
||||
assert False, '%s exited with return code %s' % (
|
||||
latex, p.returncode)
|
||||
finally:
|
||||
os.chdir(cwd)
|
||||
|
||||
if available_latexes == 0: # no latex is available, skip the test
|
||||
raise SkipTest
|
||||
p = Popen(['kpsewhich'] + list(filenames), 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
|
||||
|
||||
|
||||
@with_app(buildername='latex', freshenv=True) # use freshenv to check warnings
|
||||
def test_latex(app, status, warning):
|
||||
def test_latex():
|
||||
if kpsetest(*STYLEFILES) is False:
|
||||
raise SkipTest('not running latex, the required styles doesn\'t seem to be installed')
|
||||
|
||||
for engine, docclass in product(LATEX_ENGINES, DOCCLASSES):
|
||||
yield build_latex_doc, engine, docclass
|
||||
|
||||
|
||||
@with_app(buildername='latex')
|
||||
def build_latex_doc(app, status, warning, engine, docclass):
|
||||
app.config.latex_engine = engine
|
||||
app.config.latex_documents[0] = app.config.latex_documents[0][:4] + (docclass,)
|
||||
|
||||
LaTeXTranslator.ignore_missing_images = True
|
||||
app.builder.build_all()
|
||||
latex_warnings = strip_escseq(warning.getvalue().replace(os.sep, '/'))
|
||||
latex_warnings_exp = LATEX_WARNINGS % {
|
||||
'root': re.escape(app.srcdir.replace(os.sep, '/'))}
|
||||
assert re.match(latex_warnings_exp + '$', latex_warnings), \
|
||||
'Warnings don\'t match:\n' + \
|
||||
'--- Expected (regex):\n' + latex_warnings_exp + \
|
||||
'--- Got:\n' + latex_warnings
|
||||
|
||||
# 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:
|
||||
raise SkipTest('not running latex, it doesn\'t seem to be installed')
|
||||
for filename in ['fancyhdr.sty', 'fancybox.sty', 'titlesec.sty',
|
||||
'amsmath.sty', 'framed.sty', 'color.sty', 'fancyvrb.sty',
|
||||
'threeparttable.sty']:
|
||||
if not kpsetest(filename):
|
||||
raise SkipTest('not running latex, the %s package doesn\'t '
|
||||
'seem to be installed' % filename)
|
||||
|
||||
# now, try to run latex over it
|
||||
run_latex(app.outdir)
|
||||
with cd(app.outdir):
|
||||
try:
|
||||
ensuredir(engine)
|
||||
p = Popen([engine, '--interaction=nonstopmode',
|
||||
'-output-directory=%s' % engine, 'SphinxTests.tex'],
|
||||
stdout=PIPE, stderr=PIPE)
|
||||
except OSError: # most likely the latex executable was not found
|
||||
raise SkipTest
|
||||
else:
|
||||
stdout, stderr = p.communicate()
|
||||
if p.returncode != 0:
|
||||
print(stdout)
|
||||
print(stderr)
|
||||
assert False, '%s exited with return code %s' % (
|
||||
engine, p.returncode)
|
||||
|
||||
|
||||
@with_app(buildername='latex')
|
||||
@@ -133,53 +121,17 @@ def test_writer(app, status, warning):
|
||||
'\\end{wrapfigure}' in result)
|
||||
|
||||
|
||||
@with_app(buildername='latex', freshenv=True, # use freshenv to check warnings
|
||||
confoverrides={'latex_documents': [
|
||||
('contents', 'SphinxTests.tex', 'Sphinx Tests Documentation',
|
||||
'Georg Brandl \\and someone else', 'howto'),
|
||||
]},
|
||||
srcdir='latex_howto')
|
||||
def test_latex_howto(app, status, warning):
|
||||
LaTeXTranslator.ignore_missing_images = True
|
||||
@with_app(buildername='latex', testroot='warnings', freshenv=True)
|
||||
def test_latex_warnings(app, status, warning):
|
||||
app.builder.build_all()
|
||||
latex_warnings = strip_escseq(warning.getvalue().replace(os.sep, '/'))
|
||||
latex_warnings_exp = LATEX_WARNINGS % {
|
||||
|
||||
warnings = strip_escseq(warning.getvalue().replace(os.sep, '/'))
|
||||
warnings_exp = LATEX_WARNINGS % {
|
||||
'root': re.escape(app.srcdir.replace(os.sep, '/'))}
|
||||
assert re.match(latex_warnings_exp + '$', latex_warnings), \
|
||||
assert re.match(warnings_exp + '$', warnings), \
|
||||
'Warnings don\'t match:\n' + \
|
||||
'--- Expected (regex):\n' + latex_warnings_exp + \
|
||||
'--- Got:\n' + latex_warnings
|
||||
|
||||
# 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:
|
||||
raise SkipTest('not running latex, it doesn\'t seem to be installed')
|
||||
for filename in ['fancyhdr.sty', 'fancybox.sty', 'titlesec.sty',
|
||||
'amsmath.sty', 'framed.sty', 'color.sty', 'fancyvrb.sty',
|
||||
'threeparttable.sty']:
|
||||
if not kpsetest(filename):
|
||||
raise SkipTest('not running latex, the %s package doesn\'t '
|
||||
'seem to be installed' % filename)
|
||||
|
||||
# now, try to run latex over it
|
||||
run_latex(app.outdir)
|
||||
'--- Expected (regex):\n' + warnings_exp + \
|
||||
'--- Got:\n' + warnings
|
||||
|
||||
|
||||
@with_app(buildername='latex', testroot='numfig',
|
||||
@@ -577,11 +529,12 @@ def test_image_in_section(app, status, warning):
|
||||
print(result)
|
||||
print(status.getvalue())
|
||||
print(warning.getvalue())
|
||||
assert ('\\chapter[Test section]'
|
||||
'{\\sphinxincludegraphics[width=15pt,height=15pt]{{pic}.png} Test section}'
|
||||
assert ('\\chapter[Test section]{\\lowercase{\\sphinxincludegraphics'
|
||||
'[width=15bp,height=15bp]}{{pic}.png} Test section}'
|
||||
in result)
|
||||
assert ('\\chapter[Other {[}blah{]} section]{Other {[}blah{]} '
|
||||
'\\sphinxincludegraphics[width=15pt,height=15pt]{{pic}.png} section}' in result)
|
||||
'\\lowercase{\\sphinxincludegraphics[width=15bp,height=15bp]}'
|
||||
'{{pic}.png} section}' in result)
|
||||
assert ('\\chapter{Another section}' in result)
|
||||
|
||||
|
||||
|
||||
@@ -23,27 +23,32 @@ from test_build_html import ENV_WARNINGS
|
||||
|
||||
|
||||
TEXINFO_WARNINGS = ENV_WARNINGS + """\
|
||||
%(root)s/markup.txt:164: WARNING: unknown option: &option
|
||||
%(root)s/footnote.txt:60: WARNING: citation not found: missing
|
||||
%(root)s/images.txt:20: WARNING: no matching candidate for image URI u'foo.\\*'
|
||||
%(root)s/images.txt:29: WARNING: no matching candidate for image URI u'svgimg.\\*'
|
||||
%(root)s/index.rst:\\d+: WARNING: unknown option: &option
|
||||
%(root)s/index.rst:\\d+: WARNING: citation not found: missing
|
||||
%(root)s/index.rst:\\d+: WARNING: no matching candidate for image URI u'foo.\\*'
|
||||
%(root)s/index.rst:\\d+: WARNING: no matching candidate for image URI u'svgimg.\\*'
|
||||
"""
|
||||
|
||||
if PY3:
|
||||
TEXINFO_WARNINGS = remove_unicode_literals(TEXINFO_WARNINGS)
|
||||
|
||||
|
||||
@with_app('texinfo', freshenv=True) # use freshenv to check warnings
|
||||
@with_app(buildername='texinfo', testroot='warnings', freshenv=True)
|
||||
def test_texinfo_warnings(app, status, warning):
|
||||
app.builder.build_all()
|
||||
warnings = strip_escseq(warning.getvalue().replace(os.sep, '/'))
|
||||
warnings_exp = TEXINFO_WARNINGS % {
|
||||
'root': re.escape(app.srcdir.replace(os.sep, '/'))}
|
||||
assert re.match(warnings_exp + '$', warnings), \
|
||||
'Warnings don\'t match:\n' + \
|
||||
'--- Expected (regex):\n' + warnings_exp + \
|
||||
'--- Got:\n' + warnings
|
||||
|
||||
|
||||
@with_app(buildername='texinfo')
|
||||
def test_texinfo(app, status, warning):
|
||||
TexinfoTranslator.ignore_missing_images = True
|
||||
app.builder.build_all()
|
||||
texinfo_warnings = strip_escseq(warning.getvalue().replace(os.sep, '/'))
|
||||
texinfo_warnings_exp = TEXINFO_WARNINGS % {
|
||||
'root': re.escape(app.srcdir.replace(os.sep, '/'))}
|
||||
assert re.match(texinfo_warnings_exp + '$', texinfo_warnings), \
|
||||
'Warnings don\'t match:\n' + \
|
||||
'--- Expected (regex):\n' + texinfo_warnings_exp + \
|
||||
'--- Got:\n' + texinfo_warnings
|
||||
# now, try to run makeinfo over it
|
||||
cwd = os.getcwd()
|
||||
os.chdir(app.outdir)
|
||||
|
||||
@@ -206,3 +206,15 @@ def test_gen_check_types(app, status, warning):
|
||||
'override on "%s" should%s raise a type warning' %
|
||||
(key, '' if should else ' NOT')
|
||||
)
|
||||
|
||||
|
||||
@with_app(testroot='config')
|
||||
def test_check_enum(app, status, warning):
|
||||
assert "The config value `value17` has to be a one of ('default', 'one', 'two'), " \
|
||||
not in warning.getvalue()
|
||||
|
||||
|
||||
@with_app(testroot='config', confoverrides={'value17': 'invalid'})
|
||||
def test_check_enum_failed(app, status, warning):
|
||||
assert "The config value `value17` has to be a one of ('default', 'one', 'two'), " \
|
||||
"but `invalid` is given." in warning.getvalue()
|
||||
|
||||
@@ -228,7 +228,8 @@ def test_literalinclude_file_whole_of_emptyline(app, status, warning):
|
||||
app.builder.build_all()
|
||||
latex = (app.outdir / 'Python.tex').text(encoding='utf-8').replace('\r\n', '\n')
|
||||
includes = (
|
||||
'\\begin{sphinxVerbatim}[commandchars=\\\\\\{\\},numbers=left,firstnumber=1,stepnumber=1]\n'
|
||||
'\\begin{sphinxVerbatim}'
|
||||
'[commandchars=\\\\\\{\\},numbers=left,firstnumber=1,stepnumber=1]\n'
|
||||
'\n'
|
||||
'\n'
|
||||
'\n'
|
||||
|
||||
@@ -58,10 +58,6 @@ def test_images():
|
||||
htmlbuilder = StandaloneHTMLBuilder(app)
|
||||
htmlbuilder.imgpath = 'dummy'
|
||||
htmlbuilder.post_process_images(tree)
|
||||
image_uri_message = "no matching candidate for image URI u'foo.*'"
|
||||
if PY3:
|
||||
image_uri_message = remove_unicode_literals(image_uri_message)
|
||||
assert image_uri_message in app._warning.content[-1]
|
||||
assert set(htmlbuilder.images.keys()) == \
|
||||
set(['subdir/img.png', 'img.png', 'subdir/simg.png', 'svgimg.svg',
|
||||
'img.foo.png'])
|
||||
@@ -71,7 +67,6 @@ def test_images():
|
||||
app._warning.reset()
|
||||
latexbuilder = LaTeXBuilder(app)
|
||||
latexbuilder.post_process_images(tree)
|
||||
assert image_uri_message in app._warning.content[-1]
|
||||
assert set(latexbuilder.images.keys()) == \
|
||||
set(['subdir/img.png', 'subdir/simg.png', 'img.png', 'img.pdf',
|
||||
'svgimg.pdf', 'img.foo.png'])
|
||||
|
||||
@@ -54,7 +54,7 @@ def test_mangle_signature():
|
||||
assert res == outp, (u"'%s' -> '%s' != '%s'" % (inp, res, outp))
|
||||
|
||||
|
||||
@with_app(buildername='html', **default_kw)
|
||||
@with_app(buildername='dummy', **default_kw)
|
||||
def test_get_items_summary(app, status, warning):
|
||||
# monkey-patch Autosummary.get_items so we can easily get access to it's
|
||||
# results..
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
from util import with_app
|
||||
|
||||
|
||||
@with_app(testroot='ext-ifconfig')
|
||||
@with_app(buildername='text', testroot='ext-ifconfig')
|
||||
def test_ifconfig(app, status, warning):
|
||||
app.builder.build_all()
|
||||
result = (app.outdir / 'index.txt').text()
|
||||
assert 'spam' in result
|
||||
assert 'ham' not in result
|
||||
|
||||
@@ -43,6 +43,7 @@ module2 py:module 0 foo.html#module-$ -
|
||||
module1.func py:function 1 sub/foo.html#$ -
|
||||
CFunc c:function 2 cfunc.html#CFunc -
|
||||
a term std:term -1 glossary.html#term-a-term -
|
||||
a term including:colon std:term -1 glossary.html#term-a-term-including-colon -
|
||||
'''.encode('utf-8'))
|
||||
|
||||
|
||||
@@ -78,6 +79,8 @@ def test_read_inventory_v2():
|
||||
assert invdata1['c:function']['CFunc'][2] == '/util/cfunc.html#CFunc'
|
||||
assert invdata1['std:term']['a term'][2] == \
|
||||
'/util/glossary.html#term-a-term'
|
||||
assert invdata1['std:term']['a term including:colon'][2] == \
|
||||
'/util/glossary.html#term-a-term-including-colon'
|
||||
|
||||
|
||||
@with_app()
|
||||
|
||||
@@ -14,7 +14,24 @@ import re
|
||||
from util import with_app, SkipTest
|
||||
|
||||
|
||||
@with_app('html', testroot='ext-math',
|
||||
@with_app(buildername='html', testroot='ext-math',
|
||||
confoverrides = {'extensions': ['sphinx.ext.jsmath'], 'jsmath_path': 'dummy.js'})
|
||||
def test_jsmath(app, status, warning):
|
||||
app.builder.build_all()
|
||||
content = (app.outdir / 'math.html').text()
|
||||
|
||||
assert '<div class="math">\na^2 + b^2 = c^2</div>' in content
|
||||
assert '<div class="math">\n\\begin{split}a + 1 < b\\end{split}</div>' in content
|
||||
assert (u'<span class="eqno">(1)<a class="headerlink" href="#equation-foo" '
|
||||
u'title="Permalink to this equation">\xb6</a></span>'
|
||||
u'<div class="math" id="equation-foo">\ne^{i\\pi} = 1</div>' in content)
|
||||
assert ('<span class="eqno">(2)</span><div class="math">\n'
|
||||
'e^{ix} = \\cos x + i\\sin x</div>' in content)
|
||||
assert '<div class="math">\nn \\in \\mathbb N</div>' in content
|
||||
assert '<div class="math">\na + 1 < b</div>' in content
|
||||
|
||||
|
||||
@with_app('html', testroot='ext-math-simple',
|
||||
confoverrides = {'extensions': ['sphinx.ext.imgmath']})
|
||||
def test_imgmath_png(app, status, warning):
|
||||
app.builder.build_all()
|
||||
@@ -29,7 +46,7 @@ def test_imgmath_png(app, status, warning):
|
||||
assert re.search(html, content, re.S)
|
||||
|
||||
|
||||
@with_app('html', testroot='ext-math',
|
||||
@with_app('html', testroot='ext-math-simple',
|
||||
confoverrides={'extensions': ['sphinx.ext.imgmath'],
|
||||
'imgmath_image_format': 'svg'})
|
||||
def test_imgmath_svg(app, status, warning):
|
||||
|
||||
@@ -222,6 +222,24 @@ class GoogleDocstringTest(BaseDocstringTest):
|
||||
"""
|
||||
Single line summary
|
||||
|
||||
Args:
|
||||
arg1 (list(int)): Description
|
||||
arg2 (list[int]): Description
|
||||
arg3 (dict(str, int)): Description
|
||||
arg4 (dict[str, int]): Description
|
||||
""",
|
||||
"""
|
||||
Single line summary
|
||||
|
||||
:Parameters: * **arg1** (*list(int)*) -- Description
|
||||
* **arg2** (*list[int]*) -- Description
|
||||
* **arg3** (*dict(str, int)*) -- Description
|
||||
* **arg4** (*dict[str, int]*) -- Description
|
||||
"""
|
||||
), (
|
||||
"""
|
||||
Single line summary
|
||||
|
||||
Yield:
|
||||
str:Extended
|
||||
description of yielded value
|
||||
|
||||
85
tests/test_ext_todo.py
Normal file
@@ -0,0 +1,85 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
test_ext_todo
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Test sphinx.ext.todo extension.
|
||||
|
||||
:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
import re
|
||||
from util import with_app
|
||||
|
||||
|
||||
@with_app('html', testroot='ext-todo', freshenv=True,
|
||||
confoverrides={'todo_include_todos': True, 'todo_emit_warnings': True})
|
||||
def test_todo(app, status, warning):
|
||||
todos = []
|
||||
|
||||
def on_todo_defined(app, node):
|
||||
todos.append(node)
|
||||
|
||||
app.connect('todo-defined', on_todo_defined)
|
||||
app.builder.build_all()
|
||||
|
||||
# check todolist
|
||||
content = (app.outdir / 'index.html').text()
|
||||
html = ('<p class="first admonition-title">Todo</p>\n'
|
||||
'<p class="last">todo in foo</p>')
|
||||
assert re.search(html, content, re.S)
|
||||
|
||||
html = ('<p class="first admonition-title">Todo</p>\n'
|
||||
'<p class="last">todo in bar</p>')
|
||||
assert re.search(html, content, re.S)
|
||||
|
||||
# check todo
|
||||
content = (app.outdir / 'foo.html').text()
|
||||
html = ('<p class="first admonition-title">Todo</p>\n'
|
||||
'<p class="last">todo in foo</p>')
|
||||
assert re.search(html, content, re.S)
|
||||
|
||||
# check emitted warnings
|
||||
assert 'WARNING: TODO entry found: todo in foo' in warning.getvalue()
|
||||
assert 'WARNING: TODO entry found: todo in bar' in warning.getvalue()
|
||||
|
||||
# check handled event
|
||||
assert len(todos) == 2
|
||||
assert set(todo[1].astext() for todo in todos) == set(['todo in foo', 'todo in bar'])
|
||||
|
||||
|
||||
@with_app('html', testroot='ext-todo', freshenv=True,
|
||||
confoverrides={'todo_include_todos': False, 'todo_emit_warnings': True})
|
||||
def test_todo_not_included(app, status, warning):
|
||||
todos = []
|
||||
|
||||
def on_todo_defined(app, node):
|
||||
todos.append(node)
|
||||
|
||||
app.connect('todo-defined', on_todo_defined)
|
||||
app.builder.build_all()
|
||||
|
||||
# check todolist
|
||||
content = (app.outdir / 'index.html').text()
|
||||
html = ('<p class="first admonition-title">Todo</p>\n'
|
||||
'<p class="last">todo in foo</p>')
|
||||
assert not re.search(html, content, re.S)
|
||||
|
||||
html = ('<p class="first admonition-title">Todo</p>\n'
|
||||
'<p class="last">todo in bar</p>')
|
||||
assert not re.search(html, content, re.S)
|
||||
|
||||
# check todo
|
||||
content = (app.outdir / 'foo.html').text()
|
||||
html = ('<p class="first admonition-title">Todo</p>\n'
|
||||
'<p class="last">todo in foo</p>')
|
||||
assert not re.search(html, content, re.S)
|
||||
|
||||
# check emitted warnings
|
||||
assert 'WARNING: TODO entry found: todo in foo' in warning.getvalue()
|
||||
assert 'WARNING: TODO entry found: todo in bar' in warning.getvalue()
|
||||
|
||||
# check handled event
|
||||
assert len(todos) == 2
|
||||
assert set(todo[1].astext() for todo in todos) == set(['todo in foo', 'todo in bar'])
|
||||
@@ -1,17 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
test_i18n
|
||||
~~~~~~~~~
|
||||
|
||||
Test locale features.
|
||||
|
||||
:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
from util import with_app
|
||||
|
||||
|
||||
@with_app(confoverrides={'language': 'de'})
|
||||
def test_i18n(app, status, warning):
|
||||
app.builder.build_all()
|
||||
@@ -53,7 +53,7 @@ def test_wordcollector():
|
||||
parser.parse(FILE_CONTENTS, doc)
|
||||
|
||||
ix = IndexBuilder(None, 'en', {}, None)
|
||||
ix.feed('filename', 'title', doc)
|
||||
ix.feed('docname', 'filename', 'title', doc)
|
||||
assert 'boson' not in ix._mapping
|
||||
assert 'fermion' in ix._mapping
|
||||
|
||||
@@ -92,3 +92,16 @@ def test_meta_keys_are_handled_for_language_de(app, status, warning):
|
||||
assert is_registered_term(searchindex, 'onlygerman')
|
||||
assert not is_registered_term(searchindex, 'notgerman')
|
||||
assert is_registered_term(searchindex, 'onlytoogerman')
|
||||
|
||||
|
||||
@with_app(testroot='search')
|
||||
def test_stemmer_does_not_remove_short_words(app, status, warning):
|
||||
app.builder.build_all()
|
||||
searchindex = (app.outdir / 'searchindex.js').text()
|
||||
assert 'zfs' in searchindex
|
||||
|
||||
|
||||
@with_app(testroot='search')
|
||||
def test_stemmer(app, status, warning):
|
||||
searchindex = (app.outdir / 'searchindex.js').text()
|
||||
assert 'findthisstemmedkei' in searchindex
|
||||
|
||||
@@ -22,7 +22,7 @@ def teardown_module():
|
||||
|
||||
|
||||
def search_adapter_helper(adapter):
|
||||
settings = {'srcdir': rootdir / 'root',
|
||||
settings = {'srcdir': rootdir / 'roots' / 'test-searchadapters',
|
||||
'builddir': tempdir / 'websupport',
|
||||
'status': StringIO(),
|
||||
'warning': StringIO(),
|
||||
@@ -41,7 +41,7 @@ def search_adapter_helper(adapter):
|
||||
|
||||
# Make sure documents are properly updated by the search adapter.
|
||||
s.init_indexing(changed=['markup'])
|
||||
s.add_document(u'markup', u'title', u'SomeLongRandomWord')
|
||||
s.add_document(u'markup', u'filename', u'title', u'SomeLongRandomWord')
|
||||
s.finish_indexing()
|
||||
# Now a search for "Epigraph" should return zero results.
|
||||
results = s.query(u'Epigraph')
|
||||
|
||||
@@ -108,3 +108,25 @@ def test_build_sphinx_return_nonzero_status(pkgroot, proc):
|
||||
print(out)
|
||||
print(err)
|
||||
assert proc.returncode != 0, 'expect non-zero status for setup.py'
|
||||
|
||||
|
||||
@with_setup_command(root)
|
||||
def test_build_sphinx_warning_return_zero_status(pkgroot, proc):
|
||||
srcdir = (pkgroot / 'doc')
|
||||
(srcdir / 'contents.txt').write_text(
|
||||
'See :ref:`unexisting-reference-label`')
|
||||
out, err = proc.communicate()
|
||||
print(out)
|
||||
print(err)
|
||||
assert proc.returncode == 0
|
||||
|
||||
|
||||
@with_setup_command(root, '--warning-is-error')
|
||||
def test_build_sphinx_warning_is_error_return_nonzero_status(pkgroot, proc):
|
||||
srcdir = (pkgroot / 'doc')
|
||||
(srcdir / 'contents.txt').write_text(
|
||||
'See :ref:`unexisting-reference-label`')
|
||||
out, err = proc.communicate()
|
||||
print(out)
|
||||
print(err)
|
||||
assert proc.returncode != 0, 'expect non-zero status for setup.py'
|
||||
|
||||
@@ -26,7 +26,7 @@ def test_theme_api(app, status, warning):
|
||||
assert set(Theme.themes.keys()) == \
|
||||
set(['basic', 'default', 'scrolls', 'agogo', 'sphinxdoc', 'haiku',
|
||||
'traditional', 'testtheme', 'ziptheme', 'epub', 'nature',
|
||||
'pyramid', 'bizstyle', 'classic'])
|
||||
'pyramid', 'bizstyle', 'classic', 'nonav'])
|
||||
assert Theme.themes['testtheme'][1] is None
|
||||
assert isinstance(Theme.themes['ziptheme'][1], zipfile.ZipFile)
|
||||
|
||||
@@ -66,7 +66,7 @@ def test_js_source(app, status, warning):
|
||||
|
||||
app.builder.build(['contents'])
|
||||
|
||||
v = '1.11.1'
|
||||
v = '3.1.0'
|
||||
msg = 'jquery.js version does not match to {v}'.format(v=v)
|
||||
jquery_min = (app.outdir / '_static' / 'jquery.js').text()
|
||||
assert 'jQuery v{v}'.format(v=v) in jquery_min, msg
|
||||
|
||||
114
tests/test_util_fileutil.py
Normal file
@@ -0,0 +1,114 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
test_util_fileutil
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Tests sphinx.util.fileutil functions.
|
||||
|
||||
:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
from sphinx.util.fileutil import copy_asset, copy_asset_file
|
||||
from sphinx.jinja2glue import BuiltinTemplateLoader
|
||||
|
||||
from mock import Mock
|
||||
from util import with_tempdir
|
||||
|
||||
|
||||
class DummyTemplateLoader(BuiltinTemplateLoader):
|
||||
def __init__(self):
|
||||
BuiltinTemplateLoader.__init__(self)
|
||||
builder = Mock()
|
||||
builder.config.templates_path = []
|
||||
builder.app.translater = None
|
||||
self.init(builder)
|
||||
|
||||
|
||||
@with_tempdir
|
||||
def test_copy_asset_file(tmpdir):
|
||||
renderer = DummyTemplateLoader()
|
||||
|
||||
# copy normal file
|
||||
src = (tmpdir / 'asset.txt')
|
||||
src.write_text('# test data')
|
||||
dest = (tmpdir / 'output.txt')
|
||||
|
||||
copy_asset_file(src, dest)
|
||||
assert dest.exists()
|
||||
assert src.text() == dest.text()
|
||||
|
||||
# copy template file
|
||||
src = (tmpdir / 'asset.txt_t')
|
||||
src.write_text('# {{var1}} data')
|
||||
dest = (tmpdir / 'output.txt_t')
|
||||
|
||||
copy_asset_file(src, dest, {'var1': 'template'}, renderer)
|
||||
assert not dest.exists()
|
||||
assert (tmpdir / 'output.txt').exists()
|
||||
assert (tmpdir / 'output.txt').text() == '# template data'
|
||||
|
||||
# copy template file to subdir
|
||||
src = (tmpdir / 'asset.txt_t')
|
||||
src.write_text('# {{var1}} data')
|
||||
subdir1 = (tmpdir / 'subdir')
|
||||
subdir1.makedirs()
|
||||
|
||||
copy_asset_file(src, subdir1, {'var1': 'template'}, renderer)
|
||||
assert (subdir1 / 'asset.txt').exists()
|
||||
assert (subdir1 / 'asset.txt').text() == '# template data'
|
||||
|
||||
# copy template file without context
|
||||
src = (tmpdir / 'asset.txt_t')
|
||||
subdir2 = (tmpdir / 'subdir2')
|
||||
subdir2.makedirs()
|
||||
|
||||
copy_asset_file(src, subdir2)
|
||||
assert not (subdir2 / 'asset.txt').exists()
|
||||
assert (subdir2 / 'asset.txt_t').exists()
|
||||
assert (subdir2 / 'asset.txt_t').text() == '# {{var1}} data'
|
||||
|
||||
|
||||
@with_tempdir
|
||||
def test_copy_asset(tmpdir):
|
||||
renderer = DummyTemplateLoader()
|
||||
|
||||
# prepare source files
|
||||
source = (tmpdir / 'source')
|
||||
source.makedirs()
|
||||
(source / 'index.rst').write_text('index.rst')
|
||||
(source / 'foo.rst_t').write_text('{{var1}}.rst')
|
||||
(source / '_static').makedirs()
|
||||
(source / '_static' / 'basic.css').write_text('basic.css')
|
||||
(source / '_templates').makedirs()
|
||||
(source / '_templates' / 'layout.html').write_text('layout.html')
|
||||
(source / '_templates' / 'sidebar.html_t').write_text('sidebar: {{var2}}')
|
||||
|
||||
# copy a single file
|
||||
assert not (tmpdir / 'test1').exists()
|
||||
copy_asset(source / 'index.rst', tmpdir / 'test1')
|
||||
assert (tmpdir / 'test1').exists()
|
||||
assert (tmpdir / 'test1/index.rst').exists()
|
||||
|
||||
# copy directories
|
||||
destdir = tmpdir / 'test2'
|
||||
copy_asset(source, destdir, context=dict(var1='bar', var2='baz'), renderer=renderer)
|
||||
assert (destdir / 'index.rst').exists()
|
||||
assert (destdir / 'foo.rst').exists()
|
||||
assert (destdir / 'foo.rst').text() == 'bar.rst'
|
||||
assert (destdir / '_static' / 'basic.css').exists()
|
||||
assert (destdir / '_templates' / 'layout.html').exists()
|
||||
assert (destdir / '_templates' / 'sidebar.html').exists()
|
||||
assert (destdir / '_templates' / 'sidebar.html').text() == 'sidebar: baz'
|
||||
|
||||
# copy with exclusion
|
||||
def excluded(path):
|
||||
return ('sidebar.html' in path or 'basic.css' in path)
|
||||
|
||||
destdir = tmpdir / 'test3'
|
||||
copy_asset(source, destdir, excluded,
|
||||
context=dict(var1='bar', var2='baz'), renderer=renderer)
|
||||
assert (destdir / 'index.rst').exists()
|
||||
assert (destdir / 'foo.rst').exists()
|
||||
assert not (destdir / '_static' / 'basic.css').exists()
|
||||
assert (destdir / '_templates' / 'layout.html').exists()
|
||||
assert not (destdir / '_templates' / 'sidebar.html').exists()
|
||||
70
tests/test_util_inspect.py
Normal file
@@ -0,0 +1,70 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
test_util_inspect
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Tests util.inspect functions.
|
||||
|
||||
:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
from unittest import TestCase
|
||||
|
||||
from sphinx.util import inspect
|
||||
|
||||
|
||||
class TestSafeGetAttr(TestCase):
|
||||
def test_safe_getattr_with_default(self):
|
||||
class Foo(object):
|
||||
def __getattr__(self, item):
|
||||
raise Exception
|
||||
|
||||
obj = Foo()
|
||||
|
||||
result = inspect.safe_getattr(obj, 'bar', 'baz')
|
||||
|
||||
assert result == 'baz'
|
||||
|
||||
def test_safe_getattr_with_exception(self):
|
||||
class Foo(object):
|
||||
def __getattr__(self, item):
|
||||
raise Exception
|
||||
|
||||
obj = Foo()
|
||||
|
||||
try:
|
||||
inspect.safe_getattr(obj, 'bar')
|
||||
except AttributeError as exc:
|
||||
self.assertEqual(exc.args[0], 'bar')
|
||||
else:
|
||||
self.fail('AttributeError not raised')
|
||||
|
||||
def test_safe_getattr_with_property_exception(self):
|
||||
class Foo(object):
|
||||
@property
|
||||
def bar(self):
|
||||
raise Exception
|
||||
|
||||
obj = Foo()
|
||||
|
||||
try:
|
||||
inspect.safe_getattr(obj, 'bar')
|
||||
except AttributeError as exc:
|
||||
self.assertEqual(exc.args[0], 'bar')
|
||||
else:
|
||||
self.fail('AttributeError not raised')
|
||||
|
||||
def test_safe_getattr_with___dict___override(self):
|
||||
class Foo(object):
|
||||
@property
|
||||
def __dict__(self):
|
||||
raise Exception
|
||||
|
||||
obj = Foo()
|
||||
|
||||
try:
|
||||
inspect.safe_getattr(obj, 'bar')
|
||||
except AttributeError as exc:
|
||||
self.assertEqual(exc.args[0], 'bar')
|
||||
else:
|
||||
self.fail('AttributeError not raised')
|
||||
9
tests/test_util_jsdump.py
Normal file
@@ -0,0 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
def test_jsdump():
|
||||
from sphinx.util.jsdump import dumps
|
||||
|
||||
assert dumps({'1a': 1}) == '{"1a":1}'
|
||||
assert dumps({'a1': 1}) == '{a1:1}'
|
||||
|
||||
assert dumps({u'a\xe8': 1}) == '{"a\\u00e8":1}'
|
||||
91
tests/test_util_matching.py
Normal file
@@ -0,0 +1,91 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
test_util_matching
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Tests sphinx.util.matching functions.
|
||||
|
||||
:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
from sphinx.util.matching import compile_matchers, Matcher
|
||||
|
||||
|
||||
def test_compile_matchers():
|
||||
# exact matching
|
||||
pat = compile_matchers(['hello.py']).pop()
|
||||
assert pat('hello.py')
|
||||
assert not pat('hello-py')
|
||||
assert not pat('subdir/hello.py')
|
||||
|
||||
# wild card (*)
|
||||
pat = compile_matchers(['hello.*']).pop()
|
||||
assert pat('hello.py')
|
||||
assert pat('hello.rst')
|
||||
|
||||
pat = compile_matchers(['*.py']).pop()
|
||||
assert pat('hello.py')
|
||||
assert pat('world.py')
|
||||
assert not pat('subdir/hello.py')
|
||||
|
||||
# wild card (**)
|
||||
pat = compile_matchers(['hello.**']).pop()
|
||||
assert pat('hello.py')
|
||||
assert pat('hello.rst')
|
||||
assert pat('hello.py/world.py')
|
||||
|
||||
pat = compile_matchers(['**.py']).pop()
|
||||
assert pat('hello.py')
|
||||
assert pat('world.py')
|
||||
assert pat('subdir/hello.py')
|
||||
|
||||
pat = compile_matchers(['**/hello.py']).pop()
|
||||
assert not pat('hello.py')
|
||||
assert pat('subdir/hello.py')
|
||||
assert pat('subdir/subdir/hello.py')
|
||||
|
||||
# wild card (?)
|
||||
pat = compile_matchers(['hello.?']).pop()
|
||||
assert pat('hello.c')
|
||||
assert not pat('hello.py')
|
||||
|
||||
# pattern ([...])
|
||||
pat = compile_matchers(['hello[12\\].py']).pop()
|
||||
assert pat('hello1.py')
|
||||
assert pat('hello2.py')
|
||||
assert pat('hello\\.py')
|
||||
assert not pat('hello3.py')
|
||||
|
||||
pat = compile_matchers(['hello[^12].py']).pop() # "^" is not negative identifier
|
||||
assert pat('hello1.py')
|
||||
assert pat('hello2.py')
|
||||
assert pat('hello^.py')
|
||||
assert not pat('hello3.py')
|
||||
|
||||
# negative pattern ([!...])
|
||||
pat = compile_matchers(['hello[!12].py']).pop()
|
||||
assert not pat('hello1.py')
|
||||
assert not pat('hello2.py')
|
||||
assert not pat('hello/.py') # negative pattern does not match to "/"
|
||||
assert pat('hello3.py')
|
||||
|
||||
# non patterns
|
||||
pat = compile_matchers(['hello[.py']).pop()
|
||||
assert pat('hello[.py')
|
||||
assert not pat('hello.py')
|
||||
|
||||
pat = compile_matchers(['hello[].py']).pop()
|
||||
assert pat('hello[].py')
|
||||
assert not pat('hello.py')
|
||||
|
||||
pat = compile_matchers(['hello[!].py']).pop()
|
||||
assert pat('hello[!].py')
|
||||
assert not pat('hello.py')
|
||||
|
||||
|
||||
def test_Matcher():
|
||||
matcher = Matcher(['hello.py', '**/world.py'])
|
||||
assert matcher('hello.py')
|
||||
assert not matcher('subdir/hello.py')
|
||||
assert matcher('world.py')
|
||||
assert matcher('subdir/world.py')
|
||||
36
tests/test_writer_latex.py
Normal file
@@ -0,0 +1,36 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
test_writer_latex
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Test the LaTeX writer
|
||||
|
||||
:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
from sphinx.writers.latex import rstdim_to_latexdim
|
||||
|
||||
from util import raises
|
||||
|
||||
|
||||
def test_rstdim_to_latexdim():
|
||||
# Length units docutils supported
|
||||
# http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#length-units
|
||||
assert rstdim_to_latexdim('160em') == '160em'
|
||||
assert rstdim_to_latexdim('160px') == '160\\sphinxpxdimen'
|
||||
assert rstdim_to_latexdim('160in') == '160in'
|
||||
assert rstdim_to_latexdim('160cm') == '160cm'
|
||||
assert rstdim_to_latexdim('160mm') == '160mm'
|
||||
assert rstdim_to_latexdim('160pt') == '160bp'
|
||||
assert rstdim_to_latexdim('160pc') == '160pc'
|
||||
assert rstdim_to_latexdim('30%') == '0.300\\linewidth'
|
||||
assert rstdim_to_latexdim('160') == '160\\sphinxpxdimen'
|
||||
|
||||
# flaot values
|
||||
assert rstdim_to_latexdim('160.0em') == '160.0em'
|
||||
assert rstdim_to_latexdim('.5em') == '.5em'
|
||||
|
||||
# unknown values (it might be generated by 3rd party extension)
|
||||
raises(ValueError, rstdim_to_latexdim, 'unknown')
|
||||
assert rstdim_to_latexdim('160.0unknown') == '160.0unknown'
|
||||