blob: 30758c0eee274e2e8f0375c39be1a69ca6347b0b [file] [log] [blame]
Jon Skeet60c059b2008-10-23 21:17:56 +01001// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc. All rights reserved.
3// http://github.com/jskeet/dotnet-protobufs/
4// Original C++/Java/Python code:
Jon Skeet68036862008-10-22 13:30:34 +01005// http://code.google.com/p/protobuf/
6//
Jon Skeet60c059b2008-10-23 21:17:56 +01007// Redistribution and use in source and binary forms, with or without
8// modification, are permitted provided that the following conditions are
9// met:
Jon Skeet68036862008-10-22 13:30:34 +010010//
Jon Skeet60c059b2008-10-23 21:17:56 +010011// * Redistributions of source code must retain the above copyright
12// notice, this list of conditions and the following disclaimer.
13// * Redistributions in binary form must reproduce the above
14// copyright notice, this list of conditions and the following disclaimer
15// in the documentation and/or other materials provided with the
16// distribution.
17// * Neither the name of Google Inc. nor the names of its
18// contributors may be used to endorse or promote products derived from
19// this software without specific prior written permission.
Jon Skeet68036862008-10-22 13:30:34 +010020//
Jon Skeet60c059b2008-10-23 21:17:56 +010021// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Jon Skeet68036862008-10-22 13:30:34 +010032using System.Text;
Jon Skeet68036862008-10-22 13:30:34 +010033using Google.ProtocolBuffers.Descriptors;
34using Google.ProtocolBuffers.TestProtos;
Jon Skeetad748532009-06-25 16:55:58 +010035using NUnit.Framework;
Jon Skeet68036862008-10-22 13:30:34 +010036
37namespace Google.ProtocolBuffers {
38 /// <summary>
39 /// Tests for descriptors. (Not in its own namespace or broken up into individual classes as the
40 /// size doesn't warrant it. On the other hand, this makes me feel a bit dirty...)
41 /// </summary>
42 [TestFixture]
43 public class DescriptorsTest {
44
45 [Test]
46 public void FileDescriptor() {
47 FileDescriptor file = UnitTestProtoFile.Descriptor;
48
49 Assert.AreEqual("google/protobuf/unittest.proto", file.Name);
50 Assert.AreEqual("protobuf_unittest", file.Package);
51
52 Assert.AreEqual("UnittestProto", file.Options.JavaOuterClassname);
53 Assert.AreEqual("google/protobuf/unittest.proto", file.Proto.Name);
54
Jon Skeet343d9f52009-01-16 11:52:44 +000055// TODO(jonskeet): Either change to expect 2 dependencies, or don't emit them.
56// Assert.AreEqual(2, file.Dependencies.Count);
57 Assert.AreEqual(UnitTestImportProtoFile.Descriptor, file.Dependencies[1]);
Jon Skeet68036862008-10-22 13:30:34 +010058
59 MessageDescriptor messageType = TestAllTypes.Descriptor;
60 Assert.AreEqual(messageType, file.MessageTypes[0]);
61 Assert.AreEqual(messageType, file.FindTypeByName<MessageDescriptor>("TestAllTypes"));
62 Assert.IsNull(file.FindTypeByName<MessageDescriptor>("NoSuchType"));
63 Assert.IsNull(file.FindTypeByName<MessageDescriptor>("protobuf_unittest.TestAllTypes"));
64 for (int i = 0; i < file.MessageTypes.Count; i++) {
65 Assert.AreEqual(i, file.MessageTypes[i].Index);
66 }
67
68 Assert.AreEqual(file.EnumTypes[0], file.FindTypeByName<EnumDescriptor>("ForeignEnum"));
69 Assert.IsNull(file.FindTypeByName<EnumDescriptor>("NoSuchType"));
70 Assert.IsNull(file.FindTypeByName<EnumDescriptor>("protobuf_unittest.ForeignEnum"));
71 Assert.AreEqual(1, UnitTestImportProtoFile.Descriptor.EnumTypes.Count);
72 Assert.AreEqual("ImportEnum", UnitTestImportProtoFile.Descriptor.EnumTypes[0].Name);
73 for (int i = 0; i < file.EnumTypes.Count; i++) {
74 Assert.AreEqual(i, file.EnumTypes[i].Index);
75 }
76
77 ServiceDescriptor service = TestService.Descriptor;
78 Assert.AreEqual(service, file.Services[0]);
79 Assert.AreEqual(service, file.FindTypeByName<ServiceDescriptor>("TestService"));
80 Assert.IsNull(file.FindTypeByName<ServiceDescriptor>("NoSuchType"));
81 Assert.IsNull(file.FindTypeByName<ServiceDescriptor>("protobuf_unittest.TestService"));
82 Assert.AreEqual(0, UnitTestImportProtoFile.Descriptor.Services.Count);
83 for (int i = 0; i < file.Services.Count; i++) {
84 Assert.AreEqual(i, file.Services[i].Index);
85 }
86
87 FieldDescriptor extension = UnitTestProtoFile.OptionalInt32Extension.Descriptor;
88 Assert.AreEqual(extension, file.Extensions[0]);
89 Assert.AreEqual(extension, file.FindTypeByName<FieldDescriptor>("optional_int32_extension"));
90 Assert.IsNull(file.FindTypeByName<FieldDescriptor>("no_such_ext"));
91 Assert.IsNull(file.FindTypeByName<FieldDescriptor>("protobuf_unittest.optional_int32_extension"));
92 Assert.AreEqual(0, UnitTestImportProtoFile.Descriptor.Extensions.Count);
93 for (int i = 0; i < file.Extensions.Count; i++) {
94 Assert.AreEqual(i, file.Extensions[i].Index);
95 }
96 }
97
98 [Test]
99 public void MessageDescriptor() {
100 MessageDescriptor messageType = TestAllTypes.Descriptor;
101 MessageDescriptor nestedType = TestAllTypes.Types.NestedMessage.Descriptor;
102
103 Assert.AreEqual("TestAllTypes", messageType.Name);
104 Assert.AreEqual("protobuf_unittest.TestAllTypes", messageType.FullName);
105 Assert.AreEqual(UnitTestProtoFile.Descriptor, messageType.File);
106 Assert.IsNull(messageType.ContainingType);
107 Assert.AreEqual(DescriptorProtos.MessageOptions.DefaultInstance, messageType.Options);
108 Assert.AreEqual("TestAllTypes", messageType.Proto.Name);
109
110 Assert.AreEqual("NestedMessage", nestedType.Name);
111 Assert.AreEqual("protobuf_unittest.TestAllTypes.NestedMessage", nestedType.FullName);
112 Assert.AreEqual(UnitTestProtoFile.Descriptor, nestedType.File);
113 Assert.AreEqual(messageType, nestedType.ContainingType);
114
115 FieldDescriptor field = messageType.Fields[0];
116 Assert.AreEqual("optional_int32", field.Name);
117 Assert.AreEqual(field, messageType.FindDescriptor<FieldDescriptor>("optional_int32"));
118 Assert.IsNull(messageType.FindDescriptor<FieldDescriptor>("no_such_field"));
119 Assert.AreEqual(field, messageType.FindFieldByNumber(1));
120 Assert.IsNull(messageType.FindFieldByNumber(571283));
121 for (int i = 0; i < messageType.Fields.Count; i++) {
122 Assert.AreEqual(i, messageType.Fields[i].Index);
123 }
124
125 Assert.AreEqual(nestedType, messageType.NestedTypes[0]);
126 Assert.AreEqual(nestedType, messageType.FindDescriptor<MessageDescriptor>("NestedMessage"));
127 Assert.IsNull(messageType.FindDescriptor<MessageDescriptor>("NoSuchType"));
128 for (int i = 0; i < messageType.NestedTypes.Count; i++) {
129 Assert.AreEqual(i, messageType.NestedTypes[i].Index);
130 }
131
132 Assert.AreEqual(messageType.EnumTypes[0], messageType.FindDescriptor<EnumDescriptor>("NestedEnum"));
133 Assert.IsNull(messageType.FindDescriptor<EnumDescriptor>("NoSuchType"));
134 for (int i = 0; i < messageType.EnumTypes.Count; i++) {
135 Assert.AreEqual(i, messageType.EnumTypes[i].Index);
136 }
137 }
138
139 [Test]
140 public void FieldDescriptor() {
141 MessageDescriptor messageType = TestAllTypes.Descriptor;
142 FieldDescriptor primitiveField = messageType.FindDescriptor<FieldDescriptor>("optional_int32");
143 FieldDescriptor enumField = messageType.FindDescriptor<FieldDescriptor>("optional_nested_enum");
144 FieldDescriptor messageField = messageType.FindDescriptor<FieldDescriptor>("optional_foreign_message");
145 FieldDescriptor cordField = messageType.FindDescriptor<FieldDescriptor>("optional_cord");
146 FieldDescriptor extension = UnitTestProtoFile.OptionalInt32Extension.Descriptor;
147 FieldDescriptor nestedExtension = TestRequired.Single.Descriptor;
148
149 Assert.AreEqual("optional_int32", primitiveField.Name);
150 Assert.AreEqual("protobuf_unittest.TestAllTypes.optional_int32",
151 primitiveField.FullName);
152 Assert.AreEqual(1, primitiveField.FieldNumber);
153 Assert.AreEqual(messageType, primitiveField.ContainingType);
154 Assert.AreEqual(UnitTestProtoFile.Descriptor, primitiveField.File);
155 Assert.AreEqual(FieldType.Int32, primitiveField.FieldType);
156 Assert.AreEqual(MappedType.Int32, primitiveField.MappedType);
157 Assert.AreEqual(DescriptorProtos.FieldOptions.DefaultInstance, primitiveField.Options);
158 Assert.IsFalse(primitiveField.IsExtension);
159 Assert.AreEqual("optional_int32", primitiveField.Proto.Name);
160
161 Assert.AreEqual("optional_nested_enum", enumField.Name);
162 Assert.AreEqual(FieldType.Enum, enumField.FieldType);
163 Assert.AreEqual(MappedType.Enum, enumField.MappedType);
164 // Assert.AreEqual(TestAllTypes.Types.NestedEnum.Descriptor, enumField.EnumType);
165
166 Assert.AreEqual("optional_foreign_message", messageField.Name);
167 Assert.AreEqual(FieldType.Message, messageField.FieldType);
168 Assert.AreEqual(MappedType.Message, messageField.MappedType);
169 Assert.AreEqual(ForeignMessage.Descriptor, messageField.MessageType);
170
171 Assert.AreEqual("optional_cord", cordField.Name);
172 Assert.AreEqual(FieldType.String, cordField.FieldType);
173 Assert.AreEqual(MappedType.String, cordField.MappedType);
174 Assert.AreEqual(DescriptorProtos.FieldOptions.Types.CType.CORD, cordField.Options.Ctype);
175
176 Assert.AreEqual("optional_int32_extension", extension.Name);
177 Assert.AreEqual("protobuf_unittest.optional_int32_extension", extension.FullName);
178 Assert.AreEqual(1, extension.FieldNumber);
179 Assert.AreEqual(TestAllExtensions.Descriptor, extension.ContainingType);
180 Assert.AreEqual(UnitTestProtoFile.Descriptor, extension.File);
181 Assert.AreEqual(FieldType.Int32, extension.FieldType);
182 Assert.AreEqual(MappedType.Int32, extension.MappedType);
183 Assert.AreEqual(DescriptorProtos.FieldOptions.DefaultInstance,
184 extension.Options);
185 Assert.IsTrue(extension.IsExtension);
186 Assert.AreEqual(null, extension.ExtensionScope);
187 Assert.AreEqual("optional_int32_extension", extension.Proto.Name);
188
189 Assert.AreEqual("single", nestedExtension.Name);
190 Assert.AreEqual("protobuf_unittest.TestRequired.single",
191 nestedExtension.FullName);
192 Assert.AreEqual(TestRequired.Descriptor,
193 nestedExtension.ExtensionScope);
194 }
195
196 [Test]
197 public void FieldDescriptorLabel() {
198 FieldDescriptor requiredField =
199 TestRequired.Descriptor.FindDescriptor<FieldDescriptor>("a");
200 FieldDescriptor optionalField =
201 TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("optional_int32");
202 FieldDescriptor repeatedField =
203 TestAllTypes.Descriptor.FindDescriptor<FieldDescriptor>("repeated_int32");
204
205 Assert.IsTrue(requiredField.IsRequired);
206 Assert.IsFalse(requiredField.IsRepeated);
207 Assert.IsFalse(optionalField.IsRequired);
208 Assert.IsFalse(optionalField.IsRepeated);
209 Assert.IsFalse(repeatedField.IsRequired);
210 Assert.IsTrue(repeatedField.IsRepeated);
211 }
212
213 [Test]
214 public void FieldDescriptorDefault() {
215 MessageDescriptor d = TestAllTypes.Descriptor;
216 Assert.IsFalse(d.FindDescriptor<FieldDescriptor>("optional_int32").HasDefaultValue);
217 Assert.AreEqual(0, d.FindDescriptor<FieldDescriptor>("optional_int32").DefaultValue);
218 Assert.IsTrue(d.FindDescriptor<FieldDescriptor>("default_int32").HasDefaultValue);
219 Assert.AreEqual(41, d.FindDescriptor<FieldDescriptor>("default_int32").DefaultValue);
220
221 d = TestExtremeDefaultValues.Descriptor;
222 Assert.AreEqual(ByteString.CopyFrom("\u0000\u0001\u0007\b\f\n\r\t\u000b\\\'\"\u00fe", Encoding.GetEncoding(28591)),
223 d.FindDescriptor<FieldDescriptor>("escaped_bytes").DefaultValue);
224 Assert.AreEqual(uint.MaxValue, d.FindDescriptor<FieldDescriptor>("large_uint32").DefaultValue);
225 Assert.AreEqual(ulong.MaxValue, d.FindDescriptor<FieldDescriptor>("large_uint64").DefaultValue);
226 }
227
228 [Test]
229 public void EnumDescriptor() {
230 // Note: this test is a bit different to the Java version because there's no static way of getting to the descriptor
231 EnumDescriptor enumType = UnitTestProtoFile.Descriptor.FindTypeByName<EnumDescriptor>("ForeignEnum");
232 EnumDescriptor nestedType = TestAllTypes.Descriptor.FindDescriptor<EnumDescriptor>("NestedEnum");
233
234 Assert.AreEqual("ForeignEnum", enumType.Name);
235 Assert.AreEqual("protobuf_unittest.ForeignEnum", enumType.FullName);
236 Assert.AreEqual(UnitTestProtoFile.Descriptor, enumType.File);
237 Assert.IsNull(enumType.ContainingType);
238 Assert.AreEqual(DescriptorProtos.EnumOptions.DefaultInstance,
239 enumType.Options);
240
241 Assert.AreEqual("NestedEnum", nestedType.Name);
242 Assert.AreEqual("protobuf_unittest.TestAllTypes.NestedEnum",
243 nestedType.FullName);
244 Assert.AreEqual(UnitTestProtoFile.Descriptor, nestedType.File);
245 Assert.AreEqual(TestAllTypes.Descriptor, nestedType.ContainingType);
246
247 EnumValueDescriptor value = enumType.FindValueByName("FOREIGN_FOO");
248 Assert.AreEqual(value, enumType.Values[0]);
249 Assert.AreEqual("FOREIGN_FOO", value.Name);
250 Assert.AreEqual(4, value.Number);
251 Assert.AreEqual((int) ForeignEnum.FOREIGN_FOO, value.Number);
252 Assert.AreEqual(value, enumType.FindValueByNumber(4));
253 Assert.IsNull(enumType.FindValueByName("NO_SUCH_VALUE"));
254 for (int i = 0; i < enumType.Values.Count; i++) {
255 Assert.AreEqual(i, enumType.Values[i].Index);
256 }
257 }
258
259 [Test]
260 public void ServiceDescriptor() {
261 ServiceDescriptor service = TestService.Descriptor;
262
263 Assert.AreEqual("TestService", service.Name);
264 Assert.AreEqual("protobuf_unittest.TestService", service.FullName);
265 Assert.AreEqual(UnitTestProtoFile.Descriptor, service.File);
266
267 Assert.AreEqual(2, service.Methods.Count);
268
269 MethodDescriptor fooMethod = service.Methods[0];
270 Assert.AreEqual("Foo", fooMethod.Name);
271 Assert.AreEqual(FooRequest.Descriptor, fooMethod.InputType);
272 Assert.AreEqual(FooResponse.Descriptor, fooMethod.OutputType);
273 Assert.AreEqual(fooMethod, service.FindMethodByName("Foo"));
274
275 MethodDescriptor barMethod = service.Methods[1];
276 Assert.AreEqual("Bar", barMethod.Name);
277 Assert.AreEqual(BarRequest.Descriptor, barMethod.InputType);
278 Assert.AreEqual(BarResponse.Descriptor, barMethod.OutputType);
279 Assert.AreEqual(barMethod, service.FindMethodByName("Bar"));
280
281 Assert.IsNull(service.FindMethodByName("NoSuchMethod"));
282
283 for (int i = 0; i < service.Methods.Count; i++) {
284 Assert.AreEqual(i, service.Methods[i].Index);
285 }
286 }
Jon Skeetdf67f142009-06-05 19:29:36 +0100287
288 [Test]
289 public void CustomOptions() {
290 MessageDescriptor descriptor = TestMessageWithCustomOptions.Descriptor;
291 Assert.IsTrue(descriptor.Options.HasExtension(UnitTestCustomOptionsProtoFile.MessageOpt1));
292 Assert.AreEqual(-56, descriptor.Options.GetExtension(UnitTestCustomOptionsProtoFile.MessageOpt1));
293
294
295 FieldDescriptor field = descriptor.FindFieldByName("field1");
296 Assert.IsNotNull(field);
297
298 Assert.IsTrue(field.Options.HasExtension(UnitTestCustomOptionsProtoFile.FieldOpt1));
299 Assert.AreEqual(8765432109L, field.Options.GetExtension(UnitTestCustomOptionsProtoFile.FieldOpt1));
300
301 // TODO: Write out enum descriptors
302 /*
303 EnumDescriptor enumType = TestMessageWithCustomOptions.Types.
304 UnittestCustomOptions.TestMessageWithCustomOptions.AnEnum.getDescriptor();
305
306 Assert.IsTrue(
307 enumType.getOptions().hasExtension(UnittestCustomOptions.enumOpt1));
308 Assert.AreEqual(Integer.valueOf(-789),
309 enumType.getOptions().getExtension(UnittestCustomOptions.enumOpt1));
310 */
311
312 ServiceDescriptor service = TestServiceWithCustomOptions.Descriptor;
313
314 Assert.IsTrue(service.Options.HasExtension(UnitTestCustomOptionsProtoFile.ServiceOpt1));
315 Assert.AreEqual(-9876543210L, service.Options.GetExtension(UnitTestCustomOptionsProtoFile.ServiceOpt1));
316
317 MethodDescriptor method = service.FindMethodByName("Foo");
318 Assert.IsNotNull(method);
319
320 Assert.IsTrue(method.Options.HasExtension(UnitTestCustomOptionsProtoFile.MethodOpt1));
321 Assert.AreEqual(MethodOpt1.METHODOPT1_VAL2, method.Options.GetExtension(UnitTestCustomOptionsProtoFile.MethodOpt1));
322 }
Jon Skeet68036862008-10-22 13:30:34 +0100323 }
324}