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 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
)
35 self
.languages
= languages
39 def get_languages(self
):
41 Get installed language translations from docutils.languages and from
42 docutils.parsers.rst.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
)
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
):
73 Returns entries that are only in one dictionary.
74 (missing_in_lang, more_than_in_ref).
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
):
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."""
89 for key
, value
in adict
.items():
93 def test_labels(self
):
95 module
= docutils
.languages
.get_language(self
.language
)
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
):
108 module
= docutils
.languages
.get_language(self
.language
)
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
):
123 module
= docutils
.parsers
.rst
.languages
.get_language(
128 self
.fail('No docutils.parsers.rst.languages.%s module.'
131 for d
in module
.directives
.keys():
133 func
, msg
= directives
.directive(d
, module
, None)
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()
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
)
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')
152 def test_roles(self
):
154 module
= docutils
.parsers
.rst
.languages
.get_language(
160 self
.fail('No docutils.parsers.rst.languages.%s module.'
162 except AttributeError:
163 self
.fail('No "roles" mapping in docutils.parsers.rst.languages.'
164 '%s module.' % self
.language
)
166 for d
in module
.roles
.values():
168 method
= roles
._role
_registry
[d
]
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()
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
)
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')
188 languages_to_test
= []
191 s
= LanguageTestSuite(languages_to_test
)
195 def get_language_arguments():
196 while len(sys
.argv
) > 1:
198 if last
.startswith('-'):
200 languages_to_test
.append(last
)
202 languages_to_test
.reverse()
205 if __name__
== '__main__':
206 get_language_arguments()
208 unittest
.main(defaultTest
='suite')
210 # vim: set et ts=4 ai :