Skip to content
Snippets Groups Projects
Commit 155bb164 authored by Sandro Tosi's avatar Sandro Tosi
Browse files

New upstream version 0.2.3

parent 46a2a1f2
No related branches found
Tags upstream/0.2.3
No related merge requests found
......@@ -10,7 +10,7 @@ sphinxtesters
The sphinxtesters package, including all examples, code snippets and attached
documentation is covered by the 2-clause BSD license.
Copyright (c) 2017, Matthew Brett
Copyright (c) 2017-2019, Matthew Brett
All rights reserved.
Redistribution and use in source and binary forms, with or without
......
Metadata-Version: 2.1
Name: sphinxtesters
Version: 0.2.1
Version: 0.2.3
Summary: Utilities for testing Sphinx extensions
Home-page: http://github.com/matthew-brett/sphinxtesters
Author: Matthew Brett
......
Metadata-Version: 2.1
Name: sphinxtesters
Version: 0.2.1
Version: 0.2.3
Summary: Utilities for testing Sphinx extensions
Home-page: http://github.com/matthew-brett/sphinxtesters
Author: Matthew Brett
......
......@@ -8,11 +8,11 @@ import json
version_json = '''
{
"date": "2018-08-22T12:02:53+0100",
"date": "2019-08-07T14:23:13+0100",
"dirty": false,
"error": null,
"full-revisionid": "42e8318b246e6a2c4ff96b826e17ddf17a176b1d",
"version": "0.2.1"
"full-revisionid": "35da3ded573ca3cb95027d77fcf1caef67b7f6ba",
"version": "0.2.3"
}
''' # END VERSION_JSON
......
......@@ -15,12 +15,12 @@ from docutils import nodes
from docutils.parsers.rst import directives, roles
import sphinx
from sphinx.application import Sphinx
from sphinx.domains.std import StandardDomain
fresh_roles = copy(roles._roles)
fresh_directives = copy(directives._directives)
fresh_visitor_dict = nodes.GenericNodeVisitor.__dict__.copy()
fresh_std_domain_init_labels = StandardDomain.initial_data['labels'].copy()
@contextmanager
......@@ -35,40 +35,67 @@ def in_dir(path):
os.chdir(cwd)
def reset_class(cls, original_dict):
for key in list(cls.__dict__):
if key not in original_dict:
delattr(cls, key)
else:
setattr(cls, key, original_dict[key])
def _visit_depart_attrs(cls):
return [attr for attr in dir(cls)
if attr.startswith('visit_') or attr.startswith('depart_')]
def _get_visit_depart(cls):
return {attr: getattr(cls, attr) for attr in _visit_depart_attrs(cls)}
def _set_visit_depart(cls, to_set):
for attr in _visit_depart_attrs(cls):
if attr not in to_set:
delattr(cls, attr)
for attr, method in to_set.items():
setattr(cls, attr, method)
class TestApp(Sphinx):
# Default index filename.
index_root = ('contents' if sphinx.version_info[0] < 2 else 'index')
def __init__(self, *args, **kwargs):
self._set_cache()
with self.own_namespace():
super(TestApp, self).__init__(*args, **kwargs)
def _set_cache(self):
""" Initialize namespace from current state of docutils objects
"""
self._global_cache = dict(
directives=copy(fresh_directives),
roles=copy(fresh_roles),
visitor_dict = copy(fresh_visitor_dict),
visit_depart = _get_visit_depart(nodes.GenericNodeVisitor),
std_domain_init_labels = copy(fresh_std_domain_init_labels))
@contextmanager
def own_namespace(self):
""" Set docutils namespace for builds """
""" Set docutils namespace for builds
Sphinx uses global docutils objects. We need to isolate the effects of
this sphinx application from others.
* Store current state of docutils objects.
* Take stored state of these objects from cache attached to `self` and
put into docutils.
* Yield to user of context manager.
* Make sure any changes in state during yield go back into cache for
future use by `self`.
* Restore initial state of docutils objects.
"""
cache = self._global_cache
_directives = directives._directives
_roles = roles._roles
_visitor_dict = nodes.GenericNodeVisitor.__dict__.copy()
GNV = nodes.GenericNodeVisitor
_visit_depart = _get_visit_depart(GNV)
_std_domain_init_labels = StandardDomain.initial_data['labels']
directives._directives = cache['directives']
roles._roles = cache['roles']
reset_class(nodes.GenericNodeVisitor, cache['visitor_dict'])
_set_visit_depart(GNV, cache['visit_depart'])
StandardDomain.initial_data['labels'] = cache['std_domain_init_labels']
try:
yield
......@@ -76,7 +103,8 @@ class TestApp(Sphinx):
# Reset docutils, Sphinx global state
directives._directives = _directives
roles._roles = _roles
reset_class(nodes.GenericNodeVisitor, _visitor_dict)
cache['visit_depart'] = _get_visit_depart(GNV)
_set_visit_depart(GNV, _visit_depart)
StandardDomain.initial_data['labels'] = _std_domain_init_labels
def build(self, *args, **kwargs):
......@@ -109,8 +137,13 @@ class TempApp(TestApp):
self.tmp_dir = tmp_dir = mkdtemp()
with open(pjoin(tmp_dir, 'conf.py'), 'wt') as fobj:
fobj.write(conf_text)
with open(pjoin(tmp_dir, 'contents.rst'), 'wt') as fobj:
# Write given RST text to master document.
config = {}
exec(conf_text, {}, config)
master_doc = config.get('master_doc', self.index_root)
with open(pjoin(tmp_dir, master_doc + '.rst'), 'wt') as fobj:
fobj.write(rst_text)
# Initialize cache of docutils global vars.
self._set_cache()
with self.own_namespace():
TestApp.__init__(self,
......@@ -164,6 +197,9 @@ class PageBuilder(object):
# the source directory. Can be None (no pages copied).
page_source_template = None
# Name of default contents file (depends on Sphinx version)
index_root = TestApp.index_root
@classmethod
def setup_class(cls):
cls.build_error = None
......@@ -332,7 +368,7 @@ class SourcesBuilder(PageBuilder):
@classmethod
def _get_master(cls):
""" Return filename of master page for project """
master_doc = cls.get_conf_vars().get('master_doc', 'contents')
master_doc = cls.get_conf_vars().get('master_doc', cls.index_root)
return pjoin(cls.page_source, master_doc + '.rst')
@classmethod
......
......@@ -22,14 +22,16 @@ class TestPageBuilder(PageBuilder):
def modify_source(cls):
# Make an empty conf.py and contents.rst file with text
cls.append_conf('')
with open(pjoin(cls.page_source, 'contents.rst'), 'wt') as fobj:
index_fname = pjoin(cls.page_source, cls.index_root + '.rst')
with open(index_fname, 'wt') as fobj:
fobj.write('some text')
def test_build(self):
assert isdir(self.out_dir)
assert isdir(self.doctree_dir)
assert isfile(pjoin(self.out_dir, 'contents.html'))
doctree = self.get_doctree('contents')
index_fname = pjoin(self.out_dir, self.index_root + '.html')
assert isfile(index_fname)
doctree = self.get_doctree(self.index_root)
assert doctree.document.astext() == 'some text'
......@@ -43,7 +45,8 @@ class TestMaster(PageBuilder):
fobj.write('more text')
def test_build(self):
assert not isfile(pjoin(self.out_dir, 'contents.html'))
index_fname = pjoin(self.out_dir, self.index_root + '.html')
assert not isfile(index_fname)
assert isfile(pjoin(self.out_dir, 'foo.html'))
doctree = self.get_doctree('foo')
assert doctree.document.astext() == 'more text'
......
......@@ -52,7 +52,8 @@ class CheckSources(SourcesBuilder):
def test_structure(self):
assert isdir(self.out_dir)
assert isdir(self.doctree_dir)
assert exists(pjoin(self.doctree_dir, 'contents.doctree'))
index_fname = pjoin(self.doctree_dir, self.index_root + '.doctree')
assert exists(index_fname)
for page_name in self.rst_sources:
assert exists(pjoin(self.doctree_dir,
page_name + '.doctree'))
......@@ -144,7 +145,7 @@ class TestNoTocTree(SourcesBuilder):
rst_sources = dict(a_page=A_PAGE)
def test_master(self):
doctree = self.get_doctree('contents')
doctree = self.get_doctree(self.index_root)
assert doctree.document.astext() == ''
assert len(doctree.document.children) == 0
......@@ -153,7 +154,7 @@ class TestTocTree(TestNoTocTree):
# Test toctree write to master_doc
toctree_pages = ['a_page']
master_name = 'contents'
master_name = TestNoTocTree.index_root
def test_master(self):
doctree = self.get_doctree(self.master_name)
......
......@@ -17,7 +17,21 @@ def test_tempapp():
app = TempApp(rst_txt)
app.build()
app_path = app.tmp_dir
assert_contents_equal(pjoin(app_path, 'contents.rst'), rst_txt)
index_fname = pjoin(app_path, app.index_root + '.rst')
assert_contents_equal(index_fname, rst_txt)
assert_contents_equal(pjoin(app_path, 'conf.py'), '')
app.cleanup()
assert not isdir(app_path)
def test_tempapp_master_doc():
rst_txt = 'A simple page'
conf_txt = 'master_doc = "my_master"'
app = TempApp(rst_txt, conf_txt)
app.build()
app_path = app.tmp_dir
index_fname = pjoin(app_path, 'my_master.rst')
assert_contents_equal(index_fname, rst_txt)
assert_contents_equal(pjoin(app_path, 'conf.py'), conf_txt)
app.cleanup()
assert not isdir(app_path)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment