Home | History | Annotate | Download | only in Tests
      1 // Protocol Buffers - Google's data interchange format
      2 // Copyright 2015 Google Inc.  All rights reserved.
      3 // https://developers.google.com/protocol-buffers/
      4 //
      5 // Redistribution and use in source and binary forms, with or without
      6 // modification, are permitted provided that the following conditions are
      7 // met:
      8 //
      9 //     * Redistributions of source code must retain the above copyright
     10 // notice, this list of conditions and the following disclaimer.
     11 //     * Redistributions in binary form must reproduce the above
     12 // copyright notice, this list of conditions and the following disclaimer
     13 // in the documentation and/or other materials provided with the
     14 // distribution.
     15 //     * Neither the name of Google Inc. nor the names of its
     16 // contributors may be used to endorse or promote products derived from
     17 // this software without specific prior written permission.
     18 //
     19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30 
     31 //%PDDM-DEFINE TEST_FOR_POD_KEY(KEY_NAME, KEY_TYPE, KEY1, KEY2, KEY3, KEY4)
     32 //%TESTS_FOR_POD_VALUES(KEY_NAME, KEY_TYPE, , , KEY1, KEY2, KEY3, KEY4)
     33 //%TESTS_FOR_POD_KEY_OBJECT_VALUE(KEY_NAME, KEY_TYPE, KEY1, KEY2, KEY3, KEY4, Object, NSString*, @"abc", @"def", @"ghi", @"jkl")
     34 
     35 //%PDDM-DEFINE TESTS_FOR_POD_VALUES(KEY_NAME, KEY_TYPE, KisP, KSUFFIX, KEY1, KEY2, KEY3, KEY4)
     36 //%TEST_HELPERS(KEY_NAME, KEY_TYPE, KisP)
     37 //%TESTS_FOR_POD_VALUE(KEY_NAME, KEY_TYPE, KisP, KSUFFIX, KEY1, KEY2, KEY3, KEY4, UInt32, uint32_t, , 100U, 101U, 102U, 103U)
     38 //%TESTS_FOR_POD_VALUE(KEY_NAME, KEY_TYPE, KisP, KSUFFIX, KEY1, KEY2, KEY3, KEY4, Int32, int32_t, , 200, 201, 202, 203)
     39 //%TESTS_FOR_POD_VALUE(KEY_NAME, KEY_TYPE, KisP, KSUFFIX, KEY1, KEY2, KEY3, KEY4, UInt64, uint64_t, , 300U, 301U, 302U, 303U)
     40 //%TESTS_FOR_POD_VALUE(KEY_NAME, KEY_TYPE, KisP, KSUFFIX, KEY1, KEY2, KEY3, KEY4, Int64, int64_t, , 400, 401, 402, 403)
     41 //%TESTS_FOR_POD_VALUE(KEY_NAME, KEY_TYPE, KisP, KSUFFIX, KEY1, KEY2, KEY3, KEY4, Bool, BOOL, , YES, YES, NO, NO)
     42 //%TESTS_FOR_POD_VALUE(KEY_NAME, KEY_TYPE, KisP, KSUFFIX, KEY1, KEY2, KEY3, KEY4, Float, float, , 500.f, 501.f, 502.f, 503.f)
     43 //%TESTS_FOR_POD_VALUE(KEY_NAME, KEY_TYPE, KisP, KSUFFIX, KEY1, KEY2, KEY3, KEY4, Double, double, , 600., 601., 602., 603.)
     44 //%TESTS_FOR_POD_VALUE(KEY_NAME, KEY_TYPE, KisP, KSUFFIX, KEY1, KEY2, KEY3, KEY4, Enum, int32_t, Raw, 700, 701, 702, 703)
     45 //%TESTS_FOR_ENUM_VALUE_RAW_ADDITIONS(KEY_NAME, KEY_TYPE, KisP, KSUFFIX, KEY1, KEY2, KEY3, KEY4)
     46 
     47 //%PDDM-DEFINE TESTS_FOR_POD_VALUE(KEY_NAME, KEY_TYPE, KisP, KSUFFIX, KEY1, KEY2, KEY3, KEY4, VALUE_NAME, VALUE_TYPE, VACCESSOR, VAL1, VAL2, VAL3, VAL4)
     48 //%TESTS_COMMON(KEY_NAME, KEY_TYPE, KisP, KSUFFIX, KEY1, KEY2, KEY3, KEY4, VALUE_NAME, VALUE_TYPE, , value, POD, VACCESSOR, VAL1, VAL2, VAL3, VAL4)
     49 
     50 //%PDDM-DEFINE TESTS_FOR_POD_KEY_OBJECT_VALUE(KEY_NAME, KEY_TYPE, KEY1, KEY2, KEY3, KEY4, VALUE_NAME, VALUE_TYPE, VAL1, VAL2, VAL3, VAL4)
     51 //%TESTS_COMMON(KEY_NAME, KEY_TYPE, , , KEY1, KEY2, KEY3, KEY4, VALUE_NAME, VALUE_TYPE, Objects, object, OBJECT, , VAL1, VAL2, VAL3, VAL4)
     52 
     53 //%PDDM-DEFINE DICTIONARY_CLASS_DECLPOD(KEY_NAME, VALUE_NAME, VALUE_TYPE)
     54 //%GPB##KEY_NAME##VALUE_NAME##Dictionary
     55 //%PDDM-DEFINE DICTIONARY_CLASS_DECLEnum(KEY_NAME, VALUE_NAME, VALUE_TYPE)
     56 //%GPB##KEY_NAME##VALUE_NAME##Dictionary
     57 //%PDDM-DEFINE DICTIONARY_CLASS_DECLOBJECT(KEY_NAME, VALUE_NAME, VALUE_TYPE)
     58 //%GPB##KEY_NAME##VALUE_NAME##Dictionary<VALUE_TYPE>
     59 
     60 //%PDDM-DEFINE TESTS_COMMON(KEY_NAME, KEY_TYPE, KisP, KSUFFIX, KEY1, KEY2, KEY3, KEY4, VALUE_NAME, VALUE_TYPE, VSUFFIX, VNAME, VHELPER, VACCESSOR, VAL1, VAL2, VAL3, VAL4)
     61 //%#pragma mark - KEY_NAME -> VALUE_NAME
     62 //%
     63 //%@interface GPB##KEY_NAME##VALUE_NAME##DictionaryTests : XCTestCase
     64 //%@end
     65 //%
     66 //%@implementation GPB##KEY_NAME##VALUE_NAME##DictionaryTests
     67 //%
     68 //%- (void)testEmpty {
     69 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict = [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] init];
     70 //%  XCTAssertNotNil(dict);
     71 //%  XCTAssertEqual(dict.count, 0U);
     72 //%VALUE_NOT_FOUND##VHELPER(dict, KEY1)
     73 //%  [dict enumerateKeysAnd##VNAME$u##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u, BOOL *stop) {
     74 //%    #pragma unused(aKey, a##VNAME$u, stop)
     75 //%    XCTFail(@"Shouldn't get here!");
     76 //%  }];
     77 //%  [dict release];
     78 //%}
     79 //%
     80 //%- (void)testOne {
     81 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict = [GPB##KEY_NAME##VALUE_NAME##Dictionary dictionaryWith##VNAME$u##:VAL1 forKey:KEY1];
     82 //%  XCTAssertNotNil(dict);
     83 //%  XCTAssertEqual(dict.count, 1U);
     84 //%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
     85 //%VALUE_NOT_FOUND##VHELPER(dict, KEY2)
     86 //%  [dict enumerateKeysAnd##VNAME$u##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u, BOOL *stop) {
     87 //%    XCTAssertEqual##KSUFFIX(aKey, KEY1);
     88 //%    XCTAssertEqual##VSUFFIX(a##VNAME$u, VAL1);
     89 //%    XCTAssertNotEqual(stop, NULL);
     90 //%  }];
     91 //%}
     92 //%
     93 //%- (void)testBasics {
     94 //%  const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2, KEY3 };
     95 //%  const VALUE_TYPE k##VNAME$u##s[] = { VAL1, VAL2, VAL3 };
     96 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
     97 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s
     98 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##  forKeys:kKeys
     99 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##    count:GPBARRAYSIZE(k##VNAME$u##s)];
    100 //%  XCTAssertNotNil(dict);
    101 //%  XCTAssertEqual(dict.count, 3U);
    102 //%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
    103 //%TEST_VALUE##VHELPER(dict, VNAME, KEY2, VAL2)
    104 //%TEST_VALUE##VHELPER(dict, VNAME, KEY3, VAL3)
    105 //%VALUE_NOT_FOUND##VHELPER(dict, KEY4)
    106 //%
    107 //%  __block NSUInteger idx = 0;
    108 //%  KEY_TYPE KisP##*seenKeys = malloc(3 * sizeof(KEY_TYPE##KisP));
    109 //%  VALUE_TYPE *seen##VNAME$u##s = malloc(3 * sizeof(VALUE_TYPE));
    110 //%  [dict enumerateKeysAnd##VNAME$u##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u, BOOL *stop) {
    111 //%    XCTAssertLessThan(idx, 3U);
    112 //%    seenKeys[idx] = aKey;
    113 //%    seen##VNAME$u##s[idx] = a##VNAME$u##;
    114 //%    XCTAssertNotEqual(stop, NULL);
    115 //%    ++idx;
    116 //%  }];
    117 //%  for (int i = 0; i < 3; ++i) {
    118 //%    BOOL foundKey = NO;
    119 //%    for (int j = 0; (j < 3) && !foundKey; ++j) {
    120 //%      if (COMPARE_KEYS##KSUFFIX(kKeys[i], seenKeys[j])) {
    121 //%        foundKey = YES;
    122 //%        XCTAssertEqual##VSUFFIX(k##VNAME$u##s[i], seen##VNAME$u##s[j], @"i = %d, j = %d", i, j);
    123 //%      }
    124 //%    }
    125 //%    XCTAssertTrue(foundKey, @"i = %d", i);
    126 //%  }
    127 //%  free(seenKeys);
    128 //%  free(seen##VNAME$u##s);
    129 //%
    130 //%  // Stopping the enumeration.
    131 //%  idx = 0;
    132 //%  [dict enumerateKeysAnd##VNAME$u##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u, BOOL *stop) {
    133 //%    #pragma unused(aKey, a##VNAME$u)
    134 //%    if (idx == 1) *stop = YES;
    135 //%    XCTAssertNotEqual(idx, 2U);
    136 //%    ++idx;
    137 //%  }];
    138 //%  [dict release];
    139 //%}
    140 //%
    141 //%- (void)testEquality {
    142 //%  const KEY_TYPE KisP##kKeys1[] = { KEY1, KEY2, KEY3, KEY4 };
    143 //%  const KEY_TYPE KisP##kKeys2[] = { KEY2, KEY1, KEY4 };
    144 //%  const VALUE_TYPE k##VNAME$u##s1[] = { VAL1, VAL2, VAL3 };
    145 //%  const VALUE_TYPE k##VNAME$u##s2[] = { VAL1, VAL4, VAL3 };
    146 //%  const VALUE_TYPE k##VNAME$u##s3[] = { VAL1, VAL2, VAL3, VAL4 };
    147 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict1 =
    148 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s1
    149 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##  forKeys:kKeys1
    150 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##    count:GPBARRAYSIZE(k##VNAME$u##s1)];
    151 //%  XCTAssertNotNil(dict1);
    152 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict1prime =
    153 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s1
    154 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##  forKeys:kKeys1
    155 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##    count:GPBARRAYSIZE(k##VNAME$u##s1)];
    156 //%  XCTAssertNotNil(dict1prime);
    157 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 =
    158 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s2
    159 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##  forKeys:kKeys1
    160 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##    count:GPBARRAYSIZE(k##VNAME$u##s2)];
    161 //%  XCTAssertNotNil(dict2);
    162 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict3 =
    163 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s1
    164 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##  forKeys:kKeys2
    165 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##    count:GPBARRAYSIZE(k##VNAME$u##s1)];
    166 //%  XCTAssertNotNil(dict3);
    167 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict4 =
    168 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s3
    169 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##  forKeys:kKeys1
    170 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##    count:GPBARRAYSIZE(k##VNAME$u##s3)];
    171 //%  XCTAssertNotNil(dict4);
    172 //%
    173 //%  // 1/1Prime should be different objects, but equal.
    174 //%  XCTAssertNotEqual(dict1, dict1prime);
    175 //%  XCTAssertEqualObjects(dict1, dict1prime);
    176 //%  // Equal, so they must have same hash.
    177 //%  XCTAssertEqual([dict1 hash], [dict1prime hash]);
    178 //%
    179 //%  // 2 is same keys, different ##VNAME##s; not equal.
    180 //%  XCTAssertNotEqualObjects(dict1, dict2);
    181 //%
    182 //%  // 3 is different keys, same ##VNAME##s; not equal.
    183 //%  XCTAssertNotEqualObjects(dict1, dict3);
    184 //%
    185 //%  // 4 extra pair; not equal
    186 //%  XCTAssertNotEqualObjects(dict1, dict4);
    187 //%
    188 //%  [dict1 release];
    189 //%  [dict1prime release];
    190 //%  [dict2 release];
    191 //%  [dict3 release];
    192 //%  [dict4 release];
    193 //%}
    194 //%
    195 //%- (void)testCopy {
    196 //%  const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2, KEY3, KEY4 };
    197 //%  const VALUE_TYPE k##VNAME$u##s[] = { VAL1, VAL2, VAL3, VAL4 };
    198 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
    199 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s
    200 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##  forKeys:kKeys
    201 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##    count:GPBARRAYSIZE(k##VNAME$u##s)];
    202 //%  XCTAssertNotNil(dict);
    203 //%
    204 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 = [dict copy];
    205 //%  XCTAssertNotNil(dict2);
    206 //%
    207 //%  // Should be new object but equal.
    208 //%  XCTAssertNotEqual(dict, dict2);
    209 //%  XCTAssertEqualObjects(dict, dict2);
    210 //%  XCTAssertTrue([dict2 isKindOfClass:[GPB##KEY_NAME##VALUE_NAME##Dictionary class]]);
    211 //%
    212 //%  [dict2 release];
    213 //%  [dict release];
    214 //%}
    215 //%
    216 //%- (void)testDictionaryFromDictionary {
    217 //%  const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2, KEY3, KEY4 };
    218 //%  const VALUE_TYPE k##VNAME$u##s[] = { VAL1, VAL2, VAL3, VAL4 };
    219 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
    220 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s
    221 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##  forKeys:kKeys
    222 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##    count:GPBARRAYSIZE(k##VNAME$u##s)];
    223 //%  XCTAssertNotNil(dict);
    224 //%
    225 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 =
    226 //%      [GPB##KEY_NAME##VALUE_NAME##Dictionary dictionaryWithDictionary:dict];
    227 //%  XCTAssertNotNil(dict2);
    228 //%
    229 //%  // Should be new pointer, but equal objects.
    230 //%  XCTAssertNotEqual(dict, dict2);
    231 //%  XCTAssertEqualObjects(dict, dict2);
    232 //%  [dict release];
    233 //%}
    234 //%
    235 //%- (void)testAdds {
    236 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict = [GPB##KEY_NAME##VALUE_NAME##Dictionary dictionary];
    237 //%  XCTAssertNotNil(dict);
    238 //%
    239 //%  XCTAssertEqual(dict.count, 0U);
    240 //%  [dict set##VNAME$u##:VAL1 forKey:KEY1];
    241 //%  XCTAssertEqual(dict.count, 1U);
    242 //%
    243 //%  const KEY_TYPE KisP##kKeys[] = { KEY2, KEY3, KEY4 };
    244 //%  const VALUE_TYPE k##VNAME$u##s[] = { VAL2, VAL3, VAL4 };
    245 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 =
    246 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s
    247 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##  forKeys:kKeys
    248 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##    count:GPBARRAYSIZE(k##VNAME$u##s)];
    249 //%  XCTAssertNotNil(dict2);
    250 //%  [dict add##VACCESSOR##EntriesFromDictionary:dict2];
    251 //%  XCTAssertEqual(dict.count, 4U);
    252 //%
    253 //%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
    254 //%TEST_VALUE##VHELPER(dict, VNAME, KEY2, VAL2)
    255 //%TEST_VALUE##VHELPER(dict, VNAME, KEY3, VAL3)
    256 //%TEST_VALUE##VHELPER(dict, VNAME, KEY4, VAL4)
    257 //%  [dict2 release];
    258 //%}
    259 //%
    260 //%- (void)testRemove {
    261 //%  const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2, KEY3, KEY4 };
    262 //%  const VALUE_TYPE k##VNAME$u##s[] = { VAL1, VAL2, VAL3, VAL4 };
    263 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
    264 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s
    265 //%           KEY_NAME$S VALUE_NAME$S          ##VNAME$S##  forKeys:kKeys
    266 //%           KEY_NAME$S VALUE_NAME$S          ##VNAME$S##    count:GPBARRAYSIZE(k##VNAME$u##s)];
    267 //%  XCTAssertNotNil(dict);
    268 //%  XCTAssertEqual(dict.count, 4U);
    269 //%
    270 //%  [dict remove##VNAME$u##ForKey:KEY2];
    271 //%  XCTAssertEqual(dict.count, 3U);
    272 //%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
    273 //%VALUE_NOT_FOUND##VHELPER(dict, KEY2)
    274 //%TEST_VALUE##VHELPER(dict, VNAME, KEY3, VAL3)
    275 //%TEST_VALUE##VHELPER(dict, VNAME, KEY4, VAL4)
    276 //%
    277 //%  // Remove again does nothing.
    278 //%  [dict remove##VNAME$u##ForKey:KEY2];
    279 //%  XCTAssertEqual(dict.count, 3U);
    280 //%TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
    281 //%VALUE_NOT_FOUND##VHELPER(dict, KEY2)
    282 //%TEST_VALUE##VHELPER(dict, VNAME, KEY3, VAL3)
    283 //%TEST_VALUE##VHELPER(dict, VNAME, KEY4, VAL4)
    284 //%
    285 //%  [dict remove##VNAME$u##ForKey:KEY4];
    286 //%  XCTAssertEqual(dict.count, 2U);
    287 //%TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
    288 //%VALUE_NOT_FOUND##VHELPER(dict, KEY2)
    289 //%TEST_VALUE##VHELPER(dict, VNAME, KEY3, VAL3)
    290 //%VALUE_NOT_FOUND##VHELPER(dict, KEY4)
    291 //%
    292 //%  [dict removeAll];
    293 //%  XCTAssertEqual(dict.count, 0U);
    294 //%VALUE_NOT_FOUND##VHELPER(dict, KEY1)
    295 //%VALUE_NOT_FOUND##VHELPER(dict, KEY2)
    296 //%VALUE_NOT_FOUND##VHELPER(dict, KEY3)
    297 //%VALUE_NOT_FOUND##VHELPER(dict, KEY4)
    298 //%  [dict release];
    299 //%}
    300 //%
    301 //%- (void)testInplaceMutation {
    302 //%  const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2, KEY3, KEY4 };
    303 //%  const VALUE_TYPE k##VNAME$u##s[] = { VAL1, VAL2, VAL3, VAL4 };
    304 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
    305 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s
    306 //%           KEY_NAME$S VALUE_NAME$S          ##VNAME$S##  forKeys:kKeys
    307 //%           KEY_NAME$S VALUE_NAME$S          ##VNAME$S##    count:GPBARRAYSIZE(k##VNAME$u##s)];
    308 //%  XCTAssertNotNil(dict);
    309 //%  XCTAssertEqual(dict.count, 4U);
    310 //%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
    311 //%TEST_VALUE##VHELPER(dict, VNAME, KEY2, VAL2)
    312 //%TEST_VALUE##VHELPER(dict, VNAME, KEY3, VAL3)
    313 //%TEST_VALUE##VHELPER(dict, VNAME, KEY4, VAL4)
    314 //%
    315 //%  [dict set##VNAME$u##:VAL4 forKey:KEY1];
    316 //%  XCTAssertEqual(dict.count, 4U);
    317 //%TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL4)
    318 //%TEST_VALUE##VHELPER(dict, VNAME, KEY2, VAL2)
    319 //%TEST_VALUE##VHELPER(dict, VNAME, KEY3, VAL3)
    320 //%TEST_VALUE##VHELPER(dict, VNAME, KEY4, VAL4)
    321 //%
    322 //%  [dict set##VNAME$u##:VAL2 forKey:KEY4];
    323 //%  XCTAssertEqual(dict.count, 4U);
    324 //%TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL4)
    325 //%TEST_VALUE##VHELPER(dict, VNAME, KEY2, VAL2)
    326 //%TEST_VALUE##VHELPER(dict, VNAME, KEY3, VAL3)
    327 //%TEST_VALUE##VHELPER(dict, VNAME, KEY4, VAL2)
    328 //%
    329 //%  const KEY_TYPE KisP##kKeys2[] = { KEY2, KEY3 };
    330 //%  const VALUE_TYPE k##VNAME$u##s2[] = { VAL3, VAL1 };
    331 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 =
    332 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s2
    333 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##  forKeys:kKeys2
    334 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##    count:GPBARRAYSIZE(k##VNAME$u##s2)];
    335 //%  XCTAssertNotNil(dict2);
    336 //%  [dict add##VACCESSOR##EntriesFromDictionary:dict2];
    337 //%  XCTAssertEqual(dict.count, 4U);
    338 //%TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL4)
    339 //%TEST_VALUE##VHELPER(dict, VNAME, KEY2, VAL3)
    340 //%TEST_VALUE##VHELPER(dict, VNAME, KEY3, VAL1)
    341 //%TEST_VALUE##VHELPER(dict, VNAME, KEY4, VAL2)
    342 //%
    343 //%  [dict2 release];
    344 //%  [dict release];
    345 //%}
    346 //%
    347 //%@end
    348 //%
    349 
    350 //%PDDM-DEFINE TESTS_FOR_ENUM_VALUE_RAW_ADDITIONS(KEY_NAME, KEY_TYPE, KisP, KSUFFIX, KEY1, KEY2, KEY3, KEY4)
    351 //%TESTS_FOR_ENUM_VALUE_RAW_ADDITIONS2(KEY_NAME, KEY_TYPE, KisP, KSUFFIX, KEY1, KEY2, KEY3, KEY4, Enum, int32_t, , POD, 700, 801, 702, 803)
    352 //%PDDM-DEFINE TESTS_FOR_ENUM_VALUE_RAW_ADDITIONS2(KEY_NAME, KEY_TYPE, KisP, KSUFFIX, KEY1, KEY2, KEY3, KEY4, VALUE_NAME, VALUE_TYPE, VSUFFIX, VHELPER, VAL1, VAL2, VAL3, VAL4)
    353 //%#pragma mark - KEY_NAME -> VALUE_NAME (Unknown Enums)
    354 //%
    355 //%@interface GPB##KEY_NAME##VALUE_NAME##DictionaryUnknownEnumTests : XCTestCase
    356 //%@end
    357 //%
    358 //%@implementation GPB##KEY_NAME##VALUE_NAME##DictionaryUnknownEnumTests
    359 //%
    360 //%- (void)testRawBasics {
    361 //%  const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2, KEY3 };
    362 //%  const VALUE_TYPE kValues[] = { VAL1, VAL2, VAL3 };
    363 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
    364 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
    365 //%           KEY_NAME$S VALUE_NAME$S                                  rawValues:kValues
    366 //%           KEY_NAME$S VALUE_NAME$S                                    forKeys:kKeys
    367 //%           KEY_NAME$S VALUE_NAME$S                                      count:GPBARRAYSIZE(kValues)];
    368 //%  XCTAssertNotNil(dict);
    369 //%  XCTAssertEqual(dict.count, 3U);
    370 //%  XCTAssertTrue(dict.validationFunc == TestingEnum_IsValidValue);  // Pointer comparison
    371 //%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, value)TEST_RAW_VALUE##VHELPER(dict, value, KEY1, VAL1)
    372 //%TEST_VALUE##VHELPER(dict, value, KEY2, kGPBUnrecognizedEnumeratorValue)
    373 //%TEST_RAW_VALUE##VHELPER(dict, value, KEY2, VAL2)
    374 //%TEST_RAW_VALUE##VHELPER(dict, value, KEY3, VAL3)
    375 //%RAW_VALUE_NOT_FOUND##VHELPER(dict, KEY4)
    376 //%
    377 //%  __block NSUInteger idx = 0;
    378 //%  KEY_TYPE KisP##*seenKeys = malloc(3 * sizeof(KEY_TYPE##KisP));
    379 //%  VALUE_TYPE *seenValues = malloc(3 * sizeof(VALUE_TYPE));
    380 //%  [dict enumerateKeysAndValuesUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE aValue, BOOL *stop) {
    381 //%    XCTAssertLessThan(idx, 3U);
    382 //%    seenKeys[idx] = aKey;
    383 //%    seenValues[idx] = aValue;
    384 //%    XCTAssertNotEqual(stop, NULL);
    385 //%    ++idx;
    386 //%  }];
    387 //%  for (int i = 0; i < 3; ++i) {
    388 //%    BOOL foundKey = NO;
    389 //%    for (int j = 0; (j < 3) && !foundKey; ++j) {
    390 //%      if (COMPARE_KEYS##KSUFFIX(kKeys[i], seenKeys[j])) {
    391 //%        foundKey = YES;
    392 //%        if (i == 1) {
    393 //%          XCTAssertEqual##VSUFFIX(kGPBUnrecognizedEnumeratorValue, seenValues[j], @"i = %d, j = %d", i, j);
    394 //%        } else {
    395 //%          XCTAssertEqual##VSUFFIX(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
    396 //%        }
    397 //%      }
    398 //%    }
    399 //%    XCTAssertTrue(foundKey, @"i = %d", i);
    400 //%  }
    401 //%  idx = 0;
    402 //%  [dict enumerateKeysAndRawValuesUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE aValue, BOOL *stop) {
    403 //%    XCTAssertLessThan(idx, 3U);
    404 //%    seenKeys[idx] = aKey;
    405 //%    seenValues[idx] = aValue;
    406 //%    XCTAssertNotEqual(stop, NULL);
    407 //%    ++idx;
    408 //%  }];
    409 //%  for (int i = 0; i < 3; ++i) {
    410 //%    BOOL foundKey = NO;
    411 //%    for (int j = 0; (j < 3) && !foundKey; ++j) {
    412 //%      if (COMPARE_KEYS##KSUFFIX(kKeys[i], seenKeys[j])) {
    413 //%        foundKey = YES;
    414 //%        XCTAssertEqual##VSUFFIX(kValues[i], seenValues[j], @"i = %d, j = %d", i, j);
    415 //%      }
    416 //%    }
    417 //%    XCTAssertTrue(foundKey, @"i = %d", i);
    418 //%  }
    419 //%  free(seenKeys);
    420 //%  free(seenValues);
    421 //%
    422 //%  // Stopping the enumeration.
    423 //%  idx = 0;
    424 //%  [dict enumerateKeysAndRawValuesUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE aValue, BOOL *stop) {
    425 //%    #pragma unused(aKey, aValue)
    426 //%    if (idx == 1) *stop = YES;
    427 //%    XCTAssertNotEqual(idx, 2U);
    428 //%    ++idx;
    429 //%  }];
    430 //%  [dict release];
    431 //%}
    432 //%
    433 //%- (void)testEqualityWithUnknowns {
    434 //%  const KEY_TYPE KisP##kKeys1[] = { KEY1, KEY2, KEY3, KEY4 };
    435 //%  const KEY_TYPE KisP##kKeys2[] = { KEY2, KEY1, KEY4 };
    436 //%  const VALUE_TYPE kValues1[] = { VAL1, VAL2, VAL3 };  // Unknown
    437 //%  const VALUE_TYPE kValues2[] = { VAL1, VAL4, VAL3 };  // Unknown
    438 //%  const VALUE_TYPE kValues3[] = { VAL1, VAL2, VAL3, VAL4 };  // Unknowns
    439 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict1 =
    440 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
    441 //%           KEY_NAME$S VALUE_NAME$S                                  rawValues:kValues1
    442 //%           KEY_NAME$S VALUE_NAME$S                                    forKeys:kKeys1
    443 //%           KEY_NAME$S VALUE_NAME$S                                      count:GPBARRAYSIZE(kValues1)];
    444 //%  XCTAssertNotNil(dict1);
    445 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict1prime =
    446 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
    447 //%           KEY_NAME$S VALUE_NAME$S                                  rawValues:kValues1
    448 //%           KEY_NAME$S VALUE_NAME$S                                    forKeys:kKeys1
    449 //%           KEY_NAME$S VALUE_NAME$S                                      count:GPBARRAYSIZE(kValues1)];
    450 //%  XCTAssertNotNil(dict1prime);
    451 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 =
    452 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
    453 //%           KEY_NAME$S VALUE_NAME$S                                  rawValues:kValues2
    454 //%           KEY_NAME$S VALUE_NAME$S                                    forKeys:kKeys1
    455 //%           KEY_NAME$S VALUE_NAME$S                                      count:GPBARRAYSIZE(kValues2)];
    456 //%  XCTAssertNotNil(dict2);
    457 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict3 =
    458 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
    459 //%           KEY_NAME$S VALUE_NAME$S                                  rawValues:kValues1
    460 //%           KEY_NAME$S VALUE_NAME$S                                    forKeys:kKeys2
    461 //%           KEY_NAME$S VALUE_NAME$S                                      count:GPBARRAYSIZE(kValues1)];
    462 //%  XCTAssertNotNil(dict3);
    463 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict4 =
    464 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
    465 //%           KEY_NAME$S VALUE_NAME$S                                  rawValues:kValues3
    466 //%           KEY_NAME$S VALUE_NAME$S                                    forKeys:kKeys1
    467 //%           KEY_NAME$S VALUE_NAME$S                                      count:GPBARRAYSIZE(kValues3)];
    468 //%  XCTAssertNotNil(dict4);
    469 //%
    470 //%  // 1/1Prime should be different objects, but equal.
    471 //%  XCTAssertNotEqual(dict1, dict1prime);
    472 //%  XCTAssertEqualObjects(dict1, dict1prime);
    473 //%  // Equal, so they must have same hash.
    474 //%  XCTAssertEqual([dict1 hash], [dict1prime hash]);
    475 //%
    476 //%  // 2 is same keys, different values; not equal.
    477 //%  XCTAssertNotEqualObjects(dict1, dict2);
    478 //%
    479 //%  // 3 is different keys, same values; not equal.
    480 //%  XCTAssertNotEqualObjects(dict1, dict3);
    481 //%
    482 //%  // 4 extra pair; not equal
    483 //%  XCTAssertNotEqualObjects(dict1, dict4);
    484 //%
    485 //%  [dict1 release];
    486 //%  [dict1prime release];
    487 //%  [dict2 release];
    488 //%  [dict3 release];
    489 //%  [dict4 release];
    490 //%}
    491 //%
    492 //%- (void)testCopyWithUnknowns {
    493 //%  const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2, KEY3, KEY4 };
    494 //%  const VALUE_TYPE kValues[] = { VAL1, VAL2, VAL3, VAL4 };  // Unknown
    495 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
    496 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
    497 //%           KEY_NAME$S VALUE_NAME$S                                  rawValues:kValues
    498 //%           KEY_NAME$S VALUE_NAME$S                                    forKeys:kKeys
    499 //%           KEY_NAME$S VALUE_NAME$S                                      count:GPBARRAYSIZE(kValues)];
    500 //%  XCTAssertNotNil(dict);
    501 //%
    502 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 = [dict copy];
    503 //%  XCTAssertNotNil(dict2);
    504 //%
    505 //%  // Should be new pointer, but equal objects.
    506 //%  XCTAssertNotEqual(dict, dict2);
    507 //%  XCTAssertEqual(dict.validationFunc, dict2.validationFunc);  // Pointer comparison
    508 //%  XCTAssertEqualObjects(dict, dict2);
    509 //%
    510 //%  [dict2 release];
    511 //%  [dict release];
    512 //%}
    513 //%
    514 //%- (void)testDictionaryFromDictionary {
    515 //%  const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2, KEY3, KEY4 };
    516 //%  const VALUE_TYPE kValues[] = { VAL1, VAL2, VAL3, VAL4 };  // Unknowns
    517 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
    518 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
    519 //%           KEY_NAME$S VALUE_NAME$S                                  rawValues:kValues
    520 //%           KEY_NAME$S VALUE_NAME$S                                    forKeys:kKeys
    521 //%           KEY_NAME$S VALUE_NAME$S                                      count:GPBARRAYSIZE(kValues)];
    522 //%  XCTAssertNotNil(dict);
    523 //%
    524 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 =
    525 //%      [GPB##KEY_NAME##VALUE_NAME##Dictionary dictionaryWithDictionary:dict];
    526 //%  XCTAssertNotNil(dict2);
    527 //%
    528 //%  // Should be new pointer, but equal objects.
    529 //%  XCTAssertNotEqual(dict, dict2);
    530 //%  XCTAssertEqualObjects(dict, dict2);
    531 //%  XCTAssertEqual(dict.validationFunc, dict2.validationFunc);  // Pointer comparison
    532 //%  [dict release];
    533 //%}
    534 //%
    535 //%- (void)testUnknownAdds {
    536 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
    537 //%    [GPB##KEY_NAME##VALUE_NAME##Dictionary dictionaryWithValidationFunction:TestingEnum_IsValidValue];
    538 //%  XCTAssertNotNil(dict);
    539 //%
    540 //%  XCTAssertEqual(dict.count, 0U);
    541 //%  XCTAssertThrowsSpecificNamed([dict setValue:VAL2 forKey:KEY2],  // Unknown
    542 //%                               NSException, NSInvalidArgumentException);
    543 //%  XCTAssertEqual(dict.count, 0U);
    544 //%  [dict setRawValue:VAL2 forKey:KEY2];  // Unknown
    545 //%  XCTAssertEqual(dict.count, 1U);
    546 //%
    547 //%  const KEY_TYPE KisP##kKeys[] = { KEY1, KEY3, KEY4 };
    548 //%  const VALUE_TYPE kValues[] = { VAL1, VAL3, VAL4 };  // Unknown
    549 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 =
    550 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWithValues:kValues
    551 //%           KEY_NAME$S VALUE_NAME$S                        forKeys:kKeys
    552 //%           KEY_NAME$S VALUE_NAME$S                          count:GPBARRAYSIZE(kValues)];
    553 //%  XCTAssertNotNil(dict2);
    554 //%  [dict addRawEntriesFromDictionary:dict2];
    555 //%  XCTAssertEqual(dict.count, 4U);
    556 //%
    557 //%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, value)TEST_VALUE##VHELPER(dict, value, KEY1, VAL1)
    558 //%TEST_VALUE##VHELPER(dict, value, KEY2, kGPBUnrecognizedEnumeratorValue)
    559 //%TEST_RAW_VALUE##VHELPER(dict, value, KEY2, VAL2)
    560 //%TEST_VALUE##VHELPER(dict, value, KEY3, VAL3)
    561 //%TEST_VALUE##VHELPER(dict, value, KEY4, kGPBUnrecognizedEnumeratorValue)
    562 //%TEST_RAW_VALUE##VHELPER(dict, value, KEY4, VAL4)
    563 //%  [dict2 release];
    564 //%}
    565 //%
    566 //%- (void)testUnknownRemove {
    567 //%  const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2, KEY3, KEY4 };
    568 //%  const VALUE_TYPE kValues[] = { VAL1, VAL2, VAL3, VAL4 };  // Unknowns
    569 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
    570 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
    571 //%           KEY_NAME$S VALUE_NAME$S                                  rawValues:kValues
    572 //%           KEY_NAME$S VALUE_NAME$S                                    forKeys:kKeys
    573 //%           KEY_NAME$S VALUE_NAME$S                                      count:GPBARRAYSIZE(kValues)];
    574 //%  XCTAssertNotNil(dict);
    575 //%  XCTAssertEqual(dict.count, 4U);
    576 //%
    577 //%  [dict removeValueForKey:KEY2];
    578 //%  XCTAssertEqual(dict.count, 3U);
    579 //%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, value)TEST_VALUE##VHELPER(dict, value, KEY1, VAL1)
    580 //%VALUE_NOT_FOUND##VHELPER(dict, KEY2)
    581 //%TEST_VALUE##VHELPER(dict, value, KEY3, VAL3)
    582 //%TEST_RAW_VALUE##VHELPER(dict, value, KEY4, VAL4)
    583 //%
    584 //%  // Remove again does nothing.
    585 //%  [dict removeValueForKey:KEY2];
    586 //%  XCTAssertEqual(dict.count, 3U);
    587 //%TEST_VALUE##VHELPER(dict, value, KEY1, VAL1)
    588 //%VALUE_NOT_FOUND##VHELPER(dict, KEY2)
    589 //%TEST_VALUE##VHELPER(dict, value, KEY3, VAL3)
    590 //%TEST_RAW_VALUE##VHELPER(dict, value, KEY4, VAL4)
    591 //%
    592 //%  [dict removeValueForKey:KEY4];
    593 //%  XCTAssertEqual(dict.count, 2U);
    594 //%TEST_VALUE##VHELPER(dict, value, KEY1, VAL1)
    595 //%VALUE_NOT_FOUND##VHELPER(dict, KEY2)
    596 //%TEST_VALUE##VHELPER(dict, value, KEY3, VAL3)
    597 //%VALUE_NOT_FOUND##VHELPER(dict, KEY4)
    598 //%
    599 //%  [dict removeAll];
    600 //%  XCTAssertEqual(dict.count, 0U);
    601 //%VALUE_NOT_FOUND##VHELPER(dict, KEY1)
    602 //%VALUE_NOT_FOUND##VHELPER(dict, KEY2)
    603 //%VALUE_NOT_FOUND##VHELPER(dict, KEY3)
    604 //%VALUE_NOT_FOUND##VHELPER(dict, KEY4)
    605 //%  [dict release];
    606 //%}
    607 //%
    608 //%- (void)testInplaceMutationUnknowns {
    609 //%  const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2, KEY3, KEY4 };
    610 //%  const VALUE_TYPE kValues[] = { VAL1, VAL2, VAL3, VAL4 };  // Unknowns
    611 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
    612 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
    613 //%           KEY_NAME$S VALUE_NAME$S                                  rawValues:kValues
    614 //%           KEY_NAME$S VALUE_NAME$S                                    forKeys:kKeys
    615 //%           KEY_NAME$S VALUE_NAME$S                                      count:GPBARRAYSIZE(kValues)];
    616 //%  XCTAssertNotNil(dict);
    617 //%  XCTAssertEqual(dict.count, 4U);
    618 //%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, value)TEST_VALUE##VHELPER(dict, value, KEY1, VAL1)
    619 //%TEST_RAW_VALUE##VHELPER(dict, value, KEY2, VAL2)
    620 //%TEST_VALUE##VHELPER(dict, value, KEY3, VAL3)
    621 //%TEST_RAW_VALUE##VHELPER(dict, value, KEY4, VAL4)
    622 //%
    623 //%  XCTAssertThrowsSpecificNamed([dict setValue:VAL4 forKey:KEY1],  // Unknown
    624 //%                               NSException, NSInvalidArgumentException);
    625 //%  XCTAssertEqual(dict.count, 4U);
    626 //%TEST_VALUE##VHELPER(dict, value, KEY1, VAL1)
    627 //%TEST_RAW_VALUE##VHELPER(dict, value, KEY2, VAL2)
    628 //%TEST_VALUE##VHELPER(dict, value, KEY3, VAL3)
    629 //%TEST_RAW_VALUE##VHELPER(dict, value, KEY4, VAL4)
    630 //%
    631 //%  [dict setRawValue:VAL4 forKey:KEY1];  // Unknown
    632 //%  XCTAssertEqual(dict.count, 4U);
    633 //%TEST_RAW_VALUE##VHELPER(dict, value, KEY1, VAL4)
    634 //%TEST_RAW_VALUE##VHELPER(dict, value, KEY2, VAL2)
    635 //%TEST_VALUE##VHELPER(dict, value, KEY3, VAL3)
    636 //%TEST_RAW_VALUE##VHELPER(dict, value, KEY4, VAL4)
    637 //%
    638 //%  [dict setRawValue:VAL1 forKey:KEY4];
    639 //%  XCTAssertEqual(dict.count, 4U);
    640 //%TEST_RAW_VALUE##VHELPER(dict, value, KEY1, VAL4)
    641 //%TEST_RAW_VALUE##VHELPER(dict, value, KEY2, VAL2)
    642 //%TEST_VALUE##VHELPER(dict, value, KEY3, VAL3)
    643 //%TEST_VALUE##VHELPER(dict, value, KEY4, VAL1)
    644 //%
    645 //%  const KEY_TYPE KisP##kKeys2[] = { KEY2, KEY3 };
    646 //%  const VALUE_TYPE kValues2[] = { VAL3, VAL2 };  // Unknown
    647 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 =
    648 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
    649 //%           KEY_NAME$S VALUE_NAME$S                                  rawValues:kValues2
    650 //%           KEY_NAME$S VALUE_NAME$S                                    forKeys:kKeys2
    651 //%           KEY_NAME$S VALUE_NAME$S                                      count:GPBARRAYSIZE(kValues2)];
    652 //%  XCTAssertNotNil(dict2);
    653 //%  [dict addRawEntriesFromDictionary:dict2];
    654 //%  XCTAssertEqual(dict.count, 4U);
    655 //%TEST_RAW_VALUE##VHELPER(dict, value, KEY1, VAL4)
    656 //%TEST_VALUE##VHELPER(dict, value, KEY2, VAL3)
    657 //%TEST_RAW_VALUE##VHELPER(dict, value, KEY3, VAL2)
    658 //%TEST_VALUE##VHELPER(dict, value, KEY4, VAL1)
    659 //%
    660 //%  [dict2 release];
    661 //%  [dict release];
    662 //%}
    663 //%
    664 //%- (void)testCopyUnknowns {
    665 //%  const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2, KEY3, KEY4 };
    666 //%  const VALUE_TYPE kValues[] = { VAL1, VAL2, VAL3, VAL4 };
    667 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
    668 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWithValidationFunction:TestingEnum_IsValidValue
    669 //%           KEY_NAME$S VALUE_NAME$S                                  rawValues:kValues
    670 //%           KEY_NAME$S VALUE_NAME$S                                    forKeys:kKeys
    671 //%           KEY_NAME$S VALUE_NAME$S                                      count:GPBARRAYSIZE(kValues)];
    672 //%  XCTAssertNotNil(dict);
    673 //%
    674 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 = [dict copy];
    675 //%  XCTAssertNotNil(dict2);
    676 //%
    677 //%  // Should be new pointer, but equal objects.
    678 //%  XCTAssertNotEqual(dict, dict2);
    679 //%  XCTAssertEqualObjects(dict, dict2);
    680 //%  XCTAssertEqual(dict.validationFunc, dict2.validationFunc);  // Pointer comparison
    681 //%  XCTAssertTrue([dict2 isKindOfClass:[GPB##KEY_NAME##VALUE_NAME##Dictionary class]]);
    682 //%
    683 //%  [dict2 release];
    684 //%  [dict release];
    685 //%}
    686 //%
    687 //%@end
    688 //%
    689 
    690 //
    691 // Helpers for PODs
    692 //
    693 
    694 //%PDDM-DEFINE DECLARE_VALUE_STORAGEPOD(VALUE_TYPE, NAME)
    695 //%  VALUE_TYPE NAME;
    696 //%
    697 //%PDDM-DEFINE VALUE_NOT_FOUNDPOD(DICT, KEY)
    698 //%  XCTAssertFalse([DICT valueForKey:KEY value:NULL]);
    699 //%PDDM-DEFINE TEST_VALUEPOD(DICT, STORAGE, KEY, VALUE)
    700 //%  XCTAssertTrue([DICT valueForKey:KEY value:NULL]);
    701 //%  XCTAssertTrue([DICT valueForKey:KEY value:&STORAGE]);
    702 //%  XCTAssertEqual(STORAGE, VALUE);
    703 //%PDDM-DEFINE COMPARE_KEYS(KEY1, KEY2)
    704 //%KEY1 == KEY2
    705 //%PDDM-DEFINE RAW_VALUE_NOT_FOUNDPOD(DICT, KEY)
    706 //%  XCTAssertFalse([DICT valueForKey:KEY rawValue:NULL]);
    707 //%PDDM-DEFINE TEST_RAW_VALUEPOD(DICT, STORAGE, KEY, VALUE)
    708 //%  XCTAssertTrue([DICT valueForKey:KEY rawValue:NULL]);
    709 //%  XCTAssertTrue([DICT valueForKey:KEY rawValue:&STORAGE]);
    710 //%  XCTAssertEqual(STORAGE, VALUE);
    711 
    712 //
    713 // Helpers for Objects
    714 //
    715 
    716 //%PDDM-DEFINE DECLARE_VALUE_STORAGEOBJECT(VALUE_TYPE, NAME)
    717 // Empty
    718 //%PDDM-DEFINE VALUE_NOT_FOUNDOBJECT(DICT, KEY)
    719 //%  XCTAssertNil([DICT objectForKey:KEY]);
    720 //%PDDM-DEFINE TEST_VALUEOBJECT(DICT, STORAGE, KEY, VALUE)
    721 //%  XCTAssertEqualObjects([DICT objectForKey:KEY], VALUE);
    722 //%PDDM-DEFINE COMPARE_KEYSObjects(KEY1, KEY2)
    723 //%[KEY1 isEqual:KEY2]
    724 
    725 //
    726 // Helpers for tests.
    727 //
    728 
    729 //%PDDM-DEFINE TEST_HELPERS(KEY_NAME, KEY_TYPE, KisP)
    730 //%// To let the testing macros work, add some extra methods to simplify things.
    731 //%@interface GPB##KEY_NAME##EnumDictionary (TestingTweak)
    732 //%+ (instancetype)dictionaryWithValue:(int32_t)value forKey:(KEY_TYPE##KisP$S##KisP)key;
    733 //%- (instancetype)initWithValues:(const int32_t [])values
    734 //%                       forKeys:(const KEY_TYPE##KisP$S##KisP [])keys
    735 //%                         count:(NSUInteger)count;
    736 //%@end
    737 //%
    738 //%static BOOL TestingEnum_IsValidValue(int32_t value) {
    739 //%  switch (value) {
    740 //%    case 700:
    741 //%    case 701:
    742 //%    case 702:
    743 //%    case 703:
    744 //%      return YES;
    745 //%    default:
    746 //%      return NO;
    747 //%  }
    748 //%}
    749 //%
    750 //%@implementation GPB##KEY_NAME##EnumDictionary (TestingTweak)
    751 //%+ (instancetype)dictionaryWithValue:(int32_t)value forKey:(KEY_TYPE##KisP$S##KisP)key {
    752 //%  // Cast is needed to compiler knows what class we are invoking initWithValues: on to get the
    753 //%  // type correct.
    754 //%  return [[(GPB##KEY_NAME##EnumDictionary*)[self alloc] initWithValidationFunction:TestingEnum_IsValidValue
    755 //%                KEY_NAME$S                                             rawValues:&value
    756 //%                KEY_NAME$S                                               forKeys:&key
    757 //%                KEY_NAME$S                                                 count:1] autorelease];
    758 //%}
    759 //%- (instancetype)initWithValues:(const int32_t [])values
    760 //%                       forKeys:(const KEY_TYPE##KisP$S##KisP [])keys
    761 //%                         count:(NSUInteger)count {
    762 //%  return [self initWithValidationFunction:TestingEnum_IsValidValue
    763 //%                                rawValues:values
    764 //%                                  forKeys:keys
    765 //%                                    count:count];
    766 //%}
    767 //%@end
    768 //%
    769 //%
    770 
    771 
    772 //
    773 // BOOL test macros
    774 //
    775 //TODO(thomasvl): enum tests
    776 
    777 //%PDDM-DEFINE BOOL_TESTS_FOR_POD_VALUE(VALUE_NAME, VALUE_TYPE, VAL1, VAL2)
    778 //%BOOL_TESTS_COMMON(Bool, BOOL, , , YES, NO, VALUE_NAME, VALUE_TYPE, , value, POD, VAL1, VAL2)
    779 
    780 //%PDDM-DEFINE TESTS_FOR_BOOL_KEY_OBJECT_VALUE(VALUE_NAME, VALUE_TYPE, VAL1, VAL2)
    781 //%BOOL_TESTS_COMMON(Bool, BOOL, , , YES, NO, VALUE_NAME, VALUE_TYPE, Objects, object, OBJECT, VAL1, VAL2)
    782 
    783 //%PDDM-DEFINE BOOL_TESTS_COMMON(KEY_NAME, KEY_TYPE, KisP, KSUFFIX, KEY1, KEY2, VALUE_NAME, VALUE_TYPE, VSUFFIX, VNAME, VHELPER, VAL1, VAL2)
    784 //%#pragma mark - KEY_NAME -> VALUE_NAME
    785 //%
    786 //%@interface GPB##KEY_NAME##VALUE_NAME##DictionaryTests : XCTestCase
    787 //%@end
    788 //%
    789 //%@implementation GPB##KEY_NAME##VALUE_NAME##DictionaryTests
    790 //%
    791 //%- (void)testEmpty {
    792 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict = [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] init];
    793 //%  XCTAssertNotNil(dict);
    794 //%  XCTAssertEqual(dict.count, 0U);
    795 //%VALUE_NOT_FOUND##VHELPER(dict, KEY1)
    796 //%  [dict enumerateKeysAnd##VNAME$u##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u##, BOOL *stop) {
    797 //%    #pragma unused(aKey, a##VNAME$u##, stop)
    798 //%    XCTFail(@"Shouldn't get here!");
    799 //%  }];
    800 //%  [dict release];
    801 //%}
    802 //%
    803 //%- (void)testOne {
    804 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict = [GPB##KEY_NAME##VALUE_NAME##Dictionary dictionaryWith##VNAME$u##:VAL1 forKey:KEY1];
    805 //%  XCTAssertNotNil(dict);
    806 //%  XCTAssertEqual(dict.count, 1U);
    807 //%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
    808 //%VALUE_NOT_FOUND##VHELPER(dict, KEY2)
    809 //%  [dict enumerateKeysAnd##VNAME$u##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u, BOOL *stop) {
    810 //%    XCTAssertEqual##KSUFFIX(aKey, KEY1);
    811 //%    XCTAssertEqual##VSUFFIX(a##VNAME$u, VAL1);
    812 //%    XCTAssertNotEqual(stop, NULL);
    813 //%  }];
    814 //%}
    815 //%
    816 //%- (void)testBasics {
    817 //%  const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2 };
    818 //%  const VALUE_TYPE k##VNAME$u##s[] = { VAL1, VAL2 };
    819 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
    820 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s
    821 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##  forKeys:kKeys
    822 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##    count:GPBARRAYSIZE(k##VNAME$u##s)];
    823 //%  XCTAssertNotNil(dict);
    824 //%  XCTAssertEqual(dict.count, 2U);
    825 //%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
    826 //%TEST_VALUE##VHELPER(dict, VNAME, KEY2, VAL2)
    827 //%
    828 //%  __block NSUInteger idx = 0;
    829 //%  KEY_TYPE KisP##*seenKeys = malloc(2 * sizeof(KEY_TYPE##KisP));
    830 //%  VALUE_TYPE *seen##VNAME$u##s = malloc(2 * sizeof(VALUE_TYPE));
    831 //%  [dict enumerateKeysAnd##VNAME$u##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u##, BOOL *stop) {
    832 //%    XCTAssertLessThan(idx, 2U);
    833 //%    seenKeys[idx] = aKey;
    834 //%    seen##VNAME$u##s[idx] = a##VNAME$u;
    835 //%    XCTAssertNotEqual(stop, NULL);
    836 //%    ++idx;
    837 //%  }];
    838 //%  for (int i = 0; i < 2; ++i) {
    839 //%    BOOL foundKey = NO;
    840 //%    for (int j = 0; (j < 2) && !foundKey; ++j) {
    841 //%      if (COMPARE_KEYS##KSUFFIX(kKeys[i], seenKeys[j])) {
    842 //%        foundKey = YES;
    843 //%        XCTAssertEqual##VSUFFIX(k##VNAME$u##s[i], seen##VNAME$u##s[j], @"i = %d, j = %d", i, j);
    844 //%      }
    845 //%    }
    846 //%    XCTAssertTrue(foundKey, @"i = %d", i);
    847 //%  }
    848 //%  free(seenKeys);
    849 //%  free(seen##VNAME$u##s);
    850 //%
    851 //%  // Stopping the enumeration.
    852 //%  idx = 0;
    853 //%  [dict enumerateKeysAnd##VNAME$u##sUsingBlock:^(KEY_TYPE KisP##aKey, VALUE_TYPE a##VNAME$u##, BOOL *stop) {
    854 //%    #pragma unused(aKey, a##VNAME$u)
    855 //%    if (idx == 0) *stop = YES;
    856 //%    XCTAssertNotEqual(idx, 2U);
    857 //%    ++idx;
    858 //%  }];
    859 //%  [dict release];
    860 //%}
    861 //%
    862 //%- (void)testEquality {
    863 //%  const KEY_TYPE KisP##kKeys1[] = { KEY1, KEY2 };
    864 //%  const KEY_TYPE KisP##kKeys2[] = { KEY2, KEY1 };
    865 //%  const VALUE_TYPE k##VNAME$u##s1[] = { VAL1, VAL2 };
    866 //%  const VALUE_TYPE k##VNAME$u##s2[] = { VAL2, VAL1 };
    867 //%  const VALUE_TYPE k##VNAME$u##s3[] = { VAL2 };
    868 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict1 =
    869 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s1
    870 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##  forKeys:kKeys1
    871 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##    count:GPBARRAYSIZE(k##VNAME$u##s1)];
    872 //%  XCTAssertNotNil(dict1);
    873 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict1prime =
    874 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s1
    875 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##  forKeys:kKeys1
    876 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##    count:GPBARRAYSIZE(k##VNAME$u##s1)];
    877 //%  XCTAssertNotNil(dict1prime);
    878 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 =
    879 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s2
    880 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##  forKeys:kKeys1
    881 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##    count:GPBARRAYSIZE(k##VNAME$u##s2)];
    882 //%  XCTAssertNotNil(dict2);
    883 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict3 =
    884 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s1
    885 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##  forKeys:kKeys2
    886 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##    count:GPBARRAYSIZE(k##VNAME$u##s1)];
    887 //%  XCTAssertNotNil(dict3);
    888 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict4 =
    889 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s3
    890 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##  forKeys:kKeys1
    891 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##    count:GPBARRAYSIZE(k##VNAME$u##s3)];
    892 //%  XCTAssertNotNil(dict4);
    893 //%
    894 //%  // 1/1Prime should be different objects, but equal.
    895 //%  XCTAssertNotEqual(dict1, dict1prime);
    896 //%  XCTAssertEqualObjects(dict1, dict1prime);
    897 //%  // Equal, so they must have same hash.
    898 //%  XCTAssertEqual([dict1 hash], [dict1prime hash]);
    899 //%
    900 //%  // 2 is same keys, different ##VNAME##s; not equal.
    901 //%  XCTAssertNotEqualObjects(dict1, dict2);
    902 //%
    903 //%  // 3 is different keys, same ##VNAME##s; not equal.
    904 //%  XCTAssertNotEqualObjects(dict1, dict3);
    905 //%
    906 //%  // 4 Fewer pairs; not equal
    907 //%  XCTAssertNotEqualObjects(dict1, dict4);
    908 //%
    909 //%  [dict1 release];
    910 //%  [dict1prime release];
    911 //%  [dict2 release];
    912 //%  [dict3 release];
    913 //%  [dict4 release];
    914 //%}
    915 //%
    916 //%- (void)testCopy {
    917 //%  const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2 };
    918 //%  const VALUE_TYPE k##VNAME$u##s[] = { VAL1, VAL2 };
    919 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
    920 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s
    921 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##  forKeys:kKeys
    922 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##    count:GPBARRAYSIZE(k##VNAME$u##s)];
    923 //%  XCTAssertNotNil(dict);
    924 //%
    925 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 = [dict copy];
    926 //%  XCTAssertNotNil(dict2);
    927 //%
    928 //%  // Should be new object but equal.
    929 //%  XCTAssertNotEqual(dict, dict2);
    930 //%  XCTAssertEqualObjects(dict, dict2);
    931 //%  XCTAssertTrue([dict2 isKindOfClass:[GPB##KEY_NAME##VALUE_NAME##Dictionary class]]);
    932 //%
    933 //%  [dict2 release];
    934 //%  [dict release];
    935 //%}
    936 //%
    937 //%- (void)testDictionaryFromDictionary {
    938 //%  const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2 };
    939 //%  const VALUE_TYPE k##VNAME$u##s[] = { VAL1, VAL2 };
    940 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
    941 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s
    942 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##  forKeys:kKeys
    943 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##    count:GPBARRAYSIZE(k##VNAME$u##s)];
    944 //%  XCTAssertNotNil(dict);
    945 //%
    946 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 =
    947 //%      [GPB##KEY_NAME##VALUE_NAME##Dictionary dictionaryWithDictionary:dict];
    948 //%  XCTAssertNotNil(dict2);
    949 //%
    950 //%  // Should be new pointer, but equal objects.
    951 //%  XCTAssertNotEqual(dict, dict2);
    952 //%  XCTAssertEqualObjects(dict, dict2);
    953 //%  [dict release];
    954 //%}
    955 //%
    956 //%- (void)testAdds {
    957 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict = [GPB##KEY_NAME##VALUE_NAME##Dictionary dictionary];
    958 //%  XCTAssertNotNil(dict);
    959 //%
    960 //%  XCTAssertEqual(dict.count, 0U);
    961 //%  [dict set##VNAME$u:VAL1 forKey:KEY1];
    962 //%  XCTAssertEqual(dict.count, 1U);
    963 //%
    964 //%  const KEY_TYPE KisP##kKeys[] = { KEY2 };
    965 //%  const VALUE_TYPE k##VNAME$u##s[] = { VAL2 };
    966 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 =
    967 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s
    968 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##  forKeys:kKeys
    969 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##    count:GPBARRAYSIZE(k##VNAME$u##s)];
    970 //%  XCTAssertNotNil(dict2);
    971 //%  [dict addEntriesFromDictionary:dict2];
    972 //%  XCTAssertEqual(dict.count, 2U);
    973 //%
    974 //%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
    975 //%TEST_VALUE##VHELPER(dict, VNAME, KEY2, VAL2)
    976 //%  [dict2 release];
    977 //%}
    978 //%
    979 //%- (void)testRemove {
    980 //%  const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2};
    981 //%  const VALUE_TYPE k##VNAME$u##s[] = { VAL1, VAL2 };
    982 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
    983 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s
    984 //%           KEY_NAME$S VALUE_NAME$S          ##VNAME$S##  forKeys:kKeys
    985 //%           KEY_NAME$S VALUE_NAME$S          ##VNAME$S##    count:GPBARRAYSIZE(k##VNAME$u##s)];
    986 //%  XCTAssertNotNil(dict);
    987 //%  XCTAssertEqual(dict.count, 2U);
    988 //%
    989 //%  [dict remove##VNAME$u##ForKey:KEY2];
    990 //%  XCTAssertEqual(dict.count, 1U);
    991 //%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
    992 //%VALUE_NOT_FOUND##VHELPER(dict, KEY2)
    993 //%
    994 //%  // Remove again does nothing.
    995 //%  [dict remove##VNAME$u##ForKey:KEY2];
    996 //%  XCTAssertEqual(dict.count, 1U);
    997 //%TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
    998 //%VALUE_NOT_FOUND##VHELPER(dict, KEY2)
    999 //%
   1000 //%  [dict removeAll];
   1001 //%  XCTAssertEqual(dict.count, 0U);
   1002 //%VALUE_NOT_FOUND##VHELPER(dict, KEY1)
   1003 //%VALUE_NOT_FOUND##VHELPER(dict, KEY2)
   1004 //%  [dict release];
   1005 //%}
   1006 //%
   1007 //%- (void)testInplaceMutation {
   1008 //%  const KEY_TYPE KisP##kKeys[] = { KEY1, KEY2 };
   1009 //%  const VALUE_TYPE k##VNAME$u##s[] = { VAL1, VAL2 };
   1010 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict =
   1011 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s
   1012 //%           KEY_NAME$S VALUE_NAME$S          ##VNAME$S##  forKeys:kKeys
   1013 //%           KEY_NAME$S VALUE_NAME$S          ##VNAME$S##    count:GPBARRAYSIZE(k##VNAME$u##s)];
   1014 //%  XCTAssertNotNil(dict);
   1015 //%  XCTAssertEqual(dict.count, 2U);
   1016 //%DECLARE_VALUE_STORAGE##VHELPER(VALUE_TYPE, VNAME)TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
   1017 //%TEST_VALUE##VHELPER(dict, VNAME, KEY2, VAL2)
   1018 //%
   1019 //%  [dict set##VNAME$u##:VAL2 forKey:KEY1];
   1020 //%  XCTAssertEqual(dict.count, 2U);
   1021 //%TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL2)
   1022 //%TEST_VALUE##VHELPER(dict, VNAME, KEY2, VAL2)
   1023 //%
   1024 //%  [dict set##VNAME$u##:VAL1 forKey:KEY2];
   1025 //%  XCTAssertEqual(dict.count, 2U);
   1026 //%TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL2)
   1027 //%TEST_VALUE##VHELPER(dict, VNAME, KEY2, VAL1)
   1028 //%
   1029 //%  const KEY_TYPE KisP##kKeys2[] = { KEY2, KEY1 };
   1030 //%  const VALUE_TYPE k##VNAME$u##s2[] = { VAL2, VAL1 };
   1031 //%  DICTIONARY_CLASS_DECL##VHELPER(KEY_NAME, VALUE_NAME, VALUE_TYPE) *dict2 =
   1032 //%      [[GPB##KEY_NAME##VALUE_NAME##Dictionary alloc] initWith##VNAME$u##s:k##VNAME$u##s2
   1033 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##  forKeys:kKeys2
   1034 //%           KEY_NAME$S VALUE_NAME$S                 ##VNAME$S##    count:GPBARRAYSIZE(k##VNAME$u##s2)];
   1035 //%  XCTAssertNotNil(dict2);
   1036 //%  [dict addEntriesFromDictionary:dict2];
   1037 //%  XCTAssertEqual(dict.count, 2U);
   1038 //%TEST_VALUE##VHELPER(dict, VNAME, KEY1, VAL1)
   1039 //%TEST_VALUE##VHELPER(dict, VNAME, KEY2, VAL2)
   1040 //%
   1041 //%  [dict2 release];
   1042 //%  [dict release];
   1043 //%}
   1044 //%
   1045 //%@end
   1046 //%
   1047 
   1048