diff --git a/EasyMapping/EKObjectMapping.h b/EasyMapping/EKObjectMapping.h index ff19270..5864ebe 100644 --- a/EasyMapping/EKObjectMapping.h +++ b/EasyMapping/EKObjectMapping.h @@ -197,13 +197,15 @@ - (void)hasOne:(Class)objectClass forKeyPath:(NSString *)keyPath forProperty:(NSString *)property; /** - Map to-one relationship for keyPath. ObjectClass should conform to `EKMappingProtocol`. + Map to-one relationship for keyPath. @param keyPath keyPath to child object representation in JSON @param property Name of the property, that will receive mapped object. @param objectMapping optional mapping override for child object + + @warning If you have recursive mappings, do not use this method, cause it can cause infinite recursion to happen. Or you need to handle recursive mappings situation by yourself, subclassing EKObjectMapping and providing different mappings for different mapping levels. */ - (void)hasOne:(Class)objectClass forKeyPath:(NSString *)keyPath forProperty:(NSString *)property withObjectMapping:(EKObjectMapping*)objectMapping; @@ -229,7 +231,7 @@ - (void)hasMany:(Class)objectClass forKeyPath:(NSString *)keyPath forProperty:(NSString *)property; /** - Map to-many relationship for keyPath. ObjectClass should conform to `EKMappingProtocol`. + Map to-many relationship for keyPath. @param keyPath keyPath to child objects representation in JSON @@ -237,6 +239,7 @@ @param objectMapping optional mapping override for child objects + @warning If you have recursive mappings, do not use this method, cause it can cause infinite recursion to happen. Or you need to handle recursive mappings situation by yourself, subclassing EKObjectMapping and providing different mappings for different mapping levels. */ -(void)hasMany:(Class)objectClass forKeyPath:(NSString *)keyPath forProperty:(NSString *)property withObjectMapping:(EKObjectMapping*)objectMapping; diff --git a/EasyMapping/EKObjectMapping.m b/EasyMapping/EKObjectMapping.m index 290f8fe..868d875 100644 --- a/EasyMapping/EKObjectMapping.m +++ b/EasyMapping/EKObjectMapping.m @@ -185,8 +185,10 @@ -(void)hasOne:(Class)objectClass forKeyPath:(NSString *)keyPath forProperty:(NSS -(void)hasOne:(Class)objectClass forKeyPath:(NSString *)keyPath forProperty:(NSString *)property withObjectMapping:(EKObjectMapping*)objectMapping { - NSParameterAssert([objectClass conformsToProtocol:@protocol(EKMappingProtocol)] || - [objectClass conformsToProtocol:@protocol(EKManagedMappingProtocol)]); + if (!objectMapping) { + NSParameterAssert([objectClass conformsToProtocol:@protocol(EKMappingProtocol)] || + [objectClass conformsToProtocol:@protocol(EKManagedMappingProtocol)]); + } NSParameterAssert(keyPath); NSParameterAssert(property); @@ -211,8 +213,10 @@ -(void)hasMany:(Class)objectClass forKeyPath:(NSString *)keyPath forProperty:(NS -(void)hasMany:(Class)objectClass forKeyPath:(NSString *)keyPath forProperty:(NSString *)property withObjectMapping:(EKObjectMapping*)objectMapping { - NSParameterAssert([objectClass conformsToProtocol:@protocol(EKMappingProtocol)] || - [objectClass conformsToProtocol:@protocol(EKManagedMappingProtocol)]); + if (!objectMapping) { + NSParameterAssert([objectClass conformsToProtocol:@protocol(EKMappingProtocol)] || + [objectClass conformsToProtocol:@protocol(EKManagedMappingProtocol)]); + } NSParameterAssert(keyPath); NSParameterAssert(property); diff --git a/EasyMappingExample/Tests/Specs/EKObjectMappingSpec.m b/EasyMappingExample/Tests/Specs/EKObjectMappingSpec.m index e746c1d..29d14bb 100644 --- a/EasyMappingExample/Tests/Specs/EKObjectMappingSpec.m +++ b/EasyMappingExample/Tests/Specs/EKObjectMappingSpec.m @@ -101,6 +101,14 @@ [[mapping should] respondToSelector:@selector(hasMany:forKeyPath:forProperty:)]; }); + specify(^{ + [[mapping should] respondToSelector:@selector(hasOne:forKeyPath:forProperty:withObjectMapping:)]; + }); + + specify(^{ + [[mapping should] respondToSelector:@selector(hasMany:forKeyPath:forProperty:withObjectMapping:)]; + }); + specify(^{ [[mapping should] respondToSelector:@selector(mapPropertiesFromMappingObject:)]; }); @@ -591,6 +599,64 @@ }); + describe(@"#hasOne:forKeyPath:forProperty:withObjectMapping:", ^{ + __block EKObjectMapping * mapping; + __block EKObjectMapping * phoneMapping; + + beforeEach(^{ + mapping = [[EKObjectMapping alloc] initWithObjectClass:[Person class]]; + phoneMapping = [Phone objectMapping]; + // Use different class on purpose, checking object mapping of the relationship + [mapping hasOne:[Car class] + forKeyPath:@"phone" + forProperty:@"phone" + withObjectMapping:phoneMapping]; + }); + + specify(^{ + [mapping.hasOneMappings shouldNotBeNil]; + }); + + specify(^{ + [[mapping.hasOneMappings objectForKey:@"phone"] shouldNotBeNil]; + }); + + specify(^{ + EKRelationshipMapping * relationship = [mapping.hasOneMappings objectForKey:@"phone"]; + + [[[relationship objectMapping] should] equal:phoneMapping]; + }); + }); + + describe(@"#hasMany:forKeyPath:forProperty:withObjectMapping:", ^{ + __block EKObjectMapping * mapping; + __block EKObjectMapping * phoneMapping; + + beforeEach(^{ + mapping = [[EKObjectMapping alloc] initWithObjectClass:[Person class]]; + phoneMapping = [Phone objectMapping]; + // Use different class on purpose, checking object mapping of the relationship + [mapping hasMany:[Car class] + forKeyPath:@"phone" + forProperty:@"phone" + withObjectMapping:phoneMapping]; + }); + + specify(^{ + [mapping.hasManyMappings shouldNotBeNil]; + }); + + specify(^{ + [[mapping.hasManyMappings objectForKey:@"phone"] shouldNotBeNil]; + }); + + specify(^{ + EKRelationshipMapping * relationship = [mapping.hasManyMappings objectForKey:@"phone"]; + + [[[relationship objectMapping] should] equal:phoneMapping]; + }); + }); + }); SPEC_END