mirror of
https://github.com/Instagram/IGListKit
synced 2026-05-23 09:18:29 +00:00
Improve IGListWorkingRangeHandler Test Coverage
Summary: Added working range handler tests. This will allow changes/experiments to be made to the working range handler with improved confidence. Two of the added tests are currently disabled; working range updates don't currently take inserts and deletes into account and so these tests fail. Reviewed By: rnystrom Differential Revision: D13717357 fbshipit-source-id: dd4523d3162cfe13ee03e9d10ffa22b58514ca5f
This commit is contained in:
parent
035808e750
commit
3f5047dd9a
1 changed files with 298 additions and 7 deletions
|
|
@ -21,6 +21,10 @@
|
|||
- (instancetype)initWithObjects:(NSArray *)objects
|
||||
objectToControllerMap:(NSDictionary<id, IGListSectionController *> *)map;
|
||||
|
||||
- (void)insertObject:(id)object withController:(IGListSectionController *)controller atIndex:(NSInteger)index;
|
||||
|
||||
- (void)removeObjectAtIndex:(NSInteger)index;
|
||||
|
||||
@end
|
||||
|
||||
@implementation _IGTestWorkingRangeAdapterDataSource {
|
||||
|
|
@ -37,6 +41,24 @@
|
|||
return self;
|
||||
}
|
||||
|
||||
- (void)insertObject:(id)object withController:(IGListSectionController *)controller atIndex:(NSInteger)index {
|
||||
NSMutableArray *const objects = [_objects mutableCopy];
|
||||
NSMutableDictionary *const map = [_map mutableCopy];
|
||||
[objects insertObject:object atIndex:index];
|
||||
map[object] = controller;
|
||||
_objects = [objects copy];
|
||||
_map = [map copy];
|
||||
}
|
||||
|
||||
- (void)removeObjectAtIndex:(NSInteger)index {
|
||||
NSMutableArray *const objects = [_objects mutableCopy];
|
||||
NSMutableDictionary *const map = [_map mutableCopy];
|
||||
[map removeObjectForKey:[objects objectAtIndex:index]];
|
||||
[objects removeObjectAtIndex:index];
|
||||
_objects = [objects copy];
|
||||
_map = [map copy];
|
||||
}
|
||||
|
||||
- (UIView *)emptyViewForListAdapter:(IGListAdapter *)listAdapter {
|
||||
return nil;
|
||||
}
|
||||
|
|
@ -78,11 +100,145 @@
|
|||
|
||||
// Act: Tell the working range handler that the first, and only item in the list will be displayed.
|
||||
[[mockWorkingRangeDelegate expect] listAdapter:adapter sectionControllerWillEnterWorkingRange:controller];
|
||||
[adapter.workingRangeHandler willDisplayItemAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] forListAdapter:adapter];
|
||||
[adapter.workingRangeHandler willDisplayItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] forListAdapter:adapter];
|
||||
|
||||
[mockWorkingRangeDelegate verifyWithDelay:5];
|
||||
}
|
||||
|
||||
- (void)test_whenDisplayingItemAtPath_withWorkingRangeSizeZero_thatAdjacentItemsDoNotEnterWorkingRange {
|
||||
// Arrange 1: Set up a simple collection view and adapter with three elements.
|
||||
IGListTestSection *controller1 = [[IGListTestSection alloc] init];
|
||||
NSString *object1 = @"obj1";
|
||||
IGListTestSection *controller2 = [[IGListTestSection alloc] init];
|
||||
NSString *object2 = @"obj2";
|
||||
IGListTestSection *controller3 = [[IGListTestSection alloc] init];
|
||||
NSString *object3 = @"obj3";
|
||||
_IGTestWorkingRangeAdapterDataSource *ds = [[_IGTestWorkingRangeAdapterDataSource alloc] initWithObjects:@[object1, object2, object3]
|
||||
objectToControllerMap:@{object1: controller1,
|
||||
object2: controller2,
|
||||
object3: controller3}];
|
||||
IGListReloadDataUpdater *updater = [[IGListReloadDataUpdater alloc] init];
|
||||
IGListAdapter *adapter = [[IGListAdapter alloc] initWithUpdater:updater viewController:nil];
|
||||
id collectionView = [OCMockObject niceMockForClass:[UICollectionView class]];
|
||||
adapter.collectionView = collectionView;
|
||||
|
||||
id mockWorkingRangeDelegate1 = [OCMockObject mockForProtocol:@protocol(IGListWorkingRangeDelegate)];
|
||||
id mockWorkingRangeDelegate2 = [OCMockObject mockForProtocol:@protocol(IGListWorkingRangeDelegate)];
|
||||
id mockWorkingRangeDelegate3 = [OCMockObject mockForProtocol:@protocol(IGListWorkingRangeDelegate)];
|
||||
|
||||
adapter.dataSource = ds;
|
||||
controller1.workingRangeDelegate = mockWorkingRangeDelegate1;
|
||||
controller2.workingRangeDelegate = mockWorkingRangeDelegate2;
|
||||
controller3.workingRangeDelegate = mockWorkingRangeDelegate3;
|
||||
|
||||
// Arrange 2: Force an update so we get the objects we configured through the system.
|
||||
[adapter performUpdatesAnimated:NO completion:nil];
|
||||
|
||||
// Act: Tell the working range handler that the center item will be displayed.
|
||||
[[mockWorkingRangeDelegate1 reject] listAdapter:[OCMArg any] sectionControllerWillEnterWorkingRange:[OCMArg any]];
|
||||
[[mockWorkingRangeDelegate2 expect] listAdapter:adapter sectionControllerWillEnterWorkingRange:controller2];
|
||||
[[mockWorkingRangeDelegate3 reject] listAdapter:[OCMArg any] sectionControllerWillEnterWorkingRange:[OCMArg any]];
|
||||
[adapter.workingRangeHandler willDisplayItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:1] forListAdapter:adapter];
|
||||
|
||||
[mockWorkingRangeDelegate1 verifyWithDelay:5];
|
||||
[mockWorkingRangeDelegate2 verifyWithDelay:5];
|
||||
[mockWorkingRangeDelegate3 verifyWithDelay:5];
|
||||
}
|
||||
|
||||
- (void)test_whenDisplayingItemAtPath_withWorkingRangeSizeOne_thatAdjacentItemsEnterWorkingRange {
|
||||
// Arrange 1: Set up a simple collection view and adapter with three elements.
|
||||
IGListTestSection *controller1 = [[IGListTestSection alloc] init];
|
||||
NSString *object1 = @"obj1";
|
||||
IGListTestSection *controller2 = [[IGListTestSection alloc] init];
|
||||
NSString *object2 = @"obj2";
|
||||
IGListTestSection *controller3 = [[IGListTestSection alloc] init];
|
||||
NSString *object3 = @"obj3";
|
||||
_IGTestWorkingRangeAdapterDataSource *ds = [[_IGTestWorkingRangeAdapterDataSource alloc] initWithObjects:@[object1, object2, object3]
|
||||
objectToControllerMap:@{object1: controller1,
|
||||
object2: controller2,
|
||||
object3: controller3}];
|
||||
IGListReloadDataUpdater *updater = [[IGListReloadDataUpdater alloc] init];
|
||||
IGListAdapter *adapter = [[IGListAdapter alloc] initWithUpdater:updater viewController:nil workingRangeSize:1];
|
||||
id collectionView = [OCMockObject niceMockForClass:[UICollectionView class]];
|
||||
adapter.collectionView = collectionView;
|
||||
|
||||
id mockWorkingRangeDelegate1 = [OCMockObject mockForProtocol:@protocol(IGListWorkingRangeDelegate)];
|
||||
id mockWorkingRangeDelegate2 = [OCMockObject mockForProtocol:@protocol(IGListWorkingRangeDelegate)];
|
||||
id mockWorkingRangeDelegate3 = [OCMockObject mockForProtocol:@protocol(IGListWorkingRangeDelegate)];
|
||||
|
||||
adapter.dataSource = ds;
|
||||
controller1.workingRangeDelegate = mockWorkingRangeDelegate1;
|
||||
controller2.workingRangeDelegate = mockWorkingRangeDelegate2;
|
||||
controller3.workingRangeDelegate = mockWorkingRangeDelegate3;
|
||||
|
||||
// Arrange 2: Force an update so we get the objects we configured through the system.
|
||||
[adapter performUpdatesAnimated:NO completion:nil];
|
||||
|
||||
// Act: Tell the working range handler that the center item will be displayed.
|
||||
[[mockWorkingRangeDelegate1 expect] listAdapter:adapter sectionControllerWillEnterWorkingRange:controller1];
|
||||
[[mockWorkingRangeDelegate2 expect] listAdapter:adapter sectionControllerWillEnterWorkingRange:controller2];
|
||||
[[mockWorkingRangeDelegate3 expect] listAdapter:adapter sectionControllerWillEnterWorkingRange:controller3];
|
||||
[adapter.workingRangeHandler willDisplayItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:1] forListAdapter:adapter];
|
||||
|
||||
[mockWorkingRangeDelegate1 verifyWithDelay:5];
|
||||
[mockWorkingRangeDelegate2 verifyWithDelay:5];
|
||||
[mockWorkingRangeDelegate3 verifyWithDelay:5];
|
||||
}
|
||||
|
||||
- (void)test_whenDisplayingItemAtPath_withWorkingRangeSizeOne_thatOnlyAdjacentAndVisibleItemsEnterWorkingRange {
|
||||
// Arrange 1: Set up a simple collection view and adapter with five elements.
|
||||
IGListTestSection *controller1 = [[IGListTestSection alloc] init];
|
||||
NSString *object1 = @"obj1";
|
||||
IGListTestSection *controller2 = [[IGListTestSection alloc] init];
|
||||
NSString *object2 = @"obj2";
|
||||
IGListTestSection *controller3 = [[IGListTestSection alloc] init];
|
||||
NSString *object3 = @"obj3";
|
||||
IGListTestSection *controller4 = [[IGListTestSection alloc] init];
|
||||
NSString *object4 = @"obj4";
|
||||
IGListTestSection *controller5 = [[IGListTestSection alloc] init];
|
||||
NSString *object5 = @"obj5";
|
||||
_IGTestWorkingRangeAdapterDataSource *ds = [[_IGTestWorkingRangeAdapterDataSource alloc] initWithObjects:@[object1, object2, object3, object4, object5]
|
||||
objectToControllerMap:@{object1: controller1,
|
||||
object2: controller2,
|
||||
object3: controller3,
|
||||
object4: controller4,
|
||||
object5: controller5}];
|
||||
IGListReloadDataUpdater *updater = [[IGListReloadDataUpdater alloc] init];
|
||||
IGListAdapter *adapter = [[IGListAdapter alloc] initWithUpdater:updater viewController:nil workingRangeSize:1];
|
||||
id collectionView = [OCMockObject niceMockForClass:[UICollectionView class]];
|
||||
adapter.collectionView = collectionView;
|
||||
|
||||
id mockWorkingRangeDelegate1 = [OCMockObject mockForProtocol:@protocol(IGListWorkingRangeDelegate)];
|
||||
id mockWorkingRangeDelegate2 = [OCMockObject mockForProtocol:@protocol(IGListWorkingRangeDelegate)];
|
||||
id mockWorkingRangeDelegate3 = [OCMockObject mockForProtocol:@protocol(IGListWorkingRangeDelegate)];
|
||||
id mockWorkingRangeDelegate4 = [OCMockObject mockForProtocol:@protocol(IGListWorkingRangeDelegate)];
|
||||
id mockWorkingRangeDelegate5 = [OCMockObject mockForProtocol:@protocol(IGListWorkingRangeDelegate)];
|
||||
|
||||
adapter.dataSource = ds;
|
||||
controller1.workingRangeDelegate = mockWorkingRangeDelegate1;
|
||||
controller2.workingRangeDelegate = mockWorkingRangeDelegate2;
|
||||
controller3.workingRangeDelegate = mockWorkingRangeDelegate3;
|
||||
controller4.workingRangeDelegate = mockWorkingRangeDelegate4;
|
||||
controller5.workingRangeDelegate = mockWorkingRangeDelegate5;
|
||||
|
||||
// Arrange 2: Force an update so we get the objects we configured through the system.
|
||||
[adapter performUpdatesAnimated:NO completion:nil];
|
||||
|
||||
// Act: Tell the working range handler that the center item will be displayed.
|
||||
[[mockWorkingRangeDelegate1 reject] listAdapter:[OCMArg any] sectionControllerWillEnterWorkingRange:[OCMArg any]];
|
||||
[[mockWorkingRangeDelegate2 expect] listAdapter:adapter sectionControllerWillEnterWorkingRange:controller2];
|
||||
[[mockWorkingRangeDelegate3 expect] listAdapter:adapter sectionControllerWillEnterWorkingRange:controller3];
|
||||
[[mockWorkingRangeDelegate4 expect] listAdapter:adapter sectionControllerWillEnterWorkingRange:controller4];
|
||||
[[mockWorkingRangeDelegate5 reject] listAdapter:[OCMArg any] sectionControllerWillEnterWorkingRange:[OCMArg any]];
|
||||
[adapter.workingRangeHandler willDisplayItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:2] forListAdapter:adapter];
|
||||
|
||||
[mockWorkingRangeDelegate1 verifyWithDelay:5];
|
||||
[mockWorkingRangeDelegate2 verifyWithDelay:5];
|
||||
[mockWorkingRangeDelegate3 verifyWithDelay:5];
|
||||
[mockWorkingRangeDelegate4 verifyWithDelay:5];
|
||||
[mockWorkingRangeDelegate5 verifyWithDelay:5];
|
||||
}
|
||||
|
||||
- (void)test_whenDisplayingItemAtPath_withWorkingRangeSizeZero_thenHidingThatItem_thatItemLeavesWorkingRange {
|
||||
// Arrange 1: Set up a simple collection view and adapter with a single element.
|
||||
IGListTestSection *controller = [[IGListTestSection alloc] init];
|
||||
|
|
@ -103,14 +259,14 @@
|
|||
|
||||
// Arrange 3: Tell the working range handler that the first, and only item in the list will be displayed.
|
||||
[[mockWorkingRangeDelegate expect] listAdapter:adapter sectionControllerWillEnterWorkingRange:controller];
|
||||
[adapter.workingRangeHandler willDisplayItemAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] forListAdapter:adapter];
|
||||
[adapter.workingRangeHandler willDisplayItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] forListAdapter:adapter];
|
||||
|
||||
// Arrange 4: Wait for the item to move in-range
|
||||
[mockWorkingRangeDelegate verifyWithDelay:5];
|
||||
|
||||
// Act: Tell the working range handler that the first item is now hidden.
|
||||
[[mockWorkingRangeDelegate expect] listAdapter:adapter sectionControllerDidExitWorkingRange:controller];
|
||||
[adapter.workingRangeHandler didEndDisplayingItemAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] forListAdapter:adapter];
|
||||
[adapter.workingRangeHandler didEndDisplayingItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] forListAdapter:adapter];
|
||||
|
||||
[mockWorkingRangeDelegate verifyWithDelay:5];
|
||||
}
|
||||
|
|
@ -138,7 +294,7 @@
|
|||
|
||||
// Act: Tell the working range handler that the first, and only item in the list will be displayed.
|
||||
[[mockWorkingRangeDelegate expect] listAdapter:adapter sectionControllerWillEnterWorkingRange:controller2];
|
||||
[adapter.workingRangeHandler willDisplayItemAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] forListAdapter:adapter];
|
||||
[adapter.workingRangeHandler willDisplayItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] forListAdapter:adapter];
|
||||
|
||||
[mockWorkingRangeDelegate verifyWithDelay:5];
|
||||
}
|
||||
|
|
@ -172,7 +328,7 @@
|
|||
// Act: Tell the working range handler that the first, and only item in the list will be displayed.
|
||||
[[mockWorkingRangeDelegate2 expect] listAdapter:adapter sectionControllerWillEnterWorkingRange:controller2];
|
||||
[[mockWorkingRangeDelegate3 reject] listAdapter:[OCMArg any] sectionControllerWillEnterWorkingRange:[OCMArg any]];
|
||||
[adapter.workingRangeHandler willDisplayItemAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] forListAdapter:adapter];
|
||||
[adapter.workingRangeHandler willDisplayItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] forListAdapter:adapter];
|
||||
|
||||
[mockWorkingRangeDelegate2 verifyWithDelay:5];
|
||||
[mockWorkingRangeDelegate3 verify];
|
||||
|
|
@ -201,16 +357,151 @@
|
|||
|
||||
// Arrange 3: Tell the working range handler that the first, and only item in the list will be displayed.
|
||||
[[mockWorkingRangeDelegate expect] listAdapter:adapter sectionControllerWillEnterWorkingRange:controller2];
|
||||
[adapter.workingRangeHandler willDisplayItemAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] forListAdapter:adapter];
|
||||
[adapter.workingRangeHandler willDisplayItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] forListAdapter:adapter];
|
||||
|
||||
// Arrange 4: Wait for the item to move in-range.
|
||||
[mockWorkingRangeDelegate verifyWithDelay:5];
|
||||
|
||||
// Act: Hide the first item, and watch for the second item to leave the working range.
|
||||
[[mockWorkingRangeDelegate expect] listAdapter:adapter sectionControllerDidExitWorkingRange:controller2];
|
||||
[adapter.workingRangeHandler didEndDisplayingItemAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] forListAdapter:adapter];
|
||||
[adapter.workingRangeHandler didEndDisplayingItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] forListAdapter:adapter];
|
||||
|
||||
[mockWorkingRangeDelegate verifyWithDelay:5];
|
||||
}
|
||||
|
||||
- (void)test_whenDisplayingItemsAtPaths_withWorkingRangeSizeOne_thatSpuriousWorkingRangeCallsAreNotMade {
|
||||
// Arrange 1: Set up a simple collection view and adapter with a single element.
|
||||
IGListTestSection *controller1 = [[IGListTestSection alloc] init];
|
||||
NSString *object1 = @"obj1";
|
||||
IGListTestSection *controller2 = [[IGListTestSection alloc] init];
|
||||
NSString *object2 = @"obj2";
|
||||
_IGTestWorkingRangeAdapterDataSource *ds = [[_IGTestWorkingRangeAdapterDataSource alloc] initWithObjects:@[object1, object2]
|
||||
objectToControllerMap:@{object1: controller1,
|
||||
object2: controller2}];
|
||||
IGListReloadDataUpdater *updater = [[IGListReloadDataUpdater alloc] init];
|
||||
IGListAdapter *adapter = [[IGListAdapter alloc] initWithUpdater:updater viewController:nil workingRangeSize:1];
|
||||
id collectionView = [OCMockObject niceMockForClass:[UICollectionView class]];
|
||||
adapter.collectionView = collectionView;
|
||||
|
||||
id mockWorkingRangeDelegate1 = [OCMockObject mockForProtocol:@protocol(IGListWorkingRangeDelegate)];
|
||||
id mockWorkingRangeDelegate2 = [OCMockObject mockForProtocol:@protocol(IGListWorkingRangeDelegate)];
|
||||
|
||||
adapter.dataSource = ds;
|
||||
controller1.workingRangeDelegate = mockWorkingRangeDelegate1;
|
||||
controller2.workingRangeDelegate = mockWorkingRangeDelegate2;
|
||||
|
||||
// Arrange 2: Force an update so we get the objects we configured through the system.
|
||||
[adapter performUpdatesAnimated:NO completion:nil];
|
||||
|
||||
// Arrange 3: Tell the working range handler that the first item in the list will be displayed.
|
||||
[[mockWorkingRangeDelegate1 expect] listAdapter:adapter sectionControllerWillEnterWorkingRange:controller1];
|
||||
[[mockWorkingRangeDelegate2 expect] listAdapter:adapter sectionControllerWillEnterWorkingRange:controller2];
|
||||
[adapter.workingRangeHandler willDisplayItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] forListAdapter:adapter];
|
||||
|
||||
[mockWorkingRangeDelegate1 verifyWithDelay:5];
|
||||
[mockWorkingRangeDelegate2 verifyWithDelay:5];
|
||||
|
||||
// Act: Tell the working range handler that the second item in the list will be displayed.
|
||||
[[mockWorkingRangeDelegate1 reject] listAdapter:[OCMArg any] sectionControllerWillEnterWorkingRange:[OCMArg any]];
|
||||
[[mockWorkingRangeDelegate2 reject] listAdapter:[OCMArg any] sectionControllerWillEnterWorkingRange:[OCMArg any]];
|
||||
[adapter.workingRangeHandler willDisplayItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:1] forListAdapter:adapter];
|
||||
|
||||
[mockWorkingRangeDelegate1 verifyWithDelay:5];
|
||||
[mockWorkingRangeDelegate2 verifyWithDelay:5];
|
||||
}
|
||||
|
||||
- (void)test_whenDisplayingItemsAtPaths_withWorkingRangeSizeZero_thenRemovingFirstItem_thenInsertingItemAtLastPosition_thatItemEntersWorkingRange {
|
||||
return; // This test currently fails; working range calculations do not take inserts + deletes into account.
|
||||
|
||||
// Arrange 1: Set up a simple collection view and adapter with a single element.
|
||||
IGListTestSection *controller1 = [[IGListTestSection alloc] init];
|
||||
NSString *object1 = @"obj1";
|
||||
IGListTestSection *controller2 = [[IGListTestSection alloc] init];
|
||||
NSString *object2 = @"obj2";
|
||||
_IGTestWorkingRangeAdapterDataSource *ds = [[_IGTestWorkingRangeAdapterDataSource alloc] initWithObjects:@[object1, object2]
|
||||
objectToControllerMap:@{object1: controller1,
|
||||
object2: controller2}];
|
||||
IGListReloadDataUpdater *updater = [[IGListReloadDataUpdater alloc] init];
|
||||
IGListAdapter *adapter = [[IGListAdapter alloc] initWithUpdater:updater viewController:nil];
|
||||
id collectionView = [OCMockObject niceMockForClass:[UICollectionView class]];
|
||||
adapter.collectionView = collectionView;
|
||||
|
||||
id mockWorkingRangeDelegate1 = [OCMockObject mockForProtocol:@protocol(IGListWorkingRangeDelegate)];
|
||||
id mockWorkingRangeDelegate2 = [OCMockObject mockForProtocol:@protocol(IGListWorkingRangeDelegate)];
|
||||
|
||||
adapter.dataSource = ds;
|
||||
controller1.workingRangeDelegate = mockWorkingRangeDelegate1;
|
||||
controller2.workingRangeDelegate = mockWorkingRangeDelegate2;
|
||||
|
||||
// Arrange 2: Force an update so we get the objects we configured through the system.
|
||||
[adapter performUpdatesAnimated:NO completion:nil];
|
||||
|
||||
// Arrange 3: Tell the working range handler that the first two items in the list will be displayed.
|
||||
[[mockWorkingRangeDelegate1 expect] listAdapter:adapter sectionControllerWillEnterWorkingRange:controller1];
|
||||
[[mockWorkingRangeDelegate2 expect] listAdapter:adapter sectionControllerWillEnterWorkingRange:controller2];
|
||||
[adapter.workingRangeHandler willDisplayItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] forListAdapter:adapter];
|
||||
[adapter.workingRangeHandler willDisplayItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:1] forListAdapter:adapter];
|
||||
[mockWorkingRangeDelegate1 verifyWithDelay:5];
|
||||
[mockWorkingRangeDelegate2 verifyWithDelay:5];
|
||||
|
||||
// Arrange 4: Remove the object at the first index, and update the working range handler.
|
||||
[ds removeObjectAtIndex:0];
|
||||
[[mockWorkingRangeDelegate1 expect] listAdapter:adapter sectionControllerDidExitWorkingRange:controller1];
|
||||
[adapter.workingRangeHandler didEndDisplayingItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] forListAdapter:adapter];
|
||||
[mockWorkingRangeDelegate1 verifyWithDelay:5];
|
||||
|
||||
// Act: Insert a new object at index one, and update the working range handler.
|
||||
[ds insertObject:object1 withController:controller1 atIndex:1];
|
||||
[[mockWorkingRangeDelegate1 expect] listAdapter:adapter sectionControllerWillEnterWorkingRange:controller1];
|
||||
[[mockWorkingRangeDelegate2 reject] listAdapter:[OCMArg any] sectionControllerWillEnterWorkingRange:[OCMArg any]];
|
||||
[[mockWorkingRangeDelegate2 reject] listAdapter:[OCMArg any] sectionControllerDidExitWorkingRange:[OCMArg any]];
|
||||
[adapter.workingRangeHandler willDisplayItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:1] forListAdapter:adapter];
|
||||
[mockWorkingRangeDelegate1 verifyWithDelay:5];
|
||||
[mockWorkingRangeDelegate2 verifyWithDelay:5];
|
||||
}
|
||||
|
||||
- (void)test_whenDisplayingItemAtPath_withWorkingRangeSizeZero_thenInsertingNewItem_thatVisibleItemsRemainInWorkingRange {
|
||||
return; // This test currently fails; working range calculations do not take inserts + deletes into account.
|
||||
|
||||
// Arrange 1: Set up a simple collection view and adapter with a single element.
|
||||
IGListTestSection *controller1 = [[IGListTestSection alloc] init];
|
||||
NSString *object1 = @"obj1";
|
||||
IGListTestSection *controller2 = [[IGListTestSection alloc] init];
|
||||
NSString *object2 = @"obj2";
|
||||
_IGTestWorkingRangeAdapterDataSource *ds = [[_IGTestWorkingRangeAdapterDataSource alloc] initWithObjects:@[object1]
|
||||
objectToControllerMap:@{object1: controller1}];
|
||||
IGListReloadDataUpdater *updater = [[IGListReloadDataUpdater alloc] init];
|
||||
IGListAdapter *adapter = [[IGListAdapter alloc] initWithUpdater:updater viewController:nil];
|
||||
id collectionView = [OCMockObject niceMockForClass:[UICollectionView class]];
|
||||
adapter.collectionView = collectionView;
|
||||
|
||||
id mockWorkingRangeDelegate1 = [OCMockObject mockForProtocol:@protocol(IGListWorkingRangeDelegate)];
|
||||
id mockWorkingRangeDelegate2 = [OCMockObject mockForProtocol:@protocol(IGListWorkingRangeDelegate)];
|
||||
|
||||
adapter.dataSource = ds;
|
||||
controller1.workingRangeDelegate = mockWorkingRangeDelegate1;
|
||||
controller2.workingRangeDelegate = mockWorkingRangeDelegate2;
|
||||
|
||||
// Arrange 2: Force an update so we get the objects we configured through the system.
|
||||
[adapter performUpdatesAnimated:NO completion:nil];
|
||||
|
||||
// Arrange 3: Tell the working range handler that the first item in the list will be displayed.
|
||||
[[mockWorkingRangeDelegate1 expect] listAdapter:adapter sectionControllerWillEnterWorkingRange:controller1];
|
||||
[adapter.workingRangeHandler willDisplayItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] forListAdapter:adapter];
|
||||
[mockWorkingRangeDelegate1 verifyWithDelay:5];
|
||||
|
||||
// Arrange 4: Insert a second object in the first index.
|
||||
[ds insertObject:object2 withController:controller2 atIndex:0];
|
||||
|
||||
// Act: Tell the working range handler that the new item will become visible.
|
||||
[[mockWorkingRangeDelegate1 reject] listAdapter:[OCMArg any] sectionControllerWillEnterWorkingRange:[OCMArg any]];
|
||||
[[mockWorkingRangeDelegate1 reject] listAdapter:[OCMArg any] sectionControllerDidExitWorkingRange:[OCMArg any]];
|
||||
[[mockWorkingRangeDelegate2 expect] listAdapter:adapter sectionControllerWillEnterWorkingRange:controller2];
|
||||
[[mockWorkingRangeDelegate2 reject] listAdapter:[OCMArg any] sectionControllerDidExitWorkingRange:[OCMArg any]];
|
||||
[adapter.workingRangeHandler willDisplayItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] forListAdapter:adapter];
|
||||
|
||||
[mockWorkingRangeDelegate1 verifyWithDelay:5];
|
||||
[mockWorkingRangeDelegate2 verifyWithDelay:5];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
|||
Loading…
Reference in a new issue