blob: 2a406f11fd398ffc67dbfec4f5e688cde19abbe9 [file] [log] [blame]
Brian Silverman9c614bc2016-02-15 20:20:02 -05001// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc. All rights reserved.
3// https://developers.google.com/protocol-buffers/
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9// * Redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer.
11// * Redistributions in binary form must reproduce the above
12// copyright notice, this list of conditions and the following disclaimer
13// in the documentation and/or other materials provided with the
14// distribution.
15// * Neither the name of Google Inc. nor the names of its
16// contributors may be used to endorse or promote products derived from
17// this software without specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31#import "GPBTestUtilities.h"
32
33#import "GPBCodedInputStream.h"
34#import "GPBMessage_PackagePrivate.h"
35#import "GPBUnknownField_PackagePrivate.h"
36#import "google/protobuf/Unittest.pbobjc.h"
37#import "google/protobuf/UnittestMset.pbobjc.h"
38#import "google/protobuf/UnittestMsetWireFormat.pbobjc.h"
39
40@interface WireFormatTests : GPBTestCase
41@end
42
43@implementation WireFormatTests
44
45- (void)testSerialization {
46 TestAllTypes* message = [self allSetRepeatedCount:kGPBDefaultRepeatCount];
47
48 NSData* rawBytes = message.data;
49 XCTAssertEqual(message.serializedSize, (size_t)rawBytes.length);
50
51 TestAllTypes* message2 = [TestAllTypes parseFromData:rawBytes error:NULL];
52
53 [self assertAllFieldsSet:message2 repeatedCount:kGPBDefaultRepeatCount];
54}
55
56- (void)testSerializationPacked {
57 TestPackedTypes* message =
58 [self packedSetRepeatedCount:kGPBDefaultRepeatCount];
59
60 NSData* rawBytes = message.data;
61 XCTAssertEqual(message.serializedSize, (size_t)rawBytes.length);
62
63 TestPackedTypes* message2 =
64 [TestPackedTypes parseFromData:rawBytes error:NULL];
65
66 [self assertPackedFieldsSet:message2 repeatedCount:kGPBDefaultRepeatCount];
67}
68
69- (void)testSerializeExtensions {
70 // TestAllTypes and TestAllExtensions should have compatible wire formats,
71 // so if we serealize a TestAllExtensions then parse it as TestAllTypes
72 // it should work.
73
74 TestAllExtensions* message =
75 [self allExtensionsSetRepeatedCount:kGPBDefaultRepeatCount];
76 NSData* rawBytes = message.data;
77 XCTAssertEqual(message.serializedSize, (size_t)rawBytes.length);
78
79 TestAllTypes* message2 = [TestAllTypes parseFromData:rawBytes error:NULL];
80
81 [self assertAllFieldsSet:message2 repeatedCount:kGPBDefaultRepeatCount];
82}
83
84- (void)testSerializePackedExtensions {
85 // TestPackedTypes and TestPackedExtensions should have compatible wire
86 // formats; check that they serialize to the same string.
87 TestPackedExtensions* message =
88 [self packedExtensionsSetRepeatedCount:kGPBDefaultRepeatCount];
89 NSData* rawBytes = message.data;
90
91 TestPackedTypes* message2 =
92 [self packedSetRepeatedCount:kGPBDefaultRepeatCount];
93 NSData* rawBytes2 = message2.data;
94
95 XCTAssertEqualObjects(rawBytes, rawBytes2);
96}
97
98- (void)testParseExtensions {
99 // TestAllTypes and TestAllExtensions should have compatible wire formats,
100 // so if we serialize a TestAllTypes then parse it as TestAllExtensions
101 // it should work.
102
103 TestAllTypes* message = [self allSetRepeatedCount:kGPBDefaultRepeatCount];
104 NSData* rawBytes = message.data;
105
106 GPBExtensionRegistry* registry = [self extensionRegistry];
107
108 TestAllExtensions* message2 = [TestAllExtensions parseFromData:rawBytes
109 extensionRegistry:registry
110 error:NULL];
111
112 [self assertAllExtensionsSet:message2 repeatedCount:kGPBDefaultRepeatCount];
113}
114
115
116- (void) testExtensionsSerializedSize {
117 size_t allSet = [self allSetRepeatedCount:kGPBDefaultRepeatCount].serializedSize;
118 size_t extensionSet = [self allExtensionsSetRepeatedCount:kGPBDefaultRepeatCount].serializedSize;
119 XCTAssertEqual(allSet, extensionSet);
120}
121
122- (void)testParsePackedExtensions {
123 // Ensure that packed extensions can be properly parsed.
124 TestPackedExtensions* message =
125 [self packedExtensionsSetRepeatedCount:kGPBDefaultRepeatCount];
126 NSData* rawBytes = message.data;
127
128 GPBExtensionRegistry* registry = [self extensionRegistry];
129
130 TestPackedExtensions* message2 = [TestPackedExtensions parseFromData:rawBytes
131 extensionRegistry:registry
132 error:NULL];
133
134 [self assertPackedExtensionsSet:message2
135 repeatedCount:kGPBDefaultRepeatCount];
136}
137
138const int kUnknownTypeId = 1550055;
139
140- (void)testSerializeMessageSet {
141 // Set up a TestMessageSet with two known messages and an unknown one.
142 TestMessageSet* message_set = [TestMessageSet message];
143 [[message_set getExtension:[TestMessageSetExtension1 messageSetExtension]]
144 setI:123];
145 [[message_set getExtension:[TestMessageSetExtension2 messageSetExtension]]
146 setStr:@"foo"];
147 GPBUnknownField* unknownField =
148 [[[GPBUnknownField alloc] initWithNumber:kUnknownTypeId] autorelease];
149 [unknownField addLengthDelimited:[NSData dataWithBytes:"bar" length:3]];
150 GPBUnknownFieldSet* unknownFieldSet =
151 [[[GPBUnknownFieldSet alloc] init] autorelease];
152 [unknownFieldSet addField:unknownField];
153 [message_set setUnknownFields:unknownFieldSet];
154
155 NSData* data = [message_set data];
156
157 // Parse back using RawMessageSet and check the contents.
158 RawMessageSet* raw = [RawMessageSet parseFromData:data error:NULL];
159
160 XCTAssertEqual([raw.unknownFields countOfFields], (NSUInteger)0);
161
162 XCTAssertEqual(raw.itemArray.count, (NSUInteger)3);
163 XCTAssertEqual((uint32_t)[raw.itemArray[0] typeId],
164 [TestMessageSetExtension1 messageSetExtension].fieldNumber);
165 XCTAssertEqual((uint32_t)[raw.itemArray[1] typeId],
166 [TestMessageSetExtension2 messageSetExtension].fieldNumber);
167 XCTAssertEqual([raw.itemArray[2] typeId], kUnknownTypeId);
168
169 TestMessageSetExtension1* message1 =
170 [TestMessageSetExtension1 parseFromData:[((RawMessageSet_Item*)raw.itemArray[0]) message]
171 error:NULL];
172 XCTAssertEqual(message1.i, 123);
173
174 TestMessageSetExtension2* message2 =
175 [TestMessageSetExtension2 parseFromData:[((RawMessageSet_Item*)raw.itemArray[1]) message]
176 error:NULL];
177 XCTAssertEqualObjects(message2.str, @"foo");
178
179 XCTAssertEqualObjects([raw.itemArray[2] message],
180 [NSData dataWithBytes:"bar" length:3]);
181}
182
183- (void)testParseMessageSet {
184 // Set up a RawMessageSet with two known messages and an unknown one.
185 RawMessageSet* raw = [RawMessageSet message];
186
187 {
188 RawMessageSet_Item* item = [RawMessageSet_Item message];
189 item.typeId = [TestMessageSetExtension1 messageSetExtension].fieldNumber;
190 TestMessageSetExtension1* message = [TestMessageSetExtension1 message];
191 message.i = 123;
192 item.message = [message data];
193 [raw.itemArray addObject:item];
194 }
195
196 {
197 RawMessageSet_Item* item = [RawMessageSet_Item message];
198 item.typeId = [TestMessageSetExtension2 messageSetExtension].fieldNumber;
199 TestMessageSetExtension2* message = [TestMessageSetExtension2 message];
200 message.str = @"foo";
201 item.message = [message data];
202 [raw.itemArray addObject:item];
203 }
204
205 {
206 RawMessageSet_Item* item = [RawMessageSet_Item message];
207 item.typeId = kUnknownTypeId;
208 item.message = [NSData dataWithBytes:"bar" length:3];
209 [raw.itemArray addObject:item];
210 }
211
212 NSData* data = [raw data];
213
214 // Parse as a TestMessageSet and check the contents.
215 TestMessageSet* messageSet =
216 [TestMessageSet parseFromData:data
217 extensionRegistry:[UnittestMsetRoot extensionRegistry]
218 error:NULL];
219
220 XCTAssertEqual(
221 [[messageSet
222 getExtension:[TestMessageSetExtension1 messageSetExtension]] i],
223 123);
224 XCTAssertEqualObjects(
225 [[messageSet
226 getExtension:[TestMessageSetExtension2 messageSetExtension]] str],
227 @"foo");
228
229 XCTAssertEqual([messageSet.unknownFields countOfFields], (NSUInteger)1);
230 GPBUnknownField* unknownField = [messageSet.unknownFields getField:kUnknownTypeId];
231 XCTAssertNotNil(unknownField);
232 XCTAssertEqual(unknownField.lengthDelimitedList.count, (NSUInteger)1);
233 XCTAssertEqualObjects(unknownField.lengthDelimitedList[0],
234 [NSData dataWithBytes:"bar" length:3]);
235}
236
237- (void)assertFieldsInOrder:(NSData*)data {
238 GPBCodedInputStream* input = [GPBCodedInputStream streamWithData:data];
239 int32_t previousTag = 0;
240
241 while (YES) {
242 int32_t tag = [input readTag];
243 if (tag == 0) {
244 break;
245 }
246
247 XCTAssertGreaterThan(tag, previousTag);
248 [input skipField:tag];
249 }
250}
251
252@end