summaryrefslogtreecommitdiffstats
path: root/tests/test_util/test_util_fileutil.py
blob: 2071fc3fade11980ca91db7664618f54cb18dd9e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
"""Tests sphinx.util.fileutil functions."""

from unittest import mock

import pytest

from sphinx.jinja2glue import BuiltinTemplateLoader
from sphinx.util import strip_colors
from sphinx.util.fileutil import _template_basename, copy_asset, copy_asset_file


class DummyTemplateLoader(BuiltinTemplateLoader):
    def __init__(self):
        super().__init__()
        builder = mock.Mock()
        builder.config.templates_path = []
        builder.app.translator = None
        self.init(builder)


def test_copy_asset_file(tmp_path):
    renderer = DummyTemplateLoader()

    # copy normal file
    src = (tmp_path / 'asset.txt')
    src.write_text('# test data', encoding='utf8')
    dest = (tmp_path / 'output.txt')

    copy_asset_file(src, dest)
    assert dest.exists()
    assert src.read_text(encoding='utf8') == dest.read_text(encoding='utf8')

    # copy template file
    src = (tmp_path / 'asset.txt.jinja')
    src.write_text('# {{var1}} data', encoding='utf8')
    dest = (tmp_path / 'output.txt.jinja')

    copy_asset_file(str(src), str(dest), {'var1': 'template'}, renderer)
    assert not dest.exists()
    assert (tmp_path / 'output.txt').exists()
    assert (tmp_path / 'output.txt').read_text(encoding='utf8') == '# template data'

    # copy template file to subdir
    src = (tmp_path / 'asset.txt.jinja')
    src.write_text('# {{var1}} data', encoding='utf8')
    subdir1 = (tmp_path / 'subdir')
    subdir1.mkdir(parents=True, exist_ok=True)

    copy_asset_file(src, subdir1, {'var1': 'template'}, renderer)
    assert (subdir1 / 'asset.txt').exists()
    assert (subdir1 / 'asset.txt').read_text(encoding='utf8') == '# template data'

    # copy template file without context
    src = (tmp_path / 'asset.txt.jinja')
    subdir2 = (tmp_path / 'subdir2')
    subdir2.mkdir(parents=True, exist_ok=True)

    copy_asset_file(src, subdir2)
    assert not (subdir2 / 'asset.txt').exists()
    assert (subdir2 / 'asset.txt.jinja').exists()
    assert (subdir2 / 'asset.txt.jinja').read_text(encoding='utf8') == '# {{var1}} data'


def test_copy_asset(tmp_path):
    renderer = DummyTemplateLoader()

    # prepare source files
    source = (tmp_path / 'source')
    source.mkdir(parents=True, exist_ok=True)
    (source / 'index.rst').write_text('index.rst', encoding='utf8')
    (source / 'foo.rst.jinja').write_text('{{var1}}.rst', encoding='utf8')
    (source / '_static').mkdir(parents=True, exist_ok=True)
    (source / '_static' / 'basic.css').write_text('basic.css', encoding='utf8')
    (source / '_templates').mkdir(parents=True, exist_ok=True)
    (source / '_templates' / 'layout.html').write_text('layout.html', encoding='utf8')
    (source / '_templates' / 'sidebar.html.jinja').write_text('sidebar: {{var2}}', encoding='utf8')

    # copy a single file
    assert not (tmp_path / 'test1').exists()
    copy_asset(source / 'index.rst', tmp_path / 'test1')
    assert (tmp_path / 'test1').exists()
    assert (tmp_path / 'test1/index.rst').exists()

    # copy directories
    destdir = tmp_path / 'test2'
    copy_asset(source, destdir, context={'var1': 'bar', 'var2': 'baz'}, renderer=renderer)
    assert (destdir / 'index.rst').exists()
    assert (destdir / 'foo.rst').exists()
    assert (destdir / 'foo.rst').read_text(encoding='utf8') == 'bar.rst'
    assert (destdir / '_static' / 'basic.css').exists()
    assert (destdir / '_templates' / 'layout.html').exists()
    assert (destdir / '_templates' / 'sidebar.html').exists()
    assert (destdir / '_templates' / 'sidebar.html').read_text(encoding='utf8') == 'sidebar: baz'

    # copy with exclusion
    def excluded(path):
        return ('sidebar.html' in path or 'basic.css' in path)

    destdir = tmp_path / 'test3'
    copy_asset(source, destdir, excluded,
               context={'var1': 'bar', 'var2': 'baz'}, renderer=renderer)
    assert (destdir / 'index.rst').exists()
    assert (destdir / 'foo.rst').exists()
    assert not (destdir / '_static' / 'basic.css').exists()
    assert (destdir / '_templates' / 'layout.html').exists()
    assert not (destdir / '_templates' / 'sidebar.html').exists()


@pytest.mark.sphinx('html', testroot='util-copyasset_overwrite')
def test_copy_asset_overwrite(app):
    app.build()
    src = app.srcdir / 'myext_static' / 'custom-styles.css'
    dst = app.outdir / '_static' / 'custom-styles.css'
    assert (
        f'Copying the source path {src} to {dst} will overwrite data, '
        'as a file already exists at the destination path '
        'and the content does not match.\n'
    ) in strip_colors(app.status.getvalue())


def test_template_basename():
    assert _template_basename('asset.txt') is None
    assert _template_basename('asset.txt.jinja') == 'asset.txt'
    assert _template_basename('sidebar.html.jinja') == 'sidebar.html'


def test_legacy_template_basename():
    assert _template_basename('asset.txt_t') == 'asset.txt'