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