1""" 2 test_setup_command 3 ~~~~~~~~~~~~~~~~~~~ 4 5 Test setup_command for distutils. 6 7 :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. 8 :license: BSD, see LICENSE for details. 9""" 10 11import os 12import subprocess 13import sys 14from collections import namedtuple 15from textwrap import dedent 16 17import pytest 18 19import sphinx 20from sphinx.util.osutil import cd 21 22 23@pytest.fixture 24def setup_command(request, tempdir, rootdir): 25 """ 26 Run `setup.py build_sphinx` with args and kwargs, 27 pass it to the test and clean up properly. 28 """ 29 if hasattr(request.node, 'get_closest_marker'): # pytest-3.6.0 or newer 30 marker = request.node.get_closest_marker('setup_command') 31 else: 32 marker = request.node.get_marker('setup_command') 33 args = marker.args if marker else [] 34 35 pkgrootdir = tempdir / 'test-setup' 36 (rootdir / 'test-setup').copytree(pkgrootdir) 37 38 with cd(pkgrootdir): 39 pythonpath = os.path.dirname(os.path.dirname(sphinx.__file__)) 40 if os.getenv('PYTHONPATH'): 41 pythonpath = os.getenv('PYTHONPATH') + os.pathsep + pythonpath 42 command = [sys.executable, 'setup.py', 'build_sphinx'] 43 command.extend(args) 44 45 proc = subprocess.Popen( 46 command, 47 env=dict(os.environ, PYTHONPATH=pythonpath), 48 stdout=subprocess.PIPE, 49 stderr=subprocess.PIPE) 50 yield namedtuple('setup', 'pkgroot,proc')(pkgrootdir, proc) 51 52 53def test_build_sphinx(setup_command): 54 proc = setup_command.proc 55 out, err = proc.communicate() 56 print(out.decode()) 57 print(err.decode()) 58 assert proc.returncode == 0 59 60 61@pytest.mark.setup_command('-b', 'html,man') 62def test_build_sphinx_multiple_builders(setup_command): 63 proc = setup_command.proc 64 out, err = proc.communicate() 65 print(out.decode()) 66 print(err.decode()) 67 assert proc.returncode == 0 68 69 70@pytest.mark.setup_command('-b', 'html,bar') 71def test_build_sphinx_multiple_invalid_builders(setup_command): 72 proc = setup_command.proc 73 out, err = proc.communicate() 74 print(out.decode()) 75 print(err.decode()) 76 assert proc.returncode == 1 77 78 79@pytest.fixture 80def nonascii_srcdir(request, setup_command): 81 mb_name = '\u65e5\u672c\u8a9e' 82 srcdir = (setup_command.pkgroot / 'doc') 83 try: 84 (srcdir / mb_name).makedirs() 85 except UnicodeEncodeError: 86 from sphinx.testing.path import FILESYSTEMENCODING 87 pytest.skip( 88 'non-ASCII filename not supported on this filesystem encoding: ' 89 '%s' % FILESYSTEMENCODING) 90 91 (srcdir / mb_name / (mb_name + '.txt')).write_text(dedent(""" 92 multi byte file name page 93 ========================== 94 """)) 95 96 master_doc = srcdir / 'index.txt' 97 master_doc.write_bytes((master_doc.read_text() + dedent(""" 98 .. toctree:: 99 100 %(mb_name)s/%(mb_name)s 101 """ % locals())).encode()) 102 103 104@pytest.mark.usefixtures('nonascii_srcdir') 105def test_build_sphinx_with_nonascii_path(setup_command): 106 proc = setup_command.proc 107 out, err = proc.communicate() 108 print(out.decode()) 109 print(err.decode()) 110 assert proc.returncode == 0 111 112 113@pytest.mark.setup_command('-b', 'linkcheck') 114def test_build_sphinx_return_nonzero_status(setup_command): 115 srcdir = (setup_command.pkgroot / 'doc') 116 (srcdir / 'contents.txt').write_text( 117 'http://localhost.unexistentdomain/index.html') 118 proc = setup_command.proc 119 out, err = proc.communicate() 120 print(out.decode()) 121 print(err.decode()) 122 assert proc.returncode != 0, 'expect non-zero status for setup.py' 123 124 125def test_build_sphinx_warning_return_zero_status(setup_command): 126 srcdir = (setup_command.pkgroot / 'doc') 127 (srcdir / 'contents.txt').write_text( 128 'See :ref:`unexisting-reference-label`') 129 proc = setup_command.proc 130 out, err = proc.communicate() 131 print(out.decode()) 132 print(err.decode()) 133 assert proc.returncode == 0 134 135 136@pytest.mark.setup_command('--warning-is-error') 137def test_build_sphinx_warning_is_error_return_nonzero_status(setup_command): 138 srcdir = (setup_command.pkgroot / 'doc') 139 (srcdir / 'contents.txt').write_text( 140 'See :ref:`unexisting-reference-label`') 141 proc = setup_command.proc 142 out, err = proc.communicate() 143 print(out.decode()) 144 print(err.decode()) 145 assert proc.returncode != 0, 'expect non-zero status for setup.py' 146