File: test_functional.py

package info (click to toggle)
python-docutils 0.21.2%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 10,900 kB
  • sloc: python: 50,310; lisp: 14,475; xml: 1,810; javascript: 1,032; makefile: 107; sh: 78
file content (129 lines) | stat: -rwxr-xr-x 4,309 bytes parent folder | download
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
129
#!/usr/bin/env python3
# $Id: test_functional.py 9518 2024-01-26 22:46:31Z milde $
# 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
"""

import difflib
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 = """\
Expected and actual output differ.

{diff}

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
    }


def compare_output(output, destination_path, expected_path):

    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
    if output != expected:
        diff = ''.join(difflib.unified_diff(expected.splitlines(True),
                                            output.splitlines(True),
                                            expected_path.as_posix(),
                                            destination_path.as_posix()))
        raise AssertionError(
                  EXPECTED_OUTPUT_DIFFERS_TEMPLATE.format(
                      diff=diff, exp=expected_path, out=destination_path)
                  )


class FunctionalTests(unittest.TestCase):

    """Test case for one config file."""

    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.
                compare_output(output, destination_path, expected_path)


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