copyPropertyList.m 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. // TEST_CONFIG
  2. #include "test.h"
  3. #include <string.h>
  4. #include <malloc/malloc.h>
  5. #include <objc/objc-runtime.h>
  6. OBJC_ROOT_CLASS
  7. @interface SuperProps { id isa; int prop1; int prop2; }
  8. @property int prop1;
  9. @property int prop2;
  10. @end
  11. @implementation SuperProps
  12. @synthesize prop1;
  13. @synthesize prop2;
  14. @end
  15. @interface SubProps : SuperProps { int prop3; int prop4; }
  16. @property int prop3;
  17. @property int prop4;
  18. @end
  19. @implementation SubProps
  20. @synthesize prop3;
  21. @synthesize prop4;
  22. @end
  23. OBJC_ROOT_CLASS
  24. @interface FourProps { int prop1; int prop2; int prop3; int prop4; }
  25. @property int prop1;
  26. @property int prop2;
  27. @property int prop3;
  28. @property int prop4;
  29. @end
  30. @implementation FourProps
  31. @synthesize prop1;
  32. @synthesize prop2;
  33. @synthesize prop3;
  34. @synthesize prop4;
  35. @end
  36. OBJC_ROOT_CLASS
  37. @interface NoProps @end
  38. @implementation NoProps @end
  39. OBJC_ROOT_CLASS
  40. @interface ClassProps
  41. @property(readonly,class) int prop1;
  42. @property(readonly,class) int prop2;
  43. @property(readonly) int prop2;
  44. @property(readonly) int prop3;
  45. @end
  46. @implementation ClassProps
  47. +(int)prop1 { return 0; }
  48. +(int)prop2 { return 0; }
  49. -(int)prop2 { return 0; }
  50. -(int)prop3 { return 0; }
  51. @end
  52. static int isNamed(objc_property_t p, const char *name)
  53. {
  54. return (0 == strcmp(name, property_getName(p)));
  55. }
  56. int main()
  57. {
  58. objc_property_t *props;
  59. unsigned int count;
  60. Class cls;
  61. cls = objc_getClass("SubProps");
  62. testassert(cls);
  63. count = 100;
  64. props = class_copyPropertyList(cls, &count);
  65. testassert(props);
  66. testassert(count == 2);
  67. testassert((isNamed(props[0], "prop3") && isNamed(props[1], "prop4")) ||
  68. (isNamed(props[1], "prop3") && isNamed(props[0], "prop4")));
  69. // props[] should be null-terminated
  70. testassert(props[2] == NULL);
  71. free(props);
  72. cls = objc_getClass("SuperProps");
  73. testassert(cls);
  74. count = 100;
  75. props = class_copyPropertyList(cls, &count);
  76. testassert(props);
  77. testassert(count == 2);
  78. testassert((isNamed(props[0], "prop1") && isNamed(props[1], "prop2")) ||
  79. (isNamed(props[1], "prop1") && isNamed(props[0], "prop2")));
  80. // props[] should be null-terminated
  81. testassert(props[2] == NULL);
  82. free(props);
  83. // Check null-termination - this property list block would be 16 bytes
  84. // if it weren't for the terminator
  85. cls = objc_getClass("FourProps");
  86. testassert(cls);
  87. count = 100;
  88. props = class_copyPropertyList(cls, &count);
  89. testassert(props);
  90. testassert(count == 4);
  91. testassert(malloc_size(props) >= 5 * sizeof(objc_property_t));
  92. testassert(props[3] != NULL);
  93. testassert(props[4] == NULL);
  94. free(props);
  95. // Check NULL count parameter
  96. props = class_copyPropertyList(cls, NULL);
  97. testassert(props);
  98. testassert(props[4] == NULL);
  99. testassert(props[3] != NULL);
  100. free(props);
  101. // Check NULL class parameter
  102. count = 100;
  103. props = class_copyPropertyList(NULL, &count);
  104. testassert(!props);
  105. testassert(count == 0);
  106. // Check NULL class and count
  107. props = class_copyPropertyList(NULL, NULL);
  108. testassert(!props);
  109. // Check class with no properties
  110. cls = objc_getClass("NoProps");
  111. testassert(cls);
  112. count = 100;
  113. props = class_copyPropertyList(cls, &count);
  114. testassert(!props);
  115. testassert(count == 0);
  116. // Check class properties
  117. cls = objc_getClass("ClassProps");
  118. testassert(cls);
  119. count = 100;
  120. props = class_copyPropertyList(cls, &count);
  121. testassert(props);
  122. testassert(count == 2);
  123. testassert((isNamed(props[0], "prop2") && isNamed(props[1], "prop3")) ||
  124. (isNamed(props[1], "prop2") && isNamed(props[0], "prop3")));
  125. // props[] should be null-terminated
  126. testassert(props[2] == NULL);
  127. free(props);
  128. cls = object_getClass(objc_getClass("ClassProps"));
  129. testassert(cls);
  130. count = 100;
  131. props = class_copyPropertyList(cls, &count);
  132. testassert(props);
  133. testassert(count == 2);
  134. testassert((isNamed(props[0], "prop1") && isNamed(props[1], "prop2")) ||
  135. (isNamed(props[1], "prop1") && isNamed(props[0], "prop2")));
  136. // props[] should be null-terminated
  137. testassert(props[2] == NULL);
  138. free(props);
  139. succeed(__FILE__);
  140. return 0;
  141. }