YYTestClassInfo.m 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. //
  2. // YYTestClassInfo.m
  3. // YYModel <https://github.com/ibireme/YYModel>
  4. //
  5. // Created by ibireme on 15/11/27.
  6. // Copyright (c) 2015 ibireme.
  7. //
  8. // This source code is licensed under the MIT-style license found in the
  9. // LICENSE file in the root directory of this source tree.
  10. //
  11. #import <XCTest/XCTest.h>
  12. #import <CoreFoundation/CoreFoundation.h>
  13. #import "YYModel.h"
  14. typedef union yy_union{ char a; int b;} yy_union;
  15. @interface YYTestPropertyModel : NSObject
  16. @property bool boolValue;
  17. @property BOOL BOOLValue;
  18. @property char charValue;
  19. @property unsigned char unsignedCharValue;
  20. @property short shortValue;
  21. @property unsigned short unsignedShortValue;
  22. @property int intValue;
  23. @property unsigned int unsignedIntValue;
  24. @property long longValue;
  25. @property unsigned long unsignedLongValue;
  26. @property long long longLongValue;
  27. @property unsigned long long unsignedLongLongValue;
  28. @property float floatValue;
  29. @property double doubleValue;
  30. @property long double longDoubleValue;
  31. @property (strong) NSObject *objectValue;
  32. @property (strong) NSArray *arrayValue;
  33. @property (strong) Class classValue;
  34. @property SEL selectorValue;
  35. @property (copy) void (^blockValue)();
  36. @property void *pointerValue;
  37. @property CFArrayEqualCallBack functionPointerValue;
  38. @property CGRect structValue;
  39. @property yy_union unionValue;
  40. @property char *cStringValue;
  41. @property (nonatomic) NSObject *nonatomicValue;
  42. @property (copy) NSObject *aCopyValue;
  43. @property (assign) NSObject *assignValue;
  44. @property (strong) NSObject *strongValue;
  45. @property (retain) NSObject *retainValue;
  46. @property (weak) NSObject *weakValue;
  47. @property (readonly) NSObject *readonlyValue;
  48. @property (nonatomic) NSObject *dynamicValue;
  49. @property (unsafe_unretained) NSObject *unsafeValue;
  50. @property (nonatomic, getter=getValue) NSObject *getterValue;
  51. @property (nonatomic, setter=setValue:) NSObject *setterValue;
  52. @end
  53. @implementation YYTestPropertyModel {
  54. const NSObject *_constValue;
  55. }
  56. @dynamic dynamicValue;
  57. - (NSObject *)getValue {
  58. return _getterValue;
  59. }
  60. - (void)setValue:(NSObject *)value {
  61. _setterValue = value;
  62. }
  63. - (void)testConst:(const NSObject *)value {}
  64. - (void)testIn:(in NSObject *)value {}
  65. - (void)testOut:(out NSObject *)value {}
  66. - (void)testInout:(inout NSObject *)value {}
  67. - (void)testBycopy:(bycopy NSObject *)value {}
  68. - (void)testByref:(byref NSObject *)value {}
  69. - (void)testOneway:(oneway NSObject *)value {}
  70. @end
  71. @interface YYTestClassInfo : XCTestCase
  72. @end
  73. @implementation YYTestClassInfo
  74. - (void)testClassInfoCache {
  75. YYClassInfo *info1 = [YYClassInfo classInfoWithClass:[YYTestPropertyModel class]];
  76. [info1 setNeedUpdate];
  77. YYClassInfo *info2 = [YYClassInfo classInfoWithClassName:@"YYTestPropertyModel"];
  78. XCTAssertNotNil(info1);
  79. XCTAssertNotNil(info2);
  80. XCTAssertEqual(info1, info2);
  81. }
  82. - (void)testClassMeta {
  83. YYClassInfo *classInfo = [YYClassInfo classInfoWithClass:[YYTestPropertyModel class]];
  84. XCTAssertNotNil(classInfo);
  85. XCTAssertEqual(classInfo.cls, [YYTestPropertyModel class]);
  86. XCTAssertEqual(classInfo.superCls, [NSObject class]);
  87. XCTAssertEqual(classInfo.metaCls, objc_getMetaClass("YYTestPropertyModel"));
  88. XCTAssertEqual(classInfo.isMeta, NO);
  89. Class meta = object_getClass([YYTestPropertyModel class]);
  90. YYClassInfo *metaClassInfo = [YYClassInfo classInfoWithClass:meta];
  91. XCTAssertNotNil(metaClassInfo);
  92. XCTAssertEqual(metaClassInfo.cls, meta);
  93. XCTAssertEqual(metaClassInfo.superCls, object_getClass([NSObject class]));
  94. XCTAssertEqual(metaClassInfo.metaCls, nil);
  95. XCTAssertEqual(metaClassInfo.isMeta, YES);
  96. }
  97. - (void)testClassInfo {
  98. YYClassInfo *info = [YYClassInfo classInfoWithClass:[YYTestPropertyModel class]];
  99. XCTAssertEqual([self getType:info name:@"boolValue"] & YYEncodingTypeMask, YYEncodingTypeBool);
  100. #ifdef OBJC_BOOL_IS_BOOL
  101. XCTAssertEqual([self getType:info name:@"BOOLValue"] & YYEncodingTypeMask, YYEncodingTypeBool);
  102. #else
  103. XCTAssertEqual([self getType:info name:@"BOOLValue"] & YYEncodingTypeMask, YYEncodingTypeInt8);
  104. #endif
  105. XCTAssertEqual([self getType:info name:@"charValue"] & YYEncodingTypeMask, YYEncodingTypeInt8);
  106. XCTAssertEqual([self getType:info name:@"unsignedCharValue"] & YYEncodingTypeMask, YYEncodingTypeUInt8);
  107. XCTAssertEqual([self getType:info name:@"shortValue"] & YYEncodingTypeMask, YYEncodingTypeInt16);
  108. XCTAssertEqual([self getType:info name:@"unsignedShortValue"] & YYEncodingTypeMask, YYEncodingTypeUInt16);
  109. XCTAssertEqual([self getType:info name:@"intValue"] & YYEncodingTypeMask, YYEncodingTypeInt32);
  110. XCTAssertEqual([self getType:info name:@"unsignedIntValue"] & YYEncodingTypeMask, YYEncodingTypeUInt32);
  111. #ifdef __LP64__
  112. XCTAssertEqual([self getType:info name:@"longValue"] & YYEncodingTypeMask, YYEncodingTypeInt64);
  113. XCTAssertEqual([self getType:info name:@"unsignedLongValue"] & YYEncodingTypeMask, YYEncodingTypeUInt64);
  114. XCTAssertEqual(YYEncodingGetType("l") & YYEncodingTypeMask, YYEncodingTypeInt32); // long in 32 bit system
  115. XCTAssertEqual(YYEncodingGetType("L") & YYEncodingTypeMask, YYEncodingTypeUInt32); // unsingle long in 32 bit system
  116. #else
  117. XCTAssertEqual([self getType:info name:@"longValue"] & YYEncodingTypeMask, YYEncodingTypeInt32);
  118. XCTAssertEqual([self getType:info name:@"unsignedLongValue"] & YYEncodingTypeMask, YYEncodingTypeUInt32);
  119. #endif
  120. XCTAssertEqual([self getType:info name:@"longLongValue"] & YYEncodingTypeMask, YYEncodingTypeInt64);
  121. XCTAssertEqual([self getType:info name:@"unsignedLongLongValue"] & YYEncodingTypeMask, YYEncodingTypeUInt64);
  122. XCTAssertEqual([self getType:info name:@"floatValue"] & YYEncodingTypeMask, YYEncodingTypeFloat);
  123. XCTAssertEqual([self getType:info name:@"doubleValue"] & YYEncodingTypeMask, YYEncodingTypeDouble);
  124. XCTAssertEqual([self getType:info name:@"longDoubleValue"] & YYEncodingTypeMask, YYEncodingTypeLongDouble);
  125. XCTAssertEqual([self getType:info name:@"objectValue"] & YYEncodingTypeMask, YYEncodingTypeObject);
  126. XCTAssertEqual([self getType:info name:@"arrayValue"] & YYEncodingTypeMask, YYEncodingTypeObject);
  127. XCTAssertEqual([self getType:info name:@"classValue"] & YYEncodingTypeMask, YYEncodingTypeClass);
  128. XCTAssertEqual([self getType:info name:@"selectorValue"] & YYEncodingTypeMask, YYEncodingTypeSEL);
  129. XCTAssertEqual([self getType:info name:@"blockValue"] & YYEncodingTypeMask, YYEncodingTypeBlock);
  130. XCTAssertEqual([self getType:info name:@"pointerValue"] & YYEncodingTypeMask, YYEncodingTypePointer);
  131. XCTAssertEqual([self getType:info name:@"functionPointerValue"] & YYEncodingTypeMask, YYEncodingTypePointer);
  132. XCTAssertEqual([self getType:info name:@"structValue"] & YYEncodingTypeMask, YYEncodingTypeStruct);
  133. XCTAssertEqual([self getType:info name:@"unionValue"] & YYEncodingTypeMask, YYEncodingTypeUnion);
  134. XCTAssertEqual([self getType:info name:@"cStringValue"] & YYEncodingTypeMask, YYEncodingTypeCString);
  135. XCTAssertEqual(YYEncodingGetType(@encode(void)) & YYEncodingTypeMask, YYEncodingTypeVoid);
  136. XCTAssertEqual(YYEncodingGetType(@encode(int[10])) & YYEncodingTypeMask, YYEncodingTypeCArray);
  137. XCTAssertEqual(YYEncodingGetType("") & YYEncodingTypeMask, YYEncodingTypeUnknown);
  138. XCTAssertEqual(YYEncodingGetType(".") & YYEncodingTypeMask, YYEncodingTypeUnknown);
  139. XCTAssertEqual(YYEncodingGetType("ri") & YYEncodingTypeQualifierMask, YYEncodingTypeQualifierConst);
  140. XCTAssertEqual([self getMethodTypeWithName:@"testIn:"] & YYEncodingTypeQualifierMask, YYEncodingTypeQualifierIn);
  141. XCTAssertEqual([self getMethodTypeWithName:@"testOut:"] & YYEncodingTypeQualifierMask, YYEncodingTypeQualifierOut);
  142. XCTAssertEqual([self getMethodTypeWithName:@"testInout:"] & YYEncodingTypeQualifierMask, YYEncodingTypeQualifierInout);
  143. XCTAssertEqual([self getMethodTypeWithName:@"testBycopy:"] & YYEncodingTypeQualifierMask, YYEncodingTypeQualifierBycopy);
  144. XCTAssertEqual([self getMethodTypeWithName:@"testByref:"] & YYEncodingTypeQualifierMask, YYEncodingTypeQualifierByref);
  145. XCTAssertEqual([self getMethodTypeWithName:@"testOneway:"] & YYEncodingTypeQualifierMask, YYEncodingTypeQualifierOneway);
  146. XCTAssert([self getType:info name:@"nonatomicValue"] & YYEncodingTypePropertyMask &YYEncodingTypePropertyNonatomic);
  147. XCTAssert([self getType:info name:@"aCopyValue"] & YYEncodingTypePropertyMask & YYEncodingTypePropertyCopy);
  148. XCTAssert([self getType:info name:@"strongValue"] & YYEncodingTypePropertyMask & YYEncodingTypePropertyRetain);
  149. XCTAssert([self getType:info name:@"retainValue"] & YYEncodingTypePropertyMask & YYEncodingTypePropertyRetain);
  150. XCTAssert([self getType:info name:@"weakValue"] & YYEncodingTypePropertyMask & YYEncodingTypePropertyWeak);
  151. XCTAssert([self getType:info name:@"readonlyValue"] & YYEncodingTypePropertyMask & YYEncodingTypePropertyReadonly);
  152. XCTAssert([self getType:info name:@"dynamicValue"] & YYEncodingTypePropertyMask & YYEncodingTypePropertyDynamic);
  153. XCTAssert([self getType:info name:@"getterValue"] & YYEncodingTypePropertyMask &YYEncodingTypePropertyCustomGetter);
  154. XCTAssert([self getType:info name:@"setterValue"] & YYEncodingTypePropertyMask & YYEncodingTypePropertyCustomSetter);
  155. }
  156. - (YYEncodingType)getType:(YYClassInfo *)info name:(NSString *)name {
  157. return ((YYClassPropertyInfo *)info.propertyInfos[name]).type;
  158. }
  159. - (YYEncodingType)getMethodTypeWithName:(NSString *)name {
  160. YYTestPropertyModel *model = [YYTestPropertyModel new];
  161. NSMethodSignature *sig = [model methodSignatureForSelector:NSSelectorFromString(name)];
  162. const char *typeName = [sig getArgumentTypeAtIndex:2];
  163. return YYEncodingGetType(typeName);
  164. }
  165. @end