2022-02-19 21:05:56 -06:00
|
|
|
"""Tests util.utils functions."""
|
2018-02-10 06:04:30 -06:00
|
|
|
|
2024-07-22 20:22:58 -05:00
|
|
|
from __future__ import annotations
|
|
|
|
|
2018-06-13 09:26:42 -05:00
|
|
|
import os
|
2024-07-22 20:22:58 -05:00
|
|
|
from typing import TYPE_CHECKING
|
2018-06-13 09:26:42 -05:00
|
|
|
|
2024-08-12 16:34:03 -05:00
|
|
|
import pytest
|
2018-02-10 06:04:30 -06:00
|
|
|
from docutils import nodes
|
|
|
|
|
2023-01-07 12:31:15 -06:00
|
|
|
from sphinx.util.docutils import (
|
|
|
|
SphinxFileOutput,
|
|
|
|
SphinxTranslator,
|
|
|
|
docutils_namespace,
|
|
|
|
new_document,
|
|
|
|
register_node,
|
|
|
|
)
|
2018-02-10 06:04:30 -06:00
|
|
|
|
2024-07-22 20:22:58 -05:00
|
|
|
if TYPE_CHECKING:
|
|
|
|
from sphinx.builders import Builder
|
|
|
|
|
2018-02-10 06:04:30 -06:00
|
|
|
|
|
|
|
def test_register_node():
|
|
|
|
class custom_node(nodes.Element):
|
|
|
|
pass
|
|
|
|
|
|
|
|
with docutils_namespace():
|
|
|
|
register_node(custom_node)
|
|
|
|
|
|
|
|
# check registered
|
|
|
|
assert hasattr(nodes.GenericNodeVisitor, 'visit_custom_node')
|
|
|
|
assert hasattr(nodes.GenericNodeVisitor, 'depart_custom_node')
|
|
|
|
assert hasattr(nodes.SparseNodeVisitor, 'visit_custom_node')
|
|
|
|
assert hasattr(nodes.SparseNodeVisitor, 'depart_custom_node')
|
|
|
|
|
|
|
|
# check unregistered outside namespace
|
|
|
|
assert not hasattr(nodes.GenericNodeVisitor, 'visit_custom_node')
|
|
|
|
assert not hasattr(nodes.GenericNodeVisitor, 'depart_custom_node')
|
|
|
|
assert not hasattr(nodes.SparseNodeVisitor, 'visit_custom_node')
|
|
|
|
assert not hasattr(nodes.SparseNodeVisitor, 'depart_custom_node')
|
2018-06-13 09:26:42 -05:00
|
|
|
|
|
|
|
|
2025-01-14 08:43:02 -06:00
|
|
|
def test_SphinxFileOutput(tmp_path):
|
2018-06-13 09:26:42 -05:00
|
|
|
content = 'Hello Sphinx World'
|
|
|
|
|
|
|
|
# write test.txt at first
|
2025-01-14 08:43:02 -06:00
|
|
|
filename = tmp_path / 'test.txt'
|
|
|
|
output = SphinxFileOutput(destination_path=str(filename))
|
2018-06-13 09:26:42 -05:00
|
|
|
output.write(content)
|
2024-07-23 08:52:31 -05:00
|
|
|
os.utime(filename, ns=(0, 0))
|
2018-06-13 09:26:42 -05:00
|
|
|
|
2021-09-07 19:15:25 -05:00
|
|
|
# overwrite it again
|
2018-06-13 09:26:42 -05:00
|
|
|
output.write(content)
|
2025-01-14 08:43:02 -06:00
|
|
|
assert filename.stat().st_mtime_ns != 0 # updated
|
2018-06-13 09:26:42 -05:00
|
|
|
|
|
|
|
# write test2.txt at first
|
2025-01-14 08:43:02 -06:00
|
|
|
filename = tmp_path / 'test2.txt'
|
|
|
|
output = SphinxFileOutput(destination_path=str(filename), overwrite_if_changed=True)
|
2018-06-13 09:26:42 -05:00
|
|
|
output.write(content)
|
2024-07-23 08:52:31 -05:00
|
|
|
os.utime(filename, ns=(0, 0))
|
2018-06-13 09:26:42 -05:00
|
|
|
|
2021-09-07 19:15:25 -05:00
|
|
|
# overwrite it again
|
2018-06-13 09:26:42 -05:00
|
|
|
output.write(content)
|
2025-01-14 08:43:02 -06:00
|
|
|
assert filename.stat().st_mtime_ns == 0 # not updated
|
2018-06-13 09:26:42 -05:00
|
|
|
|
2021-09-07 19:15:25 -05:00
|
|
|
# overwrite it again (content changed)
|
2024-08-11 08:58:56 -05:00
|
|
|
output.write(content + '; content change')
|
2025-01-14 08:43:02 -06:00
|
|
|
assert filename.stat().st_mtime_ns != 0 # updated
|
2020-01-10 07:50:43 -06:00
|
|
|
|
|
|
|
|
2024-08-12 16:34:03 -05:00
|
|
|
@pytest.mark.sphinx('html', testroot='root')
|
2020-01-10 07:50:43 -06:00
|
|
|
def test_SphinxTranslator(app):
|
|
|
|
class CustomNode(nodes.inline):
|
|
|
|
pass
|
|
|
|
|
|
|
|
class MyTranslator(SphinxTranslator):
|
2024-07-22 20:22:58 -05:00
|
|
|
def __init__(self, document: nodes.document, builder: Builder):
|
|
|
|
self.called: list[str] = []
|
|
|
|
super().__init__(document, builder)
|
2020-01-10 07:50:43 -06:00
|
|
|
|
|
|
|
def visit_document(self, node):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def depart_document(self, node):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def visit_inline(self, node):
|
|
|
|
self.called.append('visit_inline')
|
|
|
|
|
|
|
|
def depart_inline(self, node):
|
|
|
|
self.called.append('depart_inline')
|
|
|
|
|
|
|
|
document = new_document('')
|
|
|
|
document += CustomNode()
|
|
|
|
|
|
|
|
translator = MyTranslator(document, app.builder)
|
|
|
|
document.walkabout(translator)
|
|
|
|
|
|
|
|
# MyTranslator does not have visit_CustomNode. But it calls visit_inline instead.
|
|
|
|
assert translator.called == ['visit_inline', 'depart_inline']
|