From 2660b14084b3c86e668a7c04e8c7d3e4f9168fb6 Mon Sep 17 00:00:00 2001 From: Ryan Nystrom Date: Fri, 18 Nov 2016 11:09:26 -0800 Subject: [PATCH] Test adapter proxy object Summary: Fixes #186 - [x] All tests pass. Demo project builds and runs. - [x] I added tests, an experiment, or detailed why my change isn't tested. - [x] I have reviewed the [contributing guide](https://github.com/Instagram/IGListKit/blob/master/CONTRIBUTING.md) Closes https://github.com/Instagram/IGListKit/pull/218 Differential Revision: D4201040 Pulled By: rnystrom fbshipit-source-id: ef94ea7d77af60abe19dc611f5390b9a8bf25f6a --- IGListKit.xcodeproj/project.pbxproj | 12 +++++ Tests/IGListAdapterProxyTests.m | 84 +++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 Tests/IGListAdapterProxyTests.m diff --git a/IGListKit.xcodeproj/project.pbxproj b/IGListKit.xcodeproj/project.pbxproj index 662845ee..11991919 100644 --- a/IGListKit.xcodeproj/project.pbxproj +++ b/IGListKit.xcodeproj/project.pbxproj @@ -27,6 +27,11 @@ 296177041D9D54E300F40F34 /* IGListSectionMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 296177001D9D54E300F40F34 /* IGListSectionMap.h */; settings = {ATTRIBUTES = (Private, ); }; }; 296177051D9D54E300F40F34 /* IGListSectionMap.m in Sources */ = {isa = PBXBuildFile; fileRef = 296177011D9D54E300F40F34 /* IGListSectionMap.m */; }; 296177061D9D54E300F40F34 /* IGListStackedSectionControllerInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 296177021D9D54E300F40F34 /* IGListStackedSectionControllerInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 29C4748C1DDF45F400AE68CE /* IGListAdapterProxyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 29C4748A1DDF45E700AE68CE /* IGListAdapterProxyTests.m */; }; + 29C4748D1DDF45F900AE68CE /* IGListAdapterProxyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 29C4748A1DDF45E700AE68CE /* IGListAdapterProxyTests.m */; }; + 29C4748E1DDF460500AE68CE /* IGListAdapterStoryboardTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8240C7F11DC284C300B3AAE7 /* IGListAdapterStoryboardTests.m */; }; + 29C4748F1DDF460500AE68CE /* IGListDiffResultTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 294AC6311DDE4C19002FCE5D /* IGListDiffResultTests.m */; }; + 29C474901DDF460500AE68CE /* IGListSectionMapTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 829D7BA81DD1816400549816 /* IGListSectionMapTests.m */; }; 29EA6C491DB43A8000957A88 /* IGTestNibCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 294369B01DB1B7AE0025F6E7 /* IGTestNibCell.xib */; }; 5C81083F8E7AEF4B3EBE8871 /* Pods_IGListKitTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FD40284889DE182FFC7F471E /* Pods_IGListKitTests.framework */; }; 821BC4C01DB8C9D500172ED0 /* IGListSingleStoryboardItemControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 821BC4BE1DB8C95300172ED0 /* IGListSingleStoryboardItemControllerTests.m */; }; @@ -243,6 +248,7 @@ 296177001D9D54E300F40F34 /* IGListSectionMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGListSectionMap.h; sourceTree = ""; }; 296177011D9D54E300F40F34 /* IGListSectionMap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGListSectionMap.m; sourceTree = ""; }; 296177021D9D54E300F40F34 /* IGListStackedSectionControllerInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IGListStackedSectionControllerInternal.h; sourceTree = ""; }; + 29C4748A1DDF45E700AE68CE /* IGListAdapterProxyTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IGListAdapterProxyTests.m; sourceTree = ""; }; 529C388FDB3DF79737F3496A /* Pods_IGListKit_tvOSTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_IGListKit_tvOSTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 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 = ""; }; @@ -564,6 +570,7 @@ children = ( 294369AF1DB1B7AE0025F6E7 /* Assets */, 88144EE21D870EDC007C7F66 /* IGListAdapterE2ETests.m */, + 29C4748A1DDF45E700AE68CE /* IGListAdapterProxyTests.m */, 8240C7F11DC284C300B3AAE7 /* IGListAdapterStoryboardTests.m */, 88144EE31D870EDC007C7F66 /* IGListAdapterTests.m */, 88144EE41D870EDC007C7F66 /* IGListAdapterUpdaterTests.m */, @@ -991,6 +998,7 @@ files = ( 885FE2361DC51B76009CE2B4 /* IGListStackSectionControllerTests.m in Sources */, 885FE2311DC51B76009CE2B4 /* IGListDisplayHandlerTests.m in Sources */, + 29C474901DDF460500AE68CE /* IGListSectionMapTests.m in Sources */, 885FE23B1DC51B86009CE2B4 /* IGListTestUICollectionViewDataSource.m in Sources */, 885FE23D1DC51B86009CE2B4 /* IGTestDelegateController.m in Sources */, 885FE22B1DC51B76009CE2B4 /* IGListAdapterE2ETests.m in Sources */, @@ -1004,12 +1012,15 @@ 885FE2381DC51B86009CE2B4 /* IGListTestAdapterDataSource.m in Sources */, 885FE2341DC51B76009CE2B4 /* IGListSingleNibItemControllerTests.m in Sources */, 885FE2391DC51B86009CE2B4 /* IGListTestOffsettingLayout.m in Sources */, + 29C4748F1DDF460500AE68CE /* IGListDiffResultTests.m in Sources */, 885FE2421DC51B86009CE2B4 /* IGTestSingleStoryboardItemDataSource.m in Sources */, 885FE2301DC51B76009CE2B4 /* IGListDiffTests.m in Sources */, 885FE22E1DC51B76009CE2B4 /* IGListBatchUpdateDataTests.m in Sources */, + 29C4748D1DDF45F900AE68CE /* IGListAdapterProxyTests.m in Sources */, 885FE22C1DC51B76009CE2B4 /* IGListAdapterTests.m in Sources */, 885FE22D1DC51B76009CE2B4 /* IGListAdapterUpdaterTests.m in Sources */, 885FE2351DC51B76009CE2B4 /* IGListSingleStoryboardItemControllerTests.m in Sources */, + 29C4748E1DDF460500AE68CE /* IGListAdapterStoryboardTests.m in Sources */, 885FE2411DC51B86009CE2B4 /* IGTestSingleNibItemDataSource.m in Sources */, 885FE2441DC51B86009CE2B4 /* IGTestStackedDataSource.m in Sources */, 885FE2461DC51B86009CE2B4 /* IGTestSupplementarySource.m in Sources */, @@ -1082,6 +1093,7 @@ 821BC4D01DB8D90900172ED0 /* IGTestStoryboardCell.m in Sources */, 88144F161D870EDC007C7F66 /* IGListTestUICollectionViewDataSource.m in Sources */, 88144F091D870EDC007C7F66 /* IGListAdapterUpdaterTests.m in Sources */, + 29C4748C1DDF45F400AE68CE /* IGListAdapterProxyTests.m in Sources */, 8240C7F81DC2F3FB00B3AAE7 /* IGListTestStoryboardSection.m in Sources */, 26271C8A1DAE94E40073E116 /* IGTestSingleNibItemDataSource.m in Sources */, ); diff --git a/Tests/IGListAdapterProxyTests.m b/Tests/IGListAdapterProxyTests.m new file mode 100644 index 00000000..cf1c8dfe --- /dev/null +++ b/Tests/IGListAdapterProxyTests.m @@ -0,0 +1,84 @@ +/** + * 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 + +#import "IGListAdapterProxy.h" + +@interface IGListAdapterProxyTests : XCTestCase + +@end + +@implementation IGListAdapterProxyTests + +- (void)test_whenSendingInterceptedMethod_thatAdapterReceivesMethod { + id mockAdapter = [OCMockObject mockForClass:[IGListAdapter class]]; + id mockCollectionViewDelegate = [OCMockObject mockForProtocol:@protocol(UICollectionViewDelegate)]; + IGListAdapterProxy *proxy = [[IGListAdapterProxy alloc] initWithCollectionViewTarget:mockCollectionViewDelegate scrollViewTarget:nil interceptor:mockAdapter]; + UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:[UICollectionViewFlowLayout new]]; + NSIndexPath *indexPath = [NSIndexPath new]; + + // method is intercepted and sent to the adapter instead + [[mockAdapter expect] collectionView:collectionView didSelectItemAtIndexPath:indexPath]; + [[mockCollectionViewDelegate reject] collectionView:collectionView didSelectItemAtIndexPath:indexPath]; + [(id)proxy collectionView:collectionView didSelectItemAtIndexPath:indexPath]; + + [mockCollectionViewDelegate verify]; + [mockAdapter verify]; +} + +- (void)test_whenSendingCollectionViewDelegateMethod_thatCollectionViewDelegateReceivesMethod { + id mockAdapter = [OCMockObject mockForClass:[IGListAdapter class]]; + id mockCollectionViewDelegate = [OCMockObject mockForProtocol:@protocol(UICollectionViewDelegate)]; + IGListAdapterProxy *proxy = [[IGListAdapterProxy alloc] initWithCollectionViewTarget:mockCollectionViewDelegate scrollViewTarget:nil interceptor:mockAdapter]; + UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:[UICollectionViewFlowLayout new]]; + NSIndexPath *indexPath = [NSIndexPath new]; + + // method is not intercepted and should be sent to the delegate + [[mockAdapter reject] collectionView:collectionView shouldShowMenuForItemAtIndexPath:indexPath]; + [[mockCollectionViewDelegate expect] collectionView:collectionView shouldShowMenuForItemAtIndexPath:indexPath]; + [(id)proxy collectionView:collectionView shouldShowMenuForItemAtIndexPath:indexPath]; + + [mockCollectionViewDelegate verify]; + [mockAdapter verify]; +} + +- (void)test_whenSendingScrollViewDelegateMethod_whenNoCollectionViewDelegate_thatScrollViewDelegateReceivesMethod { + id mockAdapter = [OCMockObject mockForClass:[IGListAdapter class]]; + id mockCollectionViewDelegate = [OCMockObject mockForProtocol:@protocol(UICollectionViewDelegate)]; + id mockScrollViewDelegate = [OCMockObject mockForProtocol:@protocol(UIScrollViewDelegate)]; + IGListAdapterProxy *proxy = [[IGListAdapterProxy alloc] initWithCollectionViewTarget:mockCollectionViewDelegate scrollViewTarget:mockScrollViewDelegate interceptor:mockAdapter]; + UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:[UICollectionViewFlowLayout new]]; + + // method is not intercepted and should be sent to the appropriate delegate + [[mockAdapter reject] scrollViewDidZoom:collectionView]; + [[mockCollectionViewDelegate reject] scrollViewDidZoom:collectionView]; + [[mockScrollViewDelegate expect] scrollViewDidZoom:collectionView]; + [(id)proxy scrollViewDidZoom:collectionView]; + + [mockCollectionViewDelegate verify]; + [mockScrollViewDelegate verify]; + [mockAdapter verify]; +} + +- (void)test_whenSendingUnimplementedSelector_thatNothingBreaks { + id mockAdapter = [OCMockObject mockForClass:[IGListAdapter class]]; + IGListAdapterProxy *proxy = [[IGListAdapterProxy alloc] initWithCollectionViewTarget:nil scrollViewTarget:nil interceptor:mockAdapter]; + + // this will try to forward a method to nil since there are no targets set + // verify that this fails silently + UIScrollView *scrollView = [UIScrollView new]; + [(id)proxy scrollViewDidZoom:scrollView]; +} + +@end