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'
29 if sys
.version_info
>= (3, 0):
33 class LanguageTestSuite(DocutilsTestSupport
.CustomTestSuite
):
35 language_module_pattern
= re
.compile(r
'^([a-z]{2,3}(_[a-z]{2,8})*)\.py$')
37 def __init__(self
, languages
=None):
38 DocutilsTestSupport
.CustomTestSuite
.__init
__(self
)
40 self
.languages
= languages
44 def get_languages(self
):
46 Get installed language translations from docutils.languages and from
47 docutils.parsers.rst.languages.
50 for mod
in (os
.listdir(docutils
.languages
.__path
__[0])
51 + os
.listdir(docutils
.parsers
.rst
.languages
.__path
__[0])):
52 match
= self
.language_module_pattern
.match(mod
)
54 languages
[match
.group(1)] = 1
55 self
.languages
= languages
.keys()
56 # test language tag normalization:
57 self
.languages
+= ['en_gb', 'en_US', 'en-CA', 'de-DE', 'de-AT-1901',
59 # test that locally created language files are also loaded.
60 # requires local_dummy_lang.py in test directory (testroot)
61 # The local_dummy_lang.py contains all the fields from both
62 # the docutils language tags and the parser.rst language tags
63 self
.languages
+= ['local_dummy_lang']
65 def generateTests(self
):
66 for language
in self
.languages
:
67 for method
in LanguageTestCase
.test_methods
:
68 self
.addTestCase(LanguageTestCase
, method
, None, None,
69 id=language
+'.py', language
=language
)
72 class LanguageTestCase(DocutilsTestSupport
.CustomTestCase
):
74 test_methods
= ['test_labels', 'test_bibliographic_fields',
75 'test_directives', 'test_roles']
76 """Names of methods used to test each language."""
78 def __init__(self
, *args
, **kwargs
):
79 self
.ref
= docutils
.languages
.get_language(reference_language
,
81 self
.language
= kwargs
['language']
82 del kwargs
['language'] # only wanted here
83 DocutilsTestSupport
.CustomTestCase
.__init
__(self
, *args
, **kwargs
)
85 def _xor(self
, ref_dict
, l_dict
):
87 Returns entries that are only in one dictionary.
88 (missing_in_lang, more_than_in_ref).
90 missing
= [] # in ref but not in l.
91 too_much
= [] # in l but not in ref.
92 for label
in ref_dict
.keys():
93 if label
not in l_dict
:
95 for label
in l_dict
.keys():
96 if label
not in ref_dict
:
97 too_much
.append(label
)
98 return (missing
, too_much
)
100 def _invert(self
, adict
):
101 """Return an inverted (keys & values swapped) dictionary."""
103 for key
, value
in adict
.items():
104 inverted
[value
] = key
107 def test_labels(self
):
109 module
= docutils
.languages
.get_language(self
.language
, _reporter
)
113 self
.fail('No docutils.languages.%s module.' % self
.language
)
114 missed
, unknown
= self
._xor
(self
.ref
.labels
, module
.labels
)
115 if missed
or unknown
:
116 self
.fail('Module docutils.languages.%s.labels:\n'
117 ' Missed: %s; Unknown: %s'
118 % (self
.language
, str(missed
), str(unknown
)))
120 def test_bibliographic_fields(self
):
122 module
= docutils
.languages
.get_language(self
.language
, _reporter
)
126 self
.fail('No docutils.languages.%s module.' % self
.language
)
127 missed
, unknown
= self
._xor
(
128 self
._invert
(self
.ref
.bibliographic_fields
),
129 self
._invert
(module
.bibliographic_fields
))
130 if missed
or unknown
:
131 self
.fail('Module docutils.languages.%s.bibliographic_fields:\n'
132 ' Missed: %s; Unknown: %s'
133 % (self
.language
, str(missed
), str(unknown
)))
135 def test_directives(self
):
137 module
= docutils
.parsers
.rst
.languages
.get_language(
142 self
.fail('No docutils.parsers.rst.languages.%s module.'
145 for d
in module
.directives
.keys():
147 func
, msg
= directives
.directive(d
, module
, None)
149 failures
.append('"%s": unknown directive' % d
)
150 except Exception as error
:
151 failures
.append('"%s": %s' % (d
, error
))
152 inverted
= self
._invert
(module
.directives
)
153 canonical
= sorted(directives
._directive
_registry
.keys())
154 canonical
.remove('restructuredtext-test-directive')
155 for name
in canonical
:
156 if name
not in inverted
:
157 failures
.append('"%s": translation missing' % name
)
159 text
= ('Module docutils.parsers.rst.languages.%s:\n %s'
160 % (self
.language
, '\n '.join(failures
)))
161 if isinstance(text
, unicode):
162 text
= text
.encode('raw_unicode_escape')
165 def test_roles(self
):
167 module
= docutils
.parsers
.rst
.languages
.get_language(
173 self
.fail('No docutils.parsers.rst.languages.%s module.'
175 except AttributeError:
176 self
.fail('No "roles" mapping in docutils.parsers.rst.languages.'
177 '%s module.' % self
.language
)
179 for d
in module
.roles
.values():
181 method
= roles
._role
_registry
[d
]
183 # failures.append('"%s": unknown role' % d)
184 except KeyError as error
:
185 failures
.append('"%s": %s' % (d
, error
))
186 inverted
= self
._invert
(module
.roles
)
187 canonical
= sorted(roles
._role
_registry
.keys())
188 canonical
.remove('restructuredtext-unimplemented-role')
189 for name
in canonical
:
190 if name
not in inverted
:
191 failures
.append('"%s": translation missing' % name
)
193 text
= ('Module docutils.parsers.rst.languages.%s:\n %s'
194 % (self
.language
, '\n '.join(failures
)))
195 if isinstance(text
, unicode):
196 text
= text
.encode('raw_unicode_escape')
199 languages_to_test
= []
202 s
= LanguageTestSuite(languages_to_test
)
206 def get_language_arguments():
207 while len(sys
.argv
) > 1:
209 if last
.startswith('-'):
211 languages_to_test
.append(last
)
213 languages_to_test
.reverse()
216 if __name__
== '__main__':
217 get_language_arguments()
219 unittest
.main(defaultTest
='suite')
221 # vim: set et ts=4 ai :