weak.m 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. // See instructions in weak.h
  2. #include "test.h"
  3. #include "weak.h"
  4. // Subclass of superclass that isn't there
  5. @interface MyMissingSuper : MissingSuper
  6. +(int) method;
  7. @end
  8. @implementation MyMissingSuper
  9. +(int) method { return 1+[super method]; }
  10. +(void) load { state++; }
  11. @end
  12. // Subclass of subclass of superclass that isn't there
  13. @interface MyMissingSub : MyMissingSuper
  14. +(int) method;
  15. @end
  16. @implementation MyMissingSub
  17. +(int) method { return 1+[super method]; }
  18. +(void) load { state++; }
  19. @end
  20. // Subclass of real superclass
  21. @interface MyNotMissingSuper : NotMissingSuper
  22. +(int) method;
  23. @end
  24. @implementation MyNotMissingSuper
  25. +(int) method { return 1+[super method]; }
  26. +(void) load { state++; }
  27. @end
  28. // Subclass of subclass of superclass that isn't there
  29. @interface MyNotMissingSub : MyNotMissingSuper
  30. +(int) method;
  31. @end
  32. @implementation MyNotMissingSub
  33. +(int) method { return 1+[super method]; }
  34. +(void) load { state++; }
  35. @end
  36. // Categories on all of the above
  37. @interface MissingRoot (MissingRootExtras)
  38. +(void)load;
  39. +(int) cat_method;
  40. @end
  41. @implementation MissingRoot (MissingRootExtras)
  42. +(void)load { state++; }
  43. +(int) cat_method { return 40; }
  44. @end
  45. @interface MissingSuper (MissingSuperExtras)
  46. +(void)load;
  47. +(int) cat_method;
  48. @end
  49. @implementation MissingSuper (MissingSuperExtras)
  50. +(void)load { state++; }
  51. +(int) cat_method { return 1+[super cat_method]; }
  52. @end
  53. @interface MyMissingSuper (MyMissingSuperExtras)
  54. +(void)load;
  55. +(int) cat_method;
  56. @end
  57. @implementation MyMissingSuper (MyMissingSuperExtras)
  58. +(void)load { state++; }
  59. +(int) cat_method { return 1+[super cat_method]; }
  60. @end
  61. @interface MyMissingSub (MyMissingSubExtras)
  62. +(void)load;
  63. +(int) cat_method;
  64. @end
  65. @implementation MyMissingSub (MyMissingSubExtras)
  66. +(void)load { state++; }
  67. +(int) cat_method { return 1+[super cat_method]; }
  68. @end
  69. @interface NotMissingRoot (NotMissingRootExtras)
  70. +(void)load;
  71. +(int) cat_method;
  72. @end
  73. @implementation NotMissingRoot (NotMissingRootExtras)
  74. +(void)load { state++; }
  75. +(int) cat_method { return 30; }
  76. @end
  77. @interface NotMissingSuper (NotMissingSuperExtras)
  78. +(void)load;
  79. +(int) cat_method;
  80. @end
  81. @implementation NotMissingSuper (NotMissingSuperExtras)
  82. +(void)load { state++; }
  83. +(int) cat_method { return 1+[super cat_method]; }
  84. @end
  85. @interface MyNotMissingSuper (MyNotMissingSuperExtras)
  86. +(void)load;
  87. +(int) cat_method;
  88. @end
  89. @implementation MyNotMissingSuper (MyNotMissingSuperExtras)
  90. +(void)load { state++; }
  91. +(int) cat_method { return 1+[super cat_method]; }
  92. @end
  93. @interface MyNotMissingSub (MyNotMissingSubExtras)
  94. +(void)load;
  95. +(int) cat_method;
  96. @end
  97. @implementation MyNotMissingSub (MyNotMissingSubExtras)
  98. +(void)load { state++; }
  99. +(int) cat_method { return 1+[super cat_method]; }
  100. @end
  101. #if WEAK_FRAMEWORK
  102. # define TESTIVAR(cond) testassert(cond)
  103. #else
  104. # define TESTIVAR(cond) /* rdar */
  105. #endif
  106. static BOOL classInList(__unsafe_unretained Class classes[], const char *name)
  107. {
  108. for (int i = 0; classes[i] != nil; i++) {
  109. if (0 == strcmp(class_getName(classes[i]), name)) return YES;
  110. }
  111. return NO;
  112. }
  113. static BOOL classInNameList(const char **names, const char *name)
  114. {
  115. const char **cp;
  116. for (cp = names; *cp; cp++) {
  117. if (0 == strcmp(*cp, name)) return YES;
  118. }
  119. return NO;
  120. }
  121. int main(int argc __unused, char **argv)
  122. {
  123. BOOL weakMissing;
  124. if (strstr(argv[0], "-not-missing.exe")) {
  125. weakMissing = NO;
  126. } else if (strstr(argv[0], "-missing.exe")) {
  127. weakMissing = YES;
  128. } else {
  129. fail("executable name must be weak*-missing.exe or weak*-not-missing.exe");
  130. }
  131. // class and category +load methods
  132. if (weakMissing) testassert(state == 8);
  133. else testassert(state == 16);
  134. state = 0;
  135. // classes
  136. testassert([NotMissingRoot class]);
  137. testassert([NotMissingSuper class]);
  138. testassert([MyNotMissingSuper class]);
  139. testassert([MyNotMissingSub class]);
  140. if (weakMissing) {
  141. testassert([MissingRoot class] == nil);
  142. testassert([MissingSuper class] == nil);
  143. testassert([MyMissingSuper class] == nil);
  144. testassert([MyMissingSub class] == nil);
  145. } else {
  146. testassert([MissingRoot class]);
  147. testassert([MissingSuper class]);
  148. testassert([MyMissingSuper class]);
  149. testassert([MyMissingSub class]);
  150. }
  151. // objc_getClass
  152. testassert(objc_getClass("NotMissingRoot"));
  153. testassert(objc_getClass("NotMissingSuper"));
  154. testassert(objc_getClass("MyNotMissingSuper"));
  155. testassert(objc_getClass("MyNotMissingSub"));
  156. if (weakMissing) {
  157. testassert(objc_getClass("MissingRoot") == nil);
  158. testassert(objc_getClass("MissingSuper") == nil);
  159. testassert(objc_getClass("MyMissingSuper") == nil);
  160. testassert(objc_getClass("MyMissingSub") == nil);
  161. } else {
  162. testassert(objc_getClass("MissingRoot"));
  163. testassert(objc_getClass("MissingSuper"));
  164. testassert(objc_getClass("MyMissingSuper"));
  165. testassert(objc_getClass("MyMissingSub"));
  166. }
  167. // class list
  168. union {
  169. Class *c;
  170. void *v;
  171. } classes;
  172. classes.c = objc_copyClassList(NULL);
  173. testassert(classInList(classes.c, "NotMissingRoot"));
  174. testassert(classInList(classes.c, "NotMissingSuper"));
  175. testassert(classInList(classes.c, "MyNotMissingSuper"));
  176. testassert(classInList(classes.c, "MyNotMissingSub"));
  177. if (weakMissing) {
  178. testassert(! classInList(classes.c, "MissingRoot"));
  179. testassert(! classInList(classes.c, "MissingSuper"));
  180. testassert(! classInList(classes.c, "MyMissingSuper"));
  181. testassert(! classInList(classes.c, "MyMissingSub"));
  182. } else {
  183. testassert(classInList(classes.c, "MissingRoot"));
  184. testassert(classInList(classes.c, "MissingSuper"));
  185. testassert(classInList(classes.c, "MyMissingSuper"));
  186. testassert(classInList(classes.c, "MyMissingSub"));
  187. }
  188. free(classes.v);
  189. // class name list
  190. const char *image = class_getImageName(objc_getClass("NotMissingRoot"));
  191. testassert(image);
  192. const char **names = objc_copyClassNamesForImage(image, NULL);
  193. testassert(names);
  194. testassert(classInNameList(names, "NotMissingRoot"));
  195. testassert(classInNameList(names, "NotMissingSuper"));
  196. if (weakMissing) {
  197. testassert(! classInNameList(names, "MissingRoot"));
  198. testassert(! classInNameList(names, "MissingSuper"));
  199. } else {
  200. testassert(classInNameList(names, "MissingRoot"));
  201. testassert(classInNameList(names, "MissingSuper"));
  202. }
  203. free(names);
  204. image = class_getImageName(objc_getClass("MyNotMissingSub"));
  205. testassert(image);
  206. names = objc_copyClassNamesForImage(image, NULL);
  207. testassert(names);
  208. testassert(classInNameList(names, "MyNotMissingSuper"));
  209. testassert(classInNameList(names, "MyNotMissingSub"));
  210. if (weakMissing) {
  211. testassert(! classInNameList(names, "MyMissingSuper"));
  212. testassert(! classInNameList(names, "MyMissingSub"));
  213. } else {
  214. testassert(classInNameList(names, "MyMissingSuper"));
  215. testassert(classInNameList(names, "MyMissingSub"));
  216. }
  217. free(names);
  218. // methods
  219. testassert(20 == [NotMissingRoot method]);
  220. testassert(21 == [NotMissingSuper method]);
  221. testassert(22 == [MyNotMissingSuper method]);
  222. testassert(23 == [MyNotMissingSub method]);
  223. if (weakMissing) {
  224. testassert(0 == [MissingRoot method]);
  225. testassert(0 == [MissingSuper method]);
  226. testassert(0 == [MyMissingSuper method]);
  227. testassert(0 == [MyMissingSub method]);
  228. } else {
  229. testassert(10 == [MissingRoot method]);
  230. testassert(11 == [MissingSuper method]);
  231. testassert(12 == [MyMissingSuper method]);
  232. testassert(13 == [MyMissingSub method]);
  233. }
  234. // category methods
  235. testassert(30 == [NotMissingRoot cat_method]);
  236. testassert(31 == [NotMissingSuper cat_method]);
  237. testassert(32 == [MyNotMissingSuper cat_method]);
  238. testassert(33 == [MyNotMissingSub cat_method]);
  239. if (weakMissing) {
  240. testassert(0 == [MissingRoot cat_method]);
  241. testassert(0 == [MissingSuper cat_method]);
  242. testassert(0 == [MyMissingSuper cat_method]);
  243. testassert(0 == [MyMissingSub cat_method]);
  244. } else {
  245. testassert(40 == [MissingRoot cat_method]);
  246. testassert(41 == [MissingSuper cat_method]);
  247. testassert(42 == [MyMissingSuper cat_method]);
  248. testassert(43 == [MyMissingSub cat_method]);
  249. }
  250. // allocations and ivars
  251. id obj;
  252. NotMissingSuper *obj2;
  253. MissingSuper *obj3;
  254. testassert((obj = [[NotMissingRoot alloc] init]));
  255. RELEASE_VAR(obj);
  256. testassert((obj2 = [[NotMissingSuper alloc] init]));
  257. TESTIVAR(obj2->ivar == 200);
  258. RELEASE_VAR(obj2);
  259. testassert((obj2 = [[MyNotMissingSuper alloc] init]));
  260. TESTIVAR(obj2->ivar == 200);
  261. RELEASE_VAR(obj2);
  262. testassert((obj2 = [[MyNotMissingSub alloc] init]));
  263. TESTIVAR(obj2->ivar == 200);
  264. RELEASE_VAR(obj2);
  265. if (weakMissing) {
  266. testassert([[MissingRoot alloc] init] == nil);
  267. testassert([[MissingSuper alloc] init] == nil);
  268. testassert([[MyMissingSuper alloc] init] == nil);
  269. testassert([[MyMissingSub alloc] init] == nil);
  270. } else {
  271. testassert((obj = [[MissingRoot alloc] init]));
  272. RELEASE_VAR(obj);
  273. testassert((obj3 = [[MissingSuper alloc] init]));
  274. TESTIVAR(obj3->ivar == 100);
  275. RELEASE_VAR(obj3);
  276. testassert((obj3 = [[MyMissingSuper alloc] init]));
  277. TESTIVAR(obj3->ivar == 100);
  278. RELEASE_VAR(obj3);
  279. testassert((obj3 = [[MyMissingSub alloc] init]));
  280. TESTIVAR(obj3->ivar == 100);
  281. RELEASE_VAR(obj3);
  282. }
  283. *strrchr(argv[0], '.') = 0;
  284. succeed(basename(argv[0]));
  285. return 0;
  286. }