From 0ca4a0feeac04c804edf689b358fc8374941d2f9 Mon Sep 17 00:00:00 2001 From: Blake Watters Date: Thu, 23 Jun 2011 08:49:20 -0400 Subject: [PATCH] Added unit tests to loaders to investigate loading an array bug reports --- Rakefile | 2 +- RestKit.xcodeproj/project.pbxproj | 10 ++ .../xcshareddata/xcschemes/UISpec.xcscheme | 4 +- Specs/Fixtures/JSON/ArrayOfResults.json | 15 +++ Specs/Models/RKObjectLoaderSpecResultModel.h | 21 ++++ Specs/Models/RKObjectLoaderSpecResultModel.m | 17 +++ Specs/ObjectMapping/RKObjectLoaderSpec.m | 112 +++--------------- 7 files changed, 84 insertions(+), 97 deletions(-) create mode 100644 Specs/Fixtures/JSON/ArrayOfResults.json create mode 100644 Specs/Models/RKObjectLoaderSpecResultModel.h create mode 100644 Specs/Models/RKObjectLoaderSpecResultModel.m diff --git a/Rakefile b/Rakefile index cdd37862..d6fb4d97 100644 --- a/Rakefile +++ b/Rakefile @@ -53,7 +53,7 @@ def run(command) system(command) if $? != 0 puts "[!] Failed with exit code #{$?} while running: `#{command}`" - exit($?) + exit($?.to_i) end end diff --git a/RestKit.xcodeproj/project.pbxproj b/RestKit.xcodeproj/project.pbxproj index 3c12b4e8..ebdcbabd 100644 --- a/RestKit.xcodeproj/project.pbxproj +++ b/RestKit.xcodeproj/project.pbxproj @@ -43,6 +43,8 @@ 250D5C0013A069C400471F0E /* lcl_config_components.h in Headers */ = {isa = PBXBuildFile; fileRef = 250D5BFF13A069C400471F0E /* lcl_config_components.h */; settings = {ATTRIBUTES = (Public, ); }; }; 250D5C0213A069EA00471F0E /* lcl_config_extensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 250D5C0113A069EA00471F0E /* lcl_config_extensions.h */; settings = {ATTRIBUTES = (Public, ); }; }; 250D5C0413A06A4D00471F0E /* lcl_config_logger.h in Headers */ = {isa = PBXBuildFile; fileRef = 250D5C0313A06A4D00471F0E /* lcl_config_logger.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2515E7BA13B36A7D00E013A4 /* ArrayOfResults.json in Resources */ = {isa = PBXBuildFile; fileRef = 2515E7B913B36A7D00E013A4 /* ArrayOfResults.json */; }; + 2515E7BD13B36AC100E013A4 /* RKObjectLoaderSpecResultModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 2515E7BC13B36AC100E013A4 /* RKObjectLoaderSpecResultModel.m */; }; 251899FC1370F4E00092B049 /* RKLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 251899FB1370F4E00092B049 /* RKLog.h */; settings = {ATTRIBUTES = (Public, ); }; }; 251939B613A94B670073A39B /* NSString+RestKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 251939B213A94B5F0073A39B /* NSString+RestKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 251939B713A94B670073A39B /* NSString+RestKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 251939B313A94B5F0073A39B /* NSString+RestKit.m */; }; @@ -410,6 +412,9 @@ 250D5BFF13A069C400471F0E /* lcl_config_components.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lcl_config_components.h; sourceTree = ""; }; 250D5C0113A069EA00471F0E /* lcl_config_extensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lcl_config_extensions.h; sourceTree = ""; }; 250D5C0313A06A4D00471F0E /* lcl_config_logger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lcl_config_logger.h; sourceTree = ""; }; + 2515E7B913B36A7D00E013A4 /* ArrayOfResults.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = ArrayOfResults.json; sourceTree = ""; }; + 2515E7BB13B36AC100E013A4 /* RKObjectLoaderSpecResultModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKObjectLoaderSpecResultModel.h; sourceTree = ""; }; + 2515E7BC13B36AC100E013A4 /* RKObjectLoaderSpecResultModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RKObjectLoaderSpecResultModel.m; sourceTree = ""; }; 251899FB1370F4E00092B049 /* RKLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RKLog.h; sourceTree = ""; }; 251939B213A94B5F0073A39B /* NSString+RestKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+RestKit.h"; sourceTree = ""; }; 251939B313A94B5F0073A39B /* NSString+RestKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+RestKit.m"; sourceTree = ""; }; @@ -1127,6 +1132,8 @@ 3F032AAA10FFBC1F00F35142 /* RKResident.m */, 256FDE53112DB0B90077F340 /* RKObjectMapperSpecModel.h */, 256FDE54112DB0B90077F340 /* RKObjectMapperSpecModel.m */, + 2515E7BB13B36AC100E013A4 /* RKObjectLoaderSpecResultModel.h */, + 2515E7BC13B36AC100E013A4 /* RKObjectLoaderSpecResultModel.m */, ); path = Models; sourceTree = ""; @@ -1289,6 +1296,7 @@ 25952ED9136F563E00D04F93 /* JSON */ = { isa = PBXGroup; children = ( + 2515E7B913B36A7D00E013A4 /* ArrayOfResults.json */, 251939EC13ABA06D0073A39B /* DynamicKeysWithRelationship.json */, 251939E613AABED40073A39B /* DynamicKeys.json */, 251939E713AABED40073A39B /* error.json */, @@ -1888,6 +1896,7 @@ 251939EB13AABED40073A39B /* errors.json in Resources */, 251939ED13ABA06D0073A39B /* DynamicKeysWithRelationship.json in Resources */, 25BA443513ABB34900ADC7D0 /* tab_data.xml in Resources */, + 2515E7BA13B36A7D00E013A4 /* ArrayOfResults.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2118,6 +2127,7 @@ 25DBB3A413A2506900CE90F1 /* RKObjectMappingOperationSpec.m in Sources */, 25DBB3A513A2506C00CE90F1 /* RKManagedObjectMappingOperationSpec.m in Sources */, 25AA85D613B1065000A95E2A /* RKObjectLoaderSpec.m in Sources */, + 2515E7BD13B36AC100E013A4 /* RKObjectLoaderSpecResultModel.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/RestKit.xcodeproj/xcshareddata/xcschemes/UISpec.xcscheme b/RestKit.xcodeproj/xcshareddata/xcschemes/UISpec.xcscheme index dcc8e78c..5437a030 100644 --- a/RestKit.xcodeproj/xcshareddata/xcschemes/UISpec.xcscheme +++ b/RestKit.xcodeproj/xcshareddata/xcschemes/UISpec.xcscheme @@ -87,12 +87,12 @@ + +@interface RKObjectLoaderSpecResultModel : NSObject { + NSNumber* _ID; + NSDate* _endsAt; + NSString* _photoURL; +} + +@property (nonatomic, retain) NSNumber* ID; +@property (nonatomic, retain) NSDate* endsAt; +@property (nonatomic, retain) NSString* photoURL; + +@end diff --git a/Specs/Models/RKObjectLoaderSpecResultModel.m b/Specs/Models/RKObjectLoaderSpecResultModel.m new file mode 100644 index 00000000..79bf3ea5 --- /dev/null +++ b/Specs/Models/RKObjectLoaderSpecResultModel.m @@ -0,0 +1,17 @@ +// +// RKObjectLoaderSpecResultModel.m +// RestKit +// +// Created by Blake Watters on 6/23/11. +// Copyright 2011 Two Toasters. All rights reserved. +// + +#import "RKObjectLoaderSpecResultModel.h" + +@implementation RKObjectLoaderSpecResultModel + +@synthesize ID = _ID; +@synthesize endsAt = _endsAt; +@synthesize photoURL = _photoURL; + +@end diff --git a/Specs/ObjectMapping/RKObjectLoaderSpec.m b/Specs/ObjectMapping/RKObjectLoaderSpec.m index d6d31941..8c4796a1 100644 --- a/Specs/ObjectMapping/RKObjectLoaderSpec.m +++ b/Specs/ObjectMapping/RKObjectLoaderSpec.m @@ -10,6 +10,9 @@ #import "RKObjectMappingProvider.h" #import "RKErrorMessage.h" +// Models +#import "RKObjectLoaderSpecResultModel.h" + @interface RKSpecComplexUser : NSObject { NSNumber* _userID; NSString* _firstname; @@ -53,8 +56,6 @@ ///////////////////////////////////////////////////////////////////////////// -// TODO: These specs need to be executed against the RKManagedObjectLoader and RKObjectLoader -// until we can collapse the functionality somehow... @interface RKObjectLoaderSpec : RKSpec { } @@ -221,98 +222,21 @@ [mockObject verify]; } -@end - -@interface RKAnotherUser : NSObject { - NSNumber *userID; - NSString *firstName; - NSString *lastName; - NSString *email; - NSString *phone; - NSString *availability; - NSArray *interests; - NSString *singleAccessToken; - NSString *password; - NSString *passwordConfirmation; - NSString *facebookAccessToken; - NSDate *facebookAccessTokenExpirationDate; -} - -@property (nonatomic, retain) NSString *firstName; -@property (nonatomic, retain) NSString *lastName; -@property (nonatomic, retain) NSArray *interests; -@property (nonatomic, retain) NSString *email; -@property (nonatomic, retain) NSString *phone; -@property (nonatomic, retain) NSString *singleAccessToken; -@property (nonatomic, retain) NSNumber *userID; -@property (nonatomic, retain) NSString *password; -@property (nonatomic, retain) NSString *passwordConfirmation; -@property (nonatomic, retain) NSString *facebookAccessToken; -@property (nonatomic, retain) NSDate* facebookAccessTokenExpirationDate; - -@end - -@implementation RKAnotherUser - -@synthesize firstName; -@synthesize lastName; -@synthesize interests; -@synthesize email; -@synthesize phone; -@synthesize singleAccessToken; -@synthesize userID; -@synthesize password; -@synthesize passwordConfirmation; -@synthesize facebookAccessToken; -@synthesize facebookAccessTokenExpirationDate; - -+ (NSDictionary*)elementToPropertyMappings { - return [NSDictionary dictionaryWithKeysAndObjects: - @"id", @"userID", - @"first_name", @"firstName", - @"last_name", @"lastName", - @"email", @"email", - @"phone", @"phone", - @"user_interests", @"interests", - @"single_access_token", @"singleAccessToken", - @"password", @"password", - @"password_confirmation", @"passwordConfirmation", - @"facebook_access_token", @"facebookAccessToken", - @"facebook_access_token_expiration_date", - @"facebookAccessTokenExpirationDate", - nil]; +- (void)itShouldLoadResultsNestedAtAKeyPath { + RKObjectManager* objectManager = RKSpecNewObjectManager(); + RKObjectMapping* objectMapping = [RKObjectMapping mappingForClass:[RKObjectLoaderSpecResultModel class]]; + [objectMapping mapKeyPath:@"id" toAttribute:@"ID"]; + [objectMapping mapKeyPath:@"ends_at" toAttribute:@"endsAt"]; + [objectMapping mapKeyPath:@"photo_url" toAttribute:@"photoURL"]; + [objectManager.mappingProvider setObjectMapping:objectMapping forKeyPath:@"results"]; + RKSpecResponseLoader* loader = [RKSpecResponseLoader responseLoader]; + [objectManager loadObjectsAtResourcePath:@"/JSON/ArrayOfResults.json" delegate:loader]; + [loader waitForResponse]; + assertThat([loader objects], hasCountOf(2)); + assertThat([[[loader objects] objectAtIndex:0] ID], is(equalToInt(226))); + assertThat([[[loader objects] objectAtIndex:0] photoURL], is(equalTo(@"1308262872.jpg"))); + assertThat([[[loader objects] objectAtIndex:1] ID], is(equalToInt(235))); + assertThat([[[loader objects] objectAtIndex:1] photoURL], is(equalTo(@"1308634984.jpg"))); } @end - -// Works with Michael Deung's RailsUser.json -@interface RKUserRailsJSONMappingSpec : RKSpec { -} -@end - -@implementation RKUserRailsJSONMappingSpec - -- (RKObjectMappingProvider*)mappingProvider { - RKObjectMappingProvider* provider = [[RKObjectMappingProvider new] autorelease]; - RKObjectMapping* mapping = [RKObjectMapping mappingForClass:[RKAnotherUser class]]; - [mapping addAttributeMapping:[RKObjectAttributeMapping mappingFromKeyPath:@"first_name" toKeyPath:@"firstName"]]; - [provider setObjectMapping:mapping forKeyPath:@"user"]; - return provider; -} - -//- (void)itShouldMapWhenGivenARegisteredClassMapping { -// RKObjectManager* objectManager = RKSpecNewObjectManager(); -// RKSpecStubNetworkAvailability(YES); -// RKRailsRouter* router = [[[RKRailsRouter alloc] init] autorelease]; -// [router setModelName:@"user" forClass:[RKAnotherUser class]]; -// -// [objectManager setMappingProvider:[self mappingProvider]]; -// -// RKSpecResponseLoader* responseLoader = [RKSpecResponseLoader responseLoader]; -// [objectManager loadObjectsAtResourcePath:@"/JSON/RailsUser.json" delegate:responseLoader]; -// [responseLoader waitForResponse]; -// RKAnotherUser* user = [responseLoader.objects objectAtIndex:0]; -// [expectThat(user.firstName) should:be(@"Test")]; -//} - -@end