summaryrefslogtreecommitdiff
path: root/docutils/test/test_functional.py
blob: 9f308c621fcb883649b0a1e0e5d85fbfafab0b21 (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
#!/usr/bin/env python3
# $Id$
# Author: Lea Wiemann <LeWiemann@gmail.com>
# Copyright: This module has been placed in the public domain.

"""
Perform tests with the data in the functional/ directory.

Please see the documentation on `functional testing`__ for details.

__ ../../docs/dev/testing.html#functional
"""

from pathlib import Path
import shutil
import sys
import unittest

if __name__ == '__main__':
    # prepend the "docutils root" to the Python library path
    # so we import the local `docutils` package.
    sys.path.insert(0, str(Path(__file__).resolve().parents[1]))

from docutils import core, SettingsSpec

FUNCTIONAL = Path('functional')
EXPECTED = FUNCTIONAL / 'expected'
INPUT = FUNCTIONAL / 'input'
OUTPUT = FUNCTIONAL / 'output'
TESTS = FUNCTIONAL / 'tests'

NO_EXPECTED_TEMPLATE = """\
Cannot find expected output at {exp}
If the output in {out}
is correct, move it to the expected/ dir and check it in:

  mv {out} {exp}
  svn add {exp}
  svn commit -m "<comment>" {exp}
"""

EXPECTED_OUTPUT_DIFFERS_TEMPLATE = """\
The expected and actual output differs.
Please compare the expected and actual output files:

  diff {exp} {out}

If the actual output is correct, please replace the
expected output and check it in:

  mv {out} {exp}
  svn add {exp}
  svn commit -m "<comment>" {exp}
"""

# Default settings for functional tests.
# Override "factory defaults",
# overridden by `settings_overrides` in the individual tests.
# cf. docs/api/runtime-settings.html#settings-priority
functional_tests_settings_spec = SettingsSpec()
functional_tests_settings_spec.settings_default_overrides = {
    '_disable_config': True,
    'halt_level': 5,
    'warning_stream': '',
    'input_encoding': 'utf-8',  # skip auto-detection
    'embed_stylesheet': False,
    'syntax_highlight': 'none'  # avoid "Pygments not found" warning
    }


class FunctionalTests(unittest.TestCase):

    """Test case for one config file."""
    maxDiff = None

    def setUp(self):
        """Clear output directory."""
        for entry in OUTPUT.rglob('*'):
            if entry.is_dir():
                shutil.rmtree(entry)
            elif entry.name != 'README.txt':
                entry.unlink()

    def test_functional(self):
        """Process test file."""
        for test_file in TESTS.glob("*.py"):
            with self.subTest(test_file=test_file.as_posix()):
                namespace = {}
                # Load variables from the current test file into the namespace
                exec(test_file.read_text(encoding='utf-8'), namespace)
                del namespace['__builtins__']  # clean-up

                # Full source, generated output, and expected output paths
                source_path = INPUT / namespace.pop('test_source')
                destination_path = OUTPUT / namespace['test_destination']
                expected_path = EXPECTED / namespace.pop('test_destination')

                # Get output (automatically written to the output/ directory
                # by publish_file):
                output = core.publish_file(
                    **namespace,
                    source_path=source_path.as_posix(),
                    destination_path=destination_path.as_posix(),
                    settings_spec=functional_tests_settings_spec,
                )

                # Get the expected output *after* writing the actual output.
                try:
                    expected = expected_path.read_text(encoding='utf-8')
                except OSError as err:
                    raise OSError(NO_EXPECTED_TEMPLATE.format(
                        exp=expected_path, out=destination_path)
                    ) from err

                self.assertEqual(output, expected,
                                 EXPECTED_OUTPUT_DIFFERS_TEMPLATE.format(
                                     exp=expected_path, out=destination_path)
                                 )


if __name__ == '__main__':
    unittest.main()