Files
RestKit/Specs/ObjectMapping/RKObjectMapperSpec.m

771 lines
27 KiB
Objective-C

//
// RKObjectMapperSpec.m
// RestKit
//
// Created by Jeremy Ellison on 12/8/09.
// Copyright 2009 Two Toasters
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#import "RKSpecEnvironment.h"
#import "RKOldObjectMapper.h"
#import "RKMappableObject.h"
#import "RKMappableAssociation.h"
#import "RKObjectMapperSpecModel.h"
#import "RKObject.h"
#import "NSDictionary+RKAdditions.h"
@interface RKOldObjectMapper (Private)
- (void)updateModel:(id)model ifNewPropertyValue:(id)propertyValue forPropertyNamed:(NSString*)propertyName;
@end
@interface RKObjectMapperSpecUser : RKObject {
@private
NSNumber* userID;
NSString* encryptedPassword;
NSString* name;
NSString* salt;
NSDate* createdAt;
NSDate* updatedAt;
NSString* image;
NSString* email;
NSArray* interests;
}
@property (nonatomic, retain) NSNumber* userID;
@property (nonatomic, retain) NSString* encryptedPassword;
@property (nonatomic, retain) NSString* name;
@property (nonatomic, retain) NSString* salt;
@property (nonatomic, retain) NSDate* createdAt;
@property (nonatomic, retain) NSDate* updatedAt;
@property (nonatomic, retain) NSString* image;
@property (nonatomic, retain) NSString* email;
@property (nonatomic, retain) NSArray* interests;
@end
@implementation RKObjectMapperSpecUser
@synthesize userID, encryptedPassword, name, salt, createdAt, updatedAt, image, email, interests;
+ (NSDictionary*)elementToPropertyMappings {
return [NSDictionary dictionaryWithKeysAndObjects:
@"id", @"userID",
@"encrypted_password", @"encryptedPassword",
@"name", @"name",
@"salt", @"salt",
@"created_at", @"createdAt",
@"updated_at", @"updatedAt",
@"image", @"image",
@"email", @"email",
@"interests", @"interests",
nil];
}
@end
@interface RKObjectMapperSpec : RKSpec
- (NSString*)jsonString;
- (NSString*)jsonCollectionString;
@end
@implementation RKObjectMapperSpec
- (NSString*)userJSON {
return @"{\"user\":"
@"{\"encrypted_password\":\"68dad82a867c4a61719fec594c119188ed35cd3b7d42eed1647e46d85f2ffdd8\",\"name\":\"mimi\","
@"\"salt\":\"809c79c24cbebfe3f9feea2e9bf98255e5af0f0b8514b6c0d71dcc63fa083688\",\"created_at\":\"2011-02-16T23:04:22Z\","
@"\"updated_at\":\"2011-02-16T23:04:22Z\",\"id\":"
@"10,\"image\":null,\"email\":\"mimi@mimi.com\"}}";
}
- (void)itShouldMapWhenGivenAClassAndElements {
RKOldObjectMapper* mapper = [[RKOldObjectMapper alloc] init];
mapper.format = RKMappingFormatJSON;
RKObjectMapperSpecUser* user = (RKObjectMapperSpecUser*) [mapper mapFromString:[self userJSON] toClass:[RKObjectMapperSpecUser class] keyPath:@"user"];
[expectThat(user.name) should:be(@"mimi")];
}
- (void)itShouldMapATargetObjectWithNamespacedJSON {
RKOldObjectMapper* mapper = [[RKOldObjectMapper new] autorelease];
[mapper registerClass:[RKObjectMapperSpecUser class] forElementNamed:@"user"];
mapper.format = RKMappingFormatJSON;
RKObjectMapperSpecUser* user = [[RKObjectMapperSpecUser new] autorelease];
[mapper mapObject:user fromString:[self userJSON]];
[expectThat(user.name) should:be(@"mimi")];
}
- (void)itShouldMapCorrectlyWithObjectClassSpecifiedAndElementRegistered {
RKOldObjectMapper* mapper = [[RKOldObjectMapper new] autorelease];
[mapper registerClass:[RKObjectMapperSpecUser class] forElementNamed:@"user"];
mapper.format = RKMappingFormatJSON;
NSString* JSON = [NSString stringWithFormat:@"[%@]", [self userJSON]];
NSArray* objects = [mapper mapFromString:JSON toClass:[RKObjectMapperSpecUser class] keyPath:nil];
RKObjectMapperSpecUser* user = [objects lastObject];
[expectThat(user.name) should:be(@"mimi")];
}
- (void)itShouldMapWhenGivenRegisteredElementsAndASingleObject {
RKOldObjectMapper* mapper = [[RKOldObjectMapper alloc] init];
[mapper registerClass:[RKObjectMapperSpecUser class] forElementNamed:@"user"];
mapper.format = RKMappingFormatJSON;
RKObjectMapperSpecUser* user = (RKObjectMapperSpecUser*) [mapper mapFromString:[self userJSON] toClass:nil keyPath:nil];
[expectThat(user.name) should:be(@"mimi")];
}
- (void)itShouldMapFromJSON {
RKOldObjectMapper* mapper = [[RKOldObjectMapper alloc] init];
mapper.format = RKMappingFormatJSON;
[mapper registerClass:[RKMappableObject class] forElementNamed:@"test_serialization_class"];
[mapper registerClass:[RKMappableAssociation class] forElementNamed:@"has_many"];
[mapper registerClass:[RKMappableAssociation class] forElementNamed:@"has_one"];
id result = [mapper mapFromString:[self jsonString]];
[expectThat(result) shouldNot:be(nil)];
[expectThat([result dateTest]) shouldNot:be(nil)];
[expectThat([result numberTest]) should:be(2)];
[expectThat([result stringTest]) should:be(@"SomeString")];
[expectThat([result urlTest]) should:be([NSURL URLWithString:@"https://github.com/twotoasters/RestKit"])];
[expectThat([result hasOne]) shouldNot:be(nil)];
[expectThat([[result hasOne] testString]) should:be(@"A String")];
[expectThat([result hasMany]) shouldNot:be(nil)];
[expectThat([[result hasMany] count]) should:be(2)];
}
- (void)itShouldLogAWarningWhenMultipleKeyPathsMatchForADictionary {
RKOldObjectMapper* mapper = [[RKOldObjectMapper alloc] init];
mapper.format = RKMappingFormatJSON;
[mapper registerClass:[RKMappableObject class] forElementNamed:@"test_serialization_class"];
[mapper registerClass:[RKMappableAssociation class] forElementNamed:@"test_serialization_class.has_one"];
[mapper mapFromString:[self jsonString]];
// TODO: Cannot unit test here -- need to factor NSLog out to allow mock object injection
NSLog(@">> PENDING");
}
- (void)itShouldMapObjectsFromJSON {
RKOldObjectMapper* mapper = [[RKOldObjectMapper alloc] init];
mapper.format = RKMappingFormatJSON;
[mapper registerClass:[RKMappableObject class] forElementNamed:@"test_serialization_class"];
[mapper registerClass:[RKMappableObject class] forElementNamed:@"test_serialization_class"];
[mapper registerClass:[RKMappableAssociation class] forElementNamed:@"has_many"];
[mapper registerClass:[RKMappableAssociation class] forElementNamed:@"has_one"];
NSString* collectionString = [self jsonCollectionString];
NSArray* results = [mapper mapFromString:collectionString];
NSLog(@"Results: %@", results);
[expectThat([results count]) should:be(2)];
RKMappableObject* result = (RKMappableObject*) [results objectAtIndex:0];
[expectThat(result) shouldNot:be(nil)];
[expectThat([result dateTest]) shouldNot:be(nil)];
[expectThat([result numberTest]) should:be(2)];
[expectThat([result stringTest]) should:be(@"SomeString")];
[expectThat([result hasOne]) shouldNot:be(nil)];
[expectThat([[result hasOne] testString]) should:be(@"A String")];
[expectThat([result hasMany]) shouldNot:be(nil)];
[expectThat([[result hasMany] count]) should:be(2)];
}
- (NSString*)arrayOfHashesJSON {
return @"{\"user\":"
@"[{\"encrypted_password\":\"68dad82a867c4a61719fec594c119188ed35cd3b7d42eed1647e46d85f2ffdd8\",\"name\":\"mimi\","
@"\"salt\":\"809c79c24cbebfe3f9feea2e9bf98255e5af0f0b8514b6c0d71dcc63fa083688\",\"created_at\":\"2011-02-16T23:04:22Z\","
@"\"updated_at\":\"2011-02-16T23:04:22Z\",\"id\":"
@"10,\"image\":null,\"email\":\"mimi@mimi.com\"}]}";
}
- (void)itShouldMapAnArrayOfHashes {
RKOldObjectMapper* mapper = [[RKOldObjectMapper alloc] init];
mapper.format = RKMappingFormatJSON;
[mapper registerClass:[RKObjectMapperSpecUser class] forElementNamed:@"user"];
NSArray* array = [mapper mapFromString:[self arrayOfHashesJSON]];
[expectThat([array isKindOfClass:[NSArray class]]) should:be(YES)];
[expectThat([array count]) should:be(1)];
[expectThat([[array lastObject] name]) should:be(@"mimi")];
}
// NOTE: email attribute is omitted!
- (NSString*)userJSONMissingAnElement {
return @"{\"user\":"
@"{\"encrypted_password\":\"68dad82a867c4a61719fec594c119188ed35cd3b7d42eed1647e46d85f2ffdd8\",\"name\":\"mimi\","
@"\"salt\":\"809c79c24cbebfe3f9feea2e9bf98255e5af0f0b8514b6c0d71dcc63fa083688\",\"created_at\":\"2011-02-16T23:04:22Z\","
@"\"updated_at\":\"2011-02-16T23:04:22Z\",\"id\":"
@"10,\"image\":null}}";
}
- (void)itShouldNotCrashWhenAttemptingToMapWithAMissingElement {
RKOldObjectMapper* mapper = [[RKOldObjectMapper alloc] init];
mapper.missingElementMappingPolicy = RKSetNilForMissingElementMappingPolicy;
mapper.format = RKMappingFormatJSON;
[mapper registerClass:[RKObjectMapperSpecUser class] forElementNamed:@"user"];
NSException* exception = nil;
@try {
[mapper mapFromString:[self userJSONMissingAnElement]];
}
@catch (NSException * e) {
exception = e;
}
[expectThat(exception) should:be(nil)];
}
- (void)itShouldNotNilOutWhenAttemptingToMapWithAMissingElementIfConfiguredNotTo {
RKObjectMapperSpecUser* user = [RKObjectMapperSpecUser object];
user.email = @"foo@bar.com";
RKOldObjectMapper* mapper = [[RKOldObjectMapper alloc] init];
mapper.missingElementMappingPolicy = RKIgnoreMissingElementMappingPolicy;
mapper.format = RKMappingFormatJSON;
[mapper registerClass:[RKObjectMapperSpecUser class] forElementNamed:@"user"];
[mapper mapObject:user fromString:[self userJSONMissingAnElement]];
[expectThat(user.email) should:be(@"foo@bar.com")];
}
- (void)itShouldNilOutWhenAttemptingToMapWithAMissingElementIfConfiguredToDoSo {
RKObjectMapperSpecUser* user = [RKObjectMapperSpecUser object];
user.email = @"foo@bar.com";
RKOldObjectMapper* mapper = [[RKOldObjectMapper alloc] init];
mapper.missingElementMappingPolicy = RKSetNilForMissingElementMappingPolicy;
mapper.format = RKMappingFormatJSON;
[mapper registerClass:[RKObjectMapperSpecUser class] forElementNamed:@"user"];
[mapper mapObject:user fromString:[self userJSONMissingAnElement]];
[expectThat(user.email) should:be(nil)];
}
- (NSString*)arrayOfStringsJSON {
return @"{\"user\":"
@"{\"encrypted_password\":\"68dad82a867c4a61719fec594c119188ed35cd3b7d42eed1647e46d85f2ffdd8\",\"name\":\"mimi\","
@"\"salt\":\"809c79c24cbebfe3f9feea2e9bf98255e5af0f0b8514b6c0d71dcc63fa083688\",\"created_at\":\"2011-02-16T23:04:22Z\","
@"\"updated_at\":\"2011-02-16T23:04:22Z\",\"id\":"
@"10,\"interests\":[\"basketball\", \"soccer\"]}}";
}
- (void)itShouldMapAnArrayOfStringsToAProperty {
RKObjectMapperSpecUser* user = [RKObjectMapperSpecUser object];
RKOldObjectMapper* mapper = [[RKOldObjectMapper alloc] init];
mapper.format = RKMappingFormatJSON;
[mapper registerClass:[RKObjectMapperSpecUser class] forElementNamed:@"user"];
[mapper mapObject:user fromString:[self arrayOfStringsJSON]];
NSArray* interests = [NSArray arrayWithObjects:@"basketball", @"soccer", nil];
[expectThat(user.interests) should:be(interests)];
}
- (void)itShouldNotUpdateNilPropertyToNil {
RKObjectMapperSpecModel* model = [[[RKObjectMapperSpecModel alloc] init] autorelease];
RKOldObjectMapper* mapper = [[RKOldObjectMapper alloc] init];
[mapper updateModel:model ifNewPropertyValue:nil forPropertyNamed:@"name"];
[expectThat(model.name) should:be(nil)];
}
- (void)itShouldBeAbleToSetNonNilPropertiesToNil {
RKObjectMapperSpecModel* model = [[[RKObjectMapperSpecModel alloc] init] autorelease];
model.age = [NSNumber numberWithInt:0];
RKOldObjectMapper* mapper = [[RKOldObjectMapper alloc] init];
[mapper updateModel:model ifNewPropertyValue:nil forPropertyNamed:@"age"];
[expectThat(model.age) should:be(nil)];
}
- (void)itShouldBeAbleToSetNilPropertiesToNonNil {
RKObjectMapperSpecModel* model = [[[RKObjectMapperSpecModel alloc] init] autorelease];
RKOldObjectMapper* mapper = [[RKOldObjectMapper alloc] init];
[mapper updateModel:model ifNewPropertyValue:[NSNumber numberWithInt:0] forPropertyNamed:@"age"];
[expectThat(model.age) should:be([NSNumber numberWithInt:0])];
}
- (void)itShouldBeAbleToSetNonNilNSStringPropertiesToNonNil {
RKObjectMapperSpecModel* model = [[[RKObjectMapperSpecModel alloc] init] autorelease];
RKOldObjectMapper* mapper = [[RKOldObjectMapper alloc] init];
model.name = @"Bob";
[mapper updateModel:model ifNewPropertyValue:@"Will" forPropertyNamed:@"name"];
[expectThat(model.name) should:be(@"Will")];
}
- (void)itShouldBeAbleToSetNonNilNSNumberPropertiesToNonNil {
RKObjectMapperSpecModel* model = [[[RKObjectMapperSpecModel alloc] init] autorelease];
RKOldObjectMapper* mapper = [[RKOldObjectMapper alloc] init];
model.age = [NSNumber numberWithInt:16];
[mapper updateModel:model ifNewPropertyValue:[NSNumber numberWithInt:17] forPropertyNamed:@"age"];
[expectThat(model.age) should:be(17)];
}
- (void)itShouldBeAbleToSetNonNilNSDatePropertiesToNonNil {
RKObjectMapperSpecModel* model = [[[RKObjectMapperSpecModel alloc] init] autorelease];
RKOldObjectMapper* mapper = [[[RKOldObjectMapper alloc] init] autorelease];
model.createdAt = [NSDate date];
[mapper updateModel:model ifNewPropertyValue:[NSDate dateWithTimeIntervalSince1970:0] forPropertyNamed:@"createdAt"];
[expectThat(model.createdAt) should:be([NSDate dateWithTimeIntervalSince1970:0])];
}
- (void)itShouldIgnoreMissingElementPropertyWhenMappingRelationships {
RKMappableObject* object = [[RKMappableObject new] autorelease];
RKMappableAssociation* association = [[RKMappableAssociation new] autorelease];
object.hasOne = association;
object.hasMany = [NSSet setWithObject:object];
RKOldObjectMapper* mapper = [[[RKOldObjectMapper alloc] init] autorelease];
mapper.missingElementMappingPolicy = RKIgnoreMissingElementMappingPolicy;
NSString* JSON = @"{ \"string_test\": \"woot!\" }";
[mapper mapObject:object fromString:JSON];
[expectThat(object.hasOne) shouldNot:be(nil)];
[expectThat(object.hasMany) shouldNot:be(nil)];
}
- (void)itShouldSetNilMissingElementPropertyWhenMappingRelationships {
RKMappableObject* object = [[RKMappableObject new] autorelease];
RKMappableAssociation* association = [[RKMappableAssociation new] autorelease];
object.hasOne = association;
object.hasMany = [NSSet setWithObject:object];
RKOldObjectMapper* mapper = [[[RKOldObjectMapper alloc] init] autorelease];
mapper.missingElementMappingPolicy = RKSetNilForMissingElementMappingPolicy;
NSString* JSON = @"{ \"string_test\": \"woot!\" }";
[mapper mapObject:object fromString:JSON];
[expectThat(object.hasOne) should:be(nil)];
[expectThat(object.hasMany) should:be(nil)];
}
// TODO: Factor these payloads out somehow to improve test clarity...
- (NSString*)jsonString {
return
@"{"
@" \"test_serialization_class\":{"
@" \"date_test\":\"2009-08-17T19:24:40Z\","
@" \"number_test\":2,"
@" \"string_test\":\"SomeString\","
@" \"url_test\":\"https://github.com/twotoasters/RestKit\","
@" \"has_one\":{"
@" \"test_string\":\"A String\""
@" },"
@" \"has_manys\":["
@" {"
@" \"has_many\":{"
@" \"test_string\":\"A String 2\""
@" }"
@" },"
@" {"
@" \"has_many\":{"
@" \"test_string\":\"A String 3\""
@" }"
@" }"
@" ]"
@" }"
@"}";
}
- (NSString*)jsonCollectionString {
return
@"["
@" {"
@" \"test_serialization_class\":{"
@" \"date_test\":\"2009-08-17T19:24:40Z\","
@" \"number_test\":2,"
@" \"string_test\":\"SomeString\","
@" \"has_one\":{"
@" \"test_string\":\"A String\""
@" },"
@" \"has_manys\":["
@" {"
@" \"has_many\":{"
@" \"test_string\":\"A String 2\""
@" }"
@" },"
@" {"
@" \"has_many\":{"
@" \"test_string\":\"A String 3\""
@" }"
@" }"
@" ]"
@" }"
@" },"
@" {"
@" \"test_serialization_class\":{"
@" \"date_test\":\"2009-08-17T19:24:40Z\","
@" \"number_test\":2,"
@" \"string_test\":\"SomeString\","
@" \"has_one\":{"
@" \"test_string\":\"A String\""
@" },"
@" \"has_manys\":["
@" {"
@" \"has_many\":{"
@" \"test_string\":\"A String 2\""
@" }"
@" },"
@" {"
@" \"has_many\":{"
@" \"test_string\":\"A String 3\""
@" }"
@" }"
@" ]"
@" }"
@" }"
@"]"
@"";
}
- (NSString*)xmlString {
NSString* xml = @"<test_serialization_class>"
@"<date_test type='datetime'>2009-08-17T19:24:40Z</date_test>"
@"<number_test type='integer'>2</number_test>"
@"<string_test>SomeString</string_test>"
@"<has_one>"
@"<test_string>A String</test_string>"
@"</has_one>"
@"<has_manys>"
@"<has_many>"
@"<test_string>A String 2</test_string>"
@"</has_many>"
@"<has_many>"
@"<test_string>A String 3</test_string>"
@"</has_many>"
@"</has_manys>"
@"</test_serialization_class>";
return xml;
}
- (NSString*)xmlCollectionString {
NSString* xml = @"<test_serialization_classes>"
@"<test_serialization_class>"
@"<date_test type='datetime'>2009-08-17T19:24:40Z</date_test>"
@"<number_test type='integer'>2</number_test>"
@"<string_test>SomeString</string_test>"
@"<has_one>"
@"<test_string>A String</test_string>"
@"</has_one>"
@"<has_manys>"
@"<has_many>"
@"<test_string>A String 2</test_string>"
@"</has_many>"
@"<has_many>"
@"<test_string>A String 3</test_string>"
@"</has_many>"
@"</has_manys>"
@"</test_serialization_class>"
@"<test_serialization_class>"
@"<date_test type='datetime'>2009-08-17T19:24:40Z</date_test>"
@"<number_test type='integer'>2</number_test>"
@"<string_test>SomeString</string_test>"
@"<has_one>"
@"<test_string>A String</test_string>"
@"</has_one>"
@"<has_manys>"
@"<has_many>"
@"<test_string>A String 2</test_string>"
@"</has_many>"
@"<has_many>"
@"<test_string>A String 3</test_string>"
@"</has_many>"
@"</has_manys>"
@"</test_serialization_class>"
@"</test_serialization_classes>";
return xml;
}
@end
//////////////////////////////////////////////////////////////////////////////////////////
// This class is a thin model around
@interface RKPath : RKObject {
@private
NSNumber* _label;
NSArray* _route; // An array of hashes
}
@property (nonatomic, retain) NSNumber* label;
@property (nonatomic, retain) NSArray* route;
@end
@implementation RKPath
@synthesize label = _label;
@synthesize route = _route;
+ (NSDictionary*)elementToPropertyMappings {
return [NSDictionary dictionaryWithKeysAndObjects:
@"label", @"label",
@"route", @"route",
nil];
}
@end
@interface RKModeledPath : RKObject {
@private
NSNumber* _label;
NSArray* _route; // An array of RKPoint objects
}
@property (nonatomic, retain) NSNumber* label;
@property (nonatomic, retain) NSArray* route;
@end
@implementation RKModeledPath
@synthesize label = _label;
@synthesize route = _route;
+ (NSDictionary*)elementToPropertyMappings {
return [NSDictionary dictionaryWithKeysAndObjects:
@"label", @"label",
nil];
}
+ (NSDictionary*)elementToRelationshipMappings {
return [NSDictionary dictionaryWithKeysAndObjects:
@"route", @"route",
nil];
}
@end
@interface RKPoint : RKObject {
NSNumber* _latitude;
NSNumber* _longitude;
}
@property (nonatomic, retain) NSNumber* latitude;
@property (nonatomic, retain) NSNumber* longitude;
@end
@implementation RKPoint
@synthesize latitude = _latitude;
@synthesize longitude = _longitude;
+ (NSDictionary*) elementToPropertyMappings {
return [NSDictionary dictionaryWithKeysAndObjects:
@"LATITUDE", @"latitude",
@"LONGITUDE", @"longitude",
nil];
}
- (NSString*)description {
return [NSString stringWithFormat:@"RKPoint : latitude = %@, longitude = %@", self.latitude, self.longitude];
}
@end
@interface RKObjectMapperRegisteredClassWithArraySpec : RKSpec {
@private
}
@end
@implementation RKObjectMapperRegisteredClassWithArraySpec
- (NSString*)JSON {
// TODO: Should create a JSON factory that can read these from a fixtures directory where we can format them nicely.
return @"[{\"route\":[{\"LATITUDE\":\"32.224519\",\"LONGITUDE\":\"-110.947325\"},{\"LATITUDE\":\"32.224542\",\"LONGITUDE\":\"-110.943861\"},{\"LATITUDE\":\"32.221431\",\"LONGITUDE\":\"-110.943930\"}],\"label\":7174},{\"route\":[{\"LATITUDE\":\"32.224519\",\"LONGITUDE\":\"-110.947325\"},{\"LATITUDE\":\"32.221402\",\"LONGITUDE\":\"-110.947293\"},{\"LATITUDE\":\"32.221431\",\"LONGITUDE\":\"-110.943930\"}],\"label\":7079},{\"route\":[{\"LATITUDE\":\"32.224519\",\"LONGITUDE\":\"-110.947325\"},{\"LATITUDE\":\"32.227820\",\"LONGITUDE\":\"-110.947293\"},{\"LATITUDE\":\"32.227843\",\"LONGITUDE\":\"-110.943865\"},{\"LATITUDE\":\"32.227879\",\"LONGITUDE\":\"-110.939531\"},{\"LATITUDE\":\"32.224599\",\"LONGITUDE\":\"-110.939495\"},{\"LATITUDE\":\"32.221476\",\"LONGITUDE\":\"-110.939496\"},{\"LATITUDE\":\"32.221431\",\"LONGITUDE\":\"-110.943930\"}],\"label\":23775}]";
}
- (void)itShouldMapAnArrayOfRoutes {
RKOldObjectMapper* mapper = [[RKOldObjectMapper alloc] init];
mapper.format = RKMappingFormatJSON;
NSArray* array = (NSArray*) [mapper mapFromString:[self JSON] toClass:[RKPath class] keyPath:nil];
[expectThat([array isKindOfClass:[NSArray class]]) should:be(YES)];
[expectThat([array count]) should:be(3)];
NSLog(@"Array is %@", array);
NSLog(@"First object is: %@", [array objectAtIndex:0]);
NSLog(@"Route on first object is: %@", [[array objectAtIndex:0] route]);
}
- (void)itShouldMapRouteToAnArrayOfPoints {
RKOldObjectMapper* mapper = [[RKOldObjectMapper alloc] init];
mapper.format = RKMappingFormatJSON;
[mapper registerClass:[RKPoint class] forElementNamed:@"route"];
NSArray* array = (NSArray*) [mapper mapFromString:[self JSON] toClass:[RKModeledPath class] keyPath:nil];
[expectThat([array isKindOfClass:[NSArray class]]) should:be(YES)];
[expectThat([array count]) should:be(3)];
NSLog(@"[Modeled] Array is %@", array);
NSLog(@"[Modeled] First object is: %@", [array objectAtIndex:0]);
NSLog(@"[Modeled] Route on first object is: %@", [[array objectAtIndex:0] route]);
}
@end
//////////////////////////////////////////////////////////////////////////////////////////
#pragma mark - Duplicated Keys
@interface RKFoursquareUser : RKObject {
NSString* _firstName;
NSString* _lastName;
NSArray* _checkins;
NSArray* _mayorships;
}
@property (nonatomic, retain) NSString* firstName;
@property (nonatomic, retain) NSString* lastName;
@property (nonatomic, retain) NSArray* checkins;
@property (nonatomic, retain) NSArray* mayorships;
@end
@implementation RKFoursquareUser
@synthesize firstName = _firstName;
@synthesize lastName = _lastName;
@synthesize checkins = _checkins;
@synthesize mayorships = _mayorships;
+ (NSDictionary*)elementToPropertyMappings {
return [NSDictionary dictionaryWithKeysAndObjects:
@"firstname", @"firstName",
@"lastname", @"lastName",
nil];
}
+ (NSDictionary*)elementToRelationshipMappings {
return [NSDictionary dictionaryWithKeysAndObjects:
@"mayorships.items", @"mayorships",
@"checkins", @"checkins",
nil];
}
- (NSString*)description {
return [NSString stringWithFormat:@"firstName = %@, lastName = %@, mayorships = %@, checkins = %@",
_firstName, _lastName, _mayorships, _checkins];
}
@end
@interface RKMayorship : RKObject {
NSString* _name;
NSNumber* _visitCount;
}
@property (nonatomic, retain) NSString* name;
@property (nonatomic, retain) NSNumber* visitCount;
@end
@implementation RKMayorship
@synthesize name = _name;
@synthesize visitCount = _visitCount;
+ (NSDictionary*)elementToPropertyMappings {
return [NSDictionary dictionaryWithKeysAndObjects:
@"name", @"name",
@"visit_count", @"visitCount",
nil];
}
@end
@interface RKCheckin : RKObject {
NSString* _name;
NSNumber* _longitude;
NSNumber* _latitude;
}
@property (nonatomic, retain) NSString* name;
@property (nonatomic, retain) NSNumber* longitude;
@property (nonatomic, retain) NSNumber* latitude;
@end
@implementation RKCheckin
@synthesize name = _name;
@synthesize longitude = _longitude;
@synthesize latitude = _latitude;
+ (NSDictionary*)elementToPropertyMappings {
return [NSDictionary dictionaryWithKeysAndObjects:
@"name", @"name",
@"longitude", @"longitude",
@"latitude", @"latitude",
nil];
}
@end
@interface RKObjectMapperPayloadItemsWithDuplicateKeysSpec : RKSpec {
}
@end
@implementation RKObjectMapperPayloadItemsWithDuplicateKeysSpec
- (NSString*)JSON {
return @"{"
@" \"response\": {"
@" \"user\": {"
@" \"id\": 1234,"
@" \"firstname\": \"Rich\","
@" \"lastname\": \"Wolf\","
@" \"mayorships\": {"
@" \"count\": 5,"
@" \"items\": ["
@" {"
@" \"name\": \"SpffiyCo\","
@" \"visit_count\": 97"
@" },"
@" {"
@" \"name\": \"Awesomeville\","
@" \"visit_count\": 235"
@" }"
@" ]"
@" },"
@" \"checkins\": {"
@" \"count\": 15,"
@" \"items\": ["
@" {"
@" \"name\": \"YummyStation\","
@" \"longitude\": -80.0,"
@" \"latitude\": 42.0"
@" },"
@" {"
@" \"name\": \"Pizzaland\","
@" \"longitude\": -81.0,"
@" \"latitude\": 41.0"
@" }"
@" ]"
@" }"
@" }"
@" }"
@"}";
}
- (void)itShouldMapOverlappingNamesUsingKeyPaths {
RKOldObjectMapper* mapper = [[RKOldObjectMapper alloc] init];
mapper.format = RKMappingFormatJSON;
[mapper registerClass:[RKFoursquareUser class] forElementNamed:@"user"];
[mapper registerClass:[RKMayorship class] forElementNamed:@"mayorships.items"];
[mapper registerClass:[RKCheckin class] forElementNamed:@"checkins.items"];
[mapper mapFromString:[self JSON] toClass:nil keyPath:@"response"];
NSLog(@"This Spec is disabled! Cannot handle these sorts of mappings with current mapper.");
}
@end