diff --git a/IGListKit.xcodeproj/project.pbxproj b/IGListKit.xcodeproj/project.pbxproj index 76c16fcc6..bcc8532ea 100644 --- a/IGListKit.xcodeproj/project.pbxproj +++ b/IGListKit.xcodeproj/project.pbxproj @@ -26,9 +26,14 @@ 5C81083F8E7AEF4B3EBE8871 /* Pods_IGListKitTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FD40284889DE182FFC7F471E /* Pods_IGListKitTests.framework */; }; 821BC4C01DB8C9D500172ED0 /* IGListSingleStoryboardItemControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 821BC4BE1DB8C95300172ED0 /* IGListSingleStoryboardItemControllerTests.m */; }; 821BC4C41DB8CEF800172ED0 /* IGTestStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 821BC4C21DB8CAE900172ED0 /* IGTestStoryboard.storyboard */; }; - 821BC4CB1DB8D60100172ED0 /* IGTestSingleStoryboardViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 821BC4C81DB8D5B200172ED0 /* IGTestSingleStoryboardViewController.m */; }; + 821BC4CB1DB8D60100172ED0 /* IGTestStoryboardViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 821BC4C81DB8D5B200172ED0 /* IGTestStoryboardViewController.m */; }; 821BC4D01DB8D90900172ED0 /* IGTestStoryboardCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 821BC4CD1DB8D8C500172ED0 /* IGTestStoryboardCell.m */; }; 821BC4D31DB981AB00172ED0 /* IGTestSingleStoryboardItemDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 821BC4D21DB981AB00172ED0 /* IGTestSingleStoryboardItemDataSource.m */; }; + 8240C7F01DC272CA00B3AAE7 /* IGTestStoryboardSupplementaryView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8240C7EF1DC272CA00B3AAE7 /* IGTestStoryboardSupplementaryView.m */; }; + 8240C7F21DC284C300B3AAE7 /* IGListAdapterStoryboardTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8240C7F11DC284C300B3AAE7 /* IGListAdapterStoryboardTests.m */; }; + 8240C7F51DC2D99300B3AAE7 /* IGTestStoryboardSupplementarySource.m in Sources */ = {isa = PBXBuildFile; fileRef = 8240C7F41DC2D99300B3AAE7 /* IGTestStoryboardSupplementarySource.m */; }; + 8240C7F81DC2F3FB00B3AAE7 /* IGListTestStoryboardSection.m in Sources */ = {isa = PBXBuildFile; fileRef = 8240C7F71DC2F3FB00B3AAE7 /* IGListTestStoryboardSection.m */; }; + 8240C7FB1DC2F6CF00B3AAE7 /* IGListTestAdapterStoryboardDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 8240C7FA1DC2F6CF00B3AAE7 /* IGListTestAdapterStoryboardDataSource.m */; }; 88144F071D870EDC007C7F66 /* IGListAdapterE2ETests.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144EE21D870EDC007C7F66 /* IGListAdapterE2ETests.m */; }; 88144F081D870EDC007C7F66 /* IGListAdapterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144EE31D870EDC007C7F66 /* IGListAdapterTests.m */; }; 88144F091D870EDC007C7F66 /* IGListAdapterUpdaterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 88144EE41D870EDC007C7F66 /* IGListAdapterUpdaterTests.m */; }; @@ -238,12 +243,21 @@ 6BCA3FF59943AD1DAC2077E3 /* Pods-IGListKitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-IGListKitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-IGListKitTests/Pods-IGListKitTests.release.xcconfig"; sourceTree = ""; }; 821BC4BE1DB8C95300172ED0 /* IGListSingleStoryboardItemControllerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGListSingleStoryboardItemControllerTests.m; sourceTree = ""; }; 821BC4C21DB8CAE900172ED0 /* IGTestStoryboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = IGTestStoryboard.storyboard; sourceTree = ""; }; - 821BC4C71DB8D5B200172ED0 /* IGTestSingleStoryboardViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGTestSingleStoryboardViewController.h; sourceTree = ""; }; - 821BC4C81DB8D5B200172ED0 /* IGTestSingleStoryboardViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGTestSingleStoryboardViewController.m; sourceTree = ""; }; + 821BC4C71DB8D5B200172ED0 /* IGTestStoryboardViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGTestStoryboardViewController.h; sourceTree = ""; }; + 821BC4C81DB8D5B200172ED0 /* IGTestStoryboardViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGTestStoryboardViewController.m; sourceTree = ""; }; 821BC4CC1DB8D8C500172ED0 /* IGTestStoryboardCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGTestStoryboardCell.h; sourceTree = ""; }; 821BC4CD1DB8D8C500172ED0 /* IGTestStoryboardCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGTestStoryboardCell.m; sourceTree = ""; }; 821BC4D11DB9816E00172ED0 /* IGTestSingleStoryboardItemDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGTestSingleStoryboardItemDataSource.h; sourceTree = ""; }; 821BC4D21DB981AB00172ED0 /* IGTestSingleStoryboardItemDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGTestSingleStoryboardItemDataSource.m; sourceTree = ""; }; + 8240C7EE1DC272CA00B3AAE7 /* IGTestStoryboardSupplementaryView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGTestStoryboardSupplementaryView.h; sourceTree = ""; }; + 8240C7EF1DC272CA00B3AAE7 /* IGTestStoryboardSupplementaryView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGTestStoryboardSupplementaryView.m; sourceTree = ""; }; + 8240C7F11DC284C300B3AAE7 /* IGListAdapterStoryboardTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = IGListAdapterStoryboardTests.m; path = Tests/IGListAdapterStoryboardTests.m; sourceTree = SOURCE_ROOT; }; + 8240C7F31DC2D99300B3AAE7 /* IGTestStoryboardSupplementarySource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGTestStoryboardSupplementarySource.h; sourceTree = ""; }; + 8240C7F41DC2D99300B3AAE7 /* IGTestStoryboardSupplementarySource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGTestStoryboardSupplementarySource.m; sourceTree = ""; }; + 8240C7F61DC2F3FB00B3AAE7 /* IGListTestStoryboardSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGListTestStoryboardSection.h; sourceTree = ""; }; + 8240C7F71DC2F3FB00B3AAE7 /* IGListTestStoryboardSection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGListTestStoryboardSection.m; sourceTree = ""; }; + 8240C7F91DC2F6CF00B3AAE7 /* IGListTestAdapterStoryboardDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGListTestAdapterStoryboardDataSource.h; sourceTree = ""; }; + 8240C7FA1DC2F6CF00B3AAE7 /* IGListTestAdapterStoryboardDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGListTestAdapterStoryboardDataSource.m; sourceTree = ""; }; 841726B542A3E9A4BD48946F /* Pods-IGListKit-tvOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-IGListKit-tvOSTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-IGListKit-tvOSTests/Pods-IGListKit-tvOSTests.debug.xcconfig"; sourceTree = ""; }; 88144EE21D870EDC007C7F66 /* IGListAdapterE2ETests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGListAdapterE2ETests.m; sourceTree = ""; }; 88144EE31D870EDC007C7F66 /* IGListAdapterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGListAdapterTests.m; sourceTree = ""; }; @@ -401,10 +415,14 @@ children = ( 88144EF11D870EDC007C7F66 /* IGListTestAdapterDataSource.h */, 88144EF21D870EDC007C7F66 /* IGListTestAdapterDataSource.m */, + 8240C7F91DC2F6CF00B3AAE7 /* IGListTestAdapterStoryboardDataSource.h */, + 8240C7FA1DC2F6CF00B3AAE7 /* IGListTestAdapterStoryboardDataSource.m */, 88144EF31D870EDC007C7F66 /* IGListTestOffsettingLayout.h */, 88144EF41D870EDC007C7F66 /* IGListTestOffsettingLayout.m */, 88144EF51D870EDC007C7F66 /* IGListTestSection.h */, 88144EF61D870EDC007C7F66 /* IGListTestSection.m */, + 8240C7F61DC2F3FB00B3AAE7 /* IGListTestStoryboardSection.h */, + 8240C7F71DC2F3FB00B3AAE7 /* IGListTestStoryboardSection.m */, 88144EF71D870EDC007C7F66 /* IGListTestUICollectionViewDataSource.h */, 88144EF81D870EDC007C7F66 /* IGListTestUICollectionViewDataSource.m */, 88144EF91D870EDC007C7F66 /* IGTestCell.h */, @@ -421,14 +439,18 @@ 26271C891DAE94E40073E116 /* IGTestSingleNibItemDataSource.m */, 821BC4D11DB9816E00172ED0 /* IGTestSingleStoryboardItemDataSource.h */, 821BC4D21DB981AB00172ED0 /* IGTestSingleStoryboardItemDataSource.m */, - 821BC4C71DB8D5B200172ED0 /* IGTestSingleStoryboardViewController.h */, - 821BC4C81DB8D5B200172ED0 /* IGTestSingleStoryboardViewController.m */, + 821BC4C71DB8D5B200172ED0 /* IGTestStoryboardViewController.h */, + 821BC4C81DB8D5B200172ED0 /* IGTestStoryboardViewController.m */, 88144F031D870EDC007C7F66 /* IGTestStackedDataSource.h */, 88144F041D870EDC007C7F66 /* IGTestStackedDataSource.m */, 821BC4CC1DB8D8C500172ED0 /* IGTestStoryboardCell.h */, 821BC4CD1DB8D8C500172ED0 /* IGTestStoryboardCell.m */, 88144F051D870EDC007C7F66 /* IGTestSupplementarySource.h */, 88144F061D870EDC007C7F66 /* IGTestSupplementarySource.m */, + 8240C7F31DC2D99300B3AAE7 /* IGTestStoryboardSupplementarySource.h */, + 8240C7F41DC2D99300B3AAE7 /* IGTestStoryboardSupplementarySource.m */, + 8240C7EE1DC272CA00B3AAE7 /* IGTestStoryboardSupplementaryView.h */, + 8240C7EF1DC272CA00B3AAE7 /* IGTestStoryboardSupplementaryView.m */, ); path = Objects; sourceTree = ""; @@ -540,6 +562,7 @@ 294369AF1DB1B7AE0025F6E7 /* Assets */, 88144EE21D870EDC007C7F66 /* IGListAdapterE2ETests.m */, 88144EE31D870EDC007C7F66 /* IGListAdapterTests.m */, + 8240C7F11DC284C300B3AAE7 /* IGListAdapterStoryboardTests.m */, 88144EE41D870EDC007C7F66 /* IGListAdapterUpdaterTests.m */, 88144EE51D870EDC007C7F66 /* IGListBatchUpdateDataTests.m */, 88144EE61D870EDC007C7F66 /* IGListDiffSwiftTests.swift */, @@ -1027,10 +1050,12 @@ 88144F1C1D870EDC007C7F66 /* IGTestStackedDataSource.m in Sources */, 88144F181D870EDC007C7F66 /* IGTestDelegateController.m in Sources */, 88144F0D1D870EDC007C7F66 /* IGListDisplayHandlerTests.m in Sources */, + 8240C7F51DC2D99300B3AAE7 /* IGTestStoryboardSupplementarySource.m in Sources */, 88144F1B1D870EDC007C7F66 /* IGTestSingleItemDataSource.m in Sources */, 88144F171D870EDC007C7F66 /* IGTestCell.m in Sources */, 821BC4C01DB8C9D500172ED0 /* IGListSingleStoryboardItemControllerTests.m in Sources */, 88144F141D870EDC007C7F66 /* IGListTestOffsettingLayout.m in Sources */, + 8240C7FB1DC2F6CF00B3AAE7 /* IGListTestAdapterStoryboardDataSource.m in Sources */, 88144F131D870EDC007C7F66 /* IGListTestAdapterDataSource.m in Sources */, 88144F071D870EDC007C7F66 /* IGListAdapterE2ETests.m in Sources */, 88144F111D870EDC007C7F66 /* IGListStackSectionControllerTests.m in Sources */, @@ -1046,11 +1071,14 @@ 88144F151D870EDC007C7F66 /* IGListTestSection.m in Sources */, 88144F1D1D870EDC007C7F66 /* IGTestSupplementarySource.m in Sources */, 88144F081D870EDC007C7F66 /* IGListAdapterTests.m in Sources */, - 821BC4CB1DB8D60100172ED0 /* IGTestSingleStoryboardViewController.m in Sources */, + 8240C7F21DC284C300B3AAE7 /* IGListAdapterStoryboardTests.m in Sources */, + 8240C7F01DC272CA00B3AAE7 /* IGTestStoryboardSupplementaryView.m in Sources */, + 821BC4CB1DB8D60100172ED0 /* IGTestStoryboardViewController.m in Sources */, 821BC4D01DB8D90900172ED0 /* IGTestStoryboardCell.m in Sources */, 88144F161D870EDC007C7F66 /* IGListTestUICollectionViewDataSource.m in Sources */, 88144F091D870EDC007C7F66 /* IGListAdapterUpdaterTests.m in Sources */, 88144F0F1D870EDC007C7F66 /* IGListObjectMapTests.m in Sources */, + 8240C7F81DC2F3FB00B3AAE7 /* IGListTestStoryboardSection.m in Sources */, 26271C8A1DAE94E40073E116 /* IGTestSingleNibItemDataSource.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Source/IGListAdapter.m b/Source/IGListAdapter.m index 34a706b99..1c64a6ff0 100644 --- a/Source/IGListAdapter.m +++ b/Source/IGListAdapter.m @@ -778,6 +778,21 @@ - (__kindof UICollectionReusableView *)dequeueReusableSupplementaryViewOfKind:(N return [collectionView dequeueReusableSupplementaryViewOfKind:elementKind withReuseIdentifier:identifier forIndexPath:indexPath]; } +- (__kindof UICollectionReusableView *)dequeueReusableSupplementaryViewFromStoryboardOfKind:(NSString *)elementKind + withIdentifier:(NSString *)identifier + forSectionController:(IGListSectionController *)sectionController + atIndex:(NSInteger)index { + IGAssertMainThread(); + IGParameterAssert(elementKind.length > 0); + IGParameterAssert(identifier.length > 0); + IGParameterAssert(sectionController != nil); + IGParameterAssert(index >= 0); + UICollectionView *collectionView = self.collectionView; + IGAssert(collectionView != nil, @"Dequeueing Supplementary View from storyboard of kind %@ with identifier %@ for section controller %@ without a collection view at index %zi", elementKind, identifier, sectionController, index); + NSIndexPath *indexPath = [self indexPathForSectionController:sectionController index:index]; + return [collectionView dequeueReusableSupplementaryViewOfKind:elementKind withReuseIdentifier:identifier forIndexPath:indexPath]; +} + - (void)reloadInSectionController:(IGListSectionController *)sectionController atIndexes:(NSIndexSet *)indexes { IGAssertMainThread(); IGParameterAssert(indexes != nil); diff --git a/Source/IGListCollectionContext.h b/Source/IGListCollectionContext.h index 28ba5dc80..b88b5aac9 100644 --- a/Source/IGListCollectionContext.h +++ b/Source/IGListCollectionContext.h @@ -116,8 +116,6 @@ NS_ASSUME_NONNULL_BEGIN @param index The index of the cell. @return A cell dequeued from the reuse pool or newly created. - - @note This method uses a string representation of the cell class as the identifier. */ - (__kindof UICollectionViewCell *)dequeueReusableCellFromStoryboardWithIdentifier:(NSString *)identifier forSectionController:(IGListSectionController *)sectionController @@ -140,6 +138,21 @@ NS_ASSUME_NONNULL_BEGIN class:(Class)viewClass atIndex:(NSInteger)index; +/** + Dequeues a supplementary view from the UICollectionView reuse pool. + + @param elementKind The kind of supplementary veiw. + @param identifier The identifier of the supplementary view in storyboard. + @param sectionController The section controller requesting this information. + @param index The index of the supplementary vew. + + @return A supplementary view dequeued from the reuse pool or newly created. + */ +- (__kindof UICollectionReusableView *)dequeueReusableSupplementaryViewFromStoryboardOfKind:(NSString *)elementKind + withIdentifier:(NSString *)identifier + forSectionController:(IGListSectionController *)sectionController + atIndex:(NSInteger)index; + /** Reloads cells in the section controller. diff --git a/Source/IGListStackedSectionController.m b/Source/IGListStackedSectionController.m index cf4e480bb..042ab0d9f 100644 --- a/Source/IGListStackedSectionController.m +++ b/Source/IGListStackedSectionController.m @@ -212,8 +212,8 @@ - (UICollectionViewCell *)dequeueReusableCellFromStoryboardWithIdentifier:(NSStr atIndex:(NSInteger)index { const NSUInteger offset = [self offsetForSectionController:sectionController]; return (UICollectionViewCell *_Nonnull)[self.collectionContext dequeueReusableCellFromStoryboardWithIdentifier:identifier - forSectionController:self - atIndex:(index + offset)]; + forSectionController:self + atIndex:(index + offset)]; } - (UICollectionReusableView *)dequeueReusableSupplementaryViewOfKind:(NSString *)elementKind @@ -227,6 +227,17 @@ - (UICollectionReusableView *)dequeueReusableSupplementaryViewOfKind:(NSString * atIndex:(index + offset)]; } +- (UICollectionReusableView *)dequeueReusableSupplementaryViewFromStoryboardOfKind:(NSString *)elementKind + withIdentifier:(NSString *)identifier + forSectionController:(IGListSectionController *)sectionController + atIndex:(NSInteger)index { + const NSUInteger offset = [self offsetForSectionController:sectionController]; + return (UICollectionViewCell *_Nonnull)[self.collectionContext dequeueReusableSupplementaryViewFromStoryboardOfKind:elementKind + withIdentifier:identifier + forSectionController:self + atIndex:(index + offset)]; +} + - (void)reloadInSectionController:(IGListSectionController *)sectionController atIndexes:(NSIndexSet *)indexes { NSIndexSet *itemIndexes = [self itemIndexesForSectionController:sectionController indexes:indexes]; [self.collectionContext reloadInSectionController:self atIndexes:itemIndexes]; diff --git a/Tests/Assets/IGTestStoryboard.storyboard b/Tests/Assets/IGTestStoryboard.storyboard index 4a6be3b16..e609cf30e 100644 --- a/Tests/Assets/IGTestStoryboard.storyboard +++ b/Tests/Assets/IGTestStoryboard.storyboard @@ -1,5 +1,5 @@ - + @@ -7,10 +7,10 @@ - + - + @@ -22,17 +22,17 @@ - - + + - + - + + + + + + + + + + + + + + + + + @@ -64,7 +84,7 @@ - + diff --git a/Tests/IGListAdapterStoryboardTests.m b/Tests/IGListAdapterStoryboardTests.m new file mode 100644 index 000000000..4b15e4629 --- /dev/null +++ b/Tests/IGListAdapterStoryboardTests.m @@ -0,0 +1,85 @@ +/** + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +#import + +#import "IGListAdapterInternal.h" +#import "IGListTestAdapterStoryboardDataSource.h" +#import "IGListStackedSectionControllerInternal.h" +#import "IGTestStoryboardViewController.h" +#import "IGTestStoryboardSupplementarySource.h" + +#define genTestObject(k, v) [[IGTestObject alloc] initWithKey:k value:v] + +static const CGRect kStackTestFrame = (CGRect){{0.0, 0.0}, {100.0, 100.0}}; + +@interface IGListAdapterStoryboardTests : XCTestCase + +@property (nonatomic, strong) UIWindow *window; +@property (nonatomic, strong) IGListCollectionView *collectionView; +@property (nonatomic, strong) IGListAdapter *adapter; +@property (nonatomic, strong) IGListTestAdapterStoryboardDataSource *dataSource; +@property (nonatomic, strong) IGListAdapterUpdater *updater; +@property (nonatomic, strong) IGTestStoryboardViewController *viewController; + +@end + +@implementation IGListAdapterStoryboardTests + +- (void)setUp { + [super setUp]; + + self.window = [[UIWindow alloc] initWithFrame:kStackTestFrame]; + UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"IGTestStoryboard" bundle:[NSBundle bundleForClass:self.class]]; + self.viewController = [storyboard instantiateViewControllerWithIdentifier:@"testVC"]; + [self.window addSubview:self.viewController.view]; + [self.viewController performSelectorOnMainThread:@selector(loadView) withObject:nil waitUntilDone:YES]; + self.collectionView = self.viewController.collectionView; + + self.dataSource = [[IGListTestAdapterStoryboardDataSource alloc] init]; + self.updater = [[IGListAdapterUpdater alloc] init]; + self.adapter = [[IGListAdapter alloc] initWithUpdater:self.updater viewController:self.viewController workingRangeSize:0]; +} + +- (void)tearDown { + [super tearDown]; + + self.adapter = nil; + self.collectionView = nil; + self.dataSource = nil; +} + +- (void)setupWithObjects:(NSArray *)objects { + self.dataSource.objects = objects; + self.adapter.collectionView = self.viewController.collectionView; + self.adapter.dataSource = self.dataSource; + [self.adapter reloadDataWithCompletion:nil]; + + IGTestStoryboardSupplementarySource *supplementarySource = [IGTestStoryboardSupplementarySource new]; + supplementarySource.collectionContext = self.adapter; + supplementarySource.supportedElementKinds = @[UICollectionElementKindSectionHeader]; + + IGListSectionController *controller = [self.adapter sectionControllerForObject:@1]; + controller.supplementaryViewSource = supplementarySource; + supplementarySource.sectionController = controller; + + [self.adapter performUpdatesAnimated:NO completion:nil]; + [self.collectionView layoutIfNeeded]; +} + +- (void)test_whenSupplementarySourceSupportsHeader { + [self setupWithObjects:@[genTestObject(@1, @"Foo")]]; + + XCTAssertNotNil([self.collectionView supplementaryViewForElementKind:UICollectionElementKindSectionHeader atIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]]); +} + + +@end diff --git a/Tests/IGListSingleStoryboardItemControllerTests.m b/Tests/IGListSingleStoryboardItemControllerTests.m index 19d738457..0acd42d4c 100644 --- a/Tests/IGListSingleStoryboardItemControllerTests.m +++ b/Tests/IGListSingleStoryboardItemControllerTests.m @@ -11,7 +11,7 @@ #import "IGTestStoryboardCell.h" #import "IGTestSingleStoryboardItemDataSource.h" -#import "IGTestSingleStoryboardViewController.h" +#import "IGTestStoryboardViewController.h" #define genTestObject(k, v) [[IGTestObject alloc] initWithKey:k value:v] @@ -23,7 +23,7 @@ @interface IGListSingleStoryboardSectionControllerTests : XCTestCase @property (nonatomic, strong) IGListAdapter *adapter; @property (nonatomic, strong) IGListAdapterUpdater *updater; @property (nonatomic, strong) IGTestSingleStoryboardItemDataSource *dataSource; -@property (nonatomic, strong) IGTestSingleStoryboardViewController *viewController; +@property (nonatomic, strong) IGTestStoryboardViewController *viewController; @property (nonatomic, strong) UIWindow *window; @end diff --git a/Tests/Objects/IGListTestAdapterStoryboardDataSource.h b/Tests/Objects/IGListTestAdapterStoryboardDataSource.h new file mode 100644 index 000000000..772bb155c --- /dev/null +++ b/Tests/Objects/IGListTestAdapterStoryboardDataSource.h @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +#import + +@interface IGListTestAdapterStoryboardDataSource : NSObject + +// array of numbers which is then passed to -[IGListTestSection setItems:] +@property (nonatomic, strong) NSArray *objects; + +@property (nonatomic, strong) UIView *backgroundView; + +@end diff --git a/Tests/Objects/IGListTestAdapterStoryboardDataSource.m b/Tests/Objects/IGListTestAdapterStoryboardDataSource.m new file mode 100644 index 000000000..ddf06ce97 --- /dev/null +++ b/Tests/Objects/IGListTestAdapterStoryboardDataSource.m @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "IGListTestAdapterStoryboardDataSource.h" + +#import + +#import "IGListTestStoryboardSection.h" + +@implementation IGListTestAdapterStoryboardDataSource + +- (NSArray *)objectsForListAdapter:(IGListAdapter *)listAdapter { + return self.objects; +} + +- (IGListSectionController *)listAdapter:(IGListAdapter *)listAdapter sectionControllerForObject:(id)object { + IGListTestStoryboardSection *list = [[IGListTestStoryboardSection alloc] init]; + return list; +} + +- (nullable UIView *)emptyViewForListAdapter:(IGListAdapter *)listAdapter { + return self.backgroundView; +} + +@end diff --git a/Tests/Objects/IGListTestStoryboardSection.h b/Tests/Objects/IGListTestStoryboardSection.h new file mode 100644 index 000000000..b84af0160 --- /dev/null +++ b/Tests/Objects/IGListTestStoryboardSection.h @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +#import +#import + +@interface IGListTestStoryboardSection : IGListSectionController + +@property (nonatomic, assign) NSInteger items; + +@end diff --git a/Tests/Objects/IGListTestStoryboardSection.m b/Tests/Objects/IGListTestStoryboardSection.m new file mode 100644 index 000000000..8992e204e --- /dev/null +++ b/Tests/Objects/IGListTestStoryboardSection.m @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "IGListTestStoryboardSection.h" +#import "IGTestStoryboardCell.h" + +@implementation IGListTestStoryboardSection + +- (NSInteger)numberOfItems { + return self.items; +} + +- (CGSize)sizeForItemAtIndex:(NSInteger)index { + return CGSizeMake(100, 45); +} + +- (UICollectionViewCell *)cellForItemAtIndex:(NSInteger)index { + return [self.collectionContext dequeueReusableCellFromStoryboardWithIdentifier:@"IGTestStoryboardCell" + forSectionController:self + atIndex:index]; +} + +- (void)didUpdateToObject:(id)object { + if ([object isKindOfClass:[NSNumber class]]) { + self.items = [object integerValue]; + } +} + +- (void)didSelectItemAtIndex:(NSInteger)index {} + +@end diff --git a/Tests/Objects/IGTestStoryboardSupplementarySource.h b/Tests/Objects/IGTestStoryboardSupplementarySource.h new file mode 100644 index 000000000..d860c7db0 --- /dev/null +++ b/Tests/Objects/IGTestStoryboardSupplementarySource.h @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +#import + +@interface IGTestStoryboardSupplementarySource : NSObject + +@property (nonatomic, strong, readwrite) NSArray *supportedElementKinds; + +@property (nonatomic, weak) id collectionContext; + +@property (nonatomic, weak) IGListSectionController *sectionController; + +@end diff --git a/Tests/Objects/IGTestStoryboardSupplementarySource.m b/Tests/Objects/IGTestStoryboardSupplementarySource.m new file mode 100644 index 000000000..9e3956c6d --- /dev/null +++ b/Tests/Objects/IGTestStoryboardSupplementarySource.m @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "IGTestStoryboardSupplementarySource.h" +#import "IGTestStoryboardSupplementaryView.h" + +@implementation IGTestStoryboardSupplementarySource + +- (UICollectionReusableView *)viewForSupplementaryElementOfKind:(NSString *)elementKind + atIndex:(NSInteger)index { + IGTestStoryboardSupplementaryView *view = [self.collectionContext dequeueReusableSupplementaryViewFromStoryboardOfKind:elementKind + withIdentifier:@"IGTestStoryboardSupplementaryView" + forSectionController:self.sectionController + atIndex:index]; + view.label.text = @"Header"; + return view; +} + +- (CGSize)sizeForSupplementaryViewOfKind:(NSString *)elementKind atIndex:(NSInteger)index { + return CGSizeMake([self.collectionContext containerSize].width, 45); +} + +- (CGSize)estimatedSizeForSupplementaryViewOfKind:(NSString *)elementKind + atIndex:(NSInteger)index { + return CGSizeZero; +} + + +@end diff --git a/Tests/Objects/IGTestStoryboardSupplementaryView.h b/Tests/Objects/IGTestStoryboardSupplementaryView.h new file mode 100644 index 000000000..bd89806fb --- /dev/null +++ b/Tests/Objects/IGTestStoryboardSupplementaryView.h @@ -0,0 +1,16 @@ +/** + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +@interface IGTestStoryboardSupplementaryView : UICollectionReusableView + +@property (weak, nonatomic) IBOutlet UILabel *label; + +@end diff --git a/Tests/Objects/IGTestStoryboardSupplementaryView.m b/Tests/Objects/IGTestStoryboardSupplementaryView.m new file mode 100644 index 000000000..47187d296 --- /dev/null +++ b/Tests/Objects/IGTestStoryboardSupplementaryView.m @@ -0,0 +1,14 @@ +/** + * Copyright (c) 2016-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "IGTestStoryboardSupplementaryView.h" + +@implementation IGTestStoryboardSupplementaryView + +@end diff --git a/Tests/Objects/IGTestSingleStoryboardViewController.h b/Tests/Objects/IGTestStoryboardViewController.h similarity index 88% rename from Tests/Objects/IGTestSingleStoryboardViewController.h rename to Tests/Objects/IGTestStoryboardViewController.h index 85939fd78..c2c8f4100 100644 --- a/Tests/Objects/IGTestSingleStoryboardViewController.h +++ b/Tests/Objects/IGTestStoryboardViewController.h @@ -15,7 +15,7 @@ #import "IGTestObject.h" -@interface IGTestSingleStoryboardViewController : UIViewController +@interface IGTestStoryboardViewController : UIViewController @property (weak, nonatomic) IBOutlet IGListCollectionView *collectionView; diff --git a/Tests/Objects/IGTestSingleStoryboardViewController.m b/Tests/Objects/IGTestStoryboardViewController.m similarity index 63% rename from Tests/Objects/IGTestSingleStoryboardViewController.m rename to Tests/Objects/IGTestStoryboardViewController.m index 1ffead515..8cf49edc5 100644 --- a/Tests/Objects/IGTestSingleStoryboardViewController.m +++ b/Tests/Objects/IGTestStoryboardViewController.m @@ -7,16 +7,13 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import "IGTestSingleStoryboardViewController.h" - -#import - +#import "IGTestStoryboardViewController.h" #import "IGTestStoryboardCell.h" -@interface IGTestSingleStoryboardViewController () +@interface IGTestStoryboardViewController () @end -@implementation IGTestSingleStoryboardViewController +@implementation IGTestStoryboardViewController @end