sphinx/tests/test_quickstart.py

274 lines
7.5 KiB
Python
Raw Normal View History

2022-02-19 21:05:56 -06:00
"""Test the sphinx.quickstart module."""
import time
from collections.abc import Callable
from io import StringIO
2021-06-11 08:06:03 -05:00
from os import path
from pathlib import Path
from typing import Any
2018-02-19 07:39:14 -06:00
import pytest
from sphinx.cmd import quickstart as qs
from sphinx.testing.util import SphinxTestApp
from sphinx.util.console import coloron, nocolor
warnfile = StringIO()
def setup_module():
nocolor()
def mock_input(
answers: dict[str, str], needanswer: bool = False
) -> Callable[[str], str]:
called = set()
def input_(prompt: str) -> str:
if prompt in called:
2024-08-11 08:58:56 -05:00
raise AssertionError(
'answer for %r missing and no default present' % prompt
)
called.add(prompt)
2024-10-18 19:16:07 -05:00
for question, answer in answers.items():
if prompt.startswith(qs.PROMPT_PREFIX + question):
2024-10-18 19:16:07 -05:00
return answer
if needanswer:
raise AssertionError('answer for %r missing' % prompt)
return ''
2024-08-11 08:58:56 -05:00
return input_
real_input: Callable[[str], str] = input
def teardown_module():
qs.term_input = real_input
coloron()
def test_do_prompt():
answers = {
'Q2': 'v2',
'Q3': 'v3',
'Q4': 'yes',
'Q5': 'no',
'Q6': 'foo',
}
qs.term_input = mock_input(answers)
assert qs.do_prompt('Q1', default='v1') == 'v1'
assert qs.do_prompt('Q3', default='v3_default') == 'v3'
assert qs.do_prompt('Q2') == 'v2'
assert qs.do_prompt('Q4', validator=qs.boolean) is True
assert qs.do_prompt('Q5', validator=qs.boolean) is False
with pytest.raises(AssertionError):
qs.do_prompt('Q6', validator=qs.boolean)
def test_do_prompt_inputstrip():
answers = {
'Q1': 'Y',
'Q2': ' Yes ',
'Q3': 'N',
'Q4': 'N ',
}
qs.term_input = mock_input(answers)
assert qs.do_prompt('Q1') == 'Y'
assert qs.do_prompt('Q2') == 'Yes'
assert qs.do_prompt('Q3') == 'N'
assert qs.do_prompt('Q4') == 'N'
2009-01-04 15:33:00 -06:00
def test_do_prompt_with_nonascii():
answers = {
2018-12-15 08:02:28 -06:00
'Q1': '\u30c9\u30a4\u30c4',
}
qs.term_input = mock_input(answers)
result = qs.do_prompt('Q1', default='\u65e5\u672c')
2018-12-15 08:02:28 -06:00
assert result == '\u30c9\u30a4\u30c4'
def test_quickstart_defaults(tmp_path):
answers = {
'Root path': str(tmp_path),
'Project name': 'Sphinx Test',
'Author name': 'Georg Brandl',
'Project version': '0.1',
}
qs.term_input = mock_input(answers)
d: dict[str, Any] = {}
qs.ask_user(d)
qs.generate(d)
conffile = tmp_path / 'conf.py'
assert conffile.is_file()
ns: dict[str, Any] = {}
2022-12-29 17:46:04 -06:00
exec(conffile.read_text(encoding='utf8'), ns) # NoQA: S102
assert ns['extensions'] == []
2009-01-04 15:33:00 -06:00
assert ns['templates_path'] == ['_templates']
assert ns['project'] == 'Sphinx Test'
assert ns['copyright'] == '%s, Georg Brandl' % time.strftime('%Y')
assert ns['version'] == '0.1'
assert ns['release'] == '0.1'
2009-01-04 15:33:00 -06:00
assert ns['html_static_path'] == ['_static']
assert (tmp_path / '_static').is_dir()
assert (tmp_path / '_templates').is_dir()
assert (tmp_path / 'index.rst').is_file()
assert (tmp_path / 'Makefile').is_file()
assert (tmp_path / 'make.bat').is_file()
2009-01-04 15:33:00 -06:00
2021-06-14 00:57:50 -05:00
def test_quickstart_all_answers(tmp_path):
answers = {
'Root path': str(tmp_path),
'Separate source and build': 'y',
2009-01-04 15:33:00 -06:00
'Name prefix for templates': '.',
'Project name': 'STASI™',
'Author name': "Wolfgang Schäuble & G'Beckstein",
Merged revisions 65283,65303,65316-65317,65372-65375,65377,65380,65483-65485,65494 via svnmerge from svn+ssh://pythondev@svn.python.org/doctools/branches/0.4.x ........ r65283 | georg.brandl | 2008-07-29 10:07:26 +0000 (Tue, 29 Jul 2008) | 2 lines Update ez_setup.py. ........ r65303 | benjamin.peterson | 2008-07-30 12:35:34 +0000 (Wed, 30 Jul 2008) | 1 line add a with_testapp decorator for test functions that passes the TestApp instance in a cleans up after it ........ r65316 | benjamin.peterson | 2008-07-30 23:12:07 +0000 (Wed, 30 Jul 2008) | 1 line make the app for test_markup global to the module ........ r65317 | benjamin.peterson | 2008-07-30 23:31:29 +0000 (Wed, 30 Jul 2008) | 1 line make TestApp.cleanup more aggressive ........ r65372 | georg.brandl | 2008-08-01 19:11:22 +0000 (Fri, 01 Aug 2008) | 2 lines Add more tests, fix a few bugs in image handling. ........ r65373 | georg.brandl | 2008-08-01 19:28:33 +0000 (Fri, 01 Aug 2008) | 2 lines Fix oversight. ........ r65374 | benjamin.peterson | 2008-08-01 19:36:32 +0000 (Fri, 01 Aug 2008) | 1 line fix one broken test ........ r65375 | georg.brandl | 2008-08-01 19:41:11 +0000 (Fri, 01 Aug 2008) | 2 lines Fix the handling of non-ASCII input in quickstart. ........ r65377 | georg.brandl | 2008-08-01 19:48:24 +0000 (Fri, 01 Aug 2008) | 2 lines Allow REs in markup checks. ........ r65380 | georg.brandl | 2008-08-01 20:31:18 +0000 (Fri, 01 Aug 2008) | 2 lines Don't rely on mtimes being different for changed files. ........ r65483 | georg.brandl | 2008-08-04 09:01:40 +0000 (Mon, 04 Aug 2008) | 4 lines Add an "encoding" option to literalinclude. Add tests for include directives. ........ r65484 | georg.brandl | 2008-08-04 09:11:17 +0000 (Mon, 04 Aug 2008) | 2 lines Add changelog entry. ........ r65485 | georg.brandl | 2008-08-04 09:21:58 +0000 (Mon, 04 Aug 2008) | 2 lines Fix markup. ........ r65494 | georg.brandl | 2008-08-04 16:34:59 +0000 (Mon, 04 Aug 2008) | 2 lines Correctly use HTML file suffix in templates. ........
2008-08-04 12:01:15 -05:00
'Project version': '2.0',
'Project release': '2.0.1',
'Project language': 'de',
'Source file suffix': '.txt',
'Name of your master document': 'contents',
'autodoc': 'y',
'doctest': 'yes',
2008-08-04 14:39:05 -05:00
'intersphinx': 'no',
'todo': 'y',
'coverage': 'no',
'imgmath': 'N',
'mathjax': 'no',
2009-02-20 03:45:24 -06:00
'ifconfig': 'no',
2010-01-17 10:02:46 -06:00
'viewcode': 'no',
'githubpages': 'no',
'Create Makefile': 'no',
2009-01-04 15:33:00 -06:00
'Create Windows command file': 'no',
2010-02-21 04:50:08 -06:00
'Do you want to use the epub builder': 'yes',
}
qs.term_input = mock_input(answers, needanswer=True)
d: dict[str, Any] = {}
qs.ask_user(d)
qs.generate(d)
conffile = tmp_path / 'source' / 'conf.py'
assert conffile.is_file()
ns: dict[str, Any] = {}
2022-12-29 17:46:04 -06:00
exec(conffile.read_text(encoding='utf8'), ns) # NoQA: S102
assert ns['extensions'] == [
2024-08-11 08:58:56 -05:00
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.todo',
]
2009-01-04 15:33:00 -06:00
assert ns['templates_path'] == ['.templates']
2015-03-15 10:27:12 -05:00
assert ns['source_suffix'] == '.txt'
assert ns['root_doc'] == 'contents'
2018-12-15 08:02:28 -06:00
assert ns['project'] == 'STASI™'
2024-08-11 08:58:56 -05:00
assert ns['copyright'] == "%s, Wolfgang Schäuble & G'Beckstein" % time.strftime(
'%Y'
)
Merged revisions 65283,65303,65316-65317,65372-65375,65377,65380,65483-65485,65494 via svnmerge from svn+ssh://pythondev@svn.python.org/doctools/branches/0.4.x ........ r65283 | georg.brandl | 2008-07-29 10:07:26 +0000 (Tue, 29 Jul 2008) | 2 lines Update ez_setup.py. ........ r65303 | benjamin.peterson | 2008-07-30 12:35:34 +0000 (Wed, 30 Jul 2008) | 1 line add a with_testapp decorator for test functions that passes the TestApp instance in a cleans up after it ........ r65316 | benjamin.peterson | 2008-07-30 23:12:07 +0000 (Wed, 30 Jul 2008) | 1 line make the app for test_markup global to the module ........ r65317 | benjamin.peterson | 2008-07-30 23:31:29 +0000 (Wed, 30 Jul 2008) | 1 line make TestApp.cleanup more aggressive ........ r65372 | georg.brandl | 2008-08-01 19:11:22 +0000 (Fri, 01 Aug 2008) | 2 lines Add more tests, fix a few bugs in image handling. ........ r65373 | georg.brandl | 2008-08-01 19:28:33 +0000 (Fri, 01 Aug 2008) | 2 lines Fix oversight. ........ r65374 | benjamin.peterson | 2008-08-01 19:36:32 +0000 (Fri, 01 Aug 2008) | 1 line fix one broken test ........ r65375 | georg.brandl | 2008-08-01 19:41:11 +0000 (Fri, 01 Aug 2008) | 2 lines Fix the handling of non-ASCII input in quickstart. ........ r65377 | georg.brandl | 2008-08-01 19:48:24 +0000 (Fri, 01 Aug 2008) | 2 lines Allow REs in markup checks. ........ r65380 | georg.brandl | 2008-08-01 20:31:18 +0000 (Fri, 01 Aug 2008) | 2 lines Don't rely on mtimes being different for changed files. ........ r65483 | georg.brandl | 2008-08-04 09:01:40 +0000 (Mon, 04 Aug 2008) | 4 lines Add an "encoding" option to literalinclude. Add tests for include directives. ........ r65484 | georg.brandl | 2008-08-04 09:11:17 +0000 (Mon, 04 Aug 2008) | 2 lines Add changelog entry. ........ r65485 | georg.brandl | 2008-08-04 09:21:58 +0000 (Mon, 04 Aug 2008) | 2 lines Fix markup. ........ r65494 | georg.brandl | 2008-08-04 16:34:59 +0000 (Mon, 04 Aug 2008) | 2 lines Correctly use HTML file suffix in templates. ........
2008-08-04 12:01:15 -05:00
assert ns['version'] == '2.0'
assert ns['release'] == '2.0.1'
assert ns['todo_include_todos'] is True
2009-01-04 15:33:00 -06:00
assert ns['html_static_path'] == ['.static']
assert (tmp_path / 'build').is_dir()
assert (tmp_path / 'source' / '.static').is_dir()
assert (tmp_path / 'source' / '.templates').is_dir()
assert (tmp_path / 'source' / 'contents.txt').is_file()
def test_generated_files_eol(tmp_path):
answers = {
'Root path': str(tmp_path),
'Project name': 'Sphinx Test',
'Author name': 'Georg Brandl',
'Project version': '0.1',
}
qs.term_input = mock_input(answers)
d: dict[str, Any] = {}
qs.ask_user(d)
qs.generate(d)
def assert_eol(filename: Path, eol: str) -> None:
2020-01-31 20:58:51 -06:00
content = filename.read_bytes().decode()
2024-08-11 08:58:56 -05:00
assert all(l[-len(eol) :] == eol for l in content.splitlines(keepends=True))
assert_eol(tmp_path / 'make.bat', '\r\n')
assert_eol(tmp_path / 'Makefile', '\n')
def test_quickstart_and_build(tmp_path):
answers = {
'Root path': str(tmp_path),
2018-12-15 08:02:28 -06:00
'Project name': 'Fullwidth characters: \u30c9\u30a4\u30c4',
'Author name': 'Georg Brandl',
'Project version': '0.1',
}
qs.term_input = mock_input(answers)
d: dict[str, Any] = {}
qs.ask_user(d)
qs.generate(d)
app = SphinxTestApp('html', srcdir=tmp_path, warning=warnfile)
2024-01-16 20:38:46 -06:00
app.build(force_all=True)
app.cleanup()
warnings = warnfile.getvalue()
assert not warnings
def test_default_filename(tmp_path):
answers = {
'Root path': str(tmp_path),
2018-12-15 08:02:28 -06:00
'Project name': '\u30c9\u30a4\u30c4', # Fullwidth characters only
'Author name': 'Georg Brandl',
'Project version': '0.1',
}
qs.term_input = mock_input(answers)
d: dict[str, Any] = {}
qs.ask_user(d)
qs.generate(d)
conffile = tmp_path / 'conf.py'
assert conffile.is_file()
ns: dict[str, Any] = {}
2022-12-29 17:46:04 -06:00
exec(conffile.read_text(encoding='utf8'), ns) # NoQA: S102
def test_extensions(tmp_path):
2024-08-11 08:58:56 -05:00
qs.main([
'-q',
'-p',
'project_name',
'-a',
'author',
'--extensions',
'foo,bar,baz',
str(tmp_path),
])
conffile = tmp_path / 'conf.py'
assert conffile.is_file()
ns: dict[str, Any] = {}
2022-12-29 17:46:04 -06:00
exec(conffile.read_text(encoding='utf8'), ns) # NoQA: S102
assert ns['extensions'] == ['foo', 'bar', 'baz']
2021-06-11 08:06:03 -05:00
2021-06-14 00:57:50 -05:00
2021-06-14 01:02:28 -05:00
def test_exits_when_existing_confpy(monkeypatch):
# The code detects existing conf.py with path.is_file()
2021-06-14 01:02:28 -05:00
# so we mock it as True with pytest's monkeypatch
2021-06-11 08:06:03 -05:00
def mock_isfile(path):
return True
2024-08-11 08:58:56 -05:00
2021-06-11 08:06:03 -05:00
monkeypatch.setattr(path, 'isfile', mock_isfile)
2021-06-14 00:57:50 -05:00
2021-06-14 01:02:28 -05:00
qs.term_input = mock_input({
2023-02-17 16:11:14 -06:00
'Please enter a new root path (or just Enter to exit)': '',
2021-06-14 01:02:28 -05:00
})
d: dict[str, Any] = {}
2021-06-11 08:06:03 -05:00
with pytest.raises(SystemExit):
qs.ask_user(d)