1""" 2 test_build 3 ~~~~~~~~~~ 4 5 Test all builders. 6 7 :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. 8 :license: BSD, see LICENSE for details. 9""" 10 11import sys 12from textwrap import dedent 13from unittest import mock 14 15import pytest 16from docutils import nodes 17 18from sphinx.errors import SphinxError 19from sphinx.testing.path import path 20 21 22def request_session_head(url, **kwargs): 23 response = mock.Mock() 24 response.status_code = 200 25 response.url = url 26 return response 27 28 29@pytest.fixture 30def nonascii_srcdir(request, rootdir, sphinx_test_tempdir): 31 # If supported, build in a non-ASCII source dir 32 test_name = '\u65e5\u672c\u8a9e' 33 basedir = sphinx_test_tempdir / request.node.originalname 34 try: 35 srcdir = basedir / test_name 36 if not srcdir.exists(): 37 (rootdir / 'test-root').copytree(srcdir) 38 except UnicodeEncodeError: 39 # Now Python 3.7+ follows PEP-540 and uses utf-8 encoding for filesystem by default. 40 # So this error handling will be no longer used (after dropping python 3.6 support). 41 srcdir = basedir / 'all' 42 if not srcdir.exists(): 43 (rootdir / 'test-root').copytree(srcdir) 44 else: 45 # add a doc with a non-ASCII file name to the source dir 46 (srcdir / (test_name + '.txt')).write_text(dedent(""" 47 nonascii file name page 48 ======================= 49 """)) 50 51 master_doc = srcdir / 'index.txt' 52 master_doc.write_text(master_doc.read_text() + dedent(""" 53 .. toctree:: 54 55 %(test_name)s/%(test_name)s 56 """ % {'test_name': test_name})) 57 return srcdir 58 59 60# note: this test skips building docs for some builders because they have independent testcase. 61# (html, changes, epub, latex, texinfo and manpage) 62@pytest.mark.parametrize( 63 "buildername", 64 ['dirhtml', 'singlehtml', 'text', 'xml', 'pseudoxml', 'linkcheck'], 65) 66@mock.patch('sphinx.builders.linkcheck.requests.head', 67 side_effect=request_session_head) 68@pytest.mark.xfail(sys.platform == 'win32', reason="Not working on windows") 69def test_build_all(requests_head, make_app, nonascii_srcdir, buildername): 70 app = make_app(buildername, srcdir=nonascii_srcdir) 71 app.build() 72 73 74def test_master_doc_not_found(tempdir, make_app): 75 (tempdir / 'conf.py').write_text('') 76 assert tempdir.listdir() == ['conf.py'] 77 78 app = make_app('dummy', srcdir=tempdir) 79 with pytest.raises(SphinxError): 80 app.builder.build_all() # no index.rst 81 82 83@pytest.mark.sphinx(buildername='text', testroot='circular') 84def test_circular_toctree(app, status, warning): 85 app.builder.build_all() 86 warnings = warning.getvalue() 87 assert ( 88 'circular toctree references detected, ignoring: ' 89 'sub <- index <- sub') in warnings 90 assert ( 91 'circular toctree references detected, ignoring: ' 92 'index <- sub <- index') in warnings 93 94 95@pytest.mark.sphinx(buildername='text', testroot='numbered-circular') 96def test_numbered_circular_toctree(app, status, warning): 97 app.builder.build_all() 98 warnings = warning.getvalue() 99 assert ( 100 'circular toctree references detected, ignoring: ' 101 'sub <- index <- sub') in warnings 102 assert ( 103 'circular toctree references detected, ignoring: ' 104 'index <- sub <- index') in warnings 105 106 107@pytest.mark.sphinx(buildername='dummy', testroot='images') 108def test_image_glob(app, status, warning): 109 app.builder.build_all() 110 111 # index.rst 112 doctree = app.env.get_doctree('index') 113 114 assert isinstance(doctree[0][1], nodes.image) 115 assert doctree[0][1]['candidates'] == {'*': 'rimg.png'} 116 assert doctree[0][1]['uri'] == 'rimg.png' 117 118 assert isinstance(doctree[0][2], nodes.figure) 119 assert isinstance(doctree[0][2][0], nodes.image) 120 assert doctree[0][2][0]['candidates'] == {'*': 'rimg.png'} 121 assert doctree[0][2][0]['uri'] == 'rimg.png' 122 123 assert isinstance(doctree[0][3], nodes.image) 124 assert doctree[0][3]['candidates'] == {'application/pdf': 'img.pdf', 125 'image/gif': 'img.gif', 126 'image/png': 'img.png'} 127 assert doctree[0][3]['uri'] == 'img.*' 128 129 assert isinstance(doctree[0][4], nodes.figure) 130 assert isinstance(doctree[0][4][0], nodes.image) 131 assert doctree[0][4][0]['candidates'] == {'application/pdf': 'img.pdf', 132 'image/gif': 'img.gif', 133 'image/png': 'img.png'} 134 assert doctree[0][4][0]['uri'] == 'img.*' 135 136 # subdir/index.rst 137 doctree = app.env.get_doctree('subdir/index') 138 139 assert isinstance(doctree[0][1], nodes.image) 140 sub = path('subdir') 141 assert doctree[0][1]['candidates'] == {'*': sub / 'rimg.png'} 142 assert doctree[0][1]['uri'] == sub / 'rimg.png' 143 144 assert isinstance(doctree[0][2], nodes.image) 145 assert doctree[0][2]['candidates'] == {'application/pdf': 'subdir/svgimg.pdf', 146 'image/svg+xml': 'subdir/svgimg.svg'} 147 assert doctree[0][2]['uri'] == sub / 'svgimg.*' 148 149 assert isinstance(doctree[0][3], nodes.figure) 150 assert isinstance(doctree[0][3][0], nodes.image) 151 assert doctree[0][3][0]['candidates'] == {'application/pdf': 'subdir/svgimg.pdf', 152 'image/svg+xml': 'subdir/svgimg.svg'} 153 assert doctree[0][3][0]['uri'] == sub / 'svgimg.*' 154