2019-12-19 17:32:49 +00:00
|
|
|
/*
|
2023-04-06 09:44:16 +00:00
|
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
2017-12-15 17:19:24 +00:00
|
|
|
*
|
2018-05-01 21:33:50 +00:00
|
|
|
* This source code is licensed under the MIT license found in the
|
|
|
|
|
* LICENSE file in the root directory of this source tree.
|
2017-12-15 17:19:24 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#import <XCTest/XCTest.h>
|
|
|
|
|
|
|
|
|
|
#import <IGListKit/IGListCollectionView.h>
|
|
|
|
|
|
2019-12-19 17:32:49 +00:00
|
|
|
#import "IGLayoutTestDataSource.h"
|
2017-12-15 17:19:24 +00:00
|
|
|
#import "IGLayoutTestItem.h"
|
|
|
|
|
#import "IGLayoutTestSection.h"
|
|
|
|
|
#import "IGListTestHelpers.h"
|
|
|
|
|
|
|
|
|
|
@interface IGListCollectionViewTests : XCTestCase
|
|
|
|
|
|
2023-10-06 10:08:34 +00:00
|
|
|
@property (nonatomic, strong) UIWindow *window;
|
2017-12-15 17:19:24 +00:00
|
|
|
@property (nonatomic, strong) IGListCollectionView *collectionView;
|
|
|
|
|
@property (nonatomic, strong) IGLayoutTestDataSource *dataSource;
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
@implementation IGListCollectionViewTests
|
|
|
|
|
|
|
|
|
|
- (void)setUp {
|
|
|
|
|
[super setUp];
|
2023-10-06 10:08:34 +00:00
|
|
|
const CGRect frame = CGRectMake(0, 0, 100, 100);
|
|
|
|
|
self.window = [[UIWindow alloc] initWithFrame:frame];
|
2017-12-15 17:19:24 +00:00
|
|
|
self.dataSource = [IGLayoutTestDataSource new];
|
2023-10-06 10:08:34 +00:00
|
|
|
self.collectionView = [[IGListCollectionView alloc] initWithFrame:frame];
|
2017-12-15 17:19:24 +00:00
|
|
|
self.collectionView.dataSource = self.dataSource;
|
|
|
|
|
self.collectionView.delegate = self.dataSource;
|
2023-10-06 10:08:34 +00:00
|
|
|
[self.window addSubview:self.collectionView];
|
2017-12-15 17:19:24 +00:00
|
|
|
[self.dataSource configCollectionView:self.collectionView];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#pragma mark - Reload All
|
|
|
|
|
|
|
|
|
|
- (void)test_whenReloadData_thatEntireLayoutUpdates {
|
|
|
|
|
self.dataSource.sections = @[
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(10, 10))])
|
|
|
|
|
];
|
|
|
|
|
[self.collectionView reloadData];
|
|
|
|
|
[self.collectionView layoutIfNeeded];
|
|
|
|
|
|
|
|
|
|
self.dataSource.sections = @[
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(20, 20))]),
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(10, 10))])
|
|
|
|
|
];
|
|
|
|
|
[self.collectionView reloadData];
|
|
|
|
|
[self.collectionView layoutIfNeeded];
|
|
|
|
|
|
|
|
|
|
IGAssertEqualFrame([self cellForSection:0 item:0].frame, 0, 0, 20, 20);
|
|
|
|
|
IGAssertEqualFrame([self cellForSection:1 item:0].frame, 20, 0, 10, 10);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#pragma mark - Insert/Delete/Reload/Move
|
|
|
|
|
|
2023-10-06 10:08:34 +00:00
|
|
|
- (void)test_whenInsertingSection_thatLayoutUpdates {
|
2017-12-15 17:19:24 +00:00
|
|
|
self.dataSource.sections = @[
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(10, 10))])
|
|
|
|
|
];
|
|
|
|
|
[self.collectionView reloadData];
|
|
|
|
|
[self.collectionView layoutIfNeeded];
|
|
|
|
|
|
|
|
|
|
self.dataSource.sections = @[
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(20, 20))]),
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(10, 10))])
|
|
|
|
|
];
|
|
|
|
|
[self.collectionView insertSections:[NSIndexSet indexSetWithIndex:1]];
|
|
|
|
|
|
2023-10-06 10:08:34 +00:00
|
|
|
// check that section 0 was updated
|
|
|
|
|
IGAssertEqualFrame([self cellForSection:0 item:0].frame, 0, 0, 20, 20);
|
2017-12-15 17:19:24 +00:00
|
|
|
// check that section 1 was updated
|
2023-10-06 10:08:34 +00:00
|
|
|
IGAssertEqualFrame([self cellForSection:1 item:0].frame, 20, 0, 10, 10);
|
2017-12-15 17:19:24 +00:00
|
|
|
}
|
|
|
|
|
|
2023-10-06 10:08:34 +00:00
|
|
|
- (void)test_whenDeletingSection_thatLayoutUpdates {
|
2017-12-15 17:19:24 +00:00
|
|
|
self.dataSource.sections = @[
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(10, 10))]),
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(10, 10))])
|
|
|
|
|
];
|
|
|
|
|
[self.collectionView reloadData];
|
|
|
|
|
[self.collectionView layoutIfNeeded];
|
|
|
|
|
|
|
|
|
|
self.dataSource.sections = @[
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(20, 20))]),
|
|
|
|
|
];
|
|
|
|
|
[self.collectionView deleteSections:[NSIndexSet indexSetWithIndex:1]];
|
|
|
|
|
|
|
|
|
|
// check that section 0 wasn't updated
|
2023-10-06 10:08:34 +00:00
|
|
|
IGAssertEqualFrame([self cellForSection:0 item:0].frame, 0, 0, 20, 20);
|
2017-12-15 17:19:24 +00:00
|
|
|
}
|
|
|
|
|
|
2023-10-06 10:08:34 +00:00
|
|
|
- (void)test_whenReloadingSection_thatLayoutUpdates {
|
2017-12-15 17:19:24 +00:00
|
|
|
self.dataSource.sections = @[
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(10, 10))]),
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(10, 10))])
|
|
|
|
|
];
|
|
|
|
|
[self.collectionView reloadData];
|
|
|
|
|
[self.collectionView layoutIfNeeded];
|
|
|
|
|
|
|
|
|
|
self.dataSource.sections = @[
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(20, 20))]),
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(20, 20))]),
|
|
|
|
|
];
|
|
|
|
|
[self.collectionView reloadSections:[NSIndexSet indexSetWithIndex:1]];
|
|
|
|
|
|
2023-10-06 10:08:34 +00:00
|
|
|
// check that section 0 was updated
|
|
|
|
|
IGAssertEqualFrame([self cellForSection:0 item:0].frame, 0, 0, 20, 20);
|
2017-12-15 17:19:24 +00:00
|
|
|
// check that section 1 was updated
|
2023-10-06 10:08:34 +00:00
|
|
|
IGAssertEqualFrame([self cellForSection:1 item:0].frame, 20, 0, 20, 20);
|
2017-12-15 17:19:24 +00:00
|
|
|
}
|
|
|
|
|
|
2023-10-06 10:08:34 +00:00
|
|
|
- (void)test_whenMoveSection_thatLayoutUpdates {
|
2017-12-15 17:19:24 +00:00
|
|
|
self.dataSource.sections = @[
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(10, 10))]),
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(20, 20))]),
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(30, 30))])
|
|
|
|
|
];
|
|
|
|
|
[self.collectionView reloadData];
|
|
|
|
|
[self.collectionView layoutIfNeeded];
|
|
|
|
|
|
|
|
|
|
self.dataSource.sections = @[
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(40, 40))]),
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(30, 30))]),
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(20, 20))]),
|
|
|
|
|
];
|
|
|
|
|
[self.collectionView moveSection:1 toSection:2];
|
|
|
|
|
|
2023-10-06 10:08:34 +00:00
|
|
|
// check that section 0 was updated
|
|
|
|
|
IGAssertEqualFrame([self cellForSection:0 item:0].frame, 0, 0, 40, 40);
|
2017-12-15 17:19:24 +00:00
|
|
|
// check that section 1 was updated
|
2023-10-06 10:08:34 +00:00
|
|
|
IGAssertEqualFrame([self cellForSection:1 item:0].frame, 40, 0, 30, 30);
|
2017-12-15 17:19:24 +00:00
|
|
|
// check that section 2 was updated
|
2023-10-06 10:08:34 +00:00
|
|
|
IGAssertEqualFrame([self cellForSection:2 item:0].frame, 70, 0, 20, 20);
|
2017-12-15 17:19:24 +00:00
|
|
|
}
|
|
|
|
|
|
2023-04-18 03:41:49 +00:00
|
|
|
- (void)test_whenMoveItem_thatLayoutPartiallyUpdates {
|
|
|
|
|
self.dataSource.sections = @[
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(10, 10))]),
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(20, 20))]),
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(30, 30))])
|
|
|
|
|
];
|
|
|
|
|
[self.collectionView reloadData];
|
|
|
|
|
[self.collectionView layoutIfNeeded];
|
|
|
|
|
|
|
|
|
|
NSArray *sections = @[genLayoutTestItem(CGSizeMake(10, 10)), genLayoutTestItem(CGSizeMake(20, 20))];
|
|
|
|
|
self.dataSource.sections = @[
|
|
|
|
|
genLayoutTestSection(sections),
|
|
|
|
|
genLayoutTestSection(@[]),
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(20, 20))]),
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
[self.collectionView moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:1]
|
|
|
|
|
toIndexPath:[NSIndexPath indexPathForItem:1 inSection:0]];
|
|
|
|
|
|
|
|
|
|
// check that section 0 wasn't updated
|
|
|
|
|
IGAssertEqualFrame([self cellForSection:0 item:0].frame, 0, 0, 10, 10);
|
|
|
|
|
// check that section 1 was updated
|
|
|
|
|
IGAssertEqualFrame([self cellForSection:0 item:1].frame, 10, 0, 20, 20);
|
|
|
|
|
// check that section 2 was updated
|
|
|
|
|
IGAssertEqualFrame([self cellForSection:2 item:0].frame, 30, 0, 20, 20);
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-15 17:19:24 +00:00
|
|
|
#pragma mark - Batch
|
|
|
|
|
|
2023-10-06 10:08:34 +00:00
|
|
|
- (void)test_whenInsertDeleteMoveSection_thatLayoutUpdates {
|
2017-12-15 17:19:24 +00:00
|
|
|
self.dataSource.sections = @[
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(1, 1))]),
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(2, 2))]),
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(3, 3))]),
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(4, 4))]),
|
|
|
|
|
];
|
|
|
|
|
[self.collectionView reloadData];
|
|
|
|
|
[self.collectionView layoutIfNeeded];
|
|
|
|
|
|
|
|
|
|
self.dataSource.sections = @[
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(0, 0))]),
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(4, 4))]),
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(3, 3))]),
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(5, 5))]),
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
XCTestExpectation *expectation = [self expectationWithDescription:NSStringFromSelector(_cmd)];
|
|
|
|
|
|
|
|
|
|
[self.collectionView performBatchUpdates:^{
|
|
|
|
|
[self.collectionView deleteSections:[NSIndexSet indexSetWithIndex:1]]; // deleted (2, 2)
|
|
|
|
|
[self.collectionView moveSection:3 toSection:1]; // move (4, 4)
|
|
|
|
|
[self.collectionView insertSections:[NSIndexSet indexSetWithIndex:3]]; // inserted (5, 5)
|
|
|
|
|
} completion:^(BOOL finished) {
|
|
|
|
|
[self.collectionView layoutIfNeeded];
|
|
|
|
|
[expectation fulfill];
|
|
|
|
|
|
2023-10-06 10:08:34 +00:00
|
|
|
// check that section 0 was updated
|
|
|
|
|
IGAssertEqualFrame([self cellForSection:0 item:0].frame, 0, 0, 0, 0);
|
2017-12-15 17:19:24 +00:00
|
|
|
// check that section 1 was updated
|
2023-10-06 10:08:34 +00:00
|
|
|
IGAssertEqualFrame([self cellForSection:1 item:0].frame, 0, 0, 4, 4);
|
2017-12-15 17:19:24 +00:00
|
|
|
// check that section 2 was updated
|
2023-10-06 10:08:34 +00:00
|
|
|
IGAssertEqualFrame([self cellForSection:2 item:0].frame, 4, 0, 3, 3);
|
2017-12-15 17:19:24 +00:00
|
|
|
// check that section 3 was updated
|
2023-10-06 10:08:34 +00:00
|
|
|
IGAssertEqualFrame([self cellForSection:3 item:0].frame, 7, 0, 5, 5);
|
2017-12-15 17:19:24 +00:00
|
|
|
}];
|
|
|
|
|
|
|
|
|
|
[self waitForExpectationsWithTimeout:30 handler:^(NSError * _Nullable error) {
|
|
|
|
|
XCTAssertNil(error);
|
|
|
|
|
}];
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-18 03:41:49 +00:00
|
|
|
- (void)test_whenInsertingNilSection_thatExecutionCompletesCleanly {
|
|
|
|
|
self.dataSource.sections = @[
|
|
|
|
|
genLayoutTestSection(@[genLayoutTestItem(CGSizeMake(10, 10))])
|
|
|
|
|
];
|
|
|
|
|
[self.collectionView reloadData];
|
|
|
|
|
[self.collectionView layoutIfNeeded];
|
|
|
|
|
|
|
|
|
|
[self.collectionView insertSections:[NSIndexSet indexSet]];
|
|
|
|
|
|
|
|
|
|
// check that section 0 wasn't updated
|
|
|
|
|
IGAssertEqualFrame([self cellForSection:0 item:0].frame, 0, 0, 10, 10);
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-15 17:19:24 +00:00
|
|
|
#pragma mark - Helpers
|
|
|
|
|
|
|
|
|
|
- (UICollectionViewCell *)cellForSection:(NSInteger)section item:(NSInteger)item {
|
|
|
|
|
return [self.collectionView cellForItemAtIndexPath:genIndexPath(section, item)];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@end
|