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.
9 Tests for language module completeness.
11 Specify a language code (e.g. "de") as a command-line parameter to test only
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
22 import docutils
.utils
, docutils
.frontend
24 _settings
= docutils
.frontend
.OptionParser().get_default_values()
25 _reporter
= docutils
.utils
.new_reporter('', _settings
)
27 reference_language
= 'en'
30 class LanguageTestSuite(DocutilsTestSupport
.CustomTestSuite
):
32 language_module_pattern
= re
.compile('^([a-z]{2,3}(_[a-z]{2,8})*)\.py$')
34 def __init__(self
, languages
=None):
35 DocutilsTestSupport
.CustomTestSuite
.__init
__(self
)
37 self
.languages
= languages
41 def get_languages(self
):
43 Get installed language translations from docutils.languages and from
44 docutils.parsers.rst.languages.
47 for mod
in (os
.listdir(docutils
.languages
.__path
__[0])
48 + os
.listdir(docutils
.parsers
.rst
.languages
.__path
__[0])):
49 match
= self
.language_module_pattern
.match(mod
)
51 languages
[match
.group(1)] = 1
52 self
.languages
= languages
.keys()
53 # test language tag normalization:
54 self
.languages
+= ['en_gb', 'en_US', 'en-CA', 'de-DE', 'de-AT-1901',
57 def generateTests(self
):
58 for language
in self
.languages
:
59 for method
in LanguageTestCase
.test_methods
:
60 self
.addTestCase(LanguageTestCase
, method
, None, None,
61 id=language
+'.py', language
=language
)
64 class LanguageTestCase(DocutilsTestSupport
.CustomTestCase
):
66 test_methods
= ['test_labels', 'test_bibliographic_fields',
67 'test_directives', 'test_roles']
68 """Names of methods used to test each language."""
70 def __init__(self
, *args
, **kwargs
):
71 self
.ref
= docutils
.languages
.get_language(reference_language
,
73 self
.language
= kwargs
['language']
74 del kwargs
['language'] # only wanted here
75 DocutilsTestSupport
.CustomTestCase
.__init
__(self
, *args
, **kwargs
)
77 def _xor(self
, ref_dict
, l_dict
):
79 Returns entries that are only in one dictionary.
80 (missing_in_lang, more_than_in_ref).
82 missing
= [] # in ref but not in l.
83 too_much
= [] # in l but not in ref.
84 for label
in ref_dict
.keys():
85 if label
not in l_dict
:
87 for label
in l_dict
.keys():
88 if label
not in ref_dict
:
89 too_much
.append(label
)
90 return (missing
, too_much
)
92 def _invert(self
, adict
):
93 """Return an inverted (keys & values swapped) dictionary."""
95 for key
, value
in adict
.items():
99 def test_labels(self
):
101 module
= docutils
.languages
.get_language(self
.language
, _reporter
)
105 self
.fail('No docutils.languages.%s module.' % self
.language
)
106 missed
, unknown
= self
._xor
(self
.ref
.labels
, module
.labels
)
107 if missed
or unknown
:
108 self
.fail('Module docutils.languages.%s.labels:\n'
109 ' Missed: %s; Unknown: %s'
110 % (self
.language
, str(missed
), str(unknown
)))
112 def test_bibliographic_fields(self
):
114 module
= docutils
.languages
.get_language(self
.language
, _reporter
)
118 self
.fail('No docutils.languages.%s module.' % self
.language
)
119 missed
, unknown
= self
._xor
(
120 self
._invert
(self
.ref
.bibliographic_fields
),
121 self
._invert
(module
.bibliographic_fields
))
122 if missed
or unknown
:
123 self
.fail('Module docutils.languages.%s.bibliographic_fields:\n'
124 ' Missed: %s; Unknown: %s'
125 % (self
.language
, str(missed
), str(unknown
)))
127 def test_directives(self
):
129 module
= docutils
.parsers
.rst
.languages
.get_language(
134 self
.fail('No docutils.parsers.rst.languages.%s module.'
137 for d
in module
.directives
.keys():
139 func
, msg
= directives
.directive(d
, module
, None)
141 failures
.append('"%s": unknown directive' % d
)
142 except Exception, error
:
143 failures
.append('"%s": %s' % (d
, error
))
144 inverted
= self
._invert
(module
.directives
)
145 canonical
= directives
._directive
_registry
.keys()
147 canonical
.remove('restructuredtext-test-directive')
148 for name
in canonical
:
149 if name
not in inverted
:
150 failures
.append('"%s": translation missing' % name
)
152 text
= ('Module docutils.parsers.rst.languages.%s:\n %s'
153 % (self
.language
, '\n '.join(failures
)))
154 if type(text
) is unicode:
155 text
= text
.encode('raw_unicode_escape')
158 def test_roles(self
):
160 module
= docutils
.parsers
.rst
.languages
.get_language(
166 self
.fail('No docutils.parsers.rst.languages.%s module.'
168 except AttributeError:
169 self
.fail('No "roles" mapping in docutils.parsers.rst.languages.'
170 '%s module.' % self
.language
)
172 for d
in module
.roles
.values():
174 method
= roles
._role
_registry
[d
]
176 # failures.append('"%s": unknown role' % d)
177 except KeyError, error
:
178 failures
.append('"%s": %s' % (d
, error
))
179 inverted
= self
._invert
(module
.roles
)
180 canonical
= roles
._role
_registry
.keys()
182 canonical
.remove('restructuredtext-unimplemented-role')
183 for name
in canonical
:
184 if name
not in inverted
:
185 failures
.append('"%s": translation missing' % name
)
187 text
= ('Module docutils.parsers.rst.languages.%s:\n %s'
188 % (self
.language
, '\n '.join(failures
)))
189 if type(text
) is unicode:
190 text
= text
.encode('raw_unicode_escape')
193 languages_to_test
= []
196 s
= LanguageTestSuite(languages_to_test
)
200 def get_language_arguments():
201 while len(sys
.argv
) > 1:
203 if last
.startswith('-'):
205 languages_to_test
.append(last
)
207 languages_to_test
.reverse()
210 if __name__
== '__main__':
211 get_language_arguments()
213 unittest
.main(defaultTest
='suite')
215 # vim: set et ts=4 ai :