diff --git a/.circleci/config.yml b/.circleci/config.yml index 7516f9c8d3a..f050a21ed95 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -17,6 +17,14 @@ jobs: - run: pip install --user tox - run: tox -e py36,codecov + sphinx-tests: + docker: + - image: 'cimg/python:3.6' + steps: + - checkout + - run: pip install --user tox + - run: tox -c sphinx-tox.ini + checks: docker: - image: 'cimg/python:3.6' @@ -45,3 +53,4 @@ workflows: jobs: - checks - tests + - sphinx-tests diff --git a/pytest.ini b/pytest.ini index 15e67f8a2d3..258ce7d1b6f 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,8 +1,8 @@ [pytest] addopts = --reuse-db --strict-markers markers = + sphinxtest search - serve proxito python_files = tests.py test_*.py *_tests.py filterwarnings = diff --git a/readthedocs/api/v2/proxied_urls.py b/readthedocs/api/v2/proxied_urls.py index 90d5f6cc74e..8b7c878c330 100644 --- a/readthedocs/api/v2/proxied_urls.py +++ b/readthedocs/api/v2/proxied_urls.py @@ -15,7 +15,7 @@ api_footer_urls = [ url(r'footer_html/', ProxiedFooterHTML.as_view(), name='footer_html'), url(r'search/$', ProxiedPageSearchAPIView.as_view(), name='search_api'), - url(r'embed/', ProxiedEmbedAPI.as_view(), name='embed_api'), + url(r'embed/', ProxiedEmbedAPI.as_view(), name='api_embed'), url(r'analytics/$', AnalyticsView.as_view(), name='analytics_api'), ] diff --git a/readthedocs/conftest.py b/readthedocs/conftest.py index 0dc0b840141..5392e941122 100644 --- a/readthedocs/conftest.py +++ b/readthedocs/conftest.py @@ -1,6 +1,8 @@ import pytest from rest_framework.test import APIClient +pytest_plugins = 'sphinx.testing.fixtures' + @pytest.fixture def api_client(): return APIClient() diff --git a/readthedocs/embed/tests/data/sphinx/bibtex/page-getting-started.html b/readthedocs/embed/tests/data/sphinx/bibtex/page-getting-started.html new file mode 100644 index 00000000000..4d0a12ea738 --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/bibtex/page-getting-started.html @@ -0,0 +1,166 @@ +
+

Getting Started

+
+

Overview

+

Sphinx extension for BibTeX style citations.

+

+ The bibtex extension allows BibTeX + citations to be inserted into documentation generated by + Sphinx, via + a bibliography directive, + along with :cite:p: and :cite:t: roles. + These work similarly to LaTeX\u2019s thebibliography environment + and the \\citet and \\citep commands. +

+

+ For formatting, the extension relies on pybtex + written by Andrey Golovizin. The extension is inspired by Matthew Brett’s + bibstuff.sphinxext.bibref + and Weston Nielson’s + sphinx-natbib. +

+ +
+
+

Installation

+

+ Install the module with pip install sphinxcontrib-bibtex, + or from source using python setup.py install. + Then add: +

+
+
+
extensions = ['sphinxcontrib.bibtex']
+bibtex_bibfiles = ['refs.bib']
+
+
+
+

+ to your project’s Sphinx configuration file conf.py. +

+
+
+

Minimal Example

+

+ In your project\u2019s documentation, you can use + :cite:t: for textual citation + references, + :cite:p: for parenthetical citation + references, and .. bibliography:: + for inserting the bibliography. For example: +

+
+
+
See :cite:t:`1987:nelson` for an introduction to non-standard analysis.
+Non-standard analysis is fun :cite:p:`1987:nelson`.
+
+.. bibliography::
+
+
+
+

+ where refs.bib would contain an + entry: +

+
+
+
@Book{1987:nelson,
+  author = {Edward Nelson},
+  title = {Radically Elementary Probability Theory},
+  publisher = {Princeton University Press},
+  year = {1987}
+}
+
+
+
+

In the default style, this will get rendered as:

+

+ See Nelson [Nel87a] for an introduction to + non-standard analysis. + Non-standard analysis is fun [Nel87a].

+
+
Nel87a(1,2)
+
+

Edward Nelson. Radically Elementary Probability Theory. Princeton University Press, 1987.

+
+
+

+ Citations in sphinx are resolved globally across all documents. + Typically, you have a single bibliography + directive across + your entire project which collects all citations. + Advanced use cases with multiple bibliography + directives + across your project are also supported, but some care + needs to be taken from your end to avoid duplicate citations. +

+

+ In contrast, footnotes in sphinx are resolved locally per document. + To achieve local bibliographies per document, you can use citations + represented by footnotes as follows: +

+
+
+
Non-standard analysis is lovely. :footcite:`1987:nelson`
+
+.. footbibliography::
+
+
+
+

which will get rendered as:

+

Non-standard analysis is lovely. 1

+
+
1
+
+

Edward Nelson. Radically Elementary Probability Theory. Princeton University Press, 1987.

+
+
+

+ Typically, you have a single footbibliography + directive + at the bottom of each document that has footcite citations. + Advanced use cases with multiple footbibliography + directives per document are also supported. Since everything is local, + there is no concern with duplicate citations when using footnotes. +

+
+
diff --git a/readthedocs/embed/tests/data/sphinx/bibtex/page-installation.html b/readthedocs/embed/tests/data/sphinx/bibtex/page-installation.html new file mode 100644 index 00000000000..4240a0ab64f --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/bibtex/page-installation.html @@ -0,0 +1,21 @@ +
+

Installation

+

+ Install the module with pip install sphinxcontrib-bibtex, + or from source using python setup.py install. + Then add: +

+
+
+
extensions = ['sphinxcontrib.bibtex']
+bibtex_bibfiles = ['refs.bib']
+
+
+
+

+ to your project’s Sphinx configuration file conf.py. +

+
diff --git a/readthedocs/embed/tests/data/sphinx/bibtex/page-minimal-example.html b/readthedocs/embed/tests/data/sphinx/bibtex/page-minimal-example.html new file mode 100644 index 00000000000..f207fffc7e3 --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/bibtex/page-minimal-example.html @@ -0,0 +1,98 @@ +
+

Minimal Example

+

+ In your project\u2019s documentation, you can use + :cite:t: for textual citation + references, + :cite:p: for parenthetical citation + references, and .. bibliography:: + for inserting the bibliography. For example: +

+
+
+
See :cite:t:`1987:nelson` for an introduction to non-standard analysis.
+Non-standard analysis is fun :cite:p:`1987:nelson`.
+
+.. bibliography::
+
+
+
+

+ where refs.bib would contain an + entry: +

+
+
+
@Book{1987:nelson,
+  author = {Edward Nelson},
+  title = {Radically Elementary Probability Theory},
+  publisher = {Princeton University Press},
+  year = {1987}
+}
+
+
+
+

In the default style, this will get rendered as:

+

+ See Nelson [Nel87a] for an introduction to + non-standard analysis. + Non-standard analysis is fun [Nel87a].

+
+
Nel87a(1,2)
+
+

Edward Nelson. Radically Elementary Probability Theory. Princeton University Press, 1987.

+
+
+

+ Citations in sphinx are resolved globally across all documents. + Typically, you have a single bibliography + directive across + your entire project which collects all citations. + Advanced use cases with multiple bibliography + directives + across your project are also supported, but some care + needs to be taken from your end to avoid duplicate citations. +

+

+ In contrast, footnotes in sphinx are resolved locally per document. + To achieve local bibliographies per document, you can use citations + represented by footnotes as follows: +

+
+
+
Non-standard analysis is lovely. :footcite:`1987:nelson`
+
+.. footbibliography::
+
+
+
+

which will get rendered as:

+

Non-standard analysis is lovely. 1

+
+
1
+
+

Edward Nelson. Radically Elementary Probability Theory. Princeton University Press, 1987.

+
+
+

+ Typically, you have a single footbibliography + directive + at the bottom of each document that has footcite citations. + Advanced use cases with multiple footbibliography + directives per document are also supported. Since everything is local, + there is no concern with duplicate citations when using footnotes. +

+
diff --git a/readthedocs/embed/tests/data/sphinx/bibtex/page-nel87a.html b/readthedocs/embed/tests/data/sphinx/bibtex/page-nel87a.html new file mode 100644 index 00000000000..9c89c8c7d63 --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/bibtex/page-nel87a.html @@ -0,0 +1,3 @@ +
+

Edward Nelson. Radically Elementary Probability Theory. Princeton University Press, 1987.

+
diff --git a/readthedocs/embed/tests/data/sphinx/bibtex/page-nel87b.html b/readthedocs/embed/tests/data/sphinx/bibtex/page-nel87b.html new file mode 100644 index 00000000000..511bfca4474 --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/bibtex/page-nel87b.html @@ -0,0 +1,6 @@ +
+
1
+
+

Edward Nelson. Radically Elementary Probability Theory. Princeton University Press, 1987.

+
+
diff --git a/readthedocs/embed/tests/data/sphinx/bibtex/page-overview.html b/readthedocs/embed/tests/data/sphinx/bibtex/page-overview.html new file mode 100644 index 00000000000..3ab199aaf15 --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/bibtex/page-overview.html @@ -0,0 +1,44 @@ +
+

Overview

+

Sphinx extension for BibTeX style citations.

+

+ The bibtex extension allows BibTeX + citations to be inserted into documentation generated by + Sphinx, via + a bibliography directive, + along with :cite:p: and :cite:t: roles. + These work similarly to LaTeX\u2019s thebibliography environment + and the \\citet and \\citep commands. +

+

+ For formatting, the extension relies on pybtex + written by Andrey Golovizin. The extension is inspired by Matthew Brett’s + bibstuff.sphinxext.bibref + and Weston Nielson’s + sphinx-natbib. +

+ +
diff --git a/readthedocs/embed/tests/data/sphinx/bibtex/page.html b/readthedocs/embed/tests/data/sphinx/bibtex/page.html new file mode 100644 index 00000000000..c29a107a82d --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/bibtex/page.html @@ -0,0 +1,167 @@ + +
+

Getting Started

+
+

Overview

+

Sphinx extension for BibTeX style citations.

+

+ The bibtex extension allows BibTeX + citations to be inserted into documentation generated by + Sphinx, via + a bibliography directive, + along with :cite:p: and :cite:t: roles. + These work similarly to LaTeX\u2019s thebibliography environment + and the \\citet and \\citep commands. +

+

+ For formatting, the extension relies on pybtex + written by Andrey Golovizin. The extension is inspired by Matthew Brett’s + bibstuff.sphinxext.bibref + and Weston Nielson’s + sphinx-natbib. +

+ +
+
+

Installation

+

+ Install the module with pip install sphinxcontrib-bibtex, + or from source using python setup.py install. + Then add: +

+
+
+
extensions = ['sphinxcontrib.bibtex']
+bibtex_bibfiles = ['refs.bib']
+
+
+
+

+ to your project’s Sphinx configuration file conf.py. +

+
+
+

Minimal Example

+

+ In your project\u2019s documentation, you can use + :cite:t: for textual citation + references, + :cite:p: for parenthetical citation + references, and .. bibliography:: + for inserting the bibliography. For example: +

+
+
+
See :cite:t:`1987:nelson` for an introduction to non-standard analysis.
+Non-standard analysis is fun :cite:p:`1987:nelson`.
+
+.. bibliography::
+
+
+
+

+ where refs.bib would contain an + entry: +

+
+
+
@Book{1987:nelson,
+  author = {Edward Nelson},
+  title = {Radically Elementary Probability Theory},
+  publisher = {Princeton University Press},
+  year = {1987}
+}
+
+
+
+

In the default style, this will get rendered as:

+

+ See Nelson [Nel87a] for an introduction to + non-standard analysis. + Non-standard analysis is fun [Nel87a].

+
+
Nel87a(1,2)
+
+

Edward Nelson. Radically Elementary Probability Theory. Princeton University Press, 1987.

+
+
+

+ Citations in sphinx are resolved globally across all documents. + Typically, you have a single bibliography + directive across + your entire project which collects all citations. + Advanced use cases with multiple bibliography + directives + across your project are also supported, but some care + needs to be taken from your end to avoid duplicate citations. +

+

+ In contrast, footnotes in sphinx are resolved locally per document. + To achieve local bibliographies per document, you can use citations + represented by footnotes as follows: +

+
+
+
Non-standard analysis is lovely. :footcite:`1987:nelson`
+
+.. footbibliography::
+
+
+
+

which will get rendered as:

+

Non-standard analysis is lovely. 1

+
+
1
+
+

Edward Nelson. Radically Elementary Probability Theory. Princeton University Press, 1987.

+
+
+

+ Typically, you have a single footbibliography + directive + at the bottom of each document that has footcite citations. + Advanced use cases with multiple footbibliography + directives per document are also supported. Since everything is local, + there is no concern with duplicate citations when using footnotes. +

+
+
diff --git a/readthedocs/embed/tests/data/sphinx/bibtex/page.json b/readthedocs/embed/tests/data/sphinx/bibtex/page.json new file mode 100644 index 00000000000..0ee303f403a --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/bibtex/page.json @@ -0,0 +1,8 @@ +{ + "body": "", + "title": "Getting Started", + "sourcename": "quickstart.rst.txt", + "current_page_name": "quickstart", + "toc": "\n", + "page_source_suffix": ".rst" +} diff --git a/readthedocs/embed/tests/data/sphinx/glossary/page-glossary.html b/readthedocs/embed/tests/data/sphinx/glossary/page-glossary.html new file mode 100644 index 00000000000..d8363e65f62 --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/glossary/page-glossary.html @@ -0,0 +1,192 @@ +
+ +

Glossary

+
+
builder
+
+

+ A class (inheriting from Builder) that + takes + parsed documents and performs an action on them. Normally, builders + translate the documents to an output format, but it is also possible to + use builders that e.g. check for broken links in the documentation, or + build coverage information. +

+

+ See Builders for an + overview over Sphinx\u2019s built-in + builders. +

+
+
configuration directory
+
+

+ The directory containing conf.py. By default, this is the + same as + the source + directory, but can be set differently with the -c + command-line option. +

+
+
directive +
+
+

+ A reStructuredText markup element that allows marking a block of content + with special meaning. Directives are supplied not only by docutils, but + Sphinx and custom extensions can add their own. The basic directive + syntax looks like this: +

+
+
+
.. directivename:: argument ...
+   :option: value
+
+   Content of the directive.
+
+
+
+

+ See Directives for more information. +

+
+
document name
+
+

+ Since reST source files can have different extensions (some people like + .txt, some like .rst \u2013 the extension can be + configured with + source_suffix) + and different OSes have different path + separators, Sphinx abstracts them: document names are always + relative to the source directory, the extension is stripped, and + path separators are converted to slashes. All values, parameters and such + referring to \u201cdocuments\u201d expect such document names. +

+

+ Examples for document names are index, library/zipfile, or + reference/datamodel/types. Note that + there is no leading or trailing + slash. +

+
+
domain
+
+

+ A domain is a collection of markup (reStructuredText directives + and roles) to + describe and link to objects belonging + together, e.g. elements of a programming language. Directive and role + names in a domain have names like domain:name, e.g. py:function. +

+

+ Having domains means that there are no naming problems when one set of + documentation wants to refer to e.g. C++ and Python classes. It also + means that extensions that support the documentation of whole new + languages are much easier to write. +

+

+ For more information, refer to Domains. +

+
+
environment
+
+

+ A structure where information about all documents under the root is saved, + and used for cross-referencing. The environment is pickled after the + parsing stage, so that successive runs only need to read and parse new and + changed documents. +

+
+
extension +
+
+

+ A custom role, directive or + other aspect of Sphinx that + allows users to modify any aspect of the build process within Sphinx. +

+

+ For more information, refer to Extensions. +

+
+
master document
+
+

+ The document that contains the root toctree directive. +

+
+
object
+
+

+ The basic building block of Sphinx documentation. Every \u201cobject + directive\u201d (e.g. function or object) creates + such a + block; and most objects can be cross-referenced to. +

+
+
RemoveInSphinxXXXWarning
+
+

+ The feature which is warned will be removed in Sphinx-XXX version. + It usually caused from Sphinx extensions which is using deprecated. + See also Deprecation + Warnings. +

+
+
role
+
+

+ A reStructuredText markup element that allows marking a piece of text. + Like directives, roles are extensible. The basic syntax looks like this: + :rolename:`content`. See Inline markup for details. +

+
+
source directory
+
+

+ The directory which, including its subdirectories, contains all source + files for one Sphinx project. +

+
+
reStructuredText
+
+

+ An easy-to-read, what-you-see-is-what-you-get plaintext markup syntax and + parser system. +

+
+
+
diff --git a/readthedocs/embed/tests/data/sphinx/glossary/page-term-RemoveInSphinxXXXWarning.html b/readthedocs/embed/tests/data/sphinx/glossary/page-term-RemoveInSphinxXXXWarning.html new file mode 100644 index 00000000000..fa723104787 --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/glossary/page-term-RemoveInSphinxXXXWarning.html @@ -0,0 +1,9 @@ +
+

+ The feature which is warned will be removed in Sphinx-XXX version. + It usually caused from Sphinx extensions which is using deprecated. + See also Deprecation + Warnings. +

+
diff --git a/readthedocs/embed/tests/data/sphinx/glossary/page-term-builder.html b/readthedocs/embed/tests/data/sphinx/glossary/page-term-builder.html new file mode 100644 index 00000000000..9d55cb6051e --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/glossary/page-term-builder.html @@ -0,0 +1,17 @@ +
+

+ A class (inheriting from Builder) that + takes + parsed documents and performs an action on them. Normally, builders + translate the documents to an output format, but it is also possible to + use builders that e.g. check for broken links in the documentation, or + build coverage information. +

+

+ See Builders for an + overview over Sphinx\u2019s built-in + builders. +

+
diff --git a/readthedocs/embed/tests/data/sphinx/glossary/page-term-configuration-directory.html b/readthedocs/embed/tests/data/sphinx/glossary/page-term-configuration-directory.html new file mode 100644 index 00000000000..3b6e4097b3a --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/glossary/page-term-configuration-directory.html @@ -0,0 +1,10 @@ +
+

+ The directory containing conf.py. By default, this is the + same as + the source + directory, but can be set differently with the -c + command-line option. +

+
diff --git a/readthedocs/embed/tests/data/sphinx/glossary/page-term-directive.html b/readthedocs/embed/tests/data/sphinx/glossary/page-term-directive.html new file mode 100644 index 00000000000..24ffad6dd78 --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/glossary/page-term-directive.html @@ -0,0 +1,21 @@ +
+

+ A reStructuredText markup element that allows marking a block of content + with special meaning. Directives are supplied not only by docutils, but + Sphinx and custom extensions can add their own. The basic directive + syntax looks like this: +

+
+
+
.. directivename:: argument ...
+   :option: value
+
+   Content of the directive.
+
+
+
+

+ See Directives for more information. +

+
diff --git a/readthedocs/embed/tests/data/sphinx/glossary/page-term-document-name.html b/readthedocs/embed/tests/data/sphinx/glossary/page-term-document-name.html new file mode 100644 index 00000000000..45745c36dd2 --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/glossary/page-term-document-name.html @@ -0,0 +1,24 @@ +
+

+ Since reST source files can have different extensions (some people like + .txt, some like .rst \u2013 the extension can be + configured with + source_suffix) + and different OSes have different path + separators, Sphinx abstracts them: document names are always + relative to the source directory, the extension is stripped, and + path separators are converted to slashes. All values, parameters and such + referring to \u201cdocuments\u201d expect such document names. +

+

+ Examples for document names are index, library/zipfile, or + reference/datamodel/types. Note that + there is no leading or trailing + slash. +

+
diff --git a/readthedocs/embed/tests/data/sphinx/glossary/page-term-domain.html b/readthedocs/embed/tests/data/sphinx/glossary/page-term-domain.html new file mode 100644 index 00000000000..b67bc51b7e7 --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/glossary/page-term-domain.html @@ -0,0 +1,23 @@ +
+

+ A domain is a collection of markup (reStructuredText directives + and roles) to + describe and link to objects belonging + together, e.g. elements of a programming language. Directive and role + names in a domain have names like domain:name, e.g. py:function. +

+

+ Having domains means that there are no naming problems when one set of + documentation wants to refer to e.g. C++ and Python classes. It also + means that extensions that support the documentation of whole new + languages are much easier to write. +

+

+ For more information, refer to Domains. +

+
diff --git a/readthedocs/embed/tests/data/sphinx/glossary/page-term-environment.html b/readthedocs/embed/tests/data/sphinx/glossary/page-term-environment.html new file mode 100644 index 00000000000..3db153b4fdb --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/glossary/page-term-environment.html @@ -0,0 +1,8 @@ +
+

+ A structure where information about all documents under the root is saved, + and used for cross-referencing. The environment is pickled after the + parsing stage, so that successive runs only need to read and parse new and + changed documents. +

+
diff --git a/readthedocs/embed/tests/data/sphinx/glossary/page-term-extension.html b/readthedocs/embed/tests/data/sphinx/glossary/page-term-extension.html new file mode 100644 index 00000000000..25cef9bdb7c --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/glossary/page-term-extension.html @@ -0,0 +1,12 @@ +
+

+ A custom role, directive or + other aspect of Sphinx that + allows users to modify any aspect of the build process within Sphinx. +

+

+ For more information, refer to Extensions. +

+
diff --git a/readthedocs/embed/tests/data/sphinx/glossary/page-term-master-document.html b/readthedocs/embed/tests/data/sphinx/glossary/page-term-master-document.html new file mode 100644 index 00000000000..e56aeb36589 --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/glossary/page-term-master-document.html @@ -0,0 +1,7 @@ +
+

+ The document that contains the root toctree directive. +

+
diff --git a/readthedocs/embed/tests/data/sphinx/glossary/page-term-object.html b/readthedocs/embed/tests/data/sphinx/glossary/page-term-object.html new file mode 100644 index 00000000000..af88e5c8b49 --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/glossary/page-term-object.html @@ -0,0 +1,12 @@ +
+

+ The basic building block of Sphinx documentation. Every \u201cobject + directive\u201d (e.g. function or object) creates + such a + block; and most objects can be cross-referenced to. +

+
diff --git a/readthedocs/embed/tests/data/sphinx/glossary/page-term-reStructuredText.html b/readthedocs/embed/tests/data/sphinx/glossary/page-term-reStructuredText.html new file mode 100644 index 00000000000..58701e11c0d --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/glossary/page-term-reStructuredText.html @@ -0,0 +1,6 @@ +
+

+ An easy-to-read, what-you-see-is-what-you-get plaintext markup syntax and + parser system. +

+
diff --git a/readthedocs/embed/tests/data/sphinx/glossary/page-term-role.html b/readthedocs/embed/tests/data/sphinx/glossary/page-term-role.html new file mode 100644 index 00000000000..1011220adac --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/glossary/page-term-role.html @@ -0,0 +1,9 @@ +
+

+ A reStructuredText markup element that allows marking a piece of text. + Like directives, roles are extensible. The basic syntax looks like this: + :rolename:`content`. See Inline markup for details. +

+
diff --git a/readthedocs/embed/tests/data/sphinx/glossary/page-term-source-directory.html b/readthedocs/embed/tests/data/sphinx/glossary/page-term-source-directory.html new file mode 100644 index 00000000000..6e946de7648 --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/glossary/page-term-source-directory.html @@ -0,0 +1,6 @@ +
+

+ The directory which, including its subdirectories, contains all source + files for one Sphinx project. +

+
diff --git a/readthedocs/embed/tests/data/sphinx/glossary/page.html b/readthedocs/embed/tests/data/sphinx/glossary/page.html new file mode 100644 index 00000000000..5d97ec479fc --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/glossary/page.html @@ -0,0 +1,193 @@ + +
+ +

Glossary

+
+
builder
+
+

+ A class (inheriting from Builder) that + takes + parsed documents and performs an action on them. Normally, builders + translate the documents to an output format, but it is also possible to + use builders that e.g. check for broken links in the documentation, or + build coverage information. +

+

+ See Builders for an + overview over Sphinx\u2019s built-in + builders. +

+
+
configuration directory
+
+

+ The directory containing conf.py. By default, this is the + same as + the source + directory, but can be set differently with the -c + command-line option. +

+
+
directive +
+
+

+ A reStructuredText markup element that allows marking a block of content + with special meaning. Directives are supplied not only by docutils, but + Sphinx and custom extensions can add their own. The basic directive + syntax looks like this: +

+
+
+
.. directivename:: argument ...
+   :option: value
+
+   Content of the directive.
+
+
+
+

+ See Directives for more information. +

+
+
document name
+
+

+ Since reST source files can have different extensions (some people like + .txt, some like .rst \u2013 the extension can be + configured with + source_suffix) + and different OSes have different path + separators, Sphinx abstracts them: document names are always + relative to the source directory, the extension is stripped, and + path separators are converted to slashes. All values, parameters and such + referring to \u201cdocuments\u201d expect such document names. +

+

+ Examples for document names are index, library/zipfile, or + reference/datamodel/types. Note that + there is no leading or trailing + slash. +

+
+
domain
+
+

+ A domain is a collection of markup (reStructuredText directives + and roles) to + describe and link to objects belonging + together, e.g. elements of a programming language. Directive and role + names in a domain have names like domain:name, e.g. py:function. +

+

+ Having domains means that there are no naming problems when one set of + documentation wants to refer to e.g. C++ and Python classes. It also + means that extensions that support the documentation of whole new + languages are much easier to write. +

+

+ For more information, refer to Domains. +

+
+
environment
+
+

+ A structure where information about all documents under the root is saved, + and used for cross-referencing. The environment is pickled after the + parsing stage, so that successive runs only need to read and parse new and + changed documents. +

+
+
extension +
+
+

+ A custom role, directive or + other aspect of Sphinx that + allows users to modify any aspect of the build process within Sphinx. +

+

+ For more information, refer to Extensions. +

+
+
master document
+
+

+ The document that contains the root toctree directive. +

+
+
object
+
+

+ The basic building block of Sphinx documentation. Every \u201cobject + directive\u201d (e.g. function or object) creates + such a + block; and most objects can be cross-referenced to. +

+
+
RemoveInSphinxXXXWarning
+
+

+ The feature which is warned will be removed in Sphinx-XXX version. + It usually caused from Sphinx extensions which is using deprecated. + See also Deprecation + Warnings. +

+
+
role
+
+

+ A reStructuredText markup element that allows marking a piece of text. + Like directives, roles are extensible. The basic syntax looks like this: + :rolename:`content`. See Inline markup for details. +

+
+
source directory
+
+

+ The directory which, including its subdirectories, contains all source + files for one Sphinx project. +

+
+
reStructuredText
+
+

+ An easy-to-read, what-you-see-is-what-you-get plaintext markup syntax and + parser system. +

+
+
+
diff --git a/readthedocs/embed/tests/data/sphinx/glossary/page.json b/readthedocs/embed/tests/data/sphinx/glossary/page.json new file mode 100644 index 00000000000..fb566b5b827 --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/glossary/page.json @@ -0,0 +1,8 @@ +{ + "body": "", + "title": "Glossary", + "sourcename": "glossary.rst.txt", + "current_page_name": "glossary", + "toc": "\n", + "page_source_suffix": ".rst" +} diff --git a/readthedocs/embed/tests/data/sphinx/source/conf.py b/readthedocs/embed/tests/data/sphinx/source/conf.py new file mode 100644 index 00000000000..4d324fd1505 --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/source/conf.py @@ -0,0 +1,7 @@ +extensions = [ + "readthedocs_ext.readthedocs", + 'sphinx.ext.autosectionlabel', +] +project = "Test" +master_doc = "index" +exclude_patterns = ["out"] diff --git a/readthedocs/embed/tests/data/sphinx/source/glossary.rst b/readthedocs/embed/tests/data/sphinx/source/glossary.rst new file mode 100644 index 00000000000..522b3ea0b99 --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/source/glossary.rst @@ -0,0 +1,40 @@ +Glossary +======== + +.. glossary:: + + builder + A class (inheriting from :class:`~sphinx.builders.Builder`) that takes + parsed documents and performs an action on them. Normally, builders + translate the documents to an output format, but it is also possible to + use builders that e.g. check for broken links in the documentation, or + build coverage information. + + See :doc:`/usage` for an overview over Sphinx's built-in + builders. + + configuration directory + The directory containing :file:`conf.py`. By default, this is the same as + the :term:`builder`, but can be set differently with the **-c** + command-line option. + + directive + A reStructuredText markup element that allows marking a block of content + with special meaning. Directives are supplied not only by docutils, but + Sphinx and custom extensions can add their own. The basic directive + syntax looks like this: + + .. sourcecode:: rst + + .. directivename:: argument ... + :option: value + + Content of the directive. + + See :ref:`index:Another title` for more information. + + environment + A structure where information about all documents under the root is saved, + and used for cross-referencing. The environment is pickled after the + parsing stage, so that successive runs only need to read and parse new and + changed documents. diff --git a/readthedocs/embed/tests/data/sphinx/source/index.rst b/readthedocs/embed/tests/data/sphinx/source/index.rst new file mode 100644 index 00000000000..ae2ee1c0c77 --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/source/index.rst @@ -0,0 +1,35 @@ +Title +===== + +`Read the Docs`_ hosts documentation for the open source community. + +.. _Read the Docs: https://readthedocs.org + +The main documentation for the site is organized into a couple sections: + +.. toctree:: + :maxdepth: 2 + + /usage + /glossary + +Subtitle +-------- + +See :term:`builder` for more information. + +Sub-sub title +````````````` + +Here is my content. + +- One +- Two +- Three + +Another title +------------- + +.. code-block:: python + + print("Hello world!") diff --git a/readthedocs/embed/tests/data/sphinx/source/out/glossary-glossary.html b/readthedocs/embed/tests/data/sphinx/source/out/glossary-glossary.html new file mode 100644 index 00000000000..3c6c904a1f0 --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/source/out/glossary-glossary.html @@ -0,0 +1,34 @@ +
+

Glossary

+
+
builder

A class (inheriting from Builder) that takes +parsed documents and performs an action on them. Normally, builders +translate the documents to an output format, but it is also possible to +use builders that e.g. check for broken links in the documentation, or +build coverage information.

+

See Usage for an overview over Sphinx’s built-in +builders.

+
+
configuration directory

The directory containing conf.py. By default, this is the same as +the builder, but can be set differently with the -c +command-line option.

+
+
directive

A reStructuredText markup element that allows marking a block of content +with special meaning. Directives are supplied not only by docutils, but +Sphinx and custom extensions can add their own. The basic directive +syntax looks like this:

+
.. directivename:: argument ...
+   :option: value
+
+   Content of the directive.
+
+
+

See index:Another title for more information.

+
+
environment

A structure where information about all documents under the root is saved, +and used for cross-referencing. The environment is pickled after the +parsing stage, so that successive runs only need to read and parse new and +changed documents.

+
+
+
diff --git a/readthedocs/embed/tests/data/sphinx/source/out/glossary-term-builder.html b/readthedocs/embed/tests/data/sphinx/source/out/glossary-term-builder.html new file mode 100644 index 00000000000..62a36df18dc --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/source/out/glossary-term-builder.html @@ -0,0 +1,8 @@ +

A class (inheriting from Builder) that takes +parsed documents and performs an action on them. Normally, builders +translate the documents to an output format, but it is also possible to +use builders that e.g. check for broken links in the documentation, or +build coverage information.

+

See Usage for an overview over Sphinx’s built-in +builders.

+
diff --git a/readthedocs/embed/tests/data/sphinx/source/out/glossary-term-configuration-directory.html b/readthedocs/embed/tests/data/sphinx/source/out/glossary-term-configuration-directory.html new file mode 100644 index 00000000000..a3c0bca18cf --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/source/out/glossary-term-configuration-directory.html @@ -0,0 +1,4 @@ +

The directory containing conf.py. By default, this is the same as +the builder, but can be set differently with the -c +command-line option.

+
diff --git a/readthedocs/embed/tests/data/sphinx/source/out/glossary-term-directive.html b/readthedocs/embed/tests/data/sphinx/source/out/glossary-term-directive.html new file mode 100644 index 00000000000..5ac40e235a0 --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/source/out/glossary-term-directive.html @@ -0,0 +1,12 @@ +

A reStructuredText markup element that allows marking a block of content +with special meaning. Directives are supplied not only by docutils, but +Sphinx and custom extensions can add their own. The basic directive +syntax looks like this:

+
.. directivename:: argument ...
+   :option: value
+
+   Content of the directive.
+
+
+

See index:Another title for more information.

+
diff --git a/readthedocs/embed/tests/data/sphinx/source/out/glossary-term-environment.html b/readthedocs/embed/tests/data/sphinx/source/out/glossary-term-environment.html new file mode 100644 index 00000000000..e6690b53b2d --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/source/out/glossary-term-environment.html @@ -0,0 +1,5 @@ +

A structure where information about all documents under the root is saved, +and used for cross-referencing. The environment is pickled after the +parsing stage, so that successive runs only need to read and parse new and +changed documents.

+
diff --git a/readthedocs/embed/tests/data/sphinx/source/out/index-another-title.html b/readthedocs/embed/tests/data/sphinx/source/out/index-another-title.html new file mode 100644 index 00000000000..69674f848e2 --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/source/out/index-another-title.html @@ -0,0 +1,6 @@ +
+

Another title

+
print("Hello world!")
+
+
+
diff --git a/readthedocs/embed/tests/data/sphinx/source/out/index-sub-sub-title.html b/readthedocs/embed/tests/data/sphinx/source/out/index-sub-sub-title.html new file mode 100644 index 00000000000..bd27b45ae5e --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/source/out/index-sub-sub-title.html @@ -0,0 +1,9 @@ +
+

Sub-sub title

+

Here is my content.

+ +
diff --git a/readthedocs/embed/tests/data/sphinx/source/out/index-subtitle.html b/readthedocs/embed/tests/data/sphinx/source/out/index-subtitle.html new file mode 100644 index 00000000000..5e83d11c068 --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/source/out/index-subtitle.html @@ -0,0 +1,13 @@ +
+

Subtitle

+

See builder for more information.

+
+

Sub-sub title

+

Here is my content.

+ +
+
diff --git a/readthedocs/embed/tests/data/sphinx/source/out/index-title.html b/readthedocs/embed/tests/data/sphinx/source/out/index-title.html new file mode 100644 index 00000000000..f27516db66d --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/source/out/index-title.html @@ -0,0 +1,30 @@ +
+

Title

+

Read the Docs hosts documentation for the open source community.

+

The main documentation for the site is organized into a couple sections:

+
+ +
+
+

Subtitle

+

See builder for more information.

+
+

Sub-sub title

+

Here is my content.

+
    +
  • One

  • +
  • Two

  • +
  • Three

  • +
+
+
+
+

Another title

+
print("Hello world!")
+
+
+
+
diff --git a/readthedocs/embed/tests/data/sphinx/source/usage.rst b/readthedocs/embed/tests/data/sphinx/source/usage.rst new file mode 100644 index 00000000000..f2f9c85ff3a --- /dev/null +++ b/readthedocs/embed/tests/data/sphinx/source/usage.rst @@ -0,0 +1,4 @@ +Usage +===== + +Here are some usage examples. diff --git a/readthedocs/embed/tests/test_api.py b/readthedocs/embed/tests/test_api.py index 0b96429d2c6..139d1dc0519 100644 --- a/readthedocs/embed/tests/test_api.py +++ b/readthedocs/embed/tests/test_api.py @@ -9,6 +9,7 @@ from django_dynamic_fixture import get from pyquery import PyQuery from rest_framework import status +from sphinx.testing.path import path from readthedocs.builds.constants import LATEST from readthedocs.projects.constants import MKDOCS, PUBLIC @@ -17,8 +18,7 @@ data_path = Path(__file__).parent.resolve() / 'data' -@pytest.mark.django_db -class TestEmbedAPI: +class EmbedAPISetUp: @pytest.fixture(autouse=True) def setup_method(self, settings): @@ -57,6 +57,13 @@ def _get_html_content(self, html_file): section_content = [PyQuery(html_file.open().read()).outerHtml()] return section_content + def get(self, client, *args, **kwargs): + return client.get(*args, **kwargs) + + +@pytest.mark.django_db +class BaseTestEmbedAPI(EmbedAPISetUp): + def test_invalid_arguments(self, client): query_params = ( { @@ -72,7 +79,7 @@ def test_invalid_arguments(self, client): api_endpoint = reverse('api_embed') for param in query_params: - r = client.get(api_endpoint, param) + r = self.get(client, api_endpoint, param) assert r.status_code == status.HTTP_400_BAD_REQUEST @mock.patch('readthedocs.embed.views.build_media_storage') @@ -123,7 +130,7 @@ def test_valid_arguments(self, storage_mock, client): ) api_endpoint = reverse('api_embed') for param in query_params: - r = client.get(api_endpoint, param) + r = self.get(client, api_endpoint, param) assert r.status_code == status.HTTP_200_OK @mock.patch('readthedocs.embed.views.build_media_storage') @@ -137,7 +144,8 @@ def test_embed_unknown_section(self, storage_mock, client): html_file=html_file, ) - response = client.get( + response = self.get( + client, reverse('api_embed'), { 'project': self.project.slug, @@ -184,7 +192,8 @@ def test_embed_sphinx(self, storage_mock, section, client): html_file=html_file, ) - response = client.get( + response = self.get( + client, reverse('api_embed'), { 'project': self.project.slug, @@ -221,47 +230,248 @@ def test_embed_sphinx(self, storage_mock, section, client): assert response.status_code == status.HTTP_200_OK assert response.data == expected + @pytest.mark.parametrize( + 'section', + [ + 'getting-started', + 'overview', + 'installation', + 'minimal-example', + # TODO: return just one element for definition lists + 'nel87a', + 'nel87b', + ] + ) @mock.patch('readthedocs.embed.views.build_media_storage') - def test_embed_mkdocs(self, storage_mock, client): - json_file = data_path / 'mkdocs/latest/index.json' - storage_mock.exists.return_value = True + def test_embed_sphinx_bibtex(self, storage_mock, section, client): + json_file = data_path / 'sphinx/bibtex/page.json' + html_file = data_path / 'sphinx/bibtex/page.html' + + self._patch_sphinx_json_file( + storage_mock=storage_mock, + json_file=json_file, + html_file=html_file, + ) + + response = self.get( + client, + reverse('api_embed'), + { + 'project': self.project.slug, + 'version': self.version.slug, + 'section': section, + 'path': 'index.html', + } + ) + + section_content = self._get_html_content( + data_path / f'sphinx/bibtex/page-{section}.html' + ) + + expected = { + 'content': section_content, + 'headers': [ + {'Getting Started': '#'}, + {'Overview': '#overview'}, + {'Installation': '#installation'}, + {'Minimal Example': '#minimal-example'}, + ], + 'url': 'http://project.readthedocs.io/en/latest/index.html', + 'meta': { + 'project': 'project', + 'version': 'latest', + 'doc': 'index', + 'section': section, + }, + } + + assert response.data == expected + + @pytest.mark.parametrize( + 'section', + [ + 'glossary', + 'term-builder', + 'term-configuration-directory', + 'term-directive', + 'term-document-name', + 'term-domain', + 'term-environment', + 'term-extension', + 'term-master-document', + 'term-object', + 'term-RemoveInSphinxXXXWarning', + 'term-role', + 'term-source-directory', + 'term-reStructuredText', + ] + ) + @mock.patch('readthedocs.embed.views.build_media_storage') + def test_embed_sphinx_glossary(self, storage_mock, section, client): + # TODO: render definition lists as a definition list with one element. + json_file = data_path / 'sphinx/glossary/page.json' + html_file = data_path / 'sphinx/glossary/page.html' + + self._patch_sphinx_json_file( + storage_mock=storage_mock, + json_file=json_file, + html_file=html_file, + ) + + response = self.get( + client, + reverse('api_embed'), + { + 'project': self.project.slug, + 'version': self.version.slug, + 'section': section, + 'path': 'index.html', + } + ) + + section_content = self._get_html_content( + data_path / f'sphinx/glossary/page-{section}.html' + ) + + expected = { + 'content': section_content, + 'headers': [ + {'Glossary': '#'}, + ], + 'url': 'http://project.readthedocs.io/en/latest/index.html', + 'meta': { + 'project': 'project', + 'version': 'latest', + 'doc': 'index', + 'section': section, + }, + } + + assert response.status_code == status.HTTP_200_OK + assert response.data == expected + + +class TestEmbedAPI(BaseTestEmbedAPI): + + pass + + +@pytest.mark.proxito +class TestProxiedEmbedAPISphinx(BaseTestEmbedAPI): + + host = 'project.readthedocs.io' + + def get(self, client, *args, **kwargs): + r = client.get(*args, HTTP_HOST=self.host, **kwargs) + return r + + +@pytest.mark.sphinxtest +@pytest.mark.django_db +class TestEmbedAPISphinx(EmbedAPISetUp): + + @pytest.mark.parametrize( + 'section', + [ + 'title', + 'subtitle', + 'sub-sub-title', + 'another-title', + ] + ) + @mock.patch('readthedocs.embed.views.build_media_storage') + def test_embed_sphinx_index(self, storage_mock, section, client, make_app): + srcdir = path(str(data_path / "sphinx/source")) + app = make_app("html", srcdir=srcdir) + app.build() + + json_file = Path(app.outdir).parent / 'json/index.fjson' storage_mock.open.side_effect = self._mock_open( json_file.open().read() ) - self.version.documentation_type = MKDOCS - self.version.save() - - response = client.get( + response = self.get( + client, reverse('api_embed'), { 'project': self.project.slug, 'version': self.version.slug, 'path': 'index.html', - 'section': 'Installation', + 'section': section, } ) + section_content = self._get_html_content( + data_path / f'sphinx/source/out/index-{section}.html' + ) + expected = { - 'content': mock.ANY, # too long to compare here + 'content': section_content, 'headers': [ - {'Overview': 'overview'}, - {'Installation': 'installation'}, - {'Getting Started': 'getting-started'}, - {'Adding pages': 'adding-pages'}, - {'Theming our documentation': 'theming-our-documentation'}, - {'Changing the Favicon Icon': 'changing-the-favicon-icon'}, - {'Building the site': 'building-the-site'}, - {'Other Commands and Options': 'other-commands-and-options'}, - {'Deploying': 'deploying'}, - {'Getting help': 'getting-help'}, + {'Title': '#'}, + {'Subtitle': '#subtitle'}, + {'Sub-sub title': '#sub-sub-title'}, + {'Another title': '#another-title'}, ], 'url': 'http://project.readthedocs.io/en/latest/index.html', 'meta': { 'project': 'project', 'version': 'latest', 'doc': 'index', - 'section': 'Installation', + 'section': section, + }, + } + + assert response.status_code == status.HTTP_200_OK + assert response.data == expected + + @pytest.mark.parametrize( + 'section', + [ + 'glossary', + 'term-builder', + 'term-configuration-directory', + 'term-directive', + 'term-environment', + ] + ) + @mock.patch('readthedocs.embed.views.build_media_storage') + def test_embed_sphinx_glossary(self, storage_mock, section, client, make_app): + srcdir = path(str(data_path / "sphinx/source")) + app = make_app("html", srcdir=srcdir) + app.build() + + json_file = Path(app.outdir).parent / 'json/glossary.fjson' + storage_mock.open.side_effect = self._mock_open( + json_file.open().read() + ) + + response = self.get( + client, + reverse('api_embed'), + { + 'project': self.project.slug, + 'version': self.version.slug, + 'path': 'index.html', + 'section': section, + }, + ) + + section_content = self._get_html_content( + data_path / f'sphinx/source/out/glossary-{section}.html' + ) + + expected = { + 'content': section_content, + 'headers': [ + {'Glossary': '#'}, + ], + 'url': 'http://project.readthedocs.io/en/latest/index.html', + 'meta': { + 'project': 'project', + 'version': 'latest', + 'doc': 'index', + 'section': section, }, } diff --git a/requirements/testing.txt b/requirements/testing.txt index 6c067fc19c3..7869cc58303 100644 --- a/requirements/testing.txt +++ b/requirements/testing.txt @@ -11,6 +11,9 @@ pytest-cov==2.11.1 apipkg==1.5 execnet==1.8.0 +# Sphinx tests +readthedocs-sphinx-ext==2.1.4 + # Mercurial 4.3 and newer require Python 2.7 # Mercurial is actively being ported to Python 3. As of Mercurial 4.3, # some commands work on Python 3. However, Python 3 is not yet a diff --git a/sphinx-tox.ini b/sphinx-tox.ini new file mode 100644 index 00000000000..dbc474737cc --- /dev/null +++ b/sphinx-tox.ini @@ -0,0 +1,30 @@ +[tox] +envlist = sphinx-{18,20,21,22,23,24,30,31,32,33,34,35,latest} + +[testenv] + +install_command = + # Install requirements in two steps to avoid the pip error + # about incompatible versions of sphinx. + /bin/sh -c ' \ + pip install -r {toxinidir}/requirements/testing.txt; \ + pip install $*;' -- {opts} {packages} +deps = + sphinx-18: Sphinx<1.9 + sphinx-20: Sphinx<2.1 + sphinx-21: Sphinx<2.2 + sphinx-22: Sphinx<2.3 + sphinx-23: Sphinx<2.4 + sphinx-24: Sphinx<2.5 + sphinx-30: Sphinx<3.1 + sphinx-31: Sphinx<3.2 + sphinx-32: Sphinx<3.3 + sphinx-33: Sphinx<3.4 + sphinx-34: Sphinx<3.5 + sphinx-35: Sphinx<3.6 + sphinx-latest: --upgrade Sphinx + +setenv = + DJANGO_SETTINGS_MODULE=readthedocs.settings.test +changedir = {toxinidir}/readthedocs +commands = pytest -m sphinxtest {posargs}