• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Protocol Buffers - Google's data interchange format
2// Copyright 2024 Google Inc.  All rights reserved.
3//
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file or at
6// https://developers.google.com/open-source/licenses/bsd
7
8#import <Foundation/Foundation.h>
9
10#import "GPBTestUtilities.h"
11#import "GPBUnknownField.h"
12#import "GPBUnknownFields.h"
13#import "GPBUnknownFields_PackagePrivate.h"
14#import "objectivec/Tests/Unittest.pbobjc.h"
15
16@interface UnknownFieldsTest : GPBTestCase
17@end
18
19@implementation UnknownFieldsTest
20
21- (void)testEmptyAndClear {
22  GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
23  XCTAssertTrue(ufs.empty);
24
25  [ufs addFieldNumber:1 varint:1];
26  XCTAssertFalse(ufs.empty);
27  [ufs clear];
28  XCTAssertTrue(ufs.empty);
29
30  [ufs addFieldNumber:1 fixed32:1];
31  XCTAssertFalse(ufs.empty);
32  [ufs clear];
33  XCTAssertTrue(ufs.empty);
34
35  [ufs addFieldNumber:1 fixed64:1];
36  XCTAssertFalse(ufs.empty);
37  [ufs clear];
38  XCTAssertTrue(ufs.empty);
39
40  [ufs addFieldNumber:1 lengthDelimited:[NSData data]];
41  XCTAssertFalse(ufs.empty);
42  [ufs clear];
43  XCTAssertTrue(ufs.empty);
44
45  GPBUnknownFields* group = [ufs addGroupWithFieldNumber:1];
46  XCTAssertNotNil(group);
47  XCTAssertFalse(ufs.empty);
48}
49
50- (void)testEqualityAndHash {
51  // This also calls the methods on the `GPBUnknownField` objects for completeness and to
52  // make any failure in that class easier to notice/debug.
53
54  // Empty
55
56  GPBUnknownFields* ufs1 = [[[GPBUnknownFields alloc] init] autorelease];
57  XCTAssertTrue([ufs1 isEqual:ufs1]);
58  XCTAssertFalse([ufs1 isEqual:@"foo"]);
59  GPBUnknownFields* ufs2 = [[[GPBUnknownFields alloc] init] autorelease];
60  XCTAssertEqualObjects(ufs1, ufs2);
61  XCTAssertEqual([ufs1 hash], [ufs2 hash]);
62
63  // Varint
64
65  [ufs1 addFieldNumber:1 varint:1];
66  XCTAssertNotEqualObjects(ufs1, ufs2);
67  [ufs2 addFieldNumber:1 varint:1];
68  XCTAssertEqualObjects(ufs1, ufs2);
69  XCTAssertEqual([ufs1 hash], [ufs2 hash]);
70  GPBUnknownField* field1 = [[ufs1 fields:1] firstObject];
71  XCTAssertNotNil(field1);
72  GPBUnknownField* field2 = [[ufs2 fields:1] firstObject];
73  XCTAssertNotNil(field2);
74  XCTAssertEqualObjects(field1, field2);
75  XCTAssertTrue(field1 != field2);  // Different objects.
76  XCTAssertEqual([field1 hash], [field2 hash]);
77
78  // Fixed32
79
80  [ufs1 addFieldNumber:2 fixed32:1];
81  XCTAssertNotEqualObjects(ufs1, ufs2);
82  [ufs2 addFieldNumber:2 fixed32:1];
83  XCTAssertEqualObjects(ufs1, ufs2);
84  XCTAssertEqual([ufs1 hash], [ufs2 hash]);
85  field1 = [[ufs1 fields:2] firstObject];
86  XCTAssertNotNil(field1);
87  field2 = [[ufs2 fields:2] firstObject];
88  XCTAssertNotNil(field2);
89  XCTAssertEqualObjects(field1, field2);
90  XCTAssertTrue(field1 != field2);  // Different objects.
91  XCTAssertEqual([field1 hash], [field2 hash]);
92
93  // Fixed64
94
95  [ufs1 addFieldNumber:3 fixed64:1];
96  XCTAssertNotEqualObjects(ufs1, ufs2);
97  [ufs2 addFieldNumber:3 fixed64:1];
98  XCTAssertEqualObjects(ufs1, ufs2);
99  XCTAssertEqual([ufs1 hash], [ufs2 hash]);
100  field1 = [[ufs1 fields:3] firstObject];
101  XCTAssertNotNil(field1);
102  field2 = [[ufs2 fields:3] firstObject];
103  XCTAssertNotNil(field2);
104  XCTAssertEqualObjects(field1, field2);
105  XCTAssertTrue(field1 != field2);  // Different objects.
106  XCTAssertEqual([field1 hash], [field2 hash]);
107
108  // LengthDelimited
109
110  [ufs1 addFieldNumber:4 lengthDelimited:DataFromCStr("foo")];
111  XCTAssertNotEqualObjects(ufs1, ufs2);
112  [ufs2 addFieldNumber:4 lengthDelimited:DataFromCStr("foo")];
113  XCTAssertEqualObjects(ufs1, ufs2);
114  XCTAssertEqual([ufs1 hash], [ufs2 hash]);
115  field1 = [[ufs1 fields:4] firstObject];
116  XCTAssertNotNil(field1);
117  field2 = [[ufs2 fields:4] firstObject];
118  XCTAssertNotNil(field2);
119  XCTAssertEqualObjects(field1, field2);
120  XCTAssertTrue(field1 != field2);  // Different objects.
121  XCTAssertEqual([field1 hash], [field2 hash]);
122
123  // Group
124
125  GPBUnknownFields* group1 = [ufs1 addGroupWithFieldNumber:5];
126  [group1 addFieldNumber:10 varint:10];
127  XCTAssertNotEqualObjects(ufs1, ufs2);
128  GPBUnknownFields* group2 = [ufs2 addGroupWithFieldNumber:5];
129  [group2 addFieldNumber:10 varint:10];
130  XCTAssertEqualObjects(ufs1, ufs2);
131  XCTAssertEqual([ufs1 hash], [ufs2 hash]);
132  field1 = [[ufs1 fields:5] firstObject];
133  XCTAssertNotNil(field1);
134  field2 = [[ufs2 fields:5] firstObject];
135  XCTAssertNotNil(field2);
136  XCTAssertEqualObjects(field1, field2);
137  XCTAssertTrue(field1 != field2);  // Different objects.
138  XCTAssertEqual([field1 hash], [field2 hash]);
139}
140
141- (void)testInequality_Values {
142  // Same field number and type, different values.
143
144  // This also calls the methods on the `GPBUnknownField` objects for completeness and to
145  // make any failure in that class easier to notice/debug.
146
147  GPBUnknownFields* ufs1 = [[[GPBUnknownFields alloc] init] autorelease];
148  GPBUnknownFields* ufs2 = [[[GPBUnknownFields alloc] init] autorelease];
149
150  [ufs1 addFieldNumber:1 varint:1];
151  [ufs2 addFieldNumber:1 varint:2];
152  XCTAssertNotEqualObjects(ufs1, ufs2);
153  GPBUnknownField* field1 = [[ufs1 fields:1] firstObject];
154  XCTAssertNotNil(field1);
155  GPBUnknownField* field2 = [[ufs2 fields:1] firstObject];
156  XCTAssertNotNil(field2);
157  XCTAssertNotEqualObjects(field1, field2);
158  XCTAssertTrue(field1 != field2);  // Different objects.
159
160  [ufs1 clear];
161  [ufs2 clear];
162  XCTAssertEqualObjects(ufs1, ufs2);
163
164  [ufs1 addFieldNumber:1 fixed32:1];
165  [ufs2 addFieldNumber:1 fixed32:2];
166  XCTAssertNotEqualObjects(ufs1, ufs2);
167  field1 = [[ufs1 fields:1] firstObject];
168  XCTAssertNotNil(field1);
169  field2 = [[ufs2 fields:1] firstObject];
170  XCTAssertNotNil(field2);
171  XCTAssertNotEqualObjects(field1, field2);
172  XCTAssertTrue(field1 != field2);  // Different objects.
173
174  [ufs1 clear];
175  [ufs2 clear];
176  XCTAssertEqualObjects(ufs1, ufs2);
177
178  [ufs1 addFieldNumber:1 fixed64:1];
179  [ufs2 addFieldNumber:1 fixed64:2];
180  XCTAssertNotEqualObjects(ufs1, ufs2);
181  field1 = [[ufs1 fields:1] firstObject];
182  XCTAssertNotNil(field1);
183  field2 = [[ufs2 fields:1] firstObject];
184  XCTAssertNotNil(field2);
185  XCTAssertNotEqualObjects(field1, field2);
186  XCTAssertTrue(field1 != field2);  // Different objects.
187
188  [ufs1 clear];
189  [ufs2 clear];
190  XCTAssertEqualObjects(ufs1, ufs2);
191
192  [ufs1 addFieldNumber:1 lengthDelimited:DataFromCStr("foo")];
193  [ufs2 addFieldNumber:1 lengthDelimited:DataFromCStr("bar")];
194  XCTAssertNotEqualObjects(ufs1, ufs2);
195  field1 = [[ufs1 fields:1] firstObject];
196  XCTAssertNotNil(field1);
197  field2 = [[ufs2 fields:1] firstObject];
198  XCTAssertNotNil(field2);
199  XCTAssertNotEqualObjects(field1, field2);
200  XCTAssertTrue(field1 != field2);  // Different objects.
201
202  [ufs1 clear];
203  [ufs2 clear];
204  XCTAssertEqualObjects(ufs1, ufs2);
205
206  GPBUnknownFields* group1 = [ufs1 addGroupWithFieldNumber:1];
207  GPBUnknownFields* group2 = [ufs2 addGroupWithFieldNumber:1];
208  [group1 addFieldNumber:10 varint:10];
209  [group2 addFieldNumber:10 varint:20];
210  XCTAssertNotEqualObjects(ufs1, ufs2);
211  XCTAssertNotEqualObjects(group1, group2);
212  field1 = [[ufs1 fields:1] firstObject];
213  XCTAssertNotNil(field1);
214  field2 = [[ufs2 fields:1] firstObject];
215  XCTAssertNotNil(field2);
216  XCTAssertNotEqualObjects(field1, field2);
217  XCTAssertTrue(field1 != field2);  // Different objects.
218}
219
220- (void)testInequality_FieldNumbers {
221  // Same type and value, different field numbers.
222
223  // This also calls the methods on the `GPBUnknownField` objects for completeness and to
224  // make any failure in that class easier to notice/debug.
225
226  GPBUnknownFields* ufs1 = [[[GPBUnknownFields alloc] init] autorelease];
227  GPBUnknownFields* ufs2 = [[[GPBUnknownFields alloc] init] autorelease];
228
229  [ufs1 addFieldNumber:1 varint:1];
230  [ufs2 addFieldNumber:2 varint:1];
231  XCTAssertNotEqualObjects(ufs1, ufs2);
232  GPBUnknownField* field1 = [[ufs1 fields:1] firstObject];
233  XCTAssertNotNil(field1);
234  GPBUnknownField* field2 = [[ufs2 fields:2] firstObject];
235  XCTAssertNotNil(field2);
236  XCTAssertNotEqualObjects(field1, field2);
237  XCTAssertTrue(field1 != field2);  // Different objects.
238
239  [ufs1 clear];
240  [ufs2 clear];
241  XCTAssertEqualObjects(ufs1, ufs2);
242
243  [ufs1 addFieldNumber:1 fixed32:1];
244  [ufs2 addFieldNumber:2 fixed32:1];
245  XCTAssertNotEqualObjects(ufs1, ufs2);
246  field1 = [[ufs1 fields:1] firstObject];
247  XCTAssertNotNil(field1);
248  field2 = [[ufs2 fields:2] firstObject];
249  XCTAssertNotNil(field2);
250  XCTAssertNotEqualObjects(field1, field2);
251  XCTAssertTrue(field1 != field2);  // Different objects.
252
253  [ufs1 clear];
254  [ufs2 clear];
255  XCTAssertEqualObjects(ufs1, ufs2);
256
257  [ufs1 addFieldNumber:1 fixed64:1];
258  [ufs2 addFieldNumber:2 fixed64:1];
259  XCTAssertNotEqualObjects(ufs1, ufs2);
260  field1 = [[ufs1 fields:1] firstObject];
261  XCTAssertNotNil(field1);
262  field2 = [[ufs2 fields:2] firstObject];
263  XCTAssertNotNil(field2);
264  XCTAssertNotEqualObjects(field1, field2);
265  XCTAssertTrue(field1 != field2);  // Different objects.
266
267  [ufs1 clear];
268  [ufs2 clear];
269  XCTAssertEqualObjects(ufs1, ufs2);
270
271  [ufs1 addFieldNumber:1 lengthDelimited:DataFromCStr("foo")];
272  [ufs2 addFieldNumber:2 lengthDelimited:DataFromCStr("fod")];
273  XCTAssertNotEqualObjects(ufs1, ufs2);
274  field1 = [[ufs1 fields:1] firstObject];
275  XCTAssertNotNil(field1);
276  field2 = [[ufs2 fields:2] firstObject];
277  XCTAssertNotNil(field2);
278  XCTAssertNotEqualObjects(field1, field2);
279  XCTAssertTrue(field1 != field2);  // Different objects.
280
281  [ufs1 clear];
282  [ufs2 clear];
283  XCTAssertEqualObjects(ufs1, ufs2);
284
285  GPBUnknownFields* group1 = [ufs1 addGroupWithFieldNumber:1];
286  GPBUnknownFields* group2 = [ufs2 addGroupWithFieldNumber:2];
287  [group1 addFieldNumber:10 varint:10];
288  [group2 addFieldNumber:10 varint:10];
289  XCTAssertNotEqualObjects(ufs1, ufs2);
290  XCTAssertEqualObjects(group1, group2);
291  field1 = [[ufs1 fields:1] firstObject];
292  XCTAssertNotNil(field1);
293  field2 = [[ufs2 fields:2] firstObject];
294  XCTAssertNotNil(field2);
295  XCTAssertNotEqualObjects(field1, field2);
296  XCTAssertTrue(field1 != field2);  // Different objects.
297}
298
299- (void)testInequality_Types {
300  // Same field number and value when possible, different types.
301
302  // This also calls the methods on the `GPBUnknownField` objects for completeness and to
303  // make any failure in that class easier to notice/debug.
304
305  GPBUnknownFields* ufs1 = [[[GPBUnknownFields alloc] init] autorelease];
306  GPBUnknownFields* ufs2 = [[[GPBUnknownFields alloc] init] autorelease];
307
308  [ufs1 addFieldNumber:1 varint:1];
309  [ufs2 addFieldNumber:1 fixed32:1];
310  XCTAssertNotEqualObjects(ufs1, ufs2);
311  GPBUnknownField* field1 = [[ufs1 fields:1] firstObject];
312  XCTAssertNotNil(field1);
313  GPBUnknownField* field2 = [[ufs2 fields:1] firstObject];
314  XCTAssertNotNil(field2);
315  XCTAssertNotEqualObjects(field1, field2);
316  XCTAssertTrue(field1 != field2);  // Different objects.
317
318  [ufs1 clear];
319  [ufs2 clear];
320  XCTAssertEqualObjects(ufs1, ufs2);
321
322  [ufs1 addFieldNumber:1 fixed32:1];
323  [ufs2 addFieldNumber:1 fixed64:1];
324  XCTAssertNotEqualObjects(ufs1, ufs2);
325  field1 = [[ufs1 fields:1] firstObject];
326  XCTAssertNotNil(field1);
327  field2 = [[ufs2 fields:1] firstObject];
328  XCTAssertNotNil(field2);
329  XCTAssertNotEqualObjects(field1, field2);
330  XCTAssertTrue(field1 != field2);  // Different objects.
331
332  [ufs1 clear];
333  [ufs2 clear];
334  XCTAssertEqualObjects(ufs1, ufs2);
335
336  [ufs1 addFieldNumber:1 fixed64:1];
337  [ufs2 addFieldNumber:1 varint:1];
338  XCTAssertNotEqualObjects(ufs1, ufs2);
339  field1 = [[ufs1 fields:1] firstObject];
340  XCTAssertNotNil(field1);
341  field2 = [[ufs2 fields:1] firstObject];
342  XCTAssertNotNil(field2);
343  XCTAssertNotEqualObjects(field1, field2);
344  XCTAssertTrue(field1 != field2);  // Different objects.
345
346  [ufs1 clear];
347  [ufs2 clear];
348  XCTAssertEqualObjects(ufs1, ufs2);
349
350  [ufs1 addFieldNumber:1 lengthDelimited:DataFromCStr("foo")];
351  [ufs2 addFieldNumber:1 varint:1];
352  XCTAssertNotEqualObjects(ufs1, ufs2);
353  field1 = [[ufs1 fields:1] firstObject];
354  XCTAssertNotNil(field1);
355  field2 = [[ufs2 fields:1] firstObject];
356  XCTAssertNotNil(field2);
357  XCTAssertNotEqualObjects(field1, field2);
358  XCTAssertTrue(field1 != field2);  // Different objects.
359
360  [ufs1 clear];
361  [ufs2 clear];
362  XCTAssertEqualObjects(ufs1, ufs2);
363
364  GPBUnknownFields* group1 = [ufs1 addGroupWithFieldNumber:1];
365  [group1 addFieldNumber:10 varint:10];
366  [ufs2 addFieldNumber:1 varint:1];
367  XCTAssertNotEqualObjects(ufs1, ufs2);
368  field1 = [[ufs1 fields:1] firstObject];
369  XCTAssertNotNil(field1);
370  field2 = [[ufs2 fields:1] firstObject];
371  XCTAssertNotNil(field2);
372  XCTAssertNotEqualObjects(field1, field2);
373  XCTAssertTrue(field1 != field2);  // Different objects.
374}
375
376- (void)testGetFirst {
377  GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
378  XCTAssertEqual(0U, ufs.count);
379  [ufs addFieldNumber:1 varint:1];
380  XCTAssertEqual(1U, ufs.count);
381  [ufs addFieldNumber:1 varint:2];
382  XCTAssertEqual(2U, ufs.count);
383  [ufs addFieldNumber:1 fixed32:3];
384  XCTAssertEqual(3U, ufs.count);
385  [ufs addFieldNumber:1 fixed32:4];
386  XCTAssertEqual(4U, ufs.count);
387  [ufs addFieldNumber:1 fixed64:5];
388  XCTAssertEqual(5U, ufs.count);
389  [ufs addFieldNumber:1 fixed64:6];
390  XCTAssertEqual(6U, ufs.count);
391  [ufs addFieldNumber:1 lengthDelimited:DataFromCStr("foo")];
392  XCTAssertEqual(7U, ufs.count);
393  [ufs addFieldNumber:1 lengthDelimited:DataFromCStr("bar")];
394  XCTAssertEqual(8U, ufs.count);
395  GPBUnknownFields* group1 = [ufs addGroupWithFieldNumber:1];
396  XCTAssertNotNil(group1);
397  XCTAssertEqual(9U, ufs.count);
398  GPBUnknownFields* group2 = [ufs addGroupWithFieldNumber:1];
399  XCTAssertNotNil(group2);
400  XCTAssertTrue(group1 != group2);  // Different objects
401  XCTAssertEqual(10U, ufs.count);
402
403  [ufs addFieldNumber:11 varint:11];
404  [ufs addFieldNumber:12 fixed32:12];
405  [ufs addFieldNumber:13 fixed64:13];
406  [ufs addFieldNumber:14 lengthDelimited:DataFromCStr("foo2")];
407  GPBUnknownFields* group3 = [ufs addGroupWithFieldNumber:15];
408  XCTAssertNotNil(group3);
409  XCTAssertTrue(group3 != group1);  // Different objects
410  XCTAssertTrue(group3 != group2);  // Different objects
411  XCTAssertEqual(15U, ufs.count);
412
413  uint64_t varint = 0;
414  XCTAssertTrue([ufs getFirst:1 varint:&varint]);
415  XCTAssertEqual(1U, varint);
416  XCTAssertTrue([ufs getFirst:11 varint:&varint]);
417  XCTAssertEqual(11U, varint);
418  XCTAssertFalse([ufs getFirst:12 varint:&varint]);  // Different type
419  XCTAssertFalse([ufs getFirst:99 varint:&varint]);  // Not present
420
421  uint32_t fixed32 = 0;
422  XCTAssertTrue([ufs getFirst:1 fixed32:&fixed32]);
423  XCTAssertEqual(3U, fixed32);
424  XCTAssertTrue([ufs getFirst:12 fixed32:&fixed32]);
425  XCTAssertEqual(12U, fixed32);
426  XCTAssertFalse([ufs getFirst:11 fixed32:&fixed32]);  // Different type
427  XCTAssertFalse([ufs getFirst:99 fixed32:&fixed32]);  // Not present
428
429  uint64_t fixed64 = 0;
430  XCTAssertTrue([ufs getFirst:1 fixed64:&fixed64]);
431  XCTAssertEqual(5U, fixed64);
432  XCTAssertTrue([ufs getFirst:13 fixed64:&fixed64]);
433  XCTAssertEqual(13U, fixed64);
434  XCTAssertFalse([ufs getFirst:11 fixed64:&fixed64]);  // Different type
435  XCTAssertFalse([ufs getFirst:99 fixed64:&fixed64]);  // Not present
436
437  XCTAssertEqualObjects(DataFromCStr("foo"), [ufs firstLengthDelimited:1]);
438  XCTAssertEqualObjects(DataFromCStr("foo2"), [ufs firstLengthDelimited:14]);
439  XCTAssertNil([ufs firstLengthDelimited:11]);  // Different type
440  XCTAssertNil([ufs firstLengthDelimited:99]);  // Not present
441
442  XCTAssertTrue(group1 == [ufs firstGroup:1]);   // Testing ptr, exact object
443  XCTAssertTrue(group3 == [ufs firstGroup:15]);  // Testing ptr, exact object
444  XCTAssertNil([ufs firstGroup:11]);             // Different type
445  XCTAssertNil([ufs firstGroup:99]);             // Not present
446}
447
448- (void)testGetFields {
449  GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
450  [ufs addFieldNumber:1 varint:1];
451  [ufs addFieldNumber:2 varint:2];
452  [ufs addFieldNumber:1 fixed32:3];
453  [ufs addFieldNumber:2 fixed32:4];
454  [ufs addFieldNumber:1 fixed64:5];
455  [ufs addFieldNumber:3 fixed64:6];
456  [ufs addFieldNumber:1 lengthDelimited:DataFromCStr("foo")];
457  [ufs addFieldNumber:2 lengthDelimited:DataFromCStr("bar")];
458  GPBUnknownFields* group1 = [ufs addGroupWithFieldNumber:1];
459  GPBUnknownFields* group2 = [ufs addGroupWithFieldNumber:3];
460
461  NSArray<GPBUnknownField*>* fields1 = [ufs fields:1];
462  XCTAssertEqual(fields1.count, 5);
463  GPBUnknownField* field = fields1[0];
464  XCTAssertEqual(field.number, 1);
465  XCTAssertEqual(field.type, GPBUnknownFieldTypeVarint);
466  XCTAssertEqual(field.varint, 1);
467  field = fields1[1];
468  XCTAssertEqual(field.number, 1);
469  XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed32);
470  XCTAssertEqual(field.fixed32, 3);
471  field = fields1[2];
472  XCTAssertEqual(field.number, 1);
473  XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed64);
474  XCTAssertEqual(field.fixed64, 5);
475  field = fields1[3];
476  XCTAssertEqual(field.number, 1);
477  XCTAssertEqual(field.type, GPBUnknownFieldTypeLengthDelimited);
478  XCTAssertEqualObjects(field.lengthDelimited, DataFromCStr("foo"));
479  field = fields1[4];
480  XCTAssertEqual(field.number, 1);
481  XCTAssertEqual(field.type, GPBUnknownFieldTypeGroup);
482  XCTAssertTrue(field.group == group1);  // Exact object.
483
484  NSArray<GPBUnknownField*>* fields2 = [ufs fields:2];
485  XCTAssertEqual(fields2.count, 3);
486  field = fields2[0];
487  XCTAssertEqual(field.number, 2);
488  XCTAssertEqual(field.type, GPBUnknownFieldTypeVarint);
489  XCTAssertEqual(field.varint, 2);
490  field = fields2[1];
491  XCTAssertEqual(field.number, 2);
492  XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed32);
493  XCTAssertEqual(field.fixed32, 4);
494  field = fields2[2];
495  XCTAssertEqual(field.number, 2);
496  XCTAssertEqual(field.type, GPBUnknownFieldTypeLengthDelimited);
497  XCTAssertEqualObjects(field.lengthDelimited, DataFromCStr("bar"));
498
499  NSArray<GPBUnknownField*>* fields3 = [ufs fields:3];
500  XCTAssertEqual(fields3.count, 2);
501  field = fields3[0];
502  XCTAssertEqual(field.number, 3);
503  XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed64);
504  XCTAssertEqual(field.fixed64, 6);
505  field = fields3[1];
506  XCTAssertEqual(field.number, 3);
507  XCTAssertEqual(field.type, GPBUnknownFieldTypeGroup);
508  XCTAssertTrue(field.group == group2);  // Exact object.
509
510  XCTAssertNil([ufs fields:99]);  // Not present
511}
512
513- (void)testRemoveField {
514  GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
515  [ufs addFieldNumber:1 varint:1];
516  [ufs addFieldNumber:1 fixed32:1];
517  [ufs addFieldNumber:1 fixed64:1];
518  XCTAssertEqual(ufs.count, 3);
519
520  NSArray<GPBUnknownField*>* fields = [ufs fields:1];
521  XCTAssertEqual(fields.count, 3);
522  GPBUnknownField* field = fields[0];
523  XCTAssertEqual(field.number, 1);
524  XCTAssertEqual(field.type, GPBUnknownFieldTypeVarint);
525  XCTAssertEqual(field.varint, 1);
526  [ufs removeField:field];  // Remove first (varint)
527  XCTAssertEqual(ufs.count, 2);
528
529  fields = [ufs fields:1];
530  XCTAssertEqual(fields.count, 2);
531  field = fields[0];
532  XCTAssertEqual(field.number, 1);
533  XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed32);
534  field = fields[1];
535  XCTAssertEqual(field.number, 1);
536  XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed64);
537  [ufs removeField:field];  // Remove the second (fixed64)
538  XCTAssertEqual(ufs.count, 1);
539
540  fields = [ufs fields:1];
541  XCTAssertEqual(fields.count, 1);
542  field = fields[0];
543  XCTAssertEqual(field.number, 1);
544  XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed32);
545
546  field = [[field retain] autorelease];  // Hold on to this last one.
547  [ufs removeField:field];               // Remove the last one (fixed32)
548  XCTAssertEqual(ufs.count, 0);
549
550  // Trying to remove something not in the set should fail.
551  XCTAssertThrowsSpecificNamed([ufs removeField:field], NSException, NSInvalidArgumentException);
552}
553
554- (void)testClearFieldNumber {
555  GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
556  [ufs addFieldNumber:1 varint:1];
557  [ufs addFieldNumber:2 fixed32:2];
558  [ufs addFieldNumber:1 fixed64:1];
559  [ufs addFieldNumber:3 varint:3];
560  XCTAssertEqual(ufs.count, 4);
561
562  [ufs clearFieldNumber:999];  // Not present, noop.
563  XCTAssertEqual(ufs.count, 4);
564
565  [ufs clearFieldNumber:1];  // Should remove slot zero and slot two.
566  XCTAssertEqual(ufs.count, 2);
567  NSArray<GPBUnknownField*>* fields = [ufs fields:2];
568  XCTAssertEqual(fields.count, 1);
569  GPBUnknownField* field = fields[0];
570  XCTAssertEqual(field.number, 2);
571  XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed32);
572  XCTAssertEqual(field.fixed32, 2);
573  fields = [ufs fields:3];
574  XCTAssertEqual(fields.count, 1);
575  field = fields[0];
576  XCTAssertEqual(field.number, 3);
577  XCTAssertEqual(field.type, GPBUnknownFieldTypeVarint);
578  XCTAssertEqual(field.varint, 3);
579
580  [ufs clearFieldNumber:2];  // Should remove slot one.
581  fields = [ufs fields:3];
582  XCTAssertEqual(fields.count, 1);
583  field = fields[0];
584  XCTAssertEqual(field.number, 3);
585  XCTAssertEqual(field.type, GPBUnknownFieldTypeVarint);
586  XCTAssertEqual(field.varint, 3);
587}
588
589- (void)testFastEnumeration {
590  GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
591  [ufs addFieldNumber:1 varint:1];
592  [ufs addFieldNumber:2 varint:2];
593  [ufs addFieldNumber:1 fixed32:3];
594  [ufs addFieldNumber:2 fixed32:4];
595  [ufs addFieldNumber:1 fixed64:5];
596  [ufs addFieldNumber:3 fixed64:6];
597  [ufs addFieldNumber:1 lengthDelimited:DataFromCStr("foo")];
598  [ufs addFieldNumber:2 lengthDelimited:DataFromCStr("bar")];
599  GPBUnknownFields* group1 = [ufs addGroupWithFieldNumber:1];
600  GPBUnknownFields* group2 = [ufs addGroupWithFieldNumber:3];
601
602  // The order added nothing to do with field numbers.
603  NSInteger loop = 0;
604  for (GPBUnknownField* field in ufs) {
605    ++loop;
606    switch (loop) {
607      case 1:
608        XCTAssertEqual(field.number, 1);
609        XCTAssertEqual(field.type, GPBUnknownFieldTypeVarint);
610        XCTAssertEqual(field.varint, 1);
611        break;
612      case 2:
613        XCTAssertEqual(field.number, 2);
614        XCTAssertEqual(field.type, GPBUnknownFieldTypeVarint);
615        XCTAssertEqual(field.varint, 2);
616        break;
617      case 3:
618        XCTAssertEqual(field.number, 1);
619        XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed32);
620        XCTAssertEqual(field.fixed32, 3);
621        break;
622      case 4:
623        XCTAssertEqual(field.number, 2);
624        XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed32);
625        XCTAssertEqual(field.fixed32, 4);
626        break;
627      case 5:
628        XCTAssertEqual(field.number, 1);
629        XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed64);
630        XCTAssertEqual(field.fixed64, 5);
631        break;
632      case 6:
633        XCTAssertEqual(field.number, 3);
634        XCTAssertEqual(field.type, GPBUnknownFieldTypeFixed64);
635        XCTAssertEqual(field.fixed64, 6);
636        break;
637      case 7:
638        XCTAssertEqual(field.number, 1);
639        XCTAssertEqual(field.type, GPBUnknownFieldTypeLengthDelimited);
640        XCTAssertEqualObjects(field.lengthDelimited, DataFromCStr("foo"));
641        break;
642      case 8:
643        XCTAssertEqual(field.number, 2);
644        XCTAssertEqual(field.type, GPBUnknownFieldTypeLengthDelimited);
645        XCTAssertEqualObjects(field.lengthDelimited, DataFromCStr("bar"));
646        break;
647      case 9:
648        XCTAssertEqual(field.number, 1);
649        XCTAssertEqual(field.type, GPBUnknownFieldTypeGroup);
650        XCTAssertTrue(field.group == group1);  // Exact object.
651        break;
652      case 10:
653        XCTAssertEqual(field.number, 3);
654        XCTAssertEqual(field.type, GPBUnknownFieldTypeGroup);
655        XCTAssertTrue(field.group == group2);  // Exact object.
656        break;
657      default:
658        XCTFail(@"Unexpected");
659        break;
660    }
661  }
662  XCTAssertEqual(loop, 10);
663}
664
665- (void)testAddCopyOfField {
666  GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
667  [ufs addFieldNumber:1 varint:10];
668  [ufs addFieldNumber:2 fixed32:11];
669  [ufs addFieldNumber:3 fixed64:12];
670  [ufs addFieldNumber:4 lengthDelimited:DataFromCStr("foo")];
671  GPBUnknownFields* group = [ufs addGroupWithFieldNumber:5];
672  [group addFieldNumber:10 varint:100];
673  GPBUnknownFields* subGroup = [group addGroupWithFieldNumber:100];
674  [subGroup addFieldNumber:50 varint:50];
675
676  GPBUnknownFields* ufs2 = [[[GPBUnknownFields alloc] init] autorelease];
677  for (GPBUnknownField* field in ufs) {
678    GPBUnknownField* field2 = [ufs2 addCopyOfField:field];
679    XCTAssertEqualObjects(field, field2);
680    if (field.type == GPBUnknownFieldTypeGroup) {
681      // Group does a copy because the `.group` value is mutable.
682      XCTAssertTrue(field != field2);        // Pointer comparison.
683      XCTAssertTrue(group != field2.group);  // Pointer comparison.
684      XCTAssertEqualObjects(group, field2.group);
685      GPBUnknownFields* subGroupAdded = [field2.group firstGroup:100];
686      XCTAssertTrue(subGroupAdded != subGroup);  // Pointer comparison.
687      XCTAssertEqualObjects(subGroupAdded, subGroup);
688    } else {
689      // All other types are immutable, so they use the same object.
690      XCTAssertTrue(field == field2);  // Pointer comparision.
691    }
692  }
693  XCTAssertEqualObjects(ufs, ufs2);
694}
695
696- (void)testDescriptions {
697  // Exercise description for completeness.
698  GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
699  [ufs addFieldNumber:1 varint:1];
700  [ufs addFieldNumber:2 fixed32:1];
701  [ufs addFieldNumber:1 fixed64:1];
702  [ufs addFieldNumber:4 lengthDelimited:DataFromCStr("foo")];
703  [[ufs addGroupWithFieldNumber:5] addFieldNumber:10 varint:10];
704  XCTAssertTrue(ufs.description.length > 10);
705  for (GPBUnknownField* field in ufs) {
706    XCTAssertTrue(field.description.length > 10);
707  }
708}
709
710- (void)testCopy {
711  GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
712  [ufs addFieldNumber:1 varint:1];
713  [ufs addFieldNumber:2 fixed32:2];
714  [ufs addFieldNumber:3 fixed64:3];
715  [ufs addFieldNumber:4 lengthDelimited:DataFromCStr("foo")];
716  GPBUnknownFields* group = [ufs addGroupWithFieldNumber:5];
717  [group addFieldNumber:10 varint:10];
718  GPBUnknownFields* subGroup = [group addGroupWithFieldNumber:100];
719  [subGroup addFieldNumber:20 varint:20];
720
721  GPBUnknownFields* ufs2 = [[ufs copy] autorelease];
722  XCTAssertTrue(ufs != ufs2);        // Different objects
723  XCTAssertEqualObjects(ufs, ufs2);  // Equal contents
724  // All field objects but the group should be the same since they are immutable.
725  XCTAssertTrue([[ufs fields:1] firstObject] == [[ufs2 fields:1] firstObject]);  // Same object
726  XCTAssertTrue([[ufs fields:2] firstObject] == [[ufs2 fields:2] firstObject]);  // Same object
727  XCTAssertTrue([[ufs fields:3] firstObject] == [[ufs2 fields:3] firstObject]);  // Same object
728  XCTAssertTrue([[ufs fields:4] firstObject] == [[ufs2 fields:4] firstObject]);  // Same object
729  XCTAssertTrue([[ufs fields:4] firstObject].lengthDelimited ==
730                [[ufs2 fields:4] firstObject].lengthDelimited);  // Same object
731  // Since the group holds another `GPBUnknownFields` object (which is mutable), it will be a
732  // different object.
733  XCTAssertTrue([[ufs fields:5] firstObject] != [[ufs2 fields:5] firstObject]);
734  XCTAssertTrue(group != [[ufs2 fields:5] firstObject].group);
735  XCTAssertEqualObjects(group, [[ufs2 fields:5] firstObject].group);
736  // And confirm that copy went deep so the nested group also is a different object.
737  GPBUnknownFields* groupCopied = [[ufs2 fields:5] firstObject].group;
738  XCTAssertTrue([[group fields:100] firstObject] != [[groupCopied fields:100] firstObject]);
739  XCTAssertTrue(subGroup != [[groupCopied fields:100] firstObject].group);
740  XCTAssertEqualObjects(subGroup, [[groupCopied fields:100] firstObject].group);
741}
742
743- (void)testInvalidFieldNumbers {
744  GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
745
746  XCTAssertThrowsSpecificNamed([ufs addFieldNumber:0 varint:1], NSException,
747                               NSInvalidArgumentException);
748  XCTAssertThrowsSpecificNamed([ufs addFieldNumber:0 fixed32:1], NSException,
749                               NSInvalidArgumentException);
750  XCTAssertThrowsSpecificNamed([ufs addFieldNumber:0 fixed64:1], NSException,
751                               NSInvalidArgumentException);
752  XCTAssertThrowsSpecificNamed([ufs addFieldNumber:0 lengthDelimited:[NSData data]], NSException,
753                               NSInvalidArgumentException);
754  XCTAssertThrowsSpecificNamed([ufs addGroupWithFieldNumber:0], NSException,
755                               NSInvalidArgumentException);
756
757  XCTAssertThrowsSpecificNamed([ufs addFieldNumber:-1 varint:1], NSException,
758                               NSInvalidArgumentException);
759  XCTAssertThrowsSpecificNamed([ufs addFieldNumber:-1 fixed32:1], NSException,
760                               NSInvalidArgumentException);
761  XCTAssertThrowsSpecificNamed([ufs addFieldNumber:-1 fixed64:1], NSException,
762                               NSInvalidArgumentException);
763  XCTAssertThrowsSpecificNamed([ufs addFieldNumber:-1 lengthDelimited:[NSData data]], NSException,
764                               NSInvalidArgumentException);
765  XCTAssertThrowsSpecificNamed([ufs addGroupWithFieldNumber:-1], NSException,
766                               NSInvalidArgumentException);
767
768  uint64_t varint;
769  uint32_t fixed32;
770  uint64_t fixed64;
771  XCTAssertThrowsSpecificNamed([ufs getFirst:0 varint:&varint], NSException,
772                               NSInvalidArgumentException);
773  XCTAssertThrowsSpecificNamed([ufs getFirst:0 fixed32:&fixed32], NSException,
774                               NSInvalidArgumentException);
775  XCTAssertThrowsSpecificNamed([ufs getFirst:0 fixed64:&fixed64], NSException,
776                               NSInvalidArgumentException);
777  XCTAssertThrowsSpecificNamed([ufs firstLengthDelimited:0], NSException,
778                               NSInvalidArgumentException);
779  XCTAssertThrowsSpecificNamed([ufs firstGroup:0], NSException, NSInvalidArgumentException);
780
781  XCTAssertThrowsSpecificNamed([ufs getFirst:-1 varint:&varint], NSException,
782                               NSInvalidArgumentException);
783  XCTAssertThrowsSpecificNamed([ufs getFirst:-1 fixed32:&fixed32], NSException,
784                               NSInvalidArgumentException);
785  XCTAssertThrowsSpecificNamed([ufs getFirst:-1 fixed64:&fixed64], NSException,
786                               NSInvalidArgumentException);
787  XCTAssertThrowsSpecificNamed([ufs firstLengthDelimited:-1], NSException,
788                               NSInvalidArgumentException);
789  XCTAssertThrowsSpecificNamed([ufs firstGroup:-1], NSException, NSInvalidArgumentException);
790  XCTAssertThrowsSpecificNamed([ufs fields:0], NSException, NSInvalidArgumentException);
791  XCTAssertThrowsSpecificNamed([ufs fields:-1], NSException, NSInvalidArgumentException);
792}
793
794- (void)testSerialize {
795  // Don't need to test CodedOutputStream, just make sure things basically end up there.
796  {
797    GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
798    XCTAssertEqualObjects([ufs serializeAsData], [NSData data]);
799  }
800  {
801    GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
802    [ufs addFieldNumber:1 varint:1];
803    XCTAssertEqualObjects([ufs serializeAsData], DataFromBytes(0x08, 0x01));
804  }
805  {
806    GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
807    [ufs addFieldNumber:1 fixed32:1];
808    XCTAssertEqualObjects([ufs serializeAsData], DataFromBytes(0x0d, 0x01, 0x00, 0x00, 0x00));
809  }
810  {
811    GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
812    [ufs addFieldNumber:1 fixed64:1];
813    XCTAssertEqualObjects([ufs serializeAsData],
814                          DataFromBytes(0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00));
815  }
816  {
817    GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
818    [ufs addFieldNumber:1 lengthDelimited:DataFromCStr("foo")];
819    XCTAssertEqualObjects([ufs serializeAsData], DataFromBytes(0x0a, 0x03, 0x66, 0x6f, 0x6f));
820  }
821  {
822    GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
823    [ufs addGroupWithFieldNumber:1];  // Empty group
824    XCTAssertEqualObjects([ufs serializeAsData], DataFromBytes(0x0b, 0x0c));
825  }
826  {
827    GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
828    GPBUnknownFields* group = [ufs addGroupWithFieldNumber:1];  // With some fields
829    [group addFieldNumber:10 varint:10];
830    [group addFieldNumber:11 fixed32:32];
831    [group addFieldNumber:12 fixed32:32];
832    XCTAssertEqualObjects([ufs serializeAsData],
833                          DataFromBytes(0x0b, 0x50, 0x0a, 0x5d, 0x20, 0x00, 0x00, 0x00, 0x65, 0x20,
834                                        0x00, 0x00, 0x00, 0x0c));
835  }
836}
837
838- (void)testMessageMergeUnknowns {
839  GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
840  [ufs addFieldNumber:TestAllTypes_FieldNumber_OptionalInt64 varint:100];
841  [ufs addFieldNumber:TestAllTypes_FieldNumber_OptionalFixed32 fixed32:200];
842  [ufs addFieldNumber:TestAllTypes_FieldNumber_OptionalFixed64 fixed64:300];
843  [ufs addFieldNumber:TestAllTypes_FieldNumber_OptionalBytes lengthDelimited:DataFromCStr("foo")];
844  GPBUnknownFields* group = [ufs addGroupWithFieldNumber:TestAllTypes_FieldNumber_OptionalGroup];
845  [group addFieldNumber:TestAllTypes_OptionalGroup_FieldNumber_A varint:55];
846  [ufs addFieldNumber:123456 varint:4321];
847  [group addFieldNumber:123456 varint:5432];
848
849  TestAllTypes* msg = [TestAllTypes message];
850  XCTAssertTrue([msg mergeUnknownFields:ufs extensionRegistry:nil error:NULL]);
851  XCTAssertEqual(msg.optionalInt64, 100);
852  XCTAssertEqual(msg.optionalFixed32, 200);
853  XCTAssertEqual(msg.optionalFixed64, 300);
854  XCTAssertEqualObjects(msg.optionalBytes, DataFromCStr("foo"));
855  XCTAssertEqual(msg.optionalGroup.a, 55);
856  GPBUnknownFields* ufs2 = [[[GPBUnknownFields alloc] initFromMessage:msg] autorelease];
857  XCTAssertEqual(ufs2.count, 1);  // The unknown at the root
858  uint64_t varint = 0;
859  XCTAssertTrue([ufs2 getFirst:123456 varint:&varint]);
860  XCTAssertEqual(varint, 4321);
861  GPBUnknownFields* ufs2group =
862      [[[GPBUnknownFields alloc] initFromMessage:msg.optionalGroup] autorelease];
863  XCTAssertEqual(ufs2group.count, 1);  // The unknown at in group
864  XCTAssertTrue([ufs2group getFirst:123456 varint:&varint]);
865  XCTAssertEqual(varint, 5432);
866
867  TestEmptyMessage* emptyMessage = [TestEmptyMessage message];
868  XCTAssertTrue([emptyMessage mergeUnknownFields:ufs extensionRegistry:nil error:NULL]);
869  GPBUnknownFields* ufs3 = [[[GPBUnknownFields alloc] initFromMessage:emptyMessage] autorelease];
870  XCTAssertEqualObjects(ufs3, ufs);  // Round trip through an empty message got us same fields back.
871  XCTAssertTrue(ufs3 != ufs);        // But they are different objects.
872}
873
874- (void)testRoundTripLotsOfFields {
875  // Usage a message with everything, into an empty message to get a lot of unknown fields,
876  // and confirm it comes back to match.
877  TestAllTypes* allFields = [self allSetRepeatedCount:kGPBDefaultRepeatCount];
878  NSData* allFieldsData = [allFields data];
879  TestEmptyMessage* emptyMessage = [TestEmptyMessage parseFromData:allFieldsData error:NULL];
880  GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] initFromMessage:emptyMessage] autorelease];
881  TestAllTypes* allFields2 = [TestAllTypes message];
882  XCTAssertTrue([allFields2 mergeUnknownFields:ufs extensionRegistry:nil error:NULL]);
883  XCTAssertEqualObjects(allFields2, allFields);
884
885  // Confirm that the they still all end up in unknowns when parsed into a message with extensions
886  // support for the field numbers (but no registry).
887  {
888    TestEmptyMessageWithExtensions* msgWithExts =
889        [TestEmptyMessageWithExtensions parseFromData:allFieldsData error:NULL];
890    GPBUnknownFields* ufs2 = [[[GPBUnknownFields alloc] initFromMessage:msgWithExts] autorelease];
891    XCTAssertEqualObjects(ufs2, ufs);
892  }
893
894  // Sanity check that with the registry, they go into the extension fields.
895  {
896    TestAllExtensions* msgWithExts =
897        [TestAllExtensions parseFromData:allFieldsData
898                       extensionRegistry:[UnittestRoot extensionRegistry]
899                                   error:NULL];
900    GPBUnknownFields* ufs2 = [[[GPBUnknownFields alloc] initFromMessage:msgWithExts] autorelease];
901    XCTAssertEqual(ufs2.count, 0);
902  }
903}
904
905- (void)testMismatchedFieldTypes {
906  // Start with a valid set of field data, and map it into unknown fields.
907  TestAllTypes* allFields = [self allSetRepeatedCount:kGPBDefaultRepeatCount];
908  NSData* allFieldsData = [allFields data];
909  TestEmptyMessage* emptyMessage = [TestEmptyMessage parseFromData:allFieldsData error:NULL];
910  GPBUnknownFields* ufsRightTypes =
911      [[[GPBUnknownFields alloc] initFromMessage:emptyMessage] autorelease];
912
913  // Now build a new set of unknown fields where all the data types are wrong for the original
914  // fields.
915  GPBUnknownFields* ufsWrongTypes = [[[GPBUnknownFields alloc] init] autorelease];
916  for (GPBUnknownField* field in ufsRightTypes) {
917    if (field.type != GPBUnknownFieldTypeVarint) {
918      // Original field is not a varint, so use a varint.
919      [ufsWrongTypes addFieldNumber:field.number varint:1];
920    } else {
921      // Original field *is* a varint, so use something else.
922      [ufsWrongTypes addFieldNumber:field.number fixed32:1];
923    }
924  }
925
926  // Parse into a message with the field numbers, the wrong types should force everything into
927  // unknown fields again.
928  {
929    TestAllTypes* msg = [TestAllTypes message];
930    XCTAssertTrue([msg mergeUnknownFields:ufsWrongTypes extensionRegistry:nil error:NULL]);
931    GPBUnknownFields* ufs2 = [[[GPBUnknownFields alloc] initFromMessage:msg] autorelease];
932    XCTAssertFalse(ufs2.empty);
933    XCTAssertEqualObjects(ufs2, ufsWrongTypes);  // All back as unknown fields.
934  }
935
936  // Parse into a message with extension registiry, the wrong types should still force everything
937  // into unknown fields.
938  {
939    TestAllExtensions* msg = [TestAllExtensions message];
940    XCTAssertTrue([msg mergeUnknownFields:ufsWrongTypes
941                        extensionRegistry:[UnittestRoot extensionRegistry]
942                                    error:NULL]);
943    GPBUnknownFields* ufs2 = [[[GPBUnknownFields alloc] initFromMessage:msg] autorelease];
944    XCTAssertFalse(ufs2.empty);
945    XCTAssertEqualObjects(ufs2, ufsWrongTypes);  // All back as unknown fields.
946  }
947}
948
949- (void)testMergeFailures {
950  // Valid data, pushes to the fields just fine.
951  {
952    GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
953    [ufs addFieldNumber:TestAllTypes_FieldNumber_OptionalString
954        lengthDelimited:DataFromCStr("abc")];
955    [ufs addFieldNumber:TestAllTypes_FieldNumber_RepeatedInt32Array
956        lengthDelimited:DataFromBytes(0x01, 0x02)];
957    [ufs addFieldNumber:TestAllTypes_FieldNumber_RepeatedFixed32Array
958        lengthDelimited:DataFromBytes(0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00)];
959    [ufs addFieldNumber:TestAllTypes_FieldNumber_RepeatedFixed64Array
960        lengthDelimited:DataFromBytes(0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
961                                      0x00, 0x00, 0x00, 0x00, 0x00, 0x00)];
962    TestAllTypes* msg = [TestAllTypes message];
963    NSError* error = nil;
964    XCTAssertTrue([msg mergeUnknownFields:ufs extensionRegistry:nil error:&error]);
965    XCTAssertNil(error);
966    XCTAssertEqualObjects(msg.optionalString, @"abc");
967    XCTAssertEqual(msg.repeatedInt32Array.count, 2);
968    XCTAssertEqual([msg.repeatedInt32Array valueAtIndex:0], 1);
969    XCTAssertEqual([msg.repeatedInt32Array valueAtIndex:1], 2);
970    XCTAssertEqual(msg.repeatedFixed32Array.count, 2);
971    XCTAssertEqual([msg.repeatedFixed32Array valueAtIndex:0], 3);
972    XCTAssertEqual([msg.repeatedFixed32Array valueAtIndex:1], 4);
973    XCTAssertEqual(msg.repeatedFixed64Array.count, 2);
974    XCTAssertEqual([msg.repeatedFixed64Array valueAtIndex:0], 5);
975    XCTAssertEqual([msg.repeatedFixed64Array valueAtIndex:1], 6);
976  }
977
978  // Invalid UTF-8 causes a failure when pushed to the message.
979  {
980    GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
981    [ufs addFieldNumber:TestAllTypes_FieldNumber_OptionalString
982        lengthDelimited:DataFromBytes(0xC2, 0xF2, 0x0, 0x0, 0x0)];
983    TestAllTypes* msg = [TestAllTypes message];
984    NSError* error = nil;
985    XCTAssertFalse([msg mergeUnknownFields:ufs extensionRegistry:nil error:&error]);
986    XCTAssertNotNil(error);
987  }
988
989  // Invalid packed varint causes a failure when pushed to the message.
990  {
991    GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
992    [ufs addFieldNumber:TestAllTypes_FieldNumber_RepeatedInt32Array
993        lengthDelimited:DataFromBytes(0xff)];  // Invalid varint
994    TestAllTypes* msg = [TestAllTypes message];
995    NSError* error = nil;
996    XCTAssertFalse([msg mergeUnknownFields:ufs extensionRegistry:nil error:&error]);
997    XCTAssertNotNil(error);
998  }
999
1000  // Invalid packed fixed32 causes a failure when pushed to the message.
1001  {
1002    GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
1003    [ufs addFieldNumber:TestAllTypes_FieldNumber_RepeatedFixed32Array
1004        lengthDelimited:DataFromBytes(0x01, 0x00, 0x00)];  // Truncated fixed32
1005    TestAllTypes* msg = [TestAllTypes message];
1006    NSError* error = nil;
1007    XCTAssertFalse([msg mergeUnknownFields:ufs extensionRegistry:nil error:&error]);
1008    XCTAssertNotNil(error);
1009  }
1010
1011  // Invalid packed fixed64 causes a failure when pushed to the message.
1012  {
1013    GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
1014    [ufs addFieldNumber:TestAllTypes_FieldNumber_RepeatedFixed64Array
1015        lengthDelimited:DataFromBytes(0x01, 0x00, 0x00, 0x00, 0x00)];  // Truncated fixed64
1016    TestAllTypes* msg = [TestAllTypes message];
1017    NSError* error = nil;
1018    XCTAssertFalse([msg mergeUnknownFields:ufs extensionRegistry:nil error:&error]);
1019    XCTAssertNotNil(error);
1020  }
1021}
1022
1023- (void)testLargeVarint {
1024  GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] init] autorelease];
1025  [ufs addFieldNumber:1 varint:0x7FFFFFFFFFFFFFFFL];
1026
1027  TestEmptyMessage* emptyMessage = [TestEmptyMessage message];
1028  XCTAssertTrue([emptyMessage mergeUnknownFields:ufs extensionRegistry:nil error:NULL]);
1029
1030  GPBUnknownFields* ufsParsed =
1031      [[[GPBUnknownFields alloc] initFromMessage:emptyMessage] autorelease];
1032  XCTAssertEqual(ufsParsed.count, 1);
1033  uint64_t varint = 0;
1034  XCTAssertTrue([ufsParsed getFirst:1 varint:&varint]);
1035  XCTAssertEqual(varint, 0x7FFFFFFFFFFFFFFFL);
1036}
1037
1038static NSData* DataForGroupsOfDepth(NSUInteger depth) {
1039  NSMutableData* data = [NSMutableData dataWithCapacity:0];
1040
1041  uint32_t byte = 35;  // 35 = 0b100011 -> field 4/start group
1042  for (NSUInteger i = 0; i < depth; ++i) {
1043    [data appendBytes:&byte length:1];
1044  }
1045
1046  byte = 8;  // 8 = 0b1000, -> field 1/varint
1047  [data appendBytes:&byte length:1];
1048  byte = 1;  // 1 -> varint value of 1
1049  [data appendBytes:&byte length:1];
1050
1051  byte = 36;  // 36 = 0b100100 -> field 4/end group
1052  for (NSUInteger i = 0; i < depth; ++i) {
1053    [data appendBytes:&byte length:1];
1054  }
1055  return data;
1056}
1057
1058- (void)testParsingNestingGroupData {
1059  // 35 = 0b100011 -> field 4/start group
1060  // 36 = 0b100100 -> field 4/end group
1061  // 43 = 0b101011 -> field 5/end group
1062  // 44 = 0b101100 -> field 5/end group
1063  // 8 = 0b1000, 1 -> field 1/varint, value of 1
1064  // 21 = 0b10101, 0x78, 0x56, 0x34, 0x12 -> field 2/fixed32, value of 0x12345678
1065  // 25 = 0b11001, 0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12 -> field 3/fixed64,
1066  //                                                                 value of 0x123456789abcdef0LL
1067  // 50 = 0b110010, 0x0 -> field 6/length delimited, length 0
1068  // 50 = 0b110010, 0x1, 42 -> field 6/length delimited, length 1, byte 42
1069  // 0 -> field 0 which is invalid/varint
1070  // 15 = 0b1111 -> field 1, wire type 7 which is invalid
1071
1072  TestEmptyMessage* m = [TestEmptyMessage parseFromData:DataFromBytes(35, 36)
1073                                                  error:NULL];  // empty group
1074  GPBUnknownFields* ufs = [[[GPBUnknownFields alloc] initFromMessage:m] autorelease];
1075  XCTAssertEqual(ufs.count, (NSUInteger)1);
1076  GPBUnknownFields* group = [ufs firstGroup:4];
1077  XCTAssertTrue(group.empty);
1078
1079  m = [TestEmptyMessage parseFromData:DataFromBytes(35, 8, 1, 36) error:NULL];  // varint
1080  ufs = [[[GPBUnknownFields alloc] initFromMessage:m] autorelease];
1081  XCTAssertEqual(ufs.count, (NSUInteger)1);
1082  group = [ufs firstGroup:4];
1083  XCTAssertEqual(group.count, (NSUInteger)1);
1084  uint64_t varint = 0;
1085  XCTAssertTrue([group getFirst:1 varint:&varint]);
1086  XCTAssertEqual(varint, 1);
1087
1088  m = [TestEmptyMessage parseFromData:DataFromBytes(35, 21, 0x78, 0x56, 0x34, 0x12, 36)
1089                                error:NULL];  // fixed32
1090  ufs = [[[GPBUnknownFields alloc] initFromMessage:m] autorelease];
1091  XCTAssertEqual(ufs.count, (NSUInteger)1);
1092  group = [ufs firstGroup:4];
1093  XCTAssertEqual(group.count, (NSUInteger)1);
1094  uint32_t fixed32 = 0;
1095  XCTAssertTrue([group getFirst:2 fixed32:&fixed32]);
1096  XCTAssertEqual(fixed32, 0x12345678);
1097
1098  m = [TestEmptyMessage
1099      parseFromData:DataFromBytes(35, 25, 0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12,
1100                                  36)
1101              error:NULL];  // fixed64
1102  ufs = [[[GPBUnknownFields alloc] initFromMessage:m] autorelease];
1103  XCTAssertEqual(ufs.count, (NSUInteger)1);
1104  group = [ufs firstGroup:4];
1105  XCTAssertEqual(group.count, (NSUInteger)1);
1106  uint64_t fixed64 = 0;
1107  XCTAssertTrue([group getFirst:3 fixed64:&fixed64]);
1108  XCTAssertEqual(fixed64, 0x123456789abcdef0LL);
1109
1110  m = [TestEmptyMessage parseFromData:DataFromBytes(35, 50, 0, 36)
1111                                error:NULL];  // length delimited, length 0
1112  ufs = [[[GPBUnknownFields alloc] initFromMessage:m] autorelease];
1113  XCTAssertEqual(ufs.count, (NSUInteger)1);
1114  group = [ufs firstGroup:4];
1115  XCTAssertEqual(group.count, (NSUInteger)1);
1116  NSData* lengthDelimited = [group firstLengthDelimited:6];
1117  XCTAssertEqualObjects(lengthDelimited, [NSData data]);
1118
1119  m = [TestEmptyMessage parseFromData:DataFromBytes(35, 50, 1, 42, 36)
1120                                error:NULL];  // length delimited, length 1, byte 42
1121  ufs = [[[GPBUnknownFields alloc] initFromMessage:m] autorelease];
1122  XCTAssertEqual(ufs.count, (NSUInteger)1);
1123  group = [ufs firstGroup:4];
1124  XCTAssertEqual(group.count, (NSUInteger)1);
1125  lengthDelimited = [group firstLengthDelimited:6];
1126  XCTAssertEqualObjects(lengthDelimited, DataFromBytes(42));
1127
1128  m = [TestEmptyMessage parseFromData:DataFromBytes(35, 43, 44, 36) error:NULL];  // Sub group
1129  ufs = [[[GPBUnknownFields alloc] initFromMessage:m] autorelease];
1130  XCTAssertEqual(ufs.count, (NSUInteger)1);
1131  group = [ufs firstGroup:4];
1132  XCTAssertEqual(group.count, (NSUInteger)1);
1133  group = [group firstGroup:5];
1134  XCTAssertTrue(group.empty);
1135
1136  m = [TestEmptyMessage parseFromData:DataFromBytes(35, 8, 1, 43, 8, 2, 44, 36)
1137                                error:NULL];  // varint and sub group with varint
1138  ufs = [[[GPBUnknownFields alloc] initFromMessage:m] autorelease];
1139  XCTAssertEqual(ufs.count, (NSUInteger)1);
1140  group = [ufs firstGroup:4];
1141  XCTAssertEqual(group.count, (NSUInteger)2);
1142  varint = 0;
1143  XCTAssertTrue([group getFirst:1 varint:&varint]);
1144  XCTAssertEqual(varint, 1);
1145  group = [group firstGroup:5];
1146  XCTAssertEqual(group.count, (NSUInteger)1);
1147  XCTAssertTrue([group getFirst:1 varint:&varint]);
1148  XCTAssertEqual(varint, 2);
1149
1150  XCTAssertNil([TestEmptyMessage parseFromData:DataFromBytes(35, 0, 36)
1151                                         error:NULL]);  // Invalid field number
1152  XCTAssertNil([TestEmptyMessage parseFromData:DataFromBytes(35, 15, 36)
1153                                         error:NULL]);  // Invalid wire type
1154  XCTAssertNil([TestEmptyMessage parseFromData:DataFromBytes(35, 21, 0x78, 0x56, 0x34)
1155                                         error:NULL]);  // truncated fixed32
1156  XCTAssertNil([TestEmptyMessage
1157      parseFromData:DataFromBytes(35, 25, 0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56,
1158                                  0x34)
1159              error:NULL]);  // truncated fixed64
1160
1161  // Missing end group
1162  XCTAssertNil([TestEmptyMessage parseFromData:DataFromBytes(35) error:NULL]);
1163  XCTAssertNil([TestEmptyMessage parseFromData:DataFromBytes(35, 8, 1) error:NULL]);
1164  XCTAssertNil([TestEmptyMessage parseFromData:DataFromBytes(35, 43) error:NULL]);
1165  XCTAssertNil([TestEmptyMessage parseFromData:DataFromBytes(35, 43, 8, 1) error:NULL]);
1166
1167  // Wrong end group
1168  XCTAssertNil([TestEmptyMessage parseFromData:DataFromBytes(35, 44) error:NULL]);
1169  XCTAssertNil([TestEmptyMessage parseFromData:DataFromBytes(35, 8, 1, 44) error:NULL]);
1170  XCTAssertNil([TestEmptyMessage parseFromData:DataFromBytes(35, 43, 36) error:NULL]);
1171  XCTAssertNil([TestEmptyMessage parseFromData:DataFromBytes(35, 43, 8, 1, 36) error:NULL]);
1172  XCTAssertNil([TestEmptyMessage parseFromData:DataFromBytes(35, 43, 44, 44) error:NULL]);
1173  XCTAssertNil([TestEmptyMessage parseFromData:DataFromBytes(35, 43, 8, 1, 44, 44) error:NULL]);
1174
1175  // This is the same limit as within GPBCodedInputStream.
1176  const NSUInteger kDefaultRecursionLimit = 100;
1177  // That depth parses.
1178  NSData* testData = DataForGroupsOfDepth(kDefaultRecursionLimit);
1179  m = [TestEmptyMessage parseFromData:testData error:NULL];
1180  ufs = [[[GPBUnknownFields alloc] initFromMessage:m] autorelease];
1181  XCTAssertEqual(ufs.count, (NSUInteger)1);
1182  group = [ufs firstGroup:4];
1183  for (NSUInteger i = 1; i < kDefaultRecursionLimit; ++i) {
1184    XCTAssertEqual(group.count, (NSUInteger)1);
1185    group = [group firstGroup:4];
1186  }
1187  // group is now the inner most group.
1188  XCTAssertEqual(group.count, (NSUInteger)1);
1189  varint = 0;
1190  XCTAssertTrue([group getFirst:1 varint:&varint]);
1191  XCTAssertEqual(varint, 1);
1192  // One more level deep fails.
1193  testData = DataForGroupsOfDepth(kDefaultRecursionLimit + 1);
1194  XCTAssertNil([TestEmptyMessage parseFromData:testData error:NULL]);
1195}
1196
1197@end
1198