latex2e writer : Move usepackage hyperref after stylesheet inclusion.
[docutils.git] / test / test_language.py
blob3f929bd052acae1fc69bdbbb2ad0fb288e0cb702
1 #!/usr/bin/env python
3 # $Id$
4 # Authors: Engelbert Gruber <grubert@users.sourceforge.net>;
5 # David Goodger <goodger@python.org>
6 # Copyright: This module has been placed in the public domain.
8 """
9 Tests for language module completeness.
11 Specify a language code (e.g. "de") as a command-line parameter to test only
12 that language.
13 """
15 import sys
16 import os
17 import re
18 from types import UnicodeType
19 import DocutilsTestSupport # must be imported before docutils
20 import docutils.languages
21 import docutils.parsers.rst.languages
22 from docutils.parsers.rst import states, directives, roles
25 reference_language = 'en'
28 class LanguageTestSuite(DocutilsTestSupport.CustomTestSuite):
30 language_module_pattern = re.compile('^([a-z]{2,3}(_[a-z]{2,8})*)\.py$')
32 def __init__(self, languages=None):
33 DocutilsTestSupport.CustomTestSuite.__init__(self)
34 if languages:
35 self.languages = languages
36 else:
37 self.get_languages()
39 def get_languages(self):
40 """
41 Get installed language translations from docutils.languages and from
42 docutils.parsers.rst.languages.
43 """
44 languages = {}
45 for mod in (os.listdir(docutils.languages.__path__[0])
46 + os.listdir(docutils.parsers.rst.languages.__path__[0])):
47 match = self.language_module_pattern.match(mod)
48 if match:
49 languages[match.group(1)] = 1
50 self.languages = languages.keys()
52 def generateTests(self):
53 for language in self.languages:
54 for method in LanguageTestCase.test_methods:
55 self.addTestCase(LanguageTestCase, method, None, None,
56 id=language+'.py', language=language)
59 class LanguageTestCase(DocutilsTestSupport.CustomTestCase):
61 test_methods = ['test_labels', 'test_bibliographic_fields',
62 'test_directives', 'test_roles']
63 """Names of methods used to test each language."""
65 def __init__(self, *args, **kwargs):
66 self.ref = docutils.languages.get_language(reference_language)
67 self.language = kwargs['language']
68 del kwargs['language'] # only wanted here
69 DocutilsTestSupport.CustomTestCase.__init__(self, *args, **kwargs)
71 def _xor(self, ref_dict, l_dict):
72 """
73 Returns entries that are only in one dictionary.
74 (missing_in_lang, more_than_in_ref).
75 """
76 missing = [] # in ref but not in l.
77 too_much = [] # in l but not in ref.
78 for label in ref_dict.keys():
79 if not l_dict.has_key(label):
80 missing.append(label)
81 for label in l_dict.keys():
82 if not ref_dict.has_key(label):
83 too_much.append(label)
84 return (missing, too_much)
86 def _invert(self, adict):
87 """Return an inverted (keys & values swapped) dictionary."""
88 inverted = {}
89 for key, value in adict.items():
90 inverted[value] = key
91 return inverted
93 def test_labels(self):
94 try:
95 module = docutils.languages.get_language(self.language)
96 if not module:
97 raise ImportError
98 except ImportError:
99 self.fail('No docutils.languages.%s module.' % self.language)
100 missed, unknown = self._xor(self.ref.labels, module.labels)
101 if missed or unknown:
102 self.fail('Module docutils.languages.%s.labels:\n'
103 ' Missed: %s; Unknown: %s'
104 % (self.language, str(missed), str(unknown)))
106 def test_bibliographic_fields(self):
107 try:
108 module = docutils.languages.get_language(self.language)
109 if not module:
110 raise ImportError
111 except ImportError:
112 self.fail('No docutils.languages.%s module.' % self.language)
113 missed, unknown = self._xor(
114 self._invert(self.ref.bibliographic_fields),
115 self._invert(module.bibliographic_fields))
116 if missed or unknown:
117 self.fail('Module docutils.languages.%s.bibliographic_fields:\n'
118 ' Missed: %s; Unknown: %s'
119 % (self.language, str(missed), str(unknown)))
121 def test_directives(self):
122 try:
123 module = docutils.parsers.rst.languages.get_language(
124 self.language)
125 if not module:
126 raise ImportError
127 except ImportError:
128 self.fail('No docutils.parsers.rst.languages.%s module.'
129 % self.language)
130 failures = []
131 for d in module.directives.keys():
132 try:
133 func, msg = directives.directive(d, module, None)
134 if not func:
135 failures.append('"%s": unknown directive' % d)
136 except Exception, error:
137 failures.append('"%s": %s' % (d, error))
138 inverted = self._invert(module.directives)
139 canonical = directives._directive_registry.keys()
140 canonical.sort()
141 canonical.remove('restructuredtext-test-directive')
142 for name in canonical:
143 if not inverted.has_key(name):
144 failures.append('"%s": translation missing' % name)
145 if failures:
146 text = ('Module docutils.parsers.rst.languages.%s:\n %s'
147 % (self.language, '\n '.join(failures)))
148 if type(text) == UnicodeType:
149 text = text.encode('raw_unicode_escape')
150 self.fail(text)
152 def test_roles(self):
153 try:
154 module = docutils.parsers.rst.languages.get_language(
155 self.language)
156 if not module:
157 raise ImportError
158 module.roles
159 except ImportError:
160 self.fail('No docutils.parsers.rst.languages.%s module.'
161 % self.language)
162 except AttributeError:
163 self.fail('No "roles" mapping in docutils.parsers.rst.languages.'
164 '%s module.' % self.language)
165 failures = []
166 for d in module.roles.values():
167 try:
168 method = roles._role_registry[d]
169 #if not method:
170 # failures.append('"%s": unknown role' % d)
171 except KeyError, error:
172 failures.append('"%s": %s' % (d, error))
173 inverted = self._invert(module.roles)
174 canonical = roles._role_registry.keys()
175 canonical.sort()
176 canonical.remove('restructuredtext-unimplemented-role')
177 for name in canonical:
178 if not inverted.has_key(name):
179 failures.append('"%s": translation missing' % name)
180 if failures:
181 text = ('Module docutils.parsers.rst.languages.%s:\n %s'
182 % (self.language, '\n '.join(failures)))
183 if type(text) == UnicodeType:
184 text = text.encode('raw_unicode_escape')
185 self.fail(text)
188 languages_to_test = []
190 def suite():
191 s = LanguageTestSuite(languages_to_test)
192 s.generateTests()
193 return s
195 def get_language_arguments():
196 while len(sys.argv) > 1:
197 last = sys.argv[-1]
198 if last.startswith('-'):
199 break
200 languages_to_test.append(last)
201 sys.argv.pop()
202 languages_to_test.reverse()
205 if __name__ == '__main__':
206 get_language_arguments()
207 import unittest
208 unittest.main(defaultTest='suite')
210 # vim: set et ts=4 ai :