Files
RestKit/Tests/Logic/CoreData/RKEntityCacheTest.m
Blake Watters 79e31b524a Refactored managed object caches and connection support to enable connecting by multiple atributes that are specified as arrays.
* Migrated the caches to return `NSSet` to eliminate duplicate objects when your cache keys overlap
* Introduced new recursive strategy for building cache keys in `RKInMemoryManagedObjectCache`
* Added support for array cache key values in `RKFetchRequestManagedObjectCache`
* Re-enabled a slew of tests that were disabled during 0.20 development
2012-12-06 23:43:34 -05:00

202 lines
9.9 KiB
Objective-C

//
// RKEntityCacheTest.m
// RestKit
//
// Created by Blake Watters on 5/2/12.
// Copyright (c) 2012 RestKit. All rights reserved.
//
#import "RKTestEnvironment.h"
#import "RKEntityCache.h"
#import "RKEntityByAttributeCache.h"
#import "RKHuman.h"
@interface RKEntityCacheTest : RKTestCase
@property (nonatomic, strong) RKManagedObjectStore *managedObjectStore;
@property (nonatomic, strong) RKEntityCache *cache;
@property (nonatomic, strong) NSEntityDescription *entity;
@end
@implementation RKEntityCacheTest
@synthesize managedObjectStore = _managedObjectStore;
@synthesize cache = _cache;
@synthesize entity = _entity;
- (void)setUp
{
[RKTestFactory setUp];
self.managedObjectStore = [RKTestFactory managedObjectStore];
_cache = [[RKEntityCache alloc] initWithManagedObjectContext:self.managedObjectStore.persistentStoreManagedObjectContext];
self.entity = [NSEntityDescription entityForName:@"Human" inManagedObjectContext:self.managedObjectStore.persistentStoreManagedObjectContext];
}
- (void)tearDown
{
self.managedObjectStore = nil;
self.cache = nil;
[RKTestFactory tearDown];
}
- (void)testInitializationSetsManagedObjectContext
{
assertThat(_cache.managedObjectContext, is(equalTo(self.managedObjectStore.persistentStoreManagedObjectContext)));
}
- (void)testIsEntityCachedByAttribute
{
assertThatBool([_cache isEntity:self.entity cachedByAttributes:@[ @"railsID" ]], is(equalToBool(NO)));
[_cache cacheObjectsForEntity:self.entity byAttributes:@[ @"railsID" ]];
assertThatBool([_cache isEntity:self.entity cachedByAttributes:@[ @"railsID" ]], is(equalToBool(YES)));
}
- (void)testRetrievalOfUnderlyingEntityAttributeCache
{
[_cache cacheObjectsForEntity:self.entity byAttributes:@[ @"railsID" ]];
RKEntityByAttributeCache *attributeCache = [_cache attributeCacheForEntity:self.entity attributes:@[ @"railsID" ]];
assertThat(attributeCache, is(notNilValue()));
}
- (void)testRetrievalOfUnderlyingEntityAttributeCaches
{
[_cache cacheObjectsForEntity:self.entity byAttributes:@[ @"railsID" ]];
NSArray *caches = [_cache attributeCachesForEntity:self.entity];
assertThat(caches, is(notNilValue()));
assertThatInteger([caches count], is(equalToInteger(1)));
}
- (void)testRetrievalOfObjectForEntityWithAttributeValue
{
RKHuman *human = [NSEntityDescription insertNewObjectForEntityForName:@"Human" inManagedObjectContext:self.managedObjectStore.persistentStoreManagedObjectContext];
human.railsID = [NSNumber numberWithInteger:12345];
NSError *error = nil;
[self.managedObjectStore.persistentStoreManagedObjectContext save:&error];
[_cache cacheObjectsForEntity:self.entity byAttributes:@[ @"railsID" ]];
NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
childContext.parentContext = self.managedObjectStore.persistentStoreManagedObjectContext;
NSManagedObject *fetchedObject = [self.cache objectForEntity:self.entity withAttributeValues:@{ @"railsID": @(12345) } inContext:childContext];
assertThat(fetchedObject, is(notNilValue()));
}
- (void)testRetrievalOfObjectsForEntityWithAttributeValue
{
RKHuman *human1 = [NSEntityDescription insertNewObjectForEntityForName:@"Human" inManagedObjectContext:self.managedObjectStore.persistentStoreManagedObjectContext];
human1.railsID = [NSNumber numberWithInteger:12345];
RKHuman *human2 = [NSEntityDescription insertNewObjectForEntityForName:@"Human" inManagedObjectContext:self.managedObjectStore.persistentStoreManagedObjectContext];
human2.railsID = [NSNumber numberWithInteger:12345];
NSError *error = nil;
[self.managedObjectStore.persistentStoreManagedObjectContext save:&error];
[_cache cacheObjectsForEntity:self.entity byAttributes:@[ @"railsID" ]];
NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
childContext.parentContext = self.managedObjectStore.persistentStoreManagedObjectContext;
NSSet *objects = [self.cache objectsForEntity:self.entity withAttributeValues:@{ @"railsID": @(12345) } inContext:childContext];
assertThat(objects, hasCountOf(2));
assertThat([objects valueForKey:@"objectID"], containsInAnyOrder(human1.objectID, human2.objectID, nil));
}
- (void)testThatFlushEmptiesAllUnderlyingAttributeCaches
{
RKHuman *human1 = [NSEntityDescription insertNewObjectForEntityForName:@"Human" inManagedObjectContext:self.managedObjectStore.persistentStoreManagedObjectContext];
human1.railsID = [NSNumber numberWithInteger:12345];
human1.name = @"Blake";
RKHuman *human2 = [NSEntityDescription insertNewObjectForEntityForName:@"Human" inManagedObjectContext:self.managedObjectStore.persistentStoreManagedObjectContext];
human2.railsID = [NSNumber numberWithInteger:12345];
human2.name = @"Sarah";
[self.managedObjectStore.persistentStoreManagedObjectContext save:nil];
[_cache cacheObjectsForEntity:self.entity byAttributes:@[ @"railsID" ]];
[_cache cacheObjectsForEntity:self.entity byAttributes:@[ @"name" ]];
NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
childContext.parentContext = self.managedObjectStore.persistentStoreManagedObjectContext;
NSSet *objects = [self.cache objectsForEntity:self.entity withAttributeValues:@{ @"railsID": @(12345) } inContext:childContext];
assertThat(objects, hasCountOf(2));
assertThat([objects valueForKey:@"objectID"], containsInAnyOrder(human1.objectID, human2.objectID, nil));
objects = [self.cache objectsForEntity:self.entity withAttributeValues:@{ @"name": @"Blake" } inContext:childContext];
assertThat(objects, hasCountOf(1));
assertThat([objects valueForKey:@"objectID"], contains(human1.objectID, nil));
[self.cache flush];
objects = [self.cache objectsForEntity:self.entity withAttributeValues:@{ @"railsID": @(12345) } inContext:childContext];
assertThat(objects, is(empty()));
objects = [self.cache objectsForEntity:self.entity withAttributeValues:@{ @"name": @"Blake" } inContext:childContext];
assertThat(objects, is(empty()));
}
- (void)testAddingObjectAddsToEachUnderlyingEntityAttributeCaches
{
[_cache cacheObjectsForEntity:self.entity byAttributes:@[ @"railsID" ]];
[_cache cacheObjectsForEntity:self.entity byAttributes:@[ @"name" ]];
RKHuman *human1 = [NSEntityDescription insertNewObjectForEntityForName:@"Human" inManagedObjectContext:self.managedObjectStore.persistentStoreManagedObjectContext];
human1.railsID = [NSNumber numberWithInteger:12345];
human1.name = @"Blake";
RKHuman *human2 = [NSEntityDescription insertNewObjectForEntityForName:@"Human" inManagedObjectContext:self.managedObjectStore.persistentStoreManagedObjectContext];
human2.railsID = [NSNumber numberWithInteger:12345];
human2.name = @"Sarah";
__block NSError *error;
__block BOOL success;
[self.managedObjectStore.persistentStoreManagedObjectContext performBlockAndWait:^{
success = [self.managedObjectStore.persistentStoreManagedObjectContext save:&error];
}];
assertThatBool(success, is(equalToBool(YES)));
[_cache addObject:human1];
[_cache addObject:human2];
NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
childContext.parentContext = self.managedObjectStore.persistentStoreManagedObjectContext;
NSSet *objects = [self.cache objectsForEntity:self.entity withAttributeValues:@{ @"railsID": @(12345) } inContext:childContext];
assertThat(objects, hasCountOf(2));
assertThat([objects valueForKey:@"objectID"], containsInAnyOrder(human1.objectID, human2.objectID, nil));
objects = [self.cache objectsForEntity:self.entity withAttributeValues:@{ @"name": @"Blake" } inContext:childContext];
assertThat(objects, hasCountOf(1));
assertThat([objects valueForKey:@"objectID"], contains(human1.objectID, nil));
}
- (void)testRemovingObjectRemovesFromUnderlyingEntityAttributeCaches
{
[_cache cacheObjectsForEntity:self.entity byAttributes:@[ @"railsID" ]];
[_cache cacheObjectsForEntity:self.entity byAttributes:@[ @"name" ]];
RKHuman *human1 = [NSEntityDescription insertNewObjectForEntityForName:@"Human" inManagedObjectContext:self.managedObjectStore.persistentStoreManagedObjectContext];
human1.railsID = [NSNumber numberWithInteger:12345];
human1.name = @"Blake";
RKHuman *human2 = [NSEntityDescription insertNewObjectForEntityForName:@"Human" inManagedObjectContext:self.managedObjectStore.persistentStoreManagedObjectContext];
human2.railsID = [NSNumber numberWithInteger:12345];
human2.name = @"Sarah";
__block NSError *error;
__block BOOL success;
[self.managedObjectStore.persistentStoreManagedObjectContext performBlockAndWait:^{
success = [self.managedObjectStore.persistentStoreManagedObjectContext save:&error];
}];
assertThatBool(success, is(equalToBool(YES)));
[_cache addObject:human1];
[_cache addObject:human2];
NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
childContext.parentContext = self.managedObjectStore.persistentStoreManagedObjectContext;
NSSet *objects = [self.cache objectsForEntity:self.entity withAttributeValues:@{ @"railsID": @(12345) } inContext:childContext];
assertThat(objects, hasCountOf(2));
assertThat([objects valueForKey:@"objectID"], containsInAnyOrder(human1.objectID, human2.objectID, nil));
RKEntityByAttributeCache *entityAttributeCache = [self.cache attributeCacheForEntity:self.entity attributes:@[ @"railsID" ]];
assertThatBool([entityAttributeCache containsObject:human1], is(equalToBool(YES)));
[self.cache removeObject:human1];
assertThatBool([entityAttributeCache containsObject:human1], is(equalToBool(NO)));
}
@end