Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(235)

Side by Side Diff: third_party/google-endpoints/apitools/base/protorpclite/messages_test.py

Issue 2666783008: Add google-endpoints to third_party/. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 #
3 # Copyright 2010 Google Inc.
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 #
17
18 """Tests for apitools.base.protorpclite.messages."""
19 import pickle
20 import re
21 import sys
22 import types
23 import unittest
24
25 import six
26
27 from apitools.base.protorpclite import descriptor
28 from apitools.base.protorpclite import message_types
29 from apitools.base.protorpclite import messages
30 from apitools.base.protorpclite import test_util
31
32 # This package plays lots of games with modifying global variables inside
33 # test cases. Hence:
34 # pylint:disable=function-redefined
35 # pylint:disable=global-variable-not-assigned
36 # pylint:disable=global-variable-undefined
37 # pylint:disable=redefined-outer-name
38 # pylint:disable=undefined-variable
39 # pylint:disable=unused-variable
40 # pylint:disable=too-many-lines
41
42
43 class ModuleInterfaceTest(test_util.ModuleInterfaceTest,
44 test_util.TestCase):
45
46 MODULE = messages
47
48
49 class ValidationErrorTest(test_util.TestCase):
50
51 def testStr_NoFieldName(self):
52 """Test string version of ValidationError when no name provided."""
53 self.assertEquals('Validation error',
54 str(messages.ValidationError('Validation error')))
55
56 def testStr_FieldName(self):
57 """Test string version of ValidationError when no name provided."""
58 validation_error = messages.ValidationError('Validation error')
59 validation_error.field_name = 'a_field'
60 self.assertEquals('Validation error', str(validation_error))
61
62
63 class EnumTest(test_util.TestCase):
64
65 def setUp(self):
66 """Set up tests."""
67 # Redefine Color class in case so that changes to it (an
68 # error) in one test does not affect other tests.
69 global Color # pylint:disable=global-variable-not-assigned
70
71 # pylint:disable=unused-variable
72 class Color(messages.Enum):
73 RED = 20
74 ORANGE = 2
75 YELLOW = 40
76 GREEN = 4
77 BLUE = 50
78 INDIGO = 5
79 VIOLET = 80
80
81 def testNames(self):
82 """Test that names iterates over enum names."""
83 self.assertEquals(
84 set(['BLUE', 'GREEN', 'INDIGO', 'ORANGE', 'RED',
85 'VIOLET', 'YELLOW']),
86 set(Color.names()))
87
88 def testNumbers(self):
89 """Tests that numbers iterates of enum numbers."""
90 self.assertEquals(set([2, 4, 5, 20, 40, 50, 80]), set(Color.numbers()))
91
92 def testIterate(self):
93 """Test that __iter__ iterates over all enum values."""
94 self.assertEquals(set(Color),
95 set([Color.RED,
96 Color.ORANGE,
97 Color.YELLOW,
98 Color.GREEN,
99 Color.BLUE,
100 Color.INDIGO,
101 Color.VIOLET]))
102
103 def testNaturalOrder(self):
104 """Test that natural order enumeration is in numeric order."""
105 self.assertEquals([Color.ORANGE,
106 Color.GREEN,
107 Color.INDIGO,
108 Color.RED,
109 Color.YELLOW,
110 Color.BLUE,
111 Color.VIOLET],
112 sorted(Color))
113
114 def testByName(self):
115 """Test look-up by name."""
116 self.assertEquals(Color.RED, Color.lookup_by_name('RED'))
117 self.assertRaises(KeyError, Color.lookup_by_name, 20)
118 self.assertRaises(KeyError, Color.lookup_by_name, Color.RED)
119
120 def testByNumber(self):
121 """Test look-up by number."""
122 self.assertRaises(KeyError, Color.lookup_by_number, 'RED')
123 self.assertEquals(Color.RED, Color.lookup_by_number(20))
124 self.assertRaises(KeyError, Color.lookup_by_number, Color.RED)
125
126 def testConstructor(self):
127 """Test that constructor look-up by name or number."""
128 self.assertEquals(Color.RED, Color('RED'))
129 self.assertEquals(Color.RED, Color(u'RED'))
130 self.assertEquals(Color.RED, Color(20))
131 if six.PY2:
132 self.assertEquals(Color.RED, Color(long(20)))
133 self.assertEquals(Color.RED, Color(Color.RED))
134 self.assertRaises(TypeError, Color, 'Not exists')
135 self.assertRaises(TypeError, Color, 'Red')
136 self.assertRaises(TypeError, Color, 100)
137 self.assertRaises(TypeError, Color, 10.0)
138
139 def testLen(self):
140 """Test that len function works to count enums."""
141 self.assertEquals(7, len(Color))
142
143 def testNoSubclasses(self):
144 """Test that it is not possible to sub-class enum classes."""
145 def declare_subclass():
146 class MoreColor(Color):
147 pass
148 self.assertRaises(messages.EnumDefinitionError,
149 declare_subclass)
150
151 def testClassNotMutable(self):
152 """Test that enum classes themselves are not mutable."""
153 self.assertRaises(AttributeError,
154 setattr,
155 Color,
156 'something_new',
157 10)
158
159 def testInstancesMutable(self):
160 """Test that enum instances are not mutable."""
161 self.assertRaises(TypeError,
162 setattr,
163 Color.RED,
164 'something_new',
165 10)
166
167 def testDefEnum(self):
168 """Test def_enum works by building enum class from dict."""
169 WeekDay = messages.Enum.def_enum({'Monday': 1,
170 'Tuesday': 2,
171 'Wednesday': 3,
172 'Thursday': 4,
173 'Friday': 6,
174 'Saturday': 7,
175 'Sunday': 8},
176 'WeekDay')
177 self.assertEquals('Wednesday', WeekDay(3).name)
178 self.assertEquals(6, WeekDay('Friday').number)
179 self.assertEquals(WeekDay.Sunday, WeekDay('Sunday'))
180
181 def testNonInt(self):
182 """Test that non-integer values rejection by enum def."""
183 self.assertRaises(messages.EnumDefinitionError,
184 messages.Enum.def_enum,
185 {'Bad': '1'},
186 'BadEnum')
187
188 def testNegativeInt(self):
189 """Test that negative numbers rejection by enum def."""
190 self.assertRaises(messages.EnumDefinitionError,
191 messages.Enum.def_enum,
192 {'Bad': -1},
193 'BadEnum')
194
195 def testLowerBound(self):
196 """Test that zero is accepted by enum def."""
197 class NotImportant(messages.Enum):
198 """Testing for value zero"""
199 VALUE = 0
200
201 self.assertEquals(0, int(NotImportant.VALUE))
202
203 def testTooLargeInt(self):
204 """Test that numbers too large are rejected."""
205 self.assertRaises(messages.EnumDefinitionError,
206 messages.Enum.def_enum,
207 {'Bad': (2 ** 29)},
208 'BadEnum')
209
210 def testRepeatedInt(self):
211 """Test duplicated numbers are forbidden."""
212 self.assertRaises(messages.EnumDefinitionError,
213 messages.Enum.def_enum,
214 {'Ok': 1, 'Repeated': 1},
215 'BadEnum')
216
217 def testStr(self):
218 """Test converting to string."""
219 self.assertEquals('RED', str(Color.RED))
220 self.assertEquals('ORANGE', str(Color.ORANGE))
221
222 def testInt(self):
223 """Test converting to int."""
224 self.assertEquals(20, int(Color.RED))
225 self.assertEquals(2, int(Color.ORANGE))
226
227 def testRepr(self):
228 """Test enum representation."""
229 self.assertEquals('Color(RED, 20)', repr(Color.RED))
230 self.assertEquals('Color(YELLOW, 40)', repr(Color.YELLOW))
231
232 def testDocstring(self):
233 """Test that docstring is supported ok."""
234 class NotImportant(messages.Enum):
235 """I have a docstring."""
236
237 VALUE1 = 1
238
239 self.assertEquals('I have a docstring.', NotImportant.__doc__)
240
241 def testDeleteEnumValue(self):
242 """Test that enum values cannot be deleted."""
243 self.assertRaises(TypeError, delattr, Color, 'RED')
244
245 def testEnumName(self):
246 """Test enum name."""
247 module_name = test_util.get_module_name(EnumTest)
248 self.assertEquals('%s.Color' % module_name, Color.definition_name())
249 self.assertEquals(module_name, Color.outer_definition_name())
250 self.assertEquals(module_name, Color.definition_package())
251
252 def testDefinitionName_OverrideModule(self):
253 """Test enum module is overriden by module package name."""
254 global package
255 try:
256 package = 'my.package'
257 self.assertEquals('my.package.Color', Color.definition_name())
258 self.assertEquals('my.package', Color.outer_definition_name())
259 self.assertEquals('my.package', Color.definition_package())
260 finally:
261 del package
262
263 def testDefinitionName_NoModule(self):
264 """Test what happens when there is no module for enum."""
265 class Enum1(messages.Enum):
266 pass
267
268 original_modules = sys.modules
269 sys.modules = dict(sys.modules)
270 try:
271 del sys.modules[__name__]
272 self.assertEquals('Enum1', Enum1.definition_name())
273 self.assertEquals(None, Enum1.outer_definition_name())
274 self.assertEquals(None, Enum1.definition_package())
275 self.assertEquals(six.text_type, type(Enum1.definition_name()))
276 finally:
277 sys.modules = original_modules
278
279 def testDefinitionName_Nested(self):
280 """Test nested Enum names."""
281 class MyMessage(messages.Message):
282
283 class NestedEnum(messages.Enum):
284
285 pass
286
287 class NestedMessage(messages.Message):
288
289 class NestedEnum(messages.Enum):
290
291 pass
292
293 module_name = test_util.get_module_name(EnumTest)
294 self.assertEquals('%s.MyMessage.NestedEnum' % module_name,
295 MyMessage.NestedEnum.definition_name())
296 self.assertEquals('%s.MyMessage' % module_name,
297 MyMessage.NestedEnum.outer_definition_name())
298 self.assertEquals(module_name,
299 MyMessage.NestedEnum.definition_package())
300
301 self.assertEquals(
302 '%s.MyMessage.NestedMessage.NestedEnum' % module_name,
303 MyMessage.NestedMessage.NestedEnum.definition_name())
304 self.assertEquals(
305 '%s.MyMessage.NestedMessage' % module_name,
306 MyMessage.NestedMessage.NestedEnum.outer_definition_name())
307 self.assertEquals(
308 module_name,
309 MyMessage.NestedMessage.NestedEnum.definition_package())
310
311 def testMessageDefinition(self):
312 """Test that enumeration knows its enclosing message definition."""
313 class OuterEnum(messages.Enum):
314 pass
315
316 self.assertEquals(None, OuterEnum.message_definition())
317
318 class OuterMessage(messages.Message):
319
320 class InnerEnum(messages.Enum):
321 pass
322
323 self.assertEquals(
324 OuterMessage, OuterMessage.InnerEnum.message_definition())
325
326 def testComparison(self):
327 """Test comparing various enums to different types."""
328 class Enum1(messages.Enum):
329 VAL1 = 1
330 VAL2 = 2
331
332 class Enum2(messages.Enum):
333 VAL1 = 1
334
335 self.assertEquals(Enum1.VAL1, Enum1.VAL1)
336 self.assertNotEquals(Enum1.VAL1, Enum1.VAL2)
337 self.assertNotEquals(Enum1.VAL1, Enum2.VAL1)
338 self.assertNotEquals(Enum1.VAL1, 'VAL1')
339 self.assertNotEquals(Enum1.VAL1, 1)
340 self.assertNotEquals(Enum1.VAL1, 2)
341 self.assertNotEquals(Enum1.VAL1, None)
342 self.assertNotEquals(Enum1.VAL1, Enum2.VAL1)
343
344 self.assertTrue(Enum1.VAL1 < Enum1.VAL2)
345 self.assertTrue(Enum1.VAL2 > Enum1.VAL1)
346
347 self.assertNotEquals(1, Enum2.VAL1)
348
349 def testPickle(self):
350 """Testing pickling and unpickling of Enum instances."""
351 colors = list(Color)
352 unpickled = pickle.loads(pickle.dumps(colors))
353 self.assertEquals(colors, unpickled)
354 # Unpickling shouldn't create new enum instances.
355 for i, color in enumerate(colors):
356 self.assertTrue(color is unpickled[i])
357
358
359 class FieldListTest(test_util.TestCase):
360
361 def setUp(self):
362 self.integer_field = messages.IntegerField(1, repeated=True)
363
364 def testConstructor(self):
365 self.assertEquals([1, 2, 3],
366 messages.FieldList(self.integer_field, [1, 2, 3]))
367 self.assertEquals([1, 2, 3],
368 messages.FieldList(self.integer_field, (1, 2, 3)))
369 self.assertEquals([], messages.FieldList(self.integer_field, []))
370
371 def testNone(self):
372 self.assertRaises(TypeError, messages.FieldList,
373 self.integer_field, None)
374
375 def testDoNotAutoConvertString(self):
376 string_field = messages.StringField(1, repeated=True)
377 self.assertRaises(messages.ValidationError,
378 messages.FieldList, string_field, 'abc')
379
380 def testConstructorCopies(self):
381 a_list = [1, 3, 6]
382 field_list = messages.FieldList(self.integer_field, a_list)
383 self.assertFalse(a_list is field_list)
384 self.assertFalse(field_list is
385 messages.FieldList(self.integer_field, field_list))
386
387 def testNonRepeatedField(self):
388 self.assertRaisesWithRegexpMatch(
389 messages.FieldDefinitionError,
390 'FieldList may only accept repeated fields',
391 messages.FieldList,
392 messages.IntegerField(1),
393 [])
394
395 def testConstructor_InvalidValues(self):
396 self.assertRaisesWithRegexpMatch(
397 messages.ValidationError,
398 re.escape("Expected type %r "
399 "for IntegerField, found 1 (type %r)"
400 % (six.integer_types, str)),
401 messages.FieldList, self.integer_field, ["1", "2", "3"])
402
403 def testConstructor_Scalars(self):
404 self.assertRaisesWithRegexpMatch(
405 messages.ValidationError,
406 "IntegerField is repeated. Found: 3",
407 messages.FieldList, self.integer_field, 3)
408
409 self.assertRaisesWithRegexpMatch(
410 messages.ValidationError,
411 ("IntegerField is repeated. Found: "
412 "<(list[_]?|sequence)iterator object"),
413 messages.FieldList, self.integer_field, iter([1, 2, 3]))
414
415 def testSetSlice(self):
416 field_list = messages.FieldList(self.integer_field, [1, 2, 3, 4, 5])
417 field_list[1:3] = [10, 20]
418 self.assertEquals([1, 10, 20, 4, 5], field_list)
419
420 def testSetSlice_InvalidValues(self):
421 field_list = messages.FieldList(self.integer_field, [1, 2, 3, 4, 5])
422
423 def setslice():
424 field_list[1:3] = ['10', '20']
425
426 msg_re = re.escape("Expected type %r "
427 "for IntegerField, found 10 (type %r)"
428 % (six.integer_types, str))
429 self.assertRaisesWithRegexpMatch(
430 messages.ValidationError,
431 msg_re,
432 setslice)
433
434 def testSetItem(self):
435 field_list = messages.FieldList(self.integer_field, [2])
436 field_list[0] = 10
437 self.assertEquals([10], field_list)
438
439 def testSetItem_InvalidValues(self):
440 field_list = messages.FieldList(self.integer_field, [2])
441
442 def setitem():
443 field_list[0] = '10'
444 self.assertRaisesWithRegexpMatch(
445 messages.ValidationError,
446 re.escape("Expected type %r "
447 "for IntegerField, found 10 (type %r)"
448 % (six.integer_types, str)),
449 setitem)
450
451 def testAppend(self):
452 field_list = messages.FieldList(self.integer_field, [2])
453 field_list.append(10)
454 self.assertEquals([2, 10], field_list)
455
456 def testAppend_InvalidValues(self):
457 field_list = messages.FieldList(self.integer_field, [2])
458 field_list.name = 'a_field'
459
460 def append():
461 field_list.append('10')
462 self.assertRaisesWithRegexpMatch(
463 messages.ValidationError,
464 re.escape("Expected type %r "
465 "for IntegerField, found 10 (type %r)"
466 % (six.integer_types, str)),
467 append)
468
469 def testExtend(self):
470 field_list = messages.FieldList(self.integer_field, [2])
471 field_list.extend([10])
472 self.assertEquals([2, 10], field_list)
473
474 def testExtend_InvalidValues(self):
475 field_list = messages.FieldList(self.integer_field, [2])
476
477 def extend():
478 field_list.extend(['10'])
479 self.assertRaisesWithRegexpMatch(
480 messages.ValidationError,
481 re.escape("Expected type %r "
482 "for IntegerField, found 10 (type %r)"
483 % (six.integer_types, str)),
484 extend)
485
486 def testInsert(self):
487 field_list = messages.FieldList(self.integer_field, [2, 3])
488 field_list.insert(1, 10)
489 self.assertEquals([2, 10, 3], field_list)
490
491 def testInsert_InvalidValues(self):
492 field_list = messages.FieldList(self.integer_field, [2, 3])
493
494 def insert():
495 field_list.insert(1, '10')
496 self.assertRaisesWithRegexpMatch(
497 messages.ValidationError,
498 re.escape("Expected type %r "
499 "for IntegerField, found 10 (type %r)"
500 % (six.integer_types, str)),
501 insert)
502
503 def testPickle(self):
504 """Testing pickling and unpickling of FieldList instances."""
505 field_list = messages.FieldList(self.integer_field, [1, 2, 3, 4, 5])
506 unpickled = pickle.loads(pickle.dumps(field_list))
507 self.assertEquals(field_list, unpickled)
508 self.assertIsInstance(unpickled.field, messages.IntegerField)
509 self.assertEquals(1, unpickled.field.number)
510 self.assertTrue(unpickled.field.repeated)
511
512
513 class FieldTest(test_util.TestCase):
514
515 def ActionOnAllFieldClasses(self, action):
516 """Test all field classes except Message and Enum.
517
518 Message and Enum require separate tests.
519
520 Args:
521 action: Callable that takes the field class as a parameter.
522 """
523 classes = (messages.IntegerField,
524 messages.FloatField,
525 messages.BooleanField,
526 messages.BytesField,
527 messages.StringField)
528 for field_class in classes:
529 action(field_class)
530
531 def testNumberAttribute(self):
532 """Test setting the number attribute."""
533 def action(field_class):
534 # Check range.
535 self.assertRaises(messages.InvalidNumberError,
536 field_class,
537 0)
538 self.assertRaises(messages.InvalidNumberError,
539 field_class,
540 -1)
541 self.assertRaises(messages.InvalidNumberError,
542 field_class,
543 messages.MAX_FIELD_NUMBER + 1)
544
545 # Check reserved.
546 self.assertRaises(messages.InvalidNumberError,
547 field_class,
548 messages.FIRST_RESERVED_FIELD_NUMBER)
549 self.assertRaises(messages.InvalidNumberError,
550 field_class,
551 messages.LAST_RESERVED_FIELD_NUMBER)
552 self.assertRaises(messages.InvalidNumberError,
553 field_class,
554 '1')
555
556 # This one should work.
557 field_class(number=1)
558 self.ActionOnAllFieldClasses(action)
559
560 def testRequiredAndRepeated(self):
561 """Test setting the required and repeated fields."""
562 def action(field_class):
563 field_class(1, required=True)
564 field_class(1, repeated=True)
565 self.assertRaises(messages.FieldDefinitionError,
566 field_class,
567 1,
568 required=True,
569 repeated=True)
570 self.ActionOnAllFieldClasses(action)
571
572 def testInvalidVariant(self):
573 """Test field with invalid variants."""
574 def action(field_class):
575 if field_class is not message_types.DateTimeField:
576 self.assertRaises(messages.InvalidVariantError,
577 field_class,
578 1,
579 variant=messages.Variant.ENUM)
580 self.ActionOnAllFieldClasses(action)
581
582 def testDefaultVariant(self):
583 """Test that default variant is used when not set."""
584 def action(field_class):
585 field = field_class(1)
586 self.assertEquals(field_class.DEFAULT_VARIANT, field.variant)
587
588 self.ActionOnAllFieldClasses(action)
589
590 def testAlternateVariant(self):
591 """Test that default variant is used when not set."""
592 field = messages.IntegerField(1, variant=messages.Variant.UINT32)
593 self.assertEquals(messages.Variant.UINT32, field.variant)
594
595 def testDefaultFields_Single(self):
596 """Test default field is correct type (single)."""
597 defaults = {
598 messages.IntegerField: 10,
599 messages.FloatField: 1.5,
600 messages.BooleanField: False,
601 messages.BytesField: b'abc',
602 messages.StringField: u'abc',
603 }
604
605 def action(field_class):
606 field_class(1, default=defaults[field_class])
607 self.ActionOnAllFieldClasses(action)
608
609 # Run defaults test again checking for str/unicode compatiblity.
610 defaults[messages.StringField] = 'abc'
611 self.ActionOnAllFieldClasses(action)
612
613 def testStringField_BadUnicodeInDefault(self):
614 """Test binary values in string field."""
615 self.assertRaisesWithRegexpMatch(
616 messages.InvalidDefaultError,
617 r"Invalid default value for StringField:.*: "
618 r"Field encountered non-ASCII string .*: "
619 r"'ascii' codec can't decode byte 0x89 in position 0: "
620 r"ordinal not in range",
621 messages.StringField, 1, default=b'\x89')
622
623 def testDefaultFields_InvalidSingle(self):
624 """Test default field is correct type (invalid single)."""
625 def action(field_class):
626 self.assertRaises(messages.InvalidDefaultError,
627 field_class,
628 1,
629 default=object())
630 self.ActionOnAllFieldClasses(action)
631
632 def testDefaultFields_InvalidRepeated(self):
633 """Test default field does not accept defaults."""
634 self.assertRaisesWithRegexpMatch(
635 messages.FieldDefinitionError,
636 'Repeated fields may not have defaults',
637 messages.StringField, 1, repeated=True, default=[1, 2, 3])
638
639 def testDefaultFields_None(self):
640 """Test none is always acceptable."""
641 def action(field_class):
642 field_class(1, default=None)
643 field_class(1, required=True, default=None)
644 field_class(1, repeated=True, default=None)
645 self.ActionOnAllFieldClasses(action)
646
647 def testDefaultFields_Enum(self):
648 """Test the default for enum fields."""
649 class Symbol(messages.Enum):
650
651 ALPHA = 1
652 BETA = 2
653 GAMMA = 3
654
655 field = messages.EnumField(Symbol, 1, default=Symbol.ALPHA)
656
657 self.assertEquals(Symbol.ALPHA, field.default)
658
659 def testDefaultFields_EnumStringDelayedResolution(self):
660 """Test that enum fields resolve default strings."""
661 field = messages.EnumField(
662 'apitools.base.protorpclite.descriptor.FieldDescriptor.Label',
663 1,
664 default='OPTIONAL')
665
666 self.assertEquals(
667 descriptor.FieldDescriptor.Label.OPTIONAL, field.default)
668
669 def testDefaultFields_EnumIntDelayedResolution(self):
670 """Test that enum fields resolve default integers."""
671 field = messages.EnumField(
672 'apitools.base.protorpclite.descriptor.FieldDescriptor.Label',
673 1,
674 default=2)
675
676 self.assertEquals(
677 descriptor.FieldDescriptor.Label.REQUIRED, field.default)
678
679 def testDefaultFields_EnumOkIfTypeKnown(self):
680 """Test enum fields accept valid default values when type is known."""
681 field = messages.EnumField(descriptor.FieldDescriptor.Label,
682 1,
683 default='REPEATED')
684
685 self.assertEquals(
686 descriptor.FieldDescriptor.Label.REPEATED, field.default)
687
688 def testDefaultFields_EnumForceCheckIfTypeKnown(self):
689 """Test that enum fields validate default values if type is known."""
690 self.assertRaisesWithRegexpMatch(TypeError,
691 'No such value for NOT_A_LABEL in '
692 'Enum Label',
693 messages.EnumField,
694 descriptor.FieldDescriptor.Label,
695 1,
696 default='NOT_A_LABEL')
697
698 def testDefaultFields_EnumInvalidDelayedResolution(self):
699 """Test that enum fields raise errors upon delayed resolution error."""
700 field = messages.EnumField(
701 'apitools.base.protorpclite.descriptor.FieldDescriptor.Label',
702 1,
703 default=200)
704
705 self.assertRaisesWithRegexpMatch(TypeError,
706 'No such value for 200 in Enum Label',
707 getattr,
708 field,
709 'default')
710
711 def testValidate_Valid(self):
712 """Test validation of valid values."""
713 values = {
714 messages.IntegerField: 10,
715 messages.FloatField: 1.5,
716 messages.BooleanField: False,
717 messages.BytesField: b'abc',
718 messages.StringField: u'abc',
719 }
720
721 def action(field_class):
722 # Optional.
723 field = field_class(1)
724 field.validate(values[field_class])
725
726 # Required.
727 field = field_class(1, required=True)
728 field.validate(values[field_class])
729
730 # Repeated.
731 field = field_class(1, repeated=True)
732 field.validate([])
733 field.validate(())
734 field.validate([values[field_class]])
735 field.validate((values[field_class],))
736
737 # Right value, but not repeated.
738 self.assertRaises(messages.ValidationError,
739 field.validate,
740 values[field_class])
741 self.assertRaises(messages.ValidationError,
742 field.validate,
743 values[field_class])
744
745 self.ActionOnAllFieldClasses(action)
746
747 def testValidate_Invalid(self):
748 """Test validation of valid values."""
749 values = {
750 messages.IntegerField: "10",
751 messages.FloatField: "blah",
752 messages.BooleanField: 0,
753 messages.BytesField: 10.20,
754 messages.StringField: 42,
755 }
756
757 def action(field_class):
758 # Optional.
759 field = field_class(1)
760 self.assertRaises(messages.ValidationError,
761 field.validate,
762 values[field_class])
763
764 # Required.
765 field = field_class(1, required=True)
766 self.assertRaises(messages.ValidationError,
767 field.validate,
768 values[field_class])
769
770 # Repeated.
771 field = field_class(1, repeated=True)
772 self.assertRaises(messages.ValidationError,
773 field.validate,
774 [values[field_class]])
775 self.assertRaises(messages.ValidationError,
776 field.validate,
777 (values[field_class],))
778 self.ActionOnAllFieldClasses(action)
779
780 def testValidate_None(self):
781 """Test that None is valid for non-required fields."""
782 def action(field_class):
783 # Optional.
784 field = field_class(1)
785 field.validate(None)
786
787 # Required.
788 field = field_class(1, required=True)
789 self.assertRaisesWithRegexpMatch(messages.ValidationError,
790 'Required field is missing',
791 field.validate,
792 None)
793
794 # Repeated.
795 field = field_class(1, repeated=True)
796 field.validate(None)
797 self.assertRaisesWithRegexpMatch(
798 messages.ValidationError,
799 'Repeated values for %s may '
800 'not be None' % field_class.__name__,
801 field.validate,
802 [None])
803 self.assertRaises(messages.ValidationError,
804 field.validate,
805 (None,))
806 self.ActionOnAllFieldClasses(action)
807
808 def testValidateElement(self):
809 """Test validation of valid values."""
810 values = {
811 messages.IntegerField: (10, -1, 0),
812 messages.FloatField: (1.5, -1.5, 3), # for json it is all a number
813 messages.BooleanField: (True, False),
814 messages.BytesField: (b'abc',),
815 messages.StringField: (u'abc',),
816 }
817
818 def action(field_class):
819 # Optional.
820 field = field_class(1)
821 for value in values[field_class]:
822 field.validate_element(value)
823
824 # Required.
825 field = field_class(1, required=True)
826 for value in values[field_class]:
827 field.validate_element(value)
828
829 # Repeated.
830 field = field_class(1, repeated=True)
831 self.assertRaises(messages.ValidationError,
832 field.validate_element,
833 [])
834 self.assertRaises(messages.ValidationError,
835 field.validate_element,
836 ())
837 for value in values[field_class]:
838 field.validate_element(value)
839
840 # Right value, but repeated.
841 self.assertRaises(messages.ValidationError,
842 field.validate_element,
843 list(values[field_class])) # testing list
844 self.assertRaises(messages.ValidationError,
845 field.validate_element,
846 values[field_class]) # testing tuple
847
848 self.ActionOnAllFieldClasses(action)
849
850 def testValidateCastingElement(self):
851 field = messages.FloatField(1)
852 self.assertEquals(type(field.validate_element(12)), float)
853 self.assertEquals(type(field.validate_element(12.0)), float)
854 # pylint: disable=redefined-variable-type
855 field = messages.IntegerField(1)
856 self.assertEquals(type(field.validate_element(12)), int)
857 self.assertRaises(messages.ValidationError,
858 field.validate_element,
859 12.0) # should fails from float to int
860
861 def testReadOnly(self):
862 """Test that objects are all read-only."""
863 def action(field_class):
864 field = field_class(10)
865 self.assertRaises(AttributeError,
866 setattr,
867 field,
868 'number',
869 20)
870 self.assertRaises(AttributeError,
871 setattr,
872 field,
873 'anything_else',
874 'whatever')
875 self.ActionOnAllFieldClasses(action)
876
877 def testMessageField(self):
878 """Test the construction of message fields."""
879 self.assertRaises(messages.FieldDefinitionError,
880 messages.MessageField,
881 str,
882 10)
883
884 self.assertRaises(messages.FieldDefinitionError,
885 messages.MessageField,
886 messages.Message,
887 10)
888
889 class MyMessage(messages.Message):
890 pass
891
892 field = messages.MessageField(MyMessage, 10)
893 self.assertEquals(MyMessage, field.type)
894
895 def testMessageField_ForwardReference(self):
896 """Test the construction of forward reference message fields."""
897 global MyMessage
898 global ForwardMessage
899 try:
900 class MyMessage(messages.Message):
901
902 self_reference = messages.MessageField('MyMessage', 1)
903 forward = messages.MessageField('ForwardMessage', 2)
904 nested = messages.MessageField(
905 'ForwardMessage.NestedMessage', 3)
906 inner = messages.MessageField('Inner', 4)
907
908 class Inner(messages.Message):
909
910 sibling = messages.MessageField('Sibling', 1)
911
912 class Sibling(messages.Message):
913
914 pass
915
916 class ForwardMessage(messages.Message):
917
918 class NestedMessage(messages.Message):
919
920 pass
921
922 self.assertEquals(MyMessage,
923 MyMessage.field_by_name('self_reference').type)
924
925 self.assertEquals(ForwardMessage,
926 MyMessage.field_by_name('forward').type)
927
928 self.assertEquals(ForwardMessage.NestedMessage,
929 MyMessage.field_by_name('nested').type)
930
931 self.assertEquals(MyMessage.Inner,
932 MyMessage.field_by_name('inner').type)
933
934 self.assertEquals(MyMessage.Sibling,
935 MyMessage.Inner.field_by_name('sibling').type)
936 finally:
937 try:
938 del MyMessage
939 del ForwardMessage
940 except: # pylint:disable=bare-except
941 pass
942
943 def testMessageField_WrongType(self):
944 """Test that forward referencing the wrong type raises an error."""
945 global AnEnum
946 try:
947 class AnEnum(messages.Enum):
948 pass
949
950 class AnotherMessage(messages.Message):
951
952 a_field = messages.MessageField('AnEnum', 1)
953
954 self.assertRaises(messages.FieldDefinitionError,
955 getattr,
956 AnotherMessage.field_by_name('a_field'),
957 'type')
958 finally:
959 del AnEnum
960
961 def testMessageFieldValidate(self):
962 """Test validation on message field."""
963 class MyMessage(messages.Message):
964 pass
965
966 class AnotherMessage(messages.Message):
967 pass
968
969 field = messages.MessageField(MyMessage, 10)
970 field.validate(MyMessage())
971
972 self.assertRaises(messages.ValidationError,
973 field.validate,
974 AnotherMessage())
975
976 def testMessageFieldMessageType(self):
977 """Test message_type property."""
978 class MyMessage(messages.Message):
979 pass
980
981 class HasMessage(messages.Message):
982 field = messages.MessageField(MyMessage, 1)
983
984 self.assertEqual(HasMessage.field.type, HasMessage.field.message_type)
985
986 def testMessageFieldValueFromMessage(self):
987 class MyMessage(messages.Message):
988 pass
989
990 class HasMessage(messages.Message):
991 field = messages.MessageField(MyMessage, 1)
992
993 instance = MyMessage()
994
995 self.assertTrue(
996 instance is HasMessage.field.value_from_message(instance))
997
998 def testMessageFieldValueFromMessageWrongType(self):
999 class MyMessage(messages.Message):
1000 pass
1001
1002 class HasMessage(messages.Message):
1003 field = messages.MessageField(MyMessage, 1)
1004
1005 self.assertRaisesWithRegexpMatch(
1006 messages.DecodeError,
1007 'Expected type MyMessage, got int: 10',
1008 HasMessage.field.value_from_message, 10)
1009
1010 def testMessageFieldValueToMessage(self):
1011 class MyMessage(messages.Message):
1012 pass
1013
1014 class HasMessage(messages.Message):
1015 field = messages.MessageField(MyMessage, 1)
1016
1017 instance = MyMessage()
1018
1019 self.assertTrue(
1020 instance is HasMessage.field.value_to_message(instance))
1021
1022 def testMessageFieldValueToMessageWrongType(self):
1023 class MyMessage(messages.Message):
1024 pass
1025
1026 class MyOtherMessage(messages.Message):
1027 pass
1028
1029 class HasMessage(messages.Message):
1030 field = messages.MessageField(MyMessage, 1)
1031
1032 instance = MyOtherMessage()
1033
1034 self.assertRaisesWithRegexpMatch(
1035 messages.EncodeError,
1036 'Expected type MyMessage, got MyOtherMessage: <MyOtherMessage>',
1037 HasMessage.field.value_to_message, instance)
1038
1039 def testIntegerField_AllowLong(self):
1040 """Test that the integer field allows for longs."""
1041 if six.PY2:
1042 messages.IntegerField(10, default=long(10))
1043
1044 def testMessageFieldValidate_Initialized(self):
1045 """Test validation on message field."""
1046 class MyMessage(messages.Message):
1047 field1 = messages.IntegerField(1, required=True)
1048
1049 field = messages.MessageField(MyMessage, 10)
1050
1051 # Will validate messages where is_initialized() is False.
1052 message = MyMessage()
1053 field.validate(message)
1054 message.field1 = 20
1055 field.validate(message)
1056
1057 def testEnumField(self):
1058 """Test the construction of enum fields."""
1059 self.assertRaises(messages.FieldDefinitionError,
1060 messages.EnumField,
1061 str,
1062 10)
1063
1064 self.assertRaises(messages.FieldDefinitionError,
1065 messages.EnumField,
1066 messages.Enum,
1067 10)
1068
1069 class Color(messages.Enum):
1070 RED = 1
1071 GREEN = 2
1072 BLUE = 3
1073
1074 field = messages.EnumField(Color, 10)
1075 self.assertEquals(Color, field.type)
1076
1077 class Another(messages.Enum):
1078 VALUE = 1
1079
1080 self.assertRaises(messages.InvalidDefaultError,
1081 messages.EnumField,
1082 Color,
1083 10,
1084 default=Another.VALUE)
1085
1086 def testEnumField_ForwardReference(self):
1087 """Test the construction of forward reference enum fields."""
1088 global MyMessage
1089 global ForwardEnum
1090 global ForwardMessage
1091 try:
1092 class MyMessage(messages.Message):
1093
1094 forward = messages.EnumField('ForwardEnum', 1)
1095 nested = messages.EnumField('ForwardMessage.NestedEnum', 2)
1096 inner = messages.EnumField('Inner', 3)
1097
1098 class Inner(messages.Enum):
1099 pass
1100
1101 class ForwardEnum(messages.Enum):
1102 pass
1103
1104 class ForwardMessage(messages.Message):
1105
1106 class NestedEnum(messages.Enum):
1107 pass
1108
1109 self.assertEquals(ForwardEnum,
1110 MyMessage.field_by_name('forward').type)
1111
1112 self.assertEquals(ForwardMessage.NestedEnum,
1113 MyMessage.field_by_name('nested').type)
1114
1115 self.assertEquals(MyMessage.Inner,
1116 MyMessage.field_by_name('inner').type)
1117 finally:
1118 try:
1119 del MyMessage
1120 del ForwardEnum
1121 del ForwardMessage
1122 except: # pylint:disable=bare-except
1123 pass
1124
1125 def testEnumField_WrongType(self):
1126 """Test that forward referencing the wrong type raises an error."""
1127 global AMessage
1128 try:
1129 class AMessage(messages.Message):
1130 pass
1131
1132 class AnotherMessage(messages.Message):
1133
1134 a_field = messages.EnumField('AMessage', 1)
1135
1136 self.assertRaises(messages.FieldDefinitionError,
1137 getattr,
1138 AnotherMessage.field_by_name('a_field'),
1139 'type')
1140 finally:
1141 del AMessage
1142
1143 def testMessageDefinition(self):
1144 """Test that message definition is set on fields."""
1145 class MyMessage(messages.Message):
1146
1147 my_field = messages.StringField(1)
1148
1149 self.assertEquals(
1150 MyMessage,
1151 MyMessage.field_by_name('my_field').message_definition())
1152
1153 def testNoneAssignment(self):
1154 """Test that assigning None does not change comparison."""
1155 class MyMessage(messages.Message):
1156
1157 my_field = messages.StringField(1)
1158
1159 m1 = MyMessage()
1160 m2 = MyMessage()
1161 m2.my_field = None
1162 self.assertEquals(m1, m2)
1163
1164 def testNonAsciiStr(self):
1165 """Test validation fails for non-ascii StringField values."""
1166 class Thing(messages.Message):
1167 string_field = messages.StringField(2)
1168
1169 thing = Thing()
1170 self.assertRaisesWithRegexpMatch(
1171 messages.ValidationError,
1172 'Field string_field encountered non-ASCII string',
1173 setattr, thing, 'string_field', test_util.BINARY)
1174
1175
1176 class MessageTest(test_util.TestCase):
1177 """Tests for message class."""
1178
1179 def CreateMessageClass(self):
1180 """Creates a simple message class with 3 fields.
1181
1182 Fields are defined in alphabetical order but with conflicting numeric
1183 order.
1184 """
1185 class ComplexMessage(messages.Message):
1186 a3 = messages.IntegerField(3)
1187 b1 = messages.StringField(1)
1188 c2 = messages.StringField(2)
1189
1190 return ComplexMessage
1191
1192 def testSameNumbers(self):
1193 """Test that cannot assign two fields with same numbers."""
1194
1195 def action():
1196 class BadMessage(messages.Message):
1197 f1 = messages.IntegerField(1)
1198 f2 = messages.IntegerField(1)
1199 self.assertRaises(messages.DuplicateNumberError,
1200 action)
1201
1202 def testStrictAssignment(self):
1203 """Tests that cannot assign to unknown or non-reserved attributes."""
1204 class SimpleMessage(messages.Message):
1205 field = messages.IntegerField(1)
1206
1207 simple_message = SimpleMessage()
1208 self.assertRaises(AttributeError,
1209 setattr,
1210 simple_message,
1211 'does_not_exist',
1212 10)
1213
1214 def testListAssignmentDoesNotCopy(self):
1215 class SimpleMessage(messages.Message):
1216 repeated = messages.IntegerField(1, repeated=True)
1217
1218 message = SimpleMessage()
1219 original = message.repeated
1220 message.repeated = []
1221 self.assertFalse(original is message.repeated)
1222
1223 def testValidate_Optional(self):
1224 """Tests validation of optional fields."""
1225 class SimpleMessage(messages.Message):
1226 non_required = messages.IntegerField(1)
1227
1228 simple_message = SimpleMessage()
1229 simple_message.check_initialized()
1230 simple_message.non_required = 10
1231 simple_message.check_initialized()
1232
1233 def testValidate_Required(self):
1234 """Tests validation of required fields."""
1235 class SimpleMessage(messages.Message):
1236 required = messages.IntegerField(1, required=True)
1237
1238 simple_message = SimpleMessage()
1239 self.assertRaises(messages.ValidationError,
1240 simple_message.check_initialized)
1241 simple_message.required = 10
1242 simple_message.check_initialized()
1243
1244 def testValidate_Repeated(self):
1245 """Tests validation of repeated fields."""
1246 class SimpleMessage(messages.Message):
1247 repeated = messages.IntegerField(1, repeated=True)
1248
1249 simple_message = SimpleMessage()
1250
1251 # Check valid values.
1252 for valid_value in [], [10], [10, 20], (), (10,), (10, 20):
1253 simple_message.repeated = valid_value
1254 simple_message.check_initialized()
1255
1256 # Check cleared.
1257 simple_message.repeated = []
1258 simple_message.check_initialized()
1259
1260 # Check invalid values.
1261 for invalid_value in 10, ['10', '20'], [None], (None,):
1262 self.assertRaises(
1263 messages.ValidationError,
1264 setattr, simple_message, 'repeated', invalid_value)
1265
1266 def testIsInitialized(self):
1267 """Tests is_initialized."""
1268 class SimpleMessage(messages.Message):
1269 required = messages.IntegerField(1, required=True)
1270
1271 simple_message = SimpleMessage()
1272 self.assertFalse(simple_message.is_initialized())
1273
1274 simple_message.required = 10
1275
1276 self.assertTrue(simple_message.is_initialized())
1277
1278 def testIsInitializedNestedField(self):
1279 """Tests is_initialized for nested fields."""
1280 class SimpleMessage(messages.Message):
1281 required = messages.IntegerField(1, required=True)
1282
1283 class NestedMessage(messages.Message):
1284 simple = messages.MessageField(SimpleMessage, 1)
1285
1286 simple_message = SimpleMessage()
1287 self.assertFalse(simple_message.is_initialized())
1288 nested_message = NestedMessage(simple=simple_message)
1289 self.assertFalse(nested_message.is_initialized())
1290
1291 simple_message.required = 10
1292
1293 self.assertTrue(simple_message.is_initialized())
1294 self.assertTrue(nested_message.is_initialized())
1295
1296 def testInitializeNestedFieldFromDict(self):
1297 """Tests initializing nested fields from dict."""
1298 class SimpleMessage(messages.Message):
1299 required = messages.IntegerField(1, required=True)
1300
1301 class NestedMessage(messages.Message):
1302 simple = messages.MessageField(SimpleMessage, 1)
1303
1304 class RepeatedMessage(messages.Message):
1305 simple = messages.MessageField(SimpleMessage, 1, repeated=True)
1306
1307 nested_message1 = NestedMessage(simple={'required': 10})
1308 self.assertTrue(nested_message1.is_initialized())
1309 self.assertTrue(nested_message1.simple.is_initialized())
1310
1311 nested_message2 = NestedMessage()
1312 nested_message2.simple = {'required': 10}
1313 self.assertTrue(nested_message2.is_initialized())
1314 self.assertTrue(nested_message2.simple.is_initialized())
1315
1316 repeated_values = [{}, {'required': 10}, SimpleMessage(required=20)]
1317
1318 repeated_message1 = RepeatedMessage(simple=repeated_values)
1319 self.assertEquals(3, len(repeated_message1.simple))
1320 self.assertFalse(repeated_message1.is_initialized())
1321
1322 repeated_message1.simple[0].required = 0
1323 self.assertTrue(repeated_message1.is_initialized())
1324
1325 repeated_message2 = RepeatedMessage()
1326 repeated_message2.simple = repeated_values
1327 self.assertEquals(3, len(repeated_message2.simple))
1328 self.assertFalse(repeated_message2.is_initialized())
1329
1330 repeated_message2.simple[0].required = 0
1331 self.assertTrue(repeated_message2.is_initialized())
1332
1333 def testNestedMethodsNotAllowed(self):
1334 """Test that method definitions on Message classes are not allowed."""
1335 def action():
1336 class WithMethods(messages.Message):
1337
1338 def not_allowed(self):
1339 pass
1340
1341 self.assertRaises(messages.MessageDefinitionError,
1342 action)
1343
1344 def testNestedAttributesNotAllowed(self):
1345 """Test attribute assignment on Message classes is not allowed."""
1346 def int_attribute():
1347 class WithMethods(messages.Message):
1348 not_allowed = 1
1349
1350 def string_attribute():
1351 class WithMethods(messages.Message):
1352 not_allowed = 'not allowed'
1353
1354 def enum_attribute():
1355 class WithMethods(messages.Message):
1356 not_allowed = Color.RED
1357
1358 for action in (int_attribute, string_attribute, enum_attribute):
1359 self.assertRaises(messages.MessageDefinitionError,
1360 action)
1361
1362 def testNameIsSetOnFields(self):
1363 """Make sure name is set on fields after Message class init."""
1364 class HasNamedFields(messages.Message):
1365 field = messages.StringField(1)
1366
1367 self.assertEquals('field', HasNamedFields.field_by_number(1).name)
1368
1369 def testSubclassingMessageDisallowed(self):
1370 """Not permitted to create sub-classes of message classes."""
1371 class SuperClass(messages.Message):
1372 pass
1373
1374 def action():
1375 class SubClass(SuperClass):
1376 pass
1377
1378 self.assertRaises(messages.MessageDefinitionError,
1379 action)
1380
1381 def testAllFields(self):
1382 """Test all_fields method."""
1383 ComplexMessage = self.CreateMessageClass()
1384 fields = list(ComplexMessage.all_fields())
1385
1386 # Order does not matter, so sort now.
1387 fields = sorted(fields, key=lambda f: f.name)
1388
1389 self.assertEquals(3, len(fields))
1390 self.assertEquals('a3', fields[0].name)
1391 self.assertEquals('b1', fields[1].name)
1392 self.assertEquals('c2', fields[2].name)
1393
1394 def testFieldByName(self):
1395 """Test getting field by name."""
1396 ComplexMessage = self.CreateMessageClass()
1397
1398 self.assertEquals(3, ComplexMessage.field_by_name('a3').number)
1399 self.assertEquals(1, ComplexMessage.field_by_name('b1').number)
1400 self.assertEquals(2, ComplexMessage.field_by_name('c2').number)
1401
1402 self.assertRaises(KeyError,
1403 ComplexMessage.field_by_name,
1404 'unknown')
1405
1406 def testFieldByNumber(self):
1407 """Test getting field by number."""
1408 ComplexMessage = self.CreateMessageClass()
1409
1410 self.assertEquals('a3', ComplexMessage.field_by_number(3).name)
1411 self.assertEquals('b1', ComplexMessage.field_by_number(1).name)
1412 self.assertEquals('c2', ComplexMessage.field_by_number(2).name)
1413
1414 self.assertRaises(KeyError,
1415 ComplexMessage.field_by_number,
1416 4)
1417
1418 def testGetAssignedValue(self):
1419 """Test getting the assigned value of a field."""
1420 class SomeMessage(messages.Message):
1421 a_value = messages.StringField(1, default=u'a default')
1422
1423 message = SomeMessage()
1424 self.assertEquals(None, message.get_assigned_value('a_value'))
1425
1426 message.a_value = u'a string'
1427 self.assertEquals(u'a string', message.get_assigned_value('a_value'))
1428
1429 message.a_value = u'a default'
1430 self.assertEquals(u'a default', message.get_assigned_value('a_value'))
1431
1432 self.assertRaisesWithRegexpMatch(
1433 AttributeError,
1434 'Message SomeMessage has no field no_such_field',
1435 message.get_assigned_value,
1436 'no_such_field')
1437
1438 def testReset(self):
1439 """Test resetting a field value."""
1440 class SomeMessage(messages.Message):
1441 a_value = messages.StringField(1, default=u'a default')
1442 repeated = messages.IntegerField(2, repeated=True)
1443
1444 message = SomeMessage()
1445
1446 self.assertRaises(AttributeError, message.reset, 'unknown')
1447
1448 self.assertEquals(u'a default', message.a_value)
1449 message.reset('a_value')
1450 self.assertEquals(u'a default', message.a_value)
1451
1452 message.a_value = u'a new value'
1453 self.assertEquals(u'a new value', message.a_value)
1454 message.reset('a_value')
1455 self.assertEquals(u'a default', message.a_value)
1456
1457 message.repeated = [1, 2, 3]
1458 self.assertEquals([1, 2, 3], message.repeated)
1459 saved = message.repeated
1460 message.reset('repeated')
1461 self.assertEquals([], message.repeated)
1462 self.assertIsInstance(message.repeated, messages.FieldList)
1463 self.assertEquals([1, 2, 3], saved)
1464
1465 def testAllowNestedEnums(self):
1466 """Test allowing nested enums in a message definition."""
1467 class Trade(messages.Message):
1468
1469 class Duration(messages.Enum):
1470 GTC = 1
1471 DAY = 2
1472
1473 class Currency(messages.Enum):
1474 USD = 1
1475 GBP = 2
1476 INR = 3
1477
1478 # Sorted by name order seems to be the only feasible option.
1479 self.assertEquals(['Currency', 'Duration'], Trade.__enums__)
1480
1481 # Message definition will now be set on Enumerated objects.
1482 self.assertEquals(Trade, Trade.Duration.message_definition())
1483
1484 def testAllowNestedMessages(self):
1485 """Test allowing nested messages in a message definition."""
1486 class Trade(messages.Message):
1487
1488 class Lot(messages.Message):
1489 pass
1490
1491 class Agent(messages.Message):
1492 pass
1493
1494 # Sorted by name order seems to be the only feasible option.
1495 self.assertEquals(['Agent', 'Lot'], Trade.__messages__)
1496 self.assertEquals(Trade, Trade.Agent.message_definition())
1497 self.assertEquals(Trade, Trade.Lot.message_definition())
1498
1499 # But not Message itself.
1500 def action():
1501 class Trade(messages.Message):
1502 NiceTry = messages.Message
1503 self.assertRaises(messages.MessageDefinitionError, action)
1504
1505 def testDisallowClassAssignments(self):
1506 """Test setting class attributes may not happen."""
1507 class MyMessage(messages.Message):
1508 pass
1509
1510 self.assertRaises(AttributeError,
1511 setattr,
1512 MyMessage,
1513 'x',
1514 'do not assign')
1515
1516 def testEquality(self):
1517 """Test message class equality."""
1518 # Comparison against enums must work.
1519 class MyEnum(messages.Enum):
1520 val1 = 1
1521 val2 = 2
1522
1523 # Comparisons against nested messages must work.
1524 class AnotherMessage(messages.Message):
1525 string = messages.StringField(1)
1526
1527 class MyMessage(messages.Message):
1528 field1 = messages.IntegerField(1)
1529 field2 = messages.EnumField(MyEnum, 2)
1530 field3 = messages.MessageField(AnotherMessage, 3)
1531
1532 message1 = MyMessage()
1533
1534 self.assertNotEquals('hi', message1)
1535 self.assertNotEquals(AnotherMessage(), message1)
1536 self.assertEquals(message1, message1)
1537
1538 message2 = MyMessage()
1539
1540 self.assertEquals(message1, message2)
1541
1542 message1.field1 = 10
1543 self.assertNotEquals(message1, message2)
1544
1545 message2.field1 = 20
1546 self.assertNotEquals(message1, message2)
1547
1548 message2.field1 = 10
1549 self.assertEquals(message1, message2)
1550
1551 message1.field2 = MyEnum.val1
1552 self.assertNotEquals(message1, message2)
1553
1554 message2.field2 = MyEnum.val2
1555 self.assertNotEquals(message1, message2)
1556
1557 message2.field2 = MyEnum.val1
1558 self.assertEquals(message1, message2)
1559
1560 message1.field3 = AnotherMessage()
1561 message1.field3.string = 'value1'
1562 self.assertNotEquals(message1, message2)
1563
1564 message2.field3 = AnotherMessage()
1565 message2.field3.string = 'value2'
1566 self.assertNotEquals(message1, message2)
1567
1568 message2.field3.string = 'value1'
1569 self.assertEquals(message1, message2)
1570
1571 def testEqualityWithUnknowns(self):
1572 """Test message class equality with unknown fields."""
1573
1574 class MyMessage(messages.Message):
1575 field1 = messages.IntegerField(1)
1576
1577 message1 = MyMessage()
1578 message2 = MyMessage()
1579 self.assertEquals(message1, message2)
1580 message1.set_unrecognized_field('unknown1', 'value1',
1581 messages.Variant.STRING)
1582 self.assertEquals(message1, message2)
1583
1584 message1.set_unrecognized_field('unknown2', ['asdf', 3],
1585 messages.Variant.STRING)
1586 message1.set_unrecognized_field('unknown3', 4.7,
1587 messages.Variant.DOUBLE)
1588 self.assertEquals(message1, message2)
1589
1590 def testUnrecognizedFieldInvalidVariant(self):
1591 class MyMessage(messages.Message):
1592 field1 = messages.IntegerField(1)
1593
1594 message1 = MyMessage()
1595 self.assertRaises(
1596 TypeError, message1.set_unrecognized_field, 'unknown4',
1597 {'unhandled': 'type'}, None)
1598 self.assertRaises(
1599 TypeError, message1.set_unrecognized_field, 'unknown4',
1600 {'unhandled': 'type'}, 123)
1601
1602 def testRepr(self):
1603 """Test represtation of Message object."""
1604 class MyMessage(messages.Message):
1605 integer_value = messages.IntegerField(1)
1606 string_value = messages.StringField(2)
1607 unassigned = messages.StringField(3)
1608 unassigned_with_default = messages.StringField(
1609 4, default=u'a default')
1610
1611 my_message = MyMessage()
1612 my_message.integer_value = 42
1613 my_message.string_value = u'A string'
1614
1615 pat = re.compile(r"<MyMessage\n integer_value: 42\n"
1616 " string_value: [u]?'A string'>")
1617 self.assertTrue(pat.match(repr(my_message)) is not None)
1618
1619 def testValidation(self):
1620 """Test validation of message values."""
1621 # Test optional.
1622 class SubMessage(messages.Message):
1623 pass
1624
1625 class Message(messages.Message):
1626 val = messages.MessageField(SubMessage, 1)
1627
1628 message = Message()
1629
1630 message_field = messages.MessageField(Message, 1)
1631 message_field.validate(message)
1632 message.val = SubMessage()
1633 message_field.validate(message)
1634 self.assertRaises(messages.ValidationError,
1635 setattr, message, 'val', [SubMessage()])
1636
1637 # Test required.
1638 class Message(messages.Message):
1639 val = messages.MessageField(SubMessage, 1, required=True)
1640
1641 message = Message()
1642
1643 message_field = messages.MessageField(Message, 1)
1644 message_field.validate(message)
1645 message.val = SubMessage()
1646 message_field.validate(message)
1647 self.assertRaises(messages.ValidationError,
1648 setattr, message, 'val', [SubMessage()])
1649
1650 # Test repeated.
1651 class Message(messages.Message):
1652 val = messages.MessageField(SubMessage, 1, repeated=True)
1653
1654 message = Message()
1655
1656 message_field = messages.MessageField(Message, 1)
1657 message_field.validate(message)
1658 self.assertRaisesWithRegexpMatch(
1659 messages.ValidationError,
1660 "Field val is repeated. Found: <SubMessage>",
1661 setattr, message, 'val', SubMessage())
1662 # pylint: disable=redefined-variable-type
1663 message.val = [SubMessage()]
1664 message_field.validate(message)
1665
1666 def testDefinitionName(self):
1667 """Test message name."""
1668 class MyMessage(messages.Message):
1669 pass
1670
1671 module_name = test_util.get_module_name(FieldTest)
1672 self.assertEquals('%s.MyMessage' % module_name,
1673 MyMessage.definition_name())
1674 self.assertEquals(module_name, MyMessage.outer_definition_name())
1675 self.assertEquals(module_name, MyMessage.definition_package())
1676
1677 self.assertEquals(six.text_type, type(MyMessage.definition_name()))
1678 self.assertEquals(six.text_type, type(
1679 MyMessage.outer_definition_name()))
1680 self.assertEquals(six.text_type, type(MyMessage.definition_package()))
1681
1682 def testDefinitionName_OverrideModule(self):
1683 """Test message module is overriden by module package name."""
1684 class MyMessage(messages.Message):
1685 pass
1686
1687 global package
1688 package = 'my.package'
1689
1690 try:
1691 self.assertEquals('my.package.MyMessage',
1692 MyMessage.definition_name())
1693 self.assertEquals('my.package', MyMessage.outer_definition_name())
1694 self.assertEquals('my.package', MyMessage.definition_package())
1695
1696 self.assertEquals(six.text_type, type(MyMessage.definition_name()))
1697 self.assertEquals(six.text_type, type(
1698 MyMessage.outer_definition_name()))
1699 self.assertEquals(six.text_type, type(
1700 MyMessage.definition_package()))
1701 finally:
1702 del package
1703
1704 def testDefinitionName_NoModule(self):
1705 """Test what happens when there is no module for message."""
1706 class MyMessage(messages.Message):
1707 pass
1708
1709 original_modules = sys.modules
1710 sys.modules = dict(sys.modules)
1711 try:
1712 del sys.modules[__name__]
1713 self.assertEquals('MyMessage', MyMessage.definition_name())
1714 self.assertEquals(None, MyMessage.outer_definition_name())
1715 self.assertEquals(None, MyMessage.definition_package())
1716
1717 self.assertEquals(six.text_type, type(MyMessage.definition_name()))
1718 finally:
1719 sys.modules = original_modules
1720
1721 def testDefinitionName_Nested(self):
1722 """Test nested message names."""
1723 class MyMessage(messages.Message):
1724
1725 class NestedMessage(messages.Message):
1726
1727 class NestedMessage(messages.Message):
1728
1729 pass
1730
1731 module_name = test_util.get_module_name(MessageTest)
1732 self.assertEquals('%s.MyMessage.NestedMessage' % module_name,
1733 MyMessage.NestedMessage.definition_name())
1734 self.assertEquals('%s.MyMessage' % module_name,
1735 MyMessage.NestedMessage.outer_definition_name())
1736 self.assertEquals(module_name,
1737 MyMessage.NestedMessage.definition_package())
1738
1739 self.assertEquals(
1740 '%s.MyMessage.NestedMessage.NestedMessage' % module_name,
1741 MyMessage.NestedMessage.NestedMessage.definition_name())
1742 self.assertEquals(
1743 '%s.MyMessage.NestedMessage' % module_name,
1744 MyMessage.NestedMessage.NestedMessage.outer_definition_name())
1745 self.assertEquals(
1746 module_name,
1747 MyMessage.NestedMessage.NestedMessage.definition_package())
1748
1749 def testMessageDefinition(self):
1750 """Test that enumeration knows its enclosing message definition."""
1751 class OuterMessage(messages.Message):
1752
1753 class InnerMessage(messages.Message):
1754 pass
1755
1756 self.assertEquals(None, OuterMessage.message_definition())
1757 self.assertEquals(OuterMessage,
1758 OuterMessage.InnerMessage.message_definition())
1759
1760 def testConstructorKwargs(self):
1761 """Test kwargs via constructor."""
1762 class SomeMessage(messages.Message):
1763 name = messages.StringField(1)
1764 number = messages.IntegerField(2)
1765
1766 expected = SomeMessage()
1767 expected.name = 'my name'
1768 expected.number = 200
1769 self.assertEquals(expected, SomeMessage(name='my name', number=200))
1770
1771 def testConstructorNotAField(self):
1772 """Test kwargs via constructor with wrong names."""
1773 class SomeMessage(messages.Message):
1774 pass
1775
1776 self.assertRaisesWithRegexpMatch(
1777 AttributeError,
1778 ('May not assign arbitrary value does_not_exist to message '
1779 'SomeMessage'),
1780 SomeMessage,
1781 does_not_exist=10)
1782
1783 def testGetUnsetRepeatedValue(self):
1784 class SomeMessage(messages.Message):
1785 repeated = messages.IntegerField(1, repeated=True)
1786
1787 instance = SomeMessage()
1788 self.assertEquals([], instance.repeated)
1789 self.assertTrue(isinstance(instance.repeated, messages.FieldList))
1790
1791 def testCompareAutoInitializedRepeatedFields(self):
1792 class SomeMessage(messages.Message):
1793 repeated = messages.IntegerField(1, repeated=True)
1794
1795 message1 = SomeMessage(repeated=[])
1796 message2 = SomeMessage()
1797 self.assertEquals(message1, message2)
1798
1799 def testUnknownValues(self):
1800 """Test message class equality with unknown fields."""
1801 class MyMessage(messages.Message):
1802 field1 = messages.IntegerField(1)
1803
1804 message = MyMessage()
1805 self.assertEquals([], message.all_unrecognized_fields())
1806 self.assertEquals((None, None),
1807 message.get_unrecognized_field_info('doesntexist'))
1808 self.assertEquals((None, None),
1809 message.get_unrecognized_field_info(
1810 'doesntexist', None, None))
1811 self.assertEquals(('defaultvalue', 'defaultwire'),
1812 message.get_unrecognized_field_info(
1813 'doesntexist', 'defaultvalue', 'defaultwire'))
1814 self.assertEquals((3, None),
1815 message.get_unrecognized_field_info(
1816 'doesntexist', value_default=3))
1817
1818 message.set_unrecognized_field('exists', 9.5, messages.Variant.DOUBLE)
1819 self.assertEquals(1, len(message.all_unrecognized_fields()))
1820 self.assertTrue('exists' in message.all_unrecognized_fields())
1821 self.assertEquals((9.5, messages.Variant.DOUBLE),
1822 message.get_unrecognized_field_info('exists'))
1823 self.assertEquals((9.5, messages.Variant.DOUBLE),
1824 message.get_unrecognized_field_info('exists', 'type',
1825 1234))
1826 self.assertEquals(
1827 (1234, None),
1828 message.get_unrecognized_field_info('doesntexist', 1234))
1829
1830 message.set_unrecognized_field(
1831 'another', 'value', messages.Variant.STRING)
1832 self.assertEquals(2, len(message.all_unrecognized_fields()))
1833 self.assertTrue('exists' in message.all_unrecognized_fields())
1834 self.assertTrue('another' in message.all_unrecognized_fields())
1835 self.assertEquals((9.5, messages.Variant.DOUBLE),
1836 message.get_unrecognized_field_info('exists'))
1837 self.assertEquals(('value', messages.Variant.STRING),
1838 message.get_unrecognized_field_info('another'))
1839
1840 message.set_unrecognized_field('typetest1', ['list', 0, ('test',)],
1841 messages.Variant.STRING)
1842 self.assertEquals((['list', 0, ('test',)], messages.Variant.STRING),
1843 message.get_unrecognized_field_info('typetest1'))
1844 message.set_unrecognized_field(
1845 'typetest2', '', messages.Variant.STRING)
1846 self.assertEquals(('', messages.Variant.STRING),
1847 message.get_unrecognized_field_info('typetest2'))
1848
1849 def testPickle(self):
1850 """Testing pickling and unpickling of Message instances."""
1851 global MyEnum
1852 global AnotherMessage
1853 global MyMessage
1854
1855 class MyEnum(messages.Enum):
1856 val1 = 1
1857 val2 = 2
1858
1859 class AnotherMessage(messages.Message):
1860 string = messages.StringField(1, repeated=True)
1861
1862 class MyMessage(messages.Message):
1863 field1 = messages.IntegerField(1)
1864 field2 = messages.EnumField(MyEnum, 2)
1865 field3 = messages.MessageField(AnotherMessage, 3)
1866
1867 message = MyMessage(field1=1, field2=MyEnum.val2,
1868 field3=AnotherMessage(string=['a', 'b', 'c']))
1869 message.set_unrecognized_field(
1870 'exists', 'value', messages.Variant.STRING)
1871 message.set_unrecognized_field('repeated', ['list', 0, ('test',)],
1872 messages.Variant.STRING)
1873 unpickled = pickle.loads(pickle.dumps(message))
1874 self.assertEquals(message, unpickled)
1875 self.assertTrue(AnotherMessage.string is unpickled.field3.string.field)
1876 self.assertTrue('exists' in message.all_unrecognized_fields())
1877 self.assertEquals(('value', messages.Variant.STRING),
1878 message.get_unrecognized_field_info('exists'))
1879 self.assertEquals((['list', 0, ('test',)], messages.Variant.STRING),
1880 message.get_unrecognized_field_info('repeated'))
1881
1882
1883 class FindDefinitionTest(test_util.TestCase):
1884 """Test finding definitions relative to various definitions and modules."""
1885
1886 def setUp(self):
1887 """Set up module-space. Starts off empty."""
1888 self.modules = {}
1889
1890 def DefineModule(self, name):
1891 """Define a module and its parents in module space.
1892
1893 Modules that are already defined in self.modules are not re-created.
1894
1895 Args:
1896 name: Fully qualified name of modules to create.
1897
1898 Returns:
1899 Deepest nested module. For example:
1900
1901 DefineModule('a.b.c') # Returns c.
1902 """
1903 name_path = name.split('.')
1904 full_path = []
1905 for node in name_path:
1906 full_path.append(node)
1907 full_name = '.'.join(full_path)
1908 self.modules.setdefault(full_name, types.ModuleType(full_name))
1909 return self.modules[name]
1910
1911 def DefineMessage(self, module, name, children=None, add_to_module=True):
1912 """Define a new Message class in the context of a module.
1913
1914 Used for easily describing complex Message hierarchy. Message
1915 is defined including all child definitions.
1916
1917 Args:
1918 module: Fully qualified name of module to place Message class in.
1919 name: Name of Message to define within module.
1920 children: Define any level of nesting of children
1921 definitions. To define a message, map the name to another
1922 dictionary. The dictionary can itself contain additional
1923 definitions, and so on. To map to an Enum, define the Enum
1924 class separately and map it by name.
1925 add_to_module: If True, new Message class is added to
1926 module. If False, new Message is not added.
1927
1928 """
1929 children = children or {}
1930 # Make sure module exists.
1931 module_instance = self.DefineModule(module)
1932
1933 # Recursively define all child messages.
1934 for attribute, value in children.items():
1935 if isinstance(value, dict):
1936 children[attribute] = self.DefineMessage(
1937 module, attribute, value, False)
1938
1939 # Override default __module__ variable.
1940 children['__module__'] = module
1941
1942 # Instantiate and possibly add to module.
1943 message_class = type(name, (messages.Message,), dict(children))
1944 if add_to_module:
1945 setattr(module_instance, name, message_class)
1946 return message_class
1947
1948 # pylint:disable=unused-argument
1949 # pylint:disable=redefined-builtin
1950 def Importer(self, module, globals='', locals='', fromlist=None):
1951 """Importer function.
1952
1953 Acts like __import__. Only loads modules from self.modules.
1954 Does not try to load real modules defined elsewhere. Does not
1955 try to handle relative imports.
1956
1957 Args:
1958 module: Fully qualified name of module to load from self.modules.
1959
1960 """
1961 if fromlist is None:
1962 module = module.split('.')[0]
1963 try:
1964 return self.modules[module]
1965 except KeyError:
1966 raise ImportError()
1967 # pylint:disable=unused-argument
1968
1969 def testNoSuchModule(self):
1970 """Test searching for definitions that do no exist."""
1971 self.assertRaises(messages.DefinitionNotFoundError,
1972 messages.find_definition,
1973 'does.not.exist',
1974 importer=self.Importer)
1975
1976 def testRefersToModule(self):
1977 """Test that referring to a module does not return that module."""
1978 self.DefineModule('i.am.a.module')
1979 self.assertRaises(messages.DefinitionNotFoundError,
1980 messages.find_definition,
1981 'i.am.a.module',
1982 importer=self.Importer)
1983
1984 def testNoDefinition(self):
1985 """Test not finding a definition in an existing module."""
1986 self.DefineModule('i.am.a.module')
1987 self.assertRaises(messages.DefinitionNotFoundError,
1988 messages.find_definition,
1989 'i.am.a.module.MyMessage',
1990 importer=self.Importer)
1991
1992 def testNotADefinition(self):
1993 """Test trying to fetch something that is not a definition."""
1994 module = self.DefineModule('i.am.a.module')
1995 setattr(module, 'A', 'a string')
1996 self.assertRaises(messages.DefinitionNotFoundError,
1997 messages.find_definition,
1998 'i.am.a.module.A',
1999 importer=self.Importer)
2000
2001 def testGlobalFind(self):
2002 """Test finding definitions from fully qualified module names."""
2003 A = self.DefineMessage('a.b.c', 'A', {})
2004 self.assertEquals(A, messages.find_definition('a.b.c.A',
2005 importer=self.Importer))
2006 B = self.DefineMessage('a.b.c', 'B', {'C': {}})
2007 self.assertEquals(
2008 B.C,
2009 messages.find_definition('a.b.c.B.C', importer=self.Importer))
2010
2011 def testRelativeToModule(self):
2012 """Test finding definitions relative to modules."""
2013 # Define modules.
2014 a = self.DefineModule('a')
2015 b = self.DefineModule('a.b')
2016 c = self.DefineModule('a.b.c')
2017
2018 # Define messages.
2019 A = self.DefineMessage('a', 'A')
2020 B = self.DefineMessage('a.b', 'B')
2021 C = self.DefineMessage('a.b.c', 'C')
2022 D = self.DefineMessage('a.b.d', 'D')
2023
2024 # Find A, B, C and D relative to a.
2025 self.assertEquals(A, messages.find_definition(
2026 'A', a, importer=self.Importer))
2027 self.assertEquals(B, messages.find_definition(
2028 'b.B', a, importer=self.Importer))
2029 self.assertEquals(C, messages.find_definition(
2030 'b.c.C', a, importer=self.Importer))
2031 self.assertEquals(D, messages.find_definition(
2032 'b.d.D', a, importer=self.Importer))
2033
2034 # Find A, B, C and D relative to b.
2035 self.assertEquals(A, messages.find_definition(
2036 'A', b, importer=self.Importer))
2037 self.assertEquals(B, messages.find_definition(
2038 'B', b, importer=self.Importer))
2039 self.assertEquals(C, messages.find_definition(
2040 'c.C', b, importer=self.Importer))
2041 self.assertEquals(D, messages.find_definition(
2042 'd.D', b, importer=self.Importer))
2043
2044 # Find A, B, C and D relative to c. Module d is the same case as c.
2045 self.assertEquals(A, messages.find_definition(
2046 'A', c, importer=self.Importer))
2047 self.assertEquals(B, messages.find_definition(
2048 'B', c, importer=self.Importer))
2049 self.assertEquals(C, messages.find_definition(
2050 'C', c, importer=self.Importer))
2051 self.assertEquals(D, messages.find_definition(
2052 'd.D', c, importer=self.Importer))
2053
2054 def testRelativeToMessages(self):
2055 """Test finding definitions relative to Message definitions."""
2056 A = self.DefineMessage('a.b', 'A', {'B': {'C': {}, 'D': {}}})
2057 B = A.B
2058 C = A.B.C
2059 D = A.B.D
2060
2061 # Find relative to A.
2062 self.assertEquals(A, messages.find_definition(
2063 'A', A, importer=self.Importer))
2064 self.assertEquals(B, messages.find_definition(
2065 'B', A, importer=self.Importer))
2066 self.assertEquals(C, messages.find_definition(
2067 'B.C', A, importer=self.Importer))
2068 self.assertEquals(D, messages.find_definition(
2069 'B.D', A, importer=self.Importer))
2070
2071 # Find relative to B.
2072 self.assertEquals(A, messages.find_definition(
2073 'A', B, importer=self.Importer))
2074 self.assertEquals(B, messages.find_definition(
2075 'B', B, importer=self.Importer))
2076 self.assertEquals(C, messages.find_definition(
2077 'C', B, importer=self.Importer))
2078 self.assertEquals(D, messages.find_definition(
2079 'D', B, importer=self.Importer))
2080
2081 # Find relative to C.
2082 self.assertEquals(A, messages.find_definition(
2083 'A', C, importer=self.Importer))
2084 self.assertEquals(B, messages.find_definition(
2085 'B', C, importer=self.Importer))
2086 self.assertEquals(C, messages.find_definition(
2087 'C', C, importer=self.Importer))
2088 self.assertEquals(D, messages.find_definition(
2089 'D', C, importer=self.Importer))
2090
2091 # Find relative to C searching from c.
2092 self.assertEquals(A, messages.find_definition(
2093 'b.A', C, importer=self.Importer))
2094 self.assertEquals(B, messages.find_definition(
2095 'b.A.B', C, importer=self.Importer))
2096 self.assertEquals(C, messages.find_definition(
2097 'b.A.B.C', C, importer=self.Importer))
2098 self.assertEquals(D, messages.find_definition(
2099 'b.A.B.D', C, importer=self.Importer))
2100
2101 def testAbsoluteReference(self):
2102 """Test finding absolute definition names."""
2103 # Define modules.
2104 a = self.DefineModule('a')
2105 b = self.DefineModule('a.a')
2106
2107 # Define messages.
2108 aA = self.DefineMessage('a', 'A')
2109 aaA = self.DefineMessage('a.a', 'A')
2110
2111 # Always find a.A.
2112 self.assertEquals(aA, messages.find_definition('.a.A', None,
2113 importer=self.Importer))
2114 self.assertEquals(aA, messages.find_definition('.a.A', a,
2115 importer=self.Importer))
2116 self.assertEquals(aA, messages.find_definition('.a.A', aA,
2117 importer=self.Importer))
2118 self.assertEquals(aA, messages.find_definition('.a.A', aaA,
2119 importer=self.Importer))
2120
2121 def testFindEnum(self):
2122 """Test that Enums are found."""
2123 class Color(messages.Enum):
2124 pass
2125 A = self.DefineMessage('a', 'A', {'Color': Color})
2126
2127 self.assertEquals(
2128 Color,
2129 messages.find_definition('Color', A, importer=self.Importer))
2130
2131 def testFalseScope(self):
2132 """Test Message definitions nested in strange objects are hidden."""
2133 global X
2134
2135 class X(object):
2136
2137 class A(messages.Message):
2138 pass
2139
2140 self.assertRaises(TypeError, messages.find_definition, 'A', X)
2141 self.assertRaises(messages.DefinitionNotFoundError,
2142 messages.find_definition,
2143 'X.A', sys.modules[__name__])
2144
2145 def testSearchAttributeFirst(self):
2146 """Make sure not faked out by module, but continues searching."""
2147 A = self.DefineMessage('a', 'A')
2148 module_A = self.DefineModule('a.A')
2149
2150 self.assertEquals(A, messages.find_definition(
2151 'a.A', None, importer=self.Importer))
2152
2153
2154 def main():
2155 unittest.main()
2156
2157
2158 if __name__ == '__main__':
2159 main()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698