#! /usr/bin/env python
#
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc.  All rights reserved.
# https://developers.google.com/protocol-buffers/
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# TODO(robinson): Flesh this out considerably.  We focused on reflection_test.py
# first, since it's testing the subtler code, and since it provides decent
# indirect testing of the protocol compiler output.

"""Unittest that directly tests the output of the pure-Python protocol
compiler.  See //google/protobuf/internal/reflection_test.py for a test which
further ensures that we can use Python protocol message objects as we expect.
"""

__author__ = 'robinson@google.com (Will Robinson)'

try:
  import unittest2 as unittest  #PY26
except ImportError:
  import unittest

from google.protobuf.internal import test_bad_identifiers_pb2
from google.protobuf import unittest_custom_options_pb2
from google.protobuf import unittest_import_pb2
from google.protobuf import unittest_import_public_pb2
from google.protobuf import unittest_mset_pb2
from google.protobuf import unittest_mset_wire_format_pb2
from google.protobuf import unittest_no_generic_services_pb2
from google.protobuf import unittest_pb2
from google.protobuf import service
from google.protobuf import symbol_database

MAX_EXTENSION = 536870912


class GeneratorTest(unittest.TestCase):

  def testNestedMessageDescriptor(self):
    field_name = 'optional_nested_message'
    proto_type = unittest_pb2.TestAllTypes
    self.assertEqual(
        proto_type.NestedMessage.DESCRIPTOR,
        proto_type.DESCRIPTOR.fields_by_name[field_name].message_type)

  def testEnums(self):
    # We test only module-level enums here.
    # TODO(robinson): Examine descriptors directly to check
    # enum descriptor output.
    self.assertEqual(4, unittest_pb2.FOREIGN_FOO)
    self.assertEqual(5, unittest_pb2.FOREIGN_BAR)
    self.assertEqual(6, unittest_pb2.FOREIGN_BAZ)

    proto = unittest_pb2.TestAllTypes()
    self.assertEqual(1, proto.FOO)
    self.assertEqual(1, unittest_pb2.TestAllTypes.FOO)
    self.assertEqual(2, proto.BAR)
    self.assertEqual(2, unittest_pb2.TestAllTypes.BAR)
    self.assertEqual(3, proto.BAZ)
    self.assertEqual(3, unittest_pb2.TestAllTypes.BAZ)

  def testExtremeDefaultValues(self):
    message = unittest_pb2.TestExtremeDefaultValues()

    # Python pre-2.6 does not have isinf() or isnan() functions, so we have
    # to provide our own.
    def isnan(val):
      # NaN is never equal to itself.
      return val != val
    def isinf(val):
      # Infinity times zero equals NaN.
      return not isnan(val) and isnan(val * 0)

    self.assertTrue(isinf(message.inf_double))
    self.assertTrue(message.inf_double > 0)
    self.assertTrue(isinf(message.neg_inf_double))
    self.assertTrue(message.neg_inf_double < 0)
    self.assertTrue(isnan(message.nan_double))

    self.assertTrue(isinf(message.inf_float))
    self.assertTrue(message.inf_float > 0)
    self.assertTrue(isinf(message.neg_inf_float))
    self.assertTrue(message.neg_inf_float < 0)
    self.assertTrue(isnan(message.nan_float))
    self.assertEqual("? ? ?? ?? ??? ??/ ??-", message.cpp_trigraph)

  def testHasDefaultValues(self):
    desc = unittest_pb2.TestAllTypes.DESCRIPTOR

    expected_has_default_by_name = {
        'optional_int32': False,
        'repeated_int32': False,
        'optional_nested_message': False,
        'default_int32': True,
    }

    has_default_by_name = dict(
        [(f.name, f.has_default_value)
         for f in desc.fields
         if f.name in expected_has_default_by_name])
    self.assertEqual(expected_has_default_by_name, has_default_by_name)

  def testContainingTypeBehaviorForExtensions(self):
    self.assertEqual(unittest_pb2.optional_int32_extension.containing_type,
                     unittest_pb2.TestAllExtensions.DESCRIPTOR)
    self.assertEqual(unittest_pb2.TestRequired.single.containing_type,
                     unittest_pb2.TestAllExtensions.DESCRIPTOR)

  def testExtensionScope(self):
    self.assertEqual(unittest_pb2.optional_int32_extension.extension_scope,
                     None)
    self.assertEqual(unittest_pb2.TestRequired.single.extension_scope,
                     unittest_pb2.TestRequired.DESCRIPTOR)

  def testIsExtension(self):
    self.assertTrue(unittest_pb2.optional_int32_extension.is_extension)
    self.assertTrue(unittest_pb2.TestRequired.single.is_extension)

    message_descriptor = unittest_pb2.TestRequired.DESCRIPTOR
    non_extension_descriptor = message_descriptor.fields_by_name['a']
    self.assertTrue(not non_extension_descriptor.is_extension)

  def testOptions(self):
    proto = unittest_mset_wire_format_pb2.TestMessageSet()
    self.assertTrue(proto.DESCRIPTOR.GetOptions().message_set_wire_format)

  def testMessageWithCustomOptions(self):
    proto = unittest_custom_options_pb2.TestMessageWithCustomOptions()
    enum_options = proto.DESCRIPTOR.enum_types_by_name['AnEnum'].GetOptions()
    self.assertTrue(enum_options is not None)
    # TODO(gps): We really should test for the presence of the enum_opt1
    # extension and for its value to be set to -789.

  def testNestedTypes(self):
    self.assertEqual(
        set(unittest_pb2.TestAllTypes.DESCRIPTOR.nested_types),
        set([
            unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR,
            unittest_pb2.TestAllTypes.OptionalGroup.DESCRIPTOR,
            unittest_pb2.TestAllTypes.RepeatedGroup.DESCRIPTOR,
        ]))
    self.assertEqual(unittest_pb2.TestEmptyMessage.DESCRIPTOR.nested_types, [])
    self.assertEqual(
        unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR.nested_types, [])

  def testContainingType(self):
    self.assertTrue(
        unittest_pb2.TestEmptyMessage.DESCRIPTOR.containing_type is None)
    self.assertTrue(
        unittest_pb2.TestAllTypes.DESCRIPTOR.containing_type is None)
    self.assertEqual(
        unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR.containing_type,
        unittest_pb2.TestAllTypes.DESCRIPTOR)
    self.assertEqual(
        unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR.containing_type,
        unittest_pb2.TestAllTypes.DESCRIPTOR)
    self.assertEqual(
        unittest_pb2.TestAllTypes.RepeatedGroup.DESCRIPTOR.containing_type,
        unittest_pb2.TestAllTypes.DESCRIPTOR)

  def testContainingTypeInEnumDescriptor(self):
    self.assertTrue(unittest_pb2._FOREIGNENUM.containing_type is None)
    self.assertEqual(unittest_pb2._TESTALLTYPES_NESTEDENUM.containing_type,
                     unittest_pb2.TestAllTypes.DESCRIPTOR)

  def testPackage(self):
    self.assertEqual(
        unittest_pb2.TestAllTypes.DESCRIPTOR.file.package,
        'protobuf_unittest')
    desc = unittest_pb2.TestAllTypes.NestedMessage.DESCRIPTOR
    self.assertEqual(desc.file.package, 'protobuf_unittest')
    self.assertEqual(
        unittest_import_pb2.ImportMessage.DESCRIPTOR.file.package,
        'protobuf_unittest_import')

    self.assertEqual(
        unittest_pb2._FOREIGNENUM.file.package, 'protobuf_unittest')
    self.assertEqual(
        unittest_pb2._TESTALLTYPES_NESTEDENUM.file.package,
        'protobuf_unittest')
    self.assertEqual(
        unittest_import_pb2._IMPORTENUM.file.package,
        'protobuf_unittest_import')

  def testExtensionRange(self):
    self.assertEqual(
        unittest_pb2.TestAllTypes.DESCRIPTOR.extension_ranges, [])
    self.assertEqual(
        unittest_pb2.TestAllExtensions.DESCRIPTOR.extension_ranges,
        [(1, MAX_EXTENSION)])
    self.assertEqual(
        unittest_pb2.TestMultipleExtensionRanges.DESCRIPTOR.extension_ranges,
        [(42, 43), (4143, 4244), (65536, MAX_EXTENSION)])

  def testFileDescriptor(self):
    self.assertEqual(unittest_pb2.DESCRIPTOR.name,
                     'google/protobuf/unittest.proto')
    self.assertEqual(unittest_pb2.DESCRIPTOR.package, 'protobuf_unittest')
    self.assertFalse(unittest_pb2.DESCRIPTOR.serialized_pb is None)
    self.assertEqual(unittest_pb2.DESCRIPTOR.dependencies,
                     [unittest_import_pb2.DESCRIPTOR])
    self.assertEqual(unittest_import_pb2.DESCRIPTOR.dependencies,
                     [unittest_import_public_pb2.DESCRIPTOR])

  def testNoGenericServices(self):
    self.assertTrue(hasattr(unittest_no_generic_services_pb2, "TestMessage"))
    self.assertTrue(hasattr(unittest_no_generic_services_pb2, "FOO"))
    self.assertTrue(hasattr(unittest_no_generic_services_pb2, "test_extension"))

    # Make sure unittest_no_generic_services_pb2 has no services subclassing
    # Proto2 Service class.
    if hasattr(unittest_no_generic_services_pb2, "TestService"):
      self.assertFalse(issubclass(unittest_no_generic_services_pb2.TestService,
                                  service.Service))

  def testMessageTypesByName(self):
    file_type = unittest_pb2.DESCRIPTOR
    self.assertEqual(
        unittest_pb2._TESTALLTYPES,
        file_type.message_types_by_name[unittest_pb2._TESTALLTYPES.name])

    # Nested messages shouldn't be included in the message_types_by_name
    # dictionary (like in the C++ API).
    self.assertFalse(
        unittest_pb2._TESTALLTYPES_NESTEDMESSAGE.name in
        file_type.message_types_by_name)

  def testEnumTypesByName(self):
    file_type = unittest_pb2.DESCRIPTOR
    self.assertEqual(
        unittest_pb2._FOREIGNENUM,
        file_type.enum_types_by_name[unittest_pb2._FOREIGNENUM.name])

  def testExtensionsByName(self):
    file_type = unittest_pb2.DESCRIPTOR
    self.assertEqual(
        unittest_pb2.my_extension_string,
        file_type.extensions_by_name[unittest_pb2.my_extension_string.name])

  def testPublicImports(self):
    # Test public imports as embedded message.
    all_type_proto = unittest_pb2.TestAllTypes()
    self.assertEqual(0, all_type_proto.optional_public_import_message.e)

    # PublicImportMessage is actually defined in unittest_import_public_pb2
    # module, and is public imported by unittest_import_pb2 module.
    public_import_proto = unittest_import_pb2.PublicImportMessage()
    self.assertEqual(0, public_import_proto.e)
    self.assertTrue(unittest_import_public_pb2.PublicImportMessage is
                    unittest_import_pb2.PublicImportMessage)

  def testBadIdentifiers(self):
    # We're just testing that the code was imported without problems.
    message = test_bad_identifiers_pb2.TestBadIdentifiers()
    self.assertEqual(message.Extensions[test_bad_identifiers_pb2.message],
                     "foo")
    self.assertEqual(message.Extensions[test_bad_identifiers_pb2.descriptor],
                     "bar")
    self.assertEqual(message.Extensions[test_bad_identifiers_pb2.reflection],
                     "baz")
    self.assertEqual(message.Extensions[test_bad_identifiers_pb2.service],
                     "qux")

  def testOneof(self):
    desc = unittest_pb2.TestAllTypes.DESCRIPTOR
    self.assertEqual(1, len(desc.oneofs))
    self.assertEqual('oneof_field', desc.oneofs[0].name)
    self.assertEqual(0, desc.oneofs[0].index)
    self.assertIs(desc, desc.oneofs[0].containing_type)
    self.assertIs(desc.oneofs[0], desc.oneofs_by_name['oneof_field'])
    nested_names = set(['oneof_uint32', 'oneof_nested_message',
                        'oneof_string', 'oneof_bytes'])
    self.assertEqual(
        nested_names,
        set([field.name for field in desc.oneofs[0].fields]))
    for field_name, field_desc in desc.fields_by_name.items():
      if field_name in nested_names:
        self.assertIs(desc.oneofs[0], field_desc.containing_oneof)
      else:
        self.assertIsNone(field_desc.containing_oneof)


class SymbolDatabaseRegistrationTest(unittest.TestCase):
  """Checks that messages, enums and files are correctly registered."""

  def testGetSymbol(self):
    self.assertEqual(
        unittest_pb2.TestAllTypes, symbol_database.Default().GetSymbol(
            'protobuf_unittest.TestAllTypes'))
    self.assertEqual(
        unittest_pb2.TestAllTypes.NestedMessage,
        symbol_database.Default().GetSymbol(
            'protobuf_unittest.TestAllTypes.NestedMessage'))
    with self.assertRaises(KeyError):
      symbol_database.Default().GetSymbol('protobuf_unittest.NestedMessage')
    self.assertEqual(
        unittest_pb2.TestAllTypes.OptionalGroup,
        symbol_database.Default().GetSymbol(
            'protobuf_unittest.TestAllTypes.OptionalGroup'))
    self.assertEqual(
        unittest_pb2.TestAllTypes.RepeatedGroup,
        symbol_database.Default().GetSymbol(
            'protobuf_unittest.TestAllTypes.RepeatedGroup'))

  def testEnums(self):
    self.assertEqual(
        'protobuf_unittest.ForeignEnum',
        symbol_database.Default().pool.FindEnumTypeByName(
            'protobuf_unittest.ForeignEnum').full_name)
    self.assertEqual(
        'protobuf_unittest.TestAllTypes.NestedEnum',
        symbol_database.Default().pool.FindEnumTypeByName(
            'protobuf_unittest.TestAllTypes.NestedEnum').full_name)

  def testFindFileByName(self):
    self.assertEqual(
        'google/protobuf/unittest.proto',
        symbol_database.Default().pool.FindFileByName(
            'google/protobuf/unittest.proto').name)

if __name__ == '__main__':
  unittest.main()
