blob: 52d5a6769729ab9c5a47f26121c4932ceb0fead3 [file] [log] [blame]
Jon Skeet9f37de92015-07-14 10:24:52 +01001#region Copyright notice and license
2// Protocol Buffers - Google's data interchange format
3// Copyright 2008 Google Inc. All rights reserved.
4// https://developers.google.com/protocol-buffers/
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met:
9//
10// * Redistributions of source code must retain the above copyright
11// notice, this list of conditions and the following disclaimer.
12// * Redistributions in binary form must reproduce the above
13// copyright notice, this list of conditions and the following disclaimer
14// in the documentation and/or other materials provided with the
15// distribution.
16// * Neither the name of Google Inc. nor the names of its
17// contributors may be used to endorse or promote products derived from
18// this software without specific prior written permission.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31#endregion
32
33using System.Linq;
34using Google.Protobuf.TestProtos;
35using NUnit.Framework;
Jon Skeet20bf6a52015-07-22 15:14:38 +010036using UnitTest.Issues.TestProtos;
Jon Skeet9f37de92015-07-14 10:24:52 +010037
38namespace Google.Protobuf.Reflection
39{
40 /// <summary>
41 /// Tests for descriptors. (Not in its own namespace or broken up into individual classes as the
42 /// size doesn't warrant it. On the other hand, this makes me feel a bit dirty...)
43 /// </summary>
44 public class DescriptorsTest
45 {
46 [Test]
47 public void FileDescriptor()
48 {
Jon Skeet284bb452015-11-05 09:13:53 +000049 FileDescriptor file = UnittestProto3Reflection.Descriptor;
Jon Skeet9f37de92015-07-14 10:24:52 +010050
51 Assert.AreEqual("google/protobuf/unittest_proto3.proto", file.Name);
52 Assert.AreEqual("protobuf_unittest", file.Package);
53
54 Assert.AreEqual("UnittestProto", file.Proto.Options.JavaOuterClassname);
55 Assert.AreEqual("google/protobuf/unittest_proto3.proto", file.Proto.Name);
56
57 // unittest.proto doesn't have any public imports, but unittest_import.proto does.
58 Assert.AreEqual(0, file.PublicDependencies.Count);
Jon Skeet284bb452015-11-05 09:13:53 +000059 Assert.AreEqual(1, UnittestImportProto3Reflection.Descriptor.PublicDependencies.Count);
60 Assert.AreEqual(UnittestImportPublicProto3Reflection.Descriptor, UnittestImportProto3Reflection.Descriptor.PublicDependencies[0]);
Jon Skeet9f37de92015-07-14 10:24:52 +010061
62 Assert.AreEqual(1, file.Dependencies.Count);
Jon Skeet284bb452015-11-05 09:13:53 +000063 Assert.AreEqual(UnittestImportProto3Reflection.Descriptor, file.Dependencies[0]);
Jon Skeet9f37de92015-07-14 10:24:52 +010064
65 MessageDescriptor messageType = TestAllTypes.Descriptor;
Jon Skeet72ec3362015-11-19 17:13:38 +000066 Assert.AreSame(typeof(TestAllTypes), messageType.ClrType);
Jon Skeeteadd4ca2015-11-13 20:04:14 +000067 Assert.AreSame(TestAllTypes.Parser, messageType.Parser);
Jon Skeet9f37de92015-07-14 10:24:52 +010068 Assert.AreEqual(messageType, file.MessageTypes[0]);
69 Assert.AreEqual(messageType, file.FindTypeByName<MessageDescriptor>("TestAllTypes"));
70 Assert.Null(file.FindTypeByName<MessageDescriptor>("NoSuchType"));
71 Assert.Null(file.FindTypeByName<MessageDescriptor>("protobuf_unittest.TestAllTypes"));
72 for (int i = 0; i < file.MessageTypes.Count; i++)
73 {
74 Assert.AreEqual(i, file.MessageTypes[i].Index);
75 }
76
77 Assert.AreEqual(file.EnumTypes[0], file.FindTypeByName<EnumDescriptor>("ForeignEnum"));
78 Assert.Null(file.FindTypeByName<EnumDescriptor>("NoSuchType"));
79 Assert.Null(file.FindTypeByName<EnumDescriptor>("protobuf_unittest.ForeignEnum"));
Jon Skeet284bb452015-11-05 09:13:53 +000080 Assert.AreEqual(1, UnittestImportProto3Reflection.Descriptor.EnumTypes.Count);
81 Assert.AreEqual("ImportEnum", UnittestImportProto3Reflection.Descriptor.EnumTypes[0].Name);
Jon Skeet9f37de92015-07-14 10:24:52 +010082 for (int i = 0; i < file.EnumTypes.Count; i++)
83 {
84 Assert.AreEqual(i, file.EnumTypes[i].Index);
85 }
Jan Tattermusch3b8c83e2015-07-24 20:27:35 -070086
87 Assert.AreEqual(10, file.SerializedData[0]);
Jon Skeet9f37de92015-07-14 10:24:52 +010088 }
89
90 [Test]
91 public void MessageDescriptor()
92 {
93 MessageDescriptor messageType = TestAllTypes.Descriptor;
94 MessageDescriptor nestedType = TestAllTypes.Types.NestedMessage.Descriptor;
95
96 Assert.AreEqual("TestAllTypes", messageType.Name);
97 Assert.AreEqual("protobuf_unittest.TestAllTypes", messageType.FullName);
Jon Skeet284bb452015-11-05 09:13:53 +000098 Assert.AreEqual(UnittestProto3Reflection.Descriptor, messageType.File);
Jon Skeet9f37de92015-07-14 10:24:52 +010099 Assert.IsNull(messageType.ContainingType);
100 Assert.IsNull(messageType.Proto.Options);
101
102 Assert.AreEqual("TestAllTypes", messageType.Name);
103
104 Assert.AreEqual("NestedMessage", nestedType.Name);
105 Assert.AreEqual("protobuf_unittest.TestAllTypes.NestedMessage", nestedType.FullName);
Jon Skeet284bb452015-11-05 09:13:53 +0000106 Assert.AreEqual(UnittestProto3Reflection.Descriptor, nestedType.File);
Jon Skeet9f37de92015-07-14 10:24:52 +0100107 Assert.AreEqual(messageType, nestedType.ContainingType);
108
Jon Skeetc1c6b2d2015-07-22 19:57:29 +0100109 FieldDescriptor field = messageType.Fields.InDeclarationOrder()[0];
Jon Skeet9f37de92015-07-14 10:24:52 +0100110 Assert.AreEqual("single_int32", field.Name);
111 Assert.AreEqual(field, messageType.FindDescriptor<FieldDescriptor>("single_int32"));
112 Assert.Null(messageType.FindDescriptor<FieldDescriptor>("no_such_field"));
113 Assert.AreEqual(field, messageType.FindFieldByNumber(1));
114 Assert.Null(messageType.FindFieldByNumber(571283));
Jon Skeetc1c6b2d2015-07-22 19:57:29 +0100115 var fieldsInDeclarationOrder = messageType.Fields.InDeclarationOrder();
116 for (int i = 0; i < fieldsInDeclarationOrder.Count; i++)
Jon Skeet9f37de92015-07-14 10:24:52 +0100117 {
Jon Skeetc1c6b2d2015-07-22 19:57:29 +0100118 Assert.AreEqual(i, fieldsInDeclarationOrder[i].Index);
Jon Skeet9f37de92015-07-14 10:24:52 +0100119 }
120
121 Assert.AreEqual(nestedType, messageType.NestedTypes[0]);
122 Assert.AreEqual(nestedType, messageType.FindDescriptor<MessageDescriptor>("NestedMessage"));
123 Assert.Null(messageType.FindDescriptor<MessageDescriptor>("NoSuchType"));
124 for (int i = 0; i < messageType.NestedTypes.Count; i++)
125 {
126 Assert.AreEqual(i, messageType.NestedTypes[i].Index);
127 }
128
129 Assert.AreEqual(messageType.EnumTypes[0], messageType.FindDescriptor<EnumDescriptor>("NestedEnum"));
130 Assert.Null(messageType.FindDescriptor<EnumDescriptor>("NoSuchType"));
131 for (int i = 0; i < messageType.EnumTypes.Count; i++)
132 {
133 Assert.AreEqual(i, messageType.EnumTypes[i].Index);
134 }
135 }
136
137 [Test]
138 public void FieldDescriptor()
139 {
140 MessageDescriptor messageType = TestAllTypes.Descriptor;
141 FieldDescriptor primitiveField = messageType.FindDescriptor<FieldDescriptor>("single_int32");
142 FieldDescriptor enumField = messageType.FindDescriptor<FieldDescriptor>("single_nested_enum");
143 FieldDescriptor messageField = messageType.FindDescriptor<FieldDescriptor>("single_foreign_message");
144
145 Assert.AreEqual("single_int32", primitiveField.Name);
146 Assert.AreEqual("protobuf_unittest.TestAllTypes.single_int32",
147 primitiveField.FullName);
148 Assert.AreEqual(1, primitiveField.FieldNumber);
149 Assert.AreEqual(messageType, primitiveField.ContainingType);
Jon Skeet284bb452015-11-05 09:13:53 +0000150 Assert.AreEqual(UnittestProto3Reflection.Descriptor, primitiveField.File);
Jon Skeet9f37de92015-07-14 10:24:52 +0100151 Assert.AreEqual(FieldType.Int32, primitiveField.FieldType);
152 Assert.IsNull(primitiveField.Proto.Options);
153
154 Assert.AreEqual("single_nested_enum", enumField.Name);
155 Assert.AreEqual(FieldType.Enum, enumField.FieldType);
156 // Assert.AreEqual(TestAllTypes.Types.NestedEnum.DescriptorProtoFile, enumField.EnumType);
157
158 Assert.AreEqual("single_foreign_message", messageField.Name);
159 Assert.AreEqual(FieldType.Message, messageField.FieldType);
160 Assert.AreEqual(ForeignMessage.Descriptor, messageField.MessageType);
161 }
162
163 [Test]
164 public void FieldDescriptorLabel()
165 {
166 FieldDescriptor singleField =
167 TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("single_int32");
168 FieldDescriptor repeatedField =
169 TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("repeated_int32");
170
171 Assert.IsFalse(singleField.IsRepeated);
172 Assert.IsTrue(repeatedField.IsRepeated);
173 }
174
175 [Test]
176 public void EnumDescriptor()
177 {
178 // Note: this test is a bit different to the Java version because there's no static way of getting to the descriptor
Jon Skeet284bb452015-11-05 09:13:53 +0000179 EnumDescriptor enumType = UnittestProto3Reflection.Descriptor.FindTypeByName<EnumDescriptor>("ForeignEnum");
Jon Skeet9f37de92015-07-14 10:24:52 +0100180 EnumDescriptor nestedType = TestAllTypes.Descriptor.FindDescriptor<EnumDescriptor>("NestedEnum");
181
182 Assert.AreEqual("ForeignEnum", enumType.Name);
183 Assert.AreEqual("protobuf_unittest.ForeignEnum", enumType.FullName);
Jon Skeet284bb452015-11-05 09:13:53 +0000184 Assert.AreEqual(UnittestProto3Reflection.Descriptor, enumType.File);
Jon Skeet9f37de92015-07-14 10:24:52 +0100185 Assert.Null(enumType.ContainingType);
186 Assert.Null(enumType.Proto.Options);
187
188 Assert.AreEqual("NestedEnum", nestedType.Name);
189 Assert.AreEqual("protobuf_unittest.TestAllTypes.NestedEnum",
190 nestedType.FullName);
Jon Skeet284bb452015-11-05 09:13:53 +0000191 Assert.AreEqual(UnittestProto3Reflection.Descriptor, nestedType.File);
Jon Skeet9f37de92015-07-14 10:24:52 +0100192 Assert.AreEqual(TestAllTypes.Descriptor, nestedType.ContainingType);
193
194 EnumValueDescriptor value = enumType.FindValueByName("FOREIGN_FOO");
195 Assert.AreEqual(value, enumType.Values[1]);
196 Assert.AreEqual("FOREIGN_FOO", value.Name);
197 Assert.AreEqual(4, value.Number);
Jon Skeet84ea2c72016-04-08 12:33:09 +0100198 Assert.AreEqual((int) ForeignEnum.ForeignFoo, value.Number);
Jon Skeet9f37de92015-07-14 10:24:52 +0100199 Assert.AreEqual(value, enumType.FindValueByNumber(4));
200 Assert.Null(enumType.FindValueByName("NO_SUCH_VALUE"));
201 for (int i = 0; i < enumType.Values.Count; i++)
202 {
203 Assert.AreEqual(i, enumType.Values[i].Index);
204 }
205 }
206
207 [Test]
208 public void OneofDescriptor()
209 {
210 OneofDescriptor descriptor = TestAllTypes.Descriptor.FindDescriptor<OneofDescriptor>("oneof_field");
211 Assert.AreEqual("oneof_field", descriptor.Name);
212 Assert.AreEqual("protobuf_unittest.TestAllTypes.oneof_field", descriptor.FullName);
213
214 var expectedFields = new[] {
215 TestAllTypes.OneofBytesFieldNumber,
216 TestAllTypes.OneofNestedMessageFieldNumber,
217 TestAllTypes.OneofStringFieldNumber,
218 TestAllTypes.OneofUint32FieldNumber }
219 .Select(fieldNumber => TestAllTypes.Descriptor.FindFieldByNumber(fieldNumber))
220 .ToList();
221 foreach (var field in expectedFields)
222 {
223 Assert.AreSame(descriptor, field.ContainingOneof);
224 }
225
226 CollectionAssert.AreEquivalent(expectedFields, descriptor.Fields);
227 }
Jon Skeet20bf6a52015-07-22 15:14:38 +0100228
229 [Test]
Jon Skeet72ec3362015-11-19 17:13:38 +0000230 public void MapEntryMessageDescriptor()
Jon Skeet20bf6a52015-07-22 15:14:38 +0100231 {
Jon Skeet72ec3362015-11-19 17:13:38 +0000232 var descriptor = MapWellKnownTypes.Descriptor.NestedTypes[0];
233 Assert.IsNull(descriptor.Parser);
234 Assert.IsNull(descriptor.ClrType);
235 Assert.IsNull(descriptor.Fields[1].Accessor);
Jon Skeet20bf6a52015-07-22 15:14:38 +0100236 }
Jon Skeetfd02e452015-07-31 10:32:04 +0100237
238 // From TestFieldOrdering:
239 // string my_string = 11;
240 // int64 my_int = 1;
241 // float my_float = 101;
242 // NestedMessage single_nested_message = 200;
243 [Test]
244 public void FieldListOrderings()
245 {
246 var fields = TestFieldOrderings.Descriptor.Fields;
247 Assert.AreEqual(new[] { 11, 1, 101, 200 }, fields.InDeclarationOrder().Select(x => x.FieldNumber));
248 Assert.AreEqual(new[] { 1, 11, 101, 200 }, fields.InFieldNumberOrder().Select(x => x.FieldNumber));
249 }
Jan Tattermusch143688f2015-08-14 13:23:44 -0700250
251
252 [Test]
253 public void DescriptorProtoFileDescriptor()
254 {
255 var descriptor = Google.Protobuf.Reflection.FileDescriptor.DescriptorProtoFileDescriptor;
Jon Skeet284bb452015-11-05 09:13:53 +0000256 Assert.AreEqual("google/protobuf/descriptor.proto", descriptor.Name);
Jan Tattermusch143688f2015-08-14 13:23:44 -0700257 }
Jon Skeet9f37de92015-07-14 10:24:52 +0100258 }
Jon Skeet5e0cfc92015-07-22 18:43:15 +0100259}