1"""
2    test_environment_toctree
3    ~~~~~~~~~~~~~~~~~~~~~~~~
4
5    Test the sphinx.environment.managers.toctree.
6
7    :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
8    :license: BSD, see LICENSE for details.
9"""
10
11import pytest
12from docutils import nodes
13from docutils.nodes import bullet_list, caption, comment, list_item, reference
14
15from sphinx import addnodes
16from sphinx.addnodes import compact_paragraph, only
17from sphinx.builders.html import StandaloneHTMLBuilder
18from sphinx.environment.adapters.toctree import TocTree
19from sphinx.testing.util import assert_node
20
21
22@pytest.mark.sphinx('xml', testroot='toctree')
23@pytest.mark.test_params(shared_result='test_environment_toctree_basic')
24def test_process_doc(app):
25    app.build()
26    # tocs
27    toctree = app.env.tocs['index']
28    assert_node(toctree,
29                [bullet_list, ([list_item, (compact_paragraph,  # [0][0]
30                                            [bullet_list, (addnodes.toctree,  # [0][1][0]
31                                                           only,  # [0][1][1]
32                                                           list_item)])],  # [0][1][2]
33                               [list_item, (compact_paragraph,  # [1][0]
34                                            [bullet_list, (addnodes.toctree,  # [1][1][0]
35                                                           addnodes.toctree)])],  # [1][1][1]
36                               list_item)])
37
38    assert_node(toctree[0][0],
39                [compact_paragraph, reference, "Welcome to Sphinx Tests’s documentation!"])
40    assert_node(toctree[0][0][0], reference, anchorname='')
41    assert_node(toctree[0][1][0], addnodes.toctree,
42                caption="Table of Contents", glob=False, hidden=False,
43                titlesonly=False, maxdepth=2, numbered=999,
44                entries=[(None, 'foo'), (None, 'bar'), (None, 'http://sphinx-doc.org/'),
45                         (None, 'self')],
46                includefiles=['foo', 'bar'])
47
48    # only branch
49    assert_node(toctree[0][1][1], addnodes.only, expr="html")
50    assert_node(toctree[0][1][1],
51                [only, list_item, ([compact_paragraph, reference, "Section for HTML"],
52                                   [bullet_list, addnodes.toctree])])
53    assert_node(toctree[0][1][1][0][0][0], reference, anchorname='#section-for-html')
54    assert_node(toctree[0][1][1][0][1][0], addnodes.toctree,
55                caption=None, glob=False, hidden=False, entries=[(None, 'baz')],
56                includefiles=['baz'], titlesonly=False, maxdepth=-1, numbered=0)
57    assert_node(toctree[0][1][2],
58                ([compact_paragraph, reference, "subsection"],
59                 [bullet_list, list_item, compact_paragraph, reference, "subsubsection"]))
60
61    assert_node(toctree[1][0],
62                [compact_paragraph, reference, "Test for issue #1157"])
63    assert_node(toctree[1][0][0], reference, anchorname='#test-for-issue-1157')
64    assert_node(toctree[1][1][0], addnodes.toctree,
65                caption=None, entries=[], glob=False, hidden=False,
66                titlesonly=False, maxdepth=-1, numbered=0)
67    assert_node(toctree[1][1][1], addnodes.toctree,
68                caption=None, glob=False, hidden=True,
69                titlesonly=False, maxdepth=-1, numbered=0,
70                entries=[('Latest reference', 'http://sphinx-doc.org/latest/'),
71                         ('Python', 'http://python.org/')])
72
73    assert_node(toctree[2][0],
74                [compact_paragraph, reference, "Indices and tables"])
75
76    # other collections
77    assert app.env.toc_num_entries['index'] == 6
78    assert app.env.toctree_includes['index'] == ['foo', 'bar', 'baz']
79    assert app.env.files_to_rebuild['foo'] == {'index'}
80    assert app.env.files_to_rebuild['bar'] == {'index'}
81    assert app.env.files_to_rebuild['baz'] == {'index'}
82    assert app.env.glob_toctrees == set()
83    assert app.env.numbered_toctrees == {'index'}
84
85    # qux has no section title
86    assert len(app.env.tocs['qux']) == 0
87    assert_node(app.env.tocs['qux'], nodes.bullet_list)
88    assert app.env.toc_num_entries['qux'] == 0
89    assert 'qux' not in app.env.toctree_includes
90
91
92@pytest.mark.sphinx('dummy', testroot='toctree-glob')
93def test_glob(app):
94    includefiles = ['foo', 'bar/index', 'bar/bar_1', 'bar/bar_2',
95                    'bar/bar_3', 'baz', 'qux/index']
96
97    app.build()
98
99    # tocs
100    toctree = app.env.tocs['index']
101    assert_node(toctree,
102                [bullet_list, list_item, (compact_paragraph,  # [0][0]
103                                          [bullet_list, (list_item,  # [0][1][0]
104                                                         list_item)])])  # [0][1][1]
105
106    assert_node(toctree[0][0],
107                [compact_paragraph, reference, "test-toctree-glob"])
108    assert_node(toctree[0][1][0],
109                [list_item, ([compact_paragraph, reference, "normal order"],
110                             [bullet_list, addnodes.toctree])])  # [0][1][0][1][0]
111    assert_node(toctree[0][1][0][1][0], addnodes.toctree, caption=None,
112                glob=True, hidden=False, titlesonly=False,
113                maxdepth=-1, numbered=0, includefiles=includefiles,
114                entries=[(None, 'foo'), (None, 'bar/index'), (None, 'bar/bar_1'),
115                         (None, 'bar/bar_2'), (None, 'bar/bar_3'), (None, 'baz'),
116                         (None, 'qux/index'),
117                         ('hyperref', 'https://sphinx-doc.org/?q=sphinx')])
118    assert_node(toctree[0][1][1],
119                [list_item, ([compact_paragraph, reference, "reversed order"],
120                             [bullet_list, addnodes.toctree])])  # [0][1][1][1][0]
121    assert_node(toctree[0][1][1][1][0], addnodes.toctree, caption=None,
122                glob=True, hidden=False, titlesonly=False,
123                maxdepth=-1, numbered=0, includefiles=list(reversed(includefiles)),
124                entries=[(None, 'qux/index'), (None, 'baz'), (None, 'bar/bar_3'),
125                         (None, 'bar/bar_2'), (None, 'bar/bar_1'), (None, 'bar/index'),
126                         (None, 'foo')])
127
128    # other collections
129    assert app.env.toc_num_entries['index'] == 3
130    assert app.env.toctree_includes['index'] == includefiles + list(reversed(includefiles))
131    for file in includefiles:
132        assert 'index' in app.env.files_to_rebuild[file]
133    assert 'index' in app.env.glob_toctrees
134    assert app.env.numbered_toctrees == set()
135
136
137@pytest.mark.sphinx('xml', testroot='toctree')
138@pytest.mark.test_params(shared_result='test_environment_toctree_basic')
139def test_get_toc_for(app):
140    app.build()
141    toctree = TocTree(app.env).get_toc_for('index', app.builder)
142
143    assert_node(toctree,
144                [bullet_list, ([list_item, (compact_paragraph,  # [0][0]
145                                            [bullet_list, (addnodes.toctree,  # [0][1][0]
146                                                           comment,  # [0][1][1]
147                                                           list_item)])],  # [0][1][2]
148                               [list_item, (compact_paragraph,  # [1][0]
149                                            [bullet_list, (addnodes.toctree,
150                                                           addnodes.toctree)])],
151                               [list_item, compact_paragraph])])  # [2][0]
152    assert_node(toctree[0][0],
153                [compact_paragraph, reference, "Welcome to Sphinx Tests’s documentation!"])
154    assert_node(toctree[0][1][2],
155                ([compact_paragraph, reference, "subsection"],
156                 [bullet_list, list_item, compact_paragraph, reference, "subsubsection"]))
157    assert_node(toctree[1][0],
158                [compact_paragraph, reference, "Test for issue #1157"])
159    assert_node(toctree[2][0],
160                [compact_paragraph, reference, "Indices and tables"])
161
162
163@pytest.mark.sphinx('xml', testroot='toctree')
164@pytest.mark.test_params(shared_result='test_environment_toctree_basic')
165def test_get_toc_for_only(app):
166    app.build()
167    builder = StandaloneHTMLBuilder(app)
168    toctree = TocTree(app.env).get_toc_for('index', builder)
169
170    assert_node(toctree,
171                [bullet_list, ([list_item, (compact_paragraph,  # [0][0]
172                                            [bullet_list, (addnodes.toctree,  # [0][1][0]
173                                                           list_item,  # [0][1][1]
174                                                           list_item)])],  # [0][1][2]
175                               [list_item, (compact_paragraph,  # [1][0]
176                                            [bullet_list, (addnodes.toctree,
177                                                           addnodes.toctree)])],
178                               [list_item, compact_paragraph])])  # [2][0]
179    assert_node(toctree[0][0],
180                [compact_paragraph, reference, "Welcome to Sphinx Tests’s documentation!"])
181    assert_node(toctree[0][1][1],
182                ([compact_paragraph, reference, "Section for HTML"],
183                 [bullet_list, addnodes.toctree]))
184    assert_node(toctree[0][1][2],
185                ([compact_paragraph, reference, "subsection"],
186                 [bullet_list, list_item, compact_paragraph, reference, "subsubsection"]))
187    assert_node(toctree[1][0],
188                [compact_paragraph, reference, "Test for issue #1157"])
189    assert_node(toctree[2][0],
190                [compact_paragraph, reference, "Indices and tables"])
191
192
193@pytest.mark.sphinx('xml', testroot='toctree')
194@pytest.mark.test_params(shared_result='test_environment_toctree_basic')
195def test_get_toc_for_tocdepth(app):
196    app.build()
197    toctree = TocTree(app.env).get_toc_for('tocdepth', app.builder)
198
199    assert_node(toctree,
200                [bullet_list, list_item, (compact_paragraph,  # [0][0]
201                                          bullet_list)])  # [0][1]
202    assert_node(toctree[0][0],
203                [compact_paragraph, reference, "level 1"])
204    assert_node(toctree[0][1],
205                [bullet_list, list_item, compact_paragraph, reference, "level 2"])
206
207
208@pytest.mark.sphinx('xml', testroot='toctree')
209@pytest.mark.test_params(shared_result='test_environment_toctree_basic')
210def test_get_toctree_for(app):
211    app.build()
212    toctree = TocTree(app.env).get_toctree_for('index', app.builder, collapse=False)
213    assert_node(toctree,
214                [compact_paragraph, ([caption, "Table of Contents"],
215                                     bullet_list,
216                                     bullet_list,
217                                     bullet_list)])
218
219    assert_node(toctree[1],
220                ([list_item, ([compact_paragraph, reference, "foo"],
221                              bullet_list)],
222                 [list_item, compact_paragraph, reference, "bar"],
223                 [list_item, compact_paragraph, reference, "http://sphinx-doc.org/"],
224                 [list_item, compact_paragraph, reference,
225                  "Welcome to Sphinx Tests’s documentation!"]))
226    assert_node(toctree[1][0][1],
227                ([list_item, compact_paragraph, reference, "quux"],
228                 [list_item, compact_paragraph, reference, "foo.1"],
229                 [list_item, compact_paragraph, reference, "foo.2"]))
230
231    assert_node(toctree[1][0][0][0], reference, refuri="foo", secnumber=[1])
232    assert_node(toctree[1][0][1][0][0][0], reference, refuri="quux", secnumber=[1, 1])
233    assert_node(toctree[1][0][1][1][0][0], reference, refuri="foo#foo-1", secnumber=[1, 2])
234    assert_node(toctree[1][0][1][2][0][0], reference, refuri="foo#foo-2", secnumber=[1, 3])
235    assert_node(toctree[1][1][0][0], reference, refuri="bar", secnumber=[2])
236    assert_node(toctree[1][2][0][0], reference, refuri="http://sphinx-doc.org/")
237    assert_node(toctree[1][3][0][0], reference, refuri="")
238
239    assert_node(toctree[2],
240                [bullet_list, list_item, compact_paragraph, reference, "baz"])
241    assert_node(toctree[3],
242                ([list_item, compact_paragraph, reference, "Latest reference"],
243                 [list_item, compact_paragraph, reference, "Python"]))
244    assert_node(toctree[3][0][0][0], reference, refuri="http://sphinx-doc.org/latest/")
245    assert_node(toctree[3][1][0][0], reference, refuri="http://python.org/")
246
247
248@pytest.mark.sphinx('xml', testroot='toctree')
249@pytest.mark.test_params(shared_result='test_environment_toctree_basic')
250def test_get_toctree_for_collapse(app):
251    app.build()
252    toctree = TocTree(app.env).get_toctree_for('index', app.builder, collapse=True)
253    assert_node(toctree,
254                [compact_paragraph, ([caption, "Table of Contents"],
255                                     bullet_list,
256                                     bullet_list,
257                                     bullet_list)])
258
259    assert_node(toctree[1],
260                ([list_item, compact_paragraph, reference, "foo"],
261                 [list_item, compact_paragraph, reference, "bar"],
262                 [list_item, compact_paragraph, reference, "http://sphinx-doc.org/"],
263                 [list_item, compact_paragraph, reference,
264                  "Welcome to Sphinx Tests’s documentation!"]))
265    assert_node(toctree[1][0][0][0], reference, refuri="foo", secnumber=[1])
266    assert_node(toctree[1][1][0][0], reference, refuri="bar", secnumber=[2])
267    assert_node(toctree[1][2][0][0], reference, refuri="http://sphinx-doc.org/")
268    assert_node(toctree[1][3][0][0], reference, refuri="")
269
270    assert_node(toctree[2],
271                [bullet_list, list_item, compact_paragraph, reference, "baz"])
272    assert_node(toctree[3],
273                ([list_item, compact_paragraph, reference, "Latest reference"],
274                 [list_item, compact_paragraph, reference, "Python"]))
275    assert_node(toctree[3][0][0][0], reference, refuri="http://sphinx-doc.org/latest/")
276    assert_node(toctree[3][1][0][0], reference, refuri="http://python.org/")
277
278
279@pytest.mark.sphinx('xml', testroot='toctree')
280@pytest.mark.test_params(shared_result='test_environment_toctree_basic')
281def test_get_toctree_for_maxdepth(app):
282    app.build()
283    toctree = TocTree(app.env).get_toctree_for('index', app.builder,
284                                               collapse=False, maxdepth=3)
285    assert_node(toctree,
286                [compact_paragraph, ([caption, "Table of Contents"],
287                                     bullet_list,
288                                     bullet_list,
289                                     bullet_list)])
290
291    assert_node(toctree[1],
292                ([list_item, ([compact_paragraph, reference, "foo"],
293                              bullet_list)],
294                 [list_item, compact_paragraph, reference, "bar"],
295                 [list_item, compact_paragraph, reference, "http://sphinx-doc.org/"],
296                 [list_item, compact_paragraph, reference,
297                  "Welcome to Sphinx Tests’s documentation!"]))
298    assert_node(toctree[1][0][1],
299                ([list_item, compact_paragraph, reference, "quux"],
300                 [list_item, ([compact_paragraph, reference, "foo.1"],
301                              bullet_list)],
302                 [list_item, compact_paragraph, reference, "foo.2"]))
303    assert_node(toctree[1][0][1][1][1],
304                [bullet_list, list_item, compact_paragraph, reference, "foo.1-1"])
305
306    assert_node(toctree[1][0][0][0], reference, refuri="foo", secnumber=[1])
307    assert_node(toctree[1][0][1][0][0][0], reference, refuri="quux", secnumber=[1, 1])
308    assert_node(toctree[1][0][1][1][0][0], reference, refuri="foo#foo-1", secnumber=[1, 2])
309    assert_node(toctree[1][0][1][1][1][0][0][0],
310                reference, refuri="foo#foo-1-1", secnumber=[1, 2, 1])
311    assert_node(toctree[1][0][1][2][0][0], reference, refuri="foo#foo-2", secnumber=[1, 3])
312    assert_node(toctree[1][1][0][0], reference, refuri="bar", secnumber=[2])
313    assert_node(toctree[1][2][0][0], reference, refuri="http://sphinx-doc.org/")
314    assert_node(toctree[1][3][0][0], reference, refuri="")
315
316    assert_node(toctree[2],
317                [bullet_list, list_item, compact_paragraph, reference, "baz"])
318    assert_node(toctree[3],
319                ([list_item, compact_paragraph, reference, "Latest reference"],
320                 [list_item, compact_paragraph, reference, "Python"]))
321    assert_node(toctree[3][0][0][0], reference, refuri="http://sphinx-doc.org/latest/")
322    assert_node(toctree[3][1][0][0], reference, refuri="http://python.org/")
323
324
325@pytest.mark.sphinx('xml', testroot='toctree')
326@pytest.mark.test_params(shared_result='test_environment_toctree_basic')
327def test_get_toctree_for_includehidden(app):
328    app.build()
329    toctree = TocTree(app.env).get_toctree_for('index', app.builder, collapse=False,
330                                               includehidden=False)
331    assert_node(toctree,
332                [compact_paragraph, ([caption, "Table of Contents"],
333                                     bullet_list,
334                                     bullet_list)])
335
336    assert_node(toctree[1],
337                ([list_item, ([compact_paragraph, reference, "foo"],
338                              bullet_list)],
339                 [list_item, compact_paragraph, reference, "bar"],
340                 [list_item, compact_paragraph, reference, "http://sphinx-doc.org/"],
341                 [list_item, compact_paragraph, reference,
342                  "Welcome to Sphinx Tests’s documentation!"]))
343    assert_node(toctree[1][0][1],
344                ([list_item, compact_paragraph, reference, "quux"],
345                 [list_item, compact_paragraph, reference, "foo.1"],
346                 [list_item, compact_paragraph, reference, "foo.2"]))
347
348    assert_node(toctree[1][0][0][0], reference, refuri="foo", secnumber=[1])
349    assert_node(toctree[1][0][1][0][0][0], reference, refuri="quux", secnumber=[1, 1])
350    assert_node(toctree[1][0][1][1][0][0], reference, refuri="foo#foo-1", secnumber=[1, 2])
351    assert_node(toctree[1][0][1][2][0][0], reference, refuri="foo#foo-2", secnumber=[1, 3])
352    assert_node(toctree[1][1][0][0], reference, refuri="bar", secnumber=[2])
353    assert_node(toctree[1][2][0][0], reference, refuri="http://sphinx-doc.org/")
354
355    assert_node(toctree[2],
356                [bullet_list, list_item, compact_paragraph, reference, "baz"])
357