2 # -*- coding: utf-8 -*-
5 # Author: David Goodger <goodger@python.org>
6 # Copyright: This module has been placed in the public domain.
9 Tests of runtime settings.
11 from __future__
import print_function
19 import DocutilsTestSupport
# must be imported before docutils
20 from docutils
import frontend
, utils
21 from docutils
.writers
import html4css1
, pep_html
22 from docutils
.parsers
import rst
25 warnings
.filterwarnings(action
='ignore',
26 category
=frontend
.ConfigDeprecationWarning
)
30 return os
.path
.abspath(os
.path
.join(*(path
.split('/'))))
33 class ConfigFileTests(unittest
.TestCase
):
35 config_files
= {'old': fixpath('data/config_old.txt'),
36 'one': fixpath('data/config_1.txt'),
37 'two': fixpath('data/config_2.txt'),
38 'list': fixpath('data/config_list.txt'),
39 'list2': fixpath('data/config_list_2.txt'),
40 'error': fixpath('data/config_error_handler.txt')}
43 'old': {u
'datestamp': u
'%Y-%m-%d %H:%M UTC',
46 u
'python_home': u
'http://www.python.org',
49 u
'stylesheet_path': [u
'stylesheets/pep.css'],
50 'template': fixpath(u
'data/pep-html-template')},
51 'one': {u
'datestamp': u
'%Y-%m-%d %H:%M UTC',
54 u
'python_home': u
'http://www.python.org',
55 u
'raw_enabled': False,
56 'record_dependencies': utils
.DependencyList(),
59 u
'stylesheet_path': [u
'stylesheets/pep.css'],
61 u
'template': fixpath(u
'data/pep-html-template'),
62 u
'trim_footnote_reference_space': True,
64 'two': {u
'footnote_references': u
'superscript',
66 'record_dependencies': utils
.DependencyList(),
68 u
'stylesheet_path': [u
'test.css'],
69 'trim_footnote_reference_space': None},
70 'list': {u
'expose_internals': [u
'a', u
'b', u
'c', u
'd', u
'e'],
71 u
'strip_classes': [u
'spam', u
'pan', u
'fun', u
'parrot'],
72 u
'strip_elements_with_classes': [u
'sugar', u
'flour', u
'milk',
74 'list2': {u
'expose_internals': [u
'a', u
'b', u
'c', u
'd', u
'e', u
'f'],
75 u
'strip_classes': [u
'spam', u
'pan', u
'fun', u
'parrot',
77 u
'strip_elements_with_classes': [u
'sugar', u
'flour',
80 'error': {u
'error_encoding': u
'ascii',
81 u
'error_encoding_error_handler': u
'strict'},
84 compare
= difflib
.Differ().compare
85 """Comparison method shared by all tests."""
88 self
.option_parser
= frontend
.OptionParser(
89 components
=(pep_html
.Writer
, rst
.Parser
), read_config_files
=None)
91 def files_settings(self
, *names
):
92 settings
= frontend
.Values()
94 settings
.update(self
.option_parser
.get_config_file_settings(
95 self
.config_files
[name
]), self
.option_parser
)
96 return settings
.__dict
__
98 def expected_settings(self
, *names
):
101 expected
.update(self
.settings
[name
])
104 def compare_output(self
, result
, expected
):
105 """`result` and `expected` should both be dicts."""
106 self
.assertTrue('record_dependencies' in result
)
107 if 'record_dependencies' not in expected
:
108 # Delete it if we don't want to test it.
109 del result
['record_dependencies']
110 result
= pprint
.pformat(result
) + '\n'
111 expected
= pprint
.pformat(expected
) + '\n'
113 self
.assertEqual(result
, expected
)
114 except AssertionError:
115 print('\n%s\n' % (self
,), file=sys
.stderr
)
116 print('-: expected\n+: result', file=sys
.stderr
)
117 print(''.join(self
.compare(expected
.splitlines(1),
118 result
.splitlines(1))), file=sys
.stderr
)
121 def test_nofiles(self
):
122 self
.compare_output(self
.files_settings(),
123 self
.expected_settings())
126 self
.compare_output(self
.files_settings('old'),
127 self
.expected_settings('old'))
130 self
.compare_output(self
.files_settings('one'),
131 self
.expected_settings('one'))
133 def test_multiple(self
):
134 self
.compare_output(self
.files_settings('one', 'two'),
135 self
.expected_settings('one', 'two'))
137 def test_old_and_new(self
):
138 self
.compare_output(self
.files_settings('old', 'two'),
139 self
.expected_settings('old', 'two'))
142 self
.compare_output(self
.files_settings('list'),
143 self
.expected_settings('list'))
145 def test_list2(self
):
146 self
.compare_output(self
.files_settings('list', 'list2'),
147 self
.expected_settings('list2'))
149 def test_error_handler(self
):
150 self
.compare_output(self
.files_settings('error'),
151 self
.expected_settings('error'))
154 class ConfigEnvVarFileTests(ConfigFileTests
):
157 Repeats the tests of `ConfigFileTests` using the ``DOCUTILSCONFIG``
158 environment variable and the standard Docutils config file mechanism.
162 ConfigFileTests
.setUp(self
)
163 self
.orig_environ
= os
.environ
164 os
.environ
= os
.environ
.copy()
166 def files_settings(self
, *names
):
167 files
= [self
.config_files
[name
] for name
in names
]
168 os
.environ
['DOCUTILSCONFIG'] = os
.pathsep
.join(files
)
169 settings
= self
.option_parser
.get_standard_config_settings()
170 return settings
.__dict
__
173 os
.environ
= self
.orig_environ
176 class HelperFunctionsTests(unittest
.TestCase
):
178 pathdict
= {'foo': 'hallo', 'ham': u
'h\xE4m', 'spam': u
'spam'}
179 keys
= ['foo', 'ham']
182 self
.option_parser
= frontend
.OptionParser(
183 components
=(rst
.Parser
,), read_config_files
=None)
185 def test_make_paths_absolute(self
):
186 pathdict
= self
.pathdict
.copy()
187 frontend
.make_paths_absolute(pathdict
, self
.keys
, base_path
='base')
188 self
.assertEqual(pathdict
['foo'], os
.path
.abspath('base/hallo'))
189 self
.assertEqual(pathdict
['ham'], os
.path
.abspath(u
'base/h\xE4m'))
190 # not touched, because key not in keys:
191 self
.assertEqual(pathdict
['spam'], u
'spam')
193 def test_make_paths_absolute_cwd(self
):
194 # With base_path None, the cwd is used as base path.
195 # Settings values may-be `unicode` instances, therefore
196 # os.getcwdu() is used and the converted path is a unicode instance:
197 pathdict
= self
.pathdict
.copy()
198 frontend
.make_paths_absolute(pathdict
, self
.keys
)
199 self
.assertEqual(pathdict
['foo'], os
.path
.abspath(u
'hallo'))
200 self
.assertEqual(pathdict
['ham'], os
.path
.abspath(u
'h\xE4m'))
201 # not touched, because key not in keys:
202 self
.assertEqual(pathdict
['spam'], u
'spam')
215 def test_validate_boolean(self
):
216 for t
in self
.boolean_settings
:
218 frontend
.validate_boolean(None, t
[0], self
.option_parser
),
221 def test_validate_ternary(self
):
224 (u
'parrot', u
'parrot'),
226 for t
in self
.boolean_settings
+ tests
:
228 frontend
.validate_ternary(None, t
[0], self
.option_parser
),
231 def test_validate_colon_separated_string_list(self
):
235 (u
'a:b', ['a', 'b'] ),
236 ('a:b', ['a', 'b'] ),
238 ([u
'a', u
'b:c'], ['a', 'b', 'c'] ),
242 frontend
.validate_colon_separated_string_list(None, t
[0], None),
245 def test_validate_comma_separated_list(self
):
249 (u
'a,b', ['a', 'b'] ),
250 ('a,b', ['a', 'b'] ),
252 ([u
'a', u
'b,c'], ['a', 'b', 'c'] ),
253 (['a', 'b,c'], ['a', 'b', 'c'] ),
257 frontend
.validate_comma_separated_list(None, t
[0], None),
260 def test_validate_url_trailing_slash(self
):
264 (u
'http://example.org', u
'http://example.org/' ),
265 ('http://example.org/', 'http://example.org/' ),
269 frontend
.validate_url_trailing_slash(None, t
[0], None),
272 def test_validate_smartquotes_locales(self
):
274 ('en:ssvv', [('en', 'ssvv')]),
275 (u
'sd:«»°°', [(u
'sd', u
'«»°°')]),
276 ([('sd', u
'«»°°'), u
'ds:°°«»'], [('sd', u
'«»°°'),
278 (u
'frs:« : »:((:))', [(u
'frs', [u
'« ', u
' »',
283 frontend
.validate_smartquotes_locales(None, t
[0], None),
288 if __name__
== '__main__':