Improve Request Descriptor registration and lookup behaviors:

* Add assertion to object manager when you attempt to register an overlapping request descriptor
* Improve search algorithm to handle subclass matches
This commit is contained in:
Blake Watters
2012-11-05 23:10:57 -05:00
parent 7f7bef3e9f
commit e85cf659c0
4 changed files with 61 additions and 13 deletions

View File

@@ -68,9 +68,14 @@ static NSArray *RKFilteredArrayOfResponseDescriptorsMatchingPath(NSArray *respon
*/
static RKRequestDescriptor *RKRequestDescriptorFromArrayMatchingObject(NSArray *requestDescriptors, id object)
{
for (RKRequestDescriptor *requestDescriptor in requestDescriptors) {
if ([requestDescriptor matchesObject:object]) return requestDescriptor;
}
Class searchClass = [object class];
do {
for (RKRequestDescriptor *requestDescriptor in requestDescriptors) {
if ([requestDescriptor.objectClass isEqual:searchClass]) return requestDescriptor;
}
searchClass = [searchClass superclass];
} while (searchClass);
return nil;
}
@@ -459,7 +464,11 @@ static NSString *RKMIMETypeFromAFHTTPClientParameterEncoding(AFHTTPClientParamet
- (void)addRequestDescriptor:(RKRequestDescriptor *)requestDescriptor
{
NSParameterAssert(requestDescriptor);
if ([self.requestDescriptors containsObject:requestDescriptor]) return;
NSAssert([requestDescriptor isKindOfClass:[RKRequestDescriptor class]], @"Expected an object of type RKRequestDescriptor, got '%@'", [requestDescriptor class]);
[self.requestDescriptors enumerateObjectsUsingBlock:^(RKRequestDescriptor *registeredDescriptor, NSUInteger idx, BOOL *stop) {
NSAssert(![registeredDescriptor.objectClass isEqual:requestDescriptor.objectClass], @"Cannot add a request descriptor for the same object class as an existing request descriptor.");
}];
[self.mutableRequestDescriptors addObject:requestDescriptor];
}

View File

@@ -26,6 +26,12 @@
#import "RKCat.h"
#import "RKObjectMapperTestModel.h"
@interface RKSubclassedTestModel : RKObjectMapperTestModel
@end
@implementation RKSubclassedTestModel
@end
@interface RKTestAFHTTPClient : AFHTTPClient
@end
@@ -480,6 +486,48 @@
});
}
- (void)testThatAttemptingToAddARequestDescriptorThatOverlapsAnExistingEntryGeneratesAnError
{
RKObjectMapping *mapping = [RKObjectMapping requestMapping];
RKRequestDescriptor *requestDesriptor1 = [RKRequestDescriptor requestDescriptorWithMapping:mapping objectClass:[RKCat class] rootKeyPath:nil];
RKRequestDescriptor *requestDesriptor2 = [RKRequestDescriptor requestDescriptorWithMapping:mapping objectClass:[RKCat class] rootKeyPath:@"cat"];
RKObjectManager *objectManager = [RKTestFactory objectManager];
[objectManager addRequestDescriptor:requestDesriptor1];
NSException *caughtException = nil;
@try {
[objectManager addRequestDescriptor:requestDesriptor2];
}
@catch (NSException *exception) {
caughtException = exception;
}
@finally {
expect(caughtException).notTo.beNil();
}
}
- (void)testThatRegisteringARequestDescriptorForASubclassSecondWillMatchAppropriately
{
RKObjectMapping *mapping1 = [RKObjectMapping requestMapping];
[mapping1 addAttributeMappingsFromArray:@[ @"name" ]];
RKObjectMapping *mapping2 = [RKObjectMapping requestMapping];
[mapping2 addAttributeMappingsFromArray:@[ @"age" ]];
RKRequestDescriptor *requestDesriptor1 = [RKRequestDescriptor requestDescriptorWithMapping:mapping1 objectClass:[RKObjectMapperTestModel class] rootKeyPath:nil];
RKRequestDescriptor *requestDesriptor2 = [RKRequestDescriptor requestDescriptorWithMapping:mapping2 objectClass:[RKSubclassedTestModel class] rootKeyPath:@"subclassed"];
RKObjectManager *objectManager = [RKTestFactory objectManager];
objectManager.requestSerializationMIMEType = RKMIMETypeJSON;
[objectManager addRequestDescriptor:requestDesriptor1];
[objectManager addRequestDescriptor:requestDesriptor2];
RKSubclassedTestModel *model = [RKSubclassedTestModel new];
model.name = @"Blake";
model.age = @30;
NSURLRequest *request = [objectManager requestWithObject:model method:RKRequestMethodPOST path:@"/path" parameters:nil];
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:request.HTTPBody options:0 error:nil];
expect(dictionary).to.equal(@{ @"subclassed": @{ @"age": @(30) } });
}
//- (void)testShouldHandleConnectionFailures
//{
// NSString *localBaseURL = [NSString stringWithFormat:@"http://127.0.0.1:3001"];

View File

@@ -21,11 +21,7 @@
#import <Foundation/Foundation.h>
@interface RKObjectMapperTestModel : NSObject {
NSString *_name;
NSNumber *_age;
NSDate *_createdAt;
}
@interface RKObjectMapperTestModel : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSNumber *age;

View File

@@ -21,9 +21,4 @@
#import "RKObjectMapperTestModel.h"
@implementation RKObjectMapperTestModel
@synthesize name = _name;
@synthesize age = _age;
@synthesize createdAt = _createdAt;
@end