mirror of
https://github.com/Instagram/IGListKit
synced 2026-05-23 09:18:29 +00:00
implement performExperimentalUpdateAnimated
Summary: Lets implement `performExperimentalUpdateAnimated`. There's a couple of things happening: * We're now using the `IGListTransitionData` container object * We don't need `pendingTransitionToObjects` anymore because we query the `fromObjects` just before performing the diffing. * We should update the unit tests to use `performExperimentalUpdateAnimated` since the regular `performUpdateAnimated` will now fail. Reviewed By: patters Differential Revision: D23145781 fbshipit-source-id: 0b896e918241e709c5eb23f56a6b7323521a2222
This commit is contained in:
parent
088d932707
commit
caf058c85a
5 changed files with 260 additions and 187 deletions
|
|
@ -393,7 +393,7 @@
|
|||
if (strongSelf == nil) {
|
||||
return nil;
|
||||
}
|
||||
NSArray *toObjects = [dataSource objectsForListAdapter:strongSelf];
|
||||
NSArray *toObjects = objectsWithDuplicateIdentifiersRemoved([dataSource objectsForListAdapter:strongSelf]);
|
||||
return [strongSelf _generateTransitionDataWithObjects:toObjects dataSource:dataSource];
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#import <IGListDiffKit/IGListMacros.h>
|
||||
#import <IGListKit/IGListAdapterUpdaterCompatible.h>
|
||||
#import <IGListKit/IGListUpdatingDelegateExperimental.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
|
|
@ -24,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
*/
|
||||
IGLK_SUBCLASSING_RESTRICTED
|
||||
NS_SWIFT_NAME(ListExperimentalAdapterUpdater)
|
||||
@interface IGListExperimentalAdapterUpdater : NSObject <IGListAdapterUpdaterCompatible>
|
||||
@interface IGListExperimentalAdapterUpdater : NSObject <IGListAdapterUpdaterCompatible, IGListUpdatingDelegateExperimental>
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@
|
|||
#import <IGListDiffKit/IGListAssert.h>
|
||||
|
||||
#import "IGListAdapterUpdaterHelpers.h"
|
||||
#import "IGListArrayUtilsInternal.h"
|
||||
#import "IGListIndexSetResultInternal.h"
|
||||
#import "IGListMoveIndexPathInternal.h"
|
||||
#import "IGListReloadIndexPath.h"
|
||||
#import "IGListTransitionData.h"
|
||||
#import "UICollectionView+IGListBatchUpdateData.h"
|
||||
|
||||
typedef void (^IGListAdapterUpdaterDiffResultBlock)(IGListIndexSetResult *);
|
||||
|
|
@ -50,8 +50,7 @@ typedef void (^IGListAdapterUpdaterCompletionBlock)(BOOL);
|
|||
- (BOOL)hasChanges {
|
||||
return self.hasQueuedReloadData
|
||||
|| [self.batchUpdates hasChanges]
|
||||
|| self.fromObjects != nil
|
||||
|| self.toObjectsBlock != nil;
|
||||
|| self.dataBlock != nil;
|
||||
}
|
||||
|
||||
- (void)performReloadDataWithCollectionViewBlock:(IGListCollectionViewBlock)collectionViewBlock {
|
||||
|
|
@ -118,10 +117,9 @@ typedef void (^IGListAdapterUpdaterCompletionBlock)(BOOL);
|
|||
|
||||
// create local variables so we can immediately clean our state but pass these items into the batch update block
|
||||
id<IGListAdapterUpdaterDelegate> delegate = self.delegate;
|
||||
NSArray *fromObjects = [self.fromObjects copy];
|
||||
IGListToObjectBlock toObjectsBlock = [self.toObjectsBlock copy];
|
||||
IGListTransitionDataBlock dataBlock = [self.dataBlock copy];
|
||||
IGListTransitionDataApplyBlock applyDataBlock = [self.applyDataBlock copy];
|
||||
NSMutableArray *completionBlocks = [self.completionBlocks mutableCopy];
|
||||
void (^objectTransitionBlock)(NSArray *) = [self.objectTransitionBlock copy];
|
||||
const BOOL animated = self.queuedUpdateIsAnimated;
|
||||
const BOOL allowsReloadingOnTooManyUpdates = self.allowsReloadingOnTooManyUpdates;
|
||||
const IGListExperiment experiments = self.experiments;
|
||||
|
|
@ -148,10 +146,15 @@ typedef void (^IGListAdapterUpdaterCompletionBlock)(BOOL);
|
|||
return;
|
||||
}
|
||||
|
||||
NSArray *toObjects = nil;
|
||||
if (toObjectsBlock != nil) {
|
||||
toObjects = objectsWithDuplicateIdentifiersRemoved(toObjectsBlock());
|
||||
|
||||
IGListTransitionData *data = nil;
|
||||
if (dataBlock != nil) {
|
||||
data = dataBlock();
|
||||
}
|
||||
|
||||
NSArray *toObjects = data.toObjects;
|
||||
NSArray *fromObjects = data.fromObjects;
|
||||
|
||||
#ifdef DEBUG
|
||||
for (id obj in toObjects) {
|
||||
IGAssert([obj conformsToProtocol:@protocol(IGListDiffable)],
|
||||
|
|
@ -167,8 +170,8 @@ typedef void (^IGListAdapterUpdaterCompletionBlock)(BOOL);
|
|||
// run the update block so that the adapter can set its items. this makes sure that just before the update is
|
||||
// committed that the data source is updated to the /latest/ "toObjects". this makes the data source in sync
|
||||
// with the items that the updater is transitioning to
|
||||
if (objectTransitionBlock != nil) {
|
||||
objectTransitionBlock(toObjects);
|
||||
if (applyDataBlock != nil && data != nil) {
|
||||
applyDataBlock(data);
|
||||
}
|
||||
|
||||
// execute each item update block which should make calls like insert, delete, and reload for index paths
|
||||
|
|
@ -189,7 +192,6 @@ typedef void (^IGListAdapterUpdaterCompletionBlock)(BOOL);
|
|||
[delegate listAdapterUpdater:self willReloadDataWithCollectionView:collectionView isFallbackReload:YES];
|
||||
executeUpdateBlocks();
|
||||
[self _cleanStateAfterUpdates];
|
||||
[self _performBatchUpdatesItemBlockApplied];
|
||||
[collectionView reloadData];
|
||||
[collectionView layoutIfNeeded];
|
||||
executeCompletionBlocks(YES);
|
||||
|
|
@ -201,7 +203,7 @@ typedef void (^IGListAdapterUpdaterCompletionBlock)(BOOL);
|
|||
};
|
||||
|
||||
// disables multiple performBatchUpdates: from happening at the same time
|
||||
[self _beginPerformBatchUpdatesToObjects:toObjects];
|
||||
self.state = IGListBatchUpdateStateQueuedBatchUpdate;
|
||||
|
||||
// if the collection view isn't in a visible window, skip diffing and batch updating. execute all transition blocks,
|
||||
// reload data, execute completion blocks, and get outta here
|
||||
|
|
@ -239,7 +241,6 @@ typedef void (^IGListAdapterUpdaterCompletionBlock)(BOOL);
|
|||
}
|
||||
|
||||
[self _cleanStateAfterUpdates];
|
||||
[self _performBatchUpdatesItemBlockApplied];
|
||||
};
|
||||
|
||||
// block used as the second param of -[UICollectionView performBatchUpdates:completion:]
|
||||
|
|
@ -312,28 +313,18 @@ willPerformBatchUpdatesWithCollectionView:collectionView
|
|||
});
|
||||
}
|
||||
|
||||
- (void)_beginPerformBatchUpdatesToObjects:(NSArray *)toObjects {
|
||||
self.pendingTransitionToObjects = toObjects;
|
||||
self.state = IGListBatchUpdateStateQueuedBatchUpdate;
|
||||
}
|
||||
|
||||
- (void)_performBatchUpdatesItemBlockApplied {
|
||||
self.pendingTransitionToObjects = nil;
|
||||
}
|
||||
|
||||
- (void)cleanStateBeforeUpdates {
|
||||
self.queuedUpdateIsAnimated = YES;
|
||||
|
||||
// destroy to/from transition items
|
||||
self.fromObjects = nil;
|
||||
self.toObjectsBlock = nil;
|
||||
self.dataBlock = nil;
|
||||
|
||||
// destroy reloadData state
|
||||
self.reloadUpdates = nil;
|
||||
self.queuedReloadData = NO;
|
||||
|
||||
// remove indexpath/item changes
|
||||
self.objectTransitionBlock = nil;
|
||||
self.applyDataBlock = nil;
|
||||
|
||||
// removes all object completion blocks. done before updates to start collecting completion blocks for coalesced
|
||||
// or re-entrant object updates
|
||||
|
|
@ -395,25 +386,30 @@ static NSUInteger IGListIdentifierHash(const void *item, NSUInteger (*size)(cons
|
|||
animated:(BOOL)animated
|
||||
objectTransitionBlock:(IGListObjectTransitionBlock)objectTransitionBlock
|
||||
completion:(IGListUpdatingCompletion)completion {
|
||||
IGFailAssert(@"IGListExperimentalAdapterUpdater works with IGListUpdatingDelegateExperimental and doesn't implement the regular -performUpdateWithCollectionViewBlock method");
|
||||
completion(NO);
|
||||
}
|
||||
|
||||
- (void)performExperimentalUpdateAnimated:(BOOL)animated
|
||||
collectionViewBlock:(IGListCollectionViewBlock)collectionViewBlock
|
||||
dataBlock:(IGListTransitionDataBlock)dataBlock
|
||||
applyDataBlock:(IGListTransitionDataApplyBlock)applyDataBlock
|
||||
completion:(IGListUpdatingCompletion)completion {
|
||||
IGAssertMainThread();
|
||||
IGParameterAssert(collectionViewBlock != nil);
|
||||
IGParameterAssert(objectTransitionBlock != nil);
|
||||
IGParameterAssert(dataBlock != nil);
|
||||
IGParameterAssert(applyDataBlock != nil);
|
||||
|
||||
// only update the items that we are coming from if it has not been set
|
||||
// this allows multiple updates to be called while an update is already in progress, and the transition from > to
|
||||
// will be done on the first "fromObjects" received and the last "toObjects"
|
||||
// if performBatchUpdates: hasn't applied the update block, then data source hasn't transitioned its state. if an
|
||||
// update is queued in between then we must use the pending toObjects
|
||||
self.fromObjects = self.fromObjects ?: self.pendingTransitionToObjects ?: fromObjects;
|
||||
self.toObjectsBlock = toObjectsBlock;
|
||||
// will call the dataBlock after the dispatch
|
||||
self.dataBlock = dataBlock;
|
||||
|
||||
// always use the last update block, even though this should always do the exact same thing
|
||||
self.applyDataBlock = applyDataBlock;
|
||||
|
||||
// disabled animations will always take priority
|
||||
// reset to YES in -cleanupState
|
||||
self.queuedUpdateIsAnimated = self.queuedUpdateIsAnimated && animated;
|
||||
|
||||
// always use the last update block, even though this should always do the exact same thing
|
||||
self.objectTransitionBlock = objectTransitionBlock;
|
||||
|
||||
IGListUpdatingCompletion localCompletion = completion;
|
||||
if (localCompletion) {
|
||||
[self.completionBlocks addObject:localCompletion];
|
||||
|
|
@ -422,6 +418,7 @@ static NSUInteger IGListIdentifierHash(const void *item, NSUInteger (*size)(cons
|
|||
[self _queueUpdateWithCollectionViewBlock:collectionViewBlock];
|
||||
}
|
||||
|
||||
|
||||
- (void)performUpdateWithCollectionViewBlock:(IGListCollectionViewBlock)collectionViewBlock
|
||||
animated:(BOOL)animated
|
||||
itemUpdates:(void (^)(void))itemUpdates
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
#import <IGListDiffKit/IGListMoveIndexPath.h>
|
||||
#import <IGListKit/IGListUpdatingDelegateExperimental.h>
|
||||
|
||||
#import "IGListExperimentalAdapterUpdater.h"
|
||||
#import "IGListBatchUpdateState.h"
|
||||
|
|
@ -18,16 +19,14 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
@interface IGListExperimentalAdapterUpdater ()
|
||||
|
||||
@property (nonatomic, copy, nullable) NSArray *fromObjects;
|
||||
@property (nonatomic, copy, nullable) IGListToObjectBlock toObjectsBlock;
|
||||
@property (nonatomic, copy, nullable) NSArray *pendingTransitionToObjects;
|
||||
@property (nonatomic, copy, nullable) IGListTransitionDataBlock dataBlock;
|
||||
@property (nonatomic, strong) NSMutableArray<IGListUpdatingCompletion> *completionBlocks;
|
||||
|
||||
@property (nonatomic, assign) BOOL queuedUpdateIsAnimated;
|
||||
|
||||
@property (nonatomic, strong) IGListBatchUpdates *batchUpdates;
|
||||
|
||||
@property (nonatomic, copy, nullable) IGListObjectTransitionBlock objectTransitionBlock;
|
||||
@property (nonatomic, copy, nullable) IGListTransitionDataApplyBlock applyDataBlock;
|
||||
|
||||
@property (nonatomic, copy, nullable) IGListReloadUpdateBlock reloadUpdates;
|
||||
@property (nonatomic, assign, getter=hasQueuedReloadData) BOOL queuedReloadData;
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
#import "IGListExperimentalAdapterUpdaterInternal.h"
|
||||
#import "IGListMoveIndexInternal.h"
|
||||
#import "IGListTestUICollectionViewDataSource.h"
|
||||
#import "IGListTransitionData.h"
|
||||
#import "IGTestObject.h"
|
||||
|
||||
#define genExpectation [self expectationWithDescription:NSStringFromSelector(_cmd)]
|
||||
|
|
@ -27,7 +28,7 @@
|
|||
@property (nonatomic, strong) UICollectionView *collectionView;
|
||||
@property (nonatomic, strong) IGListTestUICollectionViewDataSource *dataSource;
|
||||
@property (nonatomic, strong) IGListExperimentalAdapterUpdater *updater;
|
||||
@property (nonatomic, strong) IGListObjectTransitionBlock updateBlock;
|
||||
@property (nonatomic, strong) IGListTransitionDataApplyBlock applyDataBlock;
|
||||
|
||||
@end
|
||||
|
||||
|
|
@ -37,6 +38,12 @@
|
|||
return ^UICollectionView *{ return self.collectionView; };
|
||||
}
|
||||
|
||||
- (IGListTransitionDataBlock)dataBlockFromObjects:(NSArray *)fromObjects toObjects:(NSArray *)toObjects {
|
||||
return ^IGListTransitionData *{
|
||||
return [[IGListTransitionData alloc] initFromObjects:fromObjects toObjects:toObjects toSectionControllers:@[]];
|
||||
};
|
||||
}
|
||||
|
||||
- (void)setUp {
|
||||
[super setUp];
|
||||
|
||||
|
|
@ -50,8 +57,8 @@
|
|||
self.dataSource = [[IGListTestUICollectionViewDataSource alloc] initWithCollectionView:self.collectionView];
|
||||
self.updater = [IGListExperimentalAdapterUpdater new];
|
||||
__weak __typeof__(self) weakSelf = self;
|
||||
self.updateBlock = ^(NSArray *obj) {
|
||||
weakSelf.dataSource.sections = obj;
|
||||
self.applyDataBlock = ^(IGListTransitionData *data) {
|
||||
weakSelf.dataSource.sections = data.toObjects;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -63,28 +70,39 @@
|
|||
self.updater = nil;
|
||||
}
|
||||
|
||||
- (void)test_whenUpdatingWithNil_thatUpdaterHasNoChanges {
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] fromObjects:nil toObjectsBlock:nil animated:YES objectTransitionBlock:self.updateBlock completion:nil];
|
||||
XCTAssertFalse([self.updater hasChanges]);
|
||||
}
|
||||
|
||||
- (void)test_whenUpdatingtoObjects_thatUpdaterHasChanges {
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] fromObjects:nil toObjectsBlock:^NSArray *{return @[@0];} animated:YES objectTransitionBlock:self.updateBlock completion:nil];
|
||||
[self.updater performExperimentalUpdateAnimated:YES
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:@[] toObjects:@[@0]]
|
||||
applyDataBlock:self.applyDataBlock
|
||||
completion:nil];
|
||||
XCTAssertTrue([self.updater hasChanges]);
|
||||
}
|
||||
|
||||
- (void)test_whenUpdatingfromObjects_thatUpdaterHasChanges {
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] fromObjects:@[@0] toObjectsBlock:^NSArray *{return nil;} animated:YES objectTransitionBlock:self.updateBlock completion:nil];
|
||||
[self.updater performExperimentalUpdateAnimated:YES
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:@[@0] toObjects:@[]]
|
||||
applyDataBlock:self.applyDataBlock
|
||||
completion:nil];
|
||||
XCTAssertTrue([self.updater hasChanges]);
|
||||
}
|
||||
|
||||
- (void)test_whenUpdatingtoObjects_withfromObjects_thatUpdaterHasChanges {
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] fromObjects:@[@0] toObjectsBlock:^NSArray *{return @[@1];} animated:YES objectTransitionBlock:self.updateBlock completion:nil];
|
||||
[self.updater performExperimentalUpdateAnimated:YES
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:@[@0] toObjects:@[@1]]
|
||||
applyDataBlock:self.applyDataBlock
|
||||
completion:nil];
|
||||
XCTAssertTrue([self.updater hasChanges]);
|
||||
}
|
||||
|
||||
- (void)test_whenCleaningUpState_withChanges_thatUpdaterHasNoChanges {
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] fromObjects:nil toObjectsBlock:^NSArray *{return @[@0];} animated:YES objectTransitionBlock:self.updateBlock completion:nil];
|
||||
[self.updater performExperimentalUpdateAnimated:YES
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:@[] toObjects:@[@0]]
|
||||
applyDataBlock:self.applyDataBlock
|
||||
completion:nil];
|
||||
XCTAssertTrue([self.updater hasChanges]);
|
||||
[self.updater cleanStateBeforeUpdates];
|
||||
XCTAssertFalse([self.updater hasChanges]);
|
||||
|
|
@ -112,21 +130,23 @@
|
|||
|
||||
- (void)test_whenInsertingSection_thatCollectionViewUpdates {
|
||||
NSArray *from = @[
|
||||
[IGSectionObject sectionWithObjects:@[]]
|
||||
];
|
||||
IGListToObjectBlock to = ^NSArray *{
|
||||
return @[
|
||||
[IGSectionObject sectionWithObjects:@[]],
|
||||
[IGSectionObject sectionWithObjects:@[]]
|
||||
];
|
||||
};
|
||||
[IGSectionObject sectionWithObjects:@[]]
|
||||
];
|
||||
NSArray *to = @[
|
||||
[IGSectionObject sectionWithObjects:@[]],
|
||||
[IGSectionObject sectionWithObjects:@[]]
|
||||
];
|
||||
|
||||
self.dataSource.sections = from;
|
||||
[self.updater performReloadDataWithCollectionViewBlock:[self collectionViewBlock]];
|
||||
XCTAssertEqual([self.collectionView numberOfSections], 1);
|
||||
|
||||
XCTestExpectation *expectation = genExpectation;
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] fromObjects:from toObjectsBlock:to animated:YES objectTransitionBlock:self.updateBlock completion:^(BOOL finished) {
|
||||
[self.updater performExperimentalUpdateAnimated:YES
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:from toObjects:to]
|
||||
applyDataBlock:self.applyDataBlock
|
||||
completion:^(BOOL finished) {
|
||||
XCTAssertEqual([self.collectionView numberOfSections], 2);
|
||||
[expectation fulfill];
|
||||
}];
|
||||
|
|
@ -135,21 +155,23 @@
|
|||
|
||||
- (void)test_whenDeletingSection_thatCollectionViewUpdates {
|
||||
NSArray *from = @[
|
||||
[IGSectionObject sectionWithObjects:@[]],
|
||||
[IGSectionObject sectionWithObjects:@[]]
|
||||
];
|
||||
IGListToObjectBlock to = ^NSArray *{
|
||||
return @[
|
||||
[IGSectionObject sectionWithObjects:@[]]
|
||||
];
|
||||
};
|
||||
[IGSectionObject sectionWithObjects:@[]],
|
||||
[IGSectionObject sectionWithObjects:@[]]
|
||||
];
|
||||
NSArray *to = @[
|
||||
[IGSectionObject sectionWithObjects:@[]]
|
||||
];
|
||||
|
||||
self.dataSource.sections = from;
|
||||
[self.updater performReloadDataWithCollectionViewBlock:[self collectionViewBlock]];
|
||||
XCTAssertEqual([self.collectionView numberOfSections], 2);
|
||||
|
||||
XCTestExpectation *expectation = genExpectation;
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] fromObjects:from toObjectsBlock:to animated:YES objectTransitionBlock:self.updateBlock completion:^(BOOL finished) {
|
||||
[self.updater performExperimentalUpdateAnimated:YES
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:from toObjects:to]
|
||||
applyDataBlock:self.applyDataBlock
|
||||
completion:^(BOOL finished) {
|
||||
XCTAssertEqual([self.collectionView numberOfSections], 1);
|
||||
[expectation fulfill];
|
||||
}];
|
||||
|
|
@ -158,14 +180,12 @@
|
|||
|
||||
- (void)test_whenInsertingSection_withItemChanges_thatCollectionViewUpdates {
|
||||
NSArray *from = @[
|
||||
[IGSectionObject sectionWithObjects:@[@0]]
|
||||
];
|
||||
IGListToObjectBlock to = ^NSArray *{
|
||||
return @[
|
||||
[IGSectionObject sectionWithObjects:@[@0, @1]],
|
||||
[IGSectionObject sectionWithObjects:@[@0, @1]]
|
||||
];
|
||||
};
|
||||
[IGSectionObject sectionWithObjects:@[@0]]
|
||||
];
|
||||
NSArray *to = @[
|
||||
[IGSectionObject sectionWithObjects:@[@0, @1]],
|
||||
[IGSectionObject sectionWithObjects:@[@0, @1]]
|
||||
];
|
||||
|
||||
self.dataSource.sections = from;
|
||||
[self.updater performReloadDataWithCollectionViewBlock:[self collectionViewBlock]];
|
||||
|
|
@ -173,7 +193,11 @@
|
|||
XCTAssertEqual([self.collectionView numberOfItemsInSection:0], 1);
|
||||
|
||||
XCTestExpectation *expectation = genExpectation;
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] fromObjects:from toObjectsBlock:to animated:YES objectTransitionBlock:self.updateBlock completion:^(BOOL finished) {
|
||||
[self.updater performExperimentalUpdateAnimated:YES
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:from toObjects:to]
|
||||
applyDataBlock:self.applyDataBlock
|
||||
completion:^(BOOL finished) {
|
||||
XCTAssertEqual([self.collectionView numberOfSections], 2);
|
||||
XCTAssertEqual([self.collectionView numberOfItemsInSection:0], 2);
|
||||
XCTAssertEqual([self.collectionView numberOfItemsInSection:1], 2);
|
||||
|
|
@ -184,16 +208,14 @@
|
|||
|
||||
- (void)test_whenInsertingSection_withDeletedSection_thatCollectionViewUpdates {
|
||||
NSArray *from = @[
|
||||
[IGSectionObject sectionWithObjects:@[@0, @1, @2]],
|
||||
[IGSectionObject sectionWithObjects:@[]]
|
||||
];
|
||||
IGListToObjectBlock to = ^NSArray *{
|
||||
return @[
|
||||
[IGSectionObject sectionWithObjects:@[@1, @1]],
|
||||
[IGSectionObject sectionWithObjects:@[@0]],
|
||||
[IGSectionObject sectionWithObjects:@[@0, @2, @3]]
|
||||
];
|
||||
};
|
||||
[IGSectionObject sectionWithObjects:@[@0, @1, @2]],
|
||||
[IGSectionObject sectionWithObjects:@[]]
|
||||
];
|
||||
NSArray *to = @[
|
||||
[IGSectionObject sectionWithObjects:@[@1, @1]],
|
||||
[IGSectionObject sectionWithObjects:@[@0]],
|
||||
[IGSectionObject sectionWithObjects:@[@0, @2, @3]]
|
||||
];
|
||||
|
||||
self.dataSource.sections = from;
|
||||
[self.updater performReloadDataWithCollectionViewBlock:[self collectionViewBlock]];
|
||||
|
|
@ -202,7 +224,11 @@
|
|||
XCTAssertEqual([self.collectionView numberOfItemsInSection:0], 3);
|
||||
|
||||
XCTestExpectation *expectation = genExpectation;
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] fromObjects:from toObjectsBlock:to animated:NO objectTransitionBlock:self.updateBlock completion:^(BOOL finished) {
|
||||
[self.updater performExperimentalUpdateAnimated:NO
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:from toObjects:to]
|
||||
applyDataBlock:self.applyDataBlock
|
||||
completion:^(BOOL finished) {
|
||||
XCTAssertEqual([self.collectionView numberOfSections], 3);
|
||||
XCTAssertEqual([self.collectionView numberOfItemsInSection:0], 2);
|
||||
XCTAssertEqual([self.collectionView numberOfItemsInSection:1], 1);
|
||||
|
|
@ -235,14 +261,12 @@
|
|||
|
||||
- (void)test_whenCollectionViewNeedsLayout_thatPerformBatchUpdateWorks {
|
||||
NSArray *from = @[
|
||||
[IGSectionObject sectionWithObjects:@[]],
|
||||
[IGSectionObject sectionWithObjects:@[]]
|
||||
];
|
||||
IGListToObjectBlock to = ^NSArray *{
|
||||
return @[
|
||||
[IGSectionObject sectionWithObjects:@[]]
|
||||
];
|
||||
};
|
||||
[IGSectionObject sectionWithObjects:@[]],
|
||||
[IGSectionObject sectionWithObjects:@[]]
|
||||
];
|
||||
NSArray *to = @[
|
||||
[IGSectionObject sectionWithObjects:@[]]
|
||||
];
|
||||
|
||||
self.dataSource.sections = from;
|
||||
[self.updater performReloadDataWithCollectionViewBlock:[self collectionViewBlock]];
|
||||
|
|
@ -253,7 +277,11 @@
|
|||
[self.collectionView setNeedsLayout];
|
||||
|
||||
XCTestExpectation *expectation = genExpectation;
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] fromObjects:from toObjectsBlock:to animated:NO objectTransitionBlock:self.updateBlock completion:^(BOOL finished) {
|
||||
[self.updater performExperimentalUpdateAnimated:NO
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:from toObjects:to]
|
||||
applyDataBlock:self.applyDataBlock
|
||||
completion:^(BOOL finished) {
|
||||
XCTAssertEqual([self.collectionView numberOfSections], 1);
|
||||
[expectation fulfill];
|
||||
}];
|
||||
|
|
@ -262,14 +290,12 @@
|
|||
|
||||
- (void)test_whenUpdatesAreReentrant_thatUpdatesExecuteSerially {
|
||||
NSArray *from = @[
|
||||
[IGSectionObject sectionWithObjects:@[]],
|
||||
];
|
||||
IGListToObjectBlock to = ^NSArray *{
|
||||
return @[
|
||||
[IGSectionObject sectionWithObjects:@[]],
|
||||
[IGSectionObject sectionWithObjects:@[]],
|
||||
];
|
||||
};
|
||||
[IGSectionObject sectionWithObjects:@[]],
|
||||
];
|
||||
NSArray *to = @[
|
||||
[IGSectionObject sectionWithObjects:@[]],
|
||||
[IGSectionObject sectionWithObjects:@[]],
|
||||
];
|
||||
|
||||
self.dataSource.sections = from;
|
||||
[self.updater performReloadDataWithCollectionViewBlock:[self collectionViewBlock]];
|
||||
|
|
@ -278,14 +304,16 @@
|
|||
|
||||
XCTestExpectation *expectation1 = genExpectation;
|
||||
void (^preUpdateBlock)(void) = ^{
|
||||
NSArray *(^anotherTo)(void) = ^NSArray *{
|
||||
return @[
|
||||
[IGSectionObject sectionWithObjects:@[]],
|
||||
[IGSectionObject sectionWithObjects:@[]],
|
||||
[IGSectionObject sectionWithObjects:@[]]
|
||||
];
|
||||
};
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] fromObjects:from toObjectsBlock:anotherTo animated:YES objectTransitionBlock:self.updateBlock completion:^(BOOL finished) {
|
||||
NSArray *anotherTo = @[
|
||||
[IGSectionObject sectionWithObjects:@[]],
|
||||
[IGSectionObject sectionWithObjects:@[]],
|
||||
[IGSectionObject sectionWithObjects:@[]]
|
||||
];
|
||||
[self.updater performExperimentalUpdateAnimated:YES
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:to toObjects:anotherTo]
|
||||
applyDataBlock:self.applyDataBlock
|
||||
completion:^(BOOL finished) {
|
||||
completionCounter++;
|
||||
XCTAssertEqual([self.collectionView numberOfSections], 3);
|
||||
XCTAssertEqual(completionCounter, 2);
|
||||
|
|
@ -294,14 +322,18 @@
|
|||
};
|
||||
|
||||
XCTestExpectation *expectation2 = genExpectation;
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] fromObjects:from toObjectsBlock:to animated:YES objectTransitionBlock:^(NSArray *toObjects) {
|
||||
[self.updater performExperimentalUpdateAnimated:YES
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:from toObjects:to]
|
||||
applyDataBlock:^(IGListTransitionData *data) {
|
||||
// executing this block within the updater is just before performBatchUpdates: are applied
|
||||
// should be able to queue another update here, similar to an update being queued between it beginning and executing
|
||||
// the performBatchUpdates: block
|
||||
preUpdateBlock();
|
||||
|
||||
self.dataSource.sections = toObjects;
|
||||
} completion:^(BOOL finished) {
|
||||
self.dataSource.sections = data.toObjects;
|
||||
}
|
||||
completion:^(BOOL finished) {
|
||||
completionCounter++;
|
||||
XCTAssertEqual([self.collectionView numberOfSections], 2);
|
||||
XCTAssertEqual(completionCounter, 1);
|
||||
|
|
@ -328,14 +360,14 @@
|
|||
__block BOOL itemUpdateBlockExecuted = NO;
|
||||
__block BOOL sectionUpdateBlockExecuted = NO;
|
||||
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock]
|
||||
fromObjects:nil
|
||||
toObjectsBlock:^NSArray *{return @[[IGSectionObject sectionWithObjects:@[@1]]];}
|
||||
animated:YES objectTransitionBlock:^(NSArray * toObjects) {
|
||||
self.dataSource.sections = toObjects;
|
||||
sectionUpdateBlockExecuted = YES;
|
||||
}
|
||||
completion:nil];
|
||||
[self.updater performExperimentalUpdateAnimated:YES
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:@[] toObjects:@[[IGSectionObject sectionWithObjects:@[@1]]]]
|
||||
applyDataBlock:^(IGListTransitionData * data) {
|
||||
self.dataSource.sections = data.toObjects;
|
||||
sectionUpdateBlockExecuted = YES;
|
||||
}
|
||||
completion:nil];
|
||||
|
||||
XCTestExpectation *expectation = genExpectation;
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] animated:YES itemUpdates:^{
|
||||
|
|
@ -353,10 +385,10 @@
|
|||
|
||||
- (void)test_whenItemsMoveAndUpdate_thatCollectionViewWorks {
|
||||
NSArray<IGSectionObject *> *from = @[
|
||||
[IGSectionObject sectionWithObjects:@[]],
|
||||
[IGSectionObject sectionWithObjects:@[]],
|
||||
[IGSectionObject sectionWithObjects:@[]],
|
||||
];
|
||||
[IGSectionObject sectionWithObjects:@[]],
|
||||
[IGSectionObject sectionWithObjects:@[]],
|
||||
[IGSectionObject sectionWithObjects:@[]],
|
||||
];
|
||||
|
||||
// change the number of items in the section, which a move would be unable to handle and would throw
|
||||
// keep the same pointers so that the objects are equal
|
||||
|
|
@ -364,14 +396,11 @@
|
|||
[from[0] setObjects:@[@1, @1]];
|
||||
[from[1] setObjects:@[@1, @1, @1]];
|
||||
|
||||
IGListToObjectBlock to = ^NSArray *{
|
||||
// rearrange the modified objects
|
||||
return @[
|
||||
from[2],
|
||||
from[0],
|
||||
from[1]
|
||||
];
|
||||
};
|
||||
NSArray *to = @[
|
||||
from[2],
|
||||
from[0],
|
||||
from[1]
|
||||
];
|
||||
|
||||
self.dataSource.sections = from;
|
||||
[self.updater performReloadDataWithCollectionViewBlock:[self collectionViewBlock]];
|
||||
|
|
@ -380,7 +409,11 @@
|
|||
self.updater.sectionMovesAsDeletesInserts = YES;
|
||||
|
||||
XCTestExpectation *expectation = genExpectation;
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] fromObjects:from toObjectsBlock:to animated:YES objectTransitionBlock:self.updateBlock completion:^(BOOL finished) {
|
||||
[self.updater performExperimentalUpdateAnimated:YES
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:from toObjects:to]
|
||||
applyDataBlock:self.applyDataBlock
|
||||
completion:^(BOOL finished) {
|
||||
XCTAssertEqual([self.collectionView numberOfSections], 3);
|
||||
XCTAssertEqual([self.collectionView numberOfItemsInSection:0], 1);
|
||||
XCTAssertEqual([self.collectionView numberOfItemsInSection:1], 2);
|
||||
|
|
@ -508,7 +541,11 @@
|
|||
[[mockDelegate expect] listAdapterUpdater:self.updater didPerformBatchUpdates:OCMOCK_ANY collectionView:self.collectionView];
|
||||
|
||||
XCTestExpectation *expectation = genExpectation;
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] fromObjects:self.dataSource.sections toObjectsBlock:genToBlock animated:NO objectTransitionBlock:self.updateBlock completion:^(BOOL finished) {
|
||||
[self.updater performExperimentalUpdateAnimated:NO
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:self.dataSource.sections toObjects:to]
|
||||
applyDataBlock:self.applyDataBlock
|
||||
completion:^(BOOL finished) {
|
||||
[expectation fulfill];
|
||||
}];
|
||||
waitExpectation;
|
||||
|
|
@ -526,12 +563,14 @@
|
|||
[[mockDelegate expect] listAdapterUpdater:self.updater didReloadDataWithCollectionView:self.collectionView isFallbackReload:YES];
|
||||
|
||||
XCTestExpectation *expectation = genExpectation;
|
||||
IGListToObjectBlock to = ^NSArray *{
|
||||
return @[
|
||||
[IGSectionObject sectionWithObjects:@[]]
|
||||
];
|
||||
};
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] fromObjects:self.dataSource.sections toObjectsBlock:to animated:NO objectTransitionBlock:self.updateBlock completion:^(BOOL finished) {
|
||||
NSArray *to = @[
|
||||
[IGSectionObject sectionWithObjects:@[]]
|
||||
];
|
||||
[self.updater performExperimentalUpdateAnimated:NO
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:self.dataSource.sections toObjects:to]
|
||||
applyDataBlock:self.applyDataBlock
|
||||
completion:^(BOOL finished) {
|
||||
[expectation fulfill];
|
||||
}];
|
||||
waitExpectation;
|
||||
|
|
@ -549,13 +588,15 @@
|
|||
[[mockDelegate expect] listAdapterUpdater:self.updater didReloadDataWithCollectionView:self.collectionView isFallbackReload:YES];
|
||||
|
||||
XCTestExpectation *expectation = genExpectation;
|
||||
IGListToObjectBlock to = ^NSArray *{
|
||||
return @[
|
||||
[IGSectionObject sectionWithObjects:@[]]
|
||||
];
|
||||
};
|
||||
NSArray *to = @[
|
||||
[IGSectionObject sectionWithObjects:@[]]
|
||||
];
|
||||
self.collectionView.dataSource = nil;
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] fromObjects:self.dataSource.sections toObjectsBlock:to animated:NO objectTransitionBlock:self.updateBlock completion:^(BOOL finished) {
|
||||
[self.updater performExperimentalUpdateAnimated:NO
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:self.dataSource.sections toObjects:to]
|
||||
applyDataBlock:self.applyDataBlock
|
||||
completion:^(BOOL finished) {
|
||||
[expectation fulfill];
|
||||
}];
|
||||
waitExpectation;
|
||||
|
|
@ -572,7 +613,8 @@
|
|||
}];
|
||||
|
||||
XCTestExpectation *expectation = genExpectation;
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] animated:YES itemUpdates:^{
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock]
|
||||
animated:YES itemUpdates:^{
|
||||
object.objects = @[@2, @1, @4, @5];
|
||||
[self.updater insertItemsIntoCollectionView:self.collectionView indexPaths:@[
|
||||
[NSIndexPath indexPathForItem:2 inSection:0],
|
||||
|
|
@ -600,16 +642,15 @@
|
|||
|
||||
__block BOOL objectTransitionBlockExecuted = NO;
|
||||
__block BOOL completionBlockExecuted = NO;
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock]
|
||||
fromObjects:self.dataSource.sections
|
||||
toObjectsBlock:^NSArray *{return self.dataSource.sections;}
|
||||
animated:YES
|
||||
objectTransitionBlock:^(NSArray *toObjects) {
|
||||
objectTransitionBlockExecuted = YES;
|
||||
}
|
||||
completion:^(BOOL finished) {
|
||||
completionBlockExecuted = YES;
|
||||
}];
|
||||
[self.updater performExperimentalUpdateAnimated:YES
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:self.dataSource.sections toObjects:self.dataSource.sections]
|
||||
applyDataBlock:^(IGListTransitionData *data) {
|
||||
objectTransitionBlockExecuted = YES;
|
||||
}
|
||||
completion:^(BOOL finished) {
|
||||
completionBlockExecuted = YES;
|
||||
}];
|
||||
|
||||
XCTestExpectation *expectation = genExpectation;
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] animated:YES itemUpdates:^{
|
||||
|
|
@ -712,7 +753,11 @@
|
|||
|
||||
XCTestExpectation *expectation = genExpectation;
|
||||
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] fromObjects:from toObjectsBlock:genToBlock animated:NO objectTransitionBlock:self.updateBlock completion:^(BOOL finished) {
|
||||
[self.updater performExperimentalUpdateAnimated:NO
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:from toObjects:to]
|
||||
applyDataBlock:self.applyDataBlock
|
||||
completion:^(BOOL finished) {
|
||||
[expectation fulfill];
|
||||
}];
|
||||
waitExpectation;
|
||||
|
|
@ -734,8 +779,12 @@
|
|||
// Manually set the data source to be nil.
|
||||
self->_collectionView.dataSource = nil;
|
||||
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] fromObjects:from toObjectsBlock:genToBlock animated:NO objectTransitionBlock:^(NSArray * _Nonnull toObjects) {
|
||||
} completion:^(BOOL finished) {
|
||||
[self.updater performExperimentalUpdateAnimated:NO
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:from toObjects:to]
|
||||
applyDataBlock:^(IGListTransitionData *data) {
|
||||
}
|
||||
completion:^(BOOL finished) {
|
||||
[expectation fulfill];
|
||||
}];
|
||||
waitExpectation;
|
||||
|
|
@ -785,23 +834,25 @@
|
|||
[IGSectionObject sectionWithObjects:@[@0, @1]],
|
||||
[IGSectionObject sectionWithObjects:@[@0, @1]]
|
||||
];
|
||||
IGListToObjectBlock toObjectsBlock2 = ^NSArray *{
|
||||
return objects2;
|
||||
};
|
||||
IGListToObjectBlock toObjectsBlock3 = ^NSArray *{
|
||||
return objects3;
|
||||
};
|
||||
|
||||
self.dataSource.sections = objects1;
|
||||
[self.updater performReloadDataWithCollectionViewBlock:[self collectionViewBlock]];
|
||||
|
||||
XCTestExpectation *expectation = genExpectation;
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] fromObjects:objects1 toObjectsBlock:toObjectsBlock2 animated:YES objectTransitionBlock:self.updateBlock completion:^(BOOL finished) {
|
||||
[self.updater performExperimentalUpdateAnimated:YES
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:objects1 toObjects:objects2]
|
||||
applyDataBlock:self.applyDataBlock
|
||||
completion:^(BOOL finished) {
|
||||
XCTAssertEqual([self.collectionView numberOfSections], 2);
|
||||
XCTAssertEqual([self.collectionView numberOfItemsInSection:0], 2);
|
||||
XCTAssertEqual([self.collectionView numberOfItemsInSection:1], 2);
|
||||
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] fromObjects:objects2 toObjectsBlock:toObjectsBlock3 animated:YES objectTransitionBlock:self.updateBlock completion:^(BOOL finished2) {
|
||||
[self.updater performExperimentalUpdateAnimated:YES
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:objects2 toObjects:objects3]
|
||||
applyDataBlock:self.applyDataBlock
|
||||
completion:^(BOOL finished2) {
|
||||
XCTAssertEqual([self.collectionView numberOfSections], 3);
|
||||
XCTAssertEqual([self.collectionView numberOfItemsInSection:0], 2);
|
||||
XCTAssertEqual([self.collectionView numberOfItemsInSection:1], 2);
|
||||
|
|
@ -822,9 +873,6 @@
|
|||
[IGSectionObject sectionWithObjects:@[] identifier:@"0"],
|
||||
[IGSectionObject sectionWithObjects:@[] identifier:@"1"]
|
||||
];
|
||||
IGListToObjectBlock toBlock = ^NSArray *{
|
||||
return to;
|
||||
};
|
||||
|
||||
self.dataSource.sections = from;
|
||||
[self.updater performReloadDataWithCollectionViewBlock:[self collectionViewBlock]];
|
||||
|
|
@ -842,7 +890,11 @@
|
|||
|
||||
XCTestExpectation *expectation = genExpectation;
|
||||
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] fromObjects:from toObjectsBlock:toBlock animated:NO objectTransitionBlock:self.updateBlock completion:^(BOOL finished) {
|
||||
[self.updater performExperimentalUpdateAnimated:NO
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:from toObjects:to]
|
||||
applyDataBlock:self.applyDataBlock
|
||||
completion:^(BOOL finished) {
|
||||
[expectation fulfill];
|
||||
}];
|
||||
waitExpectation;
|
||||
|
|
@ -876,7 +928,11 @@
|
|||
|
||||
XCTestExpectation *expectation = genExpectation;
|
||||
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] fromObjects:from toObjectsBlock:genToBlock animated:NO objectTransitionBlock:self.updateBlock completion:^(BOOL finished) {
|
||||
[self.updater performExperimentalUpdateAnimated:NO
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:from toObjects:to]
|
||||
applyDataBlock:self.applyDataBlock
|
||||
completion:^(BOOL finished) {
|
||||
[expectation fulfill];
|
||||
}];
|
||||
waitExpectation;
|
||||
|
|
@ -908,7 +964,11 @@
|
|||
|
||||
XCTestExpectation *expectation = genExpectation;
|
||||
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] fromObjects:from toObjectsBlock:genToBlock animated:NO objectTransitionBlock:self.updateBlock completion:^(BOOL finished) {
|
||||
[self.updater performExperimentalUpdateAnimated:NO
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:from toObjects:to]
|
||||
applyDataBlock:self.applyDataBlock
|
||||
completion:^(BOOL finished) {
|
||||
[expectation fulfill];
|
||||
}];
|
||||
waitExpectation;
|
||||
|
|
@ -946,7 +1006,11 @@
|
|||
|
||||
XCTestExpectation *expectation = genExpectation;
|
||||
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] fromObjects:from toObjectsBlock:genToBlock animated:NO objectTransitionBlock:self.updateBlock completion:^(BOOL finished) {
|
||||
[self.updater performExperimentalUpdateAnimated:NO
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:from toObjects:to]
|
||||
applyDataBlock:self.applyDataBlock
|
||||
completion:^(BOOL finished) {
|
||||
[expectation fulfill];
|
||||
}];
|
||||
waitExpectation;
|
||||
|
|
@ -984,7 +1048,11 @@
|
|||
|
||||
XCTestExpectation *expectation = genExpectation;
|
||||
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] fromObjects:from toObjectsBlock:genToBlock animated:NO objectTransitionBlock:self.updateBlock completion:^(BOOL finished) {
|
||||
[self.updater performExperimentalUpdateAnimated:NO
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:from toObjects:to]
|
||||
applyDataBlock:self.applyDataBlock
|
||||
completion:^(BOOL finished) {
|
||||
[expectation fulfill];
|
||||
}];
|
||||
waitExpectation;
|
||||
|
|
@ -1024,7 +1092,11 @@
|
|||
|
||||
XCTestExpectation *expectation = genExpectation;
|
||||
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] fromObjects:from toObjectsBlock:genToBlock animated:NO objectTransitionBlock:self.updateBlock completion:^(BOOL finished) {
|
||||
[self.updater performExperimentalUpdateAnimated:NO
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:from toObjects:to]
|
||||
applyDataBlock:self.applyDataBlock
|
||||
completion:^(BOOL finished) {
|
||||
[expectation fulfill];
|
||||
}];
|
||||
waitExpectation;
|
||||
|
|
@ -1059,7 +1131,11 @@
|
|||
|
||||
XCTestExpectation *expectation = genExpectation;
|
||||
|
||||
[self.updater performUpdateWithCollectionViewBlock:[self collectionViewBlock] fromObjects:from toObjectsBlock:genToBlock animated:NO objectTransitionBlock:self.updateBlock completion:^(BOOL finished) {
|
||||
[self.updater performExperimentalUpdateAnimated:NO
|
||||
collectionViewBlock:[self collectionViewBlock]
|
||||
dataBlock:[self dataBlockFromObjects:from toObjects:to]
|
||||
applyDataBlock:self.applyDataBlock
|
||||
completion:^(BOOL finished) {
|
||||
[expectation fulfill];
|
||||
}];
|
||||
waitExpectation;
|
||||
|
|
|
|||
Loading…
Reference in a new issue