diff options
| author | shimizukawa <shimizukawa@gmail.com> | 2012-12-10 10:18:32 +0900 |
|---|---|---|
| committer | shimizukawa <shimizukawa@gmail.com> | 2012-12-10 10:18:32 +0900 |
| commit | d45dcfbd7e5add4495a7e31ee53e672ee180d534 (patch) | |
| tree | e3ccbee28f06bfccb66ab2c54cb3b1648409e704 /tests | |
| parent | 207e12471f451fee53a95ca6918c93abfef3a632 (diff) | |
| parent | 5818df7941b73abecdb1b399fee7956ea283d698 (diff) | |
| download | sphinx-d45dcfbd7e5add4495a7e31ee53e672ee180d534.tar.gz | |
merge heads
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/root/autodoc.txt | 13 | ||||
| -rw-r--r-- | tests/root/conf.py | 23 | ||||
| -rw-r--r-- | tests/root/contents.txt | 2 | ||||
| -rw-r--r-- | tests/root/i18n/external_links.po | 32 | ||||
| -rw-r--r-- | tests/root/i18n/external_links.txt | 13 | ||||
| -rw-r--r-- | tests/root/i18n/footnote.po | 33 | ||||
| -rw-r--r-- | tests/root/i18n/footnote.txt | 11 | ||||
| -rw-r--r-- | tests/root/i18n/index.txt | 7 | ||||
| -rw-r--r-- | tests/root/i18n/refs_inconsistency.po | 39 | ||||
| -rw-r--r-- | tests/root/i18n/refs_inconsistency.txt | 13 | ||||
| -rw-r--r-- | tests/root/only.txt | 203 | ||||
| -rwxr-xr-x | tests/run.py | 15 | ||||
| -rw-r--r-- | tests/test_application.py | 21 | ||||
| -rw-r--r-- | tests/test_autodoc.py | 58 | ||||
| -rw-r--r-- | tests/test_build.py | 8 | ||||
| -rw-r--r-- | tests/test_build_html.py | 7 | ||||
| -rw-r--r-- | tests/test_build_latex.py | 3 | ||||
| -rw-r--r-- | tests/test_build_texinfo.py | 3 | ||||
| -rw-r--r-- | tests/test_cpp_domain.py | 29 | ||||
| -rw-r--r-- | tests/test_env.py | 1 | ||||
| -rw-r--r-- | tests/test_intl.py | 162 | ||||
| -rw-r--r-- | tests/test_linkcode.py | 28 | ||||
| -rw-r--r-- | tests/test_only_directive.py | 61 | ||||
| -rw-r--r-- | tests/test_quickstart.py | 19 | ||||
| -rw-r--r-- | tests/util.py | 2 |
25 files changed, 775 insertions, 31 deletions
diff --git a/tests/root/autodoc.txt b/tests/root/autodoc.txt index 5c03f947..d4b3404c 100644 --- a/tests/root/autodoc.txt +++ b/tests/root/autodoc.txt @@ -32,3 +32,16 @@ Just testing a few autodoc possibilities... :noindex: .. autoclass:: MarkupError + + +.. currentmodule:: test_autodoc + +.. autoclass:: InstAttCls + :members: + + All members (5 total) + +.. autoclass:: InstAttCls + :members: ca1, ia1 + + Specific members (2 total) diff --git a/tests/root/conf.py b/tests/root/conf.py index b97ddfcc..a3ebeec7 100644 --- a/tests/root/conf.py +++ b/tests/root/conf.py @@ -3,6 +3,7 @@ import sys, os sys.path.append(os.path.abspath('.')) +sys.path.append(os.path.abspath('..')) extensions = ['sphinx.ext.autodoc', 'sphinx.ext.jsmath', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.autosummary', @@ -67,6 +68,28 @@ extlinks = {'issue': ('http://bugs.python.org/issue%s', 'issue '), # modify tags from conf.py tags.add('confpytag') +# -- linkcode + +if 'test_linkcode' in tags: + import glob + + extensions.remove('sphinx.ext.viewcode') + extensions.append('sphinx.ext.linkcode') + + exclude_patterns.extend(glob.glob('*.txt') + glob.glob('*/*.txt')) + exclude_patterns.remove('contents.txt') + exclude_patterns.remove('objects.txt') + + def linkcode_resolve(domain, info): + if domain == 'py': + fn = info['module'].replace('.', '/') + return "http://foobar/source/%s.py" % fn + elif domain == "js": + return "http://foobar/js/" + info['fullname'] + elif domain in ("c", "cpp"): + return "http://foobar/%s/%s" % (domain, "".join(info['names'])) + else: + raise AssertionError() # -- extension API diff --git a/tests/root/contents.txt b/tests/root/contents.txt index 280953b4..0a8ca00e 100644 --- a/tests/root/contents.txt +++ b/tests/root/contents.txt @@ -27,6 +27,8 @@ Contents: doctest extensions versioning/index + only + i18n/index Python <http://python.org/> diff --git a/tests/root/i18n/external_links.po b/tests/root/i18n/external_links.po new file mode 100644 index 00000000..4cd19dda --- /dev/null +++ b/tests/root/i18n/external_links.po @@ -0,0 +1,32 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2012, foof +# This file is distributed under the same license as the foo package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: sphinx 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-11-22 08:28\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "i18n with external links" +msgstr "EXTERNAL LINKS" + +msgid "External link to Python_." +msgstr "EXTERNAL LINK TO Python_." + +msgid "Internal link to `i18n with external links`_." +msgstr "`EXTERNAL LINKS`_ IS INTERNAL LINK." + +msgid "Inline link by `Sphinx <http://sphinx-doc.org>`_." +msgstr "INLINE LINK BY `SPHINX <http://sphinx-doc.org>`_." + +msgid "Unnamed link__." +msgstr "UNNAMED LINK__." diff --git a/tests/root/i18n/external_links.txt b/tests/root/i18n/external_links.txt new file mode 100644 index 00000000..7ac1db02 --- /dev/null +++ b/tests/root/i18n/external_links.txt @@ -0,0 +1,13 @@ +:tocdepth: 2 + +i18n with external links +======================== +.. #1044 external-links-dont-work-in-localized-html + +* External link to Python_. +* Internal link to `i18n with external links`_. +* Inline link by `Sphinx <http://sphinx-doc.org>`_. +* Unnamed link__. + +.. _Python: http://python.org +.. __: http://google.com diff --git a/tests/root/i18n/footnote.po b/tests/root/i18n/footnote.po new file mode 100644 index 00000000..47f8d3db --- /dev/null +++ b/tests/root/i18n/footnote.po @@ -0,0 +1,33 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2012, foof +# This file is distributed under the same license as the foo package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: sphinx 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-11-22 08:28\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "i18n with Footnote" +msgstr "I18N WITH FOOTNOTE" + +msgid "[100]_ Contents [#]_ for `i18n with Footnote`_ [ref]_" +msgstr "`I18N WITH FOOTNOTE`_ INCLUDE THIS CONTENTS [ref]_ [#]_ [100]_" + +msgid "This is a auto numbered footnote." +msgstr "THIS IS A AUTO NUMBERED FOOTNOTE." + +msgid "This is a named footnote." +msgstr "THIS IS A NAMED FOOTNOTE." + +msgid "This is a numbered footnote." +msgstr "THIS IS A NUMBERED FOOTNOTE." + diff --git a/tests/root/i18n/footnote.txt b/tests/root/i18n/footnote.txt new file mode 100644 index 00000000..3ef76bba --- /dev/null +++ b/tests/root/i18n/footnote.txt @@ -0,0 +1,11 @@ +:tocdepth: 2 + +i18n with Footnote +================== +.. #955 cant-build-html-with-footnotes-when-using + +[100]_ Contents [#]_ for `i18n with Footnote`_ [ref]_ + +.. [#] This is a auto numbered footnote. +.. [ref] This is a named footnote. +.. [100] This is a numbered footnote. diff --git a/tests/root/i18n/index.txt b/tests/root/i18n/index.txt new file mode 100644 index 00000000..f35e2766 --- /dev/null +++ b/tests/root/i18n/index.txt @@ -0,0 +1,7 @@ +.. toctree:: + :maxdepth: 2 + :numbered: + + footnote + external_links + refs_inconsistency diff --git a/tests/root/i18n/refs_inconsistency.po b/tests/root/i18n/refs_inconsistency.po new file mode 100644 index 00000000..9cab687f --- /dev/null +++ b/tests/root/i18n/refs_inconsistency.po @@ -0,0 +1,39 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2012, foof +# This file is distributed under the same license as the foo package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: sphinx 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-12-05 08:28\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "i18n with refs inconsistency" +msgstr "I18N WITH REFS INCONSISTENCY" + +msgid "[100]_ for [#]_ footnote [ref2]_." +msgstr "FOR FOOTNOTE [ref2]_." + +msgid "for reference_." +msgstr "reference_ FOR reference_." + +msgid "normal text." +msgstr "ORPHAN REFERENCE: `I18N WITH REFS INCONSISTENCY`_." + +msgid "This is a auto numbered footnote." +msgstr "THIS IS A AUTO NUMBERED FOOTNOTE." + +msgid "This is a named footnote." +msgstr "THIS IS A NAMED FOOTNOTE." + +msgid "This is a numbered footnote." +msgstr "THIS IS A NUMBERED FOOTNOTE." + diff --git a/tests/root/i18n/refs_inconsistency.txt b/tests/root/i18n/refs_inconsistency.txt new file mode 100644 index 00000000..c65c5b45 --- /dev/null +++ b/tests/root/i18n/refs_inconsistency.txt @@ -0,0 +1,13 @@ +:tocdepth: 2 + +i18n with refs inconsistency +============================= + +* [100]_ for [#]_ footnote [ref2]_. +* for reference_. +* normal text. + +.. [#] This is a auto numbered footnote. +.. [ref2] This is a named footnote. +.. [100] This is a numbered footnote. +.. _reference: http://www.example.com diff --git a/tests/root/only.txt b/tests/root/only.txt new file mode 100644 index 00000000..4a3eb48a --- /dev/null +++ b/tests/root/only.txt @@ -0,0 +1,203 @@ + +1. Sections in only directives +============================== + +Testing sections in only directives. + +.. only:: nonexisting_tag + + Skipped Section + --------------- + Should not be here. + +.. only:: not nonexisting_tag + + 1.1. Section + ------------ + Should be here. + +1.2. Section +------------ + +.. only:: not nonexisting_tag + + 1.2.1. Subsection + ~~~~~~~~~~~~~~~~~ + Should be here. + +.. only:: nonexisting_tag + + Skipped Subsection + ~~~~~~~~~~~~~~~~~~ + Should not be here. + +1.3. Section +------------ + +1.3.1. Subsection +~~~~~~~~~~~~~~~~~ +Should be here. + +1.4. Section +------------ + +.. only:: not nonexisting_tag + + 1.4.1. Subsection + ~~~~~~~~~~~~~~~~~ + Should be here. + +1.5. Section +------------ + +.. only:: not nonexisting_tag + + 1.5.1. Subsection + ~~~~~~~~~~~~~~~~~ + Should be here. + +1.5.2. Subsection +~~~~~~~~~~~~~~~~~ +Should be here. + +1.6. Section +------------ + +1.6.1. Subsection +~~~~~~~~~~~~~~~~~ +Should be here. + +.. only:: not nonexisting_tag + + 1.6.2. Subsection + ~~~~~~~~~~~~~~~~~ + Should be here. + +1.6.3. Subsection +~~~~~~~~~~~~~~~~~ +Should be here. + +1.7. Section +------------ + +1.7.1. Subsection +~~~~~~~~~~~~~~~~~ +Should be here. + +.. only:: not nonexisting_tag + + 1.7.1.1. Subsubsection + ...................... + Should be here. + +1.8. Section +------------ + +1.8.1. Subsection +~~~~~~~~~~~~~~~~~ +Should be here. + +1.8.1.1. Subsubsection +...................... +Should be here. + +.. only:: not nonexisting_tag + + 1.8.1.2. Subsubsection + ...................... + Should be here. + +1.9. Section +------------ + +.. only:: nonexisting_tag + + Skipped Subsection + ~~~~~~~~~~~~~~~~~~ + +1.9.1. Subsection +~~~~~~~~~~~~~~~~~ +Should be here. + +1.9.1.1. Subsubsection +...................... +Should be here. + +.. only:: not nonexisting_tag + + 1.10. Section + ------------- + Should be here. + +1.11. Section +------------- + +Text before subsection 11.1. + +.. only:: not nonexisting_tag + + More text before subsection 11.1. + + 1.11.1. Subsection + ~~~~~~~~~~~~~~~~~~ + Should be here. + +Text after subsection 11.1. + +.. only:: not nonexisting_tag + + 1.12. Section + ------------- + Should be here. + + 1.12.1. Subsection + ~~~~~~~~~~~~~~~~~~ + Should be here. + + 1.13. Section + ------------- + Should be here. + +.. only:: not nonexisting_tag + + 1.14. Section + ------------- + Should be here. + + .. only:: not nonexisting_tag + + 1.14.1. Subsection + ~~~~~~~~~~~~~~~~~~ + Should be here. + + 1.15. Section + ------------- + Should be here. + +.. only:: nonexisting_tag + + Skipped document level heading + ============================== + Should not be here. + +.. only:: not nonexisting_tag + + 2. Included document level heading + ================================== + Should be here. + +3. Document level heading +========================= +Should be here. + +.. only:: nonexisting_tag + + Skipped document level heading + ============================== + Should not be here. + +.. only:: not nonexisting_tag + + 4. Another included document level heading + ========================================== + Should be here. diff --git a/tests/run.py b/tests/run.py index ee63fa3f..4cd4a766 100755 --- a/tests/run.py +++ b/tests/run.py @@ -11,19 +11,24 @@ """ import sys -from os import path, chdir, listdir +from os import path, chdir, listdir, environ if sys.version_info >= (3, 0): print('Copying and converting sources to build/lib/tests...') from distutils.util import copydir_run_2to3 testroot = path.dirname(__file__) or '.' - newroot = path.join(testroot, path.pardir, 'build') - newroot = path.join(newroot, listdir(newroot)[0], 'tests') + if 'BUILD_TEST_PATH' in environ: + # for tox testing + newroot = environ['BUILD_TEST_PATH'] + # tox installs the sphinx package, no need for sys.path.insert + else: + newroot = path.join(testroot, path.pardir, 'build') + newroot = path.join(newroot, listdir(newroot)[0], 'tests') + # always test the sphinx package from build/lib/ + sys.path.insert(0, path.abspath(path.join(newroot, path.pardir))) copydir_run_2to3(testroot, newroot) # switch to the converted dir so nose tests the right tests chdir(newroot) - # always test the sphinx package from build/lib/ - sys.path.insert(0, path.pardir) else: # always test the sphinx package from this directory sys.path.insert(0, path.join(path.dirname(__file__), path.pardir)) diff --git a/tests/test_application.py b/tests/test_application.py index 4baabcec..a6e798c2 100644 --- a/tests/test_application.py +++ b/tests/test_application.py @@ -12,6 +12,7 @@ from StringIO import StringIO from sphinx.application import ExtensionError +from sphinx.domains import Domain from util import * @@ -69,3 +70,23 @@ def test_extensions(): assert warnings.getvalue().startswith("WARNING: extension 'shutil'") finally: app.cleanup() + +def test_domain_override(): + class A(Domain): + name = 'foo' + class B(A): + name = 'foo' + class C(Domain): + name = 'foo' + status, warnings = StringIO(), StringIO() + app = TestApp(status=status, warning=warnings) + try: + # No domain know named foo. + raises_msg(ExtensionError, 'domain foo not yet registered', + app.override_domain, A) + assert app.add_domain(A) is None + assert app.override_domain(B) is None + raises_msg(ExtensionError, 'new domain not a subclass of registered ' + 'foo domain', app.override_domain, C) + finally: + app.cleanup() diff --git a/tests/test_autodoc.py b/tests/test_autodoc.py index 965064c3..642b9141 100644 --- a/tests/test_autodoc.py +++ b/tests/test_autodoc.py @@ -519,6 +519,12 @@ def test_generate(): assert_result_contains( ' rest of docstring', 'method', 'test_autodoc.DocstringSig.meth') assert_result_contains( + '.. py:method:: DocstringSig.meth2()', 'method', + 'test_autodoc.DocstringSig.meth2') + assert_result_contains( + ' indented line', 'method', + 'test_autodoc.DocstringSig.meth2') + assert_result_contains( '.. py:classmethod:: Class.moore(a, e, f) -> happiness', 'method', 'test_autodoc.Class.moore') @@ -534,6 +540,32 @@ def test_generate(): assert_result_contains( ' :annotation: = None', 'attribute', 'AttCls.a2') + # test explicit members with instance attributes + del directive.env.temp_data['autodoc:class'] + del directive.env.temp_data['autodoc:module'] + directive.env.temp_data['py:module'] = 'test_autodoc' + options.inherited_members = False + options.undoc_members = False + options.members = ALL + assert_processes([ + ('class', 'test_autodoc.InstAttCls'), + ('attribute', 'test_autodoc.InstAttCls.ca1'), + ('attribute', 'test_autodoc.InstAttCls.ca2'), + ('attribute', 'test_autodoc.InstAttCls.ca3'), + ('attribute', 'test_autodoc.InstAttCls.ia1'), + ('attribute', 'test_autodoc.InstAttCls.ia2'), + ], 'class', 'InstAttCls') + del directive.env.temp_data['autodoc:class'] + del directive.env.temp_data['autodoc:module'] + options.members = ['ca1', 'ia1'] + assert_processes([ + ('class', 'test_autodoc.InstAttCls'), + ('attribute', 'test_autodoc.InstAttCls.ca1'), + ('attribute', 'test_autodoc.InstAttCls.ia1'), + ], 'class', 'InstAttCls') + del directive.env.temp_data['autodoc:class'] + del directive.env.temp_data['autodoc:module'] + del directive.env.temp_data['py:module'] # --- generate fodder ------------ @@ -660,6 +692,13 @@ First line of docstring rest of docstring """ + def meth2(self): + """First line, no signature + Second line followed by indentation:: + + indented line + """ + class StrRepr(str): def __repr__(self): return self @@ -667,3 +706,22 @@ class StrRepr(str): class AttCls(object): a1 = StrRepr('hello\nworld') a2 = None + +class InstAttCls(object): + """Class with documented class and instance attributes.""" + + #: Doc comment for class attribute InstAttCls.ca1. + #: It can have multiple lines. + ca1 = 'a' + + ca2 = 'b' #: Doc comment for InstAttCls.ca2. One line only. + + ca3 = 'c' + """Docstring for class attribute InstAttCls.ca3.""" + + def __init__(self): + #: Doc comment for instance attribute InstAttCls.ia1 + self.ia1 = 'd' + + self.ia2 = 'e' + """Docstring for instance attribute InstAttCls.ia2.""" diff --git a/tests/test_build.py b/tests/test_build.py index ae3f2921..02b3c868 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -63,6 +63,14 @@ else: def test_singlehtml(app): app.builder.build_all() +@with_app(buildername='xml') +def test_xml(app): + app.builder.build_all() + +@with_app(buildername='pseudoxml') +def test_pseudoxml(app): + app.builder.build_all() + @with_app(buildername='html', srcdir='(temp)') def test_multibyte_path(app): srcdir = path(app.srcdir) diff --git a/tests/test_build_html.py b/tests/test_build_html.py index a38806a8..a693e6c0 100644 --- a/tests/test_build_html.py +++ b/tests/test_build_html.py @@ -44,7 +44,7 @@ reading included file u'.*?wrongenc.inc' seems to be wrong, try giving an \ %(root)s/includes.txt:4: WARNING: download file not readable: .*?nonexisting.png %(root)s/objects.txt:\\d*: WARNING: using old C markup; please migrate to \ new-style markup \(e.g. c:function instead of cfunction\), see \ -http://sphinx.pocoo.org/domains.html +http://sphinx-doc.org/domains.html """ HTML_WARNINGS = ENV_WARNINGS + """\ @@ -319,7 +319,8 @@ def check_static_entries(outdir): def test_html(app): app.builder.build_all() html_warnings = html_warnfile.getvalue().replace(os.sep, '/') - html_warnings_exp = HTML_WARNINGS % {'root': re.escape(app.srcdir)} + html_warnings_exp = HTML_WARNINGS % { + 'root': re.escape(app.srcdir.replace(os.sep, '/'))} assert re.match(html_warnings_exp + '$', html_warnings), \ 'Warnings don\'t match:\n' + \ '--- Expected (regex):\n' + html_warnings_exp + \ @@ -328,7 +329,7 @@ def test_html(app): for fname, paths in HTML_XPATH.iteritems(): parser = NslessParser() parser.entity.update(htmlentitydefs.entitydefs) - fp = open(os.path.join(app.outdir, fname)) + fp = open(os.path.join(app.outdir, fname), 'rb') try: etree = ET.parse(fp, parser) finally: diff --git a/tests/test_build_latex.py b/tests/test_build_latex.py index 4e1e9f70..2fa0698b 100644 --- a/tests/test_build_latex.py +++ b/tests/test_build_latex.py @@ -42,7 +42,8 @@ def test_latex(app): LaTeXTranslator.ignore_missing_images = True app.builder.build_all() latex_warnings = latex_warnfile.getvalue().replace(os.sep, '/') - latex_warnings_exp = LATEX_WARNINGS % {'root': re.escape(app.srcdir)} + latex_warnings_exp = LATEX_WARNINGS % { + 'root': re.escape(app.srcdir.replace(os.sep, '/'))} assert re.match(latex_warnings_exp + '$', latex_warnings), \ 'Warnings don\'t match:\n' + \ '--- Expected (regex):\n' + latex_warnings_exp + \ diff --git a/tests/test_build_texinfo.py b/tests/test_build_texinfo.py index c626c976..59d03e03 100644 --- a/tests/test_build_texinfo.py +++ b/tests/test_build_texinfo.py @@ -41,7 +41,8 @@ def test_texinfo(app): TexinfoTranslator.ignore_missing_images = True app.builder.build_all() texinfo_warnings = texinfo_warnfile.getvalue().replace(os.sep, '/') - texinfo_warnings_exp = TEXINFO_WARNINGS % {'root': re.escape(app.srcdir)} + texinfo_warnings_exp = TEXINFO_WARNINGS % { + 'root': re.escape(app.srcdir.replace(os.sep, '/'))} assert re.match(texinfo_warnings_exp + '$', texinfo_warnings), \ 'Warnings don\'t match:\n' + \ '--- Expected (regex):\n' + texinfo_warnings_exp + \ diff --git a/tests/test_cpp_domain.py b/tests/test_cpp_domain.py index 3ab8ece4..c8466e37 100644 --- a/tests/test_cpp_domain.py +++ b/tests/test_cpp_domain.py @@ -11,7 +11,7 @@ from util import * -from sphinx.domains.cpp import DefinitionParser +from sphinx.domains.cpp import DefinitionParser, DefinitionError def parse(name, string): @@ -43,6 +43,15 @@ def test_type_definitions(): x = 'int printf(const char* fmt, ...)' assert unicode(parse('function', x)) == x + x = 'int foo(const unsigned int j)' + assert unicode(parse('function', x)) == x + + x = 'int foo(const unsigned int const j)' + assert unicode(parse('function', x)) == x + + x = 'int foo(const int* const ptr)' + assert unicode(parse('function', x)) == x + x = 'std::vector<std::pair<std::string, long long>> module::blah' assert unicode(parse('type_object', x)) == x @@ -60,6 +69,9 @@ def test_type_definitions(): x = 'constexpr int get_value()' assert unicode(parse('function', x)) == x + x = 'static constexpr int get_value()' + assert unicode(parse('function', x)) == x + x = 'int get_value() const noexcept' assert unicode(parse('function', x)) == x @@ -73,6 +85,21 @@ def test_type_definitions(): x = 'module::myclass foo[n]' assert unicode(parse('member_object', x)) == x + x = 'int foo(Foo f=Foo(double(), std::make_pair(int(2), double(3.4))))' + assert unicode(parse('function', x)) == x + + x = 'int foo(A a=x(a))' + assert unicode(parse('function', x)) == x + + x = 'int foo(B b=x(a)' + raises(DefinitionError, parse, 'function', x) + + x = 'int foo)C c=x(a))' + raises(DefinitionError, parse, 'function', x) + + x = 'int foo(D d=x(a' + raises(DefinitionError, parse, 'function', x) + def test_bases(): x = 'A' diff --git a/tests/test_env.py b/tests/test_env.py index e62db33b..2f75187f 100644 --- a/tests/test_env.py +++ b/tests/test_env.py @@ -54,6 +54,7 @@ def test_images(): tree = env.get_doctree('images') app._warning.reset() htmlbuilder = StandaloneHTMLBuilder(app) + htmlbuilder.imgpath = 'dummy' htmlbuilder.post_process_images(tree) image_uri_message = "no matching candidate for image URI u'foo.*'" if sys.version_info >= (3, 0): diff --git a/tests/test_intl.py b/tests/test_intl.py index d1e28002..94b21e8d 100644 --- a/tests/test_intl.py +++ b/tests/test_intl.py @@ -11,34 +11,45 @@ """ from subprocess import Popen, PIPE +import re +import os +from StringIO import StringIO from util import * from util import SkipTest +warnfile = StringIO() + + def setup_module(): (test_root / 'xx' / 'LC_MESSAGES').makedirs() # Compile all required catalogs into binary format (*.mo). - for catalog in 'bom', 'subdir': - try: - p = Popen(['msgfmt', test_root / '%s.po' % catalog, '-o', - test_root / 'xx' / 'LC_MESSAGES' / '%s.mo' % catalog], - stdout=PIPE, stderr=PIPE) - except OSError: - # The test will fail the second time it's run if we don't - # tear down here. Not sure if there's a more idiomatic way - # of ensuring that teardown gets run in the event of an - # exception from the setup function. - teardown_module() - raise SkipTest # most likely msgfmt was not found - else: - stdout, stderr = p.communicate() - if p.returncode != 0: - print stdout - print stderr - assert False, 'msgfmt exited with return code %s' % p.returncode - assert (test_root / 'xx' / 'LC_MESSAGES' / ('%s.mo' % catalog) - ).isfile(), 'msgfmt failed' + for dirpath, dirs, files in os.walk(test_root): + dirpath = path(dirpath) + for f in [f for f in files if f.endswith('.po')]: + po = dirpath / f + mo = test_root / 'xx' / 'LC_MESSAGES' / ( + os.path.relpath(po[:-3], test_root) + '.mo') + if not mo.parent.exists(): + mo.parent.makedirs() + try: + p = Popen(['msgfmt', po, '-o', mo], + stdout=PIPE, stderr=PIPE) + except OSError: + # The test will fail the second time it's run if we don't + # tear down here. Not sure if there's a more idiomatic way + # of ensuring that teardown gets run in the event of an + # exception from the setup function. + teardown_module() + raise SkipTest # most likely msgfmt was not found + else: + stdout, stderr = p.communicate() + if p.returncode != 0: + print stdout + print stderr + assert False, 'msgfmt exited with return code %s' % p.returncode + assert mo.isfile(), 'msgfmt failed' def teardown_module(): @@ -63,3 +74,114 @@ def test_subdir(app): app.builder.build(['subdir/includes']) result = (app.outdir / 'subdir' / 'includes.txt').text(encoding='utf-8') assert result.startswith(u"\ntranslation\n***********\n\n") + + +@with_app(buildername='html', cleanenv=True, + confoverrides={'language': 'xx', 'locale_dirs': ['.'], + 'gettext_compact': False}) +def test_i18n_footnote_break_refid(app): + """test for #955 cant-build-html-with-footnotes-when-using""" + app.builder.build(['i18n/footnote']) + result = (app.outdir / 'i18n' / 'footnote.html').text(encoding='utf-8') + # expect no error by build + + +@with_app(buildername='text', cleanenv=True, + confoverrides={'language': 'xx', 'locale_dirs': ['.'], + 'gettext_compact': False}) +def test_i18n_footnote_regression(app): + """regression test for fix #955""" + app.builder.build(['i18n/footnote']) + result = (app.outdir / 'i18n' / 'footnote.txt').text(encoding='utf-8') + expect = (u"\nI18N WITH FOOTNOTE" + u"\n******************\n" # underline matches new translation + u"\nI18N WITH FOOTNOTE INCLUDE THIS CONTENTS [ref] [1] [100]\n" + u"\n[1] THIS IS A AUTO NUMBERED FOOTNOTE.\n" + u"\n[ref] THIS IS A NAMED FOOTNOTE.\n" + u"\n[100] THIS IS A NUMBERED FOOTNOTE.\n") + assert result == expect + + +@with_app(buildername='text', warning=warnfile, cleanenv=True, + confoverrides={'language': 'xx', 'locale_dirs': ['.'], + 'gettext_compact': False}) +def test_i18n_warn_for_number_of_references_inconsistency(app): + app.builddir.rmtree(True) + app.builder.build(['i18n/refs_inconsistency']) + result = (app.outdir / 'i18n' / 'refs_inconsistency.txt').text(encoding='utf-8') + expect = (u"\nI18N WITH REFS INCONSISTENCY" + u"\n****************************\n" + u"\n* FOR FOOTNOTE [ref2].\n" + u"\n* reference FOR reference.\n" + u"\n* ORPHAN REFERENCE: I18N WITH REFS INCONSISTENCY.\n" + u"\n[1] THIS IS A AUTO NUMBERED FOOTNOTE.\n" + u"\n[ref2] THIS IS A NAMED FOOTNOTE.\n" + u"\n[100] THIS IS A NUMBERED FOOTNOTE.\n") + assert result == expect + + warnings = warnfile.getvalue().replace(os.sep, '/') + warning_fmt = u'.*/i18n/refs_inconsistency.txt:\\d+: ' \ + u'WARNING: inconsistent %s in translated message\n' + expected_warning_expr = ( + warning_fmt % 'footnote references' + + warning_fmt % 'references' + + warning_fmt % 'references') + assert re.search(expected_warning_expr, warnings) + + +@with_app(buildername='html', cleanenv=True, + confoverrides={'language': 'xx', 'locale_dirs': ['.'], + 'gettext_compact': False}) +def test_i18n_link_to_undefined_reference(app): + app.builder.build(['i18n/refs_inconsistency']) + result = (app.outdir / 'i18n' / 'refs_inconsistency.html').text(encoding='utf-8') + + expected_expr = """<a class="reference external" href="http://www.example.com">reference</a>""" + assert len(re.findall(expected_expr, result)) == 2 + + expected_expr = """<a class="reference internal" href="#reference">reference</a>""" + assert len(re.findall(expected_expr, result)) == 0 + + expected_expr = """<a class="reference internal" href="#i18n-with-refs-inconsistency">I18N WITH REFS INCONSISTENCY</a>""" + assert len(re.findall(expected_expr, result)) == 1 + + +@with_app(buildername='html', cleanenv=True, + confoverrides={'language': 'xx', 'locale_dirs': ['.'], + 'gettext_compact': False}) +def test_i18n_keep_external_links(app): + """regression test for #1044""" + app.builder.build(['i18n/external_links']) + result = (app.outdir / 'i18n' / 'external_links.html').text(encoding='utf-8') + + # external link check + expect_line = u"""<li>EXTERNAL LINK TO <a class="reference external" href="http://python.org">Python</a>.</li>""" + matched = re.search('^<li>EXTERNAL LINK TO .*$', result, re.M) + matched_line = '' + if matched: + matched_line = matched.group() + assert expect_line == matched_line + + # internal link check + expect_line = u"""<li><a class="reference internal" href="#i18n-with-external-links">EXTERNAL LINKS</a> IS INTERNAL LINK.</li>""" + matched = re.search('^<li><a .* IS INTERNAL LINK.</li>$', result, re.M) + matched_line = '' + if matched: + matched_line = matched.group() + assert expect_line == matched_line + + # inline link check + expect_line = u"""<li>INLINE LINK BY <a class="reference external" href="http://sphinx-doc.org">SPHINX</a>.</li>""" + matched = re.search('^<li>INLINE LINK BY .*$', result, re.M) + matched_line = '' + if matched: + matched_line = matched.group() + assert expect_line == matched_line + + # unnamed link check + expect_line = u"""<li>UNNAMED <a class="reference external" href="http://google.com">LINK</a>.</li>""" + matched = re.search('^<li>UNNAMED .*$', result, re.M) + matched_line = '' + if matched: + matched_line = matched.group() + assert expect_line == matched_line diff --git a/tests/test_linkcode.py b/tests/test_linkcode.py new file mode 100644 index 00000000..365e826f --- /dev/null +++ b/tests/test_linkcode.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +""" + test_linkcode + ~~~~~~~~~~~~~ + + Test the sphinx.ext.linkcode extension. + + :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import os +from util import * + +@with_app(srcdir='(temp)', buildername='html', tags=['test_linkcode']) +def test_html(app): + app.builder.build_all() + + fp = open(os.path.join(app.outdir, 'objects.html'), 'r') + try: + stuff = fp.read() + finally: + fp.close() + + assert 'http://foobar/source/foolib.py' in stuff + assert 'http://foobar/js/' in stuff + assert 'http://foobar/c/' in stuff + assert 'http://foobar/cpp/' in stuff diff --git a/tests/test_only_directive.py b/tests/test_only_directive.py new file mode 100644 index 00000000..2396046e --- /dev/null +++ b/tests/test_only_directive.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +""" + test_only_directive + ~~~~~~~~~~~~~~~~~~~ + + Test the only directive with the test root. + + :copyright: Copyright 2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re + +from docutils import nodes + +from util import * + + +def teardown_module(): + (test_root / '_build').rmtree(True) + + +@with_app(buildername='text') +def test_sectioning(app): + + def getsects(section): + if not isinstance(section, nodes.section): + return [getsects(n) for n in section.children] + title = section.next_node(nodes.title).astext().strip() + subsects = [] + children = section.children[:] + while children: + node = children.pop(0) + if isinstance(node, nodes.section): + subsects.append(node) + continue + children = list(node.children) + children + return [title, [getsects(subsect) for subsect in subsects]] + + def testsects(prefix, sects, indent=0): + title = sects[0] + parent_num = title.split()[0] + assert prefix == parent_num, \ + 'Section out of place: %r' % title + for i, subsect in enumerate(sects[1]): + num = subsect[0].split()[0] + assert re.match('[0-9]+[.0-9]*[.]', num), \ + 'Unnumbered section: %r' % subsect[0] + testsects(prefix + str(i+1) + '.', subsect, indent+4) + + app.builder.build(['only']) + doctree = app.env.get_doctree('only') + app.env.process_only_nodes(doctree, app.builder) + + parts = [getsects(n) + for n in filter(lambda n: isinstance(n, nodes.section), + doctree.children)] + for i, s in enumerate(parts): + testsects(str(i+1) + '.', s, 4) + assert len(parts) == 4, 'Expected 4 document level headings, got:\n%s' % \ + '\n'.join([p[0] for p in parts]) diff --git a/tests/test_quickstart.py b/tests/test_quickstart.py index dba888dd..c054f858 100644 --- a/tests/test_quickstart.py +++ b/tests/test_quickstart.py @@ -46,6 +46,25 @@ def teardown_module(): coloron() +def test_quickstart_inputstrip(): + d = {} + answers = { + 'Q1': 'Y\r', # input() return with '\r' on Python-3.2.0 for Windows + 'Q2': ' Yes \r', + 'Q3': 'N', + 'Q4': 'N ', + } + qs.term_input = mock_raw_input(answers) + qs.do_prompt(d, 'k1', 'Q1') + assert d['k1'] == 'Y' + qs.do_prompt(d, 'k2', 'Q2') + assert d['k2'] == 'Yes' + qs.do_prompt(d, 'k3', 'Q3') + assert d['k3'] == 'N' + qs.do_prompt(d, 'k4', 'Q4') + assert d['k4'] == 'N' + + def test_do_prompt(): d = {} answers = { diff --git a/tests/util.py b/tests/util.py index bd50bec0..32e94a7f 100644 --- a/tests/util.py +++ b/tests/util.py @@ -21,6 +21,7 @@ except ImportError: wraps = lambda f: (lambda w: w) from sphinx import application +from sphinx.theming import Theme from sphinx.ext.autodoc import AutoDirective from path import path @@ -170,6 +171,7 @@ class TestApp(application.Sphinx): freshenv, warningiserror, tags) def cleanup(self, doctrees=False): + Theme.themes.clear() AutoDirective._registry.clear() for tree in self.cleanup_trees: shutil.rmtree(tree, True) |
