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