mirror of
https://github.com/zhigang1992/MagicalRecord.git
synced 2026-01-12 22:48:38 +08:00
All deprecated and non-deprecated methods have tests to ensure their function
This commit is contained in:
@@ -32,14 +32,14 @@ typedef void (^MRSaveCompletionHandler)(BOOL success, NSError *error);
|
||||
* The following methods are deprecated, but remain in place for backwards compatibility until the next major version (3.x)
|
||||
*/
|
||||
- (void) MR_save __attribute__((deprecated));
|
||||
- (void) MR_saveWithErrorCallback:(void(^)(NSError *))errorCallback __attribute__((deprecated));
|
||||
- (void) MR_saveWithErrorCallback:(void(^)(NSError *error))errorCallback __attribute__((deprecated));
|
||||
|
||||
- (void) MR_saveInBackgroundCompletion:(void (^)(void))completion __attribute__((deprecated));
|
||||
- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *))errorCallback __attribute__((deprecated));
|
||||
- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *))errorCallback completion:(void (^)(void))completion __attribute__((deprecated));
|
||||
- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback __attribute__((deprecated));
|
||||
- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion __attribute__((deprecated));
|
||||
|
||||
- (void) MR_saveNestedContexts __attribute__((deprecated));
|
||||
- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *))errorCallback __attribute__((deprecated));
|
||||
- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *))errorCallback completion:(void (^)(void))completion __attribute__((deprecated));
|
||||
- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback __attribute__((deprecated));
|
||||
- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion __attribute__((deprecated));
|
||||
|
||||
@end
|
||||
|
||||
@@ -50,6 +50,8 @@
|
||||
}
|
||||
|
||||
MRLog(@"→ Saving %@", [self MR_description]);
|
||||
MRLog(@"→ Save Parents? %@", @(saveParentContexts));
|
||||
MRLog(@"→ Save Synchronously? %@", @(syncSave));
|
||||
|
||||
id saveBlock = ^{
|
||||
NSError *error = nil;
|
||||
@@ -102,46 +104,17 @@
|
||||
#pragma mark - Deprecated methods
|
||||
// These methods will be removed in MagicalRecord 3.0
|
||||
|
||||
- (void)MR_saveNestedContexts;
|
||||
{
|
||||
[self MR_saveToPersistentStoreWithCompletion:nil];
|
||||
}
|
||||
|
||||
- (void)MR_saveNestedContextsErrorHandler:(void (^)(NSError *))errorCallback;
|
||||
{
|
||||
[self MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
|
||||
if (!success) {
|
||||
if (errorCallback) {
|
||||
errorCallback(error);
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)MR_saveNestedContextsErrorHandler:(void (^)(NSError *))errorCallback completion:(void (^)(void))completion;
|
||||
{
|
||||
[self MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
|
||||
if (success) {
|
||||
if (completion) {
|
||||
completion();
|
||||
}
|
||||
} else {
|
||||
if (errorCallback) {
|
||||
errorCallback(error);
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
|
||||
|
||||
- (void)MR_save;
|
||||
{
|
||||
[self MR_saveToPersistentStoreAndWait];
|
||||
}
|
||||
|
||||
- (void)MR_saveWithErrorCallback:(void (^)(NSError *))errorCallback __attribute__((deprecated));
|
||||
|
||||
- (void)MR_saveWithErrorCallback:(void (^)(NSError *error))errorCallback;
|
||||
{
|
||||
[self MR_saveWithOptions:MRSaveSynchronously completion:^(BOOL success, NSError *error) {
|
||||
[self MR_saveWithOptions:MRSaveSynchronously|MRSaveParentContexts completion:^(BOOL success, NSError *error) {
|
||||
if (!success) {
|
||||
if (errorCallback) {
|
||||
errorCallback(error);
|
||||
@@ -161,7 +134,7 @@
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)MR_saveInBackgroundErrorHandler:(void (^)(NSError *))errorCallback;
|
||||
- (void)MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback;
|
||||
{
|
||||
[self MR_saveOnlySelfWithCompletion:^(BOOL success, NSError *error) {
|
||||
if (!success) {
|
||||
@@ -172,7 +145,7 @@
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)MR_saveInBackgroundErrorHandler:(void (^)(NSError *))errorCallback completion:(void (^)(void))completion;
|
||||
- (void)MR_saveInBackgroundErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion;
|
||||
{
|
||||
[self MR_saveOnlySelfWithCompletion:^(BOOL success, NSError *error) {
|
||||
if (success) {
|
||||
@@ -187,4 +160,37 @@
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)MR_saveNestedContexts;
|
||||
{
|
||||
[self MR_saveToPersistentStoreWithCompletion:nil];
|
||||
}
|
||||
|
||||
- (void)MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback;
|
||||
{
|
||||
[self MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
|
||||
if (!success) {
|
||||
if (errorCallback) {
|
||||
errorCallback(error);
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)MR_saveNestedContextsErrorHandler:(void (^)(NSError *error))errorCallback completion:(void (^)(void))completion;
|
||||
{
|
||||
[self MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
|
||||
if (success) {
|
||||
if (completion) {
|
||||
completion();
|
||||
}
|
||||
} else {
|
||||
if (errorCallback) {
|
||||
errorCallback(error);
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma clang diagnostic pop // ignored "-Wdeprecated-implementations"
|
||||
|
||||
@end
|
||||
|
||||
@@ -39,6 +39,6 @@
|
||||
/*
|
||||
If you want to reuse the context on the current thread, use this method.
|
||||
*/
|
||||
+ (void) saveInBackgroundUsingCurrentContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(void (^)(void))completion errorHandler:(void (^)(NSError *))errorHandler __attribute__((deprecated));
|
||||
+ (void) saveInBackgroundUsingCurrentContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(void (^)(void))completion errorHandler:(void (^)(NSError *error))errorHandler __attribute__((deprecated));
|
||||
|
||||
@end
|
||||
|
||||
@@ -78,6 +78,9 @@
|
||||
|
||||
#pragma mark - Deprecated methods
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
|
||||
|
||||
+ (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block
|
||||
{
|
||||
[[self class] saveWithBlock:block completion:nil];
|
||||
@@ -103,7 +106,7 @@
|
||||
}];
|
||||
}
|
||||
|
||||
+ (void) saveInBackgroundUsingCurrentContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(void (^)(void))completion errorHandler:(void (^)(NSError *))errorHandler;
|
||||
+ (void) saveInBackgroundUsingCurrentContextWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(void (^)(void))completion errorHandler:(void (^)(NSError *error))errorHandler;
|
||||
{
|
||||
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
|
||||
|
||||
@@ -113,7 +116,6 @@
|
||||
}
|
||||
|
||||
[localContext MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
|
||||
|
||||
if (success) {
|
||||
if (completion) {
|
||||
completion();
|
||||
@@ -128,4 +130,6 @@
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma clang diagnostic pop // ignored "-Wdeprecated-implementations"
|
||||
|
||||
@end
|
||||
|
||||
@@ -16,213 +16,288 @@ describe(@"MagicalRecord", ^{
|
||||
// Occurs after each enclosed "it" block
|
||||
[MagicalRecord cleanUp];
|
||||
});
|
||||
|
||||
|
||||
context(@"synchronous save action", ^{
|
||||
it(@"should save", ^{
|
||||
__block NSManagedObjectID *objectId;
|
||||
__block NSManagedObject *fetchedObject;
|
||||
|
||||
|
||||
[MagicalRecord saveWithBlockAndWait:^(NSManagedObjectContext *localContext) {
|
||||
NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:localContext];
|
||||
|
||||
|
||||
[[@([inserted hasChanges]) should] beTrue];
|
||||
|
||||
|
||||
[localContext obtainPermanentIDsForObjects:@[inserted] error:nil];
|
||||
objectId = [inserted objectID];
|
||||
}];
|
||||
|
||||
|
||||
[[objectId should] beNonNil];
|
||||
|
||||
fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectWithID:objectId];
|
||||
|
||||
|
||||
NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
|
||||
|
||||
[[fetchedObject should] beNonNil];
|
||||
[[@([fetchedObject hasChanges]) should] beFalse];
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
context(@"asynchronous save action", ^{
|
||||
it(@"should call completion block", ^{
|
||||
__block BOOL completionBlockCalled = NO;
|
||||
|
||||
|
||||
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
|
||||
[SingleEntityWithNoRelationships MR_createInContext:localContext];
|
||||
} completion:^(BOOL success, NSError *error) {
|
||||
// Ignore the success state — we only care that this block is executed
|
||||
completionBlockCalled = YES;
|
||||
}];
|
||||
|
||||
|
||||
[[expectFutureValue(@(completionBlockCalled)) shouldEventually] beTrue];
|
||||
});
|
||||
|
||||
|
||||
it(@"should save", ^{
|
||||
__block BOOL saveSuccessState = NO;
|
||||
__block NSManagedObjectID *objectId;
|
||||
__block NSManagedObject *fetchedObject;
|
||||
|
||||
|
||||
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
|
||||
NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:localContext];
|
||||
|
||||
|
||||
[[@([inserted hasChanges]) should] beTrue];
|
||||
|
||||
|
||||
[localContext obtainPermanentIDsForObjects:@[inserted] error:nil];
|
||||
objectId = [inserted objectID];
|
||||
} completion:^(BOOL success, NSError *error) {
|
||||
saveSuccessState = success;
|
||||
fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectWithID:objectId];
|
||||
fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
|
||||
}];
|
||||
|
||||
|
||||
[[expectFutureValue(@(saveSuccessState)) shouldEventually] beTrue];
|
||||
[[expectFutureValue(fetchedObject) shouldEventually] beNonNil];
|
||||
[[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beFalse];
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
context(@"current thread save action", ^{
|
||||
context(@"running synchronously", ^{
|
||||
it(@"should save", ^{
|
||||
__block NSManagedObjectID *objectId;
|
||||
|
||||
|
||||
[MagicalRecord saveUsingCurrentThreadContextWithBlockAndWait:^(NSManagedObjectContext *localContext) {
|
||||
NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:localContext];
|
||||
|
||||
|
||||
[[@([inserted hasChanges]) should] beTrue];
|
||||
|
||||
|
||||
[localContext obtainPermanentIDsForObjects:@[inserted] error:nil];
|
||||
objectId = [inserted objectID];
|
||||
}];
|
||||
|
||||
|
||||
[[objectId should] beNonNil];
|
||||
|
||||
NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectWithID:objectId];
|
||||
|
||||
|
||||
NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
|
||||
|
||||
[[fetchedObject should] beNonNil];
|
||||
[[@([fetchedObject hasChanges]) should] beFalse];
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
context(@"running asynchronously", ^{
|
||||
it(@"should call completion block", ^{
|
||||
__block BOOL completionBlockCalled = NO;
|
||||
|
||||
|
||||
[MagicalRecord saveUsingCurrentThreadContextWithBlock:^(NSManagedObjectContext *localContext) {
|
||||
[SingleEntityWithNoRelationships MR_createInContext:localContext];
|
||||
} completion:^(BOOL success, NSError *error) {
|
||||
// Ignore the success state — we only care that this block is executed
|
||||
completionBlockCalled = YES;
|
||||
}];
|
||||
|
||||
|
||||
[[expectFutureValue(@(completionBlockCalled)) shouldEventually] beTrue];
|
||||
});
|
||||
|
||||
|
||||
it(@"should save", ^{
|
||||
__block BOOL saveSuccessState = NO;
|
||||
__block NSError *saveError;
|
||||
__block NSManagedObjectID *objectId;
|
||||
|
||||
|
||||
[MagicalRecord saveUsingCurrentThreadContextWithBlock:^(NSManagedObjectContext *localContext) {
|
||||
NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:localContext];
|
||||
|
||||
|
||||
[[@([inserted hasChanges]) should] beTrue];
|
||||
|
||||
|
||||
[localContext obtainPermanentIDsForObjects:@[inserted] error:nil];
|
||||
objectId = [inserted objectID];
|
||||
} completion:^(BOOL success, NSError *error) {
|
||||
[[@(success) should] beTrue];
|
||||
saveSuccessState = success;
|
||||
saveError = error;
|
||||
}];
|
||||
|
||||
[[expectFutureValue(@(saveSuccessState)) shouldEventually] beTrue];
|
||||
[[expectFutureValue(saveError) shouldEventually] beNil];
|
||||
[[expectFutureValue(objectId) shouldEventually] beNonNil];
|
||||
|
||||
NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectWithID:objectId];
|
||||
|
||||
|
||||
NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
|
||||
|
||||
[[expectFutureValue(fetchedObject) shouldEventually] beNonNil];
|
||||
[[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beFalse];
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context(@"deprecated method", ^{
|
||||
context(@"simple save", ^{
|
||||
it(@"should save", ^{
|
||||
NSManagedObjectContext *managedObjectContext = [NSManagedObjectContext MR_defaultContext];
|
||||
NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createEntity];
|
||||
|
||||
[[@([inserted hasChanges]) should] beTrue];
|
||||
|
||||
[managedObjectContext obtainPermanentIDsForObjects:@[inserted] error:nil];
|
||||
NSManagedObjectID *objectId = [inserted objectID];
|
||||
|
||||
[[objectId should] beNonNil];
|
||||
|
||||
[[[managedObjectContext should] receive] MR_save];
|
||||
[managedObjectContext MR_save];
|
||||
|
||||
NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectWithID:objectId];
|
||||
|
||||
[[fetchedObject should] beNonNil];
|
||||
[[@([fetchedObject hasChanges]) should] beFalse];
|
||||
});
|
||||
});
|
||||
|
||||
context(@"save action", ^{
|
||||
|
||||
|
||||
// We're testing for deprecated method function — ignore the warnings
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
|
||||
context(@"deprecated method", ^{
|
||||
context(@"saveWithBlock:", ^{
|
||||
it(@"should save", ^{
|
||||
__block NSManagedObjectID *objectId;
|
||||
|
||||
|
||||
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
|
||||
NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:localContext];
|
||||
|
||||
|
||||
[[@([inserted hasChanges]) should] beTrue];
|
||||
|
||||
|
||||
[localContext obtainPermanentIDsForObjects:@[inserted] error:nil];
|
||||
objectId = [inserted objectID];
|
||||
}];
|
||||
|
||||
|
||||
[[objectId should] beNonNil];
|
||||
|
||||
NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectWithID:objectId];
|
||||
|
||||
NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
|
||||
|
||||
[[objectId should] beNonNil];
|
||||
[[fetchedObject should] beNonNil];
|
||||
[[@([fetchedObject hasChanges]) should] beFalse];
|
||||
});
|
||||
});
|
||||
|
||||
context(@"background save action", ^{
|
||||
it(@"should call completion block", ^{
|
||||
__block BOOL completionBlockCalled = NO;
|
||||
|
||||
[MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *localContext) {
|
||||
[SingleEntityWithNoRelationships MR_createInContext:localContext];
|
||||
} completion:^{
|
||||
// Ignore the success state — we only care that this block is executed
|
||||
completionBlockCalled = YES;
|
||||
}];
|
||||
|
||||
[[expectFutureValue(@(completionBlockCalled)) shouldEventually] beTrue];
|
||||
});
|
||||
|
||||
|
||||
context(@"saveInBackgroundWithBlock:", ^{
|
||||
it(@"should save", ^{
|
||||
__block NSManagedObjectID *objectId;
|
||||
__block NSManagedObject *fetchedObject;
|
||||
|
||||
|
||||
[MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *localContext) {
|
||||
NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:localContext];
|
||||
|
||||
|
||||
[[@([inserted hasChanges]) should] beTrue];
|
||||
|
||||
|
||||
[localContext obtainPermanentIDsForObjects:@[inserted] error:nil];
|
||||
objectId = [inserted objectID];
|
||||
} completion:^{
|
||||
[[objectId should] beNonNil];
|
||||
|
||||
fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectWithID:objectId];
|
||||
}];
|
||||
|
||||
|
||||
[[expectFutureValue(objectId) shouldEventually] beNonNil];
|
||||
|
||||
NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
|
||||
|
||||
[[expectFutureValue(objectId) shouldEventually] beNonNil];
|
||||
[[expectFutureValue(fetchedObject) shouldEventually] beNonNil];
|
||||
[[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beFalse];
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
context(@"saveInBackgroundWithBlock:completion:", ^{
|
||||
it(@"should call completion block", ^{
|
||||
__block BOOL completionBlockCalled = NO;
|
||||
|
||||
[MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *localContext) {
|
||||
[SingleEntityWithNoRelationships MR_createInContext:localContext];
|
||||
} completion:^{
|
||||
completionBlockCalled = YES;
|
||||
}];
|
||||
|
||||
[[expectFutureValue(@(completionBlockCalled)) shouldEventually] beTrue];
|
||||
});
|
||||
|
||||
it(@"should save", ^{
|
||||
__block NSManagedObjectID *objectId;
|
||||
__block NSManagedObject *fetchedObject;
|
||||
|
||||
[MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *localContext) {
|
||||
NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:localContext];
|
||||
|
||||
[[@([inserted hasChanges])should] beTrue];
|
||||
|
||||
[localContext obtainPermanentIDsForObjects:@[inserted] error:nil];
|
||||
objectId = [inserted objectID];
|
||||
} completion:^{
|
||||
[[objectId should] beNonNil];
|
||||
|
||||
fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
|
||||
}];
|
||||
|
||||
[[expectFutureValue(objectId) shouldEventually] beNonNil];
|
||||
[[expectFutureValue(fetchedObject) shouldEventually] beNonNil];
|
||||
[[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beFalse];
|
||||
});
|
||||
});
|
||||
|
||||
context(@"saveInBackgroundUsingCurrentContextWithBlock:completion:errorHandler:", ^{
|
||||
|
||||
context(@"should call", ^{
|
||||
__block BOOL completionBlockCalled = NO;
|
||||
__block BOOL errorBlockCalled = NO;
|
||||
|
||||
afterEach(^{
|
||||
completionBlockCalled = NO;
|
||||
errorBlockCalled = NO;
|
||||
});
|
||||
|
||||
it(@"completion block", ^{
|
||||
[MagicalRecord saveInBackgroundUsingCurrentContextWithBlock:^(NSManagedObjectContext *localContext) {
|
||||
[SingleEntityWithNoRelationships MR_createInContext:localContext];
|
||||
} completion:^{
|
||||
completionBlockCalled = YES;
|
||||
} errorHandler:^(NSError *error) {
|
||||
errorBlockCalled = YES;
|
||||
}];
|
||||
|
||||
[[expectFutureValue(@(completionBlockCalled)) shouldEventually] beTrue];
|
||||
[[expectFutureValue(@(errorBlockCalled)) shouldEventually] beFalse];
|
||||
});
|
||||
|
||||
it(@"error handler when there is an error", ^{
|
||||
[MagicalRecord saveInBackgroundUsingCurrentContextWithBlock:^(NSManagedObjectContext *localContext) {
|
||||
// Don't make any changes so that an error is triggered
|
||||
} completion:^{
|
||||
completionBlockCalled = YES;
|
||||
} errorHandler:^(NSError *error) {
|
||||
errorBlockCalled = YES;
|
||||
}];
|
||||
|
||||
[[expectFutureValue(@(completionBlockCalled)) shouldEventually] beFalse];
|
||||
[[expectFutureValue(@(errorBlockCalled)) shouldEventually] beTrue];
|
||||
});
|
||||
});
|
||||
|
||||
it(@"should save", ^{
|
||||
__block NSError *saveError;
|
||||
__block NSManagedObjectID *objectId;
|
||||
__block NSManagedObject *fetchedObject;
|
||||
|
||||
[MagicalRecord saveInBackgroundUsingCurrentContextWithBlock:^(NSManagedObjectContext *localContext) {
|
||||
NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:localContext];
|
||||
|
||||
[[@([inserted hasChanges])should] beTrue];
|
||||
|
||||
[localContext obtainPermanentIDsForObjects:@[inserted] error:nil];
|
||||
objectId = [inserted objectID];
|
||||
} completion:^{
|
||||
[[objectId should] beNonNil];
|
||||
|
||||
fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
|
||||
} errorHandler:^(NSError *error) {
|
||||
saveError = error;
|
||||
}];
|
||||
|
||||
[[expectFutureValue(objectId) shouldEventually] beNonNil];
|
||||
[[expectFutureValue(saveError) shouldEventually] beNil];
|
||||
[[expectFutureValue(fetchedObject) shouldEventually] beNonNil];
|
||||
[[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beFalse];
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
#pragma clang diagnostic pop // ignored "-Wdeprecated-declarations"
|
||||
|
||||
});
|
||||
|
||||
SPEC_END
|
||||
|
||||
@@ -6,73 +6,519 @@
|
||||
SPEC_BEGIN(NSManagedObjectContextMagicalSavesSpec)
|
||||
|
||||
describe(@"NSManagedObjectContext+MagicalSaves", ^{
|
||||
beforeEach(^{
|
||||
// Occurs before each enclosed "it" block
|
||||
beforeEach (^{
|
||||
// Occurs before each enclosed "it" block
|
||||
[MagicalRecord setDefaultModelFromClass:[self class]];
|
||||
[MagicalRecord setupCoreDataStackWithInMemoryStore];
|
||||
});
|
||||
|
||||
afterEach(^{
|
||||
// Occurs after each enclosed "it" block
|
||||
});
|
||||
|
||||
afterEach (^{
|
||||
// Occurs after each enclosed "it" block
|
||||
[MagicalRecord cleanUp];
|
||||
});
|
||||
|
||||
context(@"saving synchronously", ^{
|
||||
it(@"should save", ^{
|
||||
NSManagedObjectContext *managedObjectContext = [NSManagedObjectContext MR_contextWithParent:[NSManagedObjectContext MR_defaultContext]];
|
||||
NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
|
||||
|
||||
[[@([inserted hasChanges]) should] beTrue];
|
||||
|
||||
[managedObjectContext obtainPermanentIDsForObjects:@[inserted] error:nil];
|
||||
NSManagedObjectID *objectId = inserted.objectID;
|
||||
|
||||
[managedObjectContext MR_saveToPersistentStoreAndWait];
|
||||
|
||||
NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectWithID:objectId];
|
||||
|
||||
[[fetchedObject should] beNonNil];
|
||||
[[@([fetchedObject hasChanges]) should] beFalse];
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
context(@"saving asynchronously", ^{
|
||||
it(@"should call completion block", ^{
|
||||
__block BOOL completionBlockCalled = NO;
|
||||
|
||||
NSManagedObjectContext *managedObjectContext = [NSManagedObjectContext MR_contextForCurrentThread];
|
||||
|
||||
[SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
|
||||
|
||||
[managedObjectContext MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
|
||||
completionBlockCalled = YES;
|
||||
}];
|
||||
|
||||
[[expectFutureValue(@(completionBlockCalled)) shouldEventually] beTrue];
|
||||
|
||||
context(@"be able to save to self only", ^{
|
||||
__block NSManagedObjectContext *managedObjectContext;
|
||||
|
||||
beforeEach (^{
|
||||
managedObjectContext = [NSManagedObjectContext MR_context];
|
||||
});
|
||||
|
||||
it(@"should save", ^{
|
||||
__block NSManagedObjectID *objectId;
|
||||
NSManagedObjectContext *managedObjectContext = [NSManagedObjectContext MR_contextWithParent:[NSManagedObjectContext MR_defaultContext]];
|
||||
NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
|
||||
|
||||
[[@([inserted hasChanges]) should] beTrue];
|
||||
|
||||
[managedObjectContext MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
|
||||
|
||||
afterEach (^{
|
||||
[managedObjectContext reset];
|
||||
managedObjectContext = nil;
|
||||
});
|
||||
|
||||
context(@"synchronously", ^{
|
||||
it(@"should save", ^{
|
||||
NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
|
||||
|
||||
[[@([inserted hasChanges]) should] beTrue];
|
||||
|
||||
[managedObjectContext obtainPermanentIDsForObjects:@[inserted] error:nil];
|
||||
objectId = inserted.objectID;
|
||||
}];
|
||||
|
||||
[[expectFutureValue(objectId) shouldEventually] beNonNil];
|
||||
|
||||
NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectWithID:objectId];
|
||||
|
||||
[[expectFutureValue(fetchedObject) shouldEventually] beNonNil];
|
||||
[[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beFalse];
|
||||
NSManagedObjectID *objectId = [inserted objectID];
|
||||
|
||||
[managedObjectContext MR_saveOnlySelfAndWait];
|
||||
|
||||
NSManagedObject *rootFetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
|
||||
|
||||
[rootFetchedObject shouldBeNil];
|
||||
[[@([rootFetchedObject hasChanges]) should] beFalse];
|
||||
|
||||
rootFetchedObject = [managedObjectContext objectRegisteredForID:objectId];
|
||||
|
||||
[rootFetchedObject shouldNotBeNil];
|
||||
[[@([rootFetchedObject hasChanges]) should] beFalse];
|
||||
});
|
||||
});
|
||||
|
||||
context(@"asynchronously", ^{
|
||||
it(@"should call completion block", ^{
|
||||
__block BOOL completionBlockCalled = NO;
|
||||
|
||||
[SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
|
||||
|
||||
[managedObjectContext MR_saveOnlySelfWithCompletion:^(BOOL success, NSError *error) {
|
||||
completionBlockCalled = YES;
|
||||
}];
|
||||
|
||||
[[expectFutureValue(@(completionBlockCalled)) shouldEventually] beTrue];
|
||||
});
|
||||
|
||||
it(@"should save", ^{
|
||||
__block NSManagedObjectID *objectId;
|
||||
NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
|
||||
|
||||
[[@([inserted hasChanges]) should] beTrue];
|
||||
|
||||
[managedObjectContext MR_saveOnlySelfWithCompletion:^(BOOL success, NSError *error) {
|
||||
[managedObjectContext obtainPermanentIDsForObjects:@[inserted] error:nil];
|
||||
objectId = [inserted objectID];
|
||||
}];
|
||||
|
||||
[[expectFutureValue(objectId) shouldEventually] beNonNil];
|
||||
|
||||
NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
|
||||
|
||||
[[expectFutureValue(fetchedObject) shouldEventually] beNil];
|
||||
[[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beFalse];
|
||||
|
||||
fetchedObject = [managedObjectContext objectRegisteredForID:objectId];
|
||||
|
||||
[[expectFutureValue(fetchedObject) shouldEventually] beNonNil];
|
||||
[[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beFalse];
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
context(@"be able to save to the persistent store", ^{
|
||||
__block NSManagedObjectContext *managedObjectContext;
|
||||
|
||||
beforeEach (^{
|
||||
managedObjectContext = [NSManagedObjectContext MR_context];
|
||||
});
|
||||
|
||||
afterEach (^{
|
||||
[managedObjectContext reset];
|
||||
managedObjectContext = nil;
|
||||
});
|
||||
|
||||
context(@"synchronously", ^{
|
||||
it(@"and should save", ^{
|
||||
NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
|
||||
|
||||
[[@([managedObjectContext hasChanges]) should] beTrue];
|
||||
[[@([inserted hasChanges]) should] beTrue];
|
||||
|
||||
[managedObjectContext obtainPermanentIDsForObjects:@[inserted] error:nil];
|
||||
NSManagedObjectID *objectId = [inserted objectID];
|
||||
|
||||
[managedObjectContext MR_saveToPersistentStoreAndWait];
|
||||
|
||||
NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
|
||||
|
||||
[fetchedObject shouldNotBeNil];
|
||||
[[@([fetchedObject hasChanges]) should] beFalse];
|
||||
});
|
||||
});
|
||||
|
||||
context(@"asynchronously", ^{
|
||||
it(@"and should call completion block", ^{
|
||||
__block BOOL completionBlockCalled = NO;
|
||||
|
||||
[SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
|
||||
|
||||
[[@([managedObjectContext hasChanges]) should] beTrue];
|
||||
|
||||
[managedObjectContext MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
|
||||
completionBlockCalled = YES;
|
||||
}];
|
||||
|
||||
[[expectFutureValue(@(completionBlockCalled)) shouldEventually] beTrue];
|
||||
});
|
||||
|
||||
it(@"and should save", ^{
|
||||
__block NSManagedObjectID *objectId;
|
||||
|
||||
NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
|
||||
|
||||
[[@([managedObjectContext hasChanges]) should] beTrue];
|
||||
[[@([inserted hasChanges]) should] beTrue];
|
||||
|
||||
[managedObjectContext MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
|
||||
[managedObjectContext obtainPermanentIDsForObjects:@[inserted] error:nil];
|
||||
objectId = [inserted objectID];
|
||||
}];
|
||||
|
||||
[[expectFutureValue(objectId) shouldEventually] beNonNil];
|
||||
|
||||
NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
|
||||
|
||||
[[expectFutureValue(fetchedObject) shouldEventually] beNonNil];
|
||||
[[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beFalse];
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
context(@"be able to save with options", ^{
|
||||
__block NSManagedObjectContext *managedObjectContext;
|
||||
__block NSManagedObjectID *permanentObjectID;
|
||||
__block NSManagedObject *insertedObject;
|
||||
|
||||
beforeEach (^{
|
||||
managedObjectContext = [NSManagedObjectContext MR_context];
|
||||
insertedObject = [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
|
||||
[managedObjectContext obtainPermanentIDsForObjects:@[insertedObject] error:nil];
|
||||
});
|
||||
|
||||
afterEach (^{
|
||||
[managedObjectContext reset];
|
||||
|
||||
permanentObjectID = nil;
|
||||
insertedObject = nil;
|
||||
managedObjectContext = nil;
|
||||
});
|
||||
|
||||
context(@"synchronously", ^{
|
||||
beforeEach(^{
|
||||
permanentObjectID = [insertedObject objectID];
|
||||
[permanentObjectID shouldNotBeNil];
|
||||
});
|
||||
|
||||
specify (^{
|
||||
[[@([managedObjectContext hasChanges]) should] beTrue];
|
||||
[[@([insertedObject hasChanges]) should] beTrue];
|
||||
});
|
||||
|
||||
it(@"to self only", ^{
|
||||
[managedObjectContext MR_saveWithOptions:MRSaveSynchronously completion:^(BOOL success, NSError *error) {
|
||||
[[@(success) should] beTrue];
|
||||
[error shouldBeNil];
|
||||
}];
|
||||
|
||||
NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:permanentObjectID];
|
||||
[fetchedObject shouldBeNil];
|
||||
[[@([fetchedObject hasChanges]) should] beFalse];
|
||||
});
|
||||
|
||||
it(@"to persistent store", ^{
|
||||
[managedObjectContext MR_saveWithOptions:MRSaveSynchronously | MRSaveParentContexts completion:^(BOOL success, NSError *error) {
|
||||
[[@(success) should] beTrue];
|
||||
[error shouldBeNil];
|
||||
}];
|
||||
|
||||
NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:permanentObjectID];
|
||||
[fetchedObject shouldNotBeNil];
|
||||
[[@([fetchedObject hasChanges]) should] beFalse];
|
||||
});
|
||||
});
|
||||
|
||||
context(@"asynchronously", ^{
|
||||
it(@"to self only", ^{
|
||||
[managedObjectContext MR_saveWithOptions:0 completion:^(BOOL success, NSError *error) {
|
||||
[[@(success) should] beTrue];
|
||||
[error shouldBeNil];
|
||||
|
||||
[managedObjectContext obtainPermanentIDsForObjects:@[insertedObject] error:nil];
|
||||
permanentObjectID = [insertedObject objectID];
|
||||
}];
|
||||
|
||||
[[expectFutureValue(permanentObjectID) shouldEventually] beNonNil];
|
||||
|
||||
NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:permanentObjectID];
|
||||
[[expectFutureValue(fetchedObject) shouldEventually] beNil];
|
||||
[[@([fetchedObject hasChanges]) should] beFalse];
|
||||
});
|
||||
|
||||
it(@"to persistent store", ^{
|
||||
[managedObjectContext MR_saveWithOptions:MRSaveParentContexts completion:^(BOOL success, NSError *error) {
|
||||
[[@(success) should] beTrue];
|
||||
[error shouldBeNil];
|
||||
|
||||
[managedObjectContext obtainPermanentIDsForObjects:@[insertedObject] error:nil];
|
||||
permanentObjectID = [insertedObject objectID];
|
||||
}];
|
||||
|
||||
[[expectFutureValue(permanentObjectID) shouldEventually] beNonNil];
|
||||
|
||||
NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:permanentObjectID];
|
||||
[[expectFutureValue(fetchedObject) shouldEventually] beNonNil];
|
||||
[[@([fetchedObject hasChanges]) should] beFalse];
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// We're testing for deprecated method function — ignore the warnings
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
|
||||
context(@"deprecated method", ^{
|
||||
__block NSManagedObjectContext *managedObjectContext;
|
||||
|
||||
beforeEach (^{
|
||||
managedObjectContext = [NSManagedObjectContext MR_contextWithParent:[NSManagedObjectContext MR_defaultContext]];
|
||||
});
|
||||
|
||||
afterEach (^{
|
||||
[managedObjectContext reset];
|
||||
managedObjectContext = nil;
|
||||
});
|
||||
|
||||
context(@"MR_save", ^{
|
||||
it(@"should save", ^{
|
||||
NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
|
||||
|
||||
[[@([inserted hasChanges]) should] beTrue];
|
||||
|
||||
[managedObjectContext obtainPermanentIDsForObjects:@[inserted] error:nil];
|
||||
NSManagedObjectID *objectId = [inserted objectID];
|
||||
|
||||
[managedObjectContext MR_save];
|
||||
|
||||
NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
|
||||
|
||||
[fetchedObject shouldNotBeNil];
|
||||
[[@([fetchedObject hasChanges]) should] beFalse];
|
||||
});
|
||||
});
|
||||
|
||||
context(@"MR_saveWithErrorCallback", ^{
|
||||
it(@"should call error handler on errors", ^{
|
||||
__block BOOL errorHandlerCalled = NO;
|
||||
|
||||
[managedObjectContext MR_saveWithErrorCallback:^(NSError *error) {
|
||||
errorHandlerCalled = YES;
|
||||
}];
|
||||
|
||||
[[@(errorHandlerCalled) should] beTrue];
|
||||
});
|
||||
|
||||
it(@"should save", ^{
|
||||
NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
|
||||
|
||||
[[@([inserted hasChanges]) should] beTrue];
|
||||
|
||||
[managedObjectContext obtainPermanentIDsForObjects:@[inserted] error:nil];
|
||||
NSManagedObjectID *objectId = [inserted objectID];
|
||||
|
||||
__block BOOL errorHandlerCalled = NO;
|
||||
__block NSError *saveError;
|
||||
|
||||
[managedObjectContext MR_saveWithErrorCallback:^(NSError *error) {
|
||||
saveError = error;
|
||||
errorHandlerCalled = YES;
|
||||
}];
|
||||
|
||||
[saveError shouldBeNil];
|
||||
[[@(errorHandlerCalled) should] beFalse];
|
||||
|
||||
NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
|
||||
|
||||
[fetchedObject shouldNotBeNil];
|
||||
[[@([fetchedObject hasChanges]) should] beFalse];
|
||||
});
|
||||
});
|
||||
|
||||
context(@"MR_saveInBackgroundErrorHandler", ^{
|
||||
it(@"should call error handler on errors", ^{
|
||||
__block BOOL errorHandlerCalled = NO;
|
||||
|
||||
[managedObjectContext MR_saveInBackgroundErrorHandler:^(NSError *error) {
|
||||
errorHandlerCalled = YES;
|
||||
}];
|
||||
|
||||
[[expectFutureValue(@(errorHandlerCalled)) shouldEventually] beTrue];
|
||||
});
|
||||
|
||||
it(@"should save to self, and be present in parent context", ^{
|
||||
NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
|
||||
|
||||
[[@([inserted hasChanges]) should] beTrue];
|
||||
|
||||
[managedObjectContext obtainPermanentIDsForObjects:@[inserted] error:nil];
|
||||
NSManagedObjectID *objectId = [inserted objectID];
|
||||
|
||||
__block BOOL errorHandlerCalled = NO;
|
||||
__block NSError *saveError;
|
||||
|
||||
[managedObjectContext MR_saveInBackgroundErrorHandler:^(NSError *error) {
|
||||
saveError = error;
|
||||
errorHandlerCalled = YES;
|
||||
}];
|
||||
|
||||
[[expectFutureValue(@([inserted hasChanges])) shouldEventually] beFalse];
|
||||
|
||||
// There should be no errors
|
||||
[[expectFutureValue(saveError) shouldEventually] beNil];
|
||||
[[expectFutureValue(@(errorHandlerCalled)) shouldEventually] beFalse];
|
||||
|
||||
// Retrieve the object from the root saving context, and check that it's valid
|
||||
NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
|
||||
|
||||
[[expectFutureValue(fetchedObject) shouldEventually] beNil];
|
||||
[[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beFalse];
|
||||
|
||||
// Check that the object has been passed up to the parent context, but that the fetched object has unsaved changes
|
||||
fetchedObject = [[managedObjectContext parentContext] objectRegisteredForID:objectId];
|
||||
|
||||
[[expectFutureValue(fetchedObject) shouldEventually] beNonNil];
|
||||
[[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beTrue];
|
||||
});
|
||||
});
|
||||
|
||||
context(@"MR_saveInBackgroundErrorHandler", ^{
|
||||
it(@"should call completion block", ^{
|
||||
__block BOOL completionBlockCalled = NO;
|
||||
__block BOOL errorHandlerCalled = NO;
|
||||
|
||||
[SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
|
||||
|
||||
[managedObjectContext MR_saveInBackgroundErrorHandler:^(NSError *error) {
|
||||
errorHandlerCalled = YES;
|
||||
} completion:^{
|
||||
completionBlockCalled = YES;
|
||||
}];
|
||||
|
||||
[[expectFutureValue(@(errorHandlerCalled)) shouldEventually] beFalse];
|
||||
[[expectFutureValue(@(completionBlockCalled)) shouldEventually] beTrue];
|
||||
});
|
||||
|
||||
it(@"should call error handler on errors", ^{
|
||||
__block BOOL completionBlockCalled = NO;
|
||||
__block BOOL errorHandlerCalled = NO;
|
||||
|
||||
[managedObjectContext MR_saveInBackgroundErrorHandler:^(NSError *error) {
|
||||
errorHandlerCalled = YES;
|
||||
} completion:^{
|
||||
completionBlockCalled = YES;
|
||||
}];
|
||||
|
||||
[[expectFutureValue(@(errorHandlerCalled)) shouldEventually] beTrue];
|
||||
[[expectFutureValue(@(completionBlockCalled)) shouldEventually] beFalse];
|
||||
});
|
||||
|
||||
it(@"should save to self, and be present in parent context", ^{
|
||||
NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
|
||||
|
||||
[[@([inserted hasChanges]) should] beTrue];
|
||||
|
||||
[managedObjectContext obtainPermanentIDsForObjects:@[inserted] error:nil];
|
||||
NSManagedObjectID *objectId = [inserted objectID];
|
||||
|
||||
__block BOOL errorHandlerCalled = NO;
|
||||
__block NSError *saveError;
|
||||
|
||||
[managedObjectContext MR_saveInBackgroundErrorHandler:^(NSError *error) {
|
||||
saveError = error;
|
||||
errorHandlerCalled = YES;
|
||||
}];
|
||||
|
||||
[[expectFutureValue(@([inserted hasChanges])) shouldEventually] beFalse];
|
||||
|
||||
// There should be no errors
|
||||
[[expectFutureValue(saveError) shouldEventually] beNil];
|
||||
[[expectFutureValue(@(errorHandlerCalled)) shouldEventually] beFalse];
|
||||
|
||||
// Retrieve the object from the root saving context, and check that it's valid
|
||||
NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
|
||||
|
||||
[[expectFutureValue(fetchedObject) shouldEventually] beNil];
|
||||
[[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beFalse];
|
||||
|
||||
// Check that the object has been passed up to the parent context, but that the fetched object has unsaved changes
|
||||
fetchedObject = [[managedObjectContext parentContext] objectRegisteredForID:objectId];
|
||||
|
||||
[[expectFutureValue(fetchedObject) shouldEventually] beNonNil];
|
||||
[[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beTrue];
|
||||
});
|
||||
});
|
||||
|
||||
context(@"MR_saveNestedContextsErrorHandler", ^{
|
||||
it(@"should call error handler on errors", ^{
|
||||
__block BOOL errorHandlerCalled = NO;
|
||||
|
||||
[managedObjectContext MR_saveNestedContextsErrorHandler:^(NSError *error) {
|
||||
errorHandlerCalled = YES;
|
||||
}];
|
||||
|
||||
[[@(errorHandlerCalled) should] beTrue];
|
||||
});
|
||||
|
||||
it(@"should save", ^{
|
||||
NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
|
||||
|
||||
[[@([inserted hasChanges]) should] beTrue];
|
||||
|
||||
[managedObjectContext obtainPermanentIDsForObjects:@[inserted] error:nil];
|
||||
NSManagedObjectID *objectId = [inserted objectID];
|
||||
|
||||
__block BOOL errorHandlerCalled = NO;
|
||||
__block NSError *saveError;
|
||||
|
||||
[managedObjectContext MR_saveNestedContextsErrorHandler:^(NSError *error) {
|
||||
saveError = error;
|
||||
errorHandlerCalled = YES;
|
||||
}];
|
||||
|
||||
[[expectFutureValue(saveError) shouldEventually] beNil];
|
||||
[[expectFutureValue(@(errorHandlerCalled)) shouldEventually] beFalse];
|
||||
|
||||
NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
|
||||
|
||||
[[expectFutureValue(fetchedObject) shouldEventually] beNonNil];
|
||||
[[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beFalse];
|
||||
});
|
||||
});
|
||||
|
||||
context(@"MR_saveInBackgroundErrorHandler", ^{
|
||||
it(@"should call error handler on errors", ^{
|
||||
__block BOOL errorHandlerCalled = NO;
|
||||
|
||||
[managedObjectContext MR_saveInBackgroundErrorHandler:^(NSError *error) {
|
||||
errorHandlerCalled = YES;
|
||||
}];
|
||||
|
||||
[[expectFutureValue(@(errorHandlerCalled)) shouldEventually] beTrue];
|
||||
});
|
||||
|
||||
it(@"should save to self, and be present in parent context", ^{
|
||||
NSManagedObject *inserted = [SingleEntityWithNoRelationships MR_createInContext:managedObjectContext];
|
||||
|
||||
[[@([inserted hasChanges]) should] beTrue];
|
||||
|
||||
[managedObjectContext obtainPermanentIDsForObjects:@[inserted] error:nil];
|
||||
NSManagedObjectID *objectId = [inserted objectID];
|
||||
|
||||
__block BOOL errorHandlerCalled = NO;
|
||||
__block NSError *saveError;
|
||||
|
||||
[managedObjectContext MR_saveInBackgroundErrorHandler:^(NSError *error) {
|
||||
saveError = error;
|
||||
errorHandlerCalled = YES;
|
||||
}];
|
||||
|
||||
[[expectFutureValue(@([inserted hasChanges])) shouldEventually] beFalse];
|
||||
|
||||
// There should be no errors
|
||||
[[expectFutureValue(saveError) shouldEventually] beNil];
|
||||
[[expectFutureValue(@(errorHandlerCalled)) shouldEventually] beFalse];
|
||||
|
||||
// Retrieve the object from the root saving context, and check that it's valid
|
||||
NSManagedObject *fetchedObject = [[NSManagedObjectContext MR_rootSavingContext] objectRegisteredForID:objectId];
|
||||
|
||||
[[expectFutureValue(fetchedObject) shouldEventually] beNil];
|
||||
[[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beFalse];
|
||||
|
||||
// Check that the object has been passed up to the parent context, but that the fetched object has unsaved changes
|
||||
fetchedObject = [[managedObjectContext parentContext] objectRegisteredForID:objectId];
|
||||
|
||||
[[expectFutureValue(fetchedObject) shouldEventually] beNonNil];
|
||||
[[expectFutureValue(@([fetchedObject hasChanges])) shouldEventually] beTrue];
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
#pragma clang diagnostic pop // ignored "-Wdeprecated-declarations"
|
||||
});
|
||||
|
||||
SPEC_END
|
||||
|
||||
Reference in New Issue
Block a user