libObjCAttrTests/ReflectionTest/Classes/RFPropertyInfoTest.m (108 lines of code) (raw):

// // RFPropertyInfoTest.m // libObjCAttr // // Copyright (c) 2014 EPAM Systems, Inc. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // Redistributions in binary form must reproduce the above copyright notice, this // list of conditions and the following disclaimer in the documentation and/or // other materials provided with the distribution. // Neither the name of the EPAM Systems, Inc. nor the names of its contributors // may be used to endorse or promote products derived from this software without // specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // See the NOTICE file and the LICENSE file distributed with this work // for additional information regarding copyright ownership and licensing #import <XCTest/XCTest.h> #import <objc/runtime.h> #import "RFPropertyInfo.h" #import "AnnotatedClass.h" #import "NSObject+RFPropertyReflection.h" @interface RFPropertyInfoTest : XCTestCase { Class _testClass; } @end @implementation RFPropertyInfoTest const static NSUInteger numberOfProperties = 76; const static char *testClassName = "testClassName"; - (void)setUp { [super setUp]; // Put setup code here; it will be run once, before the first test case. _testClass = objc_allocateClassPair([NSObject class], testClassName, 0); } - (void)testPropertyCount { objc_property_attribute_t type = { "T", [@"NSString" UTF8String] }; objc_property_attribute_t ownership = { "R", "" }; // R = readonly NSUInteger inc; for (inc = 0; inc <= numberOfProperties; inc++) { objc_property_attribute_t backingivar = { "V", [[NSString stringWithFormat:@"_Property%lud", (long unsigned)inc] UTF8String] }; objc_property_attribute_t attrs[] = { type, ownership, backingivar }; SEL methodSelector = NSSelectorFromString([NSString stringWithFormat:@"Property%lud", (long unsigned)inc]); class_addProperty(_testClass, [[NSString stringWithFormat:@"Property%lud", (long unsigned)inc] UTF8String], attrs, 3); class_addMethod(_testClass, methodSelector, nil, "@@:"); } XCTAssertTrue(inc == [[RFPropertyInfo propertiesForClass:_testClass] count], @"It's not equal a sum of properties"); } - (void)testPropertyByPredicated { objc_property_attribute_t attrs[] = { { "T", [@"NSString" UTF8String] }, { "V", "_Property" }, { "R", "" }, }; NSString *propertyName = @"nameForTestPredicate"; SEL methodSelector = NSSelectorFromString(propertyName); class_addProperty(_testClass, "nameForTestPredicate", attrs, 3); class_addMethod(_testClass, methodSelector, nil, "@@:"); NSPredicate* predicate = [NSPredicate predicateWithFormat:@"propertyName == %@", propertyName]; RFPropertyInfo *propertyInfo = [[RFPropertyInfo propertiesForClass:_testClass withPredicate:predicate] lastObject]; XCTAssertNotNil(propertyInfo, @"Can't find metadata of property by name"); } - (void)testPropertyFunctionality { objc_property_attribute_t attrs[] = { { "T", [@"NSString" UTF8String] }, { "G", "getter" }, { "S", "setter" }, { "V", "_Property" }, { "D", "" }, { "C", "" }, { "R", "" }, { "&", "" }, { "N", "" }, { "W", "" }, }; NSString *propertyName = @"name"; SEL methodSelector = NSSelectorFromString(propertyName); class_addProperty(_testClass, "name", attrs, 10); class_addMethod(_testClass, methodSelector, nil, "@@:"); RFPropertyInfo *propertyInfo = [RFPropertyInfo RF_propertyNamed:propertyName forClass:_testClass]; XCTAssertNotNil(propertyInfo, @"Can't find metadata of property by name"); XCTAssertTrue([propertyInfo.typeName isEqualToString:@"NSString"], @"It's not equals a type name of property"); XCTAssertTrue([NSStringFromClass(propertyInfo.typeClass) isEqualToString:@"NSString"], @"It's not equals a type name of property"); XCTAssertTrue([propertyInfo.className isEqualToString:@"testClassName"], @"It's not equals a name of class of property"); XCTAssertTrue([propertyInfo.setterName isEqualToString:@"setter"], @"It's not equals a setter name of property"); XCTAssertTrue([propertyInfo.getterName isEqualToString:@"getter"], @"It's not equals a getter name of property"); XCTAssertTrue(propertyInfo.isReadonly, @"It's not equal attribute 'readonly' of property"); XCTAssertTrue(propertyInfo.isCopied, @"It's not equal attribute 'copy' of property"); XCTAssertTrue(propertyInfo.isDynamic, @"It's not equal attribute 'dynamic' of property"); XCTAssertTrue(propertyInfo.isWeak, @"It's not equal attribute 'weak' of property"); XCTAssertTrue(propertyInfo.isNonatomic, @"It's not equal attribute 'nonatomic' of property"); XCTAssertTrue(propertyInfo.isStrong, @"It's not equal attribute 'strong' of property"); } - (void)test_RF_propertiesForObjectInstance { AnnotatedClass* annotatedClass = [[AnnotatedClass alloc] init]; NSArray *properties = [annotatedClass RF_properties]; unsigned int numberOfProperties = 0; class_copyPropertyList([annotatedClass class], &numberOfProperties); XCTAssertTrue([properties count] == numberOfProperties, @"properties must contain values"); RFPropertyInfo *property = [annotatedClass RF_propertyNamed:@"prop"]; XCTAssertTrue([property.propertyName isEqualToString:@"prop"], @"please check properties"); XCTAssertTrue([property.attributes count] == 2, @"It's not equals a sum of attributes for property"); XCTAssertFalse(property.isPrimitive, @"It's not primitive property"); } - (void)testRetreivingPropertiesWithDepth { unsigned int numberOfAnnotatedClassProperties = 0; class_copyPropertyList([AnnotatedClass class], &numberOfAnnotatedClassProperties); unsigned int numberOfSubAnnotatedClassProperties = 0; class_copyPropertyList([SubAnnotatedClass class], &numberOfSubAnnotatedClassProperties); NSArray *allPropertiesForSubClass = [SubAnnotatedClass RF_propertiesWithDepth:2]; XCTAssertEqual([allPropertiesForSubClass count], numberOfAnnotatedClassProperties + numberOfSubAnnotatedClassProperties, @"Number of properies is not correct"); } - (void)testRetreivingPropertiesWithoutDepth { NSArray *allPropertiesForClass = [SubAnnotatedClass RF_propertiesWithDepth:1]; XCTAssertEqual([allPropertiesForClass count], (NSUInteger)1, @"Number of properies is not correct"); NSArray *propertiesForClass = [SubAnnotatedClass RF_properties]; XCTAssertEqual([allPropertiesForClass count], [propertiesForClass count], @"Number of properies is not correct"); } - (void)testRetreivingPropertiesWithZeroDepth { NSArray *propertiesForClass = [SubAnnotatedClass RF_propertiesWithDepth:0]; XCTAssertEqual([propertiesForClass count], (NSUInteger)0, @"Number of properies is not correct"); } - (void)tearDown { _testClass = nil; [super tearDown]; } @end