Files
RestKit/Tests/Logic/CoreData/RKManagedObjectThreadSafeInvocationTest.m

181 lines
10 KiB
Objective-C

//
// RKManagedObjectThreadSafeInvocationTest.h
// RestKit
//
// Created by Blake Watters on 5/12/11.
// Copyright (c) 2009-2012 RestKit. All rights reserved.
//
// 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 "RKTestEnvironment.h"
#import "RKHuman.h"
#import "RKManagedObjectThreadSafeInvocation.h"
@interface RKManagedObjectThreadSafeInvocation (Private)
- (void)serializeManagedObjectsForArgument:(id)argument withKeyPaths:(NSSet *)keyPaths;
- (void)deserializeManagedObjectIDsForArgument:(id)argument withKeyPaths:(NSSet *)keyPaths;
@end
@interface RKManagedObjectThreadSafeInvocationTest : RKTestCase {
NSMutableDictionary *_dictionary;
RKManagedObjectStore *_objectStore;
id _results;
BOOL _waiting;
}
@end
@implementation RKManagedObjectThreadSafeInvocationTest
- (void)testShouldSerializeOneManagedObjectToManagedObjectID
{
RKManagedObjectStore *managedObjectStore = [RKTestFactory managedObjectStore];
RKObjectManager *objectManager = [RKTestFactory objectManager];
objectManager.managedObjectStore = managedObjectStore;
RKHuman *human = [NSEntityDescription insertNewObjectForEntityForName:@"RKHuman" inManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext];
NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithObject:human forKey:@"human"];
NSMethodSignature *signature = [self methodSignatureForSelector:@selector(informDelegateWithDictionary:)];
RKManagedObjectThreadSafeInvocation *invocation = [RKManagedObjectThreadSafeInvocation invocationWithMethodSignature:signature];
[invocation serializeManagedObjectsForArgument:dictionary withKeyPaths:[NSSet setWithObject:@"human"]];
assertThat([dictionary valueForKeyPath:@"human"], is(instanceOf([NSManagedObjectID class])));
}
- (void)testShouldSerializeOneManagedObjectWithKeyPathToManagedObjectID
{
NSString *testKey = @"data.human";
RKManagedObjectStore *managedObjectStore = [RKTestFactory managedObjectStore];
RKObjectManager *objectManager = [RKTestFactory objectManager];
objectManager.managedObjectStore = managedObjectStore;
RKHuman *human = [NSEntityDescription insertNewObjectForEntityForName:@"RKHuman" inManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext];
NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithObject:human forKey:testKey];
NSMethodSignature *signature = [self methodSignatureForSelector:@selector(informDelegateWithDictionary:)];
RKManagedObjectThreadSafeInvocation *invocation = [RKManagedObjectThreadSafeInvocation invocationWithMethodSignature:signature];
[invocation serializeManagedObjectsForArgument:dictionary withKeyPaths:[NSSet setWithObject:testKey]];
assertThat([dictionary valueForKeyPath:testKey], is(instanceOf([NSManagedObjectID class])));
}
- (void)testShouldSerializeCollectionOfManagedObjectsToManagedObjectIDs
{
RKManagedObjectStore *managedObjectStore = [RKTestFactory managedObjectStore];
RKObjectManager *objectManager = [RKTestFactory objectManager];
objectManager.managedObjectStore = managedObjectStore;
RKHuman *human1 = [NSEntityDescription insertNewObjectForEntityForName:@"RKHuman" inManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext];
RKHuman *human2 = [NSEntityDescription insertNewObjectForEntityForName:@"RKHuman" inManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext];
NSArray *humans = [NSArray arrayWithObjects:human1, human2, nil];
NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithObject:humans forKey:@"humans"];
NSMethodSignature *signature = [self methodSignatureForSelector:@selector(informDelegateWithDictionary:)];
RKManagedObjectThreadSafeInvocation *invocation = [RKManagedObjectThreadSafeInvocation invocationWithMethodSignature:signature];
[invocation serializeManagedObjectsForArgument:dictionary withKeyPaths:[NSSet setWithObject:@"humans"]];
assertThat([dictionary valueForKeyPath:@"humans"], is(instanceOf([NSArray class])));
assertThat([[dictionary valueForKeyPath:@"humans"] lastObject], is(instanceOf([NSManagedObjectID class])));
}
- (void)testShouldDeserializeOneManagedObjectIDToManagedObject
{
RKManagedObjectStore *managedObjectStore = [RKTestFactory managedObjectStore];
RKObjectManager *objectManager = [RKTestFactory objectManager];
objectManager.managedObjectStore = managedObjectStore;
NSManagedObjectContext *managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
__block NSError *error;
__block NSManagedObjectID *objectID;
__block NSMutableDictionary *dictionary;
[managedObjectContext performBlockAndWait:^{
managedObjectContext.parentContext = managedObjectStore.persistentStoreManagedObjectContext;
RKHuman *human = [NSEntityDescription insertNewObjectForEntityForName:@"RKHuman" inManagedObjectContext:managedObjectContext];
BOOL success = [managedObjectContext obtainPermanentIDsForObjects:[NSArray arrayWithObject:human] error:&error];
success = [managedObjectContext save:&error];
[managedObjectContext.parentContext performBlockAndWait:^{
[managedObjectContext.parentContext save:&error];
}];
assertThatBool(success, is(equalToBool(YES)));
dictionary = [NSMutableDictionary dictionaryWithObject:[human objectID] forKey:@"human"];
objectID = human.objectID;
}];
[managedObjectStore.mainQueueManagedObjectContext reset];
NSMethodSignature *signature = [self methodSignatureForSelector:@selector(informDelegateWithDictionary:)];
RKManagedObjectThreadSafeInvocation* invocation = [RKManagedObjectThreadSafeInvocation invocationWithMethodSignature:signature];
invocation.privateQueueManagedObjectContext = managedObjectContext;
invocation.mainQueueManagedObjectContext = managedObjectStore.mainQueueManagedObjectContext;
[invocation deserializeManagedObjectIDsForArgument:dictionary withKeyPaths:[NSSet setWithObject:@"human"]];
assertThat([dictionary valueForKeyPath:@"human"], is(instanceOf([NSManagedObject class])));
assertThat([[dictionary valueForKeyPath:@"human"] objectID], is(equalTo(objectID)));
}
- (void)testShouldDeserializeCollectionOfManagedObjectIDToManagedObjects
{
RKManagedObjectStore *managedObjectStore = [RKTestFactory managedObjectStore];
RKObjectManager *objectManager = [RKTestFactory objectManager];
objectManager.managedObjectStore = managedObjectStore;
__block NSArray *humanIDs;
[managedObjectStore.persistentStoreManagedObjectContext performBlockAndWait:^{
RKHuman *human1 = [NSEntityDescription insertNewObjectForEntityForName:@"RKHuman" inManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext];
RKHuman *human2 = [NSEntityDescription insertNewObjectForEntityForName:@"RKHuman" inManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext];
NSError *error;
BOOL success = [managedObjectStore.persistentStoreManagedObjectContext save:&error];
assertThatBool(success, is(equalToBool(YES)));
humanIDs = [NSArray arrayWithObjects:[human1 objectID], [human2 objectID], nil];
}];
NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithObject:humanIDs forKey:@"humans"];
NSMethodSignature *signature = [self methodSignatureForSelector:@selector(informDelegateWithDictionary:)];
RKManagedObjectThreadSafeInvocation *invocation = [RKManagedObjectThreadSafeInvocation invocationWithMethodSignature:signature];
invocation.privateQueueManagedObjectContext = managedObjectStore.persistentStoreManagedObjectContext;
invocation.mainQueueManagedObjectContext = managedObjectStore.mainQueueManagedObjectContext;
[invocation deserializeManagedObjectIDsForArgument:dictionary withKeyPaths:[NSSet setWithObject:@"humans"]];
assertThat([dictionary valueForKeyPath:@"humans"], is(instanceOf([NSArray class])));
assertThat([dictionary valueForKeyPath:@"humans.objectID"], is(equalTo(humanIDs)));
}
- (void)informDelegateWithDictionary:(NSDictionary *)results
{
assertThatBool([NSThread isMainThread], equalToBool(YES));
assertThat(results, isNot(nilValue()));
assertThat(results, isNot(empty()));
assertThat([[results objectForKey:@"humans"] lastObject], is(instanceOf([NSManagedObject class])));
_waiting = NO;
}
- (void)createBackgroundObjects
{
@autoreleasepool {
assertThatBool([NSThread isMainThread], equalToBool(NO));
// Assert this is not the main thread
// Create a new array of objects in the background
RKObjectManager *objectManager = [RKTestFactory objectManager];
RKManagedObjectStore *managedObjectStore = [RKTestFactory managedObjectStore];
objectManager.managedObjectStore = managedObjectStore;
NSArray *humans = [NSArray arrayWithObject:[NSEntityDescription entityForName:@"RKHuman" inManagedObjectContext:managedObjectStore.persistentStoreManagedObjectContext]];
_dictionary = [NSMutableDictionary dictionaryWithObject:humans forKey:@"humans"];
NSMethodSignature *signature = [self methodSignatureForSelector:@selector(informDelegateWithDictionary:)];
RKManagedObjectThreadSafeInvocation *invocation = [RKManagedObjectThreadSafeInvocation invocationWithMethodSignature:signature];
invocation.privateQueueManagedObjectContext = _objectStore.persistentStoreManagedObjectContext;
invocation.mainQueueManagedObjectContext = _objectStore.mainQueueManagedObjectContext;
[invocation setTarget:self];
[invocation setSelector:@selector(informDelegateWithDictionary:)];
[invocation setArgument:&_dictionary atIndex:2]; // NOTE: _cmd and self are 0 and 1
[invocation setManagedObjectKeyPaths:[NSSet setWithObject:@"humans"] forArgument:2];
[invocation invokeOnMainThread];
}
}
@end