Skip to content

Commit 5784f6d

Browse files
TimOlivermeta-codesync[bot]
authored andcommitted
Enable unit test suite for tvOS (#1649)
Summary: ## Changes in this pull request Following up on #1401! This PR pulls in koenpunt's PR for tvOS test support and updates it against the latest version of IGListKit. A few changes: * I disabled the unit tests that require storyboards/NIBs for tvOS since we only have iOS formatted assets. We can follow this up in a future PR if need be. * Rewrote the Travis build command for GitHub Actions * Went through and gated any UIKit APIs that aren't available on tvOS. * A few unit tests were failing since UICollectionView on tvOS does have a few implicit behavioral differences. I gated these for now, but if anyone using IGListKit on tvOS actually encounters these errors, please open an issue so we can track it and adjust our test suite accordingly. ### Checklist - [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 added an entry to the `CHANGELOG.md` for any breaking changes, enhancements, or bug fixes. - [x] I have reviewed the [contributing guide](https://github.com/Instagram/IGListKit/blob/main/.github/CONTRIBUTING.md) Pull Request resolved: #1649 Reviewed By: jurmarcus Differential Revision: D88921781 Pulled By: TimOliver fbshipit-source-id: fb8b0becde96a504a88b651343049e51ec438b6c
1 parent 7dddb0d commit 5784f6d

11 files changed

+68
-13
lines changed

.github/workflows/CI.yml

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ jobs:
3434
- name: Run unit tests for macOS
3535
run: |
3636
set -o pipefail
37-
xcodebuild build build-for-testing -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -destination "platform=macOS" -configuration Debug ONLY_ACTIVE_ARCH=NO CODE_SIGNING_REQUIRED=NO ONLY_ACTIVE_ARCH=YES | bundle exec xcpretty -c
38-
xcodebuild analyze test-without-building -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -destination "platform=macOS" -configuration Debug ONLY_ACTIVE_ARCH=NO CODE_SIGNING_REQUIRED=NO ONLY_ACTIVE_ARCH=YES | bundle exec xcpretty -c
37+
xcodebuild build build-for-testing -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -destination "platform=macOS" -configuration Debug CODE_SIGNING_REQUIRED=NO ONLY_ACTIVE_ARCH=YES | bundle exec xcpretty -c
38+
xcodebuild analyze test-without-building -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -destination "platform=macOS" -configuration Debug CODE_SIGNING_REQUIRED=NO ONLY_ACTIVE_ARCH=YES | bundle exec xcpretty -c
3939
4040
iOS:
4141
name: Unit Test iOS
@@ -65,8 +65,8 @@ jobs:
6565
- name: iOS - ${{ matrix.destination }}
6666
run: |
6767
set -o pipefail
68-
xcodebuild build build-for-testing -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -destination "${{ matrix.destination }}" -configuration Debug ONLY_ACTIVE_ARCH=NO CODE_SIGNING_REQUIRED=NO ONLY_ACTIVE_ARCH=YES | bundle exec xcpretty -c
69-
xcodebuild analyze test-without-building -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -destination "${{ matrix.destination }}" -configuration Debug ONLY_ACTIVE_ARCH=NO CODE_SIGNING_REQUIRED=NO ONLY_ACTIVE_ARCH=YES | bundle exec xcpretty -c
68+
xcodebuild build build-for-testing -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -destination "${{ matrix.destination }}" -configuration Debug CODE_SIGNING_REQUIRED=NO ONLY_ACTIVE_ARCH=YES | bundle exec xcpretty -c
69+
xcodebuild analyze test-without-building -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -destination "${{ matrix.destination }}" -configuration Debug CODE_SIGNING_REQUIRED=NO ONLY_ACTIVE_ARCH=YES | bundle exec xcpretty -c
7070
7171
- name: Upload code coverage
7272
run: bundle exec slather
@@ -75,6 +75,37 @@ jobs:
7575
CI_PULL_REQUEST: ${{ github.event.number }}
7676
GIT_BRANCH: ${{ github.head_ref || github.ref_name }}
7777

78+
tvOS:
79+
name: Unit Test tvOS
80+
runs-on: macos-14
81+
env:
82+
DEVELOPER_DIR: /Applications/Xcode.app
83+
PROJECT_NAME: IGListKit.xcodeproj
84+
SCHEME_NAME: IGListKit-tvOS
85+
strategy:
86+
matrix:
87+
destination: ["platform=tvOS Simulator,name=Apple TV,OS=18.2"]
88+
steps:
89+
- name: Checkout
90+
uses: actions/checkout@v3
91+
92+
- name: Cache RubyGems
93+
uses: actions/cache@v3
94+
with:
95+
path: vendor/bundle
96+
key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
97+
restore-keys: |
98+
${{ runner.os }}-gems-
99+
100+
- name: Install ruby gems.
101+
run: bundle install
102+
103+
- name: Run unit tests for tvOS
104+
run: |
105+
set -o pipefail
106+
xcodebuild build build-for-testing -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -destination "${{ matrix.destination }}" -configuration Debug CODE_SIGNING_REQUIRED=NO ONLY_ACTIVE_ARCH=YES | bundle exec xcpretty -c
107+
xcodebuild analyze test-without-building -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -destination "${{ matrix.destination }}" -configuration Debug CODE_SIGNING_REQUIRED=NO ONLY_ACTIVE_ARCH=YES | bundle exec xcpretty -c
108+
78109
CocoaPods:
79110
name: CocoaPods Lint
80111
runs-on: macos-14

IGListKit.xcodeproj/project.pbxproj

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,6 @@
7070
29DA5CA71EA7D37000113926 /* IGListTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 29DA5CA61EA7D37000113926 /* IGListTestCase.m */; };
7171
29DA5CA81EA7D37000113926 /* IGListTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 29DA5CA61EA7D37000113926 /* IGListTestCase.m */; };
7272
29EA6C491DB43A8000957A88 /* IGTestNibCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 294369B01DB1B7AE0025F6E7 /* IGTestNibCell.xib */; };
73-
401B5E63230111EC004099D5 /* IGTestNibCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 294369B01DB1B7AE0025F6E7 /* IGTestNibCell.xib */; };
74-
401B5E64230111F3004099D5 /* IGTestNibSupplementaryView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2904861C1DCD02140007F41D /* IGTestNibSupplementaryView.xib */; };
75-
401B5E65230111F7004099D5 /* IGTestStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 821BC4C21DB8CAE900172ED0 /* IGTestStoryboard.storyboard */; };
7673
576029DC2C61B91D006E50E2 /* IGListViewVisibilityTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 576029D52C61B91D006E50E2 /* IGListViewVisibilityTracker.h */; };
7774
576029DD2C61B91D006E50E2 /* IGListViewVisibilityTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 576029D52C61B91D006E50E2 /* IGListViewVisibilityTracker.h */; };
7875
576029DE2C61B91D006E50E2 /* IGListPerformDiff.h in Headers */ = {isa = PBXBuildFile; fileRef = 576029D62C61B91D006E50E2 /* IGListPerformDiff.h */; };
@@ -1864,7 +1861,7 @@
18641861
BuildIndependentTargetsInParallel = YES;
18651862
CLASSPREFIX = IG;
18661863
LastSwiftUpdateCheck = 1120;
1867-
LastUpgradeCheck = 1620;
1864+
LastUpgradeCheck = 2600;
18681865
ORGANIZATIONNAME = Instagram;
18691866
TargetAttributes = {
18701867
7A02D01C2361520200B49FAE = {
@@ -1968,9 +1965,6 @@
19681965
isa = PBXResourcesBuildPhase;
19691966
buildActionMask = 2147483647;
19701967
files = (
1971-
401B5E65230111F7004099D5 /* IGTestStoryboard.storyboard in Resources */,
1972-
401B5E64230111F3004099D5 /* IGTestNibSupplementaryView.xib in Resources */,
1973-
401B5E63230111EC004099D5 /* IGTestNibCell.xib in Resources */,
19741968
);
19751969
runOnlyForDeploymentPostprocessing = 0;
19761970
};
@@ -2912,6 +2906,7 @@
29122906
SWIFT_OBJC_BRIDGING_HEADER = "Tests/IGListKitTests-Bridging-Header.h";
29132907
SWIFT_TREAT_WARNINGS_AS_ERRORS = YES;
29142908
SWIFT_VERSION = 5.0;
2909+
TARGETED_DEVICE_FAMILY = 3;
29152910
};
29162911
name = Debug;
29172912
};
@@ -2939,6 +2934,7 @@
29392934
SWIFT_OBJC_BRIDGING_HEADER = "Tests/IGListKitTests-Bridging-Header.h";
29402935
SWIFT_TREAT_WARNINGS_AS_ERRORS = YES;
29412936
SWIFT_VERSION = 5.0;
2937+
TARGETED_DEVICE_FAMILY = 3;
29422938
};
29432939
name = Release;
29442940
};

Tests/IGListAdapterE2ETests.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,7 @@ - (void)test_whenSectionControllerMutates_withReloadData_thatSectionControllerMu
588588
[self waitForExpectationsWithTimeout:30 handler:nil];
589589
}
590590

591+
#if !TARGET_OS_TV
591592
- (void)test_whenContentOffsetChanges_withPerformUpdates_thatCollectionViewWorks {
592593
// this test layout changes the offset in -prepareLayout which occurs somewhere between the update block being
593594
// applied and the completion block
@@ -612,6 +613,7 @@ - (void)test_whenContentOffsetChanges_withPerformUpdates_thatCollectionViewWorks
612613
}];
613614
[self waitForExpectationsWithTimeout:30 handler:nil];
614615
}
616+
#endif
615617

616618
- (void)test_whenReloadingItems_withNewItemInstances_thatSectionControllersReceiveNewInstances {
617619
[self setupWithObjects:@[

Tests/IGListAdapterStoryboardTests.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#import "IGTestStoryboardSupplementarySource.h"
1515
#import "IGTestStoryboardViewController.h"
1616

17+
#if !TARGET_OS_TV
18+
1719
static const CGRect kStackTestFrame = (CGRect){{0.0, 0.0}, {100.0, 100.0}};
1820

1921
@interface IGListAdapterStoryboardTests : XCTestCase
@@ -77,3 +79,5 @@ - (void)test_whenSupplementarySourceSupportsHeader {
7779
}
7880

7981
@end
82+
83+
#endif

Tests/IGListAdapterTests.m

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,8 @@ - (void)test_whenCellsExtendBeyondBounds_thatVisibleSectionControllersAreLimited
283283
XCTAssertTrue([visibleSectionControllers containsObject:[self.adapter sectionControllerForObject:@4]]);
284284
}
285285

286-
- (void)test_withEmptySectionPlusFooter_thatVisibleSectionControllersAreCorrect {
286+
#if !TARGET_OS_TV
287+
- (void) test_withEmptySectionPlusFooter_thatVisibleSectionControllersAreCorrect {
287288
self.dataSource.objects = @[@0];
288289
[self.adapter reloadDataWithCompletion:nil];
289290
IGTestSupplementarySource *supplementarySource = [IGTestSupplementarySource new];
@@ -299,6 +300,7 @@ - (void)test_withEmptySectionPlusFooter_thatVisibleSectionControllersAreCorrect
299300
XCTAssertTrue([visibleSectionControllers count] == 1);
300301
XCTAssertTrue(visibleSectionControllers.firstObject.supplementaryViewSource == supplementarySource);
301302
}
303+
#endif
302304

303305
- (void)test_whenCellsExtendBeyondBounds_thatVisibleCellsExistForSectionControllers {
304306
self.dataSource.objects = @[@2, @3, @4, @5, @6];
@@ -476,6 +478,7 @@ - (void)test_whenSupplementarySourceSupportsFooter_thatHeaderViewsAreNil {
476478
XCTAssertNil([self.collectionView supplementaryViewForElementKind:UICollectionElementKindSectionFooter atIndexPath:[NSIndexPath indexPathForItem:0 inSection:1]]);
477479
}
478480

481+
#if !TARGET_OS_TV
479482
- (void)test_whenSupplementarySourceSupportsFooter_withNibs_thatHeaderViewsAreNil {
480483
self.dataSource.objects = @[@1, @2];
481484
[self.adapter reloadDataWithCompletion:nil];
@@ -499,6 +502,7 @@ - (void)test_whenSupplementarySourceSupportsFooter_withNibs_thatHeaderViewsAreNi
499502
XCTAssertNil([self.collectionView supplementaryViewForElementKind:UICollectionElementKindSectionHeader atIndexPath:[NSIndexPath indexPathForItem:0 inSection:1]]);
500503
XCTAssertNil([self.collectionView supplementaryViewForElementKind:UICollectionElementKindSectionFooter atIndexPath:[NSIndexPath indexPathForItem:0 inSection:1]]);
501504
}
505+
#endif
502506

503507
- (void)test_whenAdapterReleased_withSectionControllerStrongRefToCell_thatSectionControllersRelease {
504508
__weak id weakCollectionView = nil, weakAdapter = nil, weakSectionController = nil;
@@ -1665,6 +1669,7 @@ - (void)test_whenUnhighlightingCell_thatSectionControllerReceivesMethod {
16651669
XCTAssertFalse(s2.wasUnhighlighted);
16661670
}
16671671

1672+
#if !TARGET_OS_TV
16681673
- (void)test_whenContextMenuAskedCell_thatCollectionViewDelegateReceivesMethod API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos) {
16691674
self.dataSource.objects = @[@0, @1, @2];
16701675
[self.adapter reloadDataWithCompletion:nil];
@@ -1698,6 +1703,7 @@ - (void)test_whenContextMenuAskedCell_thatSectionControllerReceivesMethod API_AV
16981703
XCTAssertFalse(s1.requestedContextMenu);
16991704
XCTAssertFalse(s2.requestedContextMenu);
17001705
}
1706+
#endif
17011707

17021708
- (void)test_whenDataSourceDoesntHandleObject_thatObjectIsDropped {
17031709
// IGListTestAdapterDataSource does not handle NSStrings

Tests/IGListBindingSectionControllerTests.m

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,8 @@ - (void)test_whenUnhighlightingCell_thatCorrectViewModelUnhighlighted {
196196
XCTAssertEqualObjects(section.unhighlightedViewModel, @"seven");
197197
}
198198

199+
200+
#if !TARGET_OS_TV
199201
- (void)test_whenContextMenuAskedCell_thatCorrectViewModelRetrieved API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos) {
200202
[self setupWithObjects:@[
201203
[[IGTestDiffingObject alloc] initWithKey:@1 objects:@[@7, @"seven"]],
@@ -204,6 +206,7 @@ - (void)test_whenContextMenuAskedCell_thatCorrectViewModelRetrieved API_AVAILABL
204206
IGTestDiffingSectionController *section = [self.adapter sectionControllerForObject:self.dataSource.objects.firstObject];
205207
XCTAssertEqualObjects(section.contextMenuViewModel, @"seven");
206208
}
209+
#endif
207210

208211
- (void)test_whenDeselectingCell_withoutImplementation_thatNoOps {
209212
[self setupWithObjects:@[

Tests/IGListSingleNibItemControllerTests.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#import "IGTestCell.h"
1212
#import "IGTestSingleNibItemDataSource.h"
1313

14+
#if !TARGET_OS_TV
15+
1416
@interface IGListSingleNibSectionControllerTests : IGListTestCase
1517
@end
1618

@@ -86,3 +88,5 @@ - (void)test_whenItemUpdated_thatCellIsConfigured {
8688
}
8789

8890
@end
91+
92+
#endif

Tests/IGListSingleStoryboardItemControllerTests.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
#define genExpectation [self expectationWithDescription:NSStringFromSelector(_cmd)]
1616

17+
#if !TARGET_OS_TV
18+
1719
@interface IGListSingleStoryboardSectionControllerTests : XCTestCase
1820

1921
@property (nonatomic, strong) UICollectionView *collectionView;
@@ -116,3 +118,5 @@ - (void)test_whenItemUpdated_thatCellIsConfigured {
116118
}
117119

118120
@end
121+
122+
#endif

Tests/Objects/IGListTestSection.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,12 @@ - (void)didUnhighlightItemAtIndex:(NSInteger)index {
6060
self.wasUnhighlighted = YES;
6161
}
6262

63+
#if !TARGET_OS_TV
6364
- (UIContextMenuConfiguration *)contextMenuConfigurationForItemAtIndex:(NSInteger)index point:(CGPoint)point {
6465
self.requestedContextMenu = YES;
6566
return nil;
6667
}
68+
#endif
6769

6870
#pragma mark - IGListDisplayDelegate
6971

Tests/Objects/IGTestBindingWithoutDeselectionDelegate.m

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,13 @@ - (void)sectionController:(nonnull IGListBindingSectionController *)sectionContr
3131
viewModel:(nonnull id)viewModel {
3232
}
3333

34-
34+
#if !TARGET_OS_TV
3535
- (UIContextMenuConfiguration * _Nullable)sectionController:(nonnull IGListBindingSectionController *)sectionController
3636
contextMenuConfigurationForItemAtIndex:(NSInteger)index
3737
point:(CGPoint)point
3838
viewModel:(nonnull id)viewModel API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos) {
3939
return nil;
4040
}
41+
#endif
4142

4243
@end

0 commit comments

Comments
 (0)