1"""
2    test_util_docutils
3    ~~~~~~~~~~~~~~~~~~
4
5    Tests util.utils functions.
6
7    :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
8    :license: BSD, see LICENSE for details.
9"""
10
11import os
12
13from docutils import nodes
14
15from sphinx.util.docutils import (SphinxFileOutput, SphinxTranslator, docutils_namespace,
16                                  new_document, register_node)
17
18
19def test_register_node():
20    class custom_node(nodes.Element):
21        pass
22
23    with docutils_namespace():
24        register_node(custom_node)
25
26        # check registered
27        assert hasattr(nodes.GenericNodeVisitor, 'visit_custom_node')
28        assert hasattr(nodes.GenericNodeVisitor, 'depart_custom_node')
29        assert hasattr(nodes.SparseNodeVisitor, 'visit_custom_node')
30        assert hasattr(nodes.SparseNodeVisitor, 'depart_custom_node')
31
32    # check unregistered outside namespace
33    assert not hasattr(nodes.GenericNodeVisitor, 'visit_custom_node')
34    assert not hasattr(nodes.GenericNodeVisitor, 'depart_custom_node')
35    assert not hasattr(nodes.SparseNodeVisitor, 'visit_custom_node')
36    assert not hasattr(nodes.SparseNodeVisitor, 'depart_custom_node')
37
38
39def test_SphinxFileOutput(tmpdir):
40    content = 'Hello Sphinx World'
41
42    # write test.txt at first
43    filename = str(tmpdir / 'test.txt')
44    output = SphinxFileOutput(destination_path=filename)
45    output.write(content)
46    os.utime(filename, (0, 0))
47
48    # overrite it again
49    output.write(content)
50    assert os.stat(filename).st_mtime != 0  # updated
51
52    # write test2.txt at first
53    filename = str(tmpdir / 'test2.txt')
54    output = SphinxFileOutput(destination_path=filename, overwrite_if_changed=True)
55    output.write(content)
56    os.utime(filename, (0, 0))
57
58    # overrite it again
59    output.write(content)
60    assert os.stat(filename).st_mtime == 0  # not updated
61
62    # overrite it again (content changed)
63    output.write(content + "; content change")
64    assert os.stat(filename).st_mtime != 0  # updated
65
66
67def test_SphinxTranslator(app):
68    class CustomNode(nodes.inline):
69        pass
70
71    class MyTranslator(SphinxTranslator):
72        def __init__(self, *args):
73            self.called = []
74            super().__init__(*args)
75
76        def visit_document(self, node):
77            pass
78
79        def depart_document(self, node):
80            pass
81
82        def visit_inline(self, node):
83            self.called.append('visit_inline')
84
85        def depart_inline(self, node):
86            self.called.append('depart_inline')
87
88    document = new_document('')
89    document += CustomNode()
90
91    translator = MyTranslator(document, app.builder)
92    document.walkabout(translator)
93
94    # MyTranslator does not have visit_CustomNode. But it calls visit_inline instead.
95    assert translator.called == ['visit_inline', 'depart_inline']
96