• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc.  All rights reserved.
3// https://developers.google.com/protocol-buffers/
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9//     * Redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer.
11//     * Redistributions in binary form must reproduce the above
12// copyright notice, this list of conditions and the following disclaimer
13// in the documentation and/or other materials provided with the
14// distribution.
15//     * Neither the name of Google Inc. nor the names of its
16// contributors may be used to endorse or promote products derived from
17// this software without specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31#import "GPBTestUtilities.h"
32
33#import <objc/runtime.h>
34
35#import "GPBDescriptor_PackagePrivate.h"
36#import "google/protobuf/Unittest.pbobjc.h"
37#import "google/protobuf/UnittestObjc.pbobjc.h"
38#import "google/protobuf/Descriptor.pbobjc.h"
39
40@interface DescriptorTests : GPBTestCase
41@end
42
43@implementation DescriptorTests
44
45- (void)testDescriptor_containingType {
46  GPBDescriptor *testAllTypesDesc = [TestAllTypes descriptor];
47  GPBDescriptor *nestedMessageDesc = [TestAllTypes_NestedMessage descriptor];
48  XCTAssertNil(testAllTypesDesc.containingType);
49  XCTAssertNotNil(nestedMessageDesc.containingType);
50  XCTAssertEqual(nestedMessageDesc.containingType, testAllTypesDesc);  // Ptr comparison
51}
52
53- (void)testDescriptor_fullName {
54  GPBDescriptor *testAllTypesDesc = [TestAllTypes descriptor];
55  XCTAssertEqualObjects(testAllTypesDesc.fullName, @"protobuf_unittest.TestAllTypes");
56  GPBDescriptor *nestedMessageDesc = [TestAllTypes_NestedMessage descriptor];
57  XCTAssertEqualObjects(nestedMessageDesc.fullName, @"protobuf_unittest.TestAllTypes.NestedMessage");
58
59  // Prefixes removed.
60  GPBDescriptor *descDesc = [GPBDescriptorProto descriptor];
61  XCTAssertEqualObjects(descDesc.fullName, @"google.protobuf.DescriptorProto");
62  GPBDescriptor *descExtRngDesc = [GPBDescriptorProto_ExtensionRange descriptor];
63  XCTAssertEqualObjects(descExtRngDesc.fullName, @"google.protobuf.DescriptorProto.ExtensionRange");
64
65  // Things that get "_Class" added.
66  GPBDescriptor *pointDesc = [Point_Class descriptor];
67  XCTAssertEqualObjects(pointDesc.fullName, @"protobuf_unittest.Point");
68  GPBDescriptor *pointRectDesc = [Point_Rect descriptor];
69  XCTAssertEqualObjects(pointRectDesc.fullName, @"protobuf_unittest.Point.Rect");
70}
71
72- (void)testFieldDescriptor {
73  GPBDescriptor *descriptor = [TestAllTypes descriptor];
74
75  // Nested Enum
76  GPBFieldDescriptor *fieldDescriptorWithName =
77      [descriptor fieldWithName:@"optionalNestedEnum"];
78  XCTAssertNotNil(fieldDescriptorWithName);
79  GPBFieldDescriptor *fieldDescriptorWithNumber =
80      [descriptor fieldWithNumber:21];
81  XCTAssertNotNil(fieldDescriptorWithNumber);
82  XCTAssertEqual(fieldDescriptorWithName, fieldDescriptorWithNumber);
83  XCTAssertNotNil(fieldDescriptorWithNumber.enumDescriptor);
84  XCTAssertEqualObjects(fieldDescriptorWithNumber.enumDescriptor.name,
85                        @"TestAllTypes_NestedEnum");
86  XCTAssertEqual(fieldDescriptorWithName.number, fieldDescriptorWithNumber.number);
87  XCTAssertEqual(fieldDescriptorWithName.dataType, GPBDataTypeEnum);
88
89  // Foreign Enum
90  fieldDescriptorWithName = [descriptor fieldWithName:@"optionalForeignEnum"];
91  XCTAssertNotNil(fieldDescriptorWithName);
92  fieldDescriptorWithNumber = [descriptor fieldWithNumber:22];
93  XCTAssertNotNil(fieldDescriptorWithNumber);
94  XCTAssertEqual(fieldDescriptorWithName, fieldDescriptorWithNumber);
95  XCTAssertNotNil(fieldDescriptorWithNumber.enumDescriptor);
96  XCTAssertEqualObjects(fieldDescriptorWithNumber.enumDescriptor.name,
97                        @"ForeignEnum");
98  XCTAssertEqual(fieldDescriptorWithName.number, fieldDescriptorWithNumber.number);
99  XCTAssertEqual(fieldDescriptorWithName.dataType, GPBDataTypeEnum);
100
101  // Import Enum
102  fieldDescriptorWithName = [descriptor fieldWithName:@"optionalImportEnum"];
103  XCTAssertNotNil(fieldDescriptorWithName);
104  fieldDescriptorWithNumber = [descriptor fieldWithNumber:23];
105  XCTAssertNotNil(fieldDescriptorWithNumber);
106  XCTAssertEqual(fieldDescriptorWithName, fieldDescriptorWithNumber);
107  XCTAssertNotNil(fieldDescriptorWithNumber.enumDescriptor);
108  XCTAssertEqualObjects(fieldDescriptorWithNumber.enumDescriptor.name,
109                        @"ImportEnum");
110  XCTAssertEqual(fieldDescriptorWithName.number, fieldDescriptorWithNumber.number);
111  XCTAssertEqual(fieldDescriptorWithName.dataType, GPBDataTypeEnum);
112
113  // Nested Message
114  fieldDescriptorWithName = [descriptor fieldWithName:@"optionalNestedMessage"];
115  XCTAssertNotNil(fieldDescriptorWithName);
116  fieldDescriptorWithNumber = [descriptor fieldWithNumber:18];
117  XCTAssertNotNil(fieldDescriptorWithNumber);
118  XCTAssertEqual(fieldDescriptorWithName, fieldDescriptorWithNumber);
119  XCTAssertNil(fieldDescriptorWithNumber.enumDescriptor);
120  XCTAssertEqual(fieldDescriptorWithName.number, fieldDescriptorWithNumber.number);
121  XCTAssertEqual(fieldDescriptorWithName.dataType, GPBDataTypeMessage);
122
123  // Foreign Message
124  fieldDescriptorWithName =
125      [descriptor fieldWithName:@"optionalForeignMessage"];
126  XCTAssertNotNil(fieldDescriptorWithName);
127  fieldDescriptorWithNumber = [descriptor fieldWithNumber:19];
128  XCTAssertNotNil(fieldDescriptorWithNumber);
129  XCTAssertEqual(fieldDescriptorWithName, fieldDescriptorWithNumber);
130  XCTAssertNil(fieldDescriptorWithNumber.enumDescriptor);
131  XCTAssertEqual(fieldDescriptorWithName.number, fieldDescriptorWithNumber.number);
132  XCTAssertEqual(fieldDescriptorWithName.dataType, GPBDataTypeMessage);
133
134  // Import Message
135  fieldDescriptorWithName = [descriptor fieldWithName:@"optionalImportMessage"];
136  XCTAssertNotNil(fieldDescriptorWithName);
137  fieldDescriptorWithNumber = [descriptor fieldWithNumber:20];
138  XCTAssertNotNil(fieldDescriptorWithNumber);
139  XCTAssertEqual(fieldDescriptorWithName, fieldDescriptorWithNumber);
140  XCTAssertNil(fieldDescriptorWithNumber.enumDescriptor);
141  XCTAssertEqual(fieldDescriptorWithName.number, fieldDescriptorWithNumber.number);
142  XCTAssertEqual(fieldDescriptorWithName.dataType, GPBDataTypeMessage);
143
144  // Some failed lookups.
145  XCTAssertNil([descriptor fieldWithName:@"NOT THERE"]);
146  XCTAssertNil([descriptor fieldWithNumber:9876543]);
147}
148
149- (void)testEnumDescriptor {
150  GPBEnumDescriptor *descriptor = TestAllTypes_NestedEnum_EnumDescriptor();
151
152  NSString *enumName = [descriptor enumNameForValue:1];
153  XCTAssertNotNil(enumName);
154  int32_t value;
155  XCTAssertTrue(
156      [descriptor getValue:&value forEnumName:@"TestAllTypes_NestedEnum_Foo"]);
157  XCTAssertTrue(
158      [descriptor getValue:NULL forEnumName:@"TestAllTypes_NestedEnum_Foo"]);
159  XCTAssertEqual(value, TestAllTypes_NestedEnum_Foo);
160
161  enumName = [descriptor enumNameForValue:2];
162  XCTAssertNotNil(enumName);
163  XCTAssertTrue(
164      [descriptor getValue:&value forEnumName:@"TestAllTypes_NestedEnum_Bar"]);
165  XCTAssertEqual(value, TestAllTypes_NestedEnum_Bar);
166
167  enumName = [descriptor enumNameForValue:3];
168  XCTAssertNotNil(enumName);
169  XCTAssertTrue(
170      [descriptor getValue:&value forEnumName:@"TestAllTypes_NestedEnum_Baz"]);
171  XCTAssertEqual(value, TestAllTypes_NestedEnum_Baz);
172
173  // TextFormat
174  enumName = [descriptor textFormatNameForValue:1];
175  XCTAssertNotNil(enumName);
176  XCTAssertTrue([descriptor getValue:&value forEnumTextFormatName:@"FOO"]);
177  XCTAssertEqual(value, TestAllTypes_NestedEnum_Foo);
178  XCTAssertNil([descriptor textFormatNameForValue:99999]);
179
180  // Bad values
181  enumName = [descriptor enumNameForValue:0];
182  XCTAssertNil(enumName);
183  XCTAssertFalse([descriptor getValue:&value forEnumName:@"Unknown"]);
184  XCTAssertFalse([descriptor getValue:NULL forEnumName:@"Unknown"]);
185  XCTAssertFalse([descriptor getValue:&value
186                          forEnumName:@"TestAllTypes_NestedEnum_Unknown"]);
187  XCTAssertFalse([descriptor getValue:NULL
188                          forEnumName:@"TestAllTypes_NestedEnum_Unknown"]);
189  XCTAssertFalse([descriptor getValue:NULL forEnumTextFormatName:@"Unknown"]);
190  XCTAssertFalse([descriptor getValue:&value forEnumTextFormatName:@"Unknown"]);
191}
192
193- (void)testEnumDescriptorIntrospection {
194  GPBEnumDescriptor *descriptor = TestAllTypes_NestedEnum_EnumDescriptor();
195
196  XCTAssertEqual(descriptor.enumNameCount, 4U);
197  XCTAssertEqualObjects([descriptor getEnumNameForIndex:0],
198                        @"TestAllTypes_NestedEnum_Foo");
199  XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:0], @"FOO");
200  XCTAssertEqualObjects([descriptor getEnumNameForIndex:1],
201                 @"TestAllTypes_NestedEnum_Bar");
202  XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:1], @"BAR");
203  XCTAssertEqualObjects([descriptor getEnumNameForIndex:2],
204                 @"TestAllTypes_NestedEnum_Baz");
205  XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:2], @"BAZ");
206  XCTAssertEqualObjects([descriptor getEnumNameForIndex:3],
207                 @"TestAllTypes_NestedEnum_Neg");
208  XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:3], @"NEG");
209}
210
211- (void)testEnumDescriptorIntrospectionWithAlias {
212  GPBEnumDescriptor *descriptor = TestEnumWithDupValue_EnumDescriptor();
213  NSString *enumName;
214  int32_t value;
215
216  XCTAssertEqual(descriptor.enumNameCount, 5U);
217
218  enumName = [descriptor getEnumNameForIndex:0];
219  XCTAssertEqualObjects(enumName, @"TestEnumWithDupValue_Foo1");
220  XCTAssertTrue([descriptor getValue:&value forEnumName:enumName]);
221  XCTAssertEqual(value, 1);
222  XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:0], @"FOO1");
223
224  enumName = [descriptor getEnumNameForIndex:1];
225  XCTAssertEqualObjects(enumName, @"TestEnumWithDupValue_Bar1");
226  XCTAssertTrue([descriptor getValue:&value forEnumName:enumName]);
227  XCTAssertEqual(value, 2);
228  XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:1], @"BAR1");
229
230  enumName = [descriptor getEnumNameForIndex:2];
231  XCTAssertEqualObjects(enumName, @"TestEnumWithDupValue_Baz");
232  XCTAssertTrue([descriptor getValue:&value forEnumName:enumName]);
233  XCTAssertEqual(value, 3);
234  XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:2], @"BAZ");
235
236  enumName = [descriptor getEnumNameForIndex:3];
237  XCTAssertEqualObjects(enumName, @"TestEnumWithDupValue_Foo2");
238  XCTAssertTrue([descriptor getValue:&value forEnumName:enumName]);
239  XCTAssertEqual(value, 1);
240  XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:3], @"FOO2");
241
242  enumName = [descriptor getEnumNameForIndex:4];
243  XCTAssertEqualObjects(enumName, @"TestEnumWithDupValue_Bar2");
244  XCTAssertTrue([descriptor getValue:&value forEnumName:enumName]);
245  XCTAssertEqual(value, 2);
246  XCTAssertEqualObjects([descriptor getEnumTextFormatNameForIndex:4], @"BAR2");
247}
248
249- (void)testEnumAliasNameCollisions {
250  GPBEnumDescriptor *descriptor = TestEnumObjCNameCollision_EnumDescriptor();
251  NSString *textFormatName;
252  int32_t value;
253
254  XCTAssertEqual(descriptor.enumNameCount, 5U);
255
256  XCTAssertEqualObjects([descriptor getEnumNameForIndex:0], @"TestEnumObjCNameCollision_Foo");
257  textFormatName = [descriptor getEnumTextFormatNameForIndex:0];
258  XCTAssertEqualObjects(textFormatName, @"FOO");
259  XCTAssertTrue([descriptor getValue:&value forEnumTextFormatName:textFormatName]);
260  XCTAssertEqual(value, 1);
261
262  XCTAssertEqualObjects([descriptor getEnumNameForIndex:1], @"TestEnumObjCNameCollision_Foo");
263  textFormatName = [descriptor getEnumTextFormatNameForIndex:1];
264  XCTAssertEqualObjects(textFormatName, @"foo");
265  XCTAssertTrue([descriptor getValue:&value forEnumTextFormatName:textFormatName]);
266  XCTAssertEqual(value, 1);
267
268  XCTAssertEqualObjects([descriptor getEnumNameForIndex:2], @"TestEnumObjCNameCollision_Bar");
269  textFormatName = [descriptor getEnumTextFormatNameForIndex:2];
270  XCTAssertEqualObjects(textFormatName, @"BAR");
271  XCTAssertTrue([descriptor getValue:&value forEnumTextFormatName:textFormatName]);
272  XCTAssertEqual(value, 2);
273
274  XCTAssertEqualObjects([descriptor getEnumNameForIndex:3], @"TestEnumObjCNameCollision_Mumble");
275  textFormatName = [descriptor getEnumTextFormatNameForIndex:3];
276  XCTAssertEqualObjects(textFormatName, @"mumble");
277  XCTAssertTrue([descriptor getValue:&value forEnumTextFormatName:textFormatName]);
278  XCTAssertEqual(value, 2);
279
280  XCTAssertEqualObjects([descriptor getEnumNameForIndex:4], @"TestEnumObjCNameCollision_Mumble");
281  textFormatName = [descriptor getEnumTextFormatNameForIndex:4];
282  XCTAssertEqualObjects(textFormatName, @"MUMBLE");
283  XCTAssertTrue([descriptor getValue:&value forEnumTextFormatName:textFormatName]);
284  XCTAssertEqual(value, 2);
285}
286
287- (void)testEnumValueValidator {
288  GPBDescriptor *descriptor = [TestAllTypes descriptor];
289  GPBFieldDescriptor *fieldDescriptor =
290      [descriptor fieldWithName:@"optionalNestedEnum"];
291
292  // Valid values
293  XCTAssertTrue([fieldDescriptor isValidEnumValue:1]);
294  XCTAssertTrue([fieldDescriptor isValidEnumValue:2]);
295  XCTAssertTrue([fieldDescriptor isValidEnumValue:3]);
296  XCTAssertTrue([fieldDescriptor isValidEnumValue:-1]);
297
298  // Invalid values
299  XCTAssertFalse([fieldDescriptor isValidEnumValue:4]);
300  XCTAssertFalse([fieldDescriptor isValidEnumValue:0]);
301  XCTAssertFalse([fieldDescriptor isValidEnumValue:-2]);
302}
303
304- (void)testOneofDescriptor {
305  GPBDescriptor *descriptor = [TestOneof2 descriptor];
306
307  GPBFieldDescriptor *fooStringField =
308      [descriptor fieldWithNumber:TestOneof2_FieldNumber_FooString];
309  XCTAssertNotNil(fooStringField);
310  GPBFieldDescriptor *barStringField =
311      [descriptor fieldWithNumber:TestOneof2_FieldNumber_BarString];
312  XCTAssertNotNil(barStringField);
313
314  // Check the oneofs to have what is expected but not other onesofs
315
316  GPBOneofDescriptor *oneofFoo = [descriptor oneofWithName:@"foo"];
317  XCTAssertNotNil(oneofFoo);
318  XCTAssertNotNil([oneofFoo fieldWithName:@"fooString"]);
319  XCTAssertNil([oneofFoo fieldWithName:@"barString"]);
320
321  GPBOneofDescriptor *oneofBar = [descriptor oneofWithName:@"bar"];
322  XCTAssertNotNil(oneofBar);
323  XCTAssertNil([oneofBar fieldWithName:@"fooString"]);
324  XCTAssertNotNil([oneofBar fieldWithName:@"barString"]);
325
326  // Pointer comparisons against lookups from message.
327
328  XCTAssertEqual([oneofFoo fieldWithNumber:TestOneof2_FieldNumber_FooString],
329                 fooStringField);
330  XCTAssertEqual([oneofFoo fieldWithName:@"fooString"], fooStringField);
331
332  XCTAssertEqual([oneofBar fieldWithNumber:TestOneof2_FieldNumber_BarString],
333                 barStringField);
334  XCTAssertEqual([oneofBar fieldWithName:@"barString"], barStringField);
335
336  // Unknown oneof not found.
337
338  XCTAssertNil([descriptor oneofWithName:@"mumble"]);
339  XCTAssertNil([descriptor oneofWithName:@"Foo"]);
340
341  // Unknown oneof item.
342
343  XCTAssertNil([oneofFoo fieldWithName:@"mumble"]);
344  XCTAssertNil([oneofFoo fieldWithNumber:666]);
345
346  // Field exists, but not in this oneof.
347
348  XCTAssertNil([oneofFoo fieldWithName:@"barString"]);
349  XCTAssertNil([oneofFoo fieldWithNumber:TestOneof2_FieldNumber_BarString]);
350  XCTAssertNil([oneofBar fieldWithName:@"fooString"]);
351  XCTAssertNil([oneofBar fieldWithNumber:TestOneof2_FieldNumber_FooString]);
352
353  // Check pointers back to the enclosing oneofs.
354  // (pointer comparisons)
355  XCTAssertEqual(fooStringField.containingOneof, oneofFoo);
356  XCTAssertEqual(barStringField.containingOneof, oneofBar);
357  GPBFieldDescriptor *bazString =
358      [descriptor fieldWithNumber:TestOneof2_FieldNumber_BazString];
359  XCTAssertNotNil(bazString);
360  XCTAssertNil(bazString.containingOneof);
361}
362
363- (void)testExtensiondDescriptor {
364  Class msgClass = [TestAllExtensions class];
365  Class packedMsgClass = [TestPackedExtensions class];
366
367  // Int
368
369  GPBExtensionDescriptor *descriptor = [UnittestRoot optionalInt32Extension];
370  XCTAssertNotNil(descriptor);
371  XCTAssertEqual(descriptor.containingMessageClass, msgClass);  // ptr equality
372  XCTAssertFalse(descriptor.isPackable);
373  XCTAssertEqualObjects(descriptor.defaultValue, @0);
374  XCTAssertNil(descriptor.enumDescriptor);
375
376  descriptor = [UnittestRoot defaultInt32Extension];
377  XCTAssertNotNil(descriptor);
378  XCTAssertEqual(descriptor.containingMessageClass, msgClass);  // ptr equality
379  XCTAssertFalse(descriptor.isPackable);
380  XCTAssertEqualObjects(descriptor.defaultValue, @41);
381  XCTAssertNil(descriptor.enumDescriptor);
382
383  // Enum
384
385  descriptor = [UnittestRoot optionalNestedEnumExtension];
386  XCTAssertNotNil(descriptor);
387  XCTAssertEqual(descriptor.containingMessageClass, msgClass);  // ptr equality
388  XCTAssertFalse(descriptor.isPackable);
389  XCTAssertEqual(descriptor.defaultValue, @1);
390  XCTAssertEqualObjects(descriptor.enumDescriptor.name, @"TestAllTypes_NestedEnum");
391
392  descriptor = [UnittestRoot defaultNestedEnumExtension];
393  XCTAssertNotNil(descriptor);
394  XCTAssertEqual(descriptor.containingMessageClass, msgClass);  // ptr equality
395  XCTAssertFalse(descriptor.isPackable);
396  XCTAssertEqual(descriptor.defaultValue, @2);
397  XCTAssertEqualObjects(descriptor.enumDescriptor.name, @"TestAllTypes_NestedEnum");
398
399  // Message
400
401  descriptor = [UnittestRoot optionalNestedMessageExtension];
402  XCTAssertNotNil(descriptor);
403  XCTAssertEqual(descriptor.containingMessageClass, msgClass);  // ptr equality
404  XCTAssertFalse(descriptor.isPackable);
405  XCTAssertNil(descriptor.defaultValue);
406  XCTAssertNil(descriptor.enumDescriptor);
407
408  // Repeated Int
409
410  descriptor = [UnittestRoot repeatedInt32Extension];
411  XCTAssertNotNil(descriptor);
412  XCTAssertEqual(descriptor.containingMessageClass, msgClass);  // ptr equality
413  XCTAssertFalse(descriptor.isPackable);
414  XCTAssertNil(descriptor.defaultValue);
415  XCTAssertNil(descriptor.enumDescriptor);
416
417  descriptor = [UnittestRoot packedInt32Extension];
418  XCTAssertNotNil(descriptor);
419  XCTAssertEqual(descriptor.containingMessageClass, packedMsgClass);  // ptr equality
420  XCTAssertTrue(descriptor.isPackable);
421  XCTAssertNil(descriptor.defaultValue);
422  XCTAssertNil(descriptor.enumDescriptor);
423
424  // Repeated Enum
425
426  descriptor = [UnittestRoot repeatedNestedEnumExtension];
427  XCTAssertNotNil(descriptor);
428  XCTAssertEqual(descriptor.containingMessageClass, msgClass);  // ptr equality
429  XCTAssertFalse(descriptor.isPackable);
430  XCTAssertNil(descriptor.defaultValue);
431  XCTAssertEqualObjects(descriptor.enumDescriptor.name, @"TestAllTypes_NestedEnum");
432
433  descriptor = [UnittestRoot packedEnumExtension];
434  XCTAssertNotNil(descriptor);
435  XCTAssertEqual(descriptor.containingMessageClass, packedMsgClass);  // ptr equality
436  XCTAssertTrue(descriptor.isPackable);
437  XCTAssertNil(descriptor.defaultValue);
438  XCTAssertEqualObjects(descriptor.enumDescriptor.name, @"ForeignEnum");
439
440  // Repeated Message
441
442  descriptor = [UnittestRoot repeatedNestedMessageExtension];
443  XCTAssertNotNil(descriptor);
444  XCTAssertEqual(descriptor.containingMessageClass, msgClass);  // ptr equality
445  XCTAssertFalse(descriptor.isPackable);
446  XCTAssertNil(descriptor.defaultValue);
447  XCTAssertNil(descriptor.enumDescriptor);
448
449  // Compare (used internally for serialization).
450
451  GPBExtensionDescriptor *ext1 = [UnittestRoot optionalInt32Extension];
452  XCTAssertEqual(ext1.fieldNumber, 1u);
453  GPBExtensionDescriptor *ext2 = [UnittestRoot optionalInt64Extension];
454  XCTAssertEqual(ext2.fieldNumber, 2u);
455
456  XCTAssertEqual([ext1 compareByFieldNumber:ext2], NSOrderedAscending);
457  XCTAssertEqual([ext2 compareByFieldNumber:ext1], NSOrderedDescending);
458  XCTAssertEqual([ext1 compareByFieldNumber:ext1], NSOrderedSame);
459}
460
461@end
462