App Engine Python SDK version 1.9.9
[gae.git] / python / lib / deprecated_enum / deprecated_enum / test / test_enum.py
blob8858a2d0357ad95eddb98e9cb0e9947be3e5ea09
1 #! /usr/bin/python2.4
2 # -*- coding: utf-8 -*-
4 # test/test_enum.py
5 # Part of enum, a package providing enumerated types for Python.
7 # Copyright © 2007–2009 Ben Finney <ben+python@benfinney.id.au>
8 # This is free software; you may copy, modify and/or distribute this work
9 # under the terms of the GNU General Public License, version 2 or later
10 # or, at your option, the terms of the Python license.
12 """ Unit test for ‘enum’ module.
13 """
15 import unittest
16 import operator
18 import google3
19 from deprecated_enum.test import tools
21 import deprecated_enum as enum
24 class Mock_Enum(object):
25 """ Mock object for Enum testing. """
27 def __init__(self, *keys):
28 """ Set up a new instance. """
29 pass
32 def setup_enum_value_fixtures(testcase):
33 """ Set up fixtures for test cases using ‘EnumValue’. """
35 testcase.bad_keys = [
36 None, 0, 1, (), Mock_Enum(),
37 enum.EnumValue(Mock_Enum(), 0, 'bogus'),
40 testcase.other_values = [
41 None, 0, 1, (), Mock_Enum(), "bogus",
42 enum.EnumValue(Mock_Enum(), 0, 'bogus'),
45 testcase.planets = [
46 ('mercury', "Mercury"),
47 ('venus', "Venus"),
48 ('earth', "Earth"),
49 ('mars', "Mars"),
50 ('jupiter', "Jupiter"),
51 ('saturn', "Saturn"),
52 ('uranus', "Uranus"),
53 ('neptune', "Neptune"),
55 planet_keys = [key for (key, name) in testcase.planets]
57 colour_keys = [
58 'red', 'green', 'blue',
59 'yellow', 'orange', 'purple',
60 'white', 'black',
63 simple_keys = ['spam', 'eggs', 'beans']
64 testcase.SimpleEnum = testcase.enum_factory_class(*simple_keys)
66 Colour = testcase.enum_factory_class(*colour_keys)
67 Planet = testcase.enum_factory_class(*planet_keys)
68 testcase.valid_values = {
69 Colour: dict(
70 keys = colour_keys,
72 Planet: dict(
73 keys = planet_keys,
77 for enumtype, params in testcase.valid_values.items():
78 params['enumtype'] = enumtype
79 values = {}
80 for i, key in enumerate(params['keys']):
81 values[key] = enum.EnumValue(enumtype, i, key)
82 params['values'] = values
85 class Test_Module(unittest.TestCase):
86 """ Test case for the module. """
88 def setUp(self):
89 """ Set up test fixtures. """
90 from sys import modules
91 self.module = modules['deprecated_enum']
93 def test_author_name_is_string(self):
94 """ Module should have __author_name__ string. """
95 mod_author_name = self.module.__author_name__
96 self.failUnless(isinstance(mod_author_name, basestring))
98 def test_author_email_is_string(self):
99 """ Module should have __author_email__ string. """
100 mod_author_email = self.module.__author_email__
101 self.failUnless(isinstance(mod_author_email, basestring))
103 def test_author_is_string(self):
104 """ Module should have __author__ string. """
105 mod_author = self.module.__author__
106 self.failUnless(isinstance(mod_author, basestring))
108 def test_author_contains_name(self):
109 """ Module __author__ string should contain author name. """
110 mod_author = self.module.__author__
111 mod_author_name = self.module.__author_name__
112 self.failUnless(mod_author.startswith(mod_author_name))
114 def test_author_contains_email(self):
115 """ Module __author__ string should contain author email. """
116 mod_author = self.module.__author__
117 mod_author_email = self.module.__author_email__
118 self.failUnless(mod_author.endswith("<%(mod_author_email)s>" % vars()))
120 def test_date_is_string(self):
121 """ Module should have __date__ string. """
122 mod_date = self.module.__date__
123 self.failUnless(isinstance(mod_date, basestring))
125 def test_copyright_is_string(self):
126 """ Module should have __copyright__ string. """
127 mod_copyright = self.module.__copyright__
128 self.failUnless(isinstance(mod_copyright, basestring))
130 def test_copyright_contains_name(self):
131 """ Module __copyright__ string should contain author name. """
132 mod_copyright = self.module.__copyright__
133 mod_author_name = self.module.__author_name__
134 self.failUnless(mod_copyright.endswith(mod_author_name))
136 def test_copyright_contains_begin_year(self):
137 """ Module __copyright__ string should contain beginning year. """
138 mod_copyright = self.module.__copyright__
139 year_begin = self.module._copyright_year_begin
140 self.failUnless(year_begin in mod_copyright)
142 def test_copyright_contains_latest_year(self):
143 """ Module __copyright__ string should contain latest year.. """
144 mod_copyright = self.module.__copyright__
145 year_latest = self.module.__date__.split('-')[0]
146 self.failUnless(year_latest in mod_copyright)
148 def test_license_is_string(self):
149 """ Module should have __license__ string. """
150 mod_license = self.module.__license__
151 self.failUnless(isinstance(mod_license, basestring))
153 def test_url_is_string(self):
154 """ Module should have __url__ string. """
155 mod_url = self.module.__url__
156 self.failUnless(isinstance(mod_url, basestring))
158 def test_version_is_string(self):
159 """ Module should have __version__ string. """
160 mod_version = self.module.__version__
161 self.failUnless(isinstance(mod_version, basestring))
164 class Test_EnumException(unittest.TestCase):
165 """ Test case for the Enum exception classes. """
167 def setUp(self):
168 """ Set up test fixtures. """
169 self.valid_exceptions = {
170 enum.EnumEmptyError: dict(
171 min_args = 0,
172 types = (enum.EnumException, AssertionError),
174 enum.EnumBadKeyError: dict(
175 min_args = 1,
176 types = (enum.EnumException, TypeError),
178 enum.EnumImmutableError: dict(
179 min_args = 1,
180 types = (enum.EnumException, TypeError),
184 for exc_type, params in self.valid_exceptions.items():
185 args = (None,) * params['min_args']
186 instance = exc_type(*args)
187 self.valid_exceptions[exc_type]['instance'] = instance
189 def test_EnumException_abstract(self):
190 """ The module exception base class should be abstract. """
191 self.failUnlessRaises(
192 NotImplementedError, enum.EnumException)
194 def test_exception_instance(self):
195 """ Exception instance should be created. """
196 for exc_type, params in self.valid_exceptions.items():
197 instance = params['instance']
198 self.failUnless(instance)
200 def test_exception_types(self):
201 """ Exception instances should match expected types. """
202 for exc_type, params in self.valid_exceptions.items():
203 instance = params['instance']
204 for match_type in params['types']:
205 self.failUnless(
206 isinstance(instance, match_type),
207 msg=(
208 "instance: %(instance)r, match_type: %(match_type)s"
209 ) % vars())
212 compare_functions = [
213 getattr(operator, name)
214 for name in ['__eq__', '__ne__', '__lt__', '__le__', '__gt__', '__ge__']]
216 class Test_EnumValue(unittest.TestCase):
217 """ Test case for the EnumValue class. """
219 enum_factory_class = Mock_Enum
221 def setUp(self):
222 """ Set up the test fixtures. """
223 setup_enum_value_fixtures(self)
225 def test_instantiate(self):
226 """ Creating an EnumValue instance should succeed. """
227 for enumtype, params in self.valid_values.items():
228 for key, instance in params['values'].items():
229 self.failUnless(instance)
231 def test_enumtype_equal(self):
232 """ EnumValue should export its enum type. """
233 for enumtype, params in self.valid_values.items():
234 for key, instance in params['values'].items():
235 self.failUnlessEqual(enumtype, instance.enumtype)
237 def test_key_equal(self):
238 """ EnumValue should export its string key. """
239 for enumtype, params in self.valid_values.items():
240 for key, instance in params['values'].items():
241 self.failUnlessEqual(key, instance.key)
243 def test_str_key(self):
244 """ String value for EnumValue should be its key string. """
245 for enumtype, params in self.valid_values.items():
246 for key, instance in params['values'].items():
247 self.failUnlessEqual(key, str(instance))
249 def test_index_equal(self):
250 """ EnumValue should export its sequence index. """
251 for enumtype, params in self.valid_values.items():
252 for i, key in enumerate(params['keys']):
253 instance = params['values'][key]
254 self.failUnlessEqual(i, instance.index)
256 def test_repr(self):
257 """ Representation of EnumValue should be meaningful. """
258 for enumtype, params in self.valid_values.items():
259 for i, key in enumerate(params['keys']):
260 instance = params['values'][key]
261 repr_str = repr(instance)
262 self.failUnless(repr_str.startswith('EnumValue('))
263 self.failUnless(repr_str.count(repr(enumtype)))
264 self.failUnless(repr_str.count(repr(i)))
265 self.failUnless(repr_str.count(repr(key)))
266 self.failUnless(repr_str.endswith(')'))
268 def test_hash_equal(self):
269 """ Each EnumValue instance should have same hash as its value. """
270 for enumtype, params in self.valid_values.items():
271 for i, key in enumerate(params['keys']):
272 instance = params['values'][key]
273 self.failUnlessEqual(hash(i), hash(instance))
275 def test_hash_unequal(self):
276 """ Different EnumValue instances should have different hashes. """
277 for enumtype, params in self.valid_values.items():
278 for i, key in enumerate(params['keys']):
279 instance = params['values'][key]
280 for j, other_key in enumerate(params['keys']):
281 if i == j:
282 continue
283 other_instance = params['values'][other_key]
284 self.failIfEqual(
285 hash(instance), hash(other_instance))
287 def test_comparison_method_has_matching_name(self):
288 """ Comparison method should have matching name for attribute. """
289 for compare_func in compare_functions:
290 func_name = compare_func.__name__
291 expect_name = func_name
292 compare_method = getattr(enum.EnumValue, func_name)
293 self.failUnlessEqual(
294 expect_name, compare_method.__name__)
296 def test_comparison_method_has_docstring(self):
297 """ Comparison method should have docstring. """
298 for compare_func in compare_functions:
299 func_name = compare_func.__name__
300 compare_method = getattr(enum.EnumValue, func_name)
301 self.failUnless(
302 isinstance(compare_method.__doc__, basestring))
304 def test_compare_equal(self):
305 """ An EnumValue should compare equal to its value. """
306 for enumtype, params in self.valid_values.items():
307 for i, key in enumerate(params['keys']):
308 instance = params['values'][key]
309 self.failUnlessEqual(
310 instance, enum.EnumValue(enumtype, i, key))
312 def test_compare_unequal(self):
313 """ An EnumValue should compare different to other values. """
314 for enumtype, params in self.valid_values.items():
315 for i, key in enumerate(params['keys']):
316 instance = params['values'][key]
317 self.failIfEqual(
318 instance,
319 enum.EnumValue(enumtype, None, None))
321 def test_compare_sequence(self):
322 """ EnumValue instances should compare as their sequence order. """
323 for enumtype, params in self.valid_values.items():
324 for i, left_key in enumerate(params['keys']):
325 for j, right_key in enumerate(params['keys']):
326 for compare_func in compare_functions:
327 self.failUnlessEqual(
328 compare_func(i, j),
329 compare_func(params['values'][left_key],
330 enum.EnumValue(enumtype, j, right_key))
333 def test_compare_different_enum(self):
334 """ An EnumValue should not implement comparison to other enums. """
335 for enumtype, params in self.valid_values.items():
336 for i, key in enumerate(params['keys']):
337 for compare_func in compare_functions:
338 instance = params['values'][key]
339 test_value = enum.EnumValue(self.SimpleEnum, i, key)
340 compare_method = getattr(instance, compare_func.__name__)
341 compare_result = compare_method(test_value)
342 self.failUnlessEqual(NotImplemented, compare_result)
344 def test_compare_non_enum(self):
345 """ An EnumValue should not implement comparison to other types. """
346 test_value = enum.EnumValue(self.SimpleEnum, 0, 'test')
347 for other_value in self.other_values:
348 for compare_func in compare_functions:
349 compare_method = getattr(test_value, compare_func.__name__)
350 compare_result = compare_method(other_value)
351 self.failUnlessEqual(NotImplemented, compare_result)
353 def test_compare_equality_different_enum(self):
354 """ An EnumValue should compare inequal to values of other enums. """
355 for enumtype, params in self.valid_values.items():
356 for i, key in enumerate(params['keys']):
357 instance = params['values'][key]
358 test_value = enum.EnumValue(self.SimpleEnum, i, key)
359 self.failIfEqual(test_value, instance)
361 def test_compare_equality_non_enum(self):
362 """ An EnumValue should compare inequal to any other value. """
363 test_value = enum.EnumValue(self.SimpleEnum, 0, 'test')
364 for other_value in self.other_values:
365 self.failIfEqual(test_value, other_value)
367 def test_sequence_other_values(self):
368 """ An EnumValue should compare sequentially to other values. """
369 test_value = enum.EnumValue(self.SimpleEnum, 0, 'test')
370 test_list = list(self.other_values)
371 test_list.append(test_value)
372 test_list.sort()
373 self.failUnless(test_value in test_list)
375 def test_value_key(self):
376 """ An EnumValue should have the specified key. """
377 for enumtype, params in self.valid_values.items():
378 for key, instance in params['values'].items():
379 self.failUnlessEqual(key, instance.key)
381 def test_value_enumtype(self):
382 """ An EnumValue should have its associated enumtype. """
383 for enumtype, params in self.valid_values.items():
384 for key, instance in params['values'].items():
385 self.failUnlessEqual(enumtype, instance.enumtype)
388 class Test_Enum(unittest.TestCase):
389 """ Test case for the Enum class. """
391 enum_factory_class = enum.Enum
393 def setUp(self):
394 """ Set up the test fixtures. """
395 setup_enum_value_fixtures(self)
397 def test_empty_enum(self):
398 """ Enum constructor should refuse empty keys sequence. """
399 self.failUnlessRaises(
400 enum.EnumEmptyError,
401 enum.Enum)
403 def test_bad_key(self):
404 """ Enum constructor should refuse non-string keys. """
405 for key in self.bad_keys:
406 args = ("valid", key, "valid")
407 self.failUnlessRaises(
408 enum.EnumBadKeyError,
409 enum.Enum, *args)
411 def test_value_attributes(self):
412 """ Enumeration should have attributes for each value. """
413 for enumtype, params in self.valid_values.items():
414 for i, key in enumerate(params['keys']):
415 instance = getattr(enumtype, key)
416 test_value = enum.EnumValue(enumtype, i, key)
417 self.failUnlessEqual(test_value, instance)
419 def test_length(self):
420 """ Enumeration should have length of its value set. """
421 for enumtype, params in self.valid_values.items():
422 self.failUnlessEqual(len(params['values']), len(enumtype))
424 def test_value_items(self):
425 """ Enumeration should have items for each value. """
426 for enumtype, params in self.valid_values.items():
427 for i, key in enumerate(params['keys']):
428 value = enumtype[i]
429 test_value = enum.EnumValue(enumtype, i, key)
430 self.failUnlessEqual(test_value, value)
432 def test_iterable(self):
433 """ Enumeration class should iterate over its values. """
434 for enumtype, params in self.valid_values.items():
435 for i, value in enumerate(enumtype):
436 key = params['keys'][i]
437 test_value = params['values'][key]
438 self.failUnlessEqual(value, test_value)
440 def test_iterate_sequence(self):
441 """ Enumeration iteration should match specified sequence. """
442 for enumtype, params in self.valid_values.items():
443 values_dict = params['values']
444 values_seq = [values_dict[key] for key in params['keys']]
445 enum_seq = [val for val in enumtype]
446 self.failUnlessEqual(values_seq, enum_seq)
447 self.failIfEqual(values_seq.reverse(), enum_seq)
449 def test_membership_bogus(self):
450 """ Enumeration should not contain bogus values. """
451 for enumtype, params in self.valid_values.items():
452 for value in self.other_values:
453 self.failIf(value in enumtype)
455 def test_membership_value(self):
456 """ Enumeration should contain explicit value. """
457 for enumtype, params in self.valid_values.items():
458 for i, key in enumerate(params['keys']):
459 value = params['values'][key]
460 self.failUnless(value in enumtype)
462 def test_membership_key(self):
463 """ Enumeration should contain key string. """
464 for enumtype, params in self.valid_values.items():
465 for key in params['keys']:
466 self.failUnless(key in enumtype)
468 def test_add_attribute(self):
469 """ Enumeration should refuse attribute addition. """
470 for enumtype, params in self.valid_values.items():
471 self.failUnlessRaises(
472 enum.EnumImmutableError,
473 setattr, enumtype, 'bogus', "bogus")
475 def test_modify_attribute(self):
476 """ Enumeration should refuse attribute modification. """
477 for enumtype, params in self.valid_values.items():
478 for key in params['keys']:
479 self.failUnlessRaises(
480 enum.EnumImmutableError,
481 setattr, enumtype, key, "bogus")
483 def test_delete_attribute(self):
484 """ Enumeration should refuse attribute deletion. """
485 for enumtype, params in self.valid_values.items():
486 for key in params['keys']:
487 self.failUnlessRaises(
488 enum.EnumImmutableError,
489 delattr, enumtype, key)
491 def test_add_item(self):
492 """ Enumeration should refuse item addition. """
493 for enumtype, params in self.valid_values.items():
494 index = len(params['keys'])
495 self.failUnlessRaises(
496 enum.EnumImmutableError,
497 enumtype.__setitem__, index, "bogus")
499 def test_modify_item(self):
500 """ Enumeration should refuse item modification. """
501 for enumtype, params in self.valid_values.items():
502 for i, key in enumerate(params['keys']):
503 self.failUnlessRaises(
504 enum.EnumImmutableError,
505 enumtype.__setitem__, i, "bogus")
507 def test_delete_item(self):
508 """ Enumeration should refuse item deletion. """
509 for enumtype, params in self.valid_values.items():
510 for i, key in enumerate(params['keys']):
511 self.failUnlessRaises(
512 enum.EnumImmutableError,
513 enumtype.__delitem__, i)
516 def suite():
517 """ Create the test suite for this module. """
518 from sys import modules
519 loader = unittest.TestLoader()
520 suite = loader.loadTestsFromModule(modules[__name__])
521 return suite
524 def __main__(argv=None):
525 """ Mainline function for this module. """
526 import sys as _sys
527 if not argv:
528 argv = _sys.argv
530 exitcode = None
531 try:
532 unittest.main(argv=argv, defaultTest='suite')
533 except SystemExit, exc:
534 exitcode = exc.code
536 return exitcode
538 if __name__ == '__main__':
539 import sys
540 exitcode = __main__(sys.argv)
541 sys.exit(exitcode)
544 # Local variables:
545 # mode: python
546 # End:
547 # vim: filetype=python fileencoding=utf-8 :