1// Protocol Buffers - Google's data interchange format 2// Copyright 2015 Google Inc. All rights reserved. 3// 4// Use of this source code is governed by a BSD-style 5// license that can be found in the LICENSE file or at 6// https://developers.google.com/open-source/licenses/bsd 7 8#import <Foundation/Foundation.h> 9#import <XCTest/XCTest.h> 10 11#import "GPBDictionary.h" 12#import "GPBTestUtilities.h" 13#import "objectivec/Tests/UnittestRuntimeProto2.pbobjc.h" 14 15// Disable clang-format for the macros. 16// clang-format off 17 18// Pull in the macros (using an external file because expanding all tests 19// in a single file makes a file that is failing to work with within Xcode. 20//%PDDM-IMPORT-DEFINES GPBDictionaryTests.pddm 21 22//%PDDM-EXPAND TESTS_FOR_POD_VALUES(String,NSString,*,Objects,@"foo",@"bar",@"baz",@"mumble") 23// This block of code is generated, do not edit it directly. 24 25// To let the testing macros work, add some extra methods to simplify things. 26@interface GPBStringEnumDictionary (TestingTweak) 27- (instancetype)initWithEnums:(const int32_t [])values 28 forKeys:(const NSString * [])keys 29 count:(NSUInteger)count; 30@end 31 32static BOOL TestingEnum_IsValidValue(int32_t value) { 33 switch (value) { 34 case 700: 35 case 701: 36 case 702: 37 case 703: 38 return YES; 39 default: 40 return NO; 41 } 42} 43 44@implementation GPBStringEnumDictionary (TestingTweak) 45- (instancetype)initWithEnums:(const int32_t [])values 46 forKeys:(const NSString * [])keys 47 count:(NSUInteger)count { 48 return [self initWithValidationFunction:TestingEnum_IsValidValue 49 rawValues:values 50 forKeys:keys 51 count:count]; 52} 53@end 54 55 56#pragma mark - String -> UInt32 57 58@interface GPBStringUInt32DictionaryTests : XCTestCase 59@end 60 61@implementation GPBStringUInt32DictionaryTests 62 63- (void)testEmpty { 64 GPBStringUInt32Dictionary *dict = [[GPBStringUInt32Dictionary alloc] init]; 65 XCTAssertNotNil(dict); 66 XCTAssertEqual(dict.count, 0U); 67 XCTAssertFalse([dict getUInt32:NULL forKey:@"foo"]); 68 [dict enumerateKeysAndUInt32sUsingBlock:^(__unused NSString *aKey, __unused uint32_t aValue, __unused BOOL *stop) { 69 XCTFail(@"Shouldn't get here!"); 70 }]; 71 [dict release]; 72} 73 74- (void)testOne { 75 GPBStringUInt32Dictionary *dict = [[GPBStringUInt32Dictionary alloc] init]; 76 [dict setUInt32:100U forKey:@"foo"]; 77 XCTAssertNotNil(dict); 78 XCTAssertEqual(dict.count, 1U); 79 uint32_t value; 80 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]); 81 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]); 82 XCTAssertEqual(value, 100U); 83 XCTAssertFalse([dict getUInt32:NULL forKey:@"bar"]); 84 [dict enumerateKeysAndUInt32sUsingBlock:^(NSString *aKey, uint32_t aValue, BOOL *stop) { 85 XCTAssertEqualObjects(aKey, @"foo"); 86 XCTAssertEqual(aValue, 100U); 87 XCTAssertNotEqual(stop, NULL); 88 }]; 89 [dict release]; 90} 91 92- (void)testBasics { 93 const NSString *kKeys[] = { @"foo", @"bar", @"baz" }; 94 const uint32_t kValues[] = { 100U, 101U, 102U }; 95 GPBStringUInt32Dictionary *dict = 96 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues 97 forKeys:kKeys 98 count:GPBARRAYSIZE(kValues)]; 99 XCTAssertNotNil(dict); 100 XCTAssertEqual(dict.count, 3U); 101 uint32_t value; 102 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]); 103 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]); 104 XCTAssertEqual(value, 100U); 105 XCTAssertTrue([dict getUInt32:NULL forKey:@"bar"]); 106 XCTAssertTrue([dict getUInt32:&value forKey:@"bar"]); 107 XCTAssertEqual(value, 101U); 108 XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]); 109 XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]); 110 XCTAssertEqual(value, 102U); 111 XCTAssertFalse([dict getUInt32:NULL forKey:@"mumble"]); 112 113 __block NSUInteger idx = 0; 114 NSString **seenKeys = malloc(3 * sizeof(NSString*)); 115 uint32_t *seenValues = malloc(3 * sizeof(uint32_t)); 116 [dict enumerateKeysAndUInt32sUsingBlock:^(NSString *aKey, uint32_t aValue, BOOL *stop) { 117 XCTAssertLessThan(idx, 3U); 118 seenKeys[idx] = aKey; 119 seenValues[idx] = aValue; 120 XCTAssertNotEqual(stop, NULL); 121 ++idx; 122 }]; 123 for (int i = 0; i < 3; ++i) { 124 BOOL foundKey = NO; 125 for (int j = 0; (j < 3) && !foundKey; ++j) { 126 if ([kKeys[i] isEqual:seenKeys[j]]) { 127 foundKey = YES; 128 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j); 129 } 130 } 131 XCTAssertTrue(foundKey, @"i = %d", i); 132 } 133 free(seenKeys); 134 free(seenValues); 135 136 // Stopping the enumeration. 137 idx = 0; 138 [dict enumerateKeysAndUInt32sUsingBlock:^(__unused NSString *aKey, __unused uint32_t aValue, BOOL *stop) { 139 if (idx == 1) *stop = YES; 140 XCTAssertNotEqual(idx, 2U); 141 ++idx; 142 }]; 143 [dict release]; 144} 145 146- (void)testEquality { 147 const NSString *kKeys1[] = { @"foo", @"bar", @"baz", @"mumble" }; 148 const NSString *kKeys2[] = { @"bar", @"foo", @"mumble" }; 149 const uint32_t kValues1[] = { 100U, 101U, 102U }; 150 const uint32_t kValues2[] = { 100U, 103U, 102U }; 151 const uint32_t kValues3[] = { 100U, 101U, 102U, 103U }; 152 GPBStringUInt32Dictionary *dict1 = 153 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues1 154 forKeys:kKeys1 155 count:GPBARRAYSIZE(kValues1)]; 156 XCTAssertNotNil(dict1); 157 GPBStringUInt32Dictionary *dict1prime = 158 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues1 159 forKeys:kKeys1 160 count:GPBARRAYSIZE(kValues1)]; 161 XCTAssertNotNil(dict1prime); 162 GPBStringUInt32Dictionary *dict2 = 163 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues2 164 forKeys:kKeys1 165 count:GPBARRAYSIZE(kValues2)]; 166 XCTAssertNotNil(dict2); 167 GPBStringUInt32Dictionary *dict3 = 168 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues1 169 forKeys:kKeys2 170 count:GPBARRAYSIZE(kValues1)]; 171 XCTAssertNotNil(dict3); 172 GPBStringUInt32Dictionary *dict4 = 173 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues3 174 forKeys:kKeys1 175 count:GPBARRAYSIZE(kValues3)]; 176 XCTAssertNotNil(dict4); 177 178 // 1/1Prime should be different objects, but equal. 179 XCTAssertNotEqual(dict1, dict1prime); 180 XCTAssertEqualObjects(dict1, dict1prime); 181 // Equal, so they must have same hash. 182 XCTAssertEqual([dict1 hash], [dict1prime hash]); 183 184 // 2 is same keys, different values; not equal. 185 XCTAssertNotEqualObjects(dict1, dict2); 186 187 // 3 is different keys, same values; not equal. 188 XCTAssertNotEqualObjects(dict1, dict3); 189 190 // 4 extra pair; not equal 191 XCTAssertNotEqualObjects(dict1, dict4); 192 193 [dict1 release]; 194 [dict1prime release]; 195 [dict2 release]; 196 [dict3 release]; 197 [dict4 release]; 198} 199 200- (void)testCopy { 201 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 202 const uint32_t kValues[] = { 100U, 101U, 102U, 103U }; 203 GPBStringUInt32Dictionary *dict = 204 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues 205 forKeys:kKeys 206 count:GPBARRAYSIZE(kValues)]; 207 XCTAssertNotNil(dict); 208 209 GPBStringUInt32Dictionary *dict2 = [dict copy]; 210 XCTAssertNotNil(dict2); 211 212 // Should be new object but equal. 213 XCTAssertNotEqual(dict, dict2); 214 XCTAssertEqualObjects(dict, dict2); 215 XCTAssertTrue([dict2 isKindOfClass:[GPBStringUInt32Dictionary class]]); 216 217 [dict2 release]; 218 [dict release]; 219} 220 221- (void)testDictionaryFromDictionary { 222 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 223 const uint32_t kValues[] = { 100U, 101U, 102U, 103U }; 224 GPBStringUInt32Dictionary *dict = 225 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues 226 forKeys:kKeys 227 count:GPBARRAYSIZE(kValues)]; 228 XCTAssertNotNil(dict); 229 230 GPBStringUInt32Dictionary *dict2 = 231 [[GPBStringUInt32Dictionary alloc] initWithDictionary:dict]; 232 XCTAssertNotNil(dict2); 233 234 // Should be new pointer, but equal objects. 235 XCTAssertNotEqual(dict, dict2); 236 XCTAssertEqualObjects(dict, dict2); 237 [dict2 release]; 238 [dict release]; 239} 240 241- (void)testAdds { 242 GPBStringUInt32Dictionary *dict = [[GPBStringUInt32Dictionary alloc] init]; 243 XCTAssertNotNil(dict); 244 245 XCTAssertEqual(dict.count, 0U); 246 [dict setUInt32:100U forKey:@"foo"]; 247 XCTAssertEqual(dict.count, 1U); 248 249 const NSString *kKeys[] = { @"bar", @"baz", @"mumble" }; 250 const uint32_t kValues[] = { 101U, 102U, 103U }; 251 GPBStringUInt32Dictionary *dict2 = 252 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues 253 forKeys:kKeys 254 count:GPBARRAYSIZE(kValues)]; 255 XCTAssertNotNil(dict2); 256 [dict addEntriesFromDictionary:dict2]; 257 XCTAssertEqual(dict.count, 4U); 258 259 uint32_t value; 260 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]); 261 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]); 262 XCTAssertEqual(value, 100U); 263 XCTAssertTrue([dict getUInt32:NULL forKey:@"bar"]); 264 XCTAssertTrue([dict getUInt32:&value forKey:@"bar"]); 265 XCTAssertEqual(value, 101U); 266 XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]); 267 XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]); 268 XCTAssertEqual(value, 102U); 269 XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]); 270 XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]); 271 XCTAssertEqual(value, 103U); 272 [dict2 release]; 273 [dict release]; 274} 275 276- (void)testRemove { 277 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 278 const uint32_t kValues[] = { 100U, 101U, 102U, 103U }; 279 GPBStringUInt32Dictionary *dict = 280 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues 281 forKeys:kKeys 282 count:GPBARRAYSIZE(kValues)]; 283 XCTAssertNotNil(dict); 284 XCTAssertEqual(dict.count, 4U); 285 286 [dict removeUInt32ForKey:@"bar"]; 287 XCTAssertEqual(dict.count, 3U); 288 uint32_t value; 289 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]); 290 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]); 291 XCTAssertEqual(value, 100U); 292 XCTAssertFalse([dict getUInt32:NULL forKey:@"bar"]); 293 XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]); 294 XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]); 295 XCTAssertEqual(value, 102U); 296 XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]); 297 XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]); 298 XCTAssertEqual(value, 103U); 299 300 // Remove again does nothing. 301 [dict removeUInt32ForKey:@"bar"]; 302 XCTAssertEqual(dict.count, 3U); 303 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]); 304 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]); 305 XCTAssertEqual(value, 100U); 306 XCTAssertFalse([dict getUInt32:NULL forKey:@"bar"]); 307 XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]); 308 XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]); 309 XCTAssertEqual(value, 102U); 310 XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]); 311 XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]); 312 XCTAssertEqual(value, 103U); 313 314 [dict removeUInt32ForKey:@"mumble"]; 315 XCTAssertEqual(dict.count, 2U); 316 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]); 317 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]); 318 XCTAssertEqual(value, 100U); 319 XCTAssertFalse([dict getUInt32:NULL forKey:@"bar"]); 320 XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]); 321 XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]); 322 XCTAssertEqual(value, 102U); 323 XCTAssertFalse([dict getUInt32:NULL forKey:@"mumble"]); 324 325 [dict removeAll]; 326 XCTAssertEqual(dict.count, 0U); 327 XCTAssertFalse([dict getUInt32:NULL forKey:@"foo"]); 328 XCTAssertFalse([dict getUInt32:NULL forKey:@"bar"]); 329 XCTAssertFalse([dict getUInt32:NULL forKey:@"baz"]); 330 XCTAssertFalse([dict getUInt32:NULL forKey:@"mumble"]); 331 [dict release]; 332} 333 334- (void)testInplaceMutation { 335 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 336 const uint32_t kValues[] = { 100U, 101U, 102U, 103U }; 337 GPBStringUInt32Dictionary *dict = 338 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues 339 forKeys:kKeys 340 count:GPBARRAYSIZE(kValues)]; 341 XCTAssertNotNil(dict); 342 XCTAssertEqual(dict.count, 4U); 343 uint32_t value; 344 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]); 345 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]); 346 XCTAssertEqual(value, 100U); 347 XCTAssertTrue([dict getUInt32:NULL forKey:@"bar"]); 348 XCTAssertTrue([dict getUInt32:&value forKey:@"bar"]); 349 XCTAssertEqual(value, 101U); 350 XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]); 351 XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]); 352 XCTAssertEqual(value, 102U); 353 XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]); 354 XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]); 355 XCTAssertEqual(value, 103U); 356 357 [dict setUInt32:103U forKey:@"foo"]; 358 XCTAssertEqual(dict.count, 4U); 359 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]); 360 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]); 361 XCTAssertEqual(value, 103U); 362 XCTAssertTrue([dict getUInt32:NULL forKey:@"bar"]); 363 XCTAssertTrue([dict getUInt32:&value forKey:@"bar"]); 364 XCTAssertEqual(value, 101U); 365 XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]); 366 XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]); 367 XCTAssertEqual(value, 102U); 368 XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]); 369 XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]); 370 XCTAssertEqual(value, 103U); 371 372 [dict setUInt32:101U forKey:@"mumble"]; 373 XCTAssertEqual(dict.count, 4U); 374 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]); 375 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]); 376 XCTAssertEqual(value, 103U); 377 XCTAssertTrue([dict getUInt32:NULL forKey:@"bar"]); 378 XCTAssertTrue([dict getUInt32:&value forKey:@"bar"]); 379 XCTAssertEqual(value, 101U); 380 XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]); 381 XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]); 382 XCTAssertEqual(value, 102U); 383 XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]); 384 XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]); 385 XCTAssertEqual(value, 101U); 386 387 const NSString *kKeys2[] = { @"bar", @"baz" }; 388 const uint32_t kValues2[] = { 102U, 100U }; 389 GPBStringUInt32Dictionary *dict2 = 390 [[GPBStringUInt32Dictionary alloc] initWithUInt32s:kValues2 391 forKeys:kKeys2 392 count:GPBARRAYSIZE(kValues2)]; 393 XCTAssertNotNil(dict2); 394 [dict addEntriesFromDictionary:dict2]; 395 XCTAssertEqual(dict.count, 4U); 396 XCTAssertTrue([dict getUInt32:NULL forKey:@"foo"]); 397 XCTAssertTrue([dict getUInt32:&value forKey:@"foo"]); 398 XCTAssertEqual(value, 103U); 399 XCTAssertTrue([dict getUInt32:NULL forKey:@"bar"]); 400 XCTAssertTrue([dict getUInt32:&value forKey:@"bar"]); 401 XCTAssertEqual(value, 102U); 402 XCTAssertTrue([dict getUInt32:NULL forKey:@"baz"]); 403 XCTAssertTrue([dict getUInt32:&value forKey:@"baz"]); 404 XCTAssertEqual(value, 100U); 405 XCTAssertTrue([dict getUInt32:NULL forKey:@"mumble"]); 406 XCTAssertTrue([dict getUInt32:&value forKey:@"mumble"]); 407 XCTAssertEqual(value, 101U); 408 409 [dict2 release]; 410 [dict release]; 411} 412 413@end 414 415#pragma mark - String -> Int32 416 417@interface GPBStringInt32DictionaryTests : XCTestCase 418@end 419 420@implementation GPBStringInt32DictionaryTests 421 422- (void)testEmpty { 423 GPBStringInt32Dictionary *dict = [[GPBStringInt32Dictionary alloc] init]; 424 XCTAssertNotNil(dict); 425 XCTAssertEqual(dict.count, 0U); 426 XCTAssertFalse([dict getInt32:NULL forKey:@"foo"]); 427 [dict enumerateKeysAndInt32sUsingBlock:^(__unused NSString *aKey, __unused int32_t aValue, __unused BOOL *stop) { 428 XCTFail(@"Shouldn't get here!"); 429 }]; 430 [dict release]; 431} 432 433- (void)testOne { 434 GPBStringInt32Dictionary *dict = [[GPBStringInt32Dictionary alloc] init]; 435 [dict setInt32:200 forKey:@"foo"]; 436 XCTAssertNotNil(dict); 437 XCTAssertEqual(dict.count, 1U); 438 int32_t value; 439 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]); 440 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]); 441 XCTAssertEqual(value, 200); 442 XCTAssertFalse([dict getInt32:NULL forKey:@"bar"]); 443 [dict enumerateKeysAndInt32sUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) { 444 XCTAssertEqualObjects(aKey, @"foo"); 445 XCTAssertEqual(aValue, 200); 446 XCTAssertNotEqual(stop, NULL); 447 }]; 448 [dict release]; 449} 450 451- (void)testBasics { 452 const NSString *kKeys[] = { @"foo", @"bar", @"baz" }; 453 const int32_t kValues[] = { 200, 201, 202 }; 454 GPBStringInt32Dictionary *dict = 455 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues 456 forKeys:kKeys 457 count:GPBARRAYSIZE(kValues)]; 458 XCTAssertNotNil(dict); 459 XCTAssertEqual(dict.count, 3U); 460 int32_t value; 461 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]); 462 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]); 463 XCTAssertEqual(value, 200); 464 XCTAssertTrue([dict getInt32:NULL forKey:@"bar"]); 465 XCTAssertTrue([dict getInt32:&value forKey:@"bar"]); 466 XCTAssertEqual(value, 201); 467 XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]); 468 XCTAssertTrue([dict getInt32:&value forKey:@"baz"]); 469 XCTAssertEqual(value, 202); 470 XCTAssertFalse([dict getInt32:NULL forKey:@"mumble"]); 471 472 __block NSUInteger idx = 0; 473 NSString **seenKeys = malloc(3 * sizeof(NSString*)); 474 int32_t *seenValues = malloc(3 * sizeof(int32_t)); 475 [dict enumerateKeysAndInt32sUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) { 476 XCTAssertLessThan(idx, 3U); 477 seenKeys[idx] = aKey; 478 seenValues[idx] = aValue; 479 XCTAssertNotEqual(stop, NULL); 480 ++idx; 481 }]; 482 for (int i = 0; i < 3; ++i) { 483 BOOL foundKey = NO; 484 for (int j = 0; (j < 3) && !foundKey; ++j) { 485 if ([kKeys[i] isEqual:seenKeys[j]]) { 486 foundKey = YES; 487 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j); 488 } 489 } 490 XCTAssertTrue(foundKey, @"i = %d", i); 491 } 492 free(seenKeys); 493 free(seenValues); 494 495 // Stopping the enumeration. 496 idx = 0; 497 [dict enumerateKeysAndInt32sUsingBlock:^(__unused NSString *aKey, __unused int32_t aValue, BOOL *stop) { 498 if (idx == 1) *stop = YES; 499 XCTAssertNotEqual(idx, 2U); 500 ++idx; 501 }]; 502 [dict release]; 503} 504 505- (void)testEquality { 506 const NSString *kKeys1[] = { @"foo", @"bar", @"baz", @"mumble" }; 507 const NSString *kKeys2[] = { @"bar", @"foo", @"mumble" }; 508 const int32_t kValues1[] = { 200, 201, 202 }; 509 const int32_t kValues2[] = { 200, 203, 202 }; 510 const int32_t kValues3[] = { 200, 201, 202, 203 }; 511 GPBStringInt32Dictionary *dict1 = 512 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues1 513 forKeys:kKeys1 514 count:GPBARRAYSIZE(kValues1)]; 515 XCTAssertNotNil(dict1); 516 GPBStringInt32Dictionary *dict1prime = 517 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues1 518 forKeys:kKeys1 519 count:GPBARRAYSIZE(kValues1)]; 520 XCTAssertNotNil(dict1prime); 521 GPBStringInt32Dictionary *dict2 = 522 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues2 523 forKeys:kKeys1 524 count:GPBARRAYSIZE(kValues2)]; 525 XCTAssertNotNil(dict2); 526 GPBStringInt32Dictionary *dict3 = 527 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues1 528 forKeys:kKeys2 529 count:GPBARRAYSIZE(kValues1)]; 530 XCTAssertNotNil(dict3); 531 GPBStringInt32Dictionary *dict4 = 532 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues3 533 forKeys:kKeys1 534 count:GPBARRAYSIZE(kValues3)]; 535 XCTAssertNotNil(dict4); 536 537 // 1/1Prime should be different objects, but equal. 538 XCTAssertNotEqual(dict1, dict1prime); 539 XCTAssertEqualObjects(dict1, dict1prime); 540 // Equal, so they must have same hash. 541 XCTAssertEqual([dict1 hash], [dict1prime hash]); 542 543 // 2 is same keys, different values; not equal. 544 XCTAssertNotEqualObjects(dict1, dict2); 545 546 // 3 is different keys, same values; not equal. 547 XCTAssertNotEqualObjects(dict1, dict3); 548 549 // 4 extra pair; not equal 550 XCTAssertNotEqualObjects(dict1, dict4); 551 552 [dict1 release]; 553 [dict1prime release]; 554 [dict2 release]; 555 [dict3 release]; 556 [dict4 release]; 557} 558 559- (void)testCopy { 560 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 561 const int32_t kValues[] = { 200, 201, 202, 203 }; 562 GPBStringInt32Dictionary *dict = 563 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues 564 forKeys:kKeys 565 count:GPBARRAYSIZE(kValues)]; 566 XCTAssertNotNil(dict); 567 568 GPBStringInt32Dictionary *dict2 = [dict copy]; 569 XCTAssertNotNil(dict2); 570 571 // Should be new object but equal. 572 XCTAssertNotEqual(dict, dict2); 573 XCTAssertEqualObjects(dict, dict2); 574 XCTAssertTrue([dict2 isKindOfClass:[GPBStringInt32Dictionary class]]); 575 576 [dict2 release]; 577 [dict release]; 578} 579 580- (void)testDictionaryFromDictionary { 581 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 582 const int32_t kValues[] = { 200, 201, 202, 203 }; 583 GPBStringInt32Dictionary *dict = 584 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues 585 forKeys:kKeys 586 count:GPBARRAYSIZE(kValues)]; 587 XCTAssertNotNil(dict); 588 589 GPBStringInt32Dictionary *dict2 = 590 [[GPBStringInt32Dictionary alloc] initWithDictionary:dict]; 591 XCTAssertNotNil(dict2); 592 593 // Should be new pointer, but equal objects. 594 XCTAssertNotEqual(dict, dict2); 595 XCTAssertEqualObjects(dict, dict2); 596 [dict2 release]; 597 [dict release]; 598} 599 600- (void)testAdds { 601 GPBStringInt32Dictionary *dict = [[GPBStringInt32Dictionary alloc] init]; 602 XCTAssertNotNil(dict); 603 604 XCTAssertEqual(dict.count, 0U); 605 [dict setInt32:200 forKey:@"foo"]; 606 XCTAssertEqual(dict.count, 1U); 607 608 const NSString *kKeys[] = { @"bar", @"baz", @"mumble" }; 609 const int32_t kValues[] = { 201, 202, 203 }; 610 GPBStringInt32Dictionary *dict2 = 611 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues 612 forKeys:kKeys 613 count:GPBARRAYSIZE(kValues)]; 614 XCTAssertNotNil(dict2); 615 [dict addEntriesFromDictionary:dict2]; 616 XCTAssertEqual(dict.count, 4U); 617 618 int32_t value; 619 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]); 620 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]); 621 XCTAssertEqual(value, 200); 622 XCTAssertTrue([dict getInt32:NULL forKey:@"bar"]); 623 XCTAssertTrue([dict getInt32:&value forKey:@"bar"]); 624 XCTAssertEqual(value, 201); 625 XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]); 626 XCTAssertTrue([dict getInt32:&value forKey:@"baz"]); 627 XCTAssertEqual(value, 202); 628 XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]); 629 XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]); 630 XCTAssertEqual(value, 203); 631 [dict2 release]; 632 [dict release]; 633} 634 635- (void)testRemove { 636 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 637 const int32_t kValues[] = { 200, 201, 202, 203 }; 638 GPBStringInt32Dictionary *dict = 639 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues 640 forKeys:kKeys 641 count:GPBARRAYSIZE(kValues)]; 642 XCTAssertNotNil(dict); 643 XCTAssertEqual(dict.count, 4U); 644 645 [dict removeInt32ForKey:@"bar"]; 646 XCTAssertEqual(dict.count, 3U); 647 int32_t value; 648 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]); 649 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]); 650 XCTAssertEqual(value, 200); 651 XCTAssertFalse([dict getInt32:NULL forKey:@"bar"]); 652 XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]); 653 XCTAssertTrue([dict getInt32:&value forKey:@"baz"]); 654 XCTAssertEqual(value, 202); 655 XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]); 656 XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]); 657 XCTAssertEqual(value, 203); 658 659 // Remove again does nothing. 660 [dict removeInt32ForKey:@"bar"]; 661 XCTAssertEqual(dict.count, 3U); 662 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]); 663 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]); 664 XCTAssertEqual(value, 200); 665 XCTAssertFalse([dict getInt32:NULL forKey:@"bar"]); 666 XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]); 667 XCTAssertTrue([dict getInt32:&value forKey:@"baz"]); 668 XCTAssertEqual(value, 202); 669 XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]); 670 XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]); 671 XCTAssertEqual(value, 203); 672 673 [dict removeInt32ForKey:@"mumble"]; 674 XCTAssertEqual(dict.count, 2U); 675 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]); 676 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]); 677 XCTAssertEqual(value, 200); 678 XCTAssertFalse([dict getInt32:NULL forKey:@"bar"]); 679 XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]); 680 XCTAssertTrue([dict getInt32:&value forKey:@"baz"]); 681 XCTAssertEqual(value, 202); 682 XCTAssertFalse([dict getInt32:NULL forKey:@"mumble"]); 683 684 [dict removeAll]; 685 XCTAssertEqual(dict.count, 0U); 686 XCTAssertFalse([dict getInt32:NULL forKey:@"foo"]); 687 XCTAssertFalse([dict getInt32:NULL forKey:@"bar"]); 688 XCTAssertFalse([dict getInt32:NULL forKey:@"baz"]); 689 XCTAssertFalse([dict getInt32:NULL forKey:@"mumble"]); 690 [dict release]; 691} 692 693- (void)testInplaceMutation { 694 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 695 const int32_t kValues[] = { 200, 201, 202, 203 }; 696 GPBStringInt32Dictionary *dict = 697 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues 698 forKeys:kKeys 699 count:GPBARRAYSIZE(kValues)]; 700 XCTAssertNotNil(dict); 701 XCTAssertEqual(dict.count, 4U); 702 int32_t value; 703 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]); 704 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]); 705 XCTAssertEqual(value, 200); 706 XCTAssertTrue([dict getInt32:NULL forKey:@"bar"]); 707 XCTAssertTrue([dict getInt32:&value forKey:@"bar"]); 708 XCTAssertEqual(value, 201); 709 XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]); 710 XCTAssertTrue([dict getInt32:&value forKey:@"baz"]); 711 XCTAssertEqual(value, 202); 712 XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]); 713 XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]); 714 XCTAssertEqual(value, 203); 715 716 [dict setInt32:203 forKey:@"foo"]; 717 XCTAssertEqual(dict.count, 4U); 718 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]); 719 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]); 720 XCTAssertEqual(value, 203); 721 XCTAssertTrue([dict getInt32:NULL forKey:@"bar"]); 722 XCTAssertTrue([dict getInt32:&value forKey:@"bar"]); 723 XCTAssertEqual(value, 201); 724 XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]); 725 XCTAssertTrue([dict getInt32:&value forKey:@"baz"]); 726 XCTAssertEqual(value, 202); 727 XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]); 728 XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]); 729 XCTAssertEqual(value, 203); 730 731 [dict setInt32:201 forKey:@"mumble"]; 732 XCTAssertEqual(dict.count, 4U); 733 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]); 734 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]); 735 XCTAssertEqual(value, 203); 736 XCTAssertTrue([dict getInt32:NULL forKey:@"bar"]); 737 XCTAssertTrue([dict getInt32:&value forKey:@"bar"]); 738 XCTAssertEqual(value, 201); 739 XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]); 740 XCTAssertTrue([dict getInt32:&value forKey:@"baz"]); 741 XCTAssertEqual(value, 202); 742 XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]); 743 XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]); 744 XCTAssertEqual(value, 201); 745 746 const NSString *kKeys2[] = { @"bar", @"baz" }; 747 const int32_t kValues2[] = { 202, 200 }; 748 GPBStringInt32Dictionary *dict2 = 749 [[GPBStringInt32Dictionary alloc] initWithInt32s:kValues2 750 forKeys:kKeys2 751 count:GPBARRAYSIZE(kValues2)]; 752 XCTAssertNotNil(dict2); 753 [dict addEntriesFromDictionary:dict2]; 754 XCTAssertEqual(dict.count, 4U); 755 XCTAssertTrue([dict getInt32:NULL forKey:@"foo"]); 756 XCTAssertTrue([dict getInt32:&value forKey:@"foo"]); 757 XCTAssertEqual(value, 203); 758 XCTAssertTrue([dict getInt32:NULL forKey:@"bar"]); 759 XCTAssertTrue([dict getInt32:&value forKey:@"bar"]); 760 XCTAssertEqual(value, 202); 761 XCTAssertTrue([dict getInt32:NULL forKey:@"baz"]); 762 XCTAssertTrue([dict getInt32:&value forKey:@"baz"]); 763 XCTAssertEqual(value, 200); 764 XCTAssertTrue([dict getInt32:NULL forKey:@"mumble"]); 765 XCTAssertTrue([dict getInt32:&value forKey:@"mumble"]); 766 XCTAssertEqual(value, 201); 767 768 [dict2 release]; 769 [dict release]; 770} 771 772@end 773 774#pragma mark - String -> UInt64 775 776@interface GPBStringUInt64DictionaryTests : XCTestCase 777@end 778 779@implementation GPBStringUInt64DictionaryTests 780 781- (void)testEmpty { 782 GPBStringUInt64Dictionary *dict = [[GPBStringUInt64Dictionary alloc] init]; 783 XCTAssertNotNil(dict); 784 XCTAssertEqual(dict.count, 0U); 785 XCTAssertFalse([dict getUInt64:NULL forKey:@"foo"]); 786 [dict enumerateKeysAndUInt64sUsingBlock:^(__unused NSString *aKey, __unused uint64_t aValue, __unused BOOL *stop) { 787 XCTFail(@"Shouldn't get here!"); 788 }]; 789 [dict release]; 790} 791 792- (void)testOne { 793 GPBStringUInt64Dictionary *dict = [[GPBStringUInt64Dictionary alloc] init]; 794 [dict setUInt64:300U forKey:@"foo"]; 795 XCTAssertNotNil(dict); 796 XCTAssertEqual(dict.count, 1U); 797 uint64_t value; 798 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]); 799 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]); 800 XCTAssertEqual(value, 300U); 801 XCTAssertFalse([dict getUInt64:NULL forKey:@"bar"]); 802 [dict enumerateKeysAndUInt64sUsingBlock:^(NSString *aKey, uint64_t aValue, BOOL *stop) { 803 XCTAssertEqualObjects(aKey, @"foo"); 804 XCTAssertEqual(aValue, 300U); 805 XCTAssertNotEqual(stop, NULL); 806 }]; 807 [dict release]; 808} 809 810- (void)testBasics { 811 const NSString *kKeys[] = { @"foo", @"bar", @"baz" }; 812 const uint64_t kValues[] = { 300U, 301U, 302U }; 813 GPBStringUInt64Dictionary *dict = 814 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues 815 forKeys:kKeys 816 count:GPBARRAYSIZE(kValues)]; 817 XCTAssertNotNil(dict); 818 XCTAssertEqual(dict.count, 3U); 819 uint64_t value; 820 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]); 821 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]); 822 XCTAssertEqual(value, 300U); 823 XCTAssertTrue([dict getUInt64:NULL forKey:@"bar"]); 824 XCTAssertTrue([dict getUInt64:&value forKey:@"bar"]); 825 XCTAssertEqual(value, 301U); 826 XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]); 827 XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]); 828 XCTAssertEqual(value, 302U); 829 XCTAssertFalse([dict getUInt64:NULL forKey:@"mumble"]); 830 831 __block NSUInteger idx = 0; 832 NSString **seenKeys = malloc(3 * sizeof(NSString*)); 833 uint64_t *seenValues = malloc(3 * sizeof(uint64_t)); 834 [dict enumerateKeysAndUInt64sUsingBlock:^(NSString *aKey, uint64_t aValue, BOOL *stop) { 835 XCTAssertLessThan(idx, 3U); 836 seenKeys[idx] = aKey; 837 seenValues[idx] = aValue; 838 XCTAssertNotEqual(stop, NULL); 839 ++idx; 840 }]; 841 for (int i = 0; i < 3; ++i) { 842 BOOL foundKey = NO; 843 for (int j = 0; (j < 3) && !foundKey; ++j) { 844 if ([kKeys[i] isEqual:seenKeys[j]]) { 845 foundKey = YES; 846 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j); 847 } 848 } 849 XCTAssertTrue(foundKey, @"i = %d", i); 850 } 851 free(seenKeys); 852 free(seenValues); 853 854 // Stopping the enumeration. 855 idx = 0; 856 [dict enumerateKeysAndUInt64sUsingBlock:^(__unused NSString *aKey, __unused uint64_t aValue, BOOL *stop) { 857 if (idx == 1) *stop = YES; 858 XCTAssertNotEqual(idx, 2U); 859 ++idx; 860 }]; 861 [dict release]; 862} 863 864- (void)testEquality { 865 const NSString *kKeys1[] = { @"foo", @"bar", @"baz", @"mumble" }; 866 const NSString *kKeys2[] = { @"bar", @"foo", @"mumble" }; 867 const uint64_t kValues1[] = { 300U, 301U, 302U }; 868 const uint64_t kValues2[] = { 300U, 303U, 302U }; 869 const uint64_t kValues3[] = { 300U, 301U, 302U, 303U }; 870 GPBStringUInt64Dictionary *dict1 = 871 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues1 872 forKeys:kKeys1 873 count:GPBARRAYSIZE(kValues1)]; 874 XCTAssertNotNil(dict1); 875 GPBStringUInt64Dictionary *dict1prime = 876 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues1 877 forKeys:kKeys1 878 count:GPBARRAYSIZE(kValues1)]; 879 XCTAssertNotNil(dict1prime); 880 GPBStringUInt64Dictionary *dict2 = 881 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues2 882 forKeys:kKeys1 883 count:GPBARRAYSIZE(kValues2)]; 884 XCTAssertNotNil(dict2); 885 GPBStringUInt64Dictionary *dict3 = 886 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues1 887 forKeys:kKeys2 888 count:GPBARRAYSIZE(kValues1)]; 889 XCTAssertNotNil(dict3); 890 GPBStringUInt64Dictionary *dict4 = 891 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues3 892 forKeys:kKeys1 893 count:GPBARRAYSIZE(kValues3)]; 894 XCTAssertNotNil(dict4); 895 896 // 1/1Prime should be different objects, but equal. 897 XCTAssertNotEqual(dict1, dict1prime); 898 XCTAssertEqualObjects(dict1, dict1prime); 899 // Equal, so they must have same hash. 900 XCTAssertEqual([dict1 hash], [dict1prime hash]); 901 902 // 2 is same keys, different values; not equal. 903 XCTAssertNotEqualObjects(dict1, dict2); 904 905 // 3 is different keys, same values; not equal. 906 XCTAssertNotEqualObjects(dict1, dict3); 907 908 // 4 extra pair; not equal 909 XCTAssertNotEqualObjects(dict1, dict4); 910 911 [dict1 release]; 912 [dict1prime release]; 913 [dict2 release]; 914 [dict3 release]; 915 [dict4 release]; 916} 917 918- (void)testCopy { 919 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 920 const uint64_t kValues[] = { 300U, 301U, 302U, 303U }; 921 GPBStringUInt64Dictionary *dict = 922 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues 923 forKeys:kKeys 924 count:GPBARRAYSIZE(kValues)]; 925 XCTAssertNotNil(dict); 926 927 GPBStringUInt64Dictionary *dict2 = [dict copy]; 928 XCTAssertNotNil(dict2); 929 930 // Should be new object but equal. 931 XCTAssertNotEqual(dict, dict2); 932 XCTAssertEqualObjects(dict, dict2); 933 XCTAssertTrue([dict2 isKindOfClass:[GPBStringUInt64Dictionary class]]); 934 935 [dict2 release]; 936 [dict release]; 937} 938 939- (void)testDictionaryFromDictionary { 940 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 941 const uint64_t kValues[] = { 300U, 301U, 302U, 303U }; 942 GPBStringUInt64Dictionary *dict = 943 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues 944 forKeys:kKeys 945 count:GPBARRAYSIZE(kValues)]; 946 XCTAssertNotNil(dict); 947 948 GPBStringUInt64Dictionary *dict2 = 949 [[GPBStringUInt64Dictionary alloc] initWithDictionary:dict]; 950 XCTAssertNotNil(dict2); 951 952 // Should be new pointer, but equal objects. 953 XCTAssertNotEqual(dict, dict2); 954 XCTAssertEqualObjects(dict, dict2); 955 [dict2 release]; 956 [dict release]; 957} 958 959- (void)testAdds { 960 GPBStringUInt64Dictionary *dict = [[GPBStringUInt64Dictionary alloc] init]; 961 XCTAssertNotNil(dict); 962 963 XCTAssertEqual(dict.count, 0U); 964 [dict setUInt64:300U forKey:@"foo"]; 965 XCTAssertEqual(dict.count, 1U); 966 967 const NSString *kKeys[] = { @"bar", @"baz", @"mumble" }; 968 const uint64_t kValues[] = { 301U, 302U, 303U }; 969 GPBStringUInt64Dictionary *dict2 = 970 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues 971 forKeys:kKeys 972 count:GPBARRAYSIZE(kValues)]; 973 XCTAssertNotNil(dict2); 974 [dict addEntriesFromDictionary:dict2]; 975 XCTAssertEqual(dict.count, 4U); 976 977 uint64_t value; 978 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]); 979 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]); 980 XCTAssertEqual(value, 300U); 981 XCTAssertTrue([dict getUInt64:NULL forKey:@"bar"]); 982 XCTAssertTrue([dict getUInt64:&value forKey:@"bar"]); 983 XCTAssertEqual(value, 301U); 984 XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]); 985 XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]); 986 XCTAssertEqual(value, 302U); 987 XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]); 988 XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]); 989 XCTAssertEqual(value, 303U); 990 [dict2 release]; 991 [dict release]; 992} 993 994- (void)testRemove { 995 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 996 const uint64_t kValues[] = { 300U, 301U, 302U, 303U }; 997 GPBStringUInt64Dictionary *dict = 998 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues 999 forKeys:kKeys 1000 count:GPBARRAYSIZE(kValues)]; 1001 XCTAssertNotNil(dict); 1002 XCTAssertEqual(dict.count, 4U); 1003 1004 [dict removeUInt64ForKey:@"bar"]; 1005 XCTAssertEqual(dict.count, 3U); 1006 uint64_t value; 1007 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]); 1008 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]); 1009 XCTAssertEqual(value, 300U); 1010 XCTAssertFalse([dict getUInt64:NULL forKey:@"bar"]); 1011 XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]); 1012 XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]); 1013 XCTAssertEqual(value, 302U); 1014 XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]); 1015 XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]); 1016 XCTAssertEqual(value, 303U); 1017 1018 // Remove again does nothing. 1019 [dict removeUInt64ForKey:@"bar"]; 1020 XCTAssertEqual(dict.count, 3U); 1021 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]); 1022 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]); 1023 XCTAssertEqual(value, 300U); 1024 XCTAssertFalse([dict getUInt64:NULL forKey:@"bar"]); 1025 XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]); 1026 XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]); 1027 XCTAssertEqual(value, 302U); 1028 XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]); 1029 XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]); 1030 XCTAssertEqual(value, 303U); 1031 1032 [dict removeUInt64ForKey:@"mumble"]; 1033 XCTAssertEqual(dict.count, 2U); 1034 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]); 1035 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]); 1036 XCTAssertEqual(value, 300U); 1037 XCTAssertFalse([dict getUInt64:NULL forKey:@"bar"]); 1038 XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]); 1039 XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]); 1040 XCTAssertEqual(value, 302U); 1041 XCTAssertFalse([dict getUInt64:NULL forKey:@"mumble"]); 1042 1043 [dict removeAll]; 1044 XCTAssertEqual(dict.count, 0U); 1045 XCTAssertFalse([dict getUInt64:NULL forKey:@"foo"]); 1046 XCTAssertFalse([dict getUInt64:NULL forKey:@"bar"]); 1047 XCTAssertFalse([dict getUInt64:NULL forKey:@"baz"]); 1048 XCTAssertFalse([dict getUInt64:NULL forKey:@"mumble"]); 1049 [dict release]; 1050} 1051 1052- (void)testInplaceMutation { 1053 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 1054 const uint64_t kValues[] = { 300U, 301U, 302U, 303U }; 1055 GPBStringUInt64Dictionary *dict = 1056 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues 1057 forKeys:kKeys 1058 count:GPBARRAYSIZE(kValues)]; 1059 XCTAssertNotNil(dict); 1060 XCTAssertEqual(dict.count, 4U); 1061 uint64_t value; 1062 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]); 1063 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]); 1064 XCTAssertEqual(value, 300U); 1065 XCTAssertTrue([dict getUInt64:NULL forKey:@"bar"]); 1066 XCTAssertTrue([dict getUInt64:&value forKey:@"bar"]); 1067 XCTAssertEqual(value, 301U); 1068 XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]); 1069 XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]); 1070 XCTAssertEqual(value, 302U); 1071 XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]); 1072 XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]); 1073 XCTAssertEqual(value, 303U); 1074 1075 [dict setUInt64:303U forKey:@"foo"]; 1076 XCTAssertEqual(dict.count, 4U); 1077 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]); 1078 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]); 1079 XCTAssertEqual(value, 303U); 1080 XCTAssertTrue([dict getUInt64:NULL forKey:@"bar"]); 1081 XCTAssertTrue([dict getUInt64:&value forKey:@"bar"]); 1082 XCTAssertEqual(value, 301U); 1083 XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]); 1084 XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]); 1085 XCTAssertEqual(value, 302U); 1086 XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]); 1087 XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]); 1088 XCTAssertEqual(value, 303U); 1089 1090 [dict setUInt64:301U forKey:@"mumble"]; 1091 XCTAssertEqual(dict.count, 4U); 1092 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]); 1093 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]); 1094 XCTAssertEqual(value, 303U); 1095 XCTAssertTrue([dict getUInt64:NULL forKey:@"bar"]); 1096 XCTAssertTrue([dict getUInt64:&value forKey:@"bar"]); 1097 XCTAssertEqual(value, 301U); 1098 XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]); 1099 XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]); 1100 XCTAssertEqual(value, 302U); 1101 XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]); 1102 XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]); 1103 XCTAssertEqual(value, 301U); 1104 1105 const NSString *kKeys2[] = { @"bar", @"baz" }; 1106 const uint64_t kValues2[] = { 302U, 300U }; 1107 GPBStringUInt64Dictionary *dict2 = 1108 [[GPBStringUInt64Dictionary alloc] initWithUInt64s:kValues2 1109 forKeys:kKeys2 1110 count:GPBARRAYSIZE(kValues2)]; 1111 XCTAssertNotNil(dict2); 1112 [dict addEntriesFromDictionary:dict2]; 1113 XCTAssertEqual(dict.count, 4U); 1114 XCTAssertTrue([dict getUInt64:NULL forKey:@"foo"]); 1115 XCTAssertTrue([dict getUInt64:&value forKey:@"foo"]); 1116 XCTAssertEqual(value, 303U); 1117 XCTAssertTrue([dict getUInt64:NULL forKey:@"bar"]); 1118 XCTAssertTrue([dict getUInt64:&value forKey:@"bar"]); 1119 XCTAssertEqual(value, 302U); 1120 XCTAssertTrue([dict getUInt64:NULL forKey:@"baz"]); 1121 XCTAssertTrue([dict getUInt64:&value forKey:@"baz"]); 1122 XCTAssertEqual(value, 300U); 1123 XCTAssertTrue([dict getUInt64:NULL forKey:@"mumble"]); 1124 XCTAssertTrue([dict getUInt64:&value forKey:@"mumble"]); 1125 XCTAssertEqual(value, 301U); 1126 1127 [dict2 release]; 1128 [dict release]; 1129} 1130 1131@end 1132 1133#pragma mark - String -> Int64 1134 1135@interface GPBStringInt64DictionaryTests : XCTestCase 1136@end 1137 1138@implementation GPBStringInt64DictionaryTests 1139 1140- (void)testEmpty { 1141 GPBStringInt64Dictionary *dict = [[GPBStringInt64Dictionary alloc] init]; 1142 XCTAssertNotNil(dict); 1143 XCTAssertEqual(dict.count, 0U); 1144 XCTAssertFalse([dict getInt64:NULL forKey:@"foo"]); 1145 [dict enumerateKeysAndInt64sUsingBlock:^(__unused NSString *aKey, __unused int64_t aValue, __unused BOOL *stop) { 1146 XCTFail(@"Shouldn't get here!"); 1147 }]; 1148 [dict release]; 1149} 1150 1151- (void)testOne { 1152 GPBStringInt64Dictionary *dict = [[GPBStringInt64Dictionary alloc] init]; 1153 [dict setInt64:400 forKey:@"foo"]; 1154 XCTAssertNotNil(dict); 1155 XCTAssertEqual(dict.count, 1U); 1156 int64_t value; 1157 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]); 1158 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]); 1159 XCTAssertEqual(value, 400); 1160 XCTAssertFalse([dict getInt64:NULL forKey:@"bar"]); 1161 [dict enumerateKeysAndInt64sUsingBlock:^(NSString *aKey, int64_t aValue, BOOL *stop) { 1162 XCTAssertEqualObjects(aKey, @"foo"); 1163 XCTAssertEqual(aValue, 400); 1164 XCTAssertNotEqual(stop, NULL); 1165 }]; 1166 [dict release]; 1167} 1168 1169- (void)testBasics { 1170 const NSString *kKeys[] = { @"foo", @"bar", @"baz" }; 1171 const int64_t kValues[] = { 400, 401, 402 }; 1172 GPBStringInt64Dictionary *dict = 1173 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues 1174 forKeys:kKeys 1175 count:GPBARRAYSIZE(kValues)]; 1176 XCTAssertNotNil(dict); 1177 XCTAssertEqual(dict.count, 3U); 1178 int64_t value; 1179 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]); 1180 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]); 1181 XCTAssertEqual(value, 400); 1182 XCTAssertTrue([dict getInt64:NULL forKey:@"bar"]); 1183 XCTAssertTrue([dict getInt64:&value forKey:@"bar"]); 1184 XCTAssertEqual(value, 401); 1185 XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]); 1186 XCTAssertTrue([dict getInt64:&value forKey:@"baz"]); 1187 XCTAssertEqual(value, 402); 1188 XCTAssertFalse([dict getInt64:NULL forKey:@"mumble"]); 1189 1190 __block NSUInteger idx = 0; 1191 NSString **seenKeys = malloc(3 * sizeof(NSString*)); 1192 int64_t *seenValues = malloc(3 * sizeof(int64_t)); 1193 [dict enumerateKeysAndInt64sUsingBlock:^(NSString *aKey, int64_t aValue, BOOL *stop) { 1194 XCTAssertLessThan(idx, 3U); 1195 seenKeys[idx] = aKey; 1196 seenValues[idx] = aValue; 1197 XCTAssertNotEqual(stop, NULL); 1198 ++idx; 1199 }]; 1200 for (int i = 0; i < 3; ++i) { 1201 BOOL foundKey = NO; 1202 for (int j = 0; (j < 3) && !foundKey; ++j) { 1203 if ([kKeys[i] isEqual:seenKeys[j]]) { 1204 foundKey = YES; 1205 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j); 1206 } 1207 } 1208 XCTAssertTrue(foundKey, @"i = %d", i); 1209 } 1210 free(seenKeys); 1211 free(seenValues); 1212 1213 // Stopping the enumeration. 1214 idx = 0; 1215 [dict enumerateKeysAndInt64sUsingBlock:^(__unused NSString *aKey, __unused int64_t aValue, BOOL *stop) { 1216 if (idx == 1) *stop = YES; 1217 XCTAssertNotEqual(idx, 2U); 1218 ++idx; 1219 }]; 1220 [dict release]; 1221} 1222 1223- (void)testEquality { 1224 const NSString *kKeys1[] = { @"foo", @"bar", @"baz", @"mumble" }; 1225 const NSString *kKeys2[] = { @"bar", @"foo", @"mumble" }; 1226 const int64_t kValues1[] = { 400, 401, 402 }; 1227 const int64_t kValues2[] = { 400, 403, 402 }; 1228 const int64_t kValues3[] = { 400, 401, 402, 403 }; 1229 GPBStringInt64Dictionary *dict1 = 1230 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues1 1231 forKeys:kKeys1 1232 count:GPBARRAYSIZE(kValues1)]; 1233 XCTAssertNotNil(dict1); 1234 GPBStringInt64Dictionary *dict1prime = 1235 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues1 1236 forKeys:kKeys1 1237 count:GPBARRAYSIZE(kValues1)]; 1238 XCTAssertNotNil(dict1prime); 1239 GPBStringInt64Dictionary *dict2 = 1240 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues2 1241 forKeys:kKeys1 1242 count:GPBARRAYSIZE(kValues2)]; 1243 XCTAssertNotNil(dict2); 1244 GPBStringInt64Dictionary *dict3 = 1245 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues1 1246 forKeys:kKeys2 1247 count:GPBARRAYSIZE(kValues1)]; 1248 XCTAssertNotNil(dict3); 1249 GPBStringInt64Dictionary *dict4 = 1250 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues3 1251 forKeys:kKeys1 1252 count:GPBARRAYSIZE(kValues3)]; 1253 XCTAssertNotNil(dict4); 1254 1255 // 1/1Prime should be different objects, but equal. 1256 XCTAssertNotEqual(dict1, dict1prime); 1257 XCTAssertEqualObjects(dict1, dict1prime); 1258 // Equal, so they must have same hash. 1259 XCTAssertEqual([dict1 hash], [dict1prime hash]); 1260 1261 // 2 is same keys, different values; not equal. 1262 XCTAssertNotEqualObjects(dict1, dict2); 1263 1264 // 3 is different keys, same values; not equal. 1265 XCTAssertNotEqualObjects(dict1, dict3); 1266 1267 // 4 extra pair; not equal 1268 XCTAssertNotEqualObjects(dict1, dict4); 1269 1270 [dict1 release]; 1271 [dict1prime release]; 1272 [dict2 release]; 1273 [dict3 release]; 1274 [dict4 release]; 1275} 1276 1277- (void)testCopy { 1278 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 1279 const int64_t kValues[] = { 400, 401, 402, 403 }; 1280 GPBStringInt64Dictionary *dict = 1281 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues 1282 forKeys:kKeys 1283 count:GPBARRAYSIZE(kValues)]; 1284 XCTAssertNotNil(dict); 1285 1286 GPBStringInt64Dictionary *dict2 = [dict copy]; 1287 XCTAssertNotNil(dict2); 1288 1289 // Should be new object but equal. 1290 XCTAssertNotEqual(dict, dict2); 1291 XCTAssertEqualObjects(dict, dict2); 1292 XCTAssertTrue([dict2 isKindOfClass:[GPBStringInt64Dictionary class]]); 1293 1294 [dict2 release]; 1295 [dict release]; 1296} 1297 1298- (void)testDictionaryFromDictionary { 1299 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 1300 const int64_t kValues[] = { 400, 401, 402, 403 }; 1301 GPBStringInt64Dictionary *dict = 1302 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues 1303 forKeys:kKeys 1304 count:GPBARRAYSIZE(kValues)]; 1305 XCTAssertNotNil(dict); 1306 1307 GPBStringInt64Dictionary *dict2 = 1308 [[GPBStringInt64Dictionary alloc] initWithDictionary:dict]; 1309 XCTAssertNotNil(dict2); 1310 1311 // Should be new pointer, but equal objects. 1312 XCTAssertNotEqual(dict, dict2); 1313 XCTAssertEqualObjects(dict, dict2); 1314 [dict2 release]; 1315 [dict release]; 1316} 1317 1318- (void)testAdds { 1319 GPBStringInt64Dictionary *dict = [[GPBStringInt64Dictionary alloc] init]; 1320 XCTAssertNotNil(dict); 1321 1322 XCTAssertEqual(dict.count, 0U); 1323 [dict setInt64:400 forKey:@"foo"]; 1324 XCTAssertEqual(dict.count, 1U); 1325 1326 const NSString *kKeys[] = { @"bar", @"baz", @"mumble" }; 1327 const int64_t kValues[] = { 401, 402, 403 }; 1328 GPBStringInt64Dictionary *dict2 = 1329 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues 1330 forKeys:kKeys 1331 count:GPBARRAYSIZE(kValues)]; 1332 XCTAssertNotNil(dict2); 1333 [dict addEntriesFromDictionary:dict2]; 1334 XCTAssertEqual(dict.count, 4U); 1335 1336 int64_t value; 1337 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]); 1338 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]); 1339 XCTAssertEqual(value, 400); 1340 XCTAssertTrue([dict getInt64:NULL forKey:@"bar"]); 1341 XCTAssertTrue([dict getInt64:&value forKey:@"bar"]); 1342 XCTAssertEqual(value, 401); 1343 XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]); 1344 XCTAssertTrue([dict getInt64:&value forKey:@"baz"]); 1345 XCTAssertEqual(value, 402); 1346 XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]); 1347 XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]); 1348 XCTAssertEqual(value, 403); 1349 [dict2 release]; 1350 [dict release]; 1351} 1352 1353- (void)testRemove { 1354 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 1355 const int64_t kValues[] = { 400, 401, 402, 403 }; 1356 GPBStringInt64Dictionary *dict = 1357 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues 1358 forKeys:kKeys 1359 count:GPBARRAYSIZE(kValues)]; 1360 XCTAssertNotNil(dict); 1361 XCTAssertEqual(dict.count, 4U); 1362 1363 [dict removeInt64ForKey:@"bar"]; 1364 XCTAssertEqual(dict.count, 3U); 1365 int64_t value; 1366 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]); 1367 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]); 1368 XCTAssertEqual(value, 400); 1369 XCTAssertFalse([dict getInt64:NULL forKey:@"bar"]); 1370 XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]); 1371 XCTAssertTrue([dict getInt64:&value forKey:@"baz"]); 1372 XCTAssertEqual(value, 402); 1373 XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]); 1374 XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]); 1375 XCTAssertEqual(value, 403); 1376 1377 // Remove again does nothing. 1378 [dict removeInt64ForKey:@"bar"]; 1379 XCTAssertEqual(dict.count, 3U); 1380 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]); 1381 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]); 1382 XCTAssertEqual(value, 400); 1383 XCTAssertFalse([dict getInt64:NULL forKey:@"bar"]); 1384 XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]); 1385 XCTAssertTrue([dict getInt64:&value forKey:@"baz"]); 1386 XCTAssertEqual(value, 402); 1387 XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]); 1388 XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]); 1389 XCTAssertEqual(value, 403); 1390 1391 [dict removeInt64ForKey:@"mumble"]; 1392 XCTAssertEqual(dict.count, 2U); 1393 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]); 1394 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]); 1395 XCTAssertEqual(value, 400); 1396 XCTAssertFalse([dict getInt64:NULL forKey:@"bar"]); 1397 XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]); 1398 XCTAssertTrue([dict getInt64:&value forKey:@"baz"]); 1399 XCTAssertEqual(value, 402); 1400 XCTAssertFalse([dict getInt64:NULL forKey:@"mumble"]); 1401 1402 [dict removeAll]; 1403 XCTAssertEqual(dict.count, 0U); 1404 XCTAssertFalse([dict getInt64:NULL forKey:@"foo"]); 1405 XCTAssertFalse([dict getInt64:NULL forKey:@"bar"]); 1406 XCTAssertFalse([dict getInt64:NULL forKey:@"baz"]); 1407 XCTAssertFalse([dict getInt64:NULL forKey:@"mumble"]); 1408 [dict release]; 1409} 1410 1411- (void)testInplaceMutation { 1412 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 1413 const int64_t kValues[] = { 400, 401, 402, 403 }; 1414 GPBStringInt64Dictionary *dict = 1415 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues 1416 forKeys:kKeys 1417 count:GPBARRAYSIZE(kValues)]; 1418 XCTAssertNotNil(dict); 1419 XCTAssertEqual(dict.count, 4U); 1420 int64_t value; 1421 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]); 1422 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]); 1423 XCTAssertEqual(value, 400); 1424 XCTAssertTrue([dict getInt64:NULL forKey:@"bar"]); 1425 XCTAssertTrue([dict getInt64:&value forKey:@"bar"]); 1426 XCTAssertEqual(value, 401); 1427 XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]); 1428 XCTAssertTrue([dict getInt64:&value forKey:@"baz"]); 1429 XCTAssertEqual(value, 402); 1430 XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]); 1431 XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]); 1432 XCTAssertEqual(value, 403); 1433 1434 [dict setInt64:403 forKey:@"foo"]; 1435 XCTAssertEqual(dict.count, 4U); 1436 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]); 1437 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]); 1438 XCTAssertEqual(value, 403); 1439 XCTAssertTrue([dict getInt64:NULL forKey:@"bar"]); 1440 XCTAssertTrue([dict getInt64:&value forKey:@"bar"]); 1441 XCTAssertEqual(value, 401); 1442 XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]); 1443 XCTAssertTrue([dict getInt64:&value forKey:@"baz"]); 1444 XCTAssertEqual(value, 402); 1445 XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]); 1446 XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]); 1447 XCTAssertEqual(value, 403); 1448 1449 [dict setInt64:401 forKey:@"mumble"]; 1450 XCTAssertEqual(dict.count, 4U); 1451 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]); 1452 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]); 1453 XCTAssertEqual(value, 403); 1454 XCTAssertTrue([dict getInt64:NULL forKey:@"bar"]); 1455 XCTAssertTrue([dict getInt64:&value forKey:@"bar"]); 1456 XCTAssertEqual(value, 401); 1457 XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]); 1458 XCTAssertTrue([dict getInt64:&value forKey:@"baz"]); 1459 XCTAssertEqual(value, 402); 1460 XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]); 1461 XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]); 1462 XCTAssertEqual(value, 401); 1463 1464 const NSString *kKeys2[] = { @"bar", @"baz" }; 1465 const int64_t kValues2[] = { 402, 400 }; 1466 GPBStringInt64Dictionary *dict2 = 1467 [[GPBStringInt64Dictionary alloc] initWithInt64s:kValues2 1468 forKeys:kKeys2 1469 count:GPBARRAYSIZE(kValues2)]; 1470 XCTAssertNotNil(dict2); 1471 [dict addEntriesFromDictionary:dict2]; 1472 XCTAssertEqual(dict.count, 4U); 1473 XCTAssertTrue([dict getInt64:NULL forKey:@"foo"]); 1474 XCTAssertTrue([dict getInt64:&value forKey:@"foo"]); 1475 XCTAssertEqual(value, 403); 1476 XCTAssertTrue([dict getInt64:NULL forKey:@"bar"]); 1477 XCTAssertTrue([dict getInt64:&value forKey:@"bar"]); 1478 XCTAssertEqual(value, 402); 1479 XCTAssertTrue([dict getInt64:NULL forKey:@"baz"]); 1480 XCTAssertTrue([dict getInt64:&value forKey:@"baz"]); 1481 XCTAssertEqual(value, 400); 1482 XCTAssertTrue([dict getInt64:NULL forKey:@"mumble"]); 1483 XCTAssertTrue([dict getInt64:&value forKey:@"mumble"]); 1484 XCTAssertEqual(value, 401); 1485 1486 [dict2 release]; 1487 [dict release]; 1488} 1489 1490@end 1491 1492#pragma mark - String -> Bool 1493 1494@interface GPBStringBoolDictionaryTests : XCTestCase 1495@end 1496 1497@implementation GPBStringBoolDictionaryTests 1498 1499- (void)testEmpty { 1500 GPBStringBoolDictionary *dict = [[GPBStringBoolDictionary alloc] init]; 1501 XCTAssertNotNil(dict); 1502 XCTAssertEqual(dict.count, 0U); 1503 XCTAssertFalse([dict getBool:NULL forKey:@"foo"]); 1504 [dict enumerateKeysAndBoolsUsingBlock:^(__unused NSString *aKey, __unused BOOL aValue, __unused BOOL *stop) { 1505 XCTFail(@"Shouldn't get here!"); 1506 }]; 1507 [dict release]; 1508} 1509 1510- (void)testOne { 1511 GPBStringBoolDictionary *dict = [[GPBStringBoolDictionary alloc] init]; 1512 [dict setBool:YES forKey:@"foo"]; 1513 XCTAssertNotNil(dict); 1514 XCTAssertEqual(dict.count, 1U); 1515 BOOL value; 1516 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]); 1517 XCTAssertTrue([dict getBool:&value forKey:@"foo"]); 1518 XCTAssertEqual(value, YES); 1519 XCTAssertFalse([dict getBool:NULL forKey:@"bar"]); 1520 [dict enumerateKeysAndBoolsUsingBlock:^(NSString *aKey, BOOL aValue, BOOL *stop) { 1521 XCTAssertEqualObjects(aKey, @"foo"); 1522 XCTAssertEqual(aValue, YES); 1523 XCTAssertNotEqual(stop, NULL); 1524 }]; 1525 [dict release]; 1526} 1527 1528- (void)testBasics { 1529 const NSString *kKeys[] = { @"foo", @"bar", @"baz" }; 1530 const BOOL kValues[] = { YES, YES, NO }; 1531 GPBStringBoolDictionary *dict = 1532 [[GPBStringBoolDictionary alloc] initWithBools:kValues 1533 forKeys:kKeys 1534 count:GPBARRAYSIZE(kValues)]; 1535 XCTAssertNotNil(dict); 1536 XCTAssertEqual(dict.count, 3U); 1537 BOOL value; 1538 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]); 1539 XCTAssertTrue([dict getBool:&value forKey:@"foo"]); 1540 XCTAssertEqual(value, YES); 1541 XCTAssertTrue([dict getBool:NULL forKey:@"bar"]); 1542 XCTAssertTrue([dict getBool:&value forKey:@"bar"]); 1543 XCTAssertEqual(value, YES); 1544 XCTAssertTrue([dict getBool:NULL forKey:@"baz"]); 1545 XCTAssertTrue([dict getBool:&value forKey:@"baz"]); 1546 XCTAssertEqual(value, NO); 1547 XCTAssertFalse([dict getBool:NULL forKey:@"mumble"]); 1548 1549 __block NSUInteger idx = 0; 1550 NSString **seenKeys = malloc(3 * sizeof(NSString*)); 1551 BOOL *seenValues = malloc(3 * sizeof(BOOL)); 1552 [dict enumerateKeysAndBoolsUsingBlock:^(NSString *aKey, BOOL aValue, BOOL *stop) { 1553 XCTAssertLessThan(idx, 3U); 1554 seenKeys[idx] = aKey; 1555 seenValues[idx] = aValue; 1556 XCTAssertNotEqual(stop, NULL); 1557 ++idx; 1558 }]; 1559 for (int i = 0; i < 3; ++i) { 1560 BOOL foundKey = NO; 1561 for (int j = 0; (j < 3) && !foundKey; ++j) { 1562 if ([kKeys[i] isEqual:seenKeys[j]]) { 1563 foundKey = YES; 1564 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j); 1565 } 1566 } 1567 XCTAssertTrue(foundKey, @"i = %d", i); 1568 } 1569 free(seenKeys); 1570 free(seenValues); 1571 1572 // Stopping the enumeration. 1573 idx = 0; 1574 [dict enumerateKeysAndBoolsUsingBlock:^(__unused NSString *aKey, __unused BOOL aValue, BOOL *stop) { 1575 if (idx == 1) *stop = YES; 1576 XCTAssertNotEqual(idx, 2U); 1577 ++idx; 1578 }]; 1579 [dict release]; 1580} 1581 1582- (void)testEquality { 1583 const NSString *kKeys1[] = { @"foo", @"bar", @"baz", @"mumble" }; 1584 const NSString *kKeys2[] = { @"bar", @"foo", @"mumble" }; 1585 const BOOL kValues1[] = { YES, YES, NO }; 1586 const BOOL kValues2[] = { YES, NO, NO }; 1587 const BOOL kValues3[] = { YES, YES, NO, NO }; 1588 GPBStringBoolDictionary *dict1 = 1589 [[GPBStringBoolDictionary alloc] initWithBools:kValues1 1590 forKeys:kKeys1 1591 count:GPBARRAYSIZE(kValues1)]; 1592 XCTAssertNotNil(dict1); 1593 GPBStringBoolDictionary *dict1prime = 1594 [[GPBStringBoolDictionary alloc] initWithBools:kValues1 1595 forKeys:kKeys1 1596 count:GPBARRAYSIZE(kValues1)]; 1597 XCTAssertNotNil(dict1prime); 1598 GPBStringBoolDictionary *dict2 = 1599 [[GPBStringBoolDictionary alloc] initWithBools:kValues2 1600 forKeys:kKeys1 1601 count:GPBARRAYSIZE(kValues2)]; 1602 XCTAssertNotNil(dict2); 1603 GPBStringBoolDictionary *dict3 = 1604 [[GPBStringBoolDictionary alloc] initWithBools:kValues1 1605 forKeys:kKeys2 1606 count:GPBARRAYSIZE(kValues1)]; 1607 XCTAssertNotNil(dict3); 1608 GPBStringBoolDictionary *dict4 = 1609 [[GPBStringBoolDictionary alloc] initWithBools:kValues3 1610 forKeys:kKeys1 1611 count:GPBARRAYSIZE(kValues3)]; 1612 XCTAssertNotNil(dict4); 1613 1614 // 1/1Prime should be different objects, but equal. 1615 XCTAssertNotEqual(dict1, dict1prime); 1616 XCTAssertEqualObjects(dict1, dict1prime); 1617 // Equal, so they must have same hash. 1618 XCTAssertEqual([dict1 hash], [dict1prime hash]); 1619 1620 // 2 is same keys, different values; not equal. 1621 XCTAssertNotEqualObjects(dict1, dict2); 1622 1623 // 3 is different keys, same values; not equal. 1624 XCTAssertNotEqualObjects(dict1, dict3); 1625 1626 // 4 extra pair; not equal 1627 XCTAssertNotEqualObjects(dict1, dict4); 1628 1629 [dict1 release]; 1630 [dict1prime release]; 1631 [dict2 release]; 1632 [dict3 release]; 1633 [dict4 release]; 1634} 1635 1636- (void)testCopy { 1637 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 1638 const BOOL kValues[] = { YES, YES, NO, NO }; 1639 GPBStringBoolDictionary *dict = 1640 [[GPBStringBoolDictionary alloc] initWithBools:kValues 1641 forKeys:kKeys 1642 count:GPBARRAYSIZE(kValues)]; 1643 XCTAssertNotNil(dict); 1644 1645 GPBStringBoolDictionary *dict2 = [dict copy]; 1646 XCTAssertNotNil(dict2); 1647 1648 // Should be new object but equal. 1649 XCTAssertNotEqual(dict, dict2); 1650 XCTAssertEqualObjects(dict, dict2); 1651 XCTAssertTrue([dict2 isKindOfClass:[GPBStringBoolDictionary class]]); 1652 1653 [dict2 release]; 1654 [dict release]; 1655} 1656 1657- (void)testDictionaryFromDictionary { 1658 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 1659 const BOOL kValues[] = { YES, YES, NO, NO }; 1660 GPBStringBoolDictionary *dict = 1661 [[GPBStringBoolDictionary alloc] initWithBools:kValues 1662 forKeys:kKeys 1663 count:GPBARRAYSIZE(kValues)]; 1664 XCTAssertNotNil(dict); 1665 1666 GPBStringBoolDictionary *dict2 = 1667 [[GPBStringBoolDictionary alloc] initWithDictionary:dict]; 1668 XCTAssertNotNil(dict2); 1669 1670 // Should be new pointer, but equal objects. 1671 XCTAssertNotEqual(dict, dict2); 1672 XCTAssertEqualObjects(dict, dict2); 1673 [dict2 release]; 1674 [dict release]; 1675} 1676 1677- (void)testAdds { 1678 GPBStringBoolDictionary *dict = [[GPBStringBoolDictionary alloc] init]; 1679 XCTAssertNotNil(dict); 1680 1681 XCTAssertEqual(dict.count, 0U); 1682 [dict setBool:YES forKey:@"foo"]; 1683 XCTAssertEqual(dict.count, 1U); 1684 1685 const NSString *kKeys[] = { @"bar", @"baz", @"mumble" }; 1686 const BOOL kValues[] = { YES, NO, NO }; 1687 GPBStringBoolDictionary *dict2 = 1688 [[GPBStringBoolDictionary alloc] initWithBools:kValues 1689 forKeys:kKeys 1690 count:GPBARRAYSIZE(kValues)]; 1691 XCTAssertNotNil(dict2); 1692 [dict addEntriesFromDictionary:dict2]; 1693 XCTAssertEqual(dict.count, 4U); 1694 1695 BOOL value; 1696 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]); 1697 XCTAssertTrue([dict getBool:&value forKey:@"foo"]); 1698 XCTAssertEqual(value, YES); 1699 XCTAssertTrue([dict getBool:NULL forKey:@"bar"]); 1700 XCTAssertTrue([dict getBool:&value forKey:@"bar"]); 1701 XCTAssertEqual(value, YES); 1702 XCTAssertTrue([dict getBool:NULL forKey:@"baz"]); 1703 XCTAssertTrue([dict getBool:&value forKey:@"baz"]); 1704 XCTAssertEqual(value, NO); 1705 XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]); 1706 XCTAssertTrue([dict getBool:&value forKey:@"mumble"]); 1707 XCTAssertEqual(value, NO); 1708 [dict2 release]; 1709 [dict release]; 1710} 1711 1712- (void)testRemove { 1713 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 1714 const BOOL kValues[] = { YES, YES, NO, NO }; 1715 GPBStringBoolDictionary *dict = 1716 [[GPBStringBoolDictionary alloc] initWithBools:kValues 1717 forKeys:kKeys 1718 count:GPBARRAYSIZE(kValues)]; 1719 XCTAssertNotNil(dict); 1720 XCTAssertEqual(dict.count, 4U); 1721 1722 [dict removeBoolForKey:@"bar"]; 1723 XCTAssertEqual(dict.count, 3U); 1724 BOOL value; 1725 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]); 1726 XCTAssertTrue([dict getBool:&value forKey:@"foo"]); 1727 XCTAssertEqual(value, YES); 1728 XCTAssertFalse([dict getBool:NULL forKey:@"bar"]); 1729 XCTAssertTrue([dict getBool:NULL forKey:@"baz"]); 1730 XCTAssertTrue([dict getBool:&value forKey:@"baz"]); 1731 XCTAssertEqual(value, NO); 1732 XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]); 1733 XCTAssertTrue([dict getBool:&value forKey:@"mumble"]); 1734 XCTAssertEqual(value, NO); 1735 1736 // Remove again does nothing. 1737 [dict removeBoolForKey:@"bar"]; 1738 XCTAssertEqual(dict.count, 3U); 1739 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]); 1740 XCTAssertTrue([dict getBool:&value forKey:@"foo"]); 1741 XCTAssertEqual(value, YES); 1742 XCTAssertFalse([dict getBool:NULL forKey:@"bar"]); 1743 XCTAssertTrue([dict getBool:NULL forKey:@"baz"]); 1744 XCTAssertTrue([dict getBool:&value forKey:@"baz"]); 1745 XCTAssertEqual(value, NO); 1746 XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]); 1747 XCTAssertTrue([dict getBool:&value forKey:@"mumble"]); 1748 XCTAssertEqual(value, NO); 1749 1750 [dict removeBoolForKey:@"mumble"]; 1751 XCTAssertEqual(dict.count, 2U); 1752 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]); 1753 XCTAssertTrue([dict getBool:&value forKey:@"foo"]); 1754 XCTAssertEqual(value, YES); 1755 XCTAssertFalse([dict getBool:NULL forKey:@"bar"]); 1756 XCTAssertTrue([dict getBool:NULL forKey:@"baz"]); 1757 XCTAssertTrue([dict getBool:&value forKey:@"baz"]); 1758 XCTAssertEqual(value, NO); 1759 XCTAssertFalse([dict getBool:NULL forKey:@"mumble"]); 1760 1761 [dict removeAll]; 1762 XCTAssertEqual(dict.count, 0U); 1763 XCTAssertFalse([dict getBool:NULL forKey:@"foo"]); 1764 XCTAssertFalse([dict getBool:NULL forKey:@"bar"]); 1765 XCTAssertFalse([dict getBool:NULL forKey:@"baz"]); 1766 XCTAssertFalse([dict getBool:NULL forKey:@"mumble"]); 1767 [dict release]; 1768} 1769 1770- (void)testInplaceMutation { 1771 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 1772 const BOOL kValues[] = { YES, YES, NO, NO }; 1773 GPBStringBoolDictionary *dict = 1774 [[GPBStringBoolDictionary alloc] initWithBools:kValues 1775 forKeys:kKeys 1776 count:GPBARRAYSIZE(kValues)]; 1777 XCTAssertNotNil(dict); 1778 XCTAssertEqual(dict.count, 4U); 1779 BOOL value; 1780 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]); 1781 XCTAssertTrue([dict getBool:&value forKey:@"foo"]); 1782 XCTAssertEqual(value, YES); 1783 XCTAssertTrue([dict getBool:NULL forKey:@"bar"]); 1784 XCTAssertTrue([dict getBool:&value forKey:@"bar"]); 1785 XCTAssertEqual(value, YES); 1786 XCTAssertTrue([dict getBool:NULL forKey:@"baz"]); 1787 XCTAssertTrue([dict getBool:&value forKey:@"baz"]); 1788 XCTAssertEqual(value, NO); 1789 XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]); 1790 XCTAssertTrue([dict getBool:&value forKey:@"mumble"]); 1791 XCTAssertEqual(value, NO); 1792 1793 [dict setBool:NO forKey:@"foo"]; 1794 XCTAssertEqual(dict.count, 4U); 1795 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]); 1796 XCTAssertTrue([dict getBool:&value forKey:@"foo"]); 1797 XCTAssertEqual(value, NO); 1798 XCTAssertTrue([dict getBool:NULL forKey:@"bar"]); 1799 XCTAssertTrue([dict getBool:&value forKey:@"bar"]); 1800 XCTAssertEqual(value, YES); 1801 XCTAssertTrue([dict getBool:NULL forKey:@"baz"]); 1802 XCTAssertTrue([dict getBool:&value forKey:@"baz"]); 1803 XCTAssertEqual(value, NO); 1804 XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]); 1805 XCTAssertTrue([dict getBool:&value forKey:@"mumble"]); 1806 XCTAssertEqual(value, NO); 1807 1808 [dict setBool:YES forKey:@"mumble"]; 1809 XCTAssertEqual(dict.count, 4U); 1810 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]); 1811 XCTAssertTrue([dict getBool:&value forKey:@"foo"]); 1812 XCTAssertEqual(value, NO); 1813 XCTAssertTrue([dict getBool:NULL forKey:@"bar"]); 1814 XCTAssertTrue([dict getBool:&value forKey:@"bar"]); 1815 XCTAssertEqual(value, YES); 1816 XCTAssertTrue([dict getBool:NULL forKey:@"baz"]); 1817 XCTAssertTrue([dict getBool:&value forKey:@"baz"]); 1818 XCTAssertEqual(value, NO); 1819 XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]); 1820 XCTAssertTrue([dict getBool:&value forKey:@"mumble"]); 1821 XCTAssertEqual(value, YES); 1822 1823 const NSString *kKeys2[] = { @"bar", @"baz" }; 1824 const BOOL kValues2[] = { NO, YES }; 1825 GPBStringBoolDictionary *dict2 = 1826 [[GPBStringBoolDictionary alloc] initWithBools:kValues2 1827 forKeys:kKeys2 1828 count:GPBARRAYSIZE(kValues2)]; 1829 XCTAssertNotNil(dict2); 1830 [dict addEntriesFromDictionary:dict2]; 1831 XCTAssertEqual(dict.count, 4U); 1832 XCTAssertTrue([dict getBool:NULL forKey:@"foo"]); 1833 XCTAssertTrue([dict getBool:&value forKey:@"foo"]); 1834 XCTAssertEqual(value, NO); 1835 XCTAssertTrue([dict getBool:NULL forKey:@"bar"]); 1836 XCTAssertTrue([dict getBool:&value forKey:@"bar"]); 1837 XCTAssertEqual(value, NO); 1838 XCTAssertTrue([dict getBool:NULL forKey:@"baz"]); 1839 XCTAssertTrue([dict getBool:&value forKey:@"baz"]); 1840 XCTAssertEqual(value, YES); 1841 XCTAssertTrue([dict getBool:NULL forKey:@"mumble"]); 1842 XCTAssertTrue([dict getBool:&value forKey:@"mumble"]); 1843 XCTAssertEqual(value, YES); 1844 1845 [dict2 release]; 1846 [dict release]; 1847} 1848 1849@end 1850 1851#pragma mark - String -> Float 1852 1853@interface GPBStringFloatDictionaryTests : XCTestCase 1854@end 1855 1856@implementation GPBStringFloatDictionaryTests 1857 1858- (void)testEmpty { 1859 GPBStringFloatDictionary *dict = [[GPBStringFloatDictionary alloc] init]; 1860 XCTAssertNotNil(dict); 1861 XCTAssertEqual(dict.count, 0U); 1862 XCTAssertFalse([dict getFloat:NULL forKey:@"foo"]); 1863 [dict enumerateKeysAndFloatsUsingBlock:^(__unused NSString *aKey, __unused float aValue, __unused BOOL *stop) { 1864 XCTFail(@"Shouldn't get here!"); 1865 }]; 1866 [dict release]; 1867} 1868 1869- (void)testOne { 1870 GPBStringFloatDictionary *dict = [[GPBStringFloatDictionary alloc] init]; 1871 [dict setFloat:500.f forKey:@"foo"]; 1872 XCTAssertNotNil(dict); 1873 XCTAssertEqual(dict.count, 1U); 1874 float value; 1875 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]); 1876 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]); 1877 XCTAssertEqual(value, 500.f); 1878 XCTAssertFalse([dict getFloat:NULL forKey:@"bar"]); 1879 [dict enumerateKeysAndFloatsUsingBlock:^(NSString *aKey, float aValue, BOOL *stop) { 1880 XCTAssertEqualObjects(aKey, @"foo"); 1881 XCTAssertEqual(aValue, 500.f); 1882 XCTAssertNotEqual(stop, NULL); 1883 }]; 1884 [dict release]; 1885} 1886 1887- (void)testBasics { 1888 const NSString *kKeys[] = { @"foo", @"bar", @"baz" }; 1889 const float kValues[] = { 500.f, 501.f, 502.f }; 1890 GPBStringFloatDictionary *dict = 1891 [[GPBStringFloatDictionary alloc] initWithFloats:kValues 1892 forKeys:kKeys 1893 count:GPBARRAYSIZE(kValues)]; 1894 XCTAssertNotNil(dict); 1895 XCTAssertEqual(dict.count, 3U); 1896 float value; 1897 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]); 1898 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]); 1899 XCTAssertEqual(value, 500.f); 1900 XCTAssertTrue([dict getFloat:NULL forKey:@"bar"]); 1901 XCTAssertTrue([dict getFloat:&value forKey:@"bar"]); 1902 XCTAssertEqual(value, 501.f); 1903 XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]); 1904 XCTAssertTrue([dict getFloat:&value forKey:@"baz"]); 1905 XCTAssertEqual(value, 502.f); 1906 XCTAssertFalse([dict getFloat:NULL forKey:@"mumble"]); 1907 1908 __block NSUInteger idx = 0; 1909 NSString **seenKeys = malloc(3 * sizeof(NSString*)); 1910 float *seenValues = malloc(3 * sizeof(float)); 1911 [dict enumerateKeysAndFloatsUsingBlock:^(NSString *aKey, float aValue, BOOL *stop) { 1912 XCTAssertLessThan(idx, 3U); 1913 seenKeys[idx] = aKey; 1914 seenValues[idx] = aValue; 1915 XCTAssertNotEqual(stop, NULL); 1916 ++idx; 1917 }]; 1918 for (int i = 0; i < 3; ++i) { 1919 BOOL foundKey = NO; 1920 for (int j = 0; (j < 3) && !foundKey; ++j) { 1921 if ([kKeys[i] isEqual:seenKeys[j]]) { 1922 foundKey = YES; 1923 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j); 1924 } 1925 } 1926 XCTAssertTrue(foundKey, @"i = %d", i); 1927 } 1928 free(seenKeys); 1929 free(seenValues); 1930 1931 // Stopping the enumeration. 1932 idx = 0; 1933 [dict enumerateKeysAndFloatsUsingBlock:^(__unused NSString *aKey, __unused float aValue, BOOL *stop) { 1934 if (idx == 1) *stop = YES; 1935 XCTAssertNotEqual(idx, 2U); 1936 ++idx; 1937 }]; 1938 [dict release]; 1939} 1940 1941- (void)testEquality { 1942 const NSString *kKeys1[] = { @"foo", @"bar", @"baz", @"mumble" }; 1943 const NSString *kKeys2[] = { @"bar", @"foo", @"mumble" }; 1944 const float kValues1[] = { 500.f, 501.f, 502.f }; 1945 const float kValues2[] = { 500.f, 503.f, 502.f }; 1946 const float kValues3[] = { 500.f, 501.f, 502.f, 503.f }; 1947 GPBStringFloatDictionary *dict1 = 1948 [[GPBStringFloatDictionary alloc] initWithFloats:kValues1 1949 forKeys:kKeys1 1950 count:GPBARRAYSIZE(kValues1)]; 1951 XCTAssertNotNil(dict1); 1952 GPBStringFloatDictionary *dict1prime = 1953 [[GPBStringFloatDictionary alloc] initWithFloats:kValues1 1954 forKeys:kKeys1 1955 count:GPBARRAYSIZE(kValues1)]; 1956 XCTAssertNotNil(dict1prime); 1957 GPBStringFloatDictionary *dict2 = 1958 [[GPBStringFloatDictionary alloc] initWithFloats:kValues2 1959 forKeys:kKeys1 1960 count:GPBARRAYSIZE(kValues2)]; 1961 XCTAssertNotNil(dict2); 1962 GPBStringFloatDictionary *dict3 = 1963 [[GPBStringFloatDictionary alloc] initWithFloats:kValues1 1964 forKeys:kKeys2 1965 count:GPBARRAYSIZE(kValues1)]; 1966 XCTAssertNotNil(dict3); 1967 GPBStringFloatDictionary *dict4 = 1968 [[GPBStringFloatDictionary alloc] initWithFloats:kValues3 1969 forKeys:kKeys1 1970 count:GPBARRAYSIZE(kValues3)]; 1971 XCTAssertNotNil(dict4); 1972 1973 // 1/1Prime should be different objects, but equal. 1974 XCTAssertNotEqual(dict1, dict1prime); 1975 XCTAssertEqualObjects(dict1, dict1prime); 1976 // Equal, so they must have same hash. 1977 XCTAssertEqual([dict1 hash], [dict1prime hash]); 1978 1979 // 2 is same keys, different values; not equal. 1980 XCTAssertNotEqualObjects(dict1, dict2); 1981 1982 // 3 is different keys, same values; not equal. 1983 XCTAssertNotEqualObjects(dict1, dict3); 1984 1985 // 4 extra pair; not equal 1986 XCTAssertNotEqualObjects(dict1, dict4); 1987 1988 [dict1 release]; 1989 [dict1prime release]; 1990 [dict2 release]; 1991 [dict3 release]; 1992 [dict4 release]; 1993} 1994 1995- (void)testCopy { 1996 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 1997 const float kValues[] = { 500.f, 501.f, 502.f, 503.f }; 1998 GPBStringFloatDictionary *dict = 1999 [[GPBStringFloatDictionary alloc] initWithFloats:kValues 2000 forKeys:kKeys 2001 count:GPBARRAYSIZE(kValues)]; 2002 XCTAssertNotNil(dict); 2003 2004 GPBStringFloatDictionary *dict2 = [dict copy]; 2005 XCTAssertNotNil(dict2); 2006 2007 // Should be new object but equal. 2008 XCTAssertNotEqual(dict, dict2); 2009 XCTAssertEqualObjects(dict, dict2); 2010 XCTAssertTrue([dict2 isKindOfClass:[GPBStringFloatDictionary class]]); 2011 2012 [dict2 release]; 2013 [dict release]; 2014} 2015 2016- (void)testDictionaryFromDictionary { 2017 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 2018 const float kValues[] = { 500.f, 501.f, 502.f, 503.f }; 2019 GPBStringFloatDictionary *dict = 2020 [[GPBStringFloatDictionary alloc] initWithFloats:kValues 2021 forKeys:kKeys 2022 count:GPBARRAYSIZE(kValues)]; 2023 XCTAssertNotNil(dict); 2024 2025 GPBStringFloatDictionary *dict2 = 2026 [[GPBStringFloatDictionary alloc] initWithDictionary:dict]; 2027 XCTAssertNotNil(dict2); 2028 2029 // Should be new pointer, but equal objects. 2030 XCTAssertNotEqual(dict, dict2); 2031 XCTAssertEqualObjects(dict, dict2); 2032 [dict2 release]; 2033 [dict release]; 2034} 2035 2036- (void)testAdds { 2037 GPBStringFloatDictionary *dict = [[GPBStringFloatDictionary alloc] init]; 2038 XCTAssertNotNil(dict); 2039 2040 XCTAssertEqual(dict.count, 0U); 2041 [dict setFloat:500.f forKey:@"foo"]; 2042 XCTAssertEqual(dict.count, 1U); 2043 2044 const NSString *kKeys[] = { @"bar", @"baz", @"mumble" }; 2045 const float kValues[] = { 501.f, 502.f, 503.f }; 2046 GPBStringFloatDictionary *dict2 = 2047 [[GPBStringFloatDictionary alloc] initWithFloats:kValues 2048 forKeys:kKeys 2049 count:GPBARRAYSIZE(kValues)]; 2050 XCTAssertNotNil(dict2); 2051 [dict addEntriesFromDictionary:dict2]; 2052 XCTAssertEqual(dict.count, 4U); 2053 2054 float value; 2055 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]); 2056 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]); 2057 XCTAssertEqual(value, 500.f); 2058 XCTAssertTrue([dict getFloat:NULL forKey:@"bar"]); 2059 XCTAssertTrue([dict getFloat:&value forKey:@"bar"]); 2060 XCTAssertEqual(value, 501.f); 2061 XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]); 2062 XCTAssertTrue([dict getFloat:&value forKey:@"baz"]); 2063 XCTAssertEqual(value, 502.f); 2064 XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]); 2065 XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]); 2066 XCTAssertEqual(value, 503.f); 2067 [dict2 release]; 2068 [dict release]; 2069} 2070 2071- (void)testRemove { 2072 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 2073 const float kValues[] = { 500.f, 501.f, 502.f, 503.f }; 2074 GPBStringFloatDictionary *dict = 2075 [[GPBStringFloatDictionary alloc] initWithFloats:kValues 2076 forKeys:kKeys 2077 count:GPBARRAYSIZE(kValues)]; 2078 XCTAssertNotNil(dict); 2079 XCTAssertEqual(dict.count, 4U); 2080 2081 [dict removeFloatForKey:@"bar"]; 2082 XCTAssertEqual(dict.count, 3U); 2083 float value; 2084 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]); 2085 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]); 2086 XCTAssertEqual(value, 500.f); 2087 XCTAssertFalse([dict getFloat:NULL forKey:@"bar"]); 2088 XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]); 2089 XCTAssertTrue([dict getFloat:&value forKey:@"baz"]); 2090 XCTAssertEqual(value, 502.f); 2091 XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]); 2092 XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]); 2093 XCTAssertEqual(value, 503.f); 2094 2095 // Remove again does nothing. 2096 [dict removeFloatForKey:@"bar"]; 2097 XCTAssertEqual(dict.count, 3U); 2098 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]); 2099 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]); 2100 XCTAssertEqual(value, 500.f); 2101 XCTAssertFalse([dict getFloat:NULL forKey:@"bar"]); 2102 XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]); 2103 XCTAssertTrue([dict getFloat:&value forKey:@"baz"]); 2104 XCTAssertEqual(value, 502.f); 2105 XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]); 2106 XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]); 2107 XCTAssertEqual(value, 503.f); 2108 2109 [dict removeFloatForKey:@"mumble"]; 2110 XCTAssertEqual(dict.count, 2U); 2111 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]); 2112 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]); 2113 XCTAssertEqual(value, 500.f); 2114 XCTAssertFalse([dict getFloat:NULL forKey:@"bar"]); 2115 XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]); 2116 XCTAssertTrue([dict getFloat:&value forKey:@"baz"]); 2117 XCTAssertEqual(value, 502.f); 2118 XCTAssertFalse([dict getFloat:NULL forKey:@"mumble"]); 2119 2120 [dict removeAll]; 2121 XCTAssertEqual(dict.count, 0U); 2122 XCTAssertFalse([dict getFloat:NULL forKey:@"foo"]); 2123 XCTAssertFalse([dict getFloat:NULL forKey:@"bar"]); 2124 XCTAssertFalse([dict getFloat:NULL forKey:@"baz"]); 2125 XCTAssertFalse([dict getFloat:NULL forKey:@"mumble"]); 2126 [dict release]; 2127} 2128 2129- (void)testInplaceMutation { 2130 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 2131 const float kValues[] = { 500.f, 501.f, 502.f, 503.f }; 2132 GPBStringFloatDictionary *dict = 2133 [[GPBStringFloatDictionary alloc] initWithFloats:kValues 2134 forKeys:kKeys 2135 count:GPBARRAYSIZE(kValues)]; 2136 XCTAssertNotNil(dict); 2137 XCTAssertEqual(dict.count, 4U); 2138 float value; 2139 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]); 2140 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]); 2141 XCTAssertEqual(value, 500.f); 2142 XCTAssertTrue([dict getFloat:NULL forKey:@"bar"]); 2143 XCTAssertTrue([dict getFloat:&value forKey:@"bar"]); 2144 XCTAssertEqual(value, 501.f); 2145 XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]); 2146 XCTAssertTrue([dict getFloat:&value forKey:@"baz"]); 2147 XCTAssertEqual(value, 502.f); 2148 XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]); 2149 XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]); 2150 XCTAssertEqual(value, 503.f); 2151 2152 [dict setFloat:503.f forKey:@"foo"]; 2153 XCTAssertEqual(dict.count, 4U); 2154 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]); 2155 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]); 2156 XCTAssertEqual(value, 503.f); 2157 XCTAssertTrue([dict getFloat:NULL forKey:@"bar"]); 2158 XCTAssertTrue([dict getFloat:&value forKey:@"bar"]); 2159 XCTAssertEqual(value, 501.f); 2160 XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]); 2161 XCTAssertTrue([dict getFloat:&value forKey:@"baz"]); 2162 XCTAssertEqual(value, 502.f); 2163 XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]); 2164 XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]); 2165 XCTAssertEqual(value, 503.f); 2166 2167 [dict setFloat:501.f forKey:@"mumble"]; 2168 XCTAssertEqual(dict.count, 4U); 2169 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]); 2170 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]); 2171 XCTAssertEqual(value, 503.f); 2172 XCTAssertTrue([dict getFloat:NULL forKey:@"bar"]); 2173 XCTAssertTrue([dict getFloat:&value forKey:@"bar"]); 2174 XCTAssertEqual(value, 501.f); 2175 XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]); 2176 XCTAssertTrue([dict getFloat:&value forKey:@"baz"]); 2177 XCTAssertEqual(value, 502.f); 2178 XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]); 2179 XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]); 2180 XCTAssertEqual(value, 501.f); 2181 2182 const NSString *kKeys2[] = { @"bar", @"baz" }; 2183 const float kValues2[] = { 502.f, 500.f }; 2184 GPBStringFloatDictionary *dict2 = 2185 [[GPBStringFloatDictionary alloc] initWithFloats:kValues2 2186 forKeys:kKeys2 2187 count:GPBARRAYSIZE(kValues2)]; 2188 XCTAssertNotNil(dict2); 2189 [dict addEntriesFromDictionary:dict2]; 2190 XCTAssertEqual(dict.count, 4U); 2191 XCTAssertTrue([dict getFloat:NULL forKey:@"foo"]); 2192 XCTAssertTrue([dict getFloat:&value forKey:@"foo"]); 2193 XCTAssertEqual(value, 503.f); 2194 XCTAssertTrue([dict getFloat:NULL forKey:@"bar"]); 2195 XCTAssertTrue([dict getFloat:&value forKey:@"bar"]); 2196 XCTAssertEqual(value, 502.f); 2197 XCTAssertTrue([dict getFloat:NULL forKey:@"baz"]); 2198 XCTAssertTrue([dict getFloat:&value forKey:@"baz"]); 2199 XCTAssertEqual(value, 500.f); 2200 XCTAssertTrue([dict getFloat:NULL forKey:@"mumble"]); 2201 XCTAssertTrue([dict getFloat:&value forKey:@"mumble"]); 2202 XCTAssertEqual(value, 501.f); 2203 2204 [dict2 release]; 2205 [dict release]; 2206} 2207 2208@end 2209 2210#pragma mark - String -> Double 2211 2212@interface GPBStringDoubleDictionaryTests : XCTestCase 2213@end 2214 2215@implementation GPBStringDoubleDictionaryTests 2216 2217- (void)testEmpty { 2218 GPBStringDoubleDictionary *dict = [[GPBStringDoubleDictionary alloc] init]; 2219 XCTAssertNotNil(dict); 2220 XCTAssertEqual(dict.count, 0U); 2221 XCTAssertFalse([dict getDouble:NULL forKey:@"foo"]); 2222 [dict enumerateKeysAndDoublesUsingBlock:^(__unused NSString *aKey, __unused double aValue, __unused BOOL *stop) { 2223 XCTFail(@"Shouldn't get here!"); 2224 }]; 2225 [dict release]; 2226} 2227 2228- (void)testOne { 2229 GPBStringDoubleDictionary *dict = [[GPBStringDoubleDictionary alloc] init]; 2230 [dict setDouble:600. forKey:@"foo"]; 2231 XCTAssertNotNil(dict); 2232 XCTAssertEqual(dict.count, 1U); 2233 double value; 2234 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]); 2235 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]); 2236 XCTAssertEqual(value, 600.); 2237 XCTAssertFalse([dict getDouble:NULL forKey:@"bar"]); 2238 [dict enumerateKeysAndDoublesUsingBlock:^(NSString *aKey, double aValue, BOOL *stop) { 2239 XCTAssertEqualObjects(aKey, @"foo"); 2240 XCTAssertEqual(aValue, 600.); 2241 XCTAssertNotEqual(stop, NULL); 2242 }]; 2243 [dict release]; 2244} 2245 2246- (void)testBasics { 2247 const NSString *kKeys[] = { @"foo", @"bar", @"baz" }; 2248 const double kValues[] = { 600., 601., 602. }; 2249 GPBStringDoubleDictionary *dict = 2250 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues 2251 forKeys:kKeys 2252 count:GPBARRAYSIZE(kValues)]; 2253 XCTAssertNotNil(dict); 2254 XCTAssertEqual(dict.count, 3U); 2255 double value; 2256 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]); 2257 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]); 2258 XCTAssertEqual(value, 600.); 2259 XCTAssertTrue([dict getDouble:NULL forKey:@"bar"]); 2260 XCTAssertTrue([dict getDouble:&value forKey:@"bar"]); 2261 XCTAssertEqual(value, 601.); 2262 XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]); 2263 XCTAssertTrue([dict getDouble:&value forKey:@"baz"]); 2264 XCTAssertEqual(value, 602.); 2265 XCTAssertFalse([dict getDouble:NULL forKey:@"mumble"]); 2266 2267 __block NSUInteger idx = 0; 2268 NSString **seenKeys = malloc(3 * sizeof(NSString*)); 2269 double *seenValues = malloc(3 * sizeof(double)); 2270 [dict enumerateKeysAndDoublesUsingBlock:^(NSString *aKey, double aValue, BOOL *stop) { 2271 XCTAssertLessThan(idx, 3U); 2272 seenKeys[idx] = aKey; 2273 seenValues[idx] = aValue; 2274 XCTAssertNotEqual(stop, NULL); 2275 ++idx; 2276 }]; 2277 for (int i = 0; i < 3; ++i) { 2278 BOOL foundKey = NO; 2279 for (int j = 0; (j < 3) && !foundKey; ++j) { 2280 if ([kKeys[i] isEqual:seenKeys[j]]) { 2281 foundKey = YES; 2282 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j); 2283 } 2284 } 2285 XCTAssertTrue(foundKey, @"i = %d", i); 2286 } 2287 free(seenKeys); 2288 free(seenValues); 2289 2290 // Stopping the enumeration. 2291 idx = 0; 2292 [dict enumerateKeysAndDoublesUsingBlock:^(__unused NSString *aKey, __unused double aValue, BOOL *stop) { 2293 if (idx == 1) *stop = YES; 2294 XCTAssertNotEqual(idx, 2U); 2295 ++idx; 2296 }]; 2297 [dict release]; 2298} 2299 2300- (void)testEquality { 2301 const NSString *kKeys1[] = { @"foo", @"bar", @"baz", @"mumble" }; 2302 const NSString *kKeys2[] = { @"bar", @"foo", @"mumble" }; 2303 const double kValues1[] = { 600., 601., 602. }; 2304 const double kValues2[] = { 600., 603., 602. }; 2305 const double kValues3[] = { 600., 601., 602., 603. }; 2306 GPBStringDoubleDictionary *dict1 = 2307 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues1 2308 forKeys:kKeys1 2309 count:GPBARRAYSIZE(kValues1)]; 2310 XCTAssertNotNil(dict1); 2311 GPBStringDoubleDictionary *dict1prime = 2312 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues1 2313 forKeys:kKeys1 2314 count:GPBARRAYSIZE(kValues1)]; 2315 XCTAssertNotNil(dict1prime); 2316 GPBStringDoubleDictionary *dict2 = 2317 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues2 2318 forKeys:kKeys1 2319 count:GPBARRAYSIZE(kValues2)]; 2320 XCTAssertNotNil(dict2); 2321 GPBStringDoubleDictionary *dict3 = 2322 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues1 2323 forKeys:kKeys2 2324 count:GPBARRAYSIZE(kValues1)]; 2325 XCTAssertNotNil(dict3); 2326 GPBStringDoubleDictionary *dict4 = 2327 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues3 2328 forKeys:kKeys1 2329 count:GPBARRAYSIZE(kValues3)]; 2330 XCTAssertNotNil(dict4); 2331 2332 // 1/1Prime should be different objects, but equal. 2333 XCTAssertNotEqual(dict1, dict1prime); 2334 XCTAssertEqualObjects(dict1, dict1prime); 2335 // Equal, so they must have same hash. 2336 XCTAssertEqual([dict1 hash], [dict1prime hash]); 2337 2338 // 2 is same keys, different values; not equal. 2339 XCTAssertNotEqualObjects(dict1, dict2); 2340 2341 // 3 is different keys, same values; not equal. 2342 XCTAssertNotEqualObjects(dict1, dict3); 2343 2344 // 4 extra pair; not equal 2345 XCTAssertNotEqualObjects(dict1, dict4); 2346 2347 [dict1 release]; 2348 [dict1prime release]; 2349 [dict2 release]; 2350 [dict3 release]; 2351 [dict4 release]; 2352} 2353 2354- (void)testCopy { 2355 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 2356 const double kValues[] = { 600., 601., 602., 603. }; 2357 GPBStringDoubleDictionary *dict = 2358 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues 2359 forKeys:kKeys 2360 count:GPBARRAYSIZE(kValues)]; 2361 XCTAssertNotNil(dict); 2362 2363 GPBStringDoubleDictionary *dict2 = [dict copy]; 2364 XCTAssertNotNil(dict2); 2365 2366 // Should be new object but equal. 2367 XCTAssertNotEqual(dict, dict2); 2368 XCTAssertEqualObjects(dict, dict2); 2369 XCTAssertTrue([dict2 isKindOfClass:[GPBStringDoubleDictionary class]]); 2370 2371 [dict2 release]; 2372 [dict release]; 2373} 2374 2375- (void)testDictionaryFromDictionary { 2376 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 2377 const double kValues[] = { 600., 601., 602., 603. }; 2378 GPBStringDoubleDictionary *dict = 2379 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues 2380 forKeys:kKeys 2381 count:GPBARRAYSIZE(kValues)]; 2382 XCTAssertNotNil(dict); 2383 2384 GPBStringDoubleDictionary *dict2 = 2385 [[GPBStringDoubleDictionary alloc] initWithDictionary:dict]; 2386 XCTAssertNotNil(dict2); 2387 2388 // Should be new pointer, but equal objects. 2389 XCTAssertNotEqual(dict, dict2); 2390 XCTAssertEqualObjects(dict, dict2); 2391 [dict2 release]; 2392 [dict release]; 2393} 2394 2395- (void)testAdds { 2396 GPBStringDoubleDictionary *dict = [[GPBStringDoubleDictionary alloc] init]; 2397 XCTAssertNotNil(dict); 2398 2399 XCTAssertEqual(dict.count, 0U); 2400 [dict setDouble:600. forKey:@"foo"]; 2401 XCTAssertEqual(dict.count, 1U); 2402 2403 const NSString *kKeys[] = { @"bar", @"baz", @"mumble" }; 2404 const double kValues[] = { 601., 602., 603. }; 2405 GPBStringDoubleDictionary *dict2 = 2406 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues 2407 forKeys:kKeys 2408 count:GPBARRAYSIZE(kValues)]; 2409 XCTAssertNotNil(dict2); 2410 [dict addEntriesFromDictionary:dict2]; 2411 XCTAssertEqual(dict.count, 4U); 2412 2413 double value; 2414 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]); 2415 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]); 2416 XCTAssertEqual(value, 600.); 2417 XCTAssertTrue([dict getDouble:NULL forKey:@"bar"]); 2418 XCTAssertTrue([dict getDouble:&value forKey:@"bar"]); 2419 XCTAssertEqual(value, 601.); 2420 XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]); 2421 XCTAssertTrue([dict getDouble:&value forKey:@"baz"]); 2422 XCTAssertEqual(value, 602.); 2423 XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]); 2424 XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]); 2425 XCTAssertEqual(value, 603.); 2426 [dict2 release]; 2427 [dict release]; 2428} 2429 2430- (void)testRemove { 2431 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 2432 const double kValues[] = { 600., 601., 602., 603. }; 2433 GPBStringDoubleDictionary *dict = 2434 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues 2435 forKeys:kKeys 2436 count:GPBARRAYSIZE(kValues)]; 2437 XCTAssertNotNil(dict); 2438 XCTAssertEqual(dict.count, 4U); 2439 2440 [dict removeDoubleForKey:@"bar"]; 2441 XCTAssertEqual(dict.count, 3U); 2442 double value; 2443 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]); 2444 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]); 2445 XCTAssertEqual(value, 600.); 2446 XCTAssertFalse([dict getDouble:NULL forKey:@"bar"]); 2447 XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]); 2448 XCTAssertTrue([dict getDouble:&value forKey:@"baz"]); 2449 XCTAssertEqual(value, 602.); 2450 XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]); 2451 XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]); 2452 XCTAssertEqual(value, 603.); 2453 2454 // Remove again does nothing. 2455 [dict removeDoubleForKey:@"bar"]; 2456 XCTAssertEqual(dict.count, 3U); 2457 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]); 2458 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]); 2459 XCTAssertEqual(value, 600.); 2460 XCTAssertFalse([dict getDouble:NULL forKey:@"bar"]); 2461 XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]); 2462 XCTAssertTrue([dict getDouble:&value forKey:@"baz"]); 2463 XCTAssertEqual(value, 602.); 2464 XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]); 2465 XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]); 2466 XCTAssertEqual(value, 603.); 2467 2468 [dict removeDoubleForKey:@"mumble"]; 2469 XCTAssertEqual(dict.count, 2U); 2470 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]); 2471 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]); 2472 XCTAssertEqual(value, 600.); 2473 XCTAssertFalse([dict getDouble:NULL forKey:@"bar"]); 2474 XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]); 2475 XCTAssertTrue([dict getDouble:&value forKey:@"baz"]); 2476 XCTAssertEqual(value, 602.); 2477 XCTAssertFalse([dict getDouble:NULL forKey:@"mumble"]); 2478 2479 [dict removeAll]; 2480 XCTAssertEqual(dict.count, 0U); 2481 XCTAssertFalse([dict getDouble:NULL forKey:@"foo"]); 2482 XCTAssertFalse([dict getDouble:NULL forKey:@"bar"]); 2483 XCTAssertFalse([dict getDouble:NULL forKey:@"baz"]); 2484 XCTAssertFalse([dict getDouble:NULL forKey:@"mumble"]); 2485 [dict release]; 2486} 2487 2488- (void)testInplaceMutation { 2489 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 2490 const double kValues[] = { 600., 601., 602., 603. }; 2491 GPBStringDoubleDictionary *dict = 2492 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues 2493 forKeys:kKeys 2494 count:GPBARRAYSIZE(kValues)]; 2495 XCTAssertNotNil(dict); 2496 XCTAssertEqual(dict.count, 4U); 2497 double value; 2498 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]); 2499 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]); 2500 XCTAssertEqual(value, 600.); 2501 XCTAssertTrue([dict getDouble:NULL forKey:@"bar"]); 2502 XCTAssertTrue([dict getDouble:&value forKey:@"bar"]); 2503 XCTAssertEqual(value, 601.); 2504 XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]); 2505 XCTAssertTrue([dict getDouble:&value forKey:@"baz"]); 2506 XCTAssertEqual(value, 602.); 2507 XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]); 2508 XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]); 2509 XCTAssertEqual(value, 603.); 2510 2511 [dict setDouble:603. forKey:@"foo"]; 2512 XCTAssertEqual(dict.count, 4U); 2513 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]); 2514 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]); 2515 XCTAssertEqual(value, 603.); 2516 XCTAssertTrue([dict getDouble:NULL forKey:@"bar"]); 2517 XCTAssertTrue([dict getDouble:&value forKey:@"bar"]); 2518 XCTAssertEqual(value, 601.); 2519 XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]); 2520 XCTAssertTrue([dict getDouble:&value forKey:@"baz"]); 2521 XCTAssertEqual(value, 602.); 2522 XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]); 2523 XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]); 2524 XCTAssertEqual(value, 603.); 2525 2526 [dict setDouble:601. forKey:@"mumble"]; 2527 XCTAssertEqual(dict.count, 4U); 2528 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]); 2529 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]); 2530 XCTAssertEqual(value, 603.); 2531 XCTAssertTrue([dict getDouble:NULL forKey:@"bar"]); 2532 XCTAssertTrue([dict getDouble:&value forKey:@"bar"]); 2533 XCTAssertEqual(value, 601.); 2534 XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]); 2535 XCTAssertTrue([dict getDouble:&value forKey:@"baz"]); 2536 XCTAssertEqual(value, 602.); 2537 XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]); 2538 XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]); 2539 XCTAssertEqual(value, 601.); 2540 2541 const NSString *kKeys2[] = { @"bar", @"baz" }; 2542 const double kValues2[] = { 602., 600. }; 2543 GPBStringDoubleDictionary *dict2 = 2544 [[GPBStringDoubleDictionary alloc] initWithDoubles:kValues2 2545 forKeys:kKeys2 2546 count:GPBARRAYSIZE(kValues2)]; 2547 XCTAssertNotNil(dict2); 2548 [dict addEntriesFromDictionary:dict2]; 2549 XCTAssertEqual(dict.count, 4U); 2550 XCTAssertTrue([dict getDouble:NULL forKey:@"foo"]); 2551 XCTAssertTrue([dict getDouble:&value forKey:@"foo"]); 2552 XCTAssertEqual(value, 603.); 2553 XCTAssertTrue([dict getDouble:NULL forKey:@"bar"]); 2554 XCTAssertTrue([dict getDouble:&value forKey:@"bar"]); 2555 XCTAssertEqual(value, 602.); 2556 XCTAssertTrue([dict getDouble:NULL forKey:@"baz"]); 2557 XCTAssertTrue([dict getDouble:&value forKey:@"baz"]); 2558 XCTAssertEqual(value, 600.); 2559 XCTAssertTrue([dict getDouble:NULL forKey:@"mumble"]); 2560 XCTAssertTrue([dict getDouble:&value forKey:@"mumble"]); 2561 XCTAssertEqual(value, 601.); 2562 2563 [dict2 release]; 2564 [dict release]; 2565} 2566 2567@end 2568 2569#pragma mark - String -> Enum 2570 2571@interface GPBStringEnumDictionaryTests : XCTestCase 2572@end 2573 2574@implementation GPBStringEnumDictionaryTests 2575 2576- (void)testEmpty { 2577 GPBStringEnumDictionary *dict = [[GPBStringEnumDictionary alloc] init]; 2578 XCTAssertNotNil(dict); 2579 XCTAssertEqual(dict.count, 0U); 2580 XCTAssertFalse([dict getEnum:NULL forKey:@"foo"]); 2581 [dict enumerateKeysAndEnumsUsingBlock:^(__unused NSString *aKey, __unused int32_t aValue, __unused BOOL *stop) { 2582 XCTFail(@"Shouldn't get here!"); 2583 }]; 2584 [dict release]; 2585} 2586 2587- (void)testOne { 2588 GPBStringEnumDictionary *dict = [[GPBStringEnumDictionary alloc] init]; 2589 [dict setEnum:700 forKey:@"foo"]; 2590 XCTAssertNotNil(dict); 2591 XCTAssertEqual(dict.count, 1U); 2592 int32_t value; 2593 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]); 2594 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]); 2595 XCTAssertEqual(value, 700); 2596 XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]); 2597 [dict enumerateKeysAndEnumsUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) { 2598 XCTAssertEqualObjects(aKey, @"foo"); 2599 XCTAssertEqual(aValue, 700); 2600 XCTAssertNotEqual(stop, NULL); 2601 }]; 2602 [dict release]; 2603} 2604 2605- (void)testBasics { 2606 const NSString *kKeys[] = { @"foo", @"bar", @"baz" }; 2607 const int32_t kValues[] = { 700, 701, 702 }; 2608 GPBStringEnumDictionary *dict = 2609 [[GPBStringEnumDictionary alloc] initWithEnums:kValues 2610 forKeys:kKeys 2611 count:GPBARRAYSIZE(kValues)]; 2612 XCTAssertNotNil(dict); 2613 XCTAssertEqual(dict.count, 3U); 2614 int32_t value; 2615 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]); 2616 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]); 2617 XCTAssertEqual(value, 700); 2618 XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]); 2619 XCTAssertTrue([dict getEnum:&value forKey:@"bar"]); 2620 XCTAssertEqual(value, 701); 2621 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]); 2622 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]); 2623 XCTAssertEqual(value, 702); 2624 XCTAssertFalse([dict getEnum:NULL forKey:@"mumble"]); 2625 2626 __block NSUInteger idx = 0; 2627 NSString **seenKeys = malloc(3 * sizeof(NSString*)); 2628 int32_t *seenValues = malloc(3 * sizeof(int32_t)); 2629 [dict enumerateKeysAndEnumsUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) { 2630 XCTAssertLessThan(idx, 3U); 2631 seenKeys[idx] = aKey; 2632 seenValues[idx] = aValue; 2633 XCTAssertNotEqual(stop, NULL); 2634 ++idx; 2635 }]; 2636 for (int i = 0; i < 3; ++i) { 2637 BOOL foundKey = NO; 2638 for (int j = 0; (j < 3) && !foundKey; ++j) { 2639 if ([kKeys[i] isEqual:seenKeys[j]]) { 2640 foundKey = YES; 2641 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j); 2642 } 2643 } 2644 XCTAssertTrue(foundKey, @"i = %d", i); 2645 } 2646 free(seenKeys); 2647 free(seenValues); 2648 2649 // Stopping the enumeration. 2650 idx = 0; 2651 [dict enumerateKeysAndEnumsUsingBlock:^(__unused NSString *aKey, __unused int32_t aValue, BOOL *stop) { 2652 if (idx == 1) *stop = YES; 2653 XCTAssertNotEqual(idx, 2U); 2654 ++idx; 2655 }]; 2656 [dict release]; 2657} 2658 2659- (void)testEquality { 2660 const NSString *kKeys1[] = { @"foo", @"bar", @"baz", @"mumble" }; 2661 const NSString *kKeys2[] = { @"bar", @"foo", @"mumble" }; 2662 const int32_t kValues1[] = { 700, 701, 702 }; 2663 const int32_t kValues2[] = { 700, 703, 702 }; 2664 const int32_t kValues3[] = { 700, 701, 702, 703 }; 2665 GPBStringEnumDictionary *dict1 = 2666 [[GPBStringEnumDictionary alloc] initWithEnums:kValues1 2667 forKeys:kKeys1 2668 count:GPBARRAYSIZE(kValues1)]; 2669 XCTAssertNotNil(dict1); 2670 GPBStringEnumDictionary *dict1prime = 2671 [[GPBStringEnumDictionary alloc] initWithEnums:kValues1 2672 forKeys:kKeys1 2673 count:GPBARRAYSIZE(kValues1)]; 2674 XCTAssertNotNil(dict1prime); 2675 GPBStringEnumDictionary *dict2 = 2676 [[GPBStringEnumDictionary alloc] initWithEnums:kValues2 2677 forKeys:kKeys1 2678 count:GPBARRAYSIZE(kValues2)]; 2679 XCTAssertNotNil(dict2); 2680 GPBStringEnumDictionary *dict3 = 2681 [[GPBStringEnumDictionary alloc] initWithEnums:kValues1 2682 forKeys:kKeys2 2683 count:GPBARRAYSIZE(kValues1)]; 2684 XCTAssertNotNil(dict3); 2685 GPBStringEnumDictionary *dict4 = 2686 [[GPBStringEnumDictionary alloc] initWithEnums:kValues3 2687 forKeys:kKeys1 2688 count:GPBARRAYSIZE(kValues3)]; 2689 XCTAssertNotNil(dict4); 2690 2691 // 1/1Prime should be different objects, but equal. 2692 XCTAssertNotEqual(dict1, dict1prime); 2693 XCTAssertEqualObjects(dict1, dict1prime); 2694 // Equal, so they must have same hash. 2695 XCTAssertEqual([dict1 hash], [dict1prime hash]); 2696 2697 // 2 is same keys, different values; not equal. 2698 XCTAssertNotEqualObjects(dict1, dict2); 2699 2700 // 3 is different keys, same values; not equal. 2701 XCTAssertNotEqualObjects(dict1, dict3); 2702 2703 // 4 extra pair; not equal 2704 XCTAssertNotEqualObjects(dict1, dict4); 2705 2706 [dict1 release]; 2707 [dict1prime release]; 2708 [dict2 release]; 2709 [dict3 release]; 2710 [dict4 release]; 2711} 2712 2713- (void)testCopy { 2714 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 2715 const int32_t kValues[] = { 700, 701, 702, 703 }; 2716 GPBStringEnumDictionary *dict = 2717 [[GPBStringEnumDictionary alloc] initWithEnums:kValues 2718 forKeys:kKeys 2719 count:GPBARRAYSIZE(kValues)]; 2720 XCTAssertNotNil(dict); 2721 2722 GPBStringEnumDictionary *dict2 = [dict copy]; 2723 XCTAssertNotNil(dict2); 2724 2725 // Should be new object but equal. 2726 XCTAssertNotEqual(dict, dict2); 2727 XCTAssertEqualObjects(dict, dict2); 2728 XCTAssertTrue([dict2 isKindOfClass:[GPBStringEnumDictionary class]]); 2729 2730 [dict2 release]; 2731 [dict release]; 2732} 2733 2734- (void)testDictionaryFromDictionary { 2735 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 2736 const int32_t kValues[] = { 700, 701, 702, 703 }; 2737 GPBStringEnumDictionary *dict = 2738 [[GPBStringEnumDictionary alloc] initWithEnums:kValues 2739 forKeys:kKeys 2740 count:GPBARRAYSIZE(kValues)]; 2741 XCTAssertNotNil(dict); 2742 2743 GPBStringEnumDictionary *dict2 = 2744 [[GPBStringEnumDictionary alloc] initWithDictionary:dict]; 2745 XCTAssertNotNil(dict2); 2746 2747 // Should be new pointer, but equal objects. 2748 XCTAssertNotEqual(dict, dict2); 2749 XCTAssertEqualObjects(dict, dict2); 2750 [dict2 release]; 2751 [dict release]; 2752} 2753 2754- (void)testAdds { 2755 GPBStringEnumDictionary *dict = [[GPBStringEnumDictionary alloc] init]; 2756 XCTAssertNotNil(dict); 2757 2758 XCTAssertEqual(dict.count, 0U); 2759 [dict setEnum:700 forKey:@"foo"]; 2760 XCTAssertEqual(dict.count, 1U); 2761 2762 const NSString *kKeys[] = { @"bar", @"baz", @"mumble" }; 2763 const int32_t kValues[] = { 701, 702, 703 }; 2764 GPBStringEnumDictionary *dict2 = 2765 [[GPBStringEnumDictionary alloc] initWithEnums:kValues 2766 forKeys:kKeys 2767 count:GPBARRAYSIZE(kValues)]; 2768 XCTAssertNotNil(dict2); 2769 [dict addRawEntriesFromDictionary:dict2]; 2770 XCTAssertEqual(dict.count, 4U); 2771 2772 int32_t value; 2773 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]); 2774 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]); 2775 XCTAssertEqual(value, 700); 2776 XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]); 2777 XCTAssertTrue([dict getEnum:&value forKey:@"bar"]); 2778 XCTAssertEqual(value, 701); 2779 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]); 2780 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]); 2781 XCTAssertEqual(value, 702); 2782 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]); 2783 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]); 2784 XCTAssertEqual(value, 703); 2785 [dict2 release]; 2786 [dict release]; 2787} 2788 2789- (void)testRemove { 2790 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 2791 const int32_t kValues[] = { 700, 701, 702, 703 }; 2792 GPBStringEnumDictionary *dict = 2793 [[GPBStringEnumDictionary alloc] initWithEnums:kValues 2794 forKeys:kKeys 2795 count:GPBARRAYSIZE(kValues)]; 2796 XCTAssertNotNil(dict); 2797 XCTAssertEqual(dict.count, 4U); 2798 2799 [dict removeEnumForKey:@"bar"]; 2800 XCTAssertEqual(dict.count, 3U); 2801 int32_t value; 2802 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]); 2803 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]); 2804 XCTAssertEqual(value, 700); 2805 XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]); 2806 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]); 2807 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]); 2808 XCTAssertEqual(value, 702); 2809 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]); 2810 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]); 2811 XCTAssertEqual(value, 703); 2812 2813 // Remove again does nothing. 2814 [dict removeEnumForKey:@"bar"]; 2815 XCTAssertEqual(dict.count, 3U); 2816 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]); 2817 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]); 2818 XCTAssertEqual(value, 700); 2819 XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]); 2820 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]); 2821 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]); 2822 XCTAssertEqual(value, 702); 2823 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]); 2824 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]); 2825 XCTAssertEqual(value, 703); 2826 2827 [dict removeEnumForKey:@"mumble"]; 2828 XCTAssertEqual(dict.count, 2U); 2829 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]); 2830 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]); 2831 XCTAssertEqual(value, 700); 2832 XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]); 2833 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]); 2834 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]); 2835 XCTAssertEqual(value, 702); 2836 XCTAssertFalse([dict getEnum:NULL forKey:@"mumble"]); 2837 2838 [dict removeAll]; 2839 XCTAssertEqual(dict.count, 0U); 2840 XCTAssertFalse([dict getEnum:NULL forKey:@"foo"]); 2841 XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]); 2842 XCTAssertFalse([dict getEnum:NULL forKey:@"baz"]); 2843 XCTAssertFalse([dict getEnum:NULL forKey:@"mumble"]); 2844 [dict release]; 2845} 2846 2847- (void)testInplaceMutation { 2848 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 2849 const int32_t kValues[] = { 700, 701, 702, 703 }; 2850 GPBStringEnumDictionary *dict = 2851 [[GPBStringEnumDictionary alloc] initWithEnums:kValues 2852 forKeys:kKeys 2853 count:GPBARRAYSIZE(kValues)]; 2854 XCTAssertNotNil(dict); 2855 XCTAssertEqual(dict.count, 4U); 2856 int32_t value; 2857 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]); 2858 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]); 2859 XCTAssertEqual(value, 700); 2860 XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]); 2861 XCTAssertTrue([dict getEnum:&value forKey:@"bar"]); 2862 XCTAssertEqual(value, 701); 2863 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]); 2864 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]); 2865 XCTAssertEqual(value, 702); 2866 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]); 2867 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]); 2868 XCTAssertEqual(value, 703); 2869 2870 [dict setEnum:703 forKey:@"foo"]; 2871 XCTAssertEqual(dict.count, 4U); 2872 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]); 2873 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]); 2874 XCTAssertEqual(value, 703); 2875 XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]); 2876 XCTAssertTrue([dict getEnum:&value forKey:@"bar"]); 2877 XCTAssertEqual(value, 701); 2878 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]); 2879 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]); 2880 XCTAssertEqual(value, 702); 2881 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]); 2882 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]); 2883 XCTAssertEqual(value, 703); 2884 2885 [dict setEnum:701 forKey:@"mumble"]; 2886 XCTAssertEqual(dict.count, 4U); 2887 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]); 2888 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]); 2889 XCTAssertEqual(value, 703); 2890 XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]); 2891 XCTAssertTrue([dict getEnum:&value forKey:@"bar"]); 2892 XCTAssertEqual(value, 701); 2893 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]); 2894 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]); 2895 XCTAssertEqual(value, 702); 2896 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]); 2897 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]); 2898 XCTAssertEqual(value, 701); 2899 2900 const NSString *kKeys2[] = { @"bar", @"baz" }; 2901 const int32_t kValues2[] = { 702, 700 }; 2902 GPBStringEnumDictionary *dict2 = 2903 [[GPBStringEnumDictionary alloc] initWithEnums:kValues2 2904 forKeys:kKeys2 2905 count:GPBARRAYSIZE(kValues2)]; 2906 XCTAssertNotNil(dict2); 2907 [dict addRawEntriesFromDictionary:dict2]; 2908 XCTAssertEqual(dict.count, 4U); 2909 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]); 2910 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]); 2911 XCTAssertEqual(value, 703); 2912 XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]); 2913 XCTAssertTrue([dict getEnum:&value forKey:@"bar"]); 2914 XCTAssertEqual(value, 702); 2915 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]); 2916 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]); 2917 XCTAssertEqual(value, 700); 2918 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]); 2919 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]); 2920 XCTAssertEqual(value, 701); 2921 2922 [dict2 release]; 2923 [dict release]; 2924} 2925 2926@end 2927 2928#pragma mark - String -> Enum (Unknown Enums) 2929 2930@interface GPBStringEnumDictionaryUnknownEnumTests : XCTestCase 2931@end 2932 2933@implementation GPBStringEnumDictionaryUnknownEnumTests 2934 2935- (void)testRawBasics { 2936 const NSString *kKeys[] = { @"foo", @"bar", @"baz" }; 2937 const int32_t kValues[] = { 700, 801, 702 }; 2938 GPBStringEnumDictionary *dict = 2939 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue 2940 rawValues:kValues 2941 forKeys:kKeys 2942 count:GPBARRAYSIZE(kValues)]; 2943 XCTAssertNotNil(dict); 2944 XCTAssertEqual(dict.count, 3U); 2945 XCTAssertTrue(dict.validationFunc == TestingEnum_IsValidValue); // Pointer comparison 2946 int32_t value; 2947 XCTAssertTrue([dict getRawValue:NULL forKey:@"foo"]); 2948 XCTAssertTrue([dict getRawValue:&value forKey:@"foo"]); 2949 XCTAssertEqual(value, 700); 2950 XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]); 2951 XCTAssertTrue([dict getEnum:&value forKey:@"bar"]); 2952 XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue); 2953 XCTAssertTrue([dict getRawValue:NULL forKey:@"bar"]); 2954 XCTAssertTrue([dict getRawValue:&value forKey:@"bar"]); 2955 XCTAssertEqual(value, 801); 2956 XCTAssertTrue([dict getRawValue:NULL forKey:@"baz"]); 2957 XCTAssertTrue([dict getRawValue:&value forKey:@"baz"]); 2958 XCTAssertEqual(value, 702); 2959 XCTAssertFalse([dict getRawValue:NULL forKey:@"mumble"]); 2960 2961 __block NSUInteger idx = 0; 2962 NSString **seenKeys = malloc(3 * sizeof(NSString*)); 2963 int32_t *seenValues = malloc(3 * sizeof(int32_t)); 2964 [dict enumerateKeysAndEnumsUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) { 2965 XCTAssertLessThan(idx, 3U); 2966 seenKeys[idx] = aKey; 2967 seenValues[idx] = aValue; 2968 XCTAssertNotEqual(stop, NULL); 2969 ++idx; 2970 }]; 2971 for (int i = 0; i < 3; ++i) { 2972 BOOL foundKey = NO; 2973 for (int j = 0; (j < 3) && !foundKey; ++j) { 2974 if ([kKeys[i] isEqual:seenKeys[j]]) { 2975 foundKey = YES; 2976 if (i == 1) { 2977 XCTAssertEqual(kGPBUnrecognizedEnumeratorValue, seenValues[j], @"i = %d, j = %d", i, j); 2978 } else { 2979 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j); 2980 } 2981 } 2982 } 2983 XCTAssertTrue(foundKey, @"i = %d", i); 2984 } 2985 idx = 0; 2986 [dict enumerateKeysAndRawValuesUsingBlock:^(NSString *aKey, int32_t aValue, BOOL *stop) { 2987 XCTAssertLessThan(idx, 3U); 2988 seenKeys[idx] = aKey; 2989 seenValues[idx] = aValue; 2990 XCTAssertNotEqual(stop, NULL); 2991 ++idx; 2992 }]; 2993 for (int i = 0; i < 3; ++i) { 2994 BOOL foundKey = NO; 2995 for (int j = 0; (j < 3) && !foundKey; ++j) { 2996 if ([kKeys[i] isEqual:seenKeys[j]]) { 2997 foundKey = YES; 2998 XCTAssertEqual(kValues[i], seenValues[j], @"i = %d, j = %d", i, j); 2999 } 3000 } 3001 XCTAssertTrue(foundKey, @"i = %d", i); 3002 } 3003 free(seenKeys); 3004 free(seenValues); 3005 3006 // Stopping the enumeration. 3007 idx = 0; 3008 [dict enumerateKeysAndRawValuesUsingBlock:^(__unused NSString *aKey, __unused int32_t aValue, BOOL *stop) { 3009 if (idx == 1) *stop = YES; 3010 XCTAssertNotEqual(idx, 2U); 3011 ++idx; 3012 }]; 3013 [dict release]; 3014} 3015 3016- (void)testEqualityWithUnknowns { 3017 const NSString *kKeys1[] = { @"foo", @"bar", @"baz", @"mumble" }; 3018 const NSString *kKeys2[] = { @"bar", @"foo", @"mumble" }; 3019 const int32_t kValues1[] = { 700, 801, 702 }; // Unknown 3020 const int32_t kValues2[] = { 700, 803, 702 }; // Unknown 3021 const int32_t kValues3[] = { 700, 801, 702, 803 }; // Unknowns 3022 GPBStringEnumDictionary *dict1 = 3023 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue 3024 rawValues:kValues1 3025 forKeys:kKeys1 3026 count:GPBARRAYSIZE(kValues1)]; 3027 XCTAssertNotNil(dict1); 3028 GPBStringEnumDictionary *dict1prime = 3029 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue 3030 rawValues:kValues1 3031 forKeys:kKeys1 3032 count:GPBARRAYSIZE(kValues1)]; 3033 XCTAssertNotNil(dict1prime); 3034 GPBStringEnumDictionary *dict2 = 3035 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue 3036 rawValues:kValues2 3037 forKeys:kKeys1 3038 count:GPBARRAYSIZE(kValues2)]; 3039 XCTAssertNotNil(dict2); 3040 GPBStringEnumDictionary *dict3 = 3041 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue 3042 rawValues:kValues1 3043 forKeys:kKeys2 3044 count:GPBARRAYSIZE(kValues1)]; 3045 XCTAssertNotNil(dict3); 3046 GPBStringEnumDictionary *dict4 = 3047 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue 3048 rawValues:kValues3 3049 forKeys:kKeys1 3050 count:GPBARRAYSIZE(kValues3)]; 3051 XCTAssertNotNil(dict4); 3052 3053 // 1/1Prime should be different objects, but equal. 3054 XCTAssertNotEqual(dict1, dict1prime); 3055 XCTAssertEqualObjects(dict1, dict1prime); 3056 // Equal, so they must have same hash. 3057 XCTAssertEqual([dict1 hash], [dict1prime hash]); 3058 3059 // 2 is same keys, different values; not equal. 3060 XCTAssertNotEqualObjects(dict1, dict2); 3061 3062 // 3 is different keys, same values; not equal. 3063 XCTAssertNotEqualObjects(dict1, dict3); 3064 3065 // 4 extra pair; not equal 3066 XCTAssertNotEqualObjects(dict1, dict4); 3067 3068 [dict1 release]; 3069 [dict1prime release]; 3070 [dict2 release]; 3071 [dict3 release]; 3072 [dict4 release]; 3073} 3074 3075- (void)testCopyWithUnknowns { 3076 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 3077 const int32_t kValues[] = { 700, 801, 702, 803 }; // Unknown 3078 GPBStringEnumDictionary *dict = 3079 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue 3080 rawValues:kValues 3081 forKeys:kKeys 3082 count:GPBARRAYSIZE(kValues)]; 3083 XCTAssertNotNil(dict); 3084 3085 GPBStringEnumDictionary *dict2 = [dict copy]; 3086 XCTAssertNotNil(dict2); 3087 3088 // Should be new pointer, but equal objects. 3089 XCTAssertNotEqual(dict, dict2); 3090 XCTAssertEqual(dict.validationFunc, dict2.validationFunc); // Pointer comparison 3091 XCTAssertEqualObjects(dict, dict2); 3092 3093 [dict2 release]; 3094 [dict release]; 3095} 3096 3097- (void)testDictionaryFromDictionary { 3098 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 3099 const int32_t kValues[] = { 700, 801, 702, 803 }; // Unknowns 3100 GPBStringEnumDictionary *dict = 3101 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue 3102 rawValues:kValues 3103 forKeys:kKeys 3104 count:GPBARRAYSIZE(kValues)]; 3105 XCTAssertNotNil(dict); 3106 3107 GPBStringEnumDictionary *dict2 = 3108 [[GPBStringEnumDictionary alloc] initWithDictionary:dict]; 3109 XCTAssertNotNil(dict2); 3110 3111 // Should be new pointer, but equal objects. 3112 XCTAssertNotEqual(dict, dict2); 3113 XCTAssertEqualObjects(dict, dict2); 3114 XCTAssertEqual(dict.validationFunc, dict2.validationFunc); // Pointer comparison 3115 [dict2 release]; 3116 [dict release]; 3117} 3118 3119- (void)testUnknownAdds { 3120 GPBStringEnumDictionary *dict = 3121 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue]; 3122 XCTAssertNotNil(dict); 3123 3124 XCTAssertEqual(dict.count, 0U); 3125 XCTAssertThrowsSpecificNamed([dict setEnum:801 forKey:@"bar"], // Unknown 3126 NSException, NSInvalidArgumentException); 3127 XCTAssertEqual(dict.count, 0U); 3128 [dict setRawValue:801 forKey:@"bar"]; // Unknown 3129 XCTAssertEqual(dict.count, 1U); 3130 3131 const NSString *kKeys[] = { @"foo", @"baz", @"mumble" }; 3132 const int32_t kValues[] = { 700, 702, 803 }; // Unknown 3133 GPBStringEnumDictionary *dict2 = 3134 [[GPBStringEnumDictionary alloc] initWithEnums:kValues 3135 forKeys:kKeys 3136 count:GPBARRAYSIZE(kValues)]; 3137 XCTAssertNotNil(dict2); 3138 [dict addRawEntriesFromDictionary:dict2]; 3139 XCTAssertEqual(dict.count, 4U); 3140 3141 int32_t value; 3142 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]); 3143 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]); 3144 XCTAssertEqual(value, 700); 3145 XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]); 3146 XCTAssertTrue([dict getEnum:&value forKey:@"bar"]); 3147 XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue); 3148 XCTAssertTrue([dict getRawValue:NULL forKey:@"bar"]); 3149 XCTAssertTrue([dict getRawValue:&value forKey:@"bar"]); 3150 XCTAssertEqual(value, 801); 3151 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]); 3152 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]); 3153 XCTAssertEqual(value, 702); 3154 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]); 3155 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]); 3156 XCTAssertEqual(value, kGPBUnrecognizedEnumeratorValue); 3157 XCTAssertTrue([dict getRawValue:NULL forKey:@"mumble"]); 3158 XCTAssertTrue([dict getRawValue:&value forKey:@"mumble"]); 3159 XCTAssertEqual(value, 803); 3160 [dict2 release]; 3161 [dict release]; 3162} 3163 3164- (void)testUnknownRemove { 3165 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 3166 const int32_t kValues[] = { 700, 801, 702, 803 }; // Unknowns 3167 GPBStringEnumDictionary *dict = 3168 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue 3169 rawValues:kValues 3170 forKeys:kKeys 3171 count:GPBARRAYSIZE(kValues)]; 3172 XCTAssertNotNil(dict); 3173 XCTAssertEqual(dict.count, 4U); 3174 3175 [dict removeEnumForKey:@"bar"]; 3176 XCTAssertEqual(dict.count, 3U); 3177 int32_t value; 3178 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]); 3179 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]); 3180 XCTAssertEqual(value, 700); 3181 XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]); 3182 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]); 3183 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]); 3184 XCTAssertEqual(value, 702); 3185 XCTAssertTrue([dict getRawValue:NULL forKey:@"mumble"]); 3186 XCTAssertTrue([dict getRawValue:&value forKey:@"mumble"]); 3187 XCTAssertEqual(value, 803); 3188 3189 // Remove again does nothing. 3190 [dict removeEnumForKey:@"bar"]; 3191 XCTAssertEqual(dict.count, 3U); 3192 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]); 3193 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]); 3194 XCTAssertEqual(value, 700); 3195 XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]); 3196 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]); 3197 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]); 3198 XCTAssertEqual(value, 702); 3199 XCTAssertTrue([dict getRawValue:NULL forKey:@"mumble"]); 3200 XCTAssertTrue([dict getRawValue:&value forKey:@"mumble"]); 3201 XCTAssertEqual(value, 803); 3202 3203 [dict removeEnumForKey:@"mumble"]; 3204 XCTAssertEqual(dict.count, 2U); 3205 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]); 3206 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]); 3207 XCTAssertEqual(value, 700); 3208 XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]); 3209 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]); 3210 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]); 3211 XCTAssertEqual(value, 702); 3212 XCTAssertFalse([dict getEnum:NULL forKey:@"mumble"]); 3213 3214 [dict removeAll]; 3215 XCTAssertEqual(dict.count, 0U); 3216 XCTAssertFalse([dict getEnum:NULL forKey:@"foo"]); 3217 XCTAssertFalse([dict getEnum:NULL forKey:@"bar"]); 3218 XCTAssertFalse([dict getEnum:NULL forKey:@"baz"]); 3219 XCTAssertFalse([dict getEnum:NULL forKey:@"mumble"]); 3220 [dict release]; 3221} 3222 3223- (void)testInplaceMutationUnknowns { 3224 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 3225 const int32_t kValues[] = { 700, 801, 702, 803 }; // Unknowns 3226 GPBStringEnumDictionary *dict = 3227 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue 3228 rawValues:kValues 3229 forKeys:kKeys 3230 count:GPBARRAYSIZE(kValues)]; 3231 XCTAssertNotNil(dict); 3232 XCTAssertEqual(dict.count, 4U); 3233 int32_t value; 3234 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]); 3235 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]); 3236 XCTAssertEqual(value, 700); 3237 XCTAssertTrue([dict getRawValue:NULL forKey:@"bar"]); 3238 XCTAssertTrue([dict getRawValue:&value forKey:@"bar"]); 3239 XCTAssertEqual(value, 801); 3240 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]); 3241 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]); 3242 XCTAssertEqual(value, 702); 3243 XCTAssertTrue([dict getRawValue:NULL forKey:@"mumble"]); 3244 XCTAssertTrue([dict getRawValue:&value forKey:@"mumble"]); 3245 XCTAssertEqual(value, 803); 3246 3247 XCTAssertThrowsSpecificNamed([dict setEnum:803 forKey:@"foo"], // Unknown 3248 NSException, NSInvalidArgumentException); 3249 XCTAssertEqual(dict.count, 4U); 3250 XCTAssertTrue([dict getEnum:NULL forKey:@"foo"]); 3251 XCTAssertTrue([dict getEnum:&value forKey:@"foo"]); 3252 XCTAssertEqual(value, 700); 3253 XCTAssertTrue([dict getRawValue:NULL forKey:@"bar"]); 3254 XCTAssertTrue([dict getRawValue:&value forKey:@"bar"]); 3255 XCTAssertEqual(value, 801); 3256 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]); 3257 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]); 3258 XCTAssertEqual(value, 702); 3259 XCTAssertTrue([dict getRawValue:NULL forKey:@"mumble"]); 3260 XCTAssertTrue([dict getRawValue:&value forKey:@"mumble"]); 3261 XCTAssertEqual(value, 803); 3262 3263 [dict setRawValue:803 forKey:@"foo"]; // Unknown 3264 XCTAssertEqual(dict.count, 4U); 3265 XCTAssertTrue([dict getRawValue:NULL forKey:@"foo"]); 3266 XCTAssertTrue([dict getRawValue:&value forKey:@"foo"]); 3267 XCTAssertEqual(value, 803); 3268 XCTAssertTrue([dict getRawValue:NULL forKey:@"bar"]); 3269 XCTAssertTrue([dict getRawValue:&value forKey:@"bar"]); 3270 XCTAssertEqual(value, 801); 3271 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]); 3272 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]); 3273 XCTAssertEqual(value, 702); 3274 XCTAssertTrue([dict getRawValue:NULL forKey:@"mumble"]); 3275 XCTAssertTrue([dict getRawValue:&value forKey:@"mumble"]); 3276 XCTAssertEqual(value, 803); 3277 3278 [dict setRawValue:700 forKey:@"mumble"]; 3279 XCTAssertEqual(dict.count, 4U); 3280 XCTAssertTrue([dict getRawValue:NULL forKey:@"foo"]); 3281 XCTAssertTrue([dict getRawValue:&value forKey:@"foo"]); 3282 XCTAssertEqual(value, 803); 3283 XCTAssertTrue([dict getRawValue:NULL forKey:@"bar"]); 3284 XCTAssertTrue([dict getRawValue:&value forKey:@"bar"]); 3285 XCTAssertEqual(value, 801); 3286 XCTAssertTrue([dict getEnum:NULL forKey:@"baz"]); 3287 XCTAssertTrue([dict getEnum:&value forKey:@"baz"]); 3288 XCTAssertEqual(value, 702); 3289 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]); 3290 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]); 3291 XCTAssertEqual(value, 700); 3292 3293 const NSString *kKeys2[] = { @"bar", @"baz" }; 3294 const int32_t kValues2[] = { 702, 801 }; // Unknown 3295 GPBStringEnumDictionary *dict2 = 3296 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue 3297 rawValues:kValues2 3298 forKeys:kKeys2 3299 count:GPBARRAYSIZE(kValues2)]; 3300 XCTAssertNotNil(dict2); 3301 [dict addRawEntriesFromDictionary:dict2]; 3302 XCTAssertEqual(dict.count, 4U); 3303 XCTAssertTrue([dict getRawValue:NULL forKey:@"foo"]); 3304 XCTAssertTrue([dict getRawValue:&value forKey:@"foo"]); 3305 XCTAssertEqual(value, 803); 3306 XCTAssertTrue([dict getEnum:NULL forKey:@"bar"]); 3307 XCTAssertTrue([dict getEnum:&value forKey:@"bar"]); 3308 XCTAssertEqual(value, 702); 3309 XCTAssertTrue([dict getRawValue:NULL forKey:@"baz"]); 3310 XCTAssertTrue([dict getRawValue:&value forKey:@"baz"]); 3311 XCTAssertEqual(value, 801); 3312 XCTAssertTrue([dict getEnum:NULL forKey:@"mumble"]); 3313 XCTAssertTrue([dict getEnum:&value forKey:@"mumble"]); 3314 XCTAssertEqual(value, 700); 3315 3316 [dict2 release]; 3317 [dict release]; 3318} 3319 3320- (void)testCopyUnknowns { 3321 const NSString *kKeys[] = { @"foo", @"bar", @"baz", @"mumble" }; 3322 const int32_t kValues[] = { 700, 801, 702, 803 }; 3323 GPBStringEnumDictionary *dict = 3324 [[GPBStringEnumDictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue 3325 rawValues:kValues 3326 forKeys:kKeys 3327 count:GPBARRAYSIZE(kValues)]; 3328 XCTAssertNotNil(dict); 3329 3330 GPBStringEnumDictionary *dict2 = [dict copy]; 3331 XCTAssertNotNil(dict2); 3332 3333 // Should be new pointer, but equal objects. 3334 XCTAssertNotEqual(dict, dict2); 3335 XCTAssertEqualObjects(dict, dict2); 3336 XCTAssertEqual(dict.validationFunc, dict2.validationFunc); // Pointer comparison 3337 XCTAssertTrue([dict2 isKindOfClass:[GPBStringEnumDictionary class]]); 3338 3339 [dict2 release]; 3340 [dict release]; 3341} 3342 3343@end 3344 3345//%PDDM-EXPAND-END TESTS_FOR_POD_VALUES(String,NSString,*,Objects,@"foo",@"bar",@"baz",@"mumble") 3346