* Consolidated version numbering documentation in docs/dev/policies.txt (moved text...
[docutils.git] / docutils / test / test_settings.py
blob335167436036fd5da32fa8434c123b0df5a19d09
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
4 # $Id$
5 # Author: David Goodger <goodger@python.org>
6 # Copyright: This module has been placed in the public domain.
8 """
9 Tests of runtime settings.
10 """
12 import sys
13 import os
14 import difflib
15 import pprint
16 import warnings
17 import unittest
18 import DocutilsTestSupport # must be imported before docutils
19 from docutils import frontend, utils
20 from docutils.writers import html4css1, pep_html
21 from docutils.parsers import rst
24 warnings.filterwarnings(action='ignore',
25 category=frontend.ConfigDeprecationWarning)
28 def fixpath(path):
29 return os.path.abspath(os.path.join(*(path.split('/'))))
32 class ConfigFileTests(unittest.TestCase):
34 config_files = {'old': fixpath('data/config_old.txt'),
35 'one': fixpath('data/config_1.txt'),
36 'two': fixpath('data/config_2.txt'),
37 'list': fixpath('data/config_list.txt'),
38 'list2': fixpath('data/config_list_2.txt'),
39 'error': fixpath('data/config_error_handler.txt')}
41 settings = {
42 'old': {u'datestamp': u'%Y-%m-%d %H:%M UTC',
43 u'generator': True,
44 u'no_random': True,
45 u'python_home': u'http://www.python.org',
46 u'source_link': True,
47 'stylesheet': None,
48 u'stylesheet_path': [u'stylesheets/pep.css'],
49 'template': fixpath(u'data/pep-html-template')},
50 'one': {u'datestamp': u'%Y-%m-%d %H:%M UTC',
51 u'generator': True,
52 u'no_random': True,
53 u'python_home': u'http://www.python.org',
54 u'raw_enabled': False,
55 'record_dependencies': utils.DependencyList(),
56 u'source_link': True,
57 'stylesheet': None,
58 u'stylesheet_path': [u'stylesheets/pep.css'],
59 u'tab_width': 8,
60 u'template': fixpath(u'data/pep-html-template'),
61 u'trim_footnote_reference_space': True,
63 'two': {u'footnote_references': u'superscript',
64 u'generator': False,
65 'record_dependencies': utils.DependencyList(),
66 u'stylesheet': None,
67 u'stylesheet_path': [u'test.css'],
68 'trim_footnote_reference_space': None},
69 'list': {u'expose_internals': [u'a', u'b', u'c', u'd', u'e'],
70 u'strip_classes': [u'spam', u'pan', u'fun', u'parrot'],
71 u'strip_elements_with_classes': [u'sugar', u'flour', u'milk',
72 u'safran']},
73 'list2': {u'expose_internals': [u'a', u'b', u'c', u'd', u'e', u'f'],
74 u'strip_classes': [u'spam', u'pan', u'fun', u'parrot',
75 u'ham', u'eggs'],
76 u'strip_elements_with_classes': [u'sugar', u'flour',
77 u'milk', u'safran',
78 u'eggs', u'salt']},
79 'error': {u'error_encoding': u'ascii',
80 u'error_encoding_error_handler': u'strict'},
83 compare = difflib.Differ().compare
84 """Comparison method shared by all tests."""
86 def setUp(self):
87 self.option_parser = frontend.OptionParser(
88 components=(pep_html.Writer, rst.Parser), read_config_files=None)
90 def files_settings(self, *names):
91 settings = frontend.Values()
92 for name in names:
93 settings.update(self.option_parser.get_config_file_settings(
94 self.config_files[name]), self.option_parser)
95 return settings.__dict__
97 def expected_settings(self, *names):
98 expected = {}
99 for name in names:
100 expected.update(self.settings[name])
101 return expected
103 def compare_output(self, result, expected):
104 """`result` and `expected` should both be dicts."""
105 self.assertTrue('record_dependencies' in result)
106 if 'record_dependencies' not in expected:
107 # Delete it if we don't want to test it.
108 del result['record_dependencies']
109 result = pprint.pformat(result) + '\n'
110 expected = pprint.pformat(expected) + '\n'
111 try:
112 self.assertEqual(result, expected)
113 except AssertionError:
114 print >>sys.stderr, '\n%s\n' % (self,)
115 print >>sys.stderr, '-: expected\n+: result'
116 print >>sys.stderr, ''.join(self.compare(expected.splitlines(1),
117 result.splitlines(1)))
118 raise
120 def test_nofiles(self):
121 self.compare_output(self.files_settings(),
122 self.expected_settings())
124 def test_old(self):
125 self.compare_output(self.files_settings('old'),
126 self.expected_settings('old'))
128 def test_one(self):
129 self.compare_output(self.files_settings('one'),
130 self.expected_settings('one'))
132 def test_multiple(self):
133 self.compare_output(self.files_settings('one', 'two'),
134 self.expected_settings('one', 'two'))
136 def test_old_and_new(self):
137 self.compare_output(self.files_settings('old', 'two'),
138 self.expected_settings('old', 'two'))
140 def test_list(self):
141 self.compare_output(self.files_settings('list'),
142 self.expected_settings('list'))
144 def test_list2(self):
145 self.compare_output(self.files_settings('list', 'list2'),
146 self.expected_settings('list2'))
148 def test_error_handler(self):
149 self.compare_output(self.files_settings('error'),
150 self.expected_settings('error'))
153 class ConfigEnvVarFileTests(ConfigFileTests):
156 Repeats the tests of `ConfigFileTests` using the ``DOCUTILSCONFIG``
157 environment variable and the standard Docutils config file mechanism.
160 def setUp(self):
161 ConfigFileTests.setUp(self)
162 self.orig_environ = os.environ
163 os.environ = os.environ.copy()
165 def files_settings(self, *names):
166 files = [self.config_files[name] for name in names]
167 os.environ['DOCUTILSCONFIG'] = os.pathsep.join(files)
168 settings = self.option_parser.get_standard_config_settings()
169 return settings.__dict__
171 def tearDown(self):
172 os.environ = self.orig_environ
175 class HelperFunctionsTests(unittest.TestCase):
177 pathdict = {'foo': 'hallo', 'ham': u'h\xE4m', 'spam': u'spam'}
178 keys = ['foo', 'ham']
180 def setUp(self):
181 self.option_parser = frontend.OptionParser(
182 components=(rst.Parser,), read_config_files=None)
184 def test_make_paths_absolute(self):
185 pathdict = self.pathdict.copy()
186 frontend.make_paths_absolute(pathdict, self.keys, base_path='base')
187 self.assertEqual(pathdict['foo'], os.path.abspath('base/hallo'))
188 self.assertEqual(pathdict['ham'], os.path.abspath(u'base/h\xE4m'))
189 # not touched, because key not in keys:
190 self.assertEqual(pathdict['spam'], u'spam')
192 def test_make_paths_absolute_cwd(self):
193 # With base_path None, the cwd is used as base path.
194 # Settings values may-be `unicode` instances, therefore
195 # os.getcwdu() is used and the converted path is a unicode instance:
196 pathdict = self.pathdict.copy()
197 frontend.make_paths_absolute(pathdict, self.keys)
198 self.assertEqual(pathdict['foo'], os.path.abspath(u'hallo'))
199 self.assertEqual(pathdict['ham'], os.path.abspath(u'h\xE4m'))
200 # not touched, because key not in keys:
201 self.assertEqual(pathdict['spam'], u'spam')
203 boolean_settings = (
204 (True, True ),
205 ('1', True ),
206 (u'on', True ),
207 ('yes', True ),
208 (u'true', True ),
209 (u'0', False ),
210 ('off', False ),
211 (u'no', False ),
212 ('false', False ),
214 def test_validate_boolean(self):
215 for t in self.boolean_settings:
216 self.assertEqual(
217 frontend.validate_boolean(None, t[0], self.option_parser),
218 t[1])
220 def test_validate_ternary(self):
221 tests = (
222 ('500V', '500V'),
223 (u'parrot', u'parrot'),
225 for t in self.boolean_settings + tests:
226 self.assertEqual(
227 frontend.validate_ternary(None, t[0], self.option_parser),
228 t[1])
230 def test_validate_colon_separated_string_list(self):
231 tests = (
232 (u'a', ['a',] ),
233 ('a', ['a',] ),
234 (u'a:b', ['a', 'b'] ),
235 ('a:b', ['a', 'b'] ),
236 ([u'a',], ['a',] ),
237 ([u'a', u'b:c'], ['a', 'b', 'c'] ),
239 for t in tests:
240 self.assertEqual(
241 frontend.validate_colon_separated_string_list(None, t[0], None),
242 t[1])
244 def test_validate_comma_separated_list(self):
245 tests = (
246 (u'a', ['a',] ),
247 ('a', ['a',] ),
248 (u'a,b', ['a', 'b'] ),
249 ('a,b', ['a', 'b'] ),
250 ([u'a',], ['a',] ),
251 ([u'a', u'b,c'], ['a', 'b', 'c'] ),
252 (['a', 'b,c'], ['a', 'b', 'c'] ),
254 for t in tests:
255 self.assertEqual(
256 frontend.validate_comma_separated_list(None, t[0], None),
257 t[1])
259 def test_validate_url_trailing_slash(self):
260 tests = (
261 ('', './' ),
262 (None, './' ),
263 (u'http://example.org', u'http://example.org/' ),
264 ('http://example.org/', 'http://example.org/' ),
266 for t in tests:
267 self.assertEqual(
268 frontend.validate_url_trailing_slash(None, t[0], None),
269 t[1])
271 def test_validate_smartquotes_locales(self):
272 tests = (
273 ('en:ssvv', [('en', 'ssvv')]),
274 (u'sd:«»°°', [(u'sd', u'«»°°')]),
275 ([('sd', u'«»°°'), u'ds:°°«»'], [('sd', u'«»°°'),
276 ('ds', u'°°«»')]),
277 (u'frs:« : »:((:))', [(u'frs', [u'« ', u' »',
278 u'((', u'))'])]),
280 for t in tests:
281 self.assertEqual(
282 frontend.validate_smartquotes_locales(None, t[0], None),
283 t[1])
287 if __name__ == '__main__':
288 unittest.main()