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',
56 # test that locally created language files are also loaded.
57 # requires local_dummy_lang.py in test directory (testroot)
58 # The local_dummy_lang.py contains all the fields from both
59 # the docutils language tags and the parser.rst language tags
60 self
.languages
+= ['local_dummy_lang']
62 def generateTests(self
):
63 for language
in self
.languages
:
64 for method
in LanguageTestCase
.test_methods
:
65 self
.addTestCase(LanguageTestCase
, method
, None, None,
66 id=language
+'.py', language
=language
)
69 class LanguageTestCase(DocutilsTestSupport
.CustomTestCase
):
71 test_methods
= ['test_labels', 'test_bibliographic_fields',
72 'test_directives', 'test_roles']
73 """Names of methods used to test each language."""
75 def __init__(self
, *args
, **kwargs
):
76 self
.ref
= docutils
.languages
.get_language(reference_language
,
78 self
.language
= kwargs
['language']
79 del kwargs
['language'] # only wanted here
80 DocutilsTestSupport
.CustomTestCase
.__init
__(self
, *args
, **kwargs
)
82 def _xor(self
, ref_dict
, l_dict
):
84 Returns entries that are only in one dictionary.
85 (missing_in_lang, more_than_in_ref).
87 missing
= [] # in ref but not in l.
88 too_much
= [] # in l but not in ref.
89 for label
in ref_dict
.keys():
90 if label
not in l_dict
:
92 for label
in l_dict
.keys():
93 if label
not in ref_dict
:
94 too_much
.append(label
)
95 return (missing
, too_much
)
97 def _invert(self
, adict
):
98 """Return an inverted (keys & values swapped) dictionary."""
100 for key
, value
in adict
.items():
101 inverted
[value
] = key
104 def test_labels(self
):
106 module
= docutils
.languages
.get_language(self
.language
, _reporter
)
110 self
.fail('No docutils.languages.%s module.' % self
.language
)
111 missed
, unknown
= self
._xor
(self
.ref
.labels
, module
.labels
)
112 if missed
or unknown
:
113 self
.fail('Module docutils.languages.%s.labels:\n'
114 ' Missed: %s; Unknown: %s'
115 % (self
.language
, str(missed
), str(unknown
)))
117 def test_bibliographic_fields(self
):
119 module
= docutils
.languages
.get_language(self
.language
, _reporter
)
123 self
.fail('No docutils.languages.%s module.' % self
.language
)
124 missed
, unknown
= self
._xor
(
125 self
._invert
(self
.ref
.bibliographic_fields
),
126 self
._invert
(module
.bibliographic_fields
))
127 if missed
or unknown
:
128 self
.fail('Module docutils.languages.%s.bibliographic_fields:\n'
129 ' Missed: %s; Unknown: %s'
130 % (self
.language
, str(missed
), str(unknown
)))
132 def test_directives(self
):
134 module
= docutils
.parsers
.rst
.languages
.get_language(
139 self
.fail('No docutils.parsers.rst.languages.%s module.'
142 for d
in module
.directives
.keys():
144 func
, msg
= directives
.directive(d
, module
, None)
146 failures
.append('"%s": unknown directive' % d
)
147 except Exception, error
:
148 failures
.append('"%s": %s' % (d
, error
))
149 inverted
= self
._invert
(module
.directives
)
150 canonical
= directives
._directive
_registry
.keys()
152 canonical
.remove('restructuredtext-test-directive')
153 for name
in canonical
:
154 if name
not in inverted
:
155 failures
.append('"%s": translation missing' % name
)
157 text
= ('Module docutils.parsers.rst.languages.%s:\n %s'
158 % (self
.language
, '\n '.join(failures
)))
159 if type(text
) is unicode:
160 text
= text
.encode('raw_unicode_escape')
163 def test_roles(self
):
165 module
= docutils
.parsers
.rst
.languages
.get_language(
171 self
.fail('No docutils.parsers.rst.languages.%s module.'
173 except AttributeError:
174 self
.fail('No "roles" mapping in docutils.parsers.rst.languages.'
175 '%s module.' % self
.language
)
177 for d
in module
.roles
.values():
179 method
= roles
._role
_registry
[d
]
181 # failures.append('"%s": unknown role' % d)
182 except KeyError, error
:
183 failures
.append('"%s": %s' % (d
, error
))
184 inverted
= self
._invert
(module
.roles
)
185 canonical
= roles
._role
_registry
.keys()
187 canonical
.remove('restructuredtext-unimplemented-role')
188 for name
in canonical
:
189 if name
not in inverted
:
190 failures
.append('"%s": translation missing' % name
)
192 text
= ('Module docutils.parsers.rst.languages.%s:\n %s'
193 % (self
.language
, '\n '.join(failures
)))
194 if type(text
) is unicode:
195 text
= text
.encode('raw_unicode_escape')
198 languages_to_test
= []
201 s
= LanguageTestSuite(languages_to_test
)
205 def get_language_arguments():
206 while len(sys
.argv
) > 1:
208 if last
.startswith('-'):
210 languages_to_test
.append(last
)
212 languages_to_test
.reverse()
215 if __name__
== '__main__':
216 get_language_arguments()
218 unittest
.main(defaultTest
='suite')
220 # vim: set et ts=4 ai :