Home | History | Annotate | Download | only in protorpclite
      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         field = messages.IntegerField(1)
    855         self.assertEquals(type(field.validate_element(12)), int)
    856         self.assertRaises(messages.ValidationError,
    857                           field.validate_element,
    858                           12.0)  # should fails from float to int
    859 
    860     def testReadOnly(self):
    861         """Test that objects are all read-only."""
    862         def action(field_class):
    863             field = field_class(10)
    864             self.assertRaises(AttributeError,
    865                               setattr,
    866                               field,
    867                               'number',
    868                               20)
    869             self.assertRaises(AttributeError,
    870                               setattr,
    871                               field,
    872                               'anything_else',
    873                               'whatever')
    874         self.ActionOnAllFieldClasses(action)
    875 
    876     def testMessageField(self):
    877         """Test the construction of message fields."""
    878         self.assertRaises(messages.FieldDefinitionError,
    879                           messages.MessageField,
    880                           str,
    881                           10)
    882 
    883         self.assertRaises(messages.FieldDefinitionError,
    884                           messages.MessageField,
    885                           messages.Message,
    886                           10)
    887 
    888         class MyMessage(messages.Message):
    889             pass
    890 
    891         field = messages.MessageField(MyMessage, 10)
    892         self.assertEquals(MyMessage, field.type)
    893 
    894     def testMessageField_ForwardReference(self):
    895         """Test the construction of forward reference message fields."""
    896         global MyMessage
    897         global ForwardMessage
    898         try:
    899             class MyMessage(messages.Message):
    900 
    901                 self_reference = messages.MessageField('MyMessage', 1)
    902                 forward = messages.MessageField('ForwardMessage', 2)
    903                 nested = messages.MessageField(
    904                     'ForwardMessage.NestedMessage', 3)
    905                 inner = messages.MessageField('Inner', 4)
    906 
    907                 class Inner(messages.Message):
    908 
    909                     sibling = messages.MessageField('Sibling', 1)
    910 
    911                 class Sibling(messages.Message):
    912 
    913                     pass
    914 
    915             class ForwardMessage(messages.Message):
    916 
    917                 class NestedMessage(messages.Message):
    918 
    919                     pass
    920 
    921             self.assertEquals(MyMessage,
    922                               MyMessage.field_by_name('self_reference').type)
    923 
    924             self.assertEquals(ForwardMessage,
    925                               MyMessage.field_by_name('forward').type)
    926 
    927             self.assertEquals(ForwardMessage.NestedMessage,
    928                               MyMessage.field_by_name('nested').type)
    929 
    930             self.assertEquals(MyMessage.Inner,
    931                               MyMessage.field_by_name('inner').type)
    932 
    933             self.assertEquals(MyMessage.Sibling,
    934                               MyMessage.Inner.field_by_name('sibling').type)
    935         finally:
    936             try:
    937                 del MyMessage
    938                 del ForwardMessage
    939             except:  # pylint:disable=bare-except
    940                 pass
    941 
    942     def testMessageField_WrongType(self):
    943         """Test that forward referencing the wrong type raises an error."""
    944         global AnEnum
    945         try:
    946             class AnEnum(messages.Enum):
    947                 pass
    948 
    949             class AnotherMessage(messages.Message):
    950 
    951                 a_field = messages.MessageField('AnEnum', 1)
    952 
    953             self.assertRaises(messages.FieldDefinitionError,
    954                               getattr,
    955                               AnotherMessage.field_by_name('a_field'),
    956                               'type')
    957         finally:
    958             del AnEnum
    959 
    960     def testMessageFieldValidate(self):
    961         """Test validation on message field."""
    962         class MyMessage(messages.Message):
    963             pass
    964 
    965         class AnotherMessage(messages.Message):
    966             pass
    967 
    968         field = messages.MessageField(MyMessage, 10)
    969         field.validate(MyMessage())
    970 
    971         self.assertRaises(messages.ValidationError,
    972                           field.validate,
    973                           AnotherMessage())
    974 
    975     def testMessageFieldMessageType(self):
    976         """Test message_type property."""
    977         class MyMessage(messages.Message):
    978             pass
    979 
    980         class HasMessage(messages.Message):
    981             field = messages.MessageField(MyMessage, 1)
    982 
    983         self.assertEqual(HasMessage.field.type, HasMessage.field.message_type)
    984 
    985     def testMessageFieldValueFromMessage(self):
    986         class MyMessage(messages.Message):
    987             pass
    988 
    989         class HasMessage(messages.Message):
    990             field = messages.MessageField(MyMessage, 1)
    991 
    992         instance = MyMessage()
    993 
    994         self.assertTrue(
    995             instance is HasMessage.field.value_from_message(instance))
    996 
    997     def testMessageFieldValueFromMessageWrongType(self):
    998         class MyMessage(messages.Message):
    999             pass
   1000 
   1001         class HasMessage(messages.Message):
   1002             field = messages.MessageField(MyMessage, 1)
   1003 
   1004         self.assertRaisesWithRegexpMatch(
   1005             messages.DecodeError,
   1006             'Expected type MyMessage, got int: 10',
   1007             HasMessage.field.value_from_message, 10)
   1008 
   1009     def testMessageFieldValueToMessage(self):
   1010         class MyMessage(messages.Message):
   1011             pass
   1012 
   1013         class HasMessage(messages.Message):
   1014             field = messages.MessageField(MyMessage, 1)
   1015 
   1016         instance = MyMessage()
   1017 
   1018         self.assertTrue(
   1019             instance is HasMessage.field.value_to_message(instance))
   1020 
   1021     def testMessageFieldValueToMessageWrongType(self):
   1022         class MyMessage(messages.Message):
   1023             pass
   1024 
   1025         class MyOtherMessage(messages.Message):
   1026             pass
   1027 
   1028         class HasMessage(messages.Message):
   1029             field = messages.MessageField(MyMessage, 1)
   1030 
   1031         instance = MyOtherMessage()
   1032 
   1033         self.assertRaisesWithRegexpMatch(
   1034             messages.EncodeError,
   1035             'Expected type MyMessage, got MyOtherMessage: <MyOtherMessage>',
   1036             HasMessage.field.value_to_message, instance)
   1037 
   1038     def testIntegerField_AllowLong(self):
   1039         """Test that the integer field allows for longs."""
   1040         if six.PY2:
   1041             messages.IntegerField(10, default=long(10))
   1042 
   1043     def testMessageFieldValidate_Initialized(self):
   1044         """Test validation on message field."""
   1045         class MyMessage(messages.Message):
   1046             field1 = messages.IntegerField(1, required=True)
   1047 
   1048         field = messages.MessageField(MyMessage, 10)
   1049 
   1050         # Will validate messages where is_initialized() is False.
   1051         message = MyMessage()
   1052         field.validate(message)
   1053         message.field1 = 20
   1054         field.validate(message)
   1055 
   1056     def testEnumField(self):
   1057         """Test the construction of enum fields."""
   1058         self.assertRaises(messages.FieldDefinitionError,
   1059                           messages.EnumField,
   1060                           str,
   1061                           10)
   1062 
   1063         self.assertRaises(messages.FieldDefinitionError,
   1064                           messages.EnumField,
   1065                           messages.Enum,
   1066                           10)
   1067 
   1068         class Color(messages.Enum):
   1069             RED = 1
   1070             GREEN = 2
   1071             BLUE = 3
   1072 
   1073         field = messages.EnumField(Color, 10)
   1074         self.assertEquals(Color, field.type)
   1075 
   1076         class Another(messages.Enum):
   1077             VALUE = 1
   1078 
   1079         self.assertRaises(messages.InvalidDefaultError,
   1080                           messages.EnumField,
   1081                           Color,
   1082                           10,
   1083                           default=Another.VALUE)
   1084 
   1085     def testEnumField_ForwardReference(self):
   1086         """Test the construction of forward reference enum fields."""
   1087         global MyMessage
   1088         global ForwardEnum
   1089         global ForwardMessage
   1090         try:
   1091             class MyMessage(messages.Message):
   1092 
   1093                 forward = messages.EnumField('ForwardEnum', 1)
   1094                 nested = messages.EnumField('ForwardMessage.NestedEnum', 2)
   1095                 inner = messages.EnumField('Inner', 3)
   1096 
   1097                 class Inner(messages.Enum):
   1098                     pass
   1099 
   1100             class ForwardEnum(messages.Enum):
   1101                 pass
   1102 
   1103             class ForwardMessage(messages.Message):
   1104 
   1105                 class NestedEnum(messages.Enum):
   1106                     pass
   1107 
   1108             self.assertEquals(ForwardEnum,
   1109                               MyMessage.field_by_name('forward').type)
   1110 
   1111             self.assertEquals(ForwardMessage.NestedEnum,
   1112                               MyMessage.field_by_name('nested').type)
   1113 
   1114             self.assertEquals(MyMessage.Inner,
   1115                               MyMessage.field_by_name('inner').type)
   1116         finally:
   1117             try:
   1118                 del MyMessage
   1119                 del ForwardEnum
   1120                 del ForwardMessage
   1121             except:  # pylint:disable=bare-except
   1122                 pass
   1123 
   1124     def testEnumField_WrongType(self):
   1125         """Test that forward referencing the wrong type raises an error."""
   1126         global AMessage
   1127         try:
   1128             class AMessage(messages.Message):
   1129                 pass
   1130 
   1131             class AnotherMessage(messages.Message):
   1132 
   1133                 a_field = messages.EnumField('AMessage', 1)
   1134 
   1135             self.assertRaises(messages.FieldDefinitionError,
   1136                               getattr,
   1137                               AnotherMessage.field_by_name('a_field'),
   1138                               'type')
   1139         finally:
   1140             del AMessage
   1141 
   1142     def testMessageDefinition(self):
   1143         """Test that message definition is set on fields."""
   1144         class MyMessage(messages.Message):
   1145 
   1146             my_field = messages.StringField(1)
   1147 
   1148         self.assertEquals(
   1149             MyMessage,
   1150             MyMessage.field_by_name('my_field').message_definition())
   1151 
   1152     def testNoneAssignment(self):
   1153         """Test that assigning None does not change comparison."""
   1154         class MyMessage(messages.Message):
   1155 
   1156             my_field = messages.StringField(1)
   1157 
   1158         m1 = MyMessage()
   1159         m2 = MyMessage()
   1160         m2.my_field = None
   1161         self.assertEquals(m1, m2)
   1162 
   1163     def testNonAsciiStr(self):
   1164         """Test validation fails for non-ascii StringField values."""
   1165         class Thing(messages.Message):
   1166             string_field = messages.StringField(2)
   1167 
   1168         thing = Thing()
   1169         self.assertRaisesWithRegexpMatch(
   1170             messages.ValidationError,
   1171             'Field string_field encountered non-ASCII string',
   1172             setattr, thing, 'string_field', test_util.BINARY)
   1173 
   1174 
   1175 class MessageTest(test_util.TestCase):
   1176     """Tests for message class."""
   1177 
   1178     def CreateMessageClass(self):
   1179         """Creates a simple message class with 3 fields.
   1180 
   1181         Fields are defined in alphabetical order but with conflicting numeric
   1182         order.
   1183         """
   1184         class ComplexMessage(messages.Message):
   1185             a3 = messages.IntegerField(3)
   1186             b1 = messages.StringField(1)
   1187             c2 = messages.StringField(2)
   1188 
   1189         return ComplexMessage
   1190 
   1191     def testSameNumbers(self):
   1192         """Test that cannot assign two fields with same numbers."""
   1193 
   1194         def action():
   1195             class BadMessage(messages.Message):
   1196                 f1 = messages.IntegerField(1)
   1197                 f2 = messages.IntegerField(1)
   1198         self.assertRaises(messages.DuplicateNumberError,
   1199                           action)
   1200 
   1201     def testStrictAssignment(self):
   1202         """Tests that cannot assign to unknown or non-reserved attributes."""
   1203         class SimpleMessage(messages.Message):
   1204             field = messages.IntegerField(1)
   1205 
   1206         simple_message = SimpleMessage()
   1207         self.assertRaises(AttributeError,
   1208                           setattr,
   1209                           simple_message,
   1210                           'does_not_exist',
   1211                           10)
   1212 
   1213     def testListAssignmentDoesNotCopy(self):
   1214         class SimpleMessage(messages.Message):
   1215             repeated = messages.IntegerField(1, repeated=True)
   1216 
   1217         message = SimpleMessage()
   1218         original = message.repeated
   1219         message.repeated = []
   1220         self.assertFalse(original is message.repeated)
   1221 
   1222     def testValidate_Optional(self):
   1223         """Tests validation of optional fields."""
   1224         class SimpleMessage(messages.Message):
   1225             non_required = messages.IntegerField(1)
   1226 
   1227         simple_message = SimpleMessage()
   1228         simple_message.check_initialized()
   1229         simple_message.non_required = 10
   1230         simple_message.check_initialized()
   1231 
   1232     def testValidate_Required(self):
   1233         """Tests validation of required fields."""
   1234         class SimpleMessage(messages.Message):
   1235             required = messages.IntegerField(1, required=True)
   1236 
   1237         simple_message = SimpleMessage()
   1238         self.assertRaises(messages.ValidationError,
   1239                           simple_message.check_initialized)
   1240         simple_message.required = 10
   1241         simple_message.check_initialized()
   1242 
   1243     def testValidate_Repeated(self):
   1244         """Tests validation of repeated fields."""
   1245         class SimpleMessage(messages.Message):
   1246             repeated = messages.IntegerField(1, repeated=True)
   1247 
   1248         simple_message = SimpleMessage()
   1249 
   1250         # Check valid values.
   1251         for valid_value in [], [10], [10, 20], (), (10,), (10, 20):
   1252             simple_message.repeated = valid_value
   1253             simple_message.check_initialized()
   1254 
   1255         # Check cleared.
   1256         simple_message.repeated = []
   1257         simple_message.check_initialized()
   1258 
   1259         # Check invalid values.
   1260         for invalid_value in 10, ['10', '20'], [None], (None,):
   1261             self.assertRaises(
   1262                 messages.ValidationError,
   1263                 setattr, simple_message, 'repeated', invalid_value)
   1264 
   1265     def testIsInitialized(self):
   1266         """Tests is_initialized."""
   1267         class SimpleMessage(messages.Message):
   1268             required = messages.IntegerField(1, required=True)
   1269 
   1270         simple_message = SimpleMessage()
   1271         self.assertFalse(simple_message.is_initialized())
   1272 
   1273         simple_message.required = 10
   1274 
   1275         self.assertTrue(simple_message.is_initialized())
   1276 
   1277     def testIsInitializedNestedField(self):
   1278         """Tests is_initialized for nested fields."""
   1279         class SimpleMessage(messages.Message):
   1280             required = messages.IntegerField(1, required=True)
   1281 
   1282         class NestedMessage(messages.Message):
   1283             simple = messages.MessageField(SimpleMessage, 1)
   1284 
   1285         simple_message = SimpleMessage()
   1286         self.assertFalse(simple_message.is_initialized())
   1287         nested_message = NestedMessage(simple=simple_message)
   1288         self.assertFalse(nested_message.is_initialized())
   1289 
   1290         simple_message.required = 10
   1291 
   1292         self.assertTrue(simple_message.is_initialized())
   1293         self.assertTrue(nested_message.is_initialized())
   1294 
   1295     def testInitializeNestedFieldFromDict(self):
   1296         """Tests initializing nested fields from dict."""
   1297         class SimpleMessage(messages.Message):
   1298             required = messages.IntegerField(1, required=True)
   1299 
   1300         class NestedMessage(messages.Message):
   1301             simple = messages.MessageField(SimpleMessage, 1)
   1302 
   1303         class RepeatedMessage(messages.Message):
   1304             simple = messages.MessageField(SimpleMessage, 1, repeated=True)
   1305 
   1306         nested_message1 = NestedMessage(simple={'required': 10})
   1307         self.assertTrue(nested_message1.is_initialized())
   1308         self.assertTrue(nested_message1.simple.is_initialized())
   1309 
   1310         nested_message2 = NestedMessage()
   1311         nested_message2.simple = {'required': 10}
   1312         self.assertTrue(nested_message2.is_initialized())
   1313         self.assertTrue(nested_message2.simple.is_initialized())
   1314 
   1315         repeated_values = [{}, {'required': 10}, SimpleMessage(required=20)]
   1316 
   1317         repeated_message1 = RepeatedMessage(simple=repeated_values)
   1318         self.assertEquals(3, len(repeated_message1.simple))
   1319         self.assertFalse(repeated_message1.is_initialized())
   1320 
   1321         repeated_message1.simple[0].required = 0
   1322         self.assertTrue(repeated_message1.is_initialized())
   1323 
   1324         repeated_message2 = RepeatedMessage()
   1325         repeated_message2.simple = repeated_values
   1326         self.assertEquals(3, len(repeated_message2.simple))
   1327         self.assertFalse(repeated_message2.is_initialized())
   1328 
   1329         repeated_message2.simple[0].required = 0
   1330         self.assertTrue(repeated_message2.is_initialized())
   1331 
   1332     def testNestedMethodsNotAllowed(self):
   1333         """Test that method definitions on Message classes are not allowed."""
   1334         def action():
   1335             class WithMethods(messages.Message):
   1336 
   1337                 def not_allowed(self):
   1338                     pass
   1339 
   1340         self.assertRaises(messages.MessageDefinitionError,
   1341                           action)
   1342 
   1343     def testNestedAttributesNotAllowed(self):
   1344         """Test attribute assignment on Message classes is not allowed."""
   1345         def int_attribute():
   1346             class WithMethods(messages.Message):
   1347                 not_allowed = 1
   1348 
   1349         def string_attribute():
   1350             class WithMethods(messages.Message):
   1351                 not_allowed = 'not allowed'
   1352 
   1353         def enum_attribute():
   1354             class WithMethods(messages.Message):
   1355                 not_allowed = Color.RED
   1356 
   1357         for action in (int_attribute, string_attribute, enum_attribute):
   1358             self.assertRaises(messages.MessageDefinitionError,
   1359                               action)
   1360 
   1361     def testNameIsSetOnFields(self):
   1362         """Make sure name is set on fields after Message class init."""
   1363         class HasNamedFields(messages.Message):
   1364             field = messages.StringField(1)
   1365 
   1366         self.assertEquals('field', HasNamedFields.field_by_number(1).name)
   1367 
   1368     def testSubclassingMessageDisallowed(self):
   1369         """Not permitted to create sub-classes of message classes."""
   1370         class SuperClass(messages.Message):
   1371             pass
   1372 
   1373         def action():
   1374             class SubClass(SuperClass):
   1375                 pass
   1376 
   1377         self.assertRaises(messages.MessageDefinitionError,
   1378                           action)
   1379 
   1380     def testAllFields(self):
   1381         """Test all_fields method."""
   1382         ComplexMessage = self.CreateMessageClass()
   1383         fields = list(ComplexMessage.all_fields())
   1384 
   1385         # Order does not matter, so sort now.
   1386         fields = sorted(fields, key=lambda f: f.name)
   1387 
   1388         self.assertEquals(3, len(fields))
   1389         self.assertEquals('a3', fields[0].name)
   1390         self.assertEquals('b1', fields[1].name)
   1391         self.assertEquals('c2', fields[2].name)
   1392 
   1393     def testFieldByName(self):
   1394         """Test getting field by name."""
   1395         ComplexMessage = self.CreateMessageClass()
   1396 
   1397         self.assertEquals(3, ComplexMessage.field_by_name('a3').number)
   1398         self.assertEquals(1, ComplexMessage.field_by_name('b1').number)
   1399         self.assertEquals(2, ComplexMessage.field_by_name('c2').number)
   1400 
   1401         self.assertRaises(KeyError,
   1402                           ComplexMessage.field_by_name,
   1403                           'unknown')
   1404 
   1405     def testFieldByNumber(self):
   1406         """Test getting field by number."""
   1407         ComplexMessage = self.CreateMessageClass()
   1408 
   1409         self.assertEquals('a3', ComplexMessage.field_by_number(3).name)
   1410         self.assertEquals('b1', ComplexMessage.field_by_number(1).name)
   1411         self.assertEquals('c2', ComplexMessage.field_by_number(2).name)
   1412 
   1413         self.assertRaises(KeyError,
   1414                           ComplexMessage.field_by_number,
   1415                           4)
   1416 
   1417     def testGetAssignedValue(self):
   1418         """Test getting the assigned value of a field."""
   1419         class SomeMessage(messages.Message):
   1420             a_value = messages.StringField(1, default=u'a default')
   1421 
   1422         message = SomeMessage()
   1423         self.assertEquals(None, message.get_assigned_value('a_value'))
   1424 
   1425         message.a_value = u'a string'
   1426         self.assertEquals(u'a string', message.get_assigned_value('a_value'))
   1427 
   1428         message.a_value = u'a default'
   1429         self.assertEquals(u'a default', message.get_assigned_value('a_value'))
   1430 
   1431         self.assertRaisesWithRegexpMatch(
   1432             AttributeError,
   1433             'Message SomeMessage has no field no_such_field',
   1434             message.get_assigned_value,
   1435             'no_such_field')
   1436 
   1437     def testReset(self):
   1438         """Test resetting a field value."""
   1439         class SomeMessage(messages.Message):
   1440             a_value = messages.StringField(1, default=u'a default')
   1441             repeated = messages.IntegerField(2, repeated=True)
   1442 
   1443         message = SomeMessage()
   1444 
   1445         self.assertRaises(AttributeError, message.reset, 'unknown')
   1446 
   1447         self.assertEquals(u'a default', message.a_value)
   1448         message.reset('a_value')
   1449         self.assertEquals(u'a default', message.a_value)
   1450 
   1451         message.a_value = u'a new value'
   1452         self.assertEquals(u'a new value', message.a_value)
   1453         message.reset('a_value')
   1454         self.assertEquals(u'a default', message.a_value)
   1455 
   1456         message.repeated = [1, 2, 3]
   1457         self.assertEquals([1, 2, 3], message.repeated)
   1458         saved = message.repeated
   1459         message.reset('repeated')
   1460         self.assertEquals([], message.repeated)
   1461         self.assertIsInstance(message.repeated, messages.FieldList)
   1462         self.assertEquals([1, 2, 3], saved)
   1463 
   1464     def testAllowNestedEnums(self):
   1465         """Test allowing nested enums in a message definition."""
   1466         class Trade(messages.Message):
   1467 
   1468             class Duration(messages.Enum):
   1469                 GTC = 1
   1470                 DAY = 2
   1471 
   1472             class Currency(messages.Enum):
   1473                 USD = 1
   1474                 GBP = 2
   1475                 INR = 3
   1476 
   1477         # Sorted by name order seems to be the only feasible option.
   1478         self.assertEquals(['Currency', 'Duration'], Trade.__enums__)
   1479 
   1480         # Message definition will now be set on Enumerated objects.
   1481         self.assertEquals(Trade, Trade.Duration.message_definition())
   1482 
   1483     def testAllowNestedMessages(self):
   1484         """Test allowing nested messages in a message definition."""
   1485         class Trade(messages.Message):
   1486 
   1487             class Lot(messages.Message):
   1488                 pass
   1489 
   1490             class Agent(messages.Message):
   1491                 pass
   1492 
   1493         # Sorted by name order seems to be the only feasible option.
   1494         self.assertEquals(['Agent', 'Lot'], Trade.__messages__)
   1495         self.assertEquals(Trade, Trade.Agent.message_definition())
   1496         self.assertEquals(Trade, Trade.Lot.message_definition())
   1497 
   1498         # But not Message itself.
   1499         def action():
   1500             class Trade(messages.Message):
   1501                 NiceTry = messages.Message
   1502         self.assertRaises(messages.MessageDefinitionError, action)
   1503 
   1504     def testDisallowClassAssignments(self):
   1505         """Test setting class attributes may not happen."""
   1506         class MyMessage(messages.Message):
   1507             pass
   1508 
   1509         self.assertRaises(AttributeError,
   1510                           setattr,
   1511                           MyMessage,
   1512                           'x',
   1513                           'do not assign')
   1514 
   1515     def testEquality(self):
   1516         """Test message class equality."""
   1517         # Comparison against enums must work.
   1518         class MyEnum(messages.Enum):
   1519             val1 = 1
   1520             val2 = 2
   1521 
   1522         # Comparisons against nested messages must work.
   1523         class AnotherMessage(messages.Message):
   1524             string = messages.StringField(1)
   1525 
   1526         class MyMessage(messages.Message):
   1527             field1 = messages.IntegerField(1)
   1528             field2 = messages.EnumField(MyEnum, 2)
   1529             field3 = messages.MessageField(AnotherMessage, 3)
   1530 
   1531         message1 = MyMessage()
   1532 
   1533         self.assertNotEquals('hi', message1)
   1534         self.assertNotEquals(AnotherMessage(), message1)
   1535         self.assertEquals(message1, message1)
   1536 
   1537         message2 = MyMessage()
   1538 
   1539         self.assertEquals(message1, message2)
   1540 
   1541         message1.field1 = 10
   1542         self.assertNotEquals(message1, message2)
   1543 
   1544         message2.field1 = 20
   1545         self.assertNotEquals(message1, message2)
   1546 
   1547         message2.field1 = 10
   1548         self.assertEquals(message1, message2)
   1549 
   1550         message1.field2 = MyEnum.val1
   1551         self.assertNotEquals(message1, message2)
   1552 
   1553         message2.field2 = MyEnum.val2
   1554         self.assertNotEquals(message1, message2)
   1555 
   1556         message2.field2 = MyEnum.val1
   1557         self.assertEquals(message1, message2)
   1558 
   1559         message1.field3 = AnotherMessage()
   1560         message1.field3.string = 'value1'
   1561         self.assertNotEquals(message1, message2)
   1562 
   1563         message2.field3 = AnotherMessage()
   1564         message2.field3.string = 'value2'
   1565         self.assertNotEquals(message1, message2)
   1566 
   1567         message2.field3.string = 'value1'
   1568         self.assertEquals(message1, message2)
   1569 
   1570     def testEqualityWithUnknowns(self):
   1571         """Test message class equality with unknown fields."""
   1572 
   1573         class MyMessage(messages.Message):
   1574             field1 = messages.IntegerField(1)
   1575 
   1576         message1 = MyMessage()
   1577         message2 = MyMessage()
   1578         self.assertEquals(message1, message2)
   1579         message1.set_unrecognized_field('unknown1', 'value1',
   1580                                         messages.Variant.STRING)
   1581         self.assertEquals(message1, message2)
   1582 
   1583         message1.set_unrecognized_field('unknown2', ['asdf', 3],
   1584                                         messages.Variant.STRING)
   1585         message1.set_unrecognized_field('unknown3', 4.7,
   1586                                         messages.Variant.DOUBLE)
   1587         self.assertEquals(message1, message2)
   1588 
   1589     def testUnrecognizedFieldInvalidVariant(self):
   1590         class MyMessage(messages.Message):
   1591             field1 = messages.IntegerField(1)
   1592 
   1593         message1 = MyMessage()
   1594         self.assertRaises(
   1595             TypeError, message1.set_unrecognized_field, 'unknown4',
   1596             {'unhandled': 'type'}, None)
   1597         self.assertRaises(
   1598             TypeError, message1.set_unrecognized_field, 'unknown4',
   1599             {'unhandled': 'type'}, 123)
   1600 
   1601     def testRepr(self):
   1602         """Test represtation of Message object."""
   1603         class MyMessage(messages.Message):
   1604             integer_value = messages.IntegerField(1)
   1605             string_value = messages.StringField(2)
   1606             unassigned = messages.StringField(3)
   1607             unassigned_with_default = messages.StringField(
   1608                 4, default=u'a default')
   1609 
   1610         my_message = MyMessage()
   1611         my_message.integer_value = 42
   1612         my_message.string_value = u'A string'
   1613 
   1614         pat = re.compile(r"<MyMessage\n integer_value: 42\n"
   1615                          " string_value: [u]?'A string'>")
   1616         self.assertTrue(pat.match(repr(my_message)) is not None)
   1617 
   1618     def testValidation(self):
   1619         """Test validation of message values."""
   1620         # Test optional.
   1621         class SubMessage(messages.Message):
   1622             pass
   1623 
   1624         class Message(messages.Message):
   1625             val = messages.MessageField(SubMessage, 1)
   1626 
   1627         message = Message()
   1628 
   1629         message_field = messages.MessageField(Message, 1)
   1630         message_field.validate(message)
   1631         message.val = SubMessage()
   1632         message_field.validate(message)
   1633         self.assertRaises(messages.ValidationError,
   1634                           setattr, message, 'val', [SubMessage()])
   1635 
   1636         # Test required.
   1637         class Message(messages.Message):
   1638             val = messages.MessageField(SubMessage, 1, required=True)
   1639 
   1640         message = Message()
   1641 
   1642         message_field = messages.MessageField(Message, 1)
   1643         message_field.validate(message)
   1644         message.val = SubMessage()
   1645         message_field.validate(message)
   1646         self.assertRaises(messages.ValidationError,
   1647                           setattr, message, 'val', [SubMessage()])
   1648 
   1649         # Test repeated.
   1650         class Message(messages.Message):
   1651             val = messages.MessageField(SubMessage, 1, repeated=True)
   1652 
   1653         message = Message()
   1654 
   1655         message_field = messages.MessageField(Message, 1)
   1656         message_field.validate(message)
   1657         self.assertRaisesWithRegexpMatch(
   1658             messages.ValidationError,
   1659             "Field val is repeated. Found: <SubMessage>",
   1660             setattr, message, 'val', SubMessage())
   1661         message.val = [SubMessage()]
   1662         message_field.validate(message)
   1663 
   1664     def testDefinitionName(self):
   1665         """Test message name."""
   1666         class MyMessage(messages.Message):
   1667             pass
   1668 
   1669         module_name = test_util.get_module_name(FieldTest)
   1670         self.assertEquals('%s.MyMessage' % module_name,
   1671                           MyMessage.definition_name())
   1672         self.assertEquals(module_name, MyMessage.outer_definition_name())
   1673         self.assertEquals(module_name, MyMessage.definition_package())
   1674 
   1675         self.assertEquals(six.text_type, type(MyMessage.definition_name()))
   1676         self.assertEquals(six.text_type, type(
   1677             MyMessage.outer_definition_name()))
   1678         self.assertEquals(six.text_type, type(MyMessage.definition_package()))
   1679 
   1680     def testDefinitionName_OverrideModule(self):
   1681         """Test message module is overriden by module package name."""
   1682         class MyMessage(messages.Message):
   1683             pass
   1684 
   1685         global package
   1686         package = 'my.package'
   1687 
   1688         try:
   1689             self.assertEquals('my.package.MyMessage',
   1690                               MyMessage.definition_name())
   1691             self.assertEquals('my.package', MyMessage.outer_definition_name())
   1692             self.assertEquals('my.package', MyMessage.definition_package())
   1693 
   1694             self.assertEquals(six.text_type, type(MyMessage.definition_name()))
   1695             self.assertEquals(six.text_type, type(
   1696                 MyMessage.outer_definition_name()))
   1697             self.assertEquals(six.text_type, type(
   1698                 MyMessage.definition_package()))
   1699         finally:
   1700             del package
   1701 
   1702     def testDefinitionName_NoModule(self):
   1703         """Test what happens when there is no module for message."""
   1704         class MyMessage(messages.Message):
   1705             pass
   1706 
   1707         original_modules = sys.modules
   1708         sys.modules = dict(sys.modules)
   1709         try:
   1710             del sys.modules[__name__]
   1711             self.assertEquals('MyMessage', MyMessage.definition_name())
   1712             self.assertEquals(None, MyMessage.outer_definition_name())
   1713             self.assertEquals(None, MyMessage.definition_package())
   1714 
   1715             self.assertEquals(six.text_type, type(MyMessage.definition_name()))
   1716         finally:
   1717             sys.modules = original_modules
   1718 
   1719     def testDefinitionName_Nested(self):
   1720         """Test nested message names."""
   1721         class MyMessage(messages.Message):
   1722 
   1723             class NestedMessage(messages.Message):
   1724 
   1725                 class NestedMessage(messages.Message):
   1726 
   1727                     pass
   1728 
   1729         module_name = test_util.get_module_name(MessageTest)
   1730         self.assertEquals('%s.MyMessage.NestedMessage' % module_name,
   1731                           MyMessage.NestedMessage.definition_name())
   1732         self.assertEquals('%s.MyMessage' % module_name,
   1733                           MyMessage.NestedMessage.outer_definition_name())
   1734         self.assertEquals(module_name,
   1735                           MyMessage.NestedMessage.definition_package())
   1736 
   1737         self.assertEquals(
   1738             '%s.MyMessage.NestedMessage.NestedMessage' % module_name,
   1739             MyMessage.NestedMessage.NestedMessage.definition_name())
   1740         self.assertEquals(
   1741             '%s.MyMessage.NestedMessage' % module_name,
   1742             MyMessage.NestedMessage.NestedMessage.outer_definition_name())
   1743         self.assertEquals(
   1744             module_name,
   1745             MyMessage.NestedMessage.NestedMessage.definition_package())
   1746 
   1747     def testMessageDefinition(self):
   1748         """Test that enumeration knows its enclosing message definition."""
   1749         class OuterMessage(messages.Message):
   1750 
   1751             class InnerMessage(messages.Message):
   1752                 pass
   1753 
   1754         self.assertEquals(None, OuterMessage.message_definition())
   1755         self.assertEquals(OuterMessage,
   1756                           OuterMessage.InnerMessage.message_definition())
   1757 
   1758     def testConstructorKwargs(self):
   1759         """Test kwargs via constructor."""
   1760         class SomeMessage(messages.Message):
   1761             name = messages.StringField(1)
   1762             number = messages.IntegerField(2)
   1763 
   1764         expected = SomeMessage()
   1765         expected.name = 'my name'
   1766         expected.number = 200
   1767         self.assertEquals(expected, SomeMessage(name='my name', number=200))
   1768 
   1769     def testConstructorNotAField(self):
   1770         """Test kwargs via constructor with wrong names."""
   1771         class SomeMessage(messages.Message):
   1772             pass
   1773 
   1774         self.assertRaisesWithRegexpMatch(
   1775             AttributeError,
   1776             ('May not assign arbitrary value does_not_exist to message '
   1777              'SomeMessage'),
   1778             SomeMessage,
   1779             does_not_exist=10)
   1780 
   1781     def testGetUnsetRepeatedValue(self):
   1782         class SomeMessage(messages.Message):
   1783             repeated = messages.IntegerField(1, repeated=True)
   1784 
   1785         instance = SomeMessage()
   1786         self.assertEquals([], instance.repeated)
   1787         self.assertTrue(isinstance(instance.repeated, messages.FieldList))
   1788 
   1789     def testCompareAutoInitializedRepeatedFields(self):
   1790         class SomeMessage(messages.Message):
   1791             repeated = messages.IntegerField(1, repeated=True)
   1792 
   1793         message1 = SomeMessage(repeated=[])
   1794         message2 = SomeMessage()
   1795         self.assertEquals(message1, message2)
   1796 
   1797     def testUnknownValues(self):
   1798         """Test message class equality with unknown fields."""
   1799         class MyMessage(messages.Message):
   1800             field1 = messages.IntegerField(1)
   1801 
   1802         message = MyMessage()
   1803         self.assertEquals([], message.all_unrecognized_fields())
   1804         self.assertEquals((None, None),
   1805                           message.get_unrecognized_field_info('doesntexist'))
   1806         self.assertEquals((None, None),
   1807                           message.get_unrecognized_field_info(
   1808                               'doesntexist', None, None))
   1809         self.assertEquals(('defaultvalue', 'defaultwire'),
   1810                           message.get_unrecognized_field_info(
   1811                               'doesntexist', 'defaultvalue', 'defaultwire'))
   1812         self.assertEquals((3, None),
   1813                           message.get_unrecognized_field_info(
   1814                               'doesntexist', value_default=3))
   1815 
   1816         message.set_unrecognized_field('exists', 9.5, messages.Variant.DOUBLE)
   1817         self.assertEquals(1, len(message.all_unrecognized_fields()))
   1818         self.assertTrue('exists' in message.all_unrecognized_fields())
   1819         self.assertEquals((9.5, messages.Variant.DOUBLE),
   1820                           message.get_unrecognized_field_info('exists'))
   1821         self.assertEquals((9.5, messages.Variant.DOUBLE),
   1822                           message.get_unrecognized_field_info('exists', 'type',
   1823                                                               1234))
   1824         self.assertEquals(
   1825             (1234, None),
   1826             message.get_unrecognized_field_info('doesntexist', 1234))
   1827 
   1828         message.set_unrecognized_field(
   1829             'another', 'value', messages.Variant.STRING)
   1830         self.assertEquals(2, len(message.all_unrecognized_fields()))
   1831         self.assertTrue('exists' in message.all_unrecognized_fields())
   1832         self.assertTrue('another' in message.all_unrecognized_fields())
   1833         self.assertEquals((9.5, messages.Variant.DOUBLE),
   1834                           message.get_unrecognized_field_info('exists'))
   1835         self.assertEquals(('value', messages.Variant.STRING),
   1836                           message.get_unrecognized_field_info('another'))
   1837 
   1838         message.set_unrecognized_field('typetest1', ['list', 0, ('test',)],
   1839                                        messages.Variant.STRING)
   1840         self.assertEquals((['list', 0, ('test',)], messages.Variant.STRING),
   1841                           message.get_unrecognized_field_info('typetest1'))
   1842         message.set_unrecognized_field(
   1843             'typetest2', '', messages.Variant.STRING)
   1844         self.assertEquals(('', messages.Variant.STRING),
   1845                           message.get_unrecognized_field_info('typetest2'))
   1846 
   1847     def testPickle(self):
   1848         """Testing pickling and unpickling of Message instances."""
   1849         global MyEnum
   1850         global AnotherMessage
   1851         global MyMessage
   1852 
   1853         class MyEnum(messages.Enum):
   1854             val1 = 1
   1855             val2 = 2
   1856 
   1857         class AnotherMessage(messages.Message):
   1858             string = messages.StringField(1, repeated=True)
   1859 
   1860         class MyMessage(messages.Message):
   1861             field1 = messages.IntegerField(1)
   1862             field2 = messages.EnumField(MyEnum, 2)
   1863             field3 = messages.MessageField(AnotherMessage, 3)
   1864 
   1865         message = MyMessage(field1=1, field2=MyEnum.val2,
   1866                             field3=AnotherMessage(string=['a', 'b', 'c']))
   1867         message.set_unrecognized_field(
   1868             'exists', 'value', messages.Variant.STRING)
   1869         message.set_unrecognized_field('repeated', ['list', 0, ('test',)],
   1870                                        messages.Variant.STRING)
   1871         unpickled = pickle.loads(pickle.dumps(message))
   1872         self.assertEquals(message, unpickled)
   1873         self.assertTrue(AnotherMessage.string is unpickled.field3.string.field)
   1874         self.assertTrue('exists' in message.all_unrecognized_fields())
   1875         self.assertEquals(('value', messages.Variant.STRING),
   1876                           message.get_unrecognized_field_info('exists'))
   1877         self.assertEquals((['list', 0, ('test',)], messages.Variant.STRING),
   1878                           message.get_unrecognized_field_info('repeated'))
   1879 
   1880 
   1881 class FindDefinitionTest(test_util.TestCase):
   1882     """Test finding definitions relative to various definitions and modules."""
   1883 
   1884     def setUp(self):
   1885         """Set up module-space.  Starts off empty."""
   1886         self.modules = {}
   1887 
   1888     def DefineModule(self, name):
   1889         """Define a module and its parents in module space.
   1890 
   1891         Modules that are already defined in self.modules are not re-created.
   1892 
   1893         Args:
   1894           name: Fully qualified name of modules to create.
   1895 
   1896         Returns:
   1897           Deepest nested module.  For example:
   1898 
   1899             DefineModule('a.b.c')  # Returns c.
   1900         """
   1901         name_path = name.split('.')
   1902         full_path = []
   1903         for node in name_path:
   1904             full_path.append(node)
   1905             full_name = '.'.join(full_path)
   1906             self.modules.setdefault(full_name, types.ModuleType(full_name))
   1907         return self.modules[name]
   1908 
   1909     def DefineMessage(self, module, name, children=None, add_to_module=True):
   1910         """Define a new Message class in the context of a module.
   1911 
   1912         Used for easily describing complex Message hierarchy. Message
   1913         is defined including all child definitions.
   1914 
   1915         Args:
   1916           module: Fully qualified name of module to place Message class in.
   1917           name: Name of Message to define within module.
   1918           children: Define any level of nesting of children
   1919             definitions. To define a message, map the name to another
   1920             dictionary. The dictionary can itself contain additional
   1921             definitions, and so on. To map to an Enum, define the Enum
   1922             class separately and map it by name.
   1923           add_to_module: If True, new Message class is added to
   1924             module. If False, new Message is not added.
   1925 
   1926         """
   1927         children = children or {}
   1928         # Make sure module exists.
   1929         module_instance = self.DefineModule(module)
   1930 
   1931         # Recursively define all child messages.
   1932         for attribute, value in children.items():
   1933             if isinstance(value, dict):
   1934                 children[attribute] = self.DefineMessage(
   1935                     module, attribute, value, False)
   1936 
   1937         # Override default __module__ variable.
   1938         children['__module__'] = module
   1939 
   1940         # Instantiate and possibly add to module.
   1941         message_class = type(name, (messages.Message,), dict(children))
   1942         if add_to_module:
   1943             setattr(module_instance, name, message_class)
   1944         return message_class
   1945 
   1946     # pylint:disable=unused-argument
   1947     # pylint:disable=redefined-builtin
   1948     def Importer(self, module, globals='', locals='', fromlist=None):
   1949         """Importer function.
   1950 
   1951         Acts like __import__. Only loads modules from self.modules.
   1952         Does not try to load real modules defined elsewhere. Does not
   1953         try to handle relative imports.
   1954 
   1955         Args:
   1956           module: Fully qualified name of module to load from self.modules.
   1957 
   1958         """
   1959         if fromlist is None:
   1960             module = module.split('.')[0]
   1961         try:
   1962             return self.modules[module]
   1963         except KeyError:
   1964             raise ImportError()
   1965     # pylint:disable=unused-argument
   1966 
   1967     def testNoSuchModule(self):
   1968         """Test searching for definitions that do no exist."""
   1969         self.assertRaises(messages.DefinitionNotFoundError,
   1970                           messages.find_definition,
   1971                           'does.not.exist',
   1972                           importer=self.Importer)
   1973 
   1974     def testRefersToModule(self):
   1975         """Test that referring to a module does not return that module."""
   1976         self.DefineModule('i.am.a.module')
   1977         self.assertRaises(messages.DefinitionNotFoundError,
   1978                           messages.find_definition,
   1979                           'i.am.a.module',
   1980                           importer=self.Importer)
   1981 
   1982     def testNoDefinition(self):
   1983         """Test not finding a definition in an existing module."""
   1984         self.DefineModule('i.am.a.module')
   1985         self.assertRaises(messages.DefinitionNotFoundError,
   1986                           messages.find_definition,
   1987                           'i.am.a.module.MyMessage',
   1988                           importer=self.Importer)
   1989 
   1990     def testNotADefinition(self):
   1991         """Test trying to fetch something that is not a definition."""
   1992         module = self.DefineModule('i.am.a.module')
   1993         setattr(module, 'A', 'a string')
   1994         self.assertRaises(messages.DefinitionNotFoundError,
   1995                           messages.find_definition,
   1996                           'i.am.a.module.A',
   1997                           importer=self.Importer)
   1998 
   1999     def testGlobalFind(self):
   2000         """Test finding definitions from fully qualified module names."""
   2001         A = self.DefineMessage('a.b.c', 'A', {})
   2002         self.assertEquals(A, messages.find_definition('a.b.c.A',
   2003                                                       importer=self.Importer))
   2004         B = self.DefineMessage('a.b.c', 'B', {'C': {}})
   2005         self.assertEquals(
   2006             B.C,
   2007             messages.find_definition('a.b.c.B.C', importer=self.Importer))
   2008 
   2009     def testRelativeToModule(self):
   2010         """Test finding definitions relative to modules."""
   2011         # Define modules.
   2012         a = self.DefineModule('a')
   2013         b = self.DefineModule('a.b')
   2014         c = self.DefineModule('a.b.c')
   2015 
   2016         # Define messages.
   2017         A = self.DefineMessage('a', 'A')
   2018         B = self.DefineMessage('a.b', 'B')
   2019         C = self.DefineMessage('a.b.c', 'C')
   2020         D = self.DefineMessage('a.b.d', 'D')
   2021 
   2022         # Find A, B, C and D relative to a.
   2023         self.assertEquals(A, messages.find_definition(
   2024             'A', a, importer=self.Importer))
   2025         self.assertEquals(B, messages.find_definition(
   2026             'b.B', a, importer=self.Importer))
   2027         self.assertEquals(C, messages.find_definition(
   2028             'b.c.C', a, importer=self.Importer))
   2029         self.assertEquals(D, messages.find_definition(
   2030             'b.d.D', a, importer=self.Importer))
   2031 
   2032         # Find A, B, C and D relative to b.
   2033         self.assertEquals(A, messages.find_definition(
   2034             'A', b, importer=self.Importer))
   2035         self.assertEquals(B, messages.find_definition(
   2036             'B', b, importer=self.Importer))
   2037         self.assertEquals(C, messages.find_definition(
   2038             'c.C', b, importer=self.Importer))
   2039         self.assertEquals(D, messages.find_definition(
   2040             'd.D', b, importer=self.Importer))
   2041 
   2042         # Find A, B, C and D relative to c.  Module d is the same case as c.
   2043         self.assertEquals(A, messages.find_definition(
   2044             'A', c, importer=self.Importer))
   2045         self.assertEquals(B, messages.find_definition(
   2046             'B', c, importer=self.Importer))
   2047         self.assertEquals(C, messages.find_definition(
   2048             'C', c, importer=self.Importer))
   2049         self.assertEquals(D, messages.find_definition(
   2050             'd.D', c, importer=self.Importer))
   2051 
   2052     def testRelativeToMessages(self):
   2053         """Test finding definitions relative to Message definitions."""
   2054         A = self.DefineMessage('a.b', 'A', {'B': {'C': {}, 'D': {}}})
   2055         B = A.B
   2056         C = A.B.C
   2057         D = A.B.D
   2058 
   2059         # Find relative to A.
   2060         self.assertEquals(A, messages.find_definition(
   2061             'A', A, importer=self.Importer))
   2062         self.assertEquals(B, messages.find_definition(
   2063             'B', A, importer=self.Importer))
   2064         self.assertEquals(C, messages.find_definition(
   2065             'B.C', A, importer=self.Importer))
   2066         self.assertEquals(D, messages.find_definition(
   2067             'B.D', A, importer=self.Importer))
   2068 
   2069         # Find relative to B.
   2070         self.assertEquals(A, messages.find_definition(
   2071             'A', B, importer=self.Importer))
   2072         self.assertEquals(B, messages.find_definition(
   2073             'B', B, importer=self.Importer))
   2074         self.assertEquals(C, messages.find_definition(
   2075             'C', B, importer=self.Importer))
   2076         self.assertEquals(D, messages.find_definition(
   2077             'D', B, importer=self.Importer))
   2078 
   2079         # Find relative to C.
   2080         self.assertEquals(A, messages.find_definition(
   2081             'A', C, importer=self.Importer))
   2082         self.assertEquals(B, messages.find_definition(
   2083             'B', C, importer=self.Importer))
   2084         self.assertEquals(C, messages.find_definition(
   2085             'C', C, importer=self.Importer))
   2086         self.assertEquals(D, messages.find_definition(
   2087             'D', C, importer=self.Importer))
   2088 
   2089         # Find relative to C searching from c.
   2090         self.assertEquals(A, messages.find_definition(
   2091             'b.A', C, importer=self.Importer))
   2092         self.assertEquals(B, messages.find_definition(
   2093             'b.A.B', C, importer=self.Importer))
   2094         self.assertEquals(C, messages.find_definition(
   2095             'b.A.B.C', C, importer=self.Importer))
   2096         self.assertEquals(D, messages.find_definition(
   2097             'b.A.B.D', C, importer=self.Importer))
   2098 
   2099     def testAbsoluteReference(self):
   2100         """Test finding absolute definition names."""
   2101         # Define modules.
   2102         a = self.DefineModule('a')
   2103         b = self.DefineModule('a.a')
   2104 
   2105         # Define messages.
   2106         aA = self.DefineMessage('a', 'A')
   2107         aaA = self.DefineMessage('a.a', 'A')
   2108 
   2109         # Always find a.A.
   2110         self.assertEquals(aA, messages.find_definition('.a.A', None,
   2111                                                        importer=self.Importer))
   2112         self.assertEquals(aA, messages.find_definition('.a.A', a,
   2113                                                        importer=self.Importer))
   2114         self.assertEquals(aA, messages.find_definition('.a.A', aA,
   2115                                                        importer=self.Importer))
   2116         self.assertEquals(aA, messages.find_definition('.a.A', aaA,
   2117                                                        importer=self.Importer))
   2118 
   2119     def testFindEnum(self):
   2120         """Test that Enums are found."""
   2121         class Color(messages.Enum):
   2122             pass
   2123         A = self.DefineMessage('a', 'A', {'Color': Color})
   2124 
   2125         self.assertEquals(
   2126             Color,
   2127             messages.find_definition('Color', A, importer=self.Importer))
   2128 
   2129     def testFalseScope(self):
   2130         """Test Message definitions nested in strange objects are hidden."""
   2131         global X
   2132 
   2133         class X(object):
   2134 
   2135             class A(messages.Message):
   2136                 pass
   2137 
   2138         self.assertRaises(TypeError, messages.find_definition, 'A', X)
   2139         self.assertRaises(messages.DefinitionNotFoundError,
   2140                           messages.find_definition,
   2141                           'X.A', sys.modules[__name__])
   2142 
   2143     def testSearchAttributeFirst(self):
   2144         """Make sure not faked out by module, but continues searching."""
   2145         A = self.DefineMessage('a', 'A')
   2146         module_A = self.DefineModule('a.A')
   2147 
   2148         self.assertEquals(A, messages.find_definition(
   2149             'a.A', None, importer=self.Importer))
   2150 
   2151 
   2152 def main():
   2153     unittest.main()
   2154 
   2155 
   2156 if __name__ == '__main__':
   2157     main()
   2158