Prepare for python 3.0: minimize "types" module where possible (gbrandl).
[docutils.git] / test / test_language.py
blob7d785fdb1f9e95d3ec336a422dc3e5ac4dbbbbde
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 import DocutilsTestSupport # must be imported before docutils
19 import docutils.languages
20 import docutils.parsers.rst.languages
21 from docutils.parsers.rst import states, directives, roles
24 reference_language = 'en'
27 class LanguageTestSuite(DocutilsTestSupport.CustomTestSuite):
29 language_module_pattern = re.compile('^([a-z]{2,3}(_[a-z]{2,8})*)\.py$')
31 def __init__(self, languages=None):
32 DocutilsTestSupport.CustomTestSuite.__init__(self)
33 if languages:
34 self.languages = languages
35 else:
36 self.get_languages()
38 def get_languages(self):
39 """
40 Get installed language translations from docutils.languages and from
41 docutils.parsers.rst.languages.
42 """
43 languages = {}
44 for mod in (os.listdir(docutils.languages.__path__[0])
45 + os.listdir(docutils.parsers.rst.languages.__path__[0])):
46 match = self.language_module_pattern.match(mod)
47 if match:
48 languages[match.group(1)] = 1
49 self.languages = languages.keys()
51 def generateTests(self):
52 for language in self.languages:
53 for method in LanguageTestCase.test_methods:
54 self.addTestCase(LanguageTestCase, method, None, None,
55 id=language+'.py', language=language)
58 class LanguageTestCase(DocutilsTestSupport.CustomTestCase):
60 test_methods = ['test_labels', 'test_bibliographic_fields',
61 'test_directives', 'test_roles']
62 """Names of methods used to test each language."""
64 def __init__(self, *args, **kwargs):
65 self.ref = docutils.languages.get_language(reference_language)
66 self.language = kwargs['language']
67 del kwargs['language'] # only wanted here
68 DocutilsTestSupport.CustomTestCase.__init__(self, *args, **kwargs)
70 def _xor(self, ref_dict, l_dict):
71 """
72 Returns entries that are only in one dictionary.
73 (missing_in_lang, more_than_in_ref).
74 """
75 missing = [] # in ref but not in l.
76 too_much = [] # in l but not in ref.
77 for label in ref_dict.keys():
78 if label not in l_dict:
79 missing.append(label)
80 for label in l_dict.keys():
81 if label not in ref_dict:
82 too_much.append(label)
83 return (missing, too_much)
85 def _invert(self, adict):
86 """Return an inverted (keys & values swapped) dictionary."""
87 inverted = {}
88 for key, value in adict.items():
89 inverted[value] = key
90 return inverted
92 def test_labels(self):
93 try:
94 module = docutils.languages.get_language(self.language)
95 if not module:
96 raise ImportError
97 except ImportError:
98 self.fail('No docutils.languages.%s module.' % self.language)
99 missed, unknown = self._xor(self.ref.labels, module.labels)
100 if missed or unknown:
101 self.fail('Module docutils.languages.%s.labels:\n'
102 ' Missed: %s; Unknown: %s'
103 % (self.language, str(missed), str(unknown)))
105 def test_bibliographic_fields(self):
106 try:
107 module = docutils.languages.get_language(self.language)
108 if not module:
109 raise ImportError
110 except ImportError:
111 self.fail('No docutils.languages.%s module.' % self.language)
112 missed, unknown = self._xor(
113 self._invert(self.ref.bibliographic_fields),
114 self._invert(module.bibliographic_fields))
115 if missed or unknown:
116 self.fail('Module docutils.languages.%s.bibliographic_fields:\n'
117 ' Missed: %s; Unknown: %s'
118 % (self.language, str(missed), str(unknown)))
120 def test_directives(self):
121 try:
122 module = docutils.parsers.rst.languages.get_language(
123 self.language)
124 if not module:
125 raise ImportError
126 except ImportError:
127 self.fail('No docutils.parsers.rst.languages.%s module.'
128 % self.language)
129 failures = []
130 for d in module.directives.keys():
131 try:
132 func, msg = directives.directive(d, module, None)
133 if not func:
134 failures.append('"%s": unknown directive' % d)
135 except Exception, error:
136 failures.append('"%s": %s' % (d, error))
137 inverted = self._invert(module.directives)
138 canonical = directives._directive_registry.keys()
139 canonical.sort()
140 canonical.remove('restructuredtext-test-directive')
141 for name in canonical:
142 if name not in inverted:
143 failures.append('"%s": translation missing' % name)
144 if failures:
145 text = ('Module docutils.parsers.rst.languages.%s:\n %s'
146 % (self.language, '\n '.join(failures)))
147 if type(text) is unicode:
148 text = text.encode('raw_unicode_escape')
149 self.fail(text)
151 def test_roles(self):
152 try:
153 module = docutils.parsers.rst.languages.get_language(
154 self.language)
155 if not module:
156 raise ImportError
157 module.roles
158 except ImportError:
159 self.fail('No docutils.parsers.rst.languages.%s module.'
160 % self.language)
161 except AttributeError:
162 self.fail('No "roles" mapping in docutils.parsers.rst.languages.'
163 '%s module.' % self.language)
164 failures = []
165 for d in module.roles.values():
166 try:
167 method = roles._role_registry[d]
168 #if not method:
169 # failures.append('"%s": unknown role' % d)
170 except KeyError, error:
171 failures.append('"%s": %s' % (d, error))
172 inverted = self._invert(module.roles)
173 canonical = roles._role_registry.keys()
174 canonical.sort()
175 canonical.remove('restructuredtext-unimplemented-role')
176 for name in canonical:
177 if name not in inverted:
178 failures.append('"%s": translation missing' % name)
179 if failures:
180 text = ('Module docutils.parsers.rst.languages.%s:\n %s'
181 % (self.language, '\n '.join(failures)))
182 if type(text) is unicode:
183 text = text.encode('raw_unicode_escape')
184 self.fail(text)
187 languages_to_test = []
189 def suite():
190 s = LanguageTestSuite(languages_to_test)
191 s.generateTests()
192 return s
194 def get_language_arguments():
195 while len(sys.argv) > 1:
196 last = sys.argv[-1]
197 if last.startswith('-'):
198 break
199 languages_to_test.append(last)
200 sys.argv.pop()
201 languages_to_test.reverse()
204 if __name__ == '__main__':
205 get_language_arguments()
206 import unittest
207 unittest.main(defaultTest='suite')
209 # vim: set et ts=4 ai :