xref: /aosp_15_r20/external/protobuf/objectivec/Tests/GPBUnknownFieldSetTest.m (revision 1b3f573f81763fcece89efc2b6a5209149e44ab8)
1*1b3f573fSAndroid Build Coastguard Worker// Protocol Buffers - Google's data interchange format
2*1b3f573fSAndroid Build Coastguard Worker// Copyright 2008 Google Inc.  All rights reserved.
3*1b3f573fSAndroid Build Coastguard Worker// https://developers.google.com/protocol-buffers/
4*1b3f573fSAndroid Build Coastguard Worker//
5*1b3f573fSAndroid Build Coastguard Worker// Redistribution and use in source and binary forms, with or without
6*1b3f573fSAndroid Build Coastguard Worker// modification, are permitted provided that the following conditions are
7*1b3f573fSAndroid Build Coastguard Worker// met:
8*1b3f573fSAndroid Build Coastguard Worker//
9*1b3f573fSAndroid Build Coastguard Worker//     * Redistributions of source code must retain the above copyright
10*1b3f573fSAndroid Build Coastguard Worker// notice, this list of conditions and the following disclaimer.
11*1b3f573fSAndroid Build Coastguard Worker//     * Redistributions in binary form must reproduce the above
12*1b3f573fSAndroid Build Coastguard Worker// copyright notice, this list of conditions and the following disclaimer
13*1b3f573fSAndroid Build Coastguard Worker// in the documentation and/or other materials provided with the
14*1b3f573fSAndroid Build Coastguard Worker// distribution.
15*1b3f573fSAndroid Build Coastguard Worker//     * Neither the name of Google Inc. nor the names of its
16*1b3f573fSAndroid Build Coastguard Worker// contributors may be used to endorse or promote products derived from
17*1b3f573fSAndroid Build Coastguard Worker// this software without specific prior written permission.
18*1b3f573fSAndroid Build Coastguard Worker//
19*1b3f573fSAndroid Build Coastguard Worker// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20*1b3f573fSAndroid Build Coastguard Worker// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21*1b3f573fSAndroid Build Coastguard Worker// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22*1b3f573fSAndroid Build Coastguard Worker// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23*1b3f573fSAndroid Build Coastguard Worker// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24*1b3f573fSAndroid Build Coastguard Worker// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25*1b3f573fSAndroid Build Coastguard Worker// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26*1b3f573fSAndroid Build Coastguard Worker// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27*1b3f573fSAndroid Build Coastguard Worker// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28*1b3f573fSAndroid Build Coastguard Worker// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29*1b3f573fSAndroid Build Coastguard Worker// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*1b3f573fSAndroid Build Coastguard Worker
31*1b3f573fSAndroid Build Coastguard Worker#import "GPBTestUtilities.h"
32*1b3f573fSAndroid Build Coastguard Worker
33*1b3f573fSAndroid Build Coastguard Worker#import "GPBUnknownField_PackagePrivate.h"
34*1b3f573fSAndroid Build Coastguard Worker#import "GPBUnknownFieldSet_PackagePrivate.h"
35*1b3f573fSAndroid Build Coastguard Worker#import "google/protobuf/Unittest.pbobjc.h"
36*1b3f573fSAndroid Build Coastguard Worker
37*1b3f573fSAndroid Build Coastguard Worker@interface GPBUnknownFieldSet (GPBUnknownFieldSetTest)
38*1b3f573fSAndroid Build Coastguard Worker- (void)getTags:(int32_t*)tags;
39*1b3f573fSAndroid Build Coastguard Worker@end
40*1b3f573fSAndroid Build Coastguard Worker
41*1b3f573fSAndroid Build Coastguard Worker@interface UnknownFieldSetTest : GPBTestCase {
42*1b3f573fSAndroid Build Coastguard Worker @private
43*1b3f573fSAndroid Build Coastguard Worker  TestAllTypes* allFields_;
44*1b3f573fSAndroid Build Coastguard Worker  NSData* allFieldsData_;
45*1b3f573fSAndroid Build Coastguard Worker
46*1b3f573fSAndroid Build Coastguard Worker  // An empty message that has been parsed from allFieldsData.  So, it has
47*1b3f573fSAndroid Build Coastguard Worker  // unknown fields of every type.
48*1b3f573fSAndroid Build Coastguard Worker  TestEmptyMessage* emptyMessage_;
49*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownFieldSet* unknownFields_;
50*1b3f573fSAndroid Build Coastguard Worker}
51*1b3f573fSAndroid Build Coastguard Worker
52*1b3f573fSAndroid Build Coastguard Worker@end
53*1b3f573fSAndroid Build Coastguard Worker
54*1b3f573fSAndroid Build Coastguard Worker@implementation UnknownFieldSetTest
55*1b3f573fSAndroid Build Coastguard Worker
56*1b3f573fSAndroid Build Coastguard Worker- (void)setUp {
57*1b3f573fSAndroid Build Coastguard Worker  allFields_ = [self allSetRepeatedCount:kGPBDefaultRepeatCount];
58*1b3f573fSAndroid Build Coastguard Worker  allFieldsData_ = [allFields_ data];
59*1b3f573fSAndroid Build Coastguard Worker  emptyMessage_ = [TestEmptyMessage parseFromData:allFieldsData_ error:NULL];
60*1b3f573fSAndroid Build Coastguard Worker  unknownFields_ = emptyMessage_.unknownFields;
61*1b3f573fSAndroid Build Coastguard Worker}
62*1b3f573fSAndroid Build Coastguard Worker
63*1b3f573fSAndroid Build Coastguard Worker- (void)testInvalidFieldNumber {
64*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownFieldSet *set = [[[GPBUnknownFieldSet alloc] init] autorelease];
65*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownField* field = [[[GPBUnknownField alloc] initWithNumber:0] autorelease];
66*1b3f573fSAndroid Build Coastguard Worker  XCTAssertThrowsSpecificNamed([set addField:field], NSException, NSInvalidArgumentException);
67*1b3f573fSAndroid Build Coastguard Worker}
68*1b3f573fSAndroid Build Coastguard Worker
69*1b3f573fSAndroid Build Coastguard Worker- (void)testEqualityAndHash {
70*1b3f573fSAndroid Build Coastguard Worker  // Empty
71*1b3f573fSAndroid Build Coastguard Worker
72*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownFieldSet *set1 = [[[GPBUnknownFieldSet alloc] init] autorelease];
73*1b3f573fSAndroid Build Coastguard Worker  XCTAssertTrue([set1 isEqual:set1]);
74*1b3f573fSAndroid Build Coastguard Worker  XCTAssertFalse([set1 isEqual:@"foo"]);
75*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownFieldSet *set2 = [[[GPBUnknownFieldSet alloc] init] autorelease];
76*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqualObjects(set1, set2);
77*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqual([set1 hash], [set2 hash]);
78*1b3f573fSAndroid Build Coastguard Worker
79*1b3f573fSAndroid Build Coastguard Worker  // Varint
80*1b3f573fSAndroid Build Coastguard Worker
81*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownField* field1 = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
82*1b3f573fSAndroid Build Coastguard Worker  [field1 addVarint:1];
83*1b3f573fSAndroid Build Coastguard Worker  [set1 addField:field1];
84*1b3f573fSAndroid Build Coastguard Worker  XCTAssertNotEqualObjects(set1, set2);
85*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownField* field2 = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
86*1b3f573fSAndroid Build Coastguard Worker  [field2 addVarint:1];
87*1b3f573fSAndroid Build Coastguard Worker  [set2 addField:field2];
88*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqualObjects(set1, set2);
89*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqual([set1 hash], [set2 hash]);
90*1b3f573fSAndroid Build Coastguard Worker
91*1b3f573fSAndroid Build Coastguard Worker  // Fixed32
92*1b3f573fSAndroid Build Coastguard Worker
93*1b3f573fSAndroid Build Coastguard Worker  field1 = [[[GPBUnknownField alloc] initWithNumber:2] autorelease];
94*1b3f573fSAndroid Build Coastguard Worker  [field1 addFixed32:2];
95*1b3f573fSAndroid Build Coastguard Worker  [set1 addField:field1];
96*1b3f573fSAndroid Build Coastguard Worker  XCTAssertNotEqualObjects(set1, set2);
97*1b3f573fSAndroid Build Coastguard Worker  field2 = [[[GPBUnknownField alloc] initWithNumber:2] autorelease];
98*1b3f573fSAndroid Build Coastguard Worker  [field2 addFixed32:2];
99*1b3f573fSAndroid Build Coastguard Worker  [set2 addField:field2];
100*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqualObjects(set1, set2);
101*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqual([set1 hash], [set2 hash]);
102*1b3f573fSAndroid Build Coastguard Worker
103*1b3f573fSAndroid Build Coastguard Worker  // Fixed64
104*1b3f573fSAndroid Build Coastguard Worker
105*1b3f573fSAndroid Build Coastguard Worker  field1 = [[[GPBUnknownField alloc] initWithNumber:3] autorelease];
106*1b3f573fSAndroid Build Coastguard Worker  [field1 addFixed64:3];
107*1b3f573fSAndroid Build Coastguard Worker  [set1 addField:field1];
108*1b3f573fSAndroid Build Coastguard Worker  XCTAssertNotEqualObjects(set1, set2);
109*1b3f573fSAndroid Build Coastguard Worker  field2 = [[[GPBUnknownField alloc] initWithNumber:3] autorelease];
110*1b3f573fSAndroid Build Coastguard Worker  [field2 addFixed64:3];
111*1b3f573fSAndroid Build Coastguard Worker  [set2 addField:field2];
112*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqualObjects(set1, set2);
113*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqual([set1 hash], [set2 hash]);
114*1b3f573fSAndroid Build Coastguard Worker
115*1b3f573fSAndroid Build Coastguard Worker  // LengthDelimited
116*1b3f573fSAndroid Build Coastguard Worker
117*1b3f573fSAndroid Build Coastguard Worker  field1 = [[[GPBUnknownField alloc] initWithNumber:4] autorelease];
118*1b3f573fSAndroid Build Coastguard Worker  [field1 addLengthDelimited:DataFromCStr("foo")];
119*1b3f573fSAndroid Build Coastguard Worker  [set1 addField:field1];
120*1b3f573fSAndroid Build Coastguard Worker  XCTAssertNotEqualObjects(set1, set2);
121*1b3f573fSAndroid Build Coastguard Worker  field2 = [[[GPBUnknownField alloc] initWithNumber:4] autorelease];
122*1b3f573fSAndroid Build Coastguard Worker  [field2 addLengthDelimited:DataFromCStr("foo")];
123*1b3f573fSAndroid Build Coastguard Worker  [set2 addField:field2];
124*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqualObjects(set1, set2);
125*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqual([set1 hash], [set2 hash]);
126*1b3f573fSAndroid Build Coastguard Worker
127*1b3f573fSAndroid Build Coastguard Worker  // Group
128*1b3f573fSAndroid Build Coastguard Worker
129*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownFieldSet *group1 = [[[GPBUnknownFieldSet alloc] init] autorelease];
130*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownField* fieldGroup1 = [[[GPBUnknownField alloc] initWithNumber:10] autorelease];
131*1b3f573fSAndroid Build Coastguard Worker  [fieldGroup1 addVarint:1];
132*1b3f573fSAndroid Build Coastguard Worker  [group1 addField:fieldGroup1];
133*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownFieldSet *group2 = [[[GPBUnknownFieldSet alloc] init] autorelease];
134*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownField* fieldGroup2 = [[[GPBUnknownField alloc] initWithNumber:10] autorelease];
135*1b3f573fSAndroid Build Coastguard Worker  [fieldGroup2 addVarint:1];
136*1b3f573fSAndroid Build Coastguard Worker  [group2 addField:fieldGroup2];
137*1b3f573fSAndroid Build Coastguard Worker
138*1b3f573fSAndroid Build Coastguard Worker  field1 = [[[GPBUnknownField alloc] initWithNumber:5] autorelease];
139*1b3f573fSAndroid Build Coastguard Worker  [field1 addGroup:group1];
140*1b3f573fSAndroid Build Coastguard Worker  [set1 addField:field1];
141*1b3f573fSAndroid Build Coastguard Worker  XCTAssertNotEqualObjects(set1, set2);
142*1b3f573fSAndroid Build Coastguard Worker  field2 = [[[GPBUnknownField alloc] initWithNumber:5] autorelease];
143*1b3f573fSAndroid Build Coastguard Worker  [field2 addGroup:group2];
144*1b3f573fSAndroid Build Coastguard Worker  [set2 addField:field2];
145*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqualObjects(set1, set2);
146*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqual([set1 hash], [set2 hash]);
147*1b3f573fSAndroid Build Coastguard Worker
148*1b3f573fSAndroid Build Coastguard Worker  // Exercise description for completeness.
149*1b3f573fSAndroid Build Coastguard Worker  XCTAssertTrue(set1.description.length > 10);
150*1b3f573fSAndroid Build Coastguard Worker}
151*1b3f573fSAndroid Build Coastguard Worker
152*1b3f573fSAndroid Build Coastguard Worker// Constructs a protocol buffer which contains fields with all the same
153*1b3f573fSAndroid Build Coastguard Worker// numbers as allFieldsData except that each field is some other wire
154*1b3f573fSAndroid Build Coastguard Worker// type.
155*1b3f573fSAndroid Build Coastguard Worker- (NSData*)getBizarroData {
156*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownFieldSet* bizarroFields =
157*1b3f573fSAndroid Build Coastguard Worker      [[[GPBUnknownFieldSet alloc] init] autorelease];
158*1b3f573fSAndroid Build Coastguard Worker  NSUInteger count = [unknownFields_ countOfFields];
159*1b3f573fSAndroid Build Coastguard Worker  int32_t *tags = malloc(count * sizeof(int32_t));
160*1b3f573fSAndroid Build Coastguard Worker  if (!tags) {
161*1b3f573fSAndroid Build Coastguard Worker    XCTFail(@"Failed to make scratch buffer for testing");
162*1b3f573fSAndroid Build Coastguard Worker    return [NSData data];
163*1b3f573fSAndroid Build Coastguard Worker  }
164*1b3f573fSAndroid Build Coastguard Worker  @try {
165*1b3f573fSAndroid Build Coastguard Worker    [unknownFields_ getTags:tags];
166*1b3f573fSAndroid Build Coastguard Worker    for (NSUInteger i = 0; i < count; ++i) {
167*1b3f573fSAndroid Build Coastguard Worker      int32_t tag = tags[i];
168*1b3f573fSAndroid Build Coastguard Worker      GPBUnknownField* field = [unknownFields_ getField:tag];
169*1b3f573fSAndroid Build Coastguard Worker      if (field.varintList.count == 0) {
170*1b3f573fSAndroid Build Coastguard Worker        // Original field is not a varint, so use a varint.
171*1b3f573fSAndroid Build Coastguard Worker        GPBUnknownField* varintField =
172*1b3f573fSAndroid Build Coastguard Worker            [[[GPBUnknownField alloc] initWithNumber:tag] autorelease];
173*1b3f573fSAndroid Build Coastguard Worker        [varintField addVarint:1];
174*1b3f573fSAndroid Build Coastguard Worker        [bizarroFields addField:varintField];
175*1b3f573fSAndroid Build Coastguard Worker      } else {
176*1b3f573fSAndroid Build Coastguard Worker        // Original field *is* a varint, so use something else.
177*1b3f573fSAndroid Build Coastguard Worker        GPBUnknownField* fixed32Field =
178*1b3f573fSAndroid Build Coastguard Worker            [[[GPBUnknownField alloc] initWithNumber:tag] autorelease];
179*1b3f573fSAndroid Build Coastguard Worker        [fixed32Field addFixed32:1];
180*1b3f573fSAndroid Build Coastguard Worker        [bizarroFields addField:fixed32Field];
181*1b3f573fSAndroid Build Coastguard Worker      }
182*1b3f573fSAndroid Build Coastguard Worker    }
183*1b3f573fSAndroid Build Coastguard Worker  }
184*1b3f573fSAndroid Build Coastguard Worker  @finally {
185*1b3f573fSAndroid Build Coastguard Worker    free(tags);
186*1b3f573fSAndroid Build Coastguard Worker  }
187*1b3f573fSAndroid Build Coastguard Worker
188*1b3f573fSAndroid Build Coastguard Worker  return [bizarroFields data];
189*1b3f573fSAndroid Build Coastguard Worker}
190*1b3f573fSAndroid Build Coastguard Worker
191*1b3f573fSAndroid Build Coastguard Worker- (void)testSerialize {
192*1b3f573fSAndroid Build Coastguard Worker  // Check that serializing the UnknownFieldSet produces the original data
193*1b3f573fSAndroid Build Coastguard Worker  // again.
194*1b3f573fSAndroid Build Coastguard Worker  NSData* data = [emptyMessage_ data];
195*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqualObjects(allFieldsData_, data);
196*1b3f573fSAndroid Build Coastguard Worker}
197*1b3f573fSAndroid Build Coastguard Worker
198*1b3f573fSAndroid Build Coastguard Worker- (void)testCopyFrom {
199*1b3f573fSAndroid Build Coastguard Worker  TestEmptyMessage* message = [TestEmptyMessage message];
200*1b3f573fSAndroid Build Coastguard Worker  [message mergeFrom:emptyMessage_];
201*1b3f573fSAndroid Build Coastguard Worker
202*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqualObjects(emptyMessage_.data, message.data);
203*1b3f573fSAndroid Build Coastguard Worker}
204*1b3f573fSAndroid Build Coastguard Worker
205*1b3f573fSAndroid Build Coastguard Worker- (void)testMergeFrom {
206*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownFieldSet* set1 = [[[GPBUnknownFieldSet alloc] init] autorelease];
207*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownField* field = [[[GPBUnknownField alloc] initWithNumber:2] autorelease];
208*1b3f573fSAndroid Build Coastguard Worker  [field addVarint:2];
209*1b3f573fSAndroid Build Coastguard Worker  [set1 addField:field];
210*1b3f573fSAndroid Build Coastguard Worker  field = [[[GPBUnknownField alloc] initWithNumber:3] autorelease];
211*1b3f573fSAndroid Build Coastguard Worker  [field addVarint:4];
212*1b3f573fSAndroid Build Coastguard Worker  [set1 addField:field];
213*1b3f573fSAndroid Build Coastguard Worker  field = [[[GPBUnknownField alloc] initWithNumber:4] autorelease];
214*1b3f573fSAndroid Build Coastguard Worker  [field addFixed32:6];
215*1b3f573fSAndroid Build Coastguard Worker  [set1 addField:field];
216*1b3f573fSAndroid Build Coastguard Worker  field = [[[GPBUnknownField alloc] initWithNumber:5] autorelease];
217*1b3f573fSAndroid Build Coastguard Worker  [field addFixed64:20];
218*1b3f573fSAndroid Build Coastguard Worker  [set1 addField:field];
219*1b3f573fSAndroid Build Coastguard Worker  field = [[[GPBUnknownField alloc] initWithNumber:10] autorelease];
220*1b3f573fSAndroid Build Coastguard Worker  [field addLengthDelimited:DataFromCStr("data1")];
221*1b3f573fSAndroid Build Coastguard Worker  [set1 addField:field];
222*1b3f573fSAndroid Build Coastguard Worker
223*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownFieldSet *group1 = [[[GPBUnknownFieldSet alloc] init] autorelease];
224*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownField* fieldGroup1 = [[[GPBUnknownField alloc] initWithNumber:200] autorelease];
225*1b3f573fSAndroid Build Coastguard Worker  [fieldGroup1 addVarint:100];
226*1b3f573fSAndroid Build Coastguard Worker  [group1 addField:fieldGroup1];
227*1b3f573fSAndroid Build Coastguard Worker
228*1b3f573fSAndroid Build Coastguard Worker  field = [[[GPBUnknownField alloc] initWithNumber:11] autorelease];
229*1b3f573fSAndroid Build Coastguard Worker  [field addGroup:group1];
230*1b3f573fSAndroid Build Coastguard Worker  [set1 addField:field];
231*1b3f573fSAndroid Build Coastguard Worker
232*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownFieldSet* set2 = [[[GPBUnknownFieldSet alloc] init] autorelease];
233*1b3f573fSAndroid Build Coastguard Worker  field = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
234*1b3f573fSAndroid Build Coastguard Worker  [field addVarint:1];
235*1b3f573fSAndroid Build Coastguard Worker  [set2 addField:field];
236*1b3f573fSAndroid Build Coastguard Worker  field = [[[GPBUnknownField alloc] initWithNumber:3] autorelease];
237*1b3f573fSAndroid Build Coastguard Worker  [field addVarint:3];
238*1b3f573fSAndroid Build Coastguard Worker  [set2 addField:field];
239*1b3f573fSAndroid Build Coastguard Worker  field = [[[GPBUnknownField alloc] initWithNumber:4] autorelease];
240*1b3f573fSAndroid Build Coastguard Worker  [field addFixed32:7];
241*1b3f573fSAndroid Build Coastguard Worker  [set2 addField:field];
242*1b3f573fSAndroid Build Coastguard Worker  field = [[[GPBUnknownField alloc] initWithNumber:5] autorelease];
243*1b3f573fSAndroid Build Coastguard Worker  [field addFixed64:30];
244*1b3f573fSAndroid Build Coastguard Worker  [set2 addField:field];
245*1b3f573fSAndroid Build Coastguard Worker  field = [[[GPBUnknownField alloc] initWithNumber:10] autorelease];
246*1b3f573fSAndroid Build Coastguard Worker  [field addLengthDelimited:DataFromCStr("data2")];
247*1b3f573fSAndroid Build Coastguard Worker  [set2 addField:field];
248*1b3f573fSAndroid Build Coastguard Worker
249*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownFieldSet *group2 = [[[GPBUnknownFieldSet alloc] init] autorelease];
250*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownField* fieldGroup2 = [[[GPBUnknownField alloc] initWithNumber:201] autorelease];
251*1b3f573fSAndroid Build Coastguard Worker  [fieldGroup2 addVarint:99];
252*1b3f573fSAndroid Build Coastguard Worker  [group2 addField:fieldGroup2];
253*1b3f573fSAndroid Build Coastguard Worker
254*1b3f573fSAndroid Build Coastguard Worker  field = [[[GPBUnknownField alloc] initWithNumber:11] autorelease];
255*1b3f573fSAndroid Build Coastguard Worker  [field addGroup:group2];
256*1b3f573fSAndroid Build Coastguard Worker  [set2 addField:field];
257*1b3f573fSAndroid Build Coastguard Worker
258*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownFieldSet* set3 = [[[GPBUnknownFieldSet alloc] init] autorelease];
259*1b3f573fSAndroid Build Coastguard Worker  field = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
260*1b3f573fSAndroid Build Coastguard Worker  [field addVarint:1];
261*1b3f573fSAndroid Build Coastguard Worker  [set3 addField:field];
262*1b3f573fSAndroid Build Coastguard Worker  field = [[[GPBUnknownField alloc] initWithNumber:2] autorelease];
263*1b3f573fSAndroid Build Coastguard Worker  [field addVarint:2];
264*1b3f573fSAndroid Build Coastguard Worker  [set3 addField:field];
265*1b3f573fSAndroid Build Coastguard Worker  field = [[[GPBUnknownField alloc] initWithNumber:3] autorelease];
266*1b3f573fSAndroid Build Coastguard Worker  [field addVarint:4];
267*1b3f573fSAndroid Build Coastguard Worker  [set3 addField:field];
268*1b3f573fSAndroid Build Coastguard Worker  [field addVarint:3];
269*1b3f573fSAndroid Build Coastguard Worker  [set3 addField:field];
270*1b3f573fSAndroid Build Coastguard Worker  field = [[[GPBUnknownField alloc] initWithNumber:4] autorelease];
271*1b3f573fSAndroid Build Coastguard Worker  [field addFixed32:6];
272*1b3f573fSAndroid Build Coastguard Worker  [field addFixed32:7];
273*1b3f573fSAndroid Build Coastguard Worker  [set3 addField:field];
274*1b3f573fSAndroid Build Coastguard Worker  field = [[[GPBUnknownField alloc] initWithNumber:5] autorelease];
275*1b3f573fSAndroid Build Coastguard Worker  [field addFixed64:20];
276*1b3f573fSAndroid Build Coastguard Worker  [field addFixed64:30];
277*1b3f573fSAndroid Build Coastguard Worker  [set3 addField:field];
278*1b3f573fSAndroid Build Coastguard Worker  field = [[[GPBUnknownField alloc] initWithNumber:10] autorelease];
279*1b3f573fSAndroid Build Coastguard Worker  [field addLengthDelimited:DataFromCStr("data1")];
280*1b3f573fSAndroid Build Coastguard Worker  [field addLengthDelimited:DataFromCStr("data2")];
281*1b3f573fSAndroid Build Coastguard Worker  [set3 addField:field];
282*1b3f573fSAndroid Build Coastguard Worker
283*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownFieldSet *group3a = [[[GPBUnknownFieldSet alloc] init] autorelease];
284*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownField* fieldGroup3a1 = [[[GPBUnknownField alloc] initWithNumber:200] autorelease];
285*1b3f573fSAndroid Build Coastguard Worker  [fieldGroup3a1 addVarint:100];
286*1b3f573fSAndroid Build Coastguard Worker  [group3a addField:fieldGroup3a1];
287*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownFieldSet *group3b = [[[GPBUnknownFieldSet alloc] init] autorelease];
288*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownField* fieldGroup3b2 = [[[GPBUnknownField alloc] initWithNumber:201] autorelease];
289*1b3f573fSAndroid Build Coastguard Worker  [fieldGroup3b2 addVarint:99];
290*1b3f573fSAndroid Build Coastguard Worker  [group3b addField:fieldGroup3b2];
291*1b3f573fSAndroid Build Coastguard Worker
292*1b3f573fSAndroid Build Coastguard Worker  field = [[[GPBUnknownField alloc] initWithNumber:11] autorelease];
293*1b3f573fSAndroid Build Coastguard Worker  [field addGroup:group1];
294*1b3f573fSAndroid Build Coastguard Worker  [field addGroup:group3b];
295*1b3f573fSAndroid Build Coastguard Worker  [set3 addField:field];
296*1b3f573fSAndroid Build Coastguard Worker
297*1b3f573fSAndroid Build Coastguard Worker  TestEmptyMessage* source1 = [TestEmptyMessage message];
298*1b3f573fSAndroid Build Coastguard Worker  [source1 setUnknownFields:set1];
299*1b3f573fSAndroid Build Coastguard Worker  TestEmptyMessage* source2 = [TestEmptyMessage message];
300*1b3f573fSAndroid Build Coastguard Worker  [source2 setUnknownFields:set2];
301*1b3f573fSAndroid Build Coastguard Worker  TestEmptyMessage* source3 = [TestEmptyMessage message];
302*1b3f573fSAndroid Build Coastguard Worker  [source3 setUnknownFields:set3];
303*1b3f573fSAndroid Build Coastguard Worker
304*1b3f573fSAndroid Build Coastguard Worker  TestEmptyMessage* destination1 = [TestEmptyMessage message];
305*1b3f573fSAndroid Build Coastguard Worker  [destination1 mergeFrom:source1];
306*1b3f573fSAndroid Build Coastguard Worker  [destination1 mergeFrom:source2];
307*1b3f573fSAndroid Build Coastguard Worker
308*1b3f573fSAndroid Build Coastguard Worker  TestEmptyMessage* destination2 = [TestEmptyMessage message];
309*1b3f573fSAndroid Build Coastguard Worker  [destination2 mergeFrom:source3];
310*1b3f573fSAndroid Build Coastguard Worker
311*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqualObjects(destination1.data, destination2.data);
312*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqualObjects(destination1.data, source3.data);
313*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqualObjects(destination2.data, source3.data);
314*1b3f573fSAndroid Build Coastguard Worker}
315*1b3f573fSAndroid Build Coastguard Worker
316*1b3f573fSAndroid Build Coastguard Worker- (void)testClearMessage {
317*1b3f573fSAndroid Build Coastguard Worker  TestEmptyMessage *message = [TestEmptyMessage message];
318*1b3f573fSAndroid Build Coastguard Worker  [message mergeFrom:emptyMessage_];
319*1b3f573fSAndroid Build Coastguard Worker  [message clear];
320*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqual(message.serializedSize, (size_t)0);
321*1b3f573fSAndroid Build Coastguard Worker}
322*1b3f573fSAndroid Build Coastguard Worker
323*1b3f573fSAndroid Build Coastguard Worker- (void)testParseKnownAndUnknown {
324*1b3f573fSAndroid Build Coastguard Worker  // Test mixing known and unknown fields when parsing.
325*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownFieldSet *fields = [[unknownFields_ copy] autorelease];
326*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownField *field =
327*1b3f573fSAndroid Build Coastguard Worker    [[[GPBUnknownField alloc] initWithNumber:123456] autorelease];
328*1b3f573fSAndroid Build Coastguard Worker  [field addVarint:654321];
329*1b3f573fSAndroid Build Coastguard Worker  [fields addField:field];
330*1b3f573fSAndroid Build Coastguard Worker
331*1b3f573fSAndroid Build Coastguard Worker  NSData* data = fields.data;
332*1b3f573fSAndroid Build Coastguard Worker  TestAllTypes* destination = [TestAllTypes parseFromData:data error:NULL];
333*1b3f573fSAndroid Build Coastguard Worker
334*1b3f573fSAndroid Build Coastguard Worker  [self assertAllFieldsSet:destination repeatedCount:kGPBDefaultRepeatCount];
335*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqual(destination.unknownFields.countOfFields, (NSUInteger)1);
336*1b3f573fSAndroid Build Coastguard Worker
337*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownField* field2 = [destination.unknownFields getField:123456];
338*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqual(field2.varintList.count, (NSUInteger)1);
339*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqual(654321ULL, [field2.varintList valueAtIndex:0]);
340*1b3f573fSAndroid Build Coastguard Worker}
341*1b3f573fSAndroid Build Coastguard Worker
342*1b3f573fSAndroid Build Coastguard Worker- (void)testWrongTypeTreatedAsUnknown {
343*1b3f573fSAndroid Build Coastguard Worker  // Test that fields of the wrong wire type are treated like unknown fields
344*1b3f573fSAndroid Build Coastguard Worker  // when parsing.
345*1b3f573fSAndroid Build Coastguard Worker
346*1b3f573fSAndroid Build Coastguard Worker  NSData* bizarroData = [self getBizarroData];
347*1b3f573fSAndroid Build Coastguard Worker  TestAllTypes* allTypesMessage =
348*1b3f573fSAndroid Build Coastguard Worker      [TestAllTypes parseFromData:bizarroData error:NULL];
349*1b3f573fSAndroid Build Coastguard Worker  TestEmptyMessage* emptyMessage =
350*1b3f573fSAndroid Build Coastguard Worker      [TestEmptyMessage parseFromData:bizarroData error:NULL];
351*1b3f573fSAndroid Build Coastguard Worker
352*1b3f573fSAndroid Build Coastguard Worker  // All fields should have been interpreted as unknown, so the debug strings
353*1b3f573fSAndroid Build Coastguard Worker  // should be the same.
354*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqualObjects(emptyMessage.data, allTypesMessage.data);
355*1b3f573fSAndroid Build Coastguard Worker}
356*1b3f573fSAndroid Build Coastguard Worker
357*1b3f573fSAndroid Build Coastguard Worker- (void)testUnknownExtensions {
358*1b3f573fSAndroid Build Coastguard Worker  // Make sure fields are properly parsed to the UnknownFieldSet even when
359*1b3f573fSAndroid Build Coastguard Worker  // they are declared as extension numbers.
360*1b3f573fSAndroid Build Coastguard Worker
361*1b3f573fSAndroid Build Coastguard Worker  TestEmptyMessageWithExtensions* message =
362*1b3f573fSAndroid Build Coastguard Worker      [TestEmptyMessageWithExtensions parseFromData:allFieldsData_ error:NULL];
363*1b3f573fSAndroid Build Coastguard Worker
364*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqual(unknownFields_.countOfFields,
365*1b3f573fSAndroid Build Coastguard Worker                 message.unknownFields.countOfFields);
366*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqualObjects(allFieldsData_, message.data);
367*1b3f573fSAndroid Build Coastguard Worker}
368*1b3f573fSAndroid Build Coastguard Worker
369*1b3f573fSAndroid Build Coastguard Worker- (void)testWrongExtensionTypeTreatedAsUnknown {
370*1b3f573fSAndroid Build Coastguard Worker  // Test that fields of the wrong wire type are treated like unknown fields
371*1b3f573fSAndroid Build Coastguard Worker  // when parsing extensions.
372*1b3f573fSAndroid Build Coastguard Worker
373*1b3f573fSAndroid Build Coastguard Worker  NSData* bizarroData = [self getBizarroData];
374*1b3f573fSAndroid Build Coastguard Worker  TestAllExtensions* allExtensionsMessage =
375*1b3f573fSAndroid Build Coastguard Worker      [TestAllExtensions parseFromData:bizarroData error:NULL];
376*1b3f573fSAndroid Build Coastguard Worker  TestEmptyMessage* emptyMessage =
377*1b3f573fSAndroid Build Coastguard Worker      [TestEmptyMessage parseFromData:bizarroData error:NULL];
378*1b3f573fSAndroid Build Coastguard Worker
379*1b3f573fSAndroid Build Coastguard Worker  // All fields should have been interpreted as unknown, so the debug strings
380*1b3f573fSAndroid Build Coastguard Worker  // should be the same.
381*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqualObjects(emptyMessage.data, allExtensionsMessage.data);
382*1b3f573fSAndroid Build Coastguard Worker}
383*1b3f573fSAndroid Build Coastguard Worker
384*1b3f573fSAndroid Build Coastguard Worker- (void)testLargeVarint {
385*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownFieldSet* fields = [[unknownFields_ copy] autorelease];
386*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownField* field = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
387*1b3f573fSAndroid Build Coastguard Worker  [field addVarint:0x7FFFFFFFFFFFFFFFL];
388*1b3f573fSAndroid Build Coastguard Worker  [fields addField:field];
389*1b3f573fSAndroid Build Coastguard Worker
390*1b3f573fSAndroid Build Coastguard Worker  NSData* data = [fields data];
391*1b3f573fSAndroid Build Coastguard Worker
392*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownFieldSet* parsed = [[[GPBUnknownFieldSet alloc] init] autorelease];
393*1b3f573fSAndroid Build Coastguard Worker  [parsed mergeFromData:data];
394*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownField* field2 = [parsed getField:1];
395*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqual(field2.varintList.count, (NSUInteger)1);
396*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqual(0x7FFFFFFFFFFFFFFFULL, [field2.varintList valueAtIndex:0]);
397*1b3f573fSAndroid Build Coastguard Worker}
398*1b3f573fSAndroid Build Coastguard Worker
399*1b3f573fSAndroid Build Coastguard Worker#pragma mark - Field tests
400*1b3f573fSAndroid Build Coastguard Worker// Some tests directly on fields since the dictionary in FieldSet can gate
401*1b3f573fSAndroid Build Coastguard Worker// testing some of these.
402*1b3f573fSAndroid Build Coastguard Worker
403*1b3f573fSAndroid Build Coastguard Worker- (void)testFieldEqualityAndHash {
404*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownField* field1 = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
405*1b3f573fSAndroid Build Coastguard Worker  XCTAssertTrue([field1 isEqual:field1]);
406*1b3f573fSAndroid Build Coastguard Worker  XCTAssertFalse([field1 isEqual:@"foo"]);
407*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownField* field2 = [[[GPBUnknownField alloc] initWithNumber:2] autorelease];
408*1b3f573fSAndroid Build Coastguard Worker  XCTAssertNotEqualObjects(field1, field2);
409*1b3f573fSAndroid Build Coastguard Worker
410*1b3f573fSAndroid Build Coastguard Worker  field2 = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
411*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqualObjects(field1, field2);
412*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqual([field1 hash], [field2 hash]);
413*1b3f573fSAndroid Build Coastguard Worker
414*1b3f573fSAndroid Build Coastguard Worker  // Varint
415*1b3f573fSAndroid Build Coastguard Worker
416*1b3f573fSAndroid Build Coastguard Worker  [field1 addVarint:10];
417*1b3f573fSAndroid Build Coastguard Worker  XCTAssertNotEqualObjects(field1, field2);
418*1b3f573fSAndroid Build Coastguard Worker  [field2 addVarint:10];
419*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqualObjects(field1, field2);
420*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqual([field1 hash], [field2 hash]);
421*1b3f573fSAndroid Build Coastguard Worker  [field1 addVarint:11];
422*1b3f573fSAndroid Build Coastguard Worker  XCTAssertNotEqualObjects(field1, field2);
423*1b3f573fSAndroid Build Coastguard Worker  [field2 addVarint:11];
424*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqualObjects(field1, field2);
425*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqual([field1 hash], [field2 hash]);
426*1b3f573fSAndroid Build Coastguard Worker
427*1b3f573fSAndroid Build Coastguard Worker  // Fixed32
428*1b3f573fSAndroid Build Coastguard Worker
429*1b3f573fSAndroid Build Coastguard Worker  [field1 addFixed32:20];
430*1b3f573fSAndroid Build Coastguard Worker  XCTAssertNotEqualObjects(field1, field2);
431*1b3f573fSAndroid Build Coastguard Worker  [field2 addFixed32:20];
432*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqualObjects(field1, field2);
433*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqual([field1 hash], [field2 hash]);
434*1b3f573fSAndroid Build Coastguard Worker  [field1 addFixed32:21];
435*1b3f573fSAndroid Build Coastguard Worker  XCTAssertNotEqualObjects(field1, field2);
436*1b3f573fSAndroid Build Coastguard Worker  [field2 addFixed32:21];
437*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqualObjects(field1, field2);
438*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqual([field1 hash], [field2 hash]);
439*1b3f573fSAndroid Build Coastguard Worker
440*1b3f573fSAndroid Build Coastguard Worker  // Fixed64
441*1b3f573fSAndroid Build Coastguard Worker
442*1b3f573fSAndroid Build Coastguard Worker  [field1 addFixed64:30];
443*1b3f573fSAndroid Build Coastguard Worker  XCTAssertNotEqualObjects(field1, field2);
444*1b3f573fSAndroid Build Coastguard Worker  [field2 addFixed64:30];
445*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqualObjects(field1, field2);
446*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqual([field1 hash], [field2 hash]);
447*1b3f573fSAndroid Build Coastguard Worker  [field1 addFixed64:31];
448*1b3f573fSAndroid Build Coastguard Worker  XCTAssertNotEqualObjects(field1, field2);
449*1b3f573fSAndroid Build Coastguard Worker  [field2 addFixed64:31];
450*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqualObjects(field1, field2);
451*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqual([field1 hash], [field2 hash]);
452*1b3f573fSAndroid Build Coastguard Worker
453*1b3f573fSAndroid Build Coastguard Worker  // LengthDelimited
454*1b3f573fSAndroid Build Coastguard Worker
455*1b3f573fSAndroid Build Coastguard Worker  [field1 addLengthDelimited:DataFromCStr("foo")];
456*1b3f573fSAndroid Build Coastguard Worker  XCTAssertNotEqualObjects(field1, field2);
457*1b3f573fSAndroid Build Coastguard Worker  [field2 addLengthDelimited:DataFromCStr("foo")];
458*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqualObjects(field1, field2);
459*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqual([field1 hash], [field2 hash]);
460*1b3f573fSAndroid Build Coastguard Worker  [field1 addLengthDelimited:DataFromCStr("bar")];
461*1b3f573fSAndroid Build Coastguard Worker  XCTAssertNotEqualObjects(field1, field2);
462*1b3f573fSAndroid Build Coastguard Worker  [field2 addLengthDelimited:DataFromCStr("bar")];
463*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqualObjects(field1, field2);
464*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqual([field1 hash], [field2 hash]);
465*1b3f573fSAndroid Build Coastguard Worker
466*1b3f573fSAndroid Build Coastguard Worker  // Group
467*1b3f573fSAndroid Build Coastguard Worker
468*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownFieldSet *group = [[[GPBUnknownFieldSet alloc] init] autorelease];
469*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownField* fieldGroup = [[[GPBUnknownField alloc] initWithNumber:100] autorelease];
470*1b3f573fSAndroid Build Coastguard Worker  [fieldGroup addVarint:100];
471*1b3f573fSAndroid Build Coastguard Worker  [group addField:fieldGroup];
472*1b3f573fSAndroid Build Coastguard Worker  [field1 addGroup:group];
473*1b3f573fSAndroid Build Coastguard Worker  XCTAssertNotEqualObjects(field1, field2);
474*1b3f573fSAndroid Build Coastguard Worker  group = [[[GPBUnknownFieldSet alloc] init] autorelease];
475*1b3f573fSAndroid Build Coastguard Worker  fieldGroup = [[[GPBUnknownField alloc] initWithNumber:100] autorelease];
476*1b3f573fSAndroid Build Coastguard Worker  [fieldGroup addVarint:100];
477*1b3f573fSAndroid Build Coastguard Worker  [group addField:fieldGroup];
478*1b3f573fSAndroid Build Coastguard Worker  [field2 addGroup:group];
479*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqualObjects(field1, field2);
480*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqual([field1 hash], [field2 hash]);
481*1b3f573fSAndroid Build Coastguard Worker
482*1b3f573fSAndroid Build Coastguard Worker  group = [[[GPBUnknownFieldSet alloc] init] autorelease];
483*1b3f573fSAndroid Build Coastguard Worker  fieldGroup = [[[GPBUnknownField alloc] initWithNumber:101] autorelease];
484*1b3f573fSAndroid Build Coastguard Worker  [fieldGroup addVarint:101];
485*1b3f573fSAndroid Build Coastguard Worker  [group addField:fieldGroup];
486*1b3f573fSAndroid Build Coastguard Worker  [field1 addGroup:group];
487*1b3f573fSAndroid Build Coastguard Worker  XCTAssertNotEqualObjects(field1, field2);
488*1b3f573fSAndroid Build Coastguard Worker  group = [[[GPBUnknownFieldSet alloc] init] autorelease];
489*1b3f573fSAndroid Build Coastguard Worker  fieldGroup = [[[GPBUnknownField alloc] initWithNumber:101] autorelease];
490*1b3f573fSAndroid Build Coastguard Worker  [fieldGroup addVarint:101];
491*1b3f573fSAndroid Build Coastguard Worker  [group addField:fieldGroup];
492*1b3f573fSAndroid Build Coastguard Worker  [field2 addGroup:group];
493*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqualObjects(field1, field2);
494*1b3f573fSAndroid Build Coastguard Worker  XCTAssertEqual([field1 hash], [field2 hash]);
495*1b3f573fSAndroid Build Coastguard Worker
496*1b3f573fSAndroid Build Coastguard Worker  // Exercise description for completeness.
497*1b3f573fSAndroid Build Coastguard Worker  XCTAssertTrue(field1.description.length > 10);
498*1b3f573fSAndroid Build Coastguard Worker}
499*1b3f573fSAndroid Build Coastguard Worker
500*1b3f573fSAndroid Build Coastguard Worker- (void)testMergingFields {
501*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownField* field1 = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
502*1b3f573fSAndroid Build Coastguard Worker  [field1 addVarint:1];
503*1b3f573fSAndroid Build Coastguard Worker  [field1 addFixed32:2];
504*1b3f573fSAndroid Build Coastguard Worker  [field1 addFixed64:3];
505*1b3f573fSAndroid Build Coastguard Worker  [field1 addLengthDelimited:[NSData dataWithBytes:"hello" length:5]];
506*1b3f573fSAndroid Build Coastguard Worker  [field1 addGroup:[[unknownFields_ copy] autorelease]];
507*1b3f573fSAndroid Build Coastguard Worker  GPBUnknownField* field2 = [[[GPBUnknownField alloc] initWithNumber:1] autorelease];
508*1b3f573fSAndroid Build Coastguard Worker  [field2 mergeFromField:field1];
509*1b3f573fSAndroid Build Coastguard Worker}
510*1b3f573fSAndroid Build Coastguard Worker
511*1b3f573fSAndroid Build Coastguard Worker@end
512