GPBDictionaryTests.pddm 50 KB

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