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