blob: 82d7952b0734eb629e798b314be90a1fc0128b4c [file] [log] [blame]
Brian Silverman9c614bc2016-02-15 20:20:02 -05001// Protocol Buffers - Google's data interchange format
2// Copyright 2015 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 <Foundation/Foundation.h>
32#import <XCTest/XCTest.h>
33
34#import "GPBDictionary.h"
35
36#import "GPBTestUtilities.h"
37#import "google/protobuf/UnittestRuntimeProto2.pbobjc.h"
38
39// Pull in the macros (using an external file because expanding all tests
40// in a single file makes a file that is failing to work with within Xcode.
41//%PDDM-IMPORT-DEFINES GPBDictionaryTests.pddm
42
43//%PDDM-EXPAND TESTS_FOR_POD_VALUES(String, NSString, *, Objects, @"foo", @"bar", @"baz", @"mumble")
44// This block of code is generated, do not edit it directly.
45
46// To let the testing macros work, add some extra methods to simplify things.
47@interface GPBStringEnumDictionary (TestingTweak)
Austin Schuh40c16522018-10-28 20:27:54 -070048- (instancetype)initWithEnums:(const int32_t [])values
49 forKeys:(const NSString * [])keys
50 count:(NSUInteger)count;
Brian Silverman9c614bc2016-02-15 20:20:02 -050051@end
52
53static BOOL TestingEnum_IsValidValue(int32_t value) {
54 switch (value) {
55 case 700:
56 case 701:
57 case 702:
58 case 703:
59 return YES;
60 default:
61 return NO;
62 }
63}
64
65@implementation GPBStringEnumDictionary (TestingTweak)
Austin Schuh40c16522018-10-28 20:27:54 -070066- (instancetype)initWithEnums:(const int32_t [])values
67 forKeys:(const NSString * [])keys
68 count:(NSUInteger)count {
Brian Silverman9c614bc2016-02-15 20:20:02 -050069 return [self initWithValidationFunction:TestingEnum_IsValidValue
70 rawValues:values
71 forKeys:keys
72 count:count];
73}
74@end
75
76
77#pragma mark - String -> UInt32
78
79@interface GPBStringUInt32DictionaryTests : XCTestCase
80@end
81
82@implementation GPBStringUInt32DictionaryTests
83
84- (void)testEmpty {
85 GPBStringUInt32Dictionary *dict = [[GPBStringUInt32Dictionary alloc] init];
86 XCTAssertNotNil(dict);
87 XCTAssertEqual(dict.count, 0U);
Austin Schuh40c16522018-10-28 20:27:54 -070088 XCTAssertFalse([dict getUInt32:NULL forKey:@"foo"]);
89 [dict enumerateKeysAndUInt32sUsingBlock:^(NSString *aKey, uint32_t aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -050090 #pragma unused(aKey, aValue, stop)
91 XCTFail(@"Shouldn't get here!");
92 }];
93 [dict release];
94}
95
96- (void)testOne {
Austin Schuh40c16522018-10-28 20:27:54 -070097 GPBStringUInt32Dictionary *dict = [[GPBStringUInt32Dictionary alloc] init];
98 [dict setUInt32:100U forKey:@"foo"];
Brian Silverman9c614bc2016-02-15 20:20:02 -050099 XCTAssertNotNil(dict);
100 XCTAssertEqual(dict.count, 1U);
101 uint32_t value;
Austin Schuh40c16522018-10-28 20:27:54 -0700102 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
103 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500104 XCTAssertEqual(value, 100U);
Austin Schuh40c16522018-10-28 20:27:54 -0700105 XCTAssertFalse([dict getUInt32:NULL forKey:@"bar"]);
106 [dict enumerateKeysAndUInt32sUsingBlock:^(NSString *aKey, uint32_t aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -0500107 XCTAssertEqualObjects(aKey, @"foo");
108 XCTAssertEqual(aValue, 100U);
109 XCTAssertNotEqual(stop, NULL);
110 }];
Austin Schuh40c16522018-10-28 20:27:54 -0700111 [dict release];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500112}
113
114- (void)testBasics {
115 const NSString *kKeys[] = { @"foo", @"bar", @"baz" };
116 const uint32_t kValues[] = { 100U, 101U, 102U };
117 GPBStringUInt32Dictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -0700118 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues
119 forKeys:kKeys
120 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500121 XCTAssertNotNil(dict);
122 XCTAssertEqual(dict.count, 3U);
123 uint32_t value;
Austin Schuh40c16522018-10-28 20:27:54 -0700124 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
125 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500126 XCTAssertEqual(value, 100U);
Austin Schuh40c16522018-10-28 20:27:54 -0700127 XCTAssertTrue([dict getUInt32:NULL forKey:@"bar"]);
128 XCTAssertTrue([dict getUInt32:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500129 XCTAssertEqual(value, 101U);
Austin Schuh40c16522018-10-28 20:27:54 -0700130 XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]);
131 XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500132 XCTAssertEqual(value, 102U);
Austin Schuh40c16522018-10-28 20:27:54 -0700133 XCTAssertFalse([dict getUInt32:NULL forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500134
135 __block NSUInteger idx = 0;
136 NSString **seenKeys = malloc(3 * sizeof(NSString*));
137 uint32_t *seenValues = malloc(3 * sizeof(uint32_t));
Austin Schuh40c16522018-10-28 20:27:54 -0700138 [dict enumerateKeysAndUInt32sUsingBlock:^(NSString *aKey, uint32_t aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -0500139 XCTAssertLessThan(idx, 3U);
140 seenKeys[idx] = aKey;
141 seenValues[idx] = aValue;
142 XCTAssertNotEqual(stop, NULL);
143 ++idx;
144 }];
145 for (int i = 0; i < 3; ++i) {
146 BOOL foundKey = NO;
147 for (int j = 0; (j < 3) && !foundKey; ++j) {
148 if ([kKeys[i] isEqual:seenKeys[j]]) {
149 foundKey = YES;
150 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
151 }
152 }
153 XCTAssertTrue(foundKey, @"i = %d", i);
154 }
155 free(seenKeys);
156 free(seenValues);
157
158 // Stopping the enumeration.
159 idx = 0;
Austin Schuh40c16522018-10-28 20:27:54 -0700160 [dict enumerateKeysAndUInt32sUsingBlock:^(NSString *aKey, uint32_t aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -0500161 #pragma unused(aKey, aValue)
162 if (idx == 1) *stop = YES;
163 XCTAssertNotEqual(idx, 2U);
164 ++idx;
165 }];
166 [dict release];
167}
168
169- (void)testEquality {
170 const NSString *kKeys1[] = { @"foo", @"bar", @"baz", @"mumble" };
171 const NSString *kKeys2[] = { @"bar", @"foo", @"mumble" };
172 const uint32_t kValues1[] = { 100U, 101U, 102U };
173 const uint32_t kValues2[] = { 100U, 103U, 102U };
174 const uint32_t kValues3[] = { 100U, 101U, 102U, 103U };
175 GPBStringUInt32Dictionary *dict1 =
Austin Schuh40c16522018-10-28 20:27:54 -0700176 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues1
177 forKeys:kKeys1
178 count:GPBARRAYSIZE(kValues1)];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500179 XCTAssertNotNil(dict1);
180 GPBStringUInt32Dictionary *dict1prime =
Austin Schuh40c16522018-10-28 20:27:54 -0700181 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues1
182 forKeys:kKeys1
183 count:GPBARRAYSIZE(kValues1)];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500184 XCTAssertNotNil(dict1prime);
185 GPBStringUInt32Dictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -0700186 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues2
187 forKeys:kKeys1
188 count:GPBARRAYSIZE(kValues2)];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500189 XCTAssertNotNil(dict2);
190 GPBStringUInt32Dictionary *dict3 =
Austin Schuh40c16522018-10-28 20:27:54 -0700191 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues1
192 forKeys:kKeys2
193 count:GPBARRAYSIZE(kValues1)];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500194 XCTAssertNotNil(dict3);
195 GPBStringUInt32Dictionary *dict4 =
Austin Schuh40c16522018-10-28 20:27:54 -0700196 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues3
197 forKeys:kKeys1
198 count:GPBARRAYSIZE(kValues3)];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500199 XCTAssertNotNil(dict4);
200
201 // 1/1Prime should be different objects, but equal.
202 XCTAssertNotEqual(dict1, dict1prime);
203 XCTAssertEqualObjects(dict1, dict1prime);
204 // Equal, so they must have same hash.
205 XCTAssertEqual([dict1 hash], [dict1prime hash]);
206
207 // 2 is same keys, different values; not equal.
208 XCTAssertNotEqualObjects(dict1, dict2);
209
210 // 3 is different keys, same values; not equal.
211 XCTAssertNotEqualObjects(dict1, dict3);
212
213 // 4 extra pair; not equal
214 XCTAssertNotEqualObjects(dict1, dict4);
215
216 [dict1 release];
217 [dict1prime release];
218 [dict2 release];
219 [dict3 release];
220 [dict4 release];
221}
222
223- (void)testCopy {
224 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
225 const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
226 GPBStringUInt32Dictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -0700227 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues
228 forKeys:kKeys
229 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500230 XCTAssertNotNil(dict);
231
232 GPBStringUInt32Dictionary *dict2 = [dict copy];
233 XCTAssertNotNil(dict2);
234
235 // Should be new object but equal.
236 XCTAssertNotEqual(dict, dict2);
237 XCTAssertEqualObjects(dict, dict2);
238 XCTAssertTrue([dict2 isKindOfClass:[GPBStringUInt32Dictionary class]]);
239
240 [dict2 release];
241 [dict release];
242}
243
244- (void)testDictionaryFromDictionary {
245 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
246 const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
247 GPBStringUInt32Dictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -0700248 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues
249 forKeys:kKeys
250 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500251 XCTAssertNotNil(dict);
252
253 GPBStringUInt32Dictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -0700254 [[GPBStringUInt32Dictionary alloc] initWithDictionary:dict];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500255 XCTAssertNotNil(dict2);
256
257 // Should be new pointer, but equal objects.
258 XCTAssertNotEqual(dict, dict2);
259 XCTAssertEqualObjects(dict, dict2);
Austin Schuh40c16522018-10-28 20:27:54 -0700260 [dict2 release];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500261 [dict release];
262}
263
264- (void)testAdds {
Austin Schuh40c16522018-10-28 20:27:54 -0700265 GPBStringUInt32Dictionary *dict = [[GPBStringUInt32Dictionary alloc] init];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500266 XCTAssertNotNil(dict);
267
268 XCTAssertEqual(dict.count, 0U);
Austin Schuh40c16522018-10-28 20:27:54 -0700269 [dict setUInt32:100U forKey:@"foo"];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500270 XCTAssertEqual(dict.count, 1U);
271
272 const NSString *kKeys[] = { @"bar", @"baz", @"mumble" };
273 const uint32_t kValues[] = { 101U, 102U, 103U };
274 GPBStringUInt32Dictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -0700275 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues
276 forKeys:kKeys
277 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500278 XCTAssertNotNil(dict2);
279 [dict addEntriesFromDictionary:dict2];
280 XCTAssertEqual(dict.count, 4U);
281
282 uint32_t value;
Austin Schuh40c16522018-10-28 20:27:54 -0700283 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
284 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500285 XCTAssertEqual(value, 100U);
Austin Schuh40c16522018-10-28 20:27:54 -0700286 XCTAssertTrue([dict getUInt32:NULL forKey:@"bar"]);
287 XCTAssertTrue([dict getUInt32:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500288 XCTAssertEqual(value, 101U);
Austin Schuh40c16522018-10-28 20:27:54 -0700289 XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]);
290 XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500291 XCTAssertEqual(value, 102U);
Austin Schuh40c16522018-10-28 20:27:54 -0700292 XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]);
293 XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500294 XCTAssertEqual(value, 103U);
295 [dict2 release];
Austin Schuh40c16522018-10-28 20:27:54 -0700296 [dict release];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500297}
298
299- (void)testRemove {
300 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
301 const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
302 GPBStringUInt32Dictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -0700303 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues
304 forKeys:kKeys
305 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500306 XCTAssertNotNil(dict);
307 XCTAssertEqual(dict.count, 4U);
308
Austin Schuh40c16522018-10-28 20:27:54 -0700309 [dict removeUInt32ForKey:@"bar"];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500310 XCTAssertEqual(dict.count, 3U);
311 uint32_t value;
Austin Schuh40c16522018-10-28 20:27:54 -0700312 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
313 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500314 XCTAssertEqual(value, 100U);
Austin Schuh40c16522018-10-28 20:27:54 -0700315 XCTAssertFalse([dict getUInt32:NULL forKey:@"bar"]);
316 XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]);
317 XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500318 XCTAssertEqual(value, 102U);
Austin Schuh40c16522018-10-28 20:27:54 -0700319 XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]);
320 XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500321 XCTAssertEqual(value, 103U);
322
323 // Remove again does nothing.
Austin Schuh40c16522018-10-28 20:27:54 -0700324 [dict removeUInt32ForKey:@"bar"];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500325 XCTAssertEqual(dict.count, 3U);
Austin Schuh40c16522018-10-28 20:27:54 -0700326 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
327 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500328 XCTAssertEqual(value, 100U);
Austin Schuh40c16522018-10-28 20:27:54 -0700329 XCTAssertFalse([dict getUInt32:NULL forKey:@"bar"]);
330 XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]);
331 XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500332 XCTAssertEqual(value, 102U);
Austin Schuh40c16522018-10-28 20:27:54 -0700333 XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]);
334 XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500335 XCTAssertEqual(value, 103U);
336
Austin Schuh40c16522018-10-28 20:27:54 -0700337 [dict removeUInt32ForKey:@"mumble"];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500338 XCTAssertEqual(dict.count, 2U);
Austin Schuh40c16522018-10-28 20:27:54 -0700339 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
340 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500341 XCTAssertEqual(value, 100U);
Austin Schuh40c16522018-10-28 20:27:54 -0700342 XCTAssertFalse([dict getUInt32:NULL forKey:@"bar"]);
343 XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]);
344 XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500345 XCTAssertEqual(value, 102U);
Austin Schuh40c16522018-10-28 20:27:54 -0700346 XCTAssertFalse([dict getUInt32:NULL forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500347
348 [dict removeAll];
349 XCTAssertEqual(dict.count, 0U);
Austin Schuh40c16522018-10-28 20:27:54 -0700350 XCTAssertFalse([dict getUInt32:NULL forKey:@"foo"]);
351 XCTAssertFalse([dict getUInt32:NULL forKey:@"bar"]);
352 XCTAssertFalse([dict getUInt32:NULL forKey:@"baz"]);
353 XCTAssertFalse([dict getUInt32:NULL forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500354 [dict release];
355}
356
357- (void)testInplaceMutation {
358 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
359 const uint32_t kValues[] = { 100U, 101U, 102U, 103U };
360 GPBStringUInt32Dictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -0700361 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues
362 forKeys:kKeys
363 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500364 XCTAssertNotNil(dict);
365 XCTAssertEqual(dict.count, 4U);
366 uint32_t value;
Austin Schuh40c16522018-10-28 20:27:54 -0700367 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
368 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500369 XCTAssertEqual(value, 100U);
Austin Schuh40c16522018-10-28 20:27:54 -0700370 XCTAssertTrue([dict getUInt32:NULL forKey:@"bar"]);
371 XCTAssertTrue([dict getUInt32:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500372 XCTAssertEqual(value, 101U);
Austin Schuh40c16522018-10-28 20:27:54 -0700373 XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]);
374 XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500375 XCTAssertEqual(value, 102U);
Austin Schuh40c16522018-10-28 20:27:54 -0700376 XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]);
377 XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500378 XCTAssertEqual(value, 103U);
379
Austin Schuh40c16522018-10-28 20:27:54 -0700380 [dict setUInt32:103U forKey:@"foo"];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500381 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -0700382 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
383 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500384 XCTAssertEqual(value, 103U);
Austin Schuh40c16522018-10-28 20:27:54 -0700385 XCTAssertTrue([dict getUInt32:NULL forKey:@"bar"]);
386 XCTAssertTrue([dict getUInt32:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500387 XCTAssertEqual(value, 101U);
Austin Schuh40c16522018-10-28 20:27:54 -0700388 XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]);
389 XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500390 XCTAssertEqual(value, 102U);
Austin Schuh40c16522018-10-28 20:27:54 -0700391 XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]);
392 XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500393 XCTAssertEqual(value, 103U);
394
Austin Schuh40c16522018-10-28 20:27:54 -0700395 [dict setUInt32:101U forKey:@"mumble"];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500396 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -0700397 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
398 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500399 XCTAssertEqual(value, 103U);
Austin Schuh40c16522018-10-28 20:27:54 -0700400 XCTAssertTrue([dict getUInt32:NULL forKey:@"bar"]);
401 XCTAssertTrue([dict getUInt32:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500402 XCTAssertEqual(value, 101U);
Austin Schuh40c16522018-10-28 20:27:54 -0700403 XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]);
404 XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500405 XCTAssertEqual(value, 102U);
Austin Schuh40c16522018-10-28 20:27:54 -0700406 XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]);
407 XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500408 XCTAssertEqual(value, 101U);
409
410 const NSString *kKeys2[] = { @"bar", @"baz" };
411 const uint32_t kValues2[] = { 102U, 100U };
412 GPBStringUInt32Dictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -0700413 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues2
414 forKeys:kKeys2
415 count:GPBARRAYSIZE(kValues2)];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500416 XCTAssertNotNil(dict2);
417 [dict addEntriesFromDictionary:dict2];
418 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -0700419 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]);
420 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500421 XCTAssertEqual(value, 103U);
Austin Schuh40c16522018-10-28 20:27:54 -0700422 XCTAssertTrue([dict getUInt32:NULL forKey:@"bar"]);
423 XCTAssertTrue([dict getUInt32:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500424 XCTAssertEqual(value, 102U);
Austin Schuh40c16522018-10-28 20:27:54 -0700425 XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]);
426 XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500427 XCTAssertEqual(value, 100U);
Austin Schuh40c16522018-10-28 20:27:54 -0700428 XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]);
429 XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500430 XCTAssertEqual(value, 101U);
431
432 [dict2 release];
433 [dict release];
434}
435
436@end
437
438#pragma mark - String -> Int32
439
440@interface GPBStringInt32DictionaryTests : XCTestCase
441@end
442
443@implementation GPBStringInt32DictionaryTests
444
445- (void)testEmpty {
446 GPBStringInt32Dictionary *dict = [[GPBStringInt32Dictionary alloc] init];
447 XCTAssertNotNil(dict);
448 XCTAssertEqual(dict.count, 0U);
Austin Schuh40c16522018-10-28 20:27:54 -0700449 XCTAssertFalse([dict getInt32:NULL forKey:@"foo"]);
450 [dict enumerateKeysAndInt32sUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -0500451 #pragma unused(aKey, aValue, stop)
452 XCTFail(@"Shouldn't get here!");
453 }];
454 [dict release];
455}
456
457- (void)testOne {
Austin Schuh40c16522018-10-28 20:27:54 -0700458 GPBStringInt32Dictionary *dict = [[GPBStringInt32Dictionary alloc] init];
459 [dict setInt32:200 forKey:@"foo"];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500460 XCTAssertNotNil(dict);
461 XCTAssertEqual(dict.count, 1U);
462 int32_t value;
Austin Schuh40c16522018-10-28 20:27:54 -0700463 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
464 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500465 XCTAssertEqual(value, 200);
Austin Schuh40c16522018-10-28 20:27:54 -0700466 XCTAssertFalse([dict getInt32:NULL forKey:@"bar"]);
467 [dict enumerateKeysAndInt32sUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -0500468 XCTAssertEqualObjects(aKey, @"foo");
469 XCTAssertEqual(aValue, 200);
470 XCTAssertNotEqual(stop, NULL);
471 }];
Austin Schuh40c16522018-10-28 20:27:54 -0700472 [dict release];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500473}
474
475- (void)testBasics {
476 const NSString *kKeys[] = { @"foo", @"bar", @"baz" };
477 const int32_t kValues[] = { 200, 201, 202 };
478 GPBStringInt32Dictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -0700479 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues
Brian Silverman9c614bc2016-02-15 20:20:02 -0500480 forKeys:kKeys
481 count:GPBARRAYSIZE(kValues)];
482 XCTAssertNotNil(dict);
483 XCTAssertEqual(dict.count, 3U);
484 int32_t value;
Austin Schuh40c16522018-10-28 20:27:54 -0700485 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
486 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500487 XCTAssertEqual(value, 200);
Austin Schuh40c16522018-10-28 20:27:54 -0700488 XCTAssertTrue([dict getInt32:NULL forKey:@"bar"]);
489 XCTAssertTrue([dict getInt32:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500490 XCTAssertEqual(value, 201);
Austin Schuh40c16522018-10-28 20:27:54 -0700491 XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]);
492 XCTAssertTrue([dict getInt32:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500493 XCTAssertEqual(value, 202);
Austin Schuh40c16522018-10-28 20:27:54 -0700494 XCTAssertFalse([dict getInt32:NULL forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500495
496 __block NSUInteger idx = 0;
497 NSString **seenKeys = malloc(3 * sizeof(NSString*));
498 int32_t *seenValues = malloc(3 * sizeof(int32_t));
Austin Schuh40c16522018-10-28 20:27:54 -0700499 [dict enumerateKeysAndInt32sUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -0500500 XCTAssertLessThan(idx, 3U);
501 seenKeys[idx] = aKey;
502 seenValues[idx] = aValue;
503 XCTAssertNotEqual(stop, NULL);
504 ++idx;
505 }];
506 for (int i = 0; i < 3; ++i) {
507 BOOL foundKey = NO;
508 for (int j = 0; (j < 3) && !foundKey; ++j) {
509 if ([kKeys[i] isEqual:seenKeys[j]]) {
510 foundKey = YES;
511 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
512 }
513 }
514 XCTAssertTrue(foundKey, @"i = %d", i);
515 }
516 free(seenKeys);
517 free(seenValues);
518
519 // Stopping the enumeration.
520 idx = 0;
Austin Schuh40c16522018-10-28 20:27:54 -0700521 [dict enumerateKeysAndInt32sUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -0500522 #pragma unused(aKey, aValue)
523 if (idx == 1) *stop = YES;
524 XCTAssertNotEqual(idx, 2U);
525 ++idx;
526 }];
527 [dict release];
528}
529
530- (void)testEquality {
531 const NSString *kKeys1[] = { @"foo", @"bar", @"baz", @"mumble" };
532 const NSString *kKeys2[] = { @"bar", @"foo", @"mumble" };
533 const int32_t kValues1[] = { 200, 201, 202 };
534 const int32_t kValues2[] = { 200, 203, 202 };
535 const int32_t kValues3[] = { 200, 201, 202, 203 };
536 GPBStringInt32Dictionary *dict1 =
Austin Schuh40c16522018-10-28 20:27:54 -0700537 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues1
Brian Silverman9c614bc2016-02-15 20:20:02 -0500538 forKeys:kKeys1
539 count:GPBARRAYSIZE(kValues1)];
540 XCTAssertNotNil(dict1);
541 GPBStringInt32Dictionary *dict1prime =
Austin Schuh40c16522018-10-28 20:27:54 -0700542 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues1
Brian Silverman9c614bc2016-02-15 20:20:02 -0500543 forKeys:kKeys1
544 count:GPBARRAYSIZE(kValues1)];
545 XCTAssertNotNil(dict1prime);
546 GPBStringInt32Dictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -0700547 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues2
Brian Silverman9c614bc2016-02-15 20:20:02 -0500548 forKeys:kKeys1
549 count:GPBARRAYSIZE(kValues2)];
550 XCTAssertNotNil(dict2);
551 GPBStringInt32Dictionary *dict3 =
Austin Schuh40c16522018-10-28 20:27:54 -0700552 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues1
Brian Silverman9c614bc2016-02-15 20:20:02 -0500553 forKeys:kKeys2
554 count:GPBARRAYSIZE(kValues1)];
555 XCTAssertNotNil(dict3);
556 GPBStringInt32Dictionary *dict4 =
Austin Schuh40c16522018-10-28 20:27:54 -0700557 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues3
Brian Silverman9c614bc2016-02-15 20:20:02 -0500558 forKeys:kKeys1
559 count:GPBARRAYSIZE(kValues3)];
560 XCTAssertNotNil(dict4);
561
562 // 1/1Prime should be different objects, but equal.
563 XCTAssertNotEqual(dict1, dict1prime);
564 XCTAssertEqualObjects(dict1, dict1prime);
565 // Equal, so they must have same hash.
566 XCTAssertEqual([dict1 hash], [dict1prime hash]);
567
568 // 2 is same keys, different values; not equal.
569 XCTAssertNotEqualObjects(dict1, dict2);
570
571 // 3 is different keys, same values; not equal.
572 XCTAssertNotEqualObjects(dict1, dict3);
573
574 // 4 extra pair; not equal
575 XCTAssertNotEqualObjects(dict1, dict4);
576
577 [dict1 release];
578 [dict1prime release];
579 [dict2 release];
580 [dict3 release];
581 [dict4 release];
582}
583
584- (void)testCopy {
585 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
586 const int32_t kValues[] = { 200, 201, 202, 203 };
587 GPBStringInt32Dictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -0700588 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues
Brian Silverman9c614bc2016-02-15 20:20:02 -0500589 forKeys:kKeys
590 count:GPBARRAYSIZE(kValues)];
591 XCTAssertNotNil(dict);
592
593 GPBStringInt32Dictionary *dict2 = [dict copy];
594 XCTAssertNotNil(dict2);
595
596 // Should be new object but equal.
597 XCTAssertNotEqual(dict, dict2);
598 XCTAssertEqualObjects(dict, dict2);
599 XCTAssertTrue([dict2 isKindOfClass:[GPBStringInt32Dictionary class]]);
600
601 [dict2 release];
602 [dict release];
603}
604
605- (void)testDictionaryFromDictionary {
606 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
607 const int32_t kValues[] = { 200, 201, 202, 203 };
608 GPBStringInt32Dictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -0700609 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues
Brian Silverman9c614bc2016-02-15 20:20:02 -0500610 forKeys:kKeys
611 count:GPBARRAYSIZE(kValues)];
612 XCTAssertNotNil(dict);
613
614 GPBStringInt32Dictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -0700615 [[GPBStringInt32Dictionary alloc] initWithDictionary:dict];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500616 XCTAssertNotNil(dict2);
617
618 // Should be new pointer, but equal objects.
619 XCTAssertNotEqual(dict, dict2);
620 XCTAssertEqualObjects(dict, dict2);
Austin Schuh40c16522018-10-28 20:27:54 -0700621 [dict2 release];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500622 [dict release];
623}
624
625- (void)testAdds {
Austin Schuh40c16522018-10-28 20:27:54 -0700626 GPBStringInt32Dictionary *dict = [[GPBStringInt32Dictionary alloc] init];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500627 XCTAssertNotNil(dict);
628
629 XCTAssertEqual(dict.count, 0U);
Austin Schuh40c16522018-10-28 20:27:54 -0700630 [dict setInt32:200 forKey:@"foo"];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500631 XCTAssertEqual(dict.count, 1U);
632
633 const NSString *kKeys[] = { @"bar", @"baz", @"mumble" };
634 const int32_t kValues[] = { 201, 202, 203 };
635 GPBStringInt32Dictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -0700636 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues
Brian Silverman9c614bc2016-02-15 20:20:02 -0500637 forKeys:kKeys
638 count:GPBARRAYSIZE(kValues)];
639 XCTAssertNotNil(dict2);
640 [dict addEntriesFromDictionary:dict2];
641 XCTAssertEqual(dict.count, 4U);
642
643 int32_t value;
Austin Schuh40c16522018-10-28 20:27:54 -0700644 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
645 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500646 XCTAssertEqual(value, 200);
Austin Schuh40c16522018-10-28 20:27:54 -0700647 XCTAssertTrue([dict getInt32:NULL forKey:@"bar"]);
648 XCTAssertTrue([dict getInt32:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500649 XCTAssertEqual(value, 201);
Austin Schuh40c16522018-10-28 20:27:54 -0700650 XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]);
651 XCTAssertTrue([dict getInt32:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500652 XCTAssertEqual(value, 202);
Austin Schuh40c16522018-10-28 20:27:54 -0700653 XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]);
654 XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500655 XCTAssertEqual(value, 203);
656 [dict2 release];
Austin Schuh40c16522018-10-28 20:27:54 -0700657 [dict release];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500658}
659
660- (void)testRemove {
661 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
662 const int32_t kValues[] = { 200, 201, 202, 203 };
663 GPBStringInt32Dictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -0700664 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues
665 forKeys:kKeys
666 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500667 XCTAssertNotNil(dict);
668 XCTAssertEqual(dict.count, 4U);
669
Austin Schuh40c16522018-10-28 20:27:54 -0700670 [dict removeInt32ForKey:@"bar"];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500671 XCTAssertEqual(dict.count, 3U);
672 int32_t value;
Austin Schuh40c16522018-10-28 20:27:54 -0700673 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
674 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500675 XCTAssertEqual(value, 200);
Austin Schuh40c16522018-10-28 20:27:54 -0700676 XCTAssertFalse([dict getInt32:NULL forKey:@"bar"]);
677 XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]);
678 XCTAssertTrue([dict getInt32:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500679 XCTAssertEqual(value, 202);
Austin Schuh40c16522018-10-28 20:27:54 -0700680 XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]);
681 XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500682 XCTAssertEqual(value, 203);
683
684 // Remove again does nothing.
Austin Schuh40c16522018-10-28 20:27:54 -0700685 [dict removeInt32ForKey:@"bar"];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500686 XCTAssertEqual(dict.count, 3U);
Austin Schuh40c16522018-10-28 20:27:54 -0700687 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
688 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500689 XCTAssertEqual(value, 200);
Austin Schuh40c16522018-10-28 20:27:54 -0700690 XCTAssertFalse([dict getInt32:NULL forKey:@"bar"]);
691 XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]);
692 XCTAssertTrue([dict getInt32:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500693 XCTAssertEqual(value, 202);
Austin Schuh40c16522018-10-28 20:27:54 -0700694 XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]);
695 XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500696 XCTAssertEqual(value, 203);
697
Austin Schuh40c16522018-10-28 20:27:54 -0700698 [dict removeInt32ForKey:@"mumble"];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500699 XCTAssertEqual(dict.count, 2U);
Austin Schuh40c16522018-10-28 20:27:54 -0700700 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
701 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500702 XCTAssertEqual(value, 200);
Austin Schuh40c16522018-10-28 20:27:54 -0700703 XCTAssertFalse([dict getInt32:NULL forKey:@"bar"]);
704 XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]);
705 XCTAssertTrue([dict getInt32:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500706 XCTAssertEqual(value, 202);
Austin Schuh40c16522018-10-28 20:27:54 -0700707 XCTAssertFalse([dict getInt32:NULL forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500708
709 [dict removeAll];
710 XCTAssertEqual(dict.count, 0U);
Austin Schuh40c16522018-10-28 20:27:54 -0700711 XCTAssertFalse([dict getInt32:NULL forKey:@"foo"]);
712 XCTAssertFalse([dict getInt32:NULL forKey:@"bar"]);
713 XCTAssertFalse([dict getInt32:NULL forKey:@"baz"]);
714 XCTAssertFalse([dict getInt32:NULL forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500715 [dict release];
716}
717
718- (void)testInplaceMutation {
719 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
720 const int32_t kValues[] = { 200, 201, 202, 203 };
721 GPBStringInt32Dictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -0700722 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues
723 forKeys:kKeys
724 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500725 XCTAssertNotNil(dict);
726 XCTAssertEqual(dict.count, 4U);
727 int32_t value;
Austin Schuh40c16522018-10-28 20:27:54 -0700728 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
729 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500730 XCTAssertEqual(value, 200);
Austin Schuh40c16522018-10-28 20:27:54 -0700731 XCTAssertTrue([dict getInt32:NULL forKey:@"bar"]);
732 XCTAssertTrue([dict getInt32:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500733 XCTAssertEqual(value, 201);
Austin Schuh40c16522018-10-28 20:27:54 -0700734 XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]);
735 XCTAssertTrue([dict getInt32:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500736 XCTAssertEqual(value, 202);
Austin Schuh40c16522018-10-28 20:27:54 -0700737 XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]);
738 XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500739 XCTAssertEqual(value, 203);
740
Austin Schuh40c16522018-10-28 20:27:54 -0700741 [dict setInt32:203 forKey:@"foo"];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500742 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -0700743 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
744 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500745 XCTAssertEqual(value, 203);
Austin Schuh40c16522018-10-28 20:27:54 -0700746 XCTAssertTrue([dict getInt32:NULL forKey:@"bar"]);
747 XCTAssertTrue([dict getInt32:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500748 XCTAssertEqual(value, 201);
Austin Schuh40c16522018-10-28 20:27:54 -0700749 XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]);
750 XCTAssertTrue([dict getInt32:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500751 XCTAssertEqual(value, 202);
Austin Schuh40c16522018-10-28 20:27:54 -0700752 XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]);
753 XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500754 XCTAssertEqual(value, 203);
755
Austin Schuh40c16522018-10-28 20:27:54 -0700756 [dict setInt32:201 forKey:@"mumble"];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500757 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -0700758 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
759 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500760 XCTAssertEqual(value, 203);
Austin Schuh40c16522018-10-28 20:27:54 -0700761 XCTAssertTrue([dict getInt32:NULL forKey:@"bar"]);
762 XCTAssertTrue([dict getInt32:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500763 XCTAssertEqual(value, 201);
Austin Schuh40c16522018-10-28 20:27:54 -0700764 XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]);
765 XCTAssertTrue([dict getInt32:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500766 XCTAssertEqual(value, 202);
Austin Schuh40c16522018-10-28 20:27:54 -0700767 XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]);
768 XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500769 XCTAssertEqual(value, 201);
770
771 const NSString *kKeys2[] = { @"bar", @"baz" };
772 const int32_t kValues2[] = { 202, 200 };
773 GPBStringInt32Dictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -0700774 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues2
Brian Silverman9c614bc2016-02-15 20:20:02 -0500775 forKeys:kKeys2
776 count:GPBARRAYSIZE(kValues2)];
777 XCTAssertNotNil(dict2);
778 [dict addEntriesFromDictionary:dict2];
779 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -0700780 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]);
781 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500782 XCTAssertEqual(value, 203);
Austin Schuh40c16522018-10-28 20:27:54 -0700783 XCTAssertTrue([dict getInt32:NULL forKey:@"bar"]);
784 XCTAssertTrue([dict getInt32:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500785 XCTAssertEqual(value, 202);
Austin Schuh40c16522018-10-28 20:27:54 -0700786 XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]);
787 XCTAssertTrue([dict getInt32:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500788 XCTAssertEqual(value, 200);
Austin Schuh40c16522018-10-28 20:27:54 -0700789 XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]);
790 XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500791 XCTAssertEqual(value, 201);
792
793 [dict2 release];
794 [dict release];
795}
796
797@end
798
799#pragma mark - String -> UInt64
800
801@interface GPBStringUInt64DictionaryTests : XCTestCase
802@end
803
804@implementation GPBStringUInt64DictionaryTests
805
806- (void)testEmpty {
807 GPBStringUInt64Dictionary *dict = [[GPBStringUInt64Dictionary alloc] init];
808 XCTAssertNotNil(dict);
809 XCTAssertEqual(dict.count, 0U);
Austin Schuh40c16522018-10-28 20:27:54 -0700810 XCTAssertFalse([dict getUInt64:NULL forKey:@"foo"]);
811 [dict enumerateKeysAndUInt64sUsingBlock:^(NSString *aKey, uint64_t aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -0500812 #pragma unused(aKey, aValue, stop)
813 XCTFail(@"Shouldn't get here!");
814 }];
815 [dict release];
816}
817
818- (void)testOne {
Austin Schuh40c16522018-10-28 20:27:54 -0700819 GPBStringUInt64Dictionary *dict = [[GPBStringUInt64Dictionary alloc] init];
820 [dict setUInt64:300U forKey:@"foo"];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500821 XCTAssertNotNil(dict);
822 XCTAssertEqual(dict.count, 1U);
823 uint64_t value;
Austin Schuh40c16522018-10-28 20:27:54 -0700824 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
825 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500826 XCTAssertEqual(value, 300U);
Austin Schuh40c16522018-10-28 20:27:54 -0700827 XCTAssertFalse([dict getUInt64:NULL forKey:@"bar"]);
828 [dict enumerateKeysAndUInt64sUsingBlock:^(NSString *aKey, uint64_t aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -0500829 XCTAssertEqualObjects(aKey, @"foo");
830 XCTAssertEqual(aValue, 300U);
831 XCTAssertNotEqual(stop, NULL);
832 }];
Austin Schuh40c16522018-10-28 20:27:54 -0700833 [dict release];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500834}
835
836- (void)testBasics {
837 const NSString *kKeys[] = { @"foo", @"bar", @"baz" };
838 const uint64_t kValues[] = { 300U, 301U, 302U };
839 GPBStringUInt64Dictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -0700840 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues
841 forKeys:kKeys
842 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500843 XCTAssertNotNil(dict);
844 XCTAssertEqual(dict.count, 3U);
845 uint64_t value;
Austin Schuh40c16522018-10-28 20:27:54 -0700846 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
847 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500848 XCTAssertEqual(value, 300U);
Austin Schuh40c16522018-10-28 20:27:54 -0700849 XCTAssertTrue([dict getUInt64:NULL forKey:@"bar"]);
850 XCTAssertTrue([dict getUInt64:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500851 XCTAssertEqual(value, 301U);
Austin Schuh40c16522018-10-28 20:27:54 -0700852 XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]);
853 XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500854 XCTAssertEqual(value, 302U);
Austin Schuh40c16522018-10-28 20:27:54 -0700855 XCTAssertFalse([dict getUInt64:NULL forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -0500856
857 __block NSUInteger idx = 0;
858 NSString **seenKeys = malloc(3 * sizeof(NSString*));
859 uint64_t *seenValues = malloc(3 * sizeof(uint64_t));
Austin Schuh40c16522018-10-28 20:27:54 -0700860 [dict enumerateKeysAndUInt64sUsingBlock:^(NSString *aKey, uint64_t aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -0500861 XCTAssertLessThan(idx, 3U);
862 seenKeys[idx] = aKey;
863 seenValues[idx] = aValue;
864 XCTAssertNotEqual(stop, NULL);
865 ++idx;
866 }];
867 for (int i = 0; i < 3; ++i) {
868 BOOL foundKey = NO;
869 for (int j = 0; (j < 3) && !foundKey; ++j) {
870 if ([kKeys[i] isEqual:seenKeys[j]]) {
871 foundKey = YES;
872 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
873 }
874 }
875 XCTAssertTrue(foundKey, @"i = %d", i);
876 }
877 free(seenKeys);
878 free(seenValues);
879
880 // Stopping the enumeration.
881 idx = 0;
Austin Schuh40c16522018-10-28 20:27:54 -0700882 [dict enumerateKeysAndUInt64sUsingBlock:^(NSString *aKey, uint64_t aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -0500883 #pragma unused(aKey, aValue)
884 if (idx == 1) *stop = YES;
885 XCTAssertNotEqual(idx, 2U);
886 ++idx;
887 }];
888 [dict release];
889}
890
891- (void)testEquality {
892 const NSString *kKeys1[] = { @"foo", @"bar", @"baz", @"mumble" };
893 const NSString *kKeys2[] = { @"bar", @"foo", @"mumble" };
894 const uint64_t kValues1[] = { 300U, 301U, 302U };
895 const uint64_t kValues2[] = { 300U, 303U, 302U };
896 const uint64_t kValues3[] = { 300U, 301U, 302U, 303U };
897 GPBStringUInt64Dictionary *dict1 =
Austin Schuh40c16522018-10-28 20:27:54 -0700898 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues1
899 forKeys:kKeys1
900 count:GPBARRAYSIZE(kValues1)];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500901 XCTAssertNotNil(dict1);
902 GPBStringUInt64Dictionary *dict1prime =
Austin Schuh40c16522018-10-28 20:27:54 -0700903 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues1
904 forKeys:kKeys1
905 count:GPBARRAYSIZE(kValues1)];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500906 XCTAssertNotNil(dict1prime);
907 GPBStringUInt64Dictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -0700908 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues2
909 forKeys:kKeys1
910 count:GPBARRAYSIZE(kValues2)];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500911 XCTAssertNotNil(dict2);
912 GPBStringUInt64Dictionary *dict3 =
Austin Schuh40c16522018-10-28 20:27:54 -0700913 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues1
914 forKeys:kKeys2
915 count:GPBARRAYSIZE(kValues1)];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500916 XCTAssertNotNil(dict3);
917 GPBStringUInt64Dictionary *dict4 =
Austin Schuh40c16522018-10-28 20:27:54 -0700918 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues3
919 forKeys:kKeys1
920 count:GPBARRAYSIZE(kValues3)];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500921 XCTAssertNotNil(dict4);
922
923 // 1/1Prime should be different objects, but equal.
924 XCTAssertNotEqual(dict1, dict1prime);
925 XCTAssertEqualObjects(dict1, dict1prime);
926 // Equal, so they must have same hash.
927 XCTAssertEqual([dict1 hash], [dict1prime hash]);
928
929 // 2 is same keys, different values; not equal.
930 XCTAssertNotEqualObjects(dict1, dict2);
931
932 // 3 is different keys, same values; not equal.
933 XCTAssertNotEqualObjects(dict1, dict3);
934
935 // 4 extra pair; not equal
936 XCTAssertNotEqualObjects(dict1, dict4);
937
938 [dict1 release];
939 [dict1prime release];
940 [dict2 release];
941 [dict3 release];
942 [dict4 release];
943}
944
945- (void)testCopy {
946 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
947 const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
948 GPBStringUInt64Dictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -0700949 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues
950 forKeys:kKeys
951 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500952 XCTAssertNotNil(dict);
953
954 GPBStringUInt64Dictionary *dict2 = [dict copy];
955 XCTAssertNotNil(dict2);
956
957 // Should be new object but equal.
958 XCTAssertNotEqual(dict, dict2);
959 XCTAssertEqualObjects(dict, dict2);
960 XCTAssertTrue([dict2 isKindOfClass:[GPBStringUInt64Dictionary class]]);
961
962 [dict2 release];
963 [dict release];
964}
965
966- (void)testDictionaryFromDictionary {
967 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
968 const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
969 GPBStringUInt64Dictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -0700970 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues
971 forKeys:kKeys
972 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500973 XCTAssertNotNil(dict);
974
975 GPBStringUInt64Dictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -0700976 [[GPBStringUInt64Dictionary alloc] initWithDictionary:dict];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500977 XCTAssertNotNil(dict2);
978
979 // Should be new pointer, but equal objects.
980 XCTAssertNotEqual(dict, dict2);
981 XCTAssertEqualObjects(dict, dict2);
Austin Schuh40c16522018-10-28 20:27:54 -0700982 [dict2 release];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500983 [dict release];
984}
985
986- (void)testAdds {
Austin Schuh40c16522018-10-28 20:27:54 -0700987 GPBStringUInt64Dictionary *dict = [[GPBStringUInt64Dictionary alloc] init];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500988 XCTAssertNotNil(dict);
989
990 XCTAssertEqual(dict.count, 0U);
Austin Schuh40c16522018-10-28 20:27:54 -0700991 [dict setUInt64:300U forKey:@"foo"];
Brian Silverman9c614bc2016-02-15 20:20:02 -0500992 XCTAssertEqual(dict.count, 1U);
993
994 const NSString *kKeys[] = { @"bar", @"baz", @"mumble" };
995 const uint64_t kValues[] = { 301U, 302U, 303U };
996 GPBStringUInt64Dictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -0700997 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues
998 forKeys:kKeys
999 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001000 XCTAssertNotNil(dict2);
1001 [dict addEntriesFromDictionary:dict2];
1002 XCTAssertEqual(dict.count, 4U);
1003
1004 uint64_t value;
Austin Schuh40c16522018-10-28 20:27:54 -07001005 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
1006 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001007 XCTAssertEqual(value, 300U);
Austin Schuh40c16522018-10-28 20:27:54 -07001008 XCTAssertTrue([dict getUInt64:NULL forKey:@"bar"]);
1009 XCTAssertTrue([dict getUInt64:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001010 XCTAssertEqual(value, 301U);
Austin Schuh40c16522018-10-28 20:27:54 -07001011 XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]);
1012 XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001013 XCTAssertEqual(value, 302U);
Austin Schuh40c16522018-10-28 20:27:54 -07001014 XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]);
1015 XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001016 XCTAssertEqual(value, 303U);
1017 [dict2 release];
Austin Schuh40c16522018-10-28 20:27:54 -07001018 [dict release];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001019}
1020
1021- (void)testRemove {
1022 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
1023 const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
1024 GPBStringUInt64Dictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07001025 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues
1026 forKeys:kKeys
1027 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001028 XCTAssertNotNil(dict);
1029 XCTAssertEqual(dict.count, 4U);
1030
Austin Schuh40c16522018-10-28 20:27:54 -07001031 [dict removeUInt64ForKey:@"bar"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001032 XCTAssertEqual(dict.count, 3U);
1033 uint64_t value;
Austin Schuh40c16522018-10-28 20:27:54 -07001034 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
1035 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001036 XCTAssertEqual(value, 300U);
Austin Schuh40c16522018-10-28 20:27:54 -07001037 XCTAssertFalse([dict getUInt64:NULL forKey:@"bar"]);
1038 XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]);
1039 XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001040 XCTAssertEqual(value, 302U);
Austin Schuh40c16522018-10-28 20:27:54 -07001041 XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]);
1042 XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001043 XCTAssertEqual(value, 303U);
1044
1045 // Remove again does nothing.
Austin Schuh40c16522018-10-28 20:27:54 -07001046 [dict removeUInt64ForKey:@"bar"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001047 XCTAssertEqual(dict.count, 3U);
Austin Schuh40c16522018-10-28 20:27:54 -07001048 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
1049 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001050 XCTAssertEqual(value, 300U);
Austin Schuh40c16522018-10-28 20:27:54 -07001051 XCTAssertFalse([dict getUInt64:NULL forKey:@"bar"]);
1052 XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]);
1053 XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001054 XCTAssertEqual(value, 302U);
Austin Schuh40c16522018-10-28 20:27:54 -07001055 XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]);
1056 XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001057 XCTAssertEqual(value, 303U);
1058
Austin Schuh40c16522018-10-28 20:27:54 -07001059 [dict removeUInt64ForKey:@"mumble"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001060 XCTAssertEqual(dict.count, 2U);
Austin Schuh40c16522018-10-28 20:27:54 -07001061 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
1062 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001063 XCTAssertEqual(value, 300U);
Austin Schuh40c16522018-10-28 20:27:54 -07001064 XCTAssertFalse([dict getUInt64:NULL forKey:@"bar"]);
1065 XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]);
1066 XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001067 XCTAssertEqual(value, 302U);
Austin Schuh40c16522018-10-28 20:27:54 -07001068 XCTAssertFalse([dict getUInt64:NULL forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001069
1070 [dict removeAll];
1071 XCTAssertEqual(dict.count, 0U);
Austin Schuh40c16522018-10-28 20:27:54 -07001072 XCTAssertFalse([dict getUInt64:NULL forKey:@"foo"]);
1073 XCTAssertFalse([dict getUInt64:NULL forKey:@"bar"]);
1074 XCTAssertFalse([dict getUInt64:NULL forKey:@"baz"]);
1075 XCTAssertFalse([dict getUInt64:NULL forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001076 [dict release];
1077}
1078
1079- (void)testInplaceMutation {
1080 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
1081 const uint64_t kValues[] = { 300U, 301U, 302U, 303U };
1082 GPBStringUInt64Dictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07001083 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues
1084 forKeys:kKeys
1085 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001086 XCTAssertNotNil(dict);
1087 XCTAssertEqual(dict.count, 4U);
1088 uint64_t value;
Austin Schuh40c16522018-10-28 20:27:54 -07001089 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
1090 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001091 XCTAssertEqual(value, 300U);
Austin Schuh40c16522018-10-28 20:27:54 -07001092 XCTAssertTrue([dict getUInt64:NULL forKey:@"bar"]);
1093 XCTAssertTrue([dict getUInt64:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001094 XCTAssertEqual(value, 301U);
Austin Schuh40c16522018-10-28 20:27:54 -07001095 XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]);
1096 XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001097 XCTAssertEqual(value, 302U);
Austin Schuh40c16522018-10-28 20:27:54 -07001098 XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]);
1099 XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001100 XCTAssertEqual(value, 303U);
1101
Austin Schuh40c16522018-10-28 20:27:54 -07001102 [dict setUInt64:303U forKey:@"foo"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001103 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -07001104 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
1105 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001106 XCTAssertEqual(value, 303U);
Austin Schuh40c16522018-10-28 20:27:54 -07001107 XCTAssertTrue([dict getUInt64:NULL forKey:@"bar"]);
1108 XCTAssertTrue([dict getUInt64:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001109 XCTAssertEqual(value, 301U);
Austin Schuh40c16522018-10-28 20:27:54 -07001110 XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]);
1111 XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001112 XCTAssertEqual(value, 302U);
Austin Schuh40c16522018-10-28 20:27:54 -07001113 XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]);
1114 XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001115 XCTAssertEqual(value, 303U);
1116
Austin Schuh40c16522018-10-28 20:27:54 -07001117 [dict setUInt64:301U forKey:@"mumble"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001118 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -07001119 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
1120 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001121 XCTAssertEqual(value, 303U);
Austin Schuh40c16522018-10-28 20:27:54 -07001122 XCTAssertTrue([dict getUInt64:NULL forKey:@"bar"]);
1123 XCTAssertTrue([dict getUInt64:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001124 XCTAssertEqual(value, 301U);
Austin Schuh40c16522018-10-28 20:27:54 -07001125 XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]);
1126 XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001127 XCTAssertEqual(value, 302U);
Austin Schuh40c16522018-10-28 20:27:54 -07001128 XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]);
1129 XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001130 XCTAssertEqual(value, 301U);
1131
1132 const NSString *kKeys2[] = { @"bar", @"baz" };
1133 const uint64_t kValues2[] = { 302U, 300U };
1134 GPBStringUInt64Dictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -07001135 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues2
1136 forKeys:kKeys2
1137 count:GPBARRAYSIZE(kValues2)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001138 XCTAssertNotNil(dict2);
1139 [dict addEntriesFromDictionary:dict2];
1140 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -07001141 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]);
1142 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001143 XCTAssertEqual(value, 303U);
Austin Schuh40c16522018-10-28 20:27:54 -07001144 XCTAssertTrue([dict getUInt64:NULL forKey:@"bar"]);
1145 XCTAssertTrue([dict getUInt64:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001146 XCTAssertEqual(value, 302U);
Austin Schuh40c16522018-10-28 20:27:54 -07001147 XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]);
1148 XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001149 XCTAssertEqual(value, 300U);
Austin Schuh40c16522018-10-28 20:27:54 -07001150 XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]);
1151 XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001152 XCTAssertEqual(value, 301U);
1153
1154 [dict2 release];
1155 [dict release];
1156}
1157
1158@end
1159
1160#pragma mark - String -> Int64
1161
1162@interface GPBStringInt64DictionaryTests : XCTestCase
1163@end
1164
1165@implementation GPBStringInt64DictionaryTests
1166
1167- (void)testEmpty {
1168 GPBStringInt64Dictionary *dict = [[GPBStringInt64Dictionary alloc] init];
1169 XCTAssertNotNil(dict);
1170 XCTAssertEqual(dict.count, 0U);
Austin Schuh40c16522018-10-28 20:27:54 -07001171 XCTAssertFalse([dict getInt64:NULL forKey:@"foo"]);
1172 [dict enumerateKeysAndInt64sUsingBlock:^(NSString *aKey, int64_t aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -05001173 #pragma unused(aKey, aValue, stop)
1174 XCTFail(@"Shouldn't get here!");
1175 }];
1176 [dict release];
1177}
1178
1179- (void)testOne {
Austin Schuh40c16522018-10-28 20:27:54 -07001180 GPBStringInt64Dictionary *dict = [[GPBStringInt64Dictionary alloc] init];
1181 [dict setInt64:400 forKey:@"foo"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001182 XCTAssertNotNil(dict);
1183 XCTAssertEqual(dict.count, 1U);
1184 int64_t value;
Austin Schuh40c16522018-10-28 20:27:54 -07001185 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
1186 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001187 XCTAssertEqual(value, 400);
Austin Schuh40c16522018-10-28 20:27:54 -07001188 XCTAssertFalse([dict getInt64:NULL forKey:@"bar"]);
1189 [dict enumerateKeysAndInt64sUsingBlock:^(NSString *aKey, int64_t aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -05001190 XCTAssertEqualObjects(aKey, @"foo");
1191 XCTAssertEqual(aValue, 400);
1192 XCTAssertNotEqual(stop, NULL);
1193 }];
Austin Schuh40c16522018-10-28 20:27:54 -07001194 [dict release];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001195}
1196
1197- (void)testBasics {
1198 const NSString *kKeys[] = { @"foo", @"bar", @"baz" };
1199 const int64_t kValues[] = { 400, 401, 402 };
1200 GPBStringInt64Dictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07001201 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues
Brian Silverman9c614bc2016-02-15 20:20:02 -05001202 forKeys:kKeys
1203 count:GPBARRAYSIZE(kValues)];
1204 XCTAssertNotNil(dict);
1205 XCTAssertEqual(dict.count, 3U);
1206 int64_t value;
Austin Schuh40c16522018-10-28 20:27:54 -07001207 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
1208 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001209 XCTAssertEqual(value, 400);
Austin Schuh40c16522018-10-28 20:27:54 -07001210 XCTAssertTrue([dict getInt64:NULL forKey:@"bar"]);
1211 XCTAssertTrue([dict getInt64:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001212 XCTAssertEqual(value, 401);
Austin Schuh40c16522018-10-28 20:27:54 -07001213 XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]);
1214 XCTAssertTrue([dict getInt64:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001215 XCTAssertEqual(value, 402);
Austin Schuh40c16522018-10-28 20:27:54 -07001216 XCTAssertFalse([dict getInt64:NULL forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001217
1218 __block NSUInteger idx = 0;
1219 NSString **seenKeys = malloc(3 * sizeof(NSString*));
1220 int64_t *seenValues = malloc(3 * sizeof(int64_t));
Austin Schuh40c16522018-10-28 20:27:54 -07001221 [dict enumerateKeysAndInt64sUsingBlock:^(NSString *aKey, int64_t aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -05001222 XCTAssertLessThan(idx, 3U);
1223 seenKeys[idx] = aKey;
1224 seenValues[idx] = aValue;
1225 XCTAssertNotEqual(stop, NULL);
1226 ++idx;
1227 }];
1228 for (int i = 0; i < 3; ++i) {
1229 BOOL foundKey = NO;
1230 for (int j = 0; (j < 3) && !foundKey; ++j) {
1231 if ([kKeys[i] isEqual:seenKeys[j]]) {
1232 foundKey = YES;
1233 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
1234 }
1235 }
1236 XCTAssertTrue(foundKey, @"i = %d", i);
1237 }
1238 free(seenKeys);
1239 free(seenValues);
1240
1241 // Stopping the enumeration.
1242 idx = 0;
Austin Schuh40c16522018-10-28 20:27:54 -07001243 [dict enumerateKeysAndInt64sUsingBlock:^(NSString *aKey, int64_t aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -05001244 #pragma unused(aKey, aValue)
1245 if (idx == 1) *stop = YES;
1246 XCTAssertNotEqual(idx, 2U);
1247 ++idx;
1248 }];
1249 [dict release];
1250}
1251
1252- (void)testEquality {
1253 const NSString *kKeys1[] = { @"foo", @"bar", @"baz", @"mumble" };
1254 const NSString *kKeys2[] = { @"bar", @"foo", @"mumble" };
1255 const int64_t kValues1[] = { 400, 401, 402 };
1256 const int64_t kValues2[] = { 400, 403, 402 };
1257 const int64_t kValues3[] = { 400, 401, 402, 403 };
1258 GPBStringInt64Dictionary *dict1 =
Austin Schuh40c16522018-10-28 20:27:54 -07001259 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues1
Brian Silverman9c614bc2016-02-15 20:20:02 -05001260 forKeys:kKeys1
1261 count:GPBARRAYSIZE(kValues1)];
1262 XCTAssertNotNil(dict1);
1263 GPBStringInt64Dictionary *dict1prime =
Austin Schuh40c16522018-10-28 20:27:54 -07001264 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues1
Brian Silverman9c614bc2016-02-15 20:20:02 -05001265 forKeys:kKeys1
1266 count:GPBARRAYSIZE(kValues1)];
1267 XCTAssertNotNil(dict1prime);
1268 GPBStringInt64Dictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -07001269 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues2
Brian Silverman9c614bc2016-02-15 20:20:02 -05001270 forKeys:kKeys1
1271 count:GPBARRAYSIZE(kValues2)];
1272 XCTAssertNotNil(dict2);
1273 GPBStringInt64Dictionary *dict3 =
Austin Schuh40c16522018-10-28 20:27:54 -07001274 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues1
Brian Silverman9c614bc2016-02-15 20:20:02 -05001275 forKeys:kKeys2
1276 count:GPBARRAYSIZE(kValues1)];
1277 XCTAssertNotNil(dict3);
1278 GPBStringInt64Dictionary *dict4 =
Austin Schuh40c16522018-10-28 20:27:54 -07001279 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues3
Brian Silverman9c614bc2016-02-15 20:20:02 -05001280 forKeys:kKeys1
1281 count:GPBARRAYSIZE(kValues3)];
1282 XCTAssertNotNil(dict4);
1283
1284 // 1/1Prime should be different objects, but equal.
1285 XCTAssertNotEqual(dict1, dict1prime);
1286 XCTAssertEqualObjects(dict1, dict1prime);
1287 // Equal, so they must have same hash.
1288 XCTAssertEqual([dict1 hash], [dict1prime hash]);
1289
1290 // 2 is same keys, different values; not equal.
1291 XCTAssertNotEqualObjects(dict1, dict2);
1292
1293 // 3 is different keys, same values; not equal.
1294 XCTAssertNotEqualObjects(dict1, dict3);
1295
1296 // 4 extra pair; not equal
1297 XCTAssertNotEqualObjects(dict1, dict4);
1298
1299 [dict1 release];
1300 [dict1prime release];
1301 [dict2 release];
1302 [dict3 release];
1303 [dict4 release];
1304}
1305
1306- (void)testCopy {
1307 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
1308 const int64_t kValues[] = { 400, 401, 402, 403 };
1309 GPBStringInt64Dictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07001310 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues
Brian Silverman9c614bc2016-02-15 20:20:02 -05001311 forKeys:kKeys
1312 count:GPBARRAYSIZE(kValues)];
1313 XCTAssertNotNil(dict);
1314
1315 GPBStringInt64Dictionary *dict2 = [dict copy];
1316 XCTAssertNotNil(dict2);
1317
1318 // Should be new object but equal.
1319 XCTAssertNotEqual(dict, dict2);
1320 XCTAssertEqualObjects(dict, dict2);
1321 XCTAssertTrue([dict2 isKindOfClass:[GPBStringInt64Dictionary class]]);
1322
1323 [dict2 release];
1324 [dict release];
1325}
1326
1327- (void)testDictionaryFromDictionary {
1328 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
1329 const int64_t kValues[] = { 400, 401, 402, 403 };
1330 GPBStringInt64Dictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07001331 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues
Brian Silverman9c614bc2016-02-15 20:20:02 -05001332 forKeys:kKeys
1333 count:GPBARRAYSIZE(kValues)];
1334 XCTAssertNotNil(dict);
1335
1336 GPBStringInt64Dictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -07001337 [[GPBStringInt64Dictionary alloc] initWithDictionary:dict];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001338 XCTAssertNotNil(dict2);
1339
1340 // Should be new pointer, but equal objects.
1341 XCTAssertNotEqual(dict, dict2);
1342 XCTAssertEqualObjects(dict, dict2);
Austin Schuh40c16522018-10-28 20:27:54 -07001343 [dict2 release];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001344 [dict release];
1345}
1346
1347- (void)testAdds {
Austin Schuh40c16522018-10-28 20:27:54 -07001348 GPBStringInt64Dictionary *dict = [[GPBStringInt64Dictionary alloc] init];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001349 XCTAssertNotNil(dict);
1350
1351 XCTAssertEqual(dict.count, 0U);
Austin Schuh40c16522018-10-28 20:27:54 -07001352 [dict setInt64:400 forKey:@"foo"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001353 XCTAssertEqual(dict.count, 1U);
1354
1355 const NSString *kKeys[] = { @"bar", @"baz", @"mumble" };
1356 const int64_t kValues[] = { 401, 402, 403 };
1357 GPBStringInt64Dictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -07001358 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues
Brian Silverman9c614bc2016-02-15 20:20:02 -05001359 forKeys:kKeys
1360 count:GPBARRAYSIZE(kValues)];
1361 XCTAssertNotNil(dict2);
1362 [dict addEntriesFromDictionary:dict2];
1363 XCTAssertEqual(dict.count, 4U);
1364
1365 int64_t value;
Austin Schuh40c16522018-10-28 20:27:54 -07001366 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
1367 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001368 XCTAssertEqual(value, 400);
Austin Schuh40c16522018-10-28 20:27:54 -07001369 XCTAssertTrue([dict getInt64:NULL forKey:@"bar"]);
1370 XCTAssertTrue([dict getInt64:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001371 XCTAssertEqual(value, 401);
Austin Schuh40c16522018-10-28 20:27:54 -07001372 XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]);
1373 XCTAssertTrue([dict getInt64:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001374 XCTAssertEqual(value, 402);
Austin Schuh40c16522018-10-28 20:27:54 -07001375 XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]);
1376 XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001377 XCTAssertEqual(value, 403);
1378 [dict2 release];
Austin Schuh40c16522018-10-28 20:27:54 -07001379 [dict release];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001380}
1381
1382- (void)testRemove {
1383 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
1384 const int64_t kValues[] = { 400, 401, 402, 403 };
1385 GPBStringInt64Dictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07001386 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues
1387 forKeys:kKeys
1388 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001389 XCTAssertNotNil(dict);
1390 XCTAssertEqual(dict.count, 4U);
1391
Austin Schuh40c16522018-10-28 20:27:54 -07001392 [dict removeInt64ForKey:@"bar"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001393 XCTAssertEqual(dict.count, 3U);
1394 int64_t value;
Austin Schuh40c16522018-10-28 20:27:54 -07001395 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
1396 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001397 XCTAssertEqual(value, 400);
Austin Schuh40c16522018-10-28 20:27:54 -07001398 XCTAssertFalse([dict getInt64:NULL forKey:@"bar"]);
1399 XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]);
1400 XCTAssertTrue([dict getInt64:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001401 XCTAssertEqual(value, 402);
Austin Schuh40c16522018-10-28 20:27:54 -07001402 XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]);
1403 XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001404 XCTAssertEqual(value, 403);
1405
1406 // Remove again does nothing.
Austin Schuh40c16522018-10-28 20:27:54 -07001407 [dict removeInt64ForKey:@"bar"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001408 XCTAssertEqual(dict.count, 3U);
Austin Schuh40c16522018-10-28 20:27:54 -07001409 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
1410 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001411 XCTAssertEqual(value, 400);
Austin Schuh40c16522018-10-28 20:27:54 -07001412 XCTAssertFalse([dict getInt64:NULL forKey:@"bar"]);
1413 XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]);
1414 XCTAssertTrue([dict getInt64:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001415 XCTAssertEqual(value, 402);
Austin Schuh40c16522018-10-28 20:27:54 -07001416 XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]);
1417 XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001418 XCTAssertEqual(value, 403);
1419
Austin Schuh40c16522018-10-28 20:27:54 -07001420 [dict removeInt64ForKey:@"mumble"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001421 XCTAssertEqual(dict.count, 2U);
Austin Schuh40c16522018-10-28 20:27:54 -07001422 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
1423 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001424 XCTAssertEqual(value, 400);
Austin Schuh40c16522018-10-28 20:27:54 -07001425 XCTAssertFalse([dict getInt64:NULL forKey:@"bar"]);
1426 XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]);
1427 XCTAssertTrue([dict getInt64:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001428 XCTAssertEqual(value, 402);
Austin Schuh40c16522018-10-28 20:27:54 -07001429 XCTAssertFalse([dict getInt64:NULL forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001430
1431 [dict removeAll];
1432 XCTAssertEqual(dict.count, 0U);
Austin Schuh40c16522018-10-28 20:27:54 -07001433 XCTAssertFalse([dict getInt64:NULL forKey:@"foo"]);
1434 XCTAssertFalse([dict getInt64:NULL forKey:@"bar"]);
1435 XCTAssertFalse([dict getInt64:NULL forKey:@"baz"]);
1436 XCTAssertFalse([dict getInt64:NULL forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001437 [dict release];
1438}
1439
1440- (void)testInplaceMutation {
1441 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
1442 const int64_t kValues[] = { 400, 401, 402, 403 };
1443 GPBStringInt64Dictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07001444 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues
1445 forKeys:kKeys
1446 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001447 XCTAssertNotNil(dict);
1448 XCTAssertEqual(dict.count, 4U);
1449 int64_t value;
Austin Schuh40c16522018-10-28 20:27:54 -07001450 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
1451 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001452 XCTAssertEqual(value, 400);
Austin Schuh40c16522018-10-28 20:27:54 -07001453 XCTAssertTrue([dict getInt64:NULL forKey:@"bar"]);
1454 XCTAssertTrue([dict getInt64:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001455 XCTAssertEqual(value, 401);
Austin Schuh40c16522018-10-28 20:27:54 -07001456 XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]);
1457 XCTAssertTrue([dict getInt64:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001458 XCTAssertEqual(value, 402);
Austin Schuh40c16522018-10-28 20:27:54 -07001459 XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]);
1460 XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001461 XCTAssertEqual(value, 403);
1462
Austin Schuh40c16522018-10-28 20:27:54 -07001463 [dict setInt64:403 forKey:@"foo"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001464 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -07001465 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
1466 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001467 XCTAssertEqual(value, 403);
Austin Schuh40c16522018-10-28 20:27:54 -07001468 XCTAssertTrue([dict getInt64:NULL forKey:@"bar"]);
1469 XCTAssertTrue([dict getInt64:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001470 XCTAssertEqual(value, 401);
Austin Schuh40c16522018-10-28 20:27:54 -07001471 XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]);
1472 XCTAssertTrue([dict getInt64:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001473 XCTAssertEqual(value, 402);
Austin Schuh40c16522018-10-28 20:27:54 -07001474 XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]);
1475 XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001476 XCTAssertEqual(value, 403);
1477
Austin Schuh40c16522018-10-28 20:27:54 -07001478 [dict setInt64:401 forKey:@"mumble"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001479 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -07001480 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
1481 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001482 XCTAssertEqual(value, 403);
Austin Schuh40c16522018-10-28 20:27:54 -07001483 XCTAssertTrue([dict getInt64:NULL forKey:@"bar"]);
1484 XCTAssertTrue([dict getInt64:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001485 XCTAssertEqual(value, 401);
Austin Schuh40c16522018-10-28 20:27:54 -07001486 XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]);
1487 XCTAssertTrue([dict getInt64:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001488 XCTAssertEqual(value, 402);
Austin Schuh40c16522018-10-28 20:27:54 -07001489 XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]);
1490 XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001491 XCTAssertEqual(value, 401);
1492
1493 const NSString *kKeys2[] = { @"bar", @"baz" };
1494 const int64_t kValues2[] = { 402, 400 };
1495 GPBStringInt64Dictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -07001496 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues2
Brian Silverman9c614bc2016-02-15 20:20:02 -05001497 forKeys:kKeys2
1498 count:GPBARRAYSIZE(kValues2)];
1499 XCTAssertNotNil(dict2);
1500 [dict addEntriesFromDictionary:dict2];
1501 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -07001502 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]);
1503 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001504 XCTAssertEqual(value, 403);
Austin Schuh40c16522018-10-28 20:27:54 -07001505 XCTAssertTrue([dict getInt64:NULL forKey:@"bar"]);
1506 XCTAssertTrue([dict getInt64:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001507 XCTAssertEqual(value, 402);
Austin Schuh40c16522018-10-28 20:27:54 -07001508 XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]);
1509 XCTAssertTrue([dict getInt64:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001510 XCTAssertEqual(value, 400);
Austin Schuh40c16522018-10-28 20:27:54 -07001511 XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]);
1512 XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001513 XCTAssertEqual(value, 401);
1514
1515 [dict2 release];
1516 [dict release];
1517}
1518
1519@end
1520
1521#pragma mark - String -> Bool
1522
1523@interface GPBStringBoolDictionaryTests : XCTestCase
1524@end
1525
1526@implementation GPBStringBoolDictionaryTests
1527
1528- (void)testEmpty {
1529 GPBStringBoolDictionary *dict = [[GPBStringBoolDictionary alloc] init];
1530 XCTAssertNotNil(dict);
1531 XCTAssertEqual(dict.count, 0U);
Austin Schuh40c16522018-10-28 20:27:54 -07001532 XCTAssertFalse([dict getBool:NULL forKey:@"foo"]);
1533 [dict enumerateKeysAndBoolsUsingBlock:^(NSString *aKey, BOOL aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -05001534 #pragma unused(aKey, aValue, stop)
1535 XCTFail(@"Shouldn't get here!");
1536 }];
1537 [dict release];
1538}
1539
1540- (void)testOne {
Austin Schuh40c16522018-10-28 20:27:54 -07001541 GPBStringBoolDictionary *dict = [[GPBStringBoolDictionary alloc] init];
1542 [dict setBool:YES forKey:@"foo"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001543 XCTAssertNotNil(dict);
1544 XCTAssertEqual(dict.count, 1U);
1545 BOOL value;
Austin Schuh40c16522018-10-28 20:27:54 -07001546 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
1547 XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001548 XCTAssertEqual(value, YES);
Austin Schuh40c16522018-10-28 20:27:54 -07001549 XCTAssertFalse([dict getBool:NULL forKey:@"bar"]);
1550 [dict enumerateKeysAndBoolsUsingBlock:^(NSString *aKey, BOOL aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -05001551 XCTAssertEqualObjects(aKey, @"foo");
1552 XCTAssertEqual(aValue, YES);
1553 XCTAssertNotEqual(stop, NULL);
1554 }];
Austin Schuh40c16522018-10-28 20:27:54 -07001555 [dict release];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001556}
1557
1558- (void)testBasics {
1559 const NSString *kKeys[] = { @"foo", @"bar", @"baz" };
1560 const BOOL kValues[] = { YES, YES, NO };
1561 GPBStringBoolDictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07001562 [[GPBStringBoolDictionary alloc] initWithBools:kValues
1563 forKeys:kKeys
1564 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001565 XCTAssertNotNil(dict);
1566 XCTAssertEqual(dict.count, 3U);
1567 BOOL value;
Austin Schuh40c16522018-10-28 20:27:54 -07001568 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
1569 XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001570 XCTAssertEqual(value, YES);
Austin Schuh40c16522018-10-28 20:27:54 -07001571 XCTAssertTrue([dict getBool:NULL forKey:@"bar"]);
1572 XCTAssertTrue([dict getBool:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001573 XCTAssertEqual(value, YES);
Austin Schuh40c16522018-10-28 20:27:54 -07001574 XCTAssertTrue([dict getBool:NULL forKey:@"baz"]);
1575 XCTAssertTrue([dict getBool:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001576 XCTAssertEqual(value, NO);
Austin Schuh40c16522018-10-28 20:27:54 -07001577 XCTAssertFalse([dict getBool:NULL forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001578
1579 __block NSUInteger idx = 0;
1580 NSString **seenKeys = malloc(3 * sizeof(NSString*));
1581 BOOL *seenValues = malloc(3 * sizeof(BOOL));
Austin Schuh40c16522018-10-28 20:27:54 -07001582 [dict enumerateKeysAndBoolsUsingBlock:^(NSString *aKey, BOOL aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -05001583 XCTAssertLessThan(idx, 3U);
1584 seenKeys[idx] = aKey;
1585 seenValues[idx] = aValue;
1586 XCTAssertNotEqual(stop, NULL);
1587 ++idx;
1588 }];
1589 for (int i = 0; i < 3; ++i) {
1590 BOOL foundKey = NO;
1591 for (int j = 0; (j < 3) && !foundKey; ++j) {
1592 if ([kKeys[i] isEqual:seenKeys[j]]) {
1593 foundKey = YES;
1594 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
1595 }
1596 }
1597 XCTAssertTrue(foundKey, @"i = %d", i);
1598 }
1599 free(seenKeys);
1600 free(seenValues);
1601
1602 // Stopping the enumeration.
1603 idx = 0;
Austin Schuh40c16522018-10-28 20:27:54 -07001604 [dict enumerateKeysAndBoolsUsingBlock:^(NSString *aKey, BOOL aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -05001605 #pragma unused(aKey, aValue)
1606 if (idx == 1) *stop = YES;
1607 XCTAssertNotEqual(idx, 2U);
1608 ++idx;
1609 }];
1610 [dict release];
1611}
1612
1613- (void)testEquality {
1614 const NSString *kKeys1[] = { @"foo", @"bar", @"baz", @"mumble" };
1615 const NSString *kKeys2[] = { @"bar", @"foo", @"mumble" };
1616 const BOOL kValues1[] = { YES, YES, NO };
1617 const BOOL kValues2[] = { YES, NO, NO };
1618 const BOOL kValues3[] = { YES, YES, NO, NO };
1619 GPBStringBoolDictionary *dict1 =
Austin Schuh40c16522018-10-28 20:27:54 -07001620 [[GPBStringBoolDictionary alloc] initWithBools:kValues1
1621 forKeys:kKeys1
1622 count:GPBARRAYSIZE(kValues1)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001623 XCTAssertNotNil(dict1);
1624 GPBStringBoolDictionary *dict1prime =
Austin Schuh40c16522018-10-28 20:27:54 -07001625 [[GPBStringBoolDictionary alloc] initWithBools:kValues1
1626 forKeys:kKeys1
1627 count:GPBARRAYSIZE(kValues1)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001628 XCTAssertNotNil(dict1prime);
1629 GPBStringBoolDictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -07001630 [[GPBStringBoolDictionary alloc] initWithBools:kValues2
1631 forKeys:kKeys1
1632 count:GPBARRAYSIZE(kValues2)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001633 XCTAssertNotNil(dict2);
1634 GPBStringBoolDictionary *dict3 =
Austin Schuh40c16522018-10-28 20:27:54 -07001635 [[GPBStringBoolDictionary alloc] initWithBools:kValues1
1636 forKeys:kKeys2
1637 count:GPBARRAYSIZE(kValues1)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001638 XCTAssertNotNil(dict3);
1639 GPBStringBoolDictionary *dict4 =
Austin Schuh40c16522018-10-28 20:27:54 -07001640 [[GPBStringBoolDictionary alloc] initWithBools:kValues3
1641 forKeys:kKeys1
1642 count:GPBARRAYSIZE(kValues3)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001643 XCTAssertNotNil(dict4);
1644
1645 // 1/1Prime should be different objects, but equal.
1646 XCTAssertNotEqual(dict1, dict1prime);
1647 XCTAssertEqualObjects(dict1, dict1prime);
1648 // Equal, so they must have same hash.
1649 XCTAssertEqual([dict1 hash], [dict1prime hash]);
1650
1651 // 2 is same keys, different values; not equal.
1652 XCTAssertNotEqualObjects(dict1, dict2);
1653
1654 // 3 is different keys, same values; not equal.
1655 XCTAssertNotEqualObjects(dict1, dict3);
1656
1657 // 4 extra pair; not equal
1658 XCTAssertNotEqualObjects(dict1, dict4);
1659
1660 [dict1 release];
1661 [dict1prime release];
1662 [dict2 release];
1663 [dict3 release];
1664 [dict4 release];
1665}
1666
1667- (void)testCopy {
1668 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
1669 const BOOL kValues[] = { YES, YES, NO, NO };
1670 GPBStringBoolDictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07001671 [[GPBStringBoolDictionary alloc] initWithBools:kValues
1672 forKeys:kKeys
1673 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001674 XCTAssertNotNil(dict);
1675
1676 GPBStringBoolDictionary *dict2 = [dict copy];
1677 XCTAssertNotNil(dict2);
1678
1679 // Should be new object but equal.
1680 XCTAssertNotEqual(dict, dict2);
1681 XCTAssertEqualObjects(dict, dict2);
1682 XCTAssertTrue([dict2 isKindOfClass:[GPBStringBoolDictionary class]]);
1683
1684 [dict2 release];
1685 [dict release];
1686}
1687
1688- (void)testDictionaryFromDictionary {
1689 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
1690 const BOOL kValues[] = { YES, YES, NO, NO };
1691 GPBStringBoolDictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07001692 [[GPBStringBoolDictionary alloc] initWithBools:kValues
1693 forKeys:kKeys
1694 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001695 XCTAssertNotNil(dict);
1696
1697 GPBStringBoolDictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -07001698 [[GPBStringBoolDictionary alloc] initWithDictionary:dict];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001699 XCTAssertNotNil(dict2);
1700
1701 // Should be new pointer, but equal objects.
1702 XCTAssertNotEqual(dict, dict2);
1703 XCTAssertEqualObjects(dict, dict2);
Austin Schuh40c16522018-10-28 20:27:54 -07001704 [dict2 release];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001705 [dict release];
1706}
1707
1708- (void)testAdds {
Austin Schuh40c16522018-10-28 20:27:54 -07001709 GPBStringBoolDictionary *dict = [[GPBStringBoolDictionary alloc] init];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001710 XCTAssertNotNil(dict);
1711
1712 XCTAssertEqual(dict.count, 0U);
Austin Schuh40c16522018-10-28 20:27:54 -07001713 [dict setBool:YES forKey:@"foo"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001714 XCTAssertEqual(dict.count, 1U);
1715
1716 const NSString *kKeys[] = { @"bar", @"baz", @"mumble" };
1717 const BOOL kValues[] = { YES, NO, NO };
1718 GPBStringBoolDictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -07001719 [[GPBStringBoolDictionary alloc] initWithBools:kValues
1720 forKeys:kKeys
1721 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001722 XCTAssertNotNil(dict2);
1723 [dict addEntriesFromDictionary:dict2];
1724 XCTAssertEqual(dict.count, 4U);
1725
1726 BOOL value;
Austin Schuh40c16522018-10-28 20:27:54 -07001727 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
1728 XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001729 XCTAssertEqual(value, YES);
Austin Schuh40c16522018-10-28 20:27:54 -07001730 XCTAssertTrue([dict getBool:NULL forKey:@"bar"]);
1731 XCTAssertTrue([dict getBool:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001732 XCTAssertEqual(value, YES);
Austin Schuh40c16522018-10-28 20:27:54 -07001733 XCTAssertTrue([dict getBool:NULL forKey:@"baz"]);
1734 XCTAssertTrue([dict getBool:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001735 XCTAssertEqual(value, NO);
Austin Schuh40c16522018-10-28 20:27:54 -07001736 XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]);
1737 XCTAssertTrue([dict getBool:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001738 XCTAssertEqual(value, NO);
1739 [dict2 release];
Austin Schuh40c16522018-10-28 20:27:54 -07001740 [dict release];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001741}
1742
1743- (void)testRemove {
1744 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
1745 const BOOL kValues[] = { YES, YES, NO, NO };
1746 GPBStringBoolDictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07001747 [[GPBStringBoolDictionary alloc] initWithBools:kValues
1748 forKeys:kKeys
1749 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001750 XCTAssertNotNil(dict);
1751 XCTAssertEqual(dict.count, 4U);
1752
Austin Schuh40c16522018-10-28 20:27:54 -07001753 [dict removeBoolForKey:@"bar"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001754 XCTAssertEqual(dict.count, 3U);
1755 BOOL value;
Austin Schuh40c16522018-10-28 20:27:54 -07001756 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
1757 XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001758 XCTAssertEqual(value, YES);
Austin Schuh40c16522018-10-28 20:27:54 -07001759 XCTAssertFalse([dict getBool:NULL forKey:@"bar"]);
1760 XCTAssertTrue([dict getBool:NULL forKey:@"baz"]);
1761 XCTAssertTrue([dict getBool:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001762 XCTAssertEqual(value, NO);
Austin Schuh40c16522018-10-28 20:27:54 -07001763 XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]);
1764 XCTAssertTrue([dict getBool:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001765 XCTAssertEqual(value, NO);
1766
1767 // Remove again does nothing.
Austin Schuh40c16522018-10-28 20:27:54 -07001768 [dict removeBoolForKey:@"bar"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001769 XCTAssertEqual(dict.count, 3U);
Austin Schuh40c16522018-10-28 20:27:54 -07001770 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
1771 XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001772 XCTAssertEqual(value, YES);
Austin Schuh40c16522018-10-28 20:27:54 -07001773 XCTAssertFalse([dict getBool:NULL forKey:@"bar"]);
1774 XCTAssertTrue([dict getBool:NULL forKey:@"baz"]);
1775 XCTAssertTrue([dict getBool:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001776 XCTAssertEqual(value, NO);
Austin Schuh40c16522018-10-28 20:27:54 -07001777 XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]);
1778 XCTAssertTrue([dict getBool:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001779 XCTAssertEqual(value, NO);
1780
Austin Schuh40c16522018-10-28 20:27:54 -07001781 [dict removeBoolForKey:@"mumble"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001782 XCTAssertEqual(dict.count, 2U);
Austin Schuh40c16522018-10-28 20:27:54 -07001783 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
1784 XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001785 XCTAssertEqual(value, YES);
Austin Schuh40c16522018-10-28 20:27:54 -07001786 XCTAssertFalse([dict getBool:NULL forKey:@"bar"]);
1787 XCTAssertTrue([dict getBool:NULL forKey:@"baz"]);
1788 XCTAssertTrue([dict getBool:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001789 XCTAssertEqual(value, NO);
Austin Schuh40c16522018-10-28 20:27:54 -07001790 XCTAssertFalse([dict getBool:NULL forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001791
1792 [dict removeAll];
1793 XCTAssertEqual(dict.count, 0U);
Austin Schuh40c16522018-10-28 20:27:54 -07001794 XCTAssertFalse([dict getBool:NULL forKey:@"foo"]);
1795 XCTAssertFalse([dict getBool:NULL forKey:@"bar"]);
1796 XCTAssertFalse([dict getBool:NULL forKey:@"baz"]);
1797 XCTAssertFalse([dict getBool:NULL forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001798 [dict release];
1799}
1800
1801- (void)testInplaceMutation {
1802 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
1803 const BOOL kValues[] = { YES, YES, NO, NO };
1804 GPBStringBoolDictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07001805 [[GPBStringBoolDictionary alloc] initWithBools:kValues
1806 forKeys:kKeys
1807 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001808 XCTAssertNotNil(dict);
1809 XCTAssertEqual(dict.count, 4U);
1810 BOOL value;
Austin Schuh40c16522018-10-28 20:27:54 -07001811 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
1812 XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001813 XCTAssertEqual(value, YES);
Austin Schuh40c16522018-10-28 20:27:54 -07001814 XCTAssertTrue([dict getBool:NULL forKey:@"bar"]);
1815 XCTAssertTrue([dict getBool:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001816 XCTAssertEqual(value, YES);
Austin Schuh40c16522018-10-28 20:27:54 -07001817 XCTAssertTrue([dict getBool:NULL forKey:@"baz"]);
1818 XCTAssertTrue([dict getBool:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001819 XCTAssertEqual(value, NO);
Austin Schuh40c16522018-10-28 20:27:54 -07001820 XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]);
1821 XCTAssertTrue([dict getBool:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001822 XCTAssertEqual(value, NO);
1823
Austin Schuh40c16522018-10-28 20:27:54 -07001824 [dict setBool:NO forKey:@"foo"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001825 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -07001826 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
1827 XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001828 XCTAssertEqual(value, NO);
Austin Schuh40c16522018-10-28 20:27:54 -07001829 XCTAssertTrue([dict getBool:NULL forKey:@"bar"]);
1830 XCTAssertTrue([dict getBool:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001831 XCTAssertEqual(value, YES);
Austin Schuh40c16522018-10-28 20:27:54 -07001832 XCTAssertTrue([dict getBool:NULL forKey:@"baz"]);
1833 XCTAssertTrue([dict getBool:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001834 XCTAssertEqual(value, NO);
Austin Schuh40c16522018-10-28 20:27:54 -07001835 XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]);
1836 XCTAssertTrue([dict getBool:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001837 XCTAssertEqual(value, NO);
1838
Austin Schuh40c16522018-10-28 20:27:54 -07001839 [dict setBool:YES forKey:@"mumble"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001840 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -07001841 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
1842 XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001843 XCTAssertEqual(value, NO);
Austin Schuh40c16522018-10-28 20:27:54 -07001844 XCTAssertTrue([dict getBool:NULL forKey:@"bar"]);
1845 XCTAssertTrue([dict getBool:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001846 XCTAssertEqual(value, YES);
Austin Schuh40c16522018-10-28 20:27:54 -07001847 XCTAssertTrue([dict getBool:NULL forKey:@"baz"]);
1848 XCTAssertTrue([dict getBool:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001849 XCTAssertEqual(value, NO);
Austin Schuh40c16522018-10-28 20:27:54 -07001850 XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]);
1851 XCTAssertTrue([dict getBool:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001852 XCTAssertEqual(value, YES);
1853
1854 const NSString *kKeys2[] = { @"bar", @"baz" };
1855 const BOOL kValues2[] = { NO, YES };
1856 GPBStringBoolDictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -07001857 [[GPBStringBoolDictionary alloc] initWithBools:kValues2
1858 forKeys:kKeys2
1859 count:GPBARRAYSIZE(kValues2)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001860 XCTAssertNotNil(dict2);
1861 [dict addEntriesFromDictionary:dict2];
1862 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -07001863 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]);
1864 XCTAssertTrue([dict getBool:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001865 XCTAssertEqual(value, NO);
Austin Schuh40c16522018-10-28 20:27:54 -07001866 XCTAssertTrue([dict getBool:NULL forKey:@"bar"]);
1867 XCTAssertTrue([dict getBool:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001868 XCTAssertEqual(value, NO);
Austin Schuh40c16522018-10-28 20:27:54 -07001869 XCTAssertTrue([dict getBool:NULL forKey:@"baz"]);
1870 XCTAssertTrue([dict getBool:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001871 XCTAssertEqual(value, YES);
Austin Schuh40c16522018-10-28 20:27:54 -07001872 XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]);
1873 XCTAssertTrue([dict getBool:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001874 XCTAssertEqual(value, YES);
1875
1876 [dict2 release];
1877 [dict release];
1878}
1879
1880@end
1881
1882#pragma mark - String -> Float
1883
1884@interface GPBStringFloatDictionaryTests : XCTestCase
1885@end
1886
1887@implementation GPBStringFloatDictionaryTests
1888
1889- (void)testEmpty {
1890 GPBStringFloatDictionary *dict = [[GPBStringFloatDictionary alloc] init];
1891 XCTAssertNotNil(dict);
1892 XCTAssertEqual(dict.count, 0U);
Austin Schuh40c16522018-10-28 20:27:54 -07001893 XCTAssertFalse([dict getFloat:NULL forKey:@"foo"]);
1894 [dict enumerateKeysAndFloatsUsingBlock:^(NSString *aKey, float aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -05001895 #pragma unused(aKey, aValue, stop)
1896 XCTFail(@"Shouldn't get here!");
1897 }];
1898 [dict release];
1899}
1900
1901- (void)testOne {
Austin Schuh40c16522018-10-28 20:27:54 -07001902 GPBStringFloatDictionary *dict = [[GPBStringFloatDictionary alloc] init];
1903 [dict setFloat:500.f forKey:@"foo"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001904 XCTAssertNotNil(dict);
1905 XCTAssertEqual(dict.count, 1U);
1906 float value;
Austin Schuh40c16522018-10-28 20:27:54 -07001907 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
1908 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001909 XCTAssertEqual(value, 500.f);
Austin Schuh40c16522018-10-28 20:27:54 -07001910 XCTAssertFalse([dict getFloat:NULL forKey:@"bar"]);
1911 [dict enumerateKeysAndFloatsUsingBlock:^(NSString *aKey, float aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -05001912 XCTAssertEqualObjects(aKey, @"foo");
1913 XCTAssertEqual(aValue, 500.f);
1914 XCTAssertNotEqual(stop, NULL);
1915 }];
Austin Schuh40c16522018-10-28 20:27:54 -07001916 [dict release];
Brian Silverman9c614bc2016-02-15 20:20:02 -05001917}
1918
1919- (void)testBasics {
1920 const NSString *kKeys[] = { @"foo", @"bar", @"baz" };
1921 const float kValues[] = { 500.f, 501.f, 502.f };
1922 GPBStringFloatDictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07001923 [[GPBStringFloatDictionary alloc] initWithFloats:kValues
Brian Silverman9c614bc2016-02-15 20:20:02 -05001924 forKeys:kKeys
1925 count:GPBARRAYSIZE(kValues)];
1926 XCTAssertNotNil(dict);
1927 XCTAssertEqual(dict.count, 3U);
1928 float value;
Austin Schuh40c16522018-10-28 20:27:54 -07001929 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
1930 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001931 XCTAssertEqual(value, 500.f);
Austin Schuh40c16522018-10-28 20:27:54 -07001932 XCTAssertTrue([dict getFloat:NULL forKey:@"bar"]);
1933 XCTAssertTrue([dict getFloat:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001934 XCTAssertEqual(value, 501.f);
Austin Schuh40c16522018-10-28 20:27:54 -07001935 XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]);
1936 XCTAssertTrue([dict getFloat:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001937 XCTAssertEqual(value, 502.f);
Austin Schuh40c16522018-10-28 20:27:54 -07001938 XCTAssertFalse([dict getFloat:NULL forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05001939
1940 __block NSUInteger idx = 0;
1941 NSString **seenKeys = malloc(3 * sizeof(NSString*));
1942 float *seenValues = malloc(3 * sizeof(float));
Austin Schuh40c16522018-10-28 20:27:54 -07001943 [dict enumerateKeysAndFloatsUsingBlock:^(NSString *aKey, float aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -05001944 XCTAssertLessThan(idx, 3U);
1945 seenKeys[idx] = aKey;
1946 seenValues[idx] = aValue;
1947 XCTAssertNotEqual(stop, NULL);
1948 ++idx;
1949 }];
1950 for (int i = 0; i < 3; ++i) {
1951 BOOL foundKey = NO;
1952 for (int j = 0; (j < 3) && !foundKey; ++j) {
1953 if ([kKeys[i] isEqual:seenKeys[j]]) {
1954 foundKey = YES;
1955 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
1956 }
1957 }
1958 XCTAssertTrue(foundKey, @"i = %d", i);
1959 }
1960 free(seenKeys);
1961 free(seenValues);
1962
1963 // Stopping the enumeration.
1964 idx = 0;
Austin Schuh40c16522018-10-28 20:27:54 -07001965 [dict enumerateKeysAndFloatsUsingBlock:^(NSString *aKey, float aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -05001966 #pragma unused(aKey, aValue)
1967 if (idx == 1) *stop = YES;
1968 XCTAssertNotEqual(idx, 2U);
1969 ++idx;
1970 }];
1971 [dict release];
1972}
1973
1974- (void)testEquality {
1975 const NSString *kKeys1[] = { @"foo", @"bar", @"baz", @"mumble" };
1976 const NSString *kKeys2[] = { @"bar", @"foo", @"mumble" };
1977 const float kValues1[] = { 500.f, 501.f, 502.f };
1978 const float kValues2[] = { 500.f, 503.f, 502.f };
1979 const float kValues3[] = { 500.f, 501.f, 502.f, 503.f };
1980 GPBStringFloatDictionary *dict1 =
Austin Schuh40c16522018-10-28 20:27:54 -07001981 [[GPBStringFloatDictionary alloc] initWithFloats:kValues1
Brian Silverman9c614bc2016-02-15 20:20:02 -05001982 forKeys:kKeys1
1983 count:GPBARRAYSIZE(kValues1)];
1984 XCTAssertNotNil(dict1);
1985 GPBStringFloatDictionary *dict1prime =
Austin Schuh40c16522018-10-28 20:27:54 -07001986 [[GPBStringFloatDictionary alloc] initWithFloats:kValues1
Brian Silverman9c614bc2016-02-15 20:20:02 -05001987 forKeys:kKeys1
1988 count:GPBARRAYSIZE(kValues1)];
1989 XCTAssertNotNil(dict1prime);
1990 GPBStringFloatDictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -07001991 [[GPBStringFloatDictionary alloc] initWithFloats:kValues2
Brian Silverman9c614bc2016-02-15 20:20:02 -05001992 forKeys:kKeys1
1993 count:GPBARRAYSIZE(kValues2)];
1994 XCTAssertNotNil(dict2);
1995 GPBStringFloatDictionary *dict3 =
Austin Schuh40c16522018-10-28 20:27:54 -07001996 [[GPBStringFloatDictionary alloc] initWithFloats:kValues1
Brian Silverman9c614bc2016-02-15 20:20:02 -05001997 forKeys:kKeys2
1998 count:GPBARRAYSIZE(kValues1)];
1999 XCTAssertNotNil(dict3);
2000 GPBStringFloatDictionary *dict4 =
Austin Schuh40c16522018-10-28 20:27:54 -07002001 [[GPBStringFloatDictionary alloc] initWithFloats:kValues3
Brian Silverman9c614bc2016-02-15 20:20:02 -05002002 forKeys:kKeys1
2003 count:GPBARRAYSIZE(kValues3)];
2004 XCTAssertNotNil(dict4);
2005
2006 // 1/1Prime should be different objects, but equal.
2007 XCTAssertNotEqual(dict1, dict1prime);
2008 XCTAssertEqualObjects(dict1, dict1prime);
2009 // Equal, so they must have same hash.
2010 XCTAssertEqual([dict1 hash], [dict1prime hash]);
2011
2012 // 2 is same keys, different values; not equal.
2013 XCTAssertNotEqualObjects(dict1, dict2);
2014
2015 // 3 is different keys, same values; not equal.
2016 XCTAssertNotEqualObjects(dict1, dict3);
2017
2018 // 4 extra pair; not equal
2019 XCTAssertNotEqualObjects(dict1, dict4);
2020
2021 [dict1 release];
2022 [dict1prime release];
2023 [dict2 release];
2024 [dict3 release];
2025 [dict4 release];
2026}
2027
2028- (void)testCopy {
2029 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
2030 const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
2031 GPBStringFloatDictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07002032 [[GPBStringFloatDictionary alloc] initWithFloats:kValues
Brian Silverman9c614bc2016-02-15 20:20:02 -05002033 forKeys:kKeys
2034 count:GPBARRAYSIZE(kValues)];
2035 XCTAssertNotNil(dict);
2036
2037 GPBStringFloatDictionary *dict2 = [dict copy];
2038 XCTAssertNotNil(dict2);
2039
2040 // Should be new object but equal.
2041 XCTAssertNotEqual(dict, dict2);
2042 XCTAssertEqualObjects(dict, dict2);
2043 XCTAssertTrue([dict2 isKindOfClass:[GPBStringFloatDictionary class]]);
2044
2045 [dict2 release];
2046 [dict release];
2047}
2048
2049- (void)testDictionaryFromDictionary {
2050 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
2051 const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
2052 GPBStringFloatDictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07002053 [[GPBStringFloatDictionary alloc] initWithFloats:kValues
Brian Silverman9c614bc2016-02-15 20:20:02 -05002054 forKeys:kKeys
2055 count:GPBARRAYSIZE(kValues)];
2056 XCTAssertNotNil(dict);
2057
2058 GPBStringFloatDictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -07002059 [[GPBStringFloatDictionary alloc] initWithDictionary:dict];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002060 XCTAssertNotNil(dict2);
2061
2062 // Should be new pointer, but equal objects.
2063 XCTAssertNotEqual(dict, dict2);
2064 XCTAssertEqualObjects(dict, dict2);
Austin Schuh40c16522018-10-28 20:27:54 -07002065 [dict2 release];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002066 [dict release];
2067}
2068
2069- (void)testAdds {
Austin Schuh40c16522018-10-28 20:27:54 -07002070 GPBStringFloatDictionary *dict = [[GPBStringFloatDictionary alloc] init];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002071 XCTAssertNotNil(dict);
2072
2073 XCTAssertEqual(dict.count, 0U);
Austin Schuh40c16522018-10-28 20:27:54 -07002074 [dict setFloat:500.f forKey:@"foo"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002075 XCTAssertEqual(dict.count, 1U);
2076
2077 const NSString *kKeys[] = { @"bar", @"baz", @"mumble" };
2078 const float kValues[] = { 501.f, 502.f, 503.f };
2079 GPBStringFloatDictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -07002080 [[GPBStringFloatDictionary alloc] initWithFloats:kValues
Brian Silverman9c614bc2016-02-15 20:20:02 -05002081 forKeys:kKeys
2082 count:GPBARRAYSIZE(kValues)];
2083 XCTAssertNotNil(dict2);
2084 [dict addEntriesFromDictionary:dict2];
2085 XCTAssertEqual(dict.count, 4U);
2086
2087 float value;
Austin Schuh40c16522018-10-28 20:27:54 -07002088 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
2089 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002090 XCTAssertEqual(value, 500.f);
Austin Schuh40c16522018-10-28 20:27:54 -07002091 XCTAssertTrue([dict getFloat:NULL forKey:@"bar"]);
2092 XCTAssertTrue([dict getFloat:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002093 XCTAssertEqual(value, 501.f);
Austin Schuh40c16522018-10-28 20:27:54 -07002094 XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]);
2095 XCTAssertTrue([dict getFloat:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002096 XCTAssertEqual(value, 502.f);
Austin Schuh40c16522018-10-28 20:27:54 -07002097 XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]);
2098 XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002099 XCTAssertEqual(value, 503.f);
2100 [dict2 release];
Austin Schuh40c16522018-10-28 20:27:54 -07002101 [dict release];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002102}
2103
2104- (void)testRemove {
2105 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
2106 const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
2107 GPBStringFloatDictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07002108 [[GPBStringFloatDictionary alloc] initWithFloats:kValues
2109 forKeys:kKeys
2110 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002111 XCTAssertNotNil(dict);
2112 XCTAssertEqual(dict.count, 4U);
2113
Austin Schuh40c16522018-10-28 20:27:54 -07002114 [dict removeFloatForKey:@"bar"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002115 XCTAssertEqual(dict.count, 3U);
2116 float value;
Austin Schuh40c16522018-10-28 20:27:54 -07002117 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
2118 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002119 XCTAssertEqual(value, 500.f);
Austin Schuh40c16522018-10-28 20:27:54 -07002120 XCTAssertFalse([dict getFloat:NULL forKey:@"bar"]);
2121 XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]);
2122 XCTAssertTrue([dict getFloat:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002123 XCTAssertEqual(value, 502.f);
Austin Schuh40c16522018-10-28 20:27:54 -07002124 XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]);
2125 XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002126 XCTAssertEqual(value, 503.f);
2127
2128 // Remove again does nothing.
Austin Schuh40c16522018-10-28 20:27:54 -07002129 [dict removeFloatForKey:@"bar"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002130 XCTAssertEqual(dict.count, 3U);
Austin Schuh40c16522018-10-28 20:27:54 -07002131 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
2132 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002133 XCTAssertEqual(value, 500.f);
Austin Schuh40c16522018-10-28 20:27:54 -07002134 XCTAssertFalse([dict getFloat:NULL forKey:@"bar"]);
2135 XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]);
2136 XCTAssertTrue([dict getFloat:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002137 XCTAssertEqual(value, 502.f);
Austin Schuh40c16522018-10-28 20:27:54 -07002138 XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]);
2139 XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002140 XCTAssertEqual(value, 503.f);
2141
Austin Schuh40c16522018-10-28 20:27:54 -07002142 [dict removeFloatForKey:@"mumble"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002143 XCTAssertEqual(dict.count, 2U);
Austin Schuh40c16522018-10-28 20:27:54 -07002144 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
2145 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002146 XCTAssertEqual(value, 500.f);
Austin Schuh40c16522018-10-28 20:27:54 -07002147 XCTAssertFalse([dict getFloat:NULL forKey:@"bar"]);
2148 XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]);
2149 XCTAssertTrue([dict getFloat:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002150 XCTAssertEqual(value, 502.f);
Austin Schuh40c16522018-10-28 20:27:54 -07002151 XCTAssertFalse([dict getFloat:NULL forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002152
2153 [dict removeAll];
2154 XCTAssertEqual(dict.count, 0U);
Austin Schuh40c16522018-10-28 20:27:54 -07002155 XCTAssertFalse([dict getFloat:NULL forKey:@"foo"]);
2156 XCTAssertFalse([dict getFloat:NULL forKey:@"bar"]);
2157 XCTAssertFalse([dict getFloat:NULL forKey:@"baz"]);
2158 XCTAssertFalse([dict getFloat:NULL forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002159 [dict release];
2160}
2161
2162- (void)testInplaceMutation {
2163 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
2164 const float kValues[] = { 500.f, 501.f, 502.f, 503.f };
2165 GPBStringFloatDictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07002166 [[GPBStringFloatDictionary alloc] initWithFloats:kValues
2167 forKeys:kKeys
2168 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002169 XCTAssertNotNil(dict);
2170 XCTAssertEqual(dict.count, 4U);
2171 float value;
Austin Schuh40c16522018-10-28 20:27:54 -07002172 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
2173 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002174 XCTAssertEqual(value, 500.f);
Austin Schuh40c16522018-10-28 20:27:54 -07002175 XCTAssertTrue([dict getFloat:NULL forKey:@"bar"]);
2176 XCTAssertTrue([dict getFloat:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002177 XCTAssertEqual(value, 501.f);
Austin Schuh40c16522018-10-28 20:27:54 -07002178 XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]);
2179 XCTAssertTrue([dict getFloat:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002180 XCTAssertEqual(value, 502.f);
Austin Schuh40c16522018-10-28 20:27:54 -07002181 XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]);
2182 XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002183 XCTAssertEqual(value, 503.f);
2184
Austin Schuh40c16522018-10-28 20:27:54 -07002185 [dict setFloat:503.f forKey:@"foo"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002186 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -07002187 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
2188 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002189 XCTAssertEqual(value, 503.f);
Austin Schuh40c16522018-10-28 20:27:54 -07002190 XCTAssertTrue([dict getFloat:NULL forKey:@"bar"]);
2191 XCTAssertTrue([dict getFloat:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002192 XCTAssertEqual(value, 501.f);
Austin Schuh40c16522018-10-28 20:27:54 -07002193 XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]);
2194 XCTAssertTrue([dict getFloat:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002195 XCTAssertEqual(value, 502.f);
Austin Schuh40c16522018-10-28 20:27:54 -07002196 XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]);
2197 XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002198 XCTAssertEqual(value, 503.f);
2199
Austin Schuh40c16522018-10-28 20:27:54 -07002200 [dict setFloat:501.f forKey:@"mumble"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002201 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -07002202 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
2203 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002204 XCTAssertEqual(value, 503.f);
Austin Schuh40c16522018-10-28 20:27:54 -07002205 XCTAssertTrue([dict getFloat:NULL forKey:@"bar"]);
2206 XCTAssertTrue([dict getFloat:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002207 XCTAssertEqual(value, 501.f);
Austin Schuh40c16522018-10-28 20:27:54 -07002208 XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]);
2209 XCTAssertTrue([dict getFloat:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002210 XCTAssertEqual(value, 502.f);
Austin Schuh40c16522018-10-28 20:27:54 -07002211 XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]);
2212 XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002213 XCTAssertEqual(value, 501.f);
2214
2215 const NSString *kKeys2[] = { @"bar", @"baz" };
2216 const float kValues2[] = { 502.f, 500.f };
2217 GPBStringFloatDictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -07002218 [[GPBStringFloatDictionary alloc] initWithFloats:kValues2
Brian Silverman9c614bc2016-02-15 20:20:02 -05002219 forKeys:kKeys2
2220 count:GPBARRAYSIZE(kValues2)];
2221 XCTAssertNotNil(dict2);
2222 [dict addEntriesFromDictionary:dict2];
2223 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -07002224 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]);
2225 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002226 XCTAssertEqual(value, 503.f);
Austin Schuh40c16522018-10-28 20:27:54 -07002227 XCTAssertTrue([dict getFloat:NULL forKey:@"bar"]);
2228 XCTAssertTrue([dict getFloat:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002229 XCTAssertEqual(value, 502.f);
Austin Schuh40c16522018-10-28 20:27:54 -07002230 XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]);
2231 XCTAssertTrue([dict getFloat:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002232 XCTAssertEqual(value, 500.f);
Austin Schuh40c16522018-10-28 20:27:54 -07002233 XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]);
2234 XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002235 XCTAssertEqual(value, 501.f);
2236
2237 [dict2 release];
2238 [dict release];
2239}
2240
2241@end
2242
2243#pragma mark - String -> Double
2244
2245@interface GPBStringDoubleDictionaryTests : XCTestCase
2246@end
2247
2248@implementation GPBStringDoubleDictionaryTests
2249
2250- (void)testEmpty {
2251 GPBStringDoubleDictionary *dict = [[GPBStringDoubleDictionary alloc] init];
2252 XCTAssertNotNil(dict);
2253 XCTAssertEqual(dict.count, 0U);
Austin Schuh40c16522018-10-28 20:27:54 -07002254 XCTAssertFalse([dict getDouble:NULL forKey:@"foo"]);
2255 [dict enumerateKeysAndDoublesUsingBlock:^(NSString *aKey, double aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -05002256 #pragma unused(aKey, aValue, stop)
2257 XCTFail(@"Shouldn't get here!");
2258 }];
2259 [dict release];
2260}
2261
2262- (void)testOne {
Austin Schuh40c16522018-10-28 20:27:54 -07002263 GPBStringDoubleDictionary *dict = [[GPBStringDoubleDictionary alloc] init];
2264 [dict setDouble:600. forKey:@"foo"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002265 XCTAssertNotNil(dict);
2266 XCTAssertEqual(dict.count, 1U);
2267 double value;
Austin Schuh40c16522018-10-28 20:27:54 -07002268 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
2269 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002270 XCTAssertEqual(value, 600.);
Austin Schuh40c16522018-10-28 20:27:54 -07002271 XCTAssertFalse([dict getDouble:NULL forKey:@"bar"]);
2272 [dict enumerateKeysAndDoublesUsingBlock:^(NSString *aKey, double aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -05002273 XCTAssertEqualObjects(aKey, @"foo");
2274 XCTAssertEqual(aValue, 600.);
2275 XCTAssertNotEqual(stop, NULL);
2276 }];
Austin Schuh40c16522018-10-28 20:27:54 -07002277 [dict release];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002278}
2279
2280- (void)testBasics {
2281 const NSString *kKeys[] = { @"foo", @"bar", @"baz" };
2282 const double kValues[] = { 600., 601., 602. };
2283 GPBStringDoubleDictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07002284 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues
2285 forKeys:kKeys
2286 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002287 XCTAssertNotNil(dict);
2288 XCTAssertEqual(dict.count, 3U);
2289 double value;
Austin Schuh40c16522018-10-28 20:27:54 -07002290 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
2291 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002292 XCTAssertEqual(value, 600.);
Austin Schuh40c16522018-10-28 20:27:54 -07002293 XCTAssertTrue([dict getDouble:NULL forKey:@"bar"]);
2294 XCTAssertTrue([dict getDouble:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002295 XCTAssertEqual(value, 601.);
Austin Schuh40c16522018-10-28 20:27:54 -07002296 XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]);
2297 XCTAssertTrue([dict getDouble:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002298 XCTAssertEqual(value, 602.);
Austin Schuh40c16522018-10-28 20:27:54 -07002299 XCTAssertFalse([dict getDouble:NULL forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002300
2301 __block NSUInteger idx = 0;
2302 NSString **seenKeys = malloc(3 * sizeof(NSString*));
2303 double *seenValues = malloc(3 * sizeof(double));
Austin Schuh40c16522018-10-28 20:27:54 -07002304 [dict enumerateKeysAndDoublesUsingBlock:^(NSString *aKey, double aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -05002305 XCTAssertLessThan(idx, 3U);
2306 seenKeys[idx] = aKey;
2307 seenValues[idx] = aValue;
2308 XCTAssertNotEqual(stop, NULL);
2309 ++idx;
2310 }];
2311 for (int i = 0; i < 3; ++i) {
2312 BOOL foundKey = NO;
2313 for (int j = 0; (j < 3) && !foundKey; ++j) {
2314 if ([kKeys[i] isEqual:seenKeys[j]]) {
2315 foundKey = YES;
2316 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
2317 }
2318 }
2319 XCTAssertTrue(foundKey, @"i = %d", i);
2320 }
2321 free(seenKeys);
2322 free(seenValues);
2323
2324 // Stopping the enumeration.
2325 idx = 0;
Austin Schuh40c16522018-10-28 20:27:54 -07002326 [dict enumerateKeysAndDoublesUsingBlock:^(NSString *aKey, double aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -05002327 #pragma unused(aKey, aValue)
2328 if (idx == 1) *stop = YES;
2329 XCTAssertNotEqual(idx, 2U);
2330 ++idx;
2331 }];
2332 [dict release];
2333}
2334
2335- (void)testEquality {
2336 const NSString *kKeys1[] = { @"foo", @"bar", @"baz", @"mumble" };
2337 const NSString *kKeys2[] = { @"bar", @"foo", @"mumble" };
2338 const double kValues1[] = { 600., 601., 602. };
2339 const double kValues2[] = { 600., 603., 602. };
2340 const double kValues3[] = { 600., 601., 602., 603. };
2341 GPBStringDoubleDictionary *dict1 =
Austin Schuh40c16522018-10-28 20:27:54 -07002342 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues1
2343 forKeys:kKeys1
2344 count:GPBARRAYSIZE(kValues1)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002345 XCTAssertNotNil(dict1);
2346 GPBStringDoubleDictionary *dict1prime =
Austin Schuh40c16522018-10-28 20:27:54 -07002347 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues1
2348 forKeys:kKeys1
2349 count:GPBARRAYSIZE(kValues1)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002350 XCTAssertNotNil(dict1prime);
2351 GPBStringDoubleDictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -07002352 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues2
2353 forKeys:kKeys1
2354 count:GPBARRAYSIZE(kValues2)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002355 XCTAssertNotNil(dict2);
2356 GPBStringDoubleDictionary *dict3 =
Austin Schuh40c16522018-10-28 20:27:54 -07002357 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues1
2358 forKeys:kKeys2
2359 count:GPBARRAYSIZE(kValues1)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002360 XCTAssertNotNil(dict3);
2361 GPBStringDoubleDictionary *dict4 =
Austin Schuh40c16522018-10-28 20:27:54 -07002362 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues3
2363 forKeys:kKeys1
2364 count:GPBARRAYSIZE(kValues3)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002365 XCTAssertNotNil(dict4);
2366
2367 // 1/1Prime should be different objects, but equal.
2368 XCTAssertNotEqual(dict1, dict1prime);
2369 XCTAssertEqualObjects(dict1, dict1prime);
2370 // Equal, so they must have same hash.
2371 XCTAssertEqual([dict1 hash], [dict1prime hash]);
2372
2373 // 2 is same keys, different values; not equal.
2374 XCTAssertNotEqualObjects(dict1, dict2);
2375
2376 // 3 is different keys, same values; not equal.
2377 XCTAssertNotEqualObjects(dict1, dict3);
2378
2379 // 4 extra pair; not equal
2380 XCTAssertNotEqualObjects(dict1, dict4);
2381
2382 [dict1 release];
2383 [dict1prime release];
2384 [dict2 release];
2385 [dict3 release];
2386 [dict4 release];
2387}
2388
2389- (void)testCopy {
2390 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
2391 const double kValues[] = { 600., 601., 602., 603. };
2392 GPBStringDoubleDictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07002393 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues
2394 forKeys:kKeys
2395 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002396 XCTAssertNotNil(dict);
2397
2398 GPBStringDoubleDictionary *dict2 = [dict copy];
2399 XCTAssertNotNil(dict2);
2400
2401 // Should be new object but equal.
2402 XCTAssertNotEqual(dict, dict2);
2403 XCTAssertEqualObjects(dict, dict2);
2404 XCTAssertTrue([dict2 isKindOfClass:[GPBStringDoubleDictionary class]]);
2405
2406 [dict2 release];
2407 [dict release];
2408}
2409
2410- (void)testDictionaryFromDictionary {
2411 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
2412 const double kValues[] = { 600., 601., 602., 603. };
2413 GPBStringDoubleDictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07002414 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues
2415 forKeys:kKeys
2416 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002417 XCTAssertNotNil(dict);
2418
2419 GPBStringDoubleDictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -07002420 [[GPBStringDoubleDictionary alloc] initWithDictionary:dict];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002421 XCTAssertNotNil(dict2);
2422
2423 // Should be new pointer, but equal objects.
2424 XCTAssertNotEqual(dict, dict2);
2425 XCTAssertEqualObjects(dict, dict2);
Austin Schuh40c16522018-10-28 20:27:54 -07002426 [dict2 release];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002427 [dict release];
2428}
2429
2430- (void)testAdds {
Austin Schuh40c16522018-10-28 20:27:54 -07002431 GPBStringDoubleDictionary *dict = [[GPBStringDoubleDictionary alloc] init];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002432 XCTAssertNotNil(dict);
2433
2434 XCTAssertEqual(dict.count, 0U);
Austin Schuh40c16522018-10-28 20:27:54 -07002435 [dict setDouble:600. forKey:@"foo"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002436 XCTAssertEqual(dict.count, 1U);
2437
2438 const NSString *kKeys[] = { @"bar", @"baz", @"mumble" };
2439 const double kValues[] = { 601., 602., 603. };
2440 GPBStringDoubleDictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -07002441 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues
2442 forKeys:kKeys
2443 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002444 XCTAssertNotNil(dict2);
2445 [dict addEntriesFromDictionary:dict2];
2446 XCTAssertEqual(dict.count, 4U);
2447
2448 double value;
Austin Schuh40c16522018-10-28 20:27:54 -07002449 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
2450 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002451 XCTAssertEqual(value, 600.);
Austin Schuh40c16522018-10-28 20:27:54 -07002452 XCTAssertTrue([dict getDouble:NULL forKey:@"bar"]);
2453 XCTAssertTrue([dict getDouble:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002454 XCTAssertEqual(value, 601.);
Austin Schuh40c16522018-10-28 20:27:54 -07002455 XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]);
2456 XCTAssertTrue([dict getDouble:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002457 XCTAssertEqual(value, 602.);
Austin Schuh40c16522018-10-28 20:27:54 -07002458 XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]);
2459 XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002460 XCTAssertEqual(value, 603.);
2461 [dict2 release];
Austin Schuh40c16522018-10-28 20:27:54 -07002462 [dict release];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002463}
2464
2465- (void)testRemove {
2466 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
2467 const double kValues[] = { 600., 601., 602., 603. };
2468 GPBStringDoubleDictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07002469 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues
2470 forKeys:kKeys
2471 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002472 XCTAssertNotNil(dict);
2473 XCTAssertEqual(dict.count, 4U);
2474
Austin Schuh40c16522018-10-28 20:27:54 -07002475 [dict removeDoubleForKey:@"bar"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002476 XCTAssertEqual(dict.count, 3U);
2477 double value;
Austin Schuh40c16522018-10-28 20:27:54 -07002478 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
2479 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002480 XCTAssertEqual(value, 600.);
Austin Schuh40c16522018-10-28 20:27:54 -07002481 XCTAssertFalse([dict getDouble:NULL forKey:@"bar"]);
2482 XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]);
2483 XCTAssertTrue([dict getDouble:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002484 XCTAssertEqual(value, 602.);
Austin Schuh40c16522018-10-28 20:27:54 -07002485 XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]);
2486 XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002487 XCTAssertEqual(value, 603.);
2488
2489 // Remove again does nothing.
Austin Schuh40c16522018-10-28 20:27:54 -07002490 [dict removeDoubleForKey:@"bar"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002491 XCTAssertEqual(dict.count, 3U);
Austin Schuh40c16522018-10-28 20:27:54 -07002492 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
2493 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002494 XCTAssertEqual(value, 600.);
Austin Schuh40c16522018-10-28 20:27:54 -07002495 XCTAssertFalse([dict getDouble:NULL forKey:@"bar"]);
2496 XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]);
2497 XCTAssertTrue([dict getDouble:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002498 XCTAssertEqual(value, 602.);
Austin Schuh40c16522018-10-28 20:27:54 -07002499 XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]);
2500 XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002501 XCTAssertEqual(value, 603.);
2502
Austin Schuh40c16522018-10-28 20:27:54 -07002503 [dict removeDoubleForKey:@"mumble"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002504 XCTAssertEqual(dict.count, 2U);
Austin Schuh40c16522018-10-28 20:27:54 -07002505 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
2506 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002507 XCTAssertEqual(value, 600.);
Austin Schuh40c16522018-10-28 20:27:54 -07002508 XCTAssertFalse([dict getDouble:NULL forKey:@"bar"]);
2509 XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]);
2510 XCTAssertTrue([dict getDouble:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002511 XCTAssertEqual(value, 602.);
Austin Schuh40c16522018-10-28 20:27:54 -07002512 XCTAssertFalse([dict getDouble:NULL forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002513
2514 [dict removeAll];
2515 XCTAssertEqual(dict.count, 0U);
Austin Schuh40c16522018-10-28 20:27:54 -07002516 XCTAssertFalse([dict getDouble:NULL forKey:@"foo"]);
2517 XCTAssertFalse([dict getDouble:NULL forKey:@"bar"]);
2518 XCTAssertFalse([dict getDouble:NULL forKey:@"baz"]);
2519 XCTAssertFalse([dict getDouble:NULL forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002520 [dict release];
2521}
2522
2523- (void)testInplaceMutation {
2524 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
2525 const double kValues[] = { 600., 601., 602., 603. };
2526 GPBStringDoubleDictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07002527 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues
2528 forKeys:kKeys
2529 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002530 XCTAssertNotNil(dict);
2531 XCTAssertEqual(dict.count, 4U);
2532 double value;
Austin Schuh40c16522018-10-28 20:27:54 -07002533 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
2534 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002535 XCTAssertEqual(value, 600.);
Austin Schuh40c16522018-10-28 20:27:54 -07002536 XCTAssertTrue([dict getDouble:NULL forKey:@"bar"]);
2537 XCTAssertTrue([dict getDouble:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002538 XCTAssertEqual(value, 601.);
Austin Schuh40c16522018-10-28 20:27:54 -07002539 XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]);
2540 XCTAssertTrue([dict getDouble:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002541 XCTAssertEqual(value, 602.);
Austin Schuh40c16522018-10-28 20:27:54 -07002542 XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]);
2543 XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002544 XCTAssertEqual(value, 603.);
2545
Austin Schuh40c16522018-10-28 20:27:54 -07002546 [dict setDouble:603. forKey:@"foo"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002547 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -07002548 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
2549 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002550 XCTAssertEqual(value, 603.);
Austin Schuh40c16522018-10-28 20:27:54 -07002551 XCTAssertTrue([dict getDouble:NULL forKey:@"bar"]);
2552 XCTAssertTrue([dict getDouble:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002553 XCTAssertEqual(value, 601.);
Austin Schuh40c16522018-10-28 20:27:54 -07002554 XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]);
2555 XCTAssertTrue([dict getDouble:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002556 XCTAssertEqual(value, 602.);
Austin Schuh40c16522018-10-28 20:27:54 -07002557 XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]);
2558 XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002559 XCTAssertEqual(value, 603.);
2560
Austin Schuh40c16522018-10-28 20:27:54 -07002561 [dict setDouble:601. forKey:@"mumble"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002562 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -07002563 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
2564 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002565 XCTAssertEqual(value, 603.);
Austin Schuh40c16522018-10-28 20:27:54 -07002566 XCTAssertTrue([dict getDouble:NULL forKey:@"bar"]);
2567 XCTAssertTrue([dict getDouble:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002568 XCTAssertEqual(value, 601.);
Austin Schuh40c16522018-10-28 20:27:54 -07002569 XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]);
2570 XCTAssertTrue([dict getDouble:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002571 XCTAssertEqual(value, 602.);
Austin Schuh40c16522018-10-28 20:27:54 -07002572 XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]);
2573 XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002574 XCTAssertEqual(value, 601.);
2575
2576 const NSString *kKeys2[] = { @"bar", @"baz" };
2577 const double kValues2[] = { 602., 600. };
2578 GPBStringDoubleDictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -07002579 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues2
2580 forKeys:kKeys2
2581 count:GPBARRAYSIZE(kValues2)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002582 XCTAssertNotNil(dict2);
2583 [dict addEntriesFromDictionary:dict2];
2584 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -07002585 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]);
2586 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002587 XCTAssertEqual(value, 603.);
Austin Schuh40c16522018-10-28 20:27:54 -07002588 XCTAssertTrue([dict getDouble:NULL forKey:@"bar"]);
2589 XCTAssertTrue([dict getDouble:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002590 XCTAssertEqual(value, 602.);
Austin Schuh40c16522018-10-28 20:27:54 -07002591 XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]);
2592 XCTAssertTrue([dict getDouble:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002593 XCTAssertEqual(value, 600.);
Austin Schuh40c16522018-10-28 20:27:54 -07002594 XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]);
2595 XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002596 XCTAssertEqual(value, 601.);
2597
2598 [dict2 release];
2599 [dict release];
2600}
2601
2602@end
2603
2604#pragma mark - String -> Enum
2605
2606@interface GPBStringEnumDictionaryTests : XCTestCase
2607@end
2608
2609@implementation GPBStringEnumDictionaryTests
2610
2611- (void)testEmpty {
2612 GPBStringEnumDictionary *dict = [[GPBStringEnumDictionary alloc] init];
2613 XCTAssertNotNil(dict);
2614 XCTAssertEqual(dict.count, 0U);
Austin Schuh40c16522018-10-28 20:27:54 -07002615 XCTAssertFalse([dict getEnum:NULL forKey:@"foo"]);
2616 [dict enumerateKeysAndEnumsUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -05002617 #pragma unused(aKey, aValue, stop)
2618 XCTFail(@"Shouldn't get here!");
2619 }];
2620 [dict release];
2621}
2622
2623- (void)testOne {
Austin Schuh40c16522018-10-28 20:27:54 -07002624 GPBStringEnumDictionary *dict = [[GPBStringEnumDictionary alloc] init];
2625 [dict setEnum:700 forKey:@"foo"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002626 XCTAssertNotNil(dict);
2627 XCTAssertEqual(dict.count, 1U);
2628 int32_t value;
Austin Schuh40c16522018-10-28 20:27:54 -07002629 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
2630 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002631 XCTAssertEqual(value, 700);
Austin Schuh40c16522018-10-28 20:27:54 -07002632 XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]);
2633 [dict enumerateKeysAndEnumsUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -05002634 XCTAssertEqualObjects(aKey, @"foo");
2635 XCTAssertEqual(aValue, 700);
2636 XCTAssertNotEqual(stop, NULL);
2637 }];
Austin Schuh40c16522018-10-28 20:27:54 -07002638 [dict release];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002639}
2640
2641- (void)testBasics {
2642 const NSString *kKeys[] = { @"foo", @"bar", @"baz" };
2643 const int32_t kValues[] = { 700, 701, 702 };
2644 GPBStringEnumDictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07002645 [[GPBStringEnumDictionary alloc] initWithEnums:kValues
2646 forKeys:kKeys
2647 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002648 XCTAssertNotNil(dict);
2649 XCTAssertEqual(dict.count, 3U);
2650 int32_t value;
Austin Schuh40c16522018-10-28 20:27:54 -07002651 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
2652 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002653 XCTAssertEqual(value, 700);
Austin Schuh40c16522018-10-28 20:27:54 -07002654 XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]);
2655 XCTAssertTrue([dict getEnum:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002656 XCTAssertEqual(value, 701);
Austin Schuh40c16522018-10-28 20:27:54 -07002657 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
2658 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002659 XCTAssertEqual(value, 702);
Austin Schuh40c16522018-10-28 20:27:54 -07002660 XCTAssertFalse([dict getEnum:NULL forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002661
2662 __block NSUInteger idx = 0;
2663 NSString **seenKeys = malloc(3 * sizeof(NSString*));
2664 int32_t *seenValues = malloc(3 * sizeof(int32_t));
Austin Schuh40c16522018-10-28 20:27:54 -07002665 [dict enumerateKeysAndEnumsUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -05002666 XCTAssertLessThan(idx, 3U);
2667 seenKeys[idx] = aKey;
2668 seenValues[idx] = aValue;
2669 XCTAssertNotEqual(stop, NULL);
2670 ++idx;
2671 }];
2672 for (int i = 0; i < 3; ++i) {
2673 BOOL foundKey = NO;
2674 for (int j = 0; (j < 3) && !foundKey; ++j) {
2675 if ([kKeys[i] isEqual:seenKeys[j]]) {
2676 foundKey = YES;
2677 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
2678 }
2679 }
2680 XCTAssertTrue(foundKey, @"i = %d", i);
2681 }
2682 free(seenKeys);
2683 free(seenValues);
2684
2685 // Stopping the enumeration.
2686 idx = 0;
Austin Schuh40c16522018-10-28 20:27:54 -07002687 [dict enumerateKeysAndEnumsUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -05002688 #pragma unused(aKey, aValue)
2689 if (idx == 1) *stop = YES;
2690 XCTAssertNotEqual(idx, 2U);
2691 ++idx;
2692 }];
2693 [dict release];
2694}
2695
2696- (void)testEquality {
2697 const NSString *kKeys1[] = { @"foo", @"bar", @"baz", @"mumble" };
2698 const NSString *kKeys2[] = { @"bar", @"foo", @"mumble" };
2699 const int32_t kValues1[] = { 700, 701, 702 };
2700 const int32_t kValues2[] = { 700, 703, 702 };
2701 const int32_t kValues3[] = { 700, 701, 702, 703 };
2702 GPBStringEnumDictionary *dict1 =
Austin Schuh40c16522018-10-28 20:27:54 -07002703 [[GPBStringEnumDictionary alloc] initWithEnums:kValues1
2704 forKeys:kKeys1
2705 count:GPBARRAYSIZE(kValues1)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002706 XCTAssertNotNil(dict1);
2707 GPBStringEnumDictionary *dict1prime =
Austin Schuh40c16522018-10-28 20:27:54 -07002708 [[GPBStringEnumDictionary alloc] initWithEnums:kValues1
2709 forKeys:kKeys1
2710 count:GPBARRAYSIZE(kValues1)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002711 XCTAssertNotNil(dict1prime);
2712 GPBStringEnumDictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -07002713 [[GPBStringEnumDictionary alloc] initWithEnums:kValues2
2714 forKeys:kKeys1
2715 count:GPBARRAYSIZE(kValues2)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002716 XCTAssertNotNil(dict2);
2717 GPBStringEnumDictionary *dict3 =
Austin Schuh40c16522018-10-28 20:27:54 -07002718 [[GPBStringEnumDictionary alloc] initWithEnums:kValues1
2719 forKeys:kKeys2
2720 count:GPBARRAYSIZE(kValues1)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002721 XCTAssertNotNil(dict3);
2722 GPBStringEnumDictionary *dict4 =
Austin Schuh40c16522018-10-28 20:27:54 -07002723 [[GPBStringEnumDictionary alloc] initWithEnums:kValues3
2724 forKeys:kKeys1
2725 count:GPBARRAYSIZE(kValues3)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002726 XCTAssertNotNil(dict4);
2727
2728 // 1/1Prime should be different objects, but equal.
2729 XCTAssertNotEqual(dict1, dict1prime);
2730 XCTAssertEqualObjects(dict1, dict1prime);
2731 // Equal, so they must have same hash.
2732 XCTAssertEqual([dict1 hash], [dict1prime hash]);
2733
2734 // 2 is same keys, different values; not equal.
2735 XCTAssertNotEqualObjects(dict1, dict2);
2736
2737 // 3 is different keys, same values; not equal.
2738 XCTAssertNotEqualObjects(dict1, dict3);
2739
2740 // 4 extra pair; not equal
2741 XCTAssertNotEqualObjects(dict1, dict4);
2742
2743 [dict1 release];
2744 [dict1prime release];
2745 [dict2 release];
2746 [dict3 release];
2747 [dict4 release];
2748}
2749
2750- (void)testCopy {
2751 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
2752 const int32_t kValues[] = { 700, 701, 702, 703 };
2753 GPBStringEnumDictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07002754 [[GPBStringEnumDictionary alloc] initWithEnums:kValues
2755 forKeys:kKeys
2756 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002757 XCTAssertNotNil(dict);
2758
2759 GPBStringEnumDictionary *dict2 = [dict copy];
2760 XCTAssertNotNil(dict2);
2761
2762 // Should be new object but equal.
2763 XCTAssertNotEqual(dict, dict2);
2764 XCTAssertEqualObjects(dict, dict2);
2765 XCTAssertTrue([dict2 isKindOfClass:[GPBStringEnumDictionary class]]);
2766
2767 [dict2 release];
2768 [dict release];
2769}
2770
2771- (void)testDictionaryFromDictionary {
2772 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
2773 const int32_t kValues[] = { 700, 701, 702, 703 };
2774 GPBStringEnumDictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07002775 [[GPBStringEnumDictionary alloc] initWithEnums:kValues
2776 forKeys:kKeys
2777 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002778 XCTAssertNotNil(dict);
2779
2780 GPBStringEnumDictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -07002781 [[GPBStringEnumDictionary alloc] initWithDictionary:dict];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002782 XCTAssertNotNil(dict2);
2783
2784 // Should be new pointer, but equal objects.
2785 XCTAssertNotEqual(dict, dict2);
2786 XCTAssertEqualObjects(dict, dict2);
Austin Schuh40c16522018-10-28 20:27:54 -07002787 [dict2 release];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002788 [dict release];
2789}
2790
2791- (void)testAdds {
Austin Schuh40c16522018-10-28 20:27:54 -07002792 GPBStringEnumDictionary *dict = [[GPBStringEnumDictionary alloc] init];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002793 XCTAssertNotNil(dict);
2794
2795 XCTAssertEqual(dict.count, 0U);
Austin Schuh40c16522018-10-28 20:27:54 -07002796 [dict setEnum:700 forKey:@"foo"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002797 XCTAssertEqual(dict.count, 1U);
2798
2799 const NSString *kKeys[] = { @"bar", @"baz", @"mumble" };
2800 const int32_t kValues[] = { 701, 702, 703 };
2801 GPBStringEnumDictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -07002802 [[GPBStringEnumDictionary alloc] initWithEnums:kValues
2803 forKeys:kKeys
2804 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002805 XCTAssertNotNil(dict2);
2806 [dict addRawEntriesFromDictionary:dict2];
2807 XCTAssertEqual(dict.count, 4U);
2808
2809 int32_t value;
Austin Schuh40c16522018-10-28 20:27:54 -07002810 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
2811 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002812 XCTAssertEqual(value, 700);
Austin Schuh40c16522018-10-28 20:27:54 -07002813 XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]);
2814 XCTAssertTrue([dict getEnum:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002815 XCTAssertEqual(value, 701);
Austin Schuh40c16522018-10-28 20:27:54 -07002816 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
2817 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002818 XCTAssertEqual(value, 702);
Austin Schuh40c16522018-10-28 20:27:54 -07002819 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
2820 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002821 XCTAssertEqual(value, 703);
2822 [dict2 release];
Austin Schuh40c16522018-10-28 20:27:54 -07002823 [dict release];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002824}
2825
2826- (void)testRemove {
2827 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
2828 const int32_t kValues[] = { 700, 701, 702, 703 };
2829 GPBStringEnumDictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07002830 [[GPBStringEnumDictionary alloc] initWithEnums:kValues
2831 forKeys:kKeys
2832 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002833 XCTAssertNotNil(dict);
2834 XCTAssertEqual(dict.count, 4U);
2835
Austin Schuh40c16522018-10-28 20:27:54 -07002836 [dict removeEnumForKey:@"bar"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002837 XCTAssertEqual(dict.count, 3U);
2838 int32_t value;
Austin Schuh40c16522018-10-28 20:27:54 -07002839 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
2840 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002841 XCTAssertEqual(value, 700);
Austin Schuh40c16522018-10-28 20:27:54 -07002842 XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]);
2843 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
2844 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002845 XCTAssertEqual(value, 702);
Austin Schuh40c16522018-10-28 20:27:54 -07002846 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
2847 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002848 XCTAssertEqual(value, 703);
2849
2850 // Remove again does nothing.
Austin Schuh40c16522018-10-28 20:27:54 -07002851 [dict removeEnumForKey:@"bar"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002852 XCTAssertEqual(dict.count, 3U);
Austin Schuh40c16522018-10-28 20:27:54 -07002853 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
2854 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002855 XCTAssertEqual(value, 700);
Austin Schuh40c16522018-10-28 20:27:54 -07002856 XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]);
2857 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
2858 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002859 XCTAssertEqual(value, 702);
Austin Schuh40c16522018-10-28 20:27:54 -07002860 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
2861 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002862 XCTAssertEqual(value, 703);
2863
Austin Schuh40c16522018-10-28 20:27:54 -07002864 [dict removeEnumForKey:@"mumble"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002865 XCTAssertEqual(dict.count, 2U);
Austin Schuh40c16522018-10-28 20:27:54 -07002866 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
2867 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002868 XCTAssertEqual(value, 700);
Austin Schuh40c16522018-10-28 20:27:54 -07002869 XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]);
2870 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
2871 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002872 XCTAssertEqual(value, 702);
Austin Schuh40c16522018-10-28 20:27:54 -07002873 XCTAssertFalse([dict getEnum:NULL forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002874
2875 [dict removeAll];
2876 XCTAssertEqual(dict.count, 0U);
Austin Schuh40c16522018-10-28 20:27:54 -07002877 XCTAssertFalse([dict getEnum:NULL forKey:@"foo"]);
2878 XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]);
2879 XCTAssertFalse([dict getEnum:NULL forKey:@"baz"]);
2880 XCTAssertFalse([dict getEnum:NULL forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002881 [dict release];
2882}
2883
2884- (void)testInplaceMutation {
2885 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
2886 const int32_t kValues[] = { 700, 701, 702, 703 };
2887 GPBStringEnumDictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07002888 [[GPBStringEnumDictionary alloc] initWithEnums:kValues
2889 forKeys:kKeys
2890 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002891 XCTAssertNotNil(dict);
2892 XCTAssertEqual(dict.count, 4U);
2893 int32_t value;
Austin Schuh40c16522018-10-28 20:27:54 -07002894 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
2895 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002896 XCTAssertEqual(value, 700);
Austin Schuh40c16522018-10-28 20:27:54 -07002897 XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]);
2898 XCTAssertTrue([dict getEnum:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002899 XCTAssertEqual(value, 701);
Austin Schuh40c16522018-10-28 20:27:54 -07002900 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
2901 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002902 XCTAssertEqual(value, 702);
Austin Schuh40c16522018-10-28 20:27:54 -07002903 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
2904 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002905 XCTAssertEqual(value, 703);
2906
Austin Schuh40c16522018-10-28 20:27:54 -07002907 [dict setEnum:703 forKey:@"foo"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002908 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -07002909 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
2910 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002911 XCTAssertEqual(value, 703);
Austin Schuh40c16522018-10-28 20:27:54 -07002912 XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]);
2913 XCTAssertTrue([dict getEnum:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002914 XCTAssertEqual(value, 701);
Austin Schuh40c16522018-10-28 20:27:54 -07002915 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
2916 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002917 XCTAssertEqual(value, 702);
Austin Schuh40c16522018-10-28 20:27:54 -07002918 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
2919 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002920 XCTAssertEqual(value, 703);
2921
Austin Schuh40c16522018-10-28 20:27:54 -07002922 [dict setEnum:701 forKey:@"mumble"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002923 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -07002924 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
2925 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002926 XCTAssertEqual(value, 703);
Austin Schuh40c16522018-10-28 20:27:54 -07002927 XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]);
2928 XCTAssertTrue([dict getEnum:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002929 XCTAssertEqual(value, 701);
Austin Schuh40c16522018-10-28 20:27:54 -07002930 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
2931 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002932 XCTAssertEqual(value, 702);
Austin Schuh40c16522018-10-28 20:27:54 -07002933 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
2934 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002935 XCTAssertEqual(value, 701);
2936
2937 const NSString *kKeys2[] = { @"bar", @"baz" };
2938 const int32_t kValues2[] = { 702, 700 };
2939 GPBStringEnumDictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -07002940 [[GPBStringEnumDictionary alloc] initWithEnums:kValues2
2941 forKeys:kKeys2
2942 count:GPBARRAYSIZE(kValues2)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05002943 XCTAssertNotNil(dict2);
2944 [dict addRawEntriesFromDictionary:dict2];
2945 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -07002946 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
2947 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002948 XCTAssertEqual(value, 703);
Austin Schuh40c16522018-10-28 20:27:54 -07002949 XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]);
2950 XCTAssertTrue([dict getEnum:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002951 XCTAssertEqual(value, 702);
Austin Schuh40c16522018-10-28 20:27:54 -07002952 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
2953 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002954 XCTAssertEqual(value, 700);
Austin Schuh40c16522018-10-28 20:27:54 -07002955 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
2956 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002957 XCTAssertEqual(value, 701);
2958
2959 [dict2 release];
2960 [dict release];
2961}
2962
2963@end
2964
2965#pragma mark - String -> Enum (Unknown Enums)
2966
2967@interface GPBStringEnumDictionaryUnknownEnumTests : XCTestCase
2968@end
2969
2970@implementation GPBStringEnumDictionaryUnknownEnumTests
2971
2972- (void)testRawBasics {
2973 const NSString *kKeys[] = { @"foo", @"bar", @"baz" };
2974 const int32_t kValues[] = { 700, 801, 702 };
2975 GPBStringEnumDictionary *dict =
2976 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
2977 rawValues:kValues
2978 forKeys:kKeys
2979 count:GPBARRAYSIZE(kValues)];
2980 XCTAssertNotNil(dict);
2981 XCTAssertEqual(dict.count, 3U);
2982 XCTAssertTrue(dict.validationFunc == TestingEnum_IsValidValue); // Pointer comparison
2983 int32_t value;
Austin Schuh40c16522018-10-28 20:27:54 -07002984 XCTAssertTrue([dict getRawValue:NULL forKey:@"foo"]);
2985 XCTAssertTrue([dict getRawValue:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002986 XCTAssertEqual(value, 700);
Austin Schuh40c16522018-10-28 20:27:54 -07002987 XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]);
2988 XCTAssertTrue([dict getEnum:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002989 XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue);
Austin Schuh40c16522018-10-28 20:27:54 -07002990 XCTAssertTrue([dict getRawValue:NULL forKey:@"bar"]);
2991 XCTAssertTrue([dict getRawValue:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002992 XCTAssertEqual(value, 801);
Austin Schuh40c16522018-10-28 20:27:54 -07002993 XCTAssertTrue([dict getRawValue:NULL forKey:@"baz"]);
2994 XCTAssertTrue([dict getRawValue:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002995 XCTAssertEqual(value, 702);
Austin Schuh40c16522018-10-28 20:27:54 -07002996 XCTAssertFalse([dict getRawValue:NULL forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05002997
2998 __block NSUInteger idx = 0;
2999 NSString **seenKeys = malloc(3 * sizeof(NSString*));
3000 int32_t *seenValues = malloc(3 * sizeof(int32_t));
Austin Schuh40c16522018-10-28 20:27:54 -07003001 [dict enumerateKeysAndEnumsUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
Brian Silverman9c614bc2016-02-15 20:20:02 -05003002 XCTAssertLessThan(idx, 3U);
3003 seenKeys[idx] = aKey;
3004 seenValues[idx] = aValue;
3005 XCTAssertNotEqual(stop, NULL);
3006 ++idx;
3007 }];
3008 for (int i = 0; i < 3; ++i) {
3009 BOOL foundKey = NO;
3010 for (int j = 0; (j < 3) && !foundKey; ++j) {
3011 if ([kKeys[i] isEqual:seenKeys[j]]) {
3012 foundKey = YES;
3013 if (i == 1) {
3014 XCTAssertEqual(kGPBUnrecognizedEnumeratorValue, seenValues[j], @"i = %d, j = %d", i, j);
3015 } else {
3016 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
3017 }
3018 }
3019 }
3020 XCTAssertTrue(foundKey, @"i = %d", i);
3021 }
3022 idx = 0;
3023 [dict enumerateKeysAndRawValuesUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
3024 XCTAssertLessThan(idx, 3U);
3025 seenKeys[idx] = aKey;
3026 seenValues[idx] = aValue;
3027 XCTAssertNotEqual(stop, NULL);
3028 ++idx;
3029 }];
3030 for (int i = 0; i < 3; ++i) {
3031 BOOL foundKey = NO;
3032 for (int j = 0; (j < 3) && !foundKey; ++j) {
3033 if ([kKeys[i] isEqual:seenKeys[j]]) {
3034 foundKey = YES;
3035 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
3036 }
3037 }
3038 XCTAssertTrue(foundKey, @"i = %d", i);
3039 }
3040 free(seenKeys);
3041 free(seenValues);
3042
3043 // Stopping the enumeration.
3044 idx = 0;
3045 [dict enumerateKeysAndRawValuesUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) {
3046 #pragma unused(aKey, aValue)
3047 if (idx == 1) *stop = YES;
3048 XCTAssertNotEqual(idx, 2U);
3049 ++idx;
3050 }];
3051 [dict release];
3052}
3053
3054- (void)testEqualityWithUnknowns {
3055 const NSString *kKeys1[] = { @"foo", @"bar", @"baz", @"mumble" };
3056 const NSString *kKeys2[] = { @"bar", @"foo", @"mumble" };
3057 const int32_t kValues1[] = { 700, 801, 702 }; // Unknown
3058 const int32_t kValues2[] = { 700, 803, 702 }; // Unknown
3059 const int32_t kValues3[] = { 700, 801, 702, 803 }; // Unknowns
3060 GPBStringEnumDictionary *dict1 =
3061 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3062 rawValues:kValues1
3063 forKeys:kKeys1
3064 count:GPBARRAYSIZE(kValues1)];
3065 XCTAssertNotNil(dict1);
3066 GPBStringEnumDictionary *dict1prime =
3067 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3068 rawValues:kValues1
3069 forKeys:kKeys1
3070 count:GPBARRAYSIZE(kValues1)];
3071 XCTAssertNotNil(dict1prime);
3072 GPBStringEnumDictionary *dict2 =
3073 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3074 rawValues:kValues2
3075 forKeys:kKeys1
3076 count:GPBARRAYSIZE(kValues2)];
3077 XCTAssertNotNil(dict2);
3078 GPBStringEnumDictionary *dict3 =
3079 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3080 rawValues:kValues1
3081 forKeys:kKeys2
3082 count:GPBARRAYSIZE(kValues1)];
3083 XCTAssertNotNil(dict3);
3084 GPBStringEnumDictionary *dict4 =
3085 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3086 rawValues:kValues3
3087 forKeys:kKeys1
3088 count:GPBARRAYSIZE(kValues3)];
3089 XCTAssertNotNil(dict4);
3090
3091 // 1/1Prime should be different objects, but equal.
3092 XCTAssertNotEqual(dict1, dict1prime);
3093 XCTAssertEqualObjects(dict1, dict1prime);
3094 // Equal, so they must have same hash.
3095 XCTAssertEqual([dict1 hash], [dict1prime hash]);
3096
3097 // 2 is same keys, different values; not equal.
3098 XCTAssertNotEqualObjects(dict1, dict2);
3099
3100 // 3 is different keys, same values; not equal.
3101 XCTAssertNotEqualObjects(dict1, dict3);
3102
3103 // 4 extra pair; not equal
3104 XCTAssertNotEqualObjects(dict1, dict4);
3105
3106 [dict1 release];
3107 [dict1prime release];
3108 [dict2 release];
3109 [dict3 release];
3110 [dict4 release];
3111}
3112
3113- (void)testCopyWithUnknowns {
3114 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
3115 const int32_t kValues[] = { 700, 801, 702, 803 }; // Unknown
3116 GPBStringEnumDictionary *dict =
3117 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3118 rawValues:kValues
3119 forKeys:kKeys
3120 count:GPBARRAYSIZE(kValues)];
3121 XCTAssertNotNil(dict);
3122
3123 GPBStringEnumDictionary *dict2 = [dict copy];
3124 XCTAssertNotNil(dict2);
3125
3126 // Should be new pointer, but equal objects.
3127 XCTAssertNotEqual(dict, dict2);
3128 XCTAssertEqual(dict.validationFunc, dict2.validationFunc); // Pointer comparison
3129 XCTAssertEqualObjects(dict, dict2);
3130
3131 [dict2 release];
3132 [dict release];
3133}
3134
3135- (void)testDictionaryFromDictionary {
3136 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
3137 const int32_t kValues[] = { 700, 801, 702, 803 }; // Unknowns
3138 GPBStringEnumDictionary *dict =
3139 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3140 rawValues:kValues
3141 forKeys:kKeys
3142 count:GPBARRAYSIZE(kValues)];
3143 XCTAssertNotNil(dict);
3144
3145 GPBStringEnumDictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -07003146 [[GPBStringEnumDictionary alloc] initWithDictionary:dict];
Brian Silverman9c614bc2016-02-15 20:20:02 -05003147 XCTAssertNotNil(dict2);
3148
3149 // Should be new pointer, but equal objects.
3150 XCTAssertNotEqual(dict, dict2);
3151 XCTAssertEqualObjects(dict, dict2);
3152 XCTAssertEqual(dict.validationFunc, dict2.validationFunc); // Pointer comparison
Austin Schuh40c16522018-10-28 20:27:54 -07003153 [dict2 release];
Brian Silverman9c614bc2016-02-15 20:20:02 -05003154 [dict release];
3155}
3156
3157- (void)testUnknownAdds {
3158 GPBStringEnumDictionary *dict =
Austin Schuh40c16522018-10-28 20:27:54 -07003159 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue];
Brian Silverman9c614bc2016-02-15 20:20:02 -05003160 XCTAssertNotNil(dict);
3161
3162 XCTAssertEqual(dict.count, 0U);
Austin Schuh40c16522018-10-28 20:27:54 -07003163 XCTAssertThrowsSpecificNamed([dict setEnum:801 forKey:@"bar"], // Unknown
Brian Silverman9c614bc2016-02-15 20:20:02 -05003164 NSException, NSInvalidArgumentException);
3165 XCTAssertEqual(dict.count, 0U);
3166 [dict setRawValue:801 forKey:@"bar"]; // Unknown
3167 XCTAssertEqual(dict.count, 1U);
3168
3169 const NSString *kKeys[] = { @"foo", @"baz", @"mumble" };
3170 const int32_t kValues[] = { 700, 702, 803 }; // Unknown
3171 GPBStringEnumDictionary *dict2 =
Austin Schuh40c16522018-10-28 20:27:54 -07003172 [[GPBStringEnumDictionary alloc] initWithEnums:kValues
3173 forKeys:kKeys
3174 count:GPBARRAYSIZE(kValues)];
Brian Silverman9c614bc2016-02-15 20:20:02 -05003175 XCTAssertNotNil(dict2);
3176 [dict addRawEntriesFromDictionary:dict2];
3177 XCTAssertEqual(dict.count, 4U);
3178
3179 int32_t value;
Austin Schuh40c16522018-10-28 20:27:54 -07003180 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
3181 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003182 XCTAssertEqual(value, 700);
Austin Schuh40c16522018-10-28 20:27:54 -07003183 XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]);
3184 XCTAssertTrue([dict getEnum:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003185 XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue);
Austin Schuh40c16522018-10-28 20:27:54 -07003186 XCTAssertTrue([dict getRawValue:NULL forKey:@"bar"]);
3187 XCTAssertTrue([dict getRawValue:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003188 XCTAssertEqual(value, 801);
Austin Schuh40c16522018-10-28 20:27:54 -07003189 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
3190 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003191 XCTAssertEqual(value, 702);
Austin Schuh40c16522018-10-28 20:27:54 -07003192 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
3193 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003194 XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue);
Austin Schuh40c16522018-10-28 20:27:54 -07003195 XCTAssertTrue([dict getRawValue:NULL forKey:@"mumble"]);
3196 XCTAssertTrue([dict getRawValue:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003197 XCTAssertEqual(value, 803);
3198 [dict2 release];
Austin Schuh40c16522018-10-28 20:27:54 -07003199 [dict release];
Brian Silverman9c614bc2016-02-15 20:20:02 -05003200}
3201
3202- (void)testUnknownRemove {
3203 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
3204 const int32_t kValues[] = { 700, 801, 702, 803 }; // Unknowns
3205 GPBStringEnumDictionary *dict =
3206 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3207 rawValues:kValues
3208 forKeys:kKeys
3209 count:GPBARRAYSIZE(kValues)];
3210 XCTAssertNotNil(dict);
3211 XCTAssertEqual(dict.count, 4U);
3212
Austin Schuh40c16522018-10-28 20:27:54 -07003213 [dict removeEnumForKey:@"bar"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05003214 XCTAssertEqual(dict.count, 3U);
3215 int32_t value;
Austin Schuh40c16522018-10-28 20:27:54 -07003216 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
3217 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003218 XCTAssertEqual(value, 700);
Austin Schuh40c16522018-10-28 20:27:54 -07003219 XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]);
3220 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
3221 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003222 XCTAssertEqual(value, 702);
Austin Schuh40c16522018-10-28 20:27:54 -07003223 XCTAssertTrue([dict getRawValue:NULL forKey:@"mumble"]);
3224 XCTAssertTrue([dict getRawValue:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003225 XCTAssertEqual(value, 803);
3226
3227 // Remove again does nothing.
Austin Schuh40c16522018-10-28 20:27:54 -07003228 [dict removeEnumForKey:@"bar"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05003229 XCTAssertEqual(dict.count, 3U);
Austin Schuh40c16522018-10-28 20:27:54 -07003230 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
3231 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003232 XCTAssertEqual(value, 700);
Austin Schuh40c16522018-10-28 20:27:54 -07003233 XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]);
3234 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
3235 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003236 XCTAssertEqual(value, 702);
Austin Schuh40c16522018-10-28 20:27:54 -07003237 XCTAssertTrue([dict getRawValue:NULL forKey:@"mumble"]);
3238 XCTAssertTrue([dict getRawValue:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003239 XCTAssertEqual(value, 803);
3240
Austin Schuh40c16522018-10-28 20:27:54 -07003241 [dict removeEnumForKey:@"mumble"];
Brian Silverman9c614bc2016-02-15 20:20:02 -05003242 XCTAssertEqual(dict.count, 2U);
Austin Schuh40c16522018-10-28 20:27:54 -07003243 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
3244 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003245 XCTAssertEqual(value, 700);
Austin Schuh40c16522018-10-28 20:27:54 -07003246 XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]);
3247 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
3248 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003249 XCTAssertEqual(value, 702);
Austin Schuh40c16522018-10-28 20:27:54 -07003250 XCTAssertFalse([dict getEnum:NULL forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003251
3252 [dict removeAll];
3253 XCTAssertEqual(dict.count, 0U);
Austin Schuh40c16522018-10-28 20:27:54 -07003254 XCTAssertFalse([dict getEnum:NULL forKey:@"foo"]);
3255 XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]);
3256 XCTAssertFalse([dict getEnum:NULL forKey:@"baz"]);
3257 XCTAssertFalse([dict getEnum:NULL forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003258 [dict release];
3259}
3260
3261- (void)testInplaceMutationUnknowns {
3262 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
3263 const int32_t kValues[] = { 700, 801, 702, 803 }; // Unknowns
3264 GPBStringEnumDictionary *dict =
3265 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3266 rawValues:kValues
3267 forKeys:kKeys
3268 count:GPBARRAYSIZE(kValues)];
3269 XCTAssertNotNil(dict);
3270 XCTAssertEqual(dict.count, 4U);
3271 int32_t value;
Austin Schuh40c16522018-10-28 20:27:54 -07003272 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
3273 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003274 XCTAssertEqual(value, 700);
Austin Schuh40c16522018-10-28 20:27:54 -07003275 XCTAssertTrue([dict getRawValue:NULL forKey:@"bar"]);
3276 XCTAssertTrue([dict getRawValue:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003277 XCTAssertEqual(value, 801);
Austin Schuh40c16522018-10-28 20:27:54 -07003278 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
3279 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003280 XCTAssertEqual(value, 702);
Austin Schuh40c16522018-10-28 20:27:54 -07003281 XCTAssertTrue([dict getRawValue:NULL forKey:@"mumble"]);
3282 XCTAssertTrue([dict getRawValue:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003283 XCTAssertEqual(value, 803);
3284
Austin Schuh40c16522018-10-28 20:27:54 -07003285 XCTAssertThrowsSpecificNamed([dict setEnum:803 forKey:@"foo"], // Unknown
Brian Silverman9c614bc2016-02-15 20:20:02 -05003286 NSException, NSInvalidArgumentException);
3287 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -07003288 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]);
3289 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003290 XCTAssertEqual(value, 700);
Austin Schuh40c16522018-10-28 20:27:54 -07003291 XCTAssertTrue([dict getRawValue:NULL forKey:@"bar"]);
3292 XCTAssertTrue([dict getRawValue:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003293 XCTAssertEqual(value, 801);
Austin Schuh40c16522018-10-28 20:27:54 -07003294 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
3295 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003296 XCTAssertEqual(value, 702);
Austin Schuh40c16522018-10-28 20:27:54 -07003297 XCTAssertTrue([dict getRawValue:NULL forKey:@"mumble"]);
3298 XCTAssertTrue([dict getRawValue:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003299 XCTAssertEqual(value, 803);
3300
3301 [dict setRawValue:803 forKey:@"foo"]; // Unknown
3302 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -07003303 XCTAssertTrue([dict getRawValue:NULL forKey:@"foo"]);
3304 XCTAssertTrue([dict getRawValue:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003305 XCTAssertEqual(value, 803);
Austin Schuh40c16522018-10-28 20:27:54 -07003306 XCTAssertTrue([dict getRawValue:NULL forKey:@"bar"]);
3307 XCTAssertTrue([dict getRawValue:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003308 XCTAssertEqual(value, 801);
Austin Schuh40c16522018-10-28 20:27:54 -07003309 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
3310 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003311 XCTAssertEqual(value, 702);
Austin Schuh40c16522018-10-28 20:27:54 -07003312 XCTAssertTrue([dict getRawValue:NULL forKey:@"mumble"]);
3313 XCTAssertTrue([dict getRawValue:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003314 XCTAssertEqual(value, 803);
3315
3316 [dict setRawValue:700 forKey:@"mumble"];
3317 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -07003318 XCTAssertTrue([dict getRawValue:NULL forKey:@"foo"]);
3319 XCTAssertTrue([dict getRawValue:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003320 XCTAssertEqual(value, 803);
Austin Schuh40c16522018-10-28 20:27:54 -07003321 XCTAssertTrue([dict getRawValue:NULL forKey:@"bar"]);
3322 XCTAssertTrue([dict getRawValue:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003323 XCTAssertEqual(value, 801);
Austin Schuh40c16522018-10-28 20:27:54 -07003324 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]);
3325 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003326 XCTAssertEqual(value, 702);
Austin Schuh40c16522018-10-28 20:27:54 -07003327 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
3328 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003329 XCTAssertEqual(value, 700);
3330
3331 const NSString *kKeys2[] = { @"bar", @"baz" };
3332 const int32_t kValues2[] = { 702, 801 }; // Unknown
3333 GPBStringEnumDictionary *dict2 =
3334 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3335 rawValues:kValues2
3336 forKeys:kKeys2
3337 count:GPBARRAYSIZE(kValues2)];
3338 XCTAssertNotNil(dict2);
3339 [dict addRawEntriesFromDictionary:dict2];
3340 XCTAssertEqual(dict.count, 4U);
Austin Schuh40c16522018-10-28 20:27:54 -07003341 XCTAssertTrue([dict getRawValue:NULL forKey:@"foo"]);
3342 XCTAssertTrue([dict getRawValue:&value forKey:@"foo"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003343 XCTAssertEqual(value, 803);
Austin Schuh40c16522018-10-28 20:27:54 -07003344 XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]);
3345 XCTAssertTrue([dict getEnum:&value forKey:@"bar"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003346 XCTAssertEqual(value, 702);
Austin Schuh40c16522018-10-28 20:27:54 -07003347 XCTAssertTrue([dict getRawValue:NULL forKey:@"baz"]);
3348 XCTAssertTrue([dict getRawValue:&value forKey:@"baz"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003349 XCTAssertEqual(value, 801);
Austin Schuh40c16522018-10-28 20:27:54 -07003350 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]);
3351 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]);
Brian Silverman9c614bc2016-02-15 20:20:02 -05003352 XCTAssertEqual(value, 700);
3353
3354 [dict2 release];
3355 [dict release];
3356}
3357
3358- (void)testCopyUnknowns {
3359 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" };
3360 const int32_t kValues[] = { 700, 801, 702, 803 };
3361 GPBStringEnumDictionary *dict =
3362 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
3363 rawValues:kValues
3364 forKeys:kKeys
3365 count:GPBARRAYSIZE(kValues)];
3366 XCTAssertNotNil(dict);
3367
3368 GPBStringEnumDictionary *dict2 = [dict copy];
3369 XCTAssertNotNil(dict2);
3370
3371 // Should be new pointer, but equal objects.
3372 XCTAssertNotEqual(dict, dict2);
3373 XCTAssertEqualObjects(dict, dict2);
3374 XCTAssertEqual(dict.validationFunc, dict2.validationFunc); // Pointer comparison
3375 XCTAssertTrue([dict2 isKindOfClass:[GPBStringEnumDictionary class]]);
3376
3377 [dict2 release];
3378 [dict release];
3379}
3380
3381@end
3382
3383//%PDDM-EXPAND-END TESTS_FOR_POD_VALUES(String, NSString, *, Objects, @"foo", @"bar", @"baz", @"mumble")
3384