1 #region Copyright notice and license 2 // Protocol Buffers - Google's data interchange format 3 // Copyright 2008 Google Inc. All rights reserved. 4 // 5 // Use of this source code is governed by a BSD-style 6 // license that can be found in the LICENSE file or at 7 // https://developers.google.com/open-source/licenses/bsd 8 #endregion 9 10 using System.Linq; 11 using Google.Protobuf.TestProtos; 12 using NUnit.Framework; 13 using UnitTest.Issues.TestProtos; 14 15 namespace Google.Protobuf.Reflection 16 { 17 /// <summary> 18 /// Tests for descriptors. (Not in its own namespace or broken up into individual classes as the 19 /// size doesn't warrant it. On the other hand, this makes me feel a bit dirty...) 20 /// </summary> 21 public class DescriptorsTest 22 { 23 [Test] FileDescriptor()24 public void FileDescriptor() 25 { 26 FileDescriptor file = UnittestProto3Reflection.Descriptor; 27 28 Assert.AreEqual("google/protobuf/unittest_proto3.proto", file.Name); 29 Assert.AreEqual("protobuf_unittest", file.Package); 30 31 Assert.AreEqual("UnittestProto", file.Proto.Options.JavaOuterClassname); 32 Assert.AreEqual("google/protobuf/unittest_proto3.proto", file.Proto.Name); 33 34 // unittest.proto doesn't have any public imports, but unittest_import.proto does. 35 Assert.AreEqual(0, file.PublicDependencies.Count); 36 Assert.AreEqual(1, UnittestImportProto3Reflection.Descriptor.PublicDependencies.Count); 37 Assert.AreEqual(UnittestImportPublicProto3Reflection.Descriptor, UnittestImportProto3Reflection.Descriptor.PublicDependencies[0]); 38 39 Assert.AreEqual(1, file.Dependencies.Count); 40 Assert.AreEqual(UnittestImportProto3Reflection.Descriptor, file.Dependencies[0]); 41 42 MessageDescriptor messageType = TestAllTypes.Descriptor; 43 Assert.AreSame(typeof(TestAllTypes), messageType.ClrType); 44 Assert.AreSame(TestAllTypes.Parser, messageType.Parser); 45 Assert.AreEqual(messageType, file.MessageTypes[0]); 46 Assert.AreEqual(messageType, file.FindTypeByName<MessageDescriptor>("TestAllTypes")); 47 Assert.Null(file.FindTypeByName<MessageDescriptor>("NoSuchType")); 48 Assert.Null(file.FindTypeByName<MessageDescriptor>("protobuf_unittest.TestAllTypes")); 49 for (int i = 0; i < file.MessageTypes.Count; i++) 50 { 51 Assert.AreEqual(i, file.MessageTypes[i].Index); 52 } 53 54 Assert.AreEqual(file.EnumTypes[0], file.FindTypeByName<EnumDescriptor>("ForeignEnum")); 55 Assert.Null(file.FindTypeByName<EnumDescriptor>("NoSuchType")); 56 Assert.Null(file.FindTypeByName<EnumDescriptor>("protobuf_unittest.ForeignEnum")); 57 Assert.AreEqual(1, UnittestImportProto3Reflection.Descriptor.EnumTypes.Count); 58 Assert.AreEqual("ImportEnum", UnittestImportProto3Reflection.Descriptor.EnumTypes[0].Name); 59 for (int i = 0; i < file.EnumTypes.Count; i++) 60 { 61 Assert.AreEqual(i, file.EnumTypes[i].Index); 62 } 63 64 Assert.AreEqual(10, file.SerializedData[0]); 65 } 66 67 [Test] MessageDescriptor()68 public void MessageDescriptor() 69 { 70 MessageDescriptor messageType = TestAllTypes.Descriptor; 71 MessageDescriptor nestedType = TestAllTypes.Types.NestedMessage.Descriptor; 72 73 Assert.AreEqual("TestAllTypes", messageType.Name); 74 Assert.AreEqual("protobuf_unittest.TestAllTypes", messageType.FullName); 75 Assert.AreEqual(UnittestProto3Reflection.Descriptor, messageType.File); 76 Assert.IsNull(messageType.ContainingType); 77 Assert.IsNull(messageType.Proto.Options); 78 79 Assert.AreEqual("TestAllTypes", messageType.Name); 80 81 Assert.AreEqual("NestedMessage", nestedType.Name); 82 Assert.AreEqual("protobuf_unittest.TestAllTypes.NestedMessage", nestedType.FullName); 83 Assert.AreEqual(UnittestProto3Reflection.Descriptor, nestedType.File); 84 Assert.AreEqual(messageType, nestedType.ContainingType); 85 86 FieldDescriptor field = messageType.Fields.InDeclarationOrder()[0]; 87 Assert.AreEqual("single_int32", field.Name); 88 Assert.AreEqual(field, messageType.FindDescriptor<FieldDescriptor>("single_int32")); 89 Assert.Null(messageType.FindDescriptor<FieldDescriptor>("no_such_field")); 90 Assert.AreEqual(field, messageType.FindFieldByNumber(1)); 91 Assert.Null(messageType.FindFieldByNumber(571283)); 92 var fieldsInDeclarationOrder = messageType.Fields.InDeclarationOrder(); 93 for (int i = 0; i < fieldsInDeclarationOrder.Count; i++) 94 { 95 Assert.AreEqual(i, fieldsInDeclarationOrder[i].Index); 96 } 97 98 Assert.AreEqual(nestedType, messageType.NestedTypes[0]); 99 Assert.AreEqual(nestedType, messageType.FindDescriptor<MessageDescriptor>("NestedMessage")); 100 Assert.Null(messageType.FindDescriptor<MessageDescriptor>("NoSuchType")); 101 for (int i = 0; i < messageType.NestedTypes.Count; i++) 102 { 103 Assert.AreEqual(i, messageType.NestedTypes[i].Index); 104 } 105 106 Assert.AreEqual(messageType.EnumTypes[0], messageType.FindDescriptor<EnumDescriptor>("NestedEnum")); 107 Assert.Null(messageType.FindDescriptor<EnumDescriptor>("NoSuchType")); 108 for (int i = 0; i < messageType.EnumTypes.Count; i++) 109 { 110 Assert.AreEqual(i, messageType.EnumTypes[i].Index); 111 } 112 } 113 114 [Test] FieldDescriptor()115 public void FieldDescriptor() 116 { 117 MessageDescriptor messageType = TestAllTypes.Descriptor; 118 FieldDescriptor primitiveField = messageType.FindDescriptor<FieldDescriptor>("single_int32"); 119 FieldDescriptor enumField = messageType.FindDescriptor<FieldDescriptor>("single_nested_enum"); 120 FieldDescriptor messageField = messageType.FindDescriptor<FieldDescriptor>("single_foreign_message"); 121 122 Assert.AreEqual("single_int32", primitiveField.Name); 123 Assert.AreEqual("protobuf_unittest.TestAllTypes.single_int32", 124 primitiveField.FullName); 125 Assert.AreEqual(1, primitiveField.FieldNumber); 126 Assert.AreEqual(messageType, primitiveField.ContainingType); 127 Assert.AreEqual(UnittestProto3Reflection.Descriptor, primitiveField.File); 128 Assert.AreEqual(FieldType.Int32, primitiveField.FieldType); 129 Assert.IsNull(primitiveField.Proto.Options); 130 131 Assert.AreEqual("single_nested_enum", enumField.Name); 132 Assert.AreEqual(FieldType.Enum, enumField.FieldType); 133 // Assert.AreEqual(TestAllTypes.Types.NestedEnum.DescriptorProtoFile, enumField.EnumType); 134 135 Assert.AreEqual("single_foreign_message", messageField.Name); 136 Assert.AreEqual(FieldType.Message, messageField.FieldType); 137 Assert.AreEqual(ForeignMessage.Descriptor, messageField.MessageType); 138 } 139 140 [Test] FieldDescriptorLabel()141 public void FieldDescriptorLabel() 142 { 143 FieldDescriptor singleField = 144 TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("single_int32"); 145 FieldDescriptor repeatedField = 146 TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("repeated_int32"); 147 148 Assert.IsFalse(singleField.IsRepeated); 149 Assert.IsTrue(repeatedField.IsRepeated); 150 } 151 152 [Test] EnumDescriptor()153 public void EnumDescriptor() 154 { 155 // Note: this test is a bit different to the Java version because there's no static way of getting to the descriptor 156 EnumDescriptor enumType = UnittestProto3Reflection.Descriptor.FindTypeByName<EnumDescriptor>("ForeignEnum"); 157 EnumDescriptor nestedType = TestAllTypes.Descriptor.FindDescriptor<EnumDescriptor>("NestedEnum"); 158 159 Assert.AreEqual("ForeignEnum", enumType.Name); 160 Assert.AreEqual("protobuf_unittest.ForeignEnum", enumType.FullName); 161 Assert.AreEqual(UnittestProto3Reflection.Descriptor, enumType.File); 162 Assert.Null(enumType.ContainingType); 163 Assert.Null(enumType.Proto.Options); 164 165 Assert.AreEqual("NestedEnum", nestedType.Name); 166 Assert.AreEqual("protobuf_unittest.TestAllTypes.NestedEnum", 167 nestedType.FullName); 168 Assert.AreEqual(UnittestProto3Reflection.Descriptor, nestedType.File); 169 Assert.AreEqual(TestAllTypes.Descriptor, nestedType.ContainingType); 170 171 EnumValueDescriptor value = enumType.FindValueByName("FOREIGN_FOO"); 172 Assert.AreEqual(value, enumType.Values[1]); 173 Assert.AreEqual("FOREIGN_FOO", value.Name); 174 Assert.AreEqual(4, value.Number); 175 Assert.AreEqual((int) ForeignEnum.ForeignFoo, value.Number); 176 Assert.AreEqual(value, enumType.FindValueByNumber(4)); 177 Assert.Null(enumType.FindValueByName("NO_SUCH_VALUE")); 178 for (int i = 0; i < enumType.Values.Count; i++) 179 { 180 Assert.AreEqual(i, enumType.Values[i].Index); 181 } 182 } 183 184 [Test] OneofDescriptor()185 public void OneofDescriptor() 186 { 187 OneofDescriptor descriptor = TestAllTypes.Descriptor.FindDescriptor<OneofDescriptor>("oneof_field"); 188 Assert.AreEqual("oneof_field", descriptor.Name); 189 Assert.AreEqual("protobuf_unittest.TestAllTypes.oneof_field", descriptor.FullName); 190 191 var expectedFields = new[] { 192 TestAllTypes.OneofBytesFieldNumber, 193 TestAllTypes.OneofNestedMessageFieldNumber, 194 TestAllTypes.OneofStringFieldNumber, 195 TestAllTypes.OneofUint32FieldNumber } 196 .Select(fieldNumber => TestAllTypes.Descriptor.FindFieldByNumber(fieldNumber)) 197 .ToList(); 198 foreach (var field in expectedFields) 199 { 200 Assert.AreSame(descriptor, field.ContainingOneof); 201 } 202 203 CollectionAssert.AreEquivalent(expectedFields, descriptor.Fields); 204 } 205 206 [Test] MapEntryMessageDescriptor()207 public void MapEntryMessageDescriptor() 208 { 209 var descriptor = MapWellKnownTypes.Descriptor.NestedTypes[0]; 210 Assert.IsNull(descriptor.Parser); 211 Assert.IsNull(descriptor.ClrType); 212 Assert.IsNull(descriptor.Fields[1].Accessor); 213 } 214 215 // From TestFieldOrdering: 216 // string my_string = 11; 217 // int64 my_int = 1; 218 // float my_float = 101; 219 // NestedMessage single_nested_message = 200; 220 [Test] FieldListOrderings()221 public void FieldListOrderings() 222 { 223 var fields = TestFieldOrderings.Descriptor.Fields; 224 Assert.AreEqual(new[] { 11, 1, 101, 200 }, fields.InDeclarationOrder().Select(x => x.FieldNumber)); 225 Assert.AreEqual(new[] { 1, 11, 101, 200 }, fields.InFieldNumberOrder().Select(x => x.FieldNumber)); 226 } 227 228 229 [Test] DescriptorProtoFileDescriptor()230 public void DescriptorProtoFileDescriptor() 231 { 232 var descriptor = Google.Protobuf.Reflection.FileDescriptor.DescriptorProtoFileDescriptor; 233 Assert.AreEqual("google/protobuf/descriptor.proto", descriptor.Name); 234 } 235 } 236 } 237