Skip to content
This repository was archived by the owner on Jan 17, 2019. It is now read-only.

Commit 31983b9

Browse files
authored
Merge pull request #166 from mvlasieva/update-parent-on-reuse
Update components parent wrapper when it is reused
2 parents a898497 + 8d185e7 commit 31983b9

File tree

3 files changed

+68
-1
lines changed

3 files changed

+68
-1
lines changed

sources/HUBComponentReusePool.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ - (HUBComponentWrapper *)componentWrapperForModel:(id<HUBComponentModel>)model
7777
if (existingWrappers.count > 0) {
7878
HUBComponentWrapper * const wrapper = [existingWrappers anyObject];
7979
wrapper.delegate = delegate;
80+
wrapper.parent = parent;
8081
[existingWrappers removeObject:wrapper];
8182
return wrapper;
8283
}

sources/HUBComponentWrapper.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ willUpdateSelectionState:(HUBComponentSelectionState)selectionState;
150150
@property (nonatomic, weak, nullable) id<HUBComponentWrapperDelegate> delegate;
151151

152152
/// The components parent wrapper if it is a child component
153-
@property (nonatomic, weak, nullable, readonly) HUBComponentWrapper *parent;
153+
@property (nonatomic, weak, nullable) HUBComponentWrapper *parent;
154154

155155
/// Whether the wrapper is for a root component, or for a child component
156156
@property (nonatomic, readonly) BOOL isRootComponent;

tests/HUBViewControllerTests.m

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -938,6 +938,72 @@ - (void)testCreatingAndReusingChildComponent
938938
XCTAssertEqual(childComponentWrapper, reusedChildComponentWrapper);
939939
}
940940

941+
- (void)testChildComponentsRemovedFromParentOnReuse
942+
{
943+
HUBComponentMock * const componentA = [HUBComponentMock new];
944+
componentA.view = [[UIView alloc] initWithFrame:CGRectZero];
945+
946+
HUBComponentMock * const componentB = [HUBComponentMock new];
947+
componentB.view = [[UIView alloc] initWithFrame:CGRectZero];
948+
949+
HUBComponentMock * const childComponent = [HUBComponentMock new];
950+
UIView *childComponentView = [[UIView alloc] initWithFrame:CGRectZero];
951+
childComponent.view = childComponentView;
952+
953+
self.componentFactory.components[@"A"] = componentA;
954+
self.componentFactory.components[@"B"] = componentB;
955+
self.componentFactory.components[@"child"] = childComponent;
956+
957+
self.contentOperation.contentLoadingBlock = ^(id<HUBViewModelBuilder> viewModelBuilder) {
958+
id<HUBComponentModelBuilder> const componentModelBuilderA = [viewModelBuilder builderForBodyComponentModelWithIdentifier:@"A"];
959+
componentModelBuilderA.componentName = @"A";
960+
[componentModelBuilderA builderForChildWithIdentifier:@"childA"].componentName = @"child";
961+
962+
id<HUBComponentModelBuilder> const componentModelBuilderB = [viewModelBuilder builderForBodyComponentModelWithIdentifier:@"B"];
963+
componentModelBuilderB.componentName = @"B";
964+
[componentModelBuilderB builderForChildWithIdentifier:@"childB"].componentName = @"child";
965+
966+
return YES;
967+
};
968+
969+
[self simulateViewControllerLayoutCycle];
970+
971+
id<UICollectionViewDataSource> const collectionViewDataSource = self.collectionView.dataSource;
972+
973+
NSIndexPath * const indexPathA = [NSIndexPath indexPathForItem:0 inSection:0];
974+
UICollectionViewCell * const cellA = [collectionViewDataSource collectionView:self.collectionView cellForItemAtIndexPath:indexPathA];
975+
976+
NSIndexPath * const indexPathB = [NSIndexPath indexPathForItem:1 inSection:0];
977+
UICollectionViewCell * const cellB = [collectionViewDataSource collectionView:self.collectionView cellForItemAtIndexPath:indexPathB];
978+
979+
self.collectionView.mockedVisibleCells = @[cellA, cellB];
980+
self.collectionView.cells[indexPathA] = cellA;
981+
self.collectionView.cells[indexPathB] = cellB;
982+
983+
id<HUBComponentChildDelegate> componentAChildDelegate = componentA.childDelegate;
984+
id<HUBComponentModel> const childComponentModelA = [componentA.model childAtIndex:0];
985+
id<HUBComponent> const childComponentWrapperA = [componentAChildDelegate component:componentA childComponentForModel:childComponentModelA];
986+
987+
[componentAChildDelegate component:componentA willDisplayChildAtIndex:0 view:childComponentView];
988+
NSIndexPath * const indexPathChildA = [NSIndexPath indexPathForItem:0 inSection:0];
989+
XCTAssertEqual([self.viewController visibleViewForComponentOfType:HUBComponentTypeBody indexPath:indexPathChildA], childComponentView);
990+
991+
[childComponentWrapperA prepareViewForReuse];
992+
XCTAssertNil([self.viewController visibleViewForComponentOfType:HUBComponentTypeBody indexPath:indexPathChildA]);
993+
994+
id<HUBComponentChildDelegate> componentBChildDelegate = componentB.childDelegate;
995+
id<HUBComponentModel> const childComponentModelB = [componentB.model childAtIndex:0];
996+
id<HUBComponent> const childComponentWrapperB = [componentBChildDelegate component:componentB childComponentForModel:childComponentModelB];
997+
XCTAssertEqual(childComponentWrapperA, childComponentWrapperB);
998+
999+
[componentBChildDelegate component:componentB willDisplayChildAtIndex:0 view:childComponentView];
1000+
NSIndexPath * const indexPathChildB = [NSIndexPath indexPathForItem:0 inSection:1];
1001+
XCTAssertEqual([self.viewController visibleViewForComponentOfType:HUBComponentTypeBody indexPath:indexPathChildB], childComponentView);
1002+
1003+
[childComponentWrapperB prepareViewForReuse];
1004+
XCTAssertNil([self.viewController visibleViewForComponentOfType:HUBComponentTypeBody indexPath:indexPathChildB]);
1005+
}
1006+
9411007
- (void)testSelectionForRootComponent
9421008
{
9431009
NSString * const componentNamespace = @"selectionForRootComponent";

0 commit comments

Comments
 (0)