react-native-navigation的迁移库

RNNComponentPresenterTest.m 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. #import <XCTest/XCTest.h>
  2. #import <OCMock/OCMock.h>
  3. #import "RNNComponentPresenter.h"
  4. #import "UIViewController+RNNOptions.h"
  5. #import "RNNComponentViewController.h"
  6. #import "UIViewController+LayoutProtocol.h"
  7. #import "RNNTitleViewHelper.h"
  8. #import "RCTConvert+Modal.h"
  9. @interface RNNComponentPresenterTest : XCTestCase
  10. @property (nonatomic, strong) RNNComponentPresenter *uut;
  11. @property (nonatomic, strong) RNNNavigationOptions *options;
  12. @property (nonatomic, strong) UIViewController *boundViewController;
  13. @property (nonatomic, strong) RNNReactComponentRegistry *componentRegistry;
  14. @end
  15. @implementation RNNComponentPresenterTest
  16. - (void)setUp {
  17. [super setUp];
  18. self.componentRegistry = [OCMockObject partialMockForObject:[RNNReactComponentRegistry new]];
  19. self.uut = [[RNNComponentPresenter alloc] initWithComponentRegistry:self.componentRegistry:[[RNNNavigationOptions alloc] initEmptyOptions]];
  20. self.boundViewController = [OCMockObject partialMockForObject:[RNNComponentViewController new]];
  21. [self.uut boundViewController:self.boundViewController];
  22. self.options = [[RNNNavigationOptions alloc] initEmptyOptions];
  23. }
  24. - (void)testApplyOptions_backgroundImageDefaultNilShouldNotAddSubview {
  25. [self.uut applyOptions:self.options];
  26. XCTAssertTrue((self.boundViewController.view.subviews.count) == 0);
  27. }
  28. - (void)testApplyOptions_topBarPrefersLargeTitleDefaultFalse {
  29. [self.uut applyOptions:self.options];
  30. XCTAssertTrue(self.boundViewController.navigationItem.largeTitleDisplayMode == UINavigationItemLargeTitleDisplayModeNever);
  31. }
  32. - (void)testApplyOptions_layoutBackgroundColorDefaultWhiteColor {
  33. [self.uut applyOptions:self.options];
  34. XCTAssertNil(self.boundViewController.view.backgroundColor);
  35. }
  36. - (void)testApplyOptions_statusBarBlurDefaultFalse {
  37. [self.uut applyOptions:self.options];
  38. XCTAssertNil([self.boundViewController.view viewWithTag:BLUR_STATUS_TAG]);
  39. }
  40. - (void)testApplyOptions_statusBarStyleDefaultStyle {
  41. [self.uut applyOptions:self.options];
  42. XCTAssertTrue([self.boundViewController preferredStatusBarStyle] == UIStatusBarStyleDefault);
  43. }
  44. - (void)testApplyOptions_backButtonVisibleDefaultTrue {
  45. [self.uut applyOptions:self.options];
  46. XCTAssertFalse(self.boundViewController.navigationItem.hidesBackButton);
  47. }
  48. - (void)testApplyOptions_drawBehindTabBarTrueWhenVisibleFalse {
  49. self.options.bottomTabs.visible = [[Bool alloc] initWithValue:@(0)];
  50. [[(id) self.boundViewController expect] setDrawBehindTabBar:YES];
  51. [self.uut applyOptionsOnInit:self.options];
  52. [(id)self.boundViewController verify];
  53. }
  54. - (void)testApplyOptions_setOverlayTouchOutsideIfHasValue {
  55. self.options.overlay.interceptTouchOutside = [[Bool alloc] initWithBOOL:YES];
  56. [(UIViewController *) [(id) self.boundViewController expect] setInterceptTouchOutside:YES];
  57. [self.uut applyOptions:self.options];
  58. [(id)self.boundViewController verify];
  59. }
  60. - (void)testBindViewControllerShouldCreateNavigationButtonsCreator {
  61. RNNComponentPresenter* presenter = [[RNNComponentPresenter alloc] init];
  62. [presenter boundViewController:self.boundViewController];
  63. XCTAssertNotNil(presenter.navigationButtons);
  64. }
  65. - (void)testApplyOptionsOnInit_shouldSetModalPresentationStyleWithDefault {
  66. [(UIViewController *) [(id) self.boundViewController expect] setModalPresentationStyle:[RCTConvert defaultModalPresentationStyle]];
  67. [self.uut applyOptionsOnInit:self.options];
  68. [(id)self.boundViewController verify];
  69. }
  70. - (void)testApplyOptionsOnInit_shouldSetModalTransitionStyleWithDefault {
  71. [(UIViewController *) [(id) self.boundViewController expect] setModalTransitionStyle:UIModalTransitionStyleCoverVertical];
  72. [self.uut applyOptionsOnInit:self.options];
  73. [(id)self.boundViewController verify];
  74. }
  75. - (void)testApplyOptionsOnInit_shouldSetModalPresentationStyleWithValue {
  76. self.options.modalPresentationStyle = [[Text alloc] initWithValue:@"overCurrentContext"];
  77. [(UIViewController *) [(id) self.boundViewController expect] setModalPresentationStyle:UIModalPresentationOverCurrentContext];
  78. [self.uut applyOptionsOnInit:self.options];
  79. [(id)self.boundViewController verify];
  80. }
  81. - (void)testApplyOptionsOnInit_shouldSetModalTransitionStyleWithValue {
  82. self.options.modalTransitionStyle = [[Text alloc] initWithValue:@"crossDissolve"];
  83. [(UIViewController *) [(id) self.boundViewController expect] setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
  84. [self.uut applyOptionsOnInit:self.options];
  85. [(id)self.boundViewController verify];
  86. }
  87. -(void)testApplyOptionsOnInit_TopBarDrawUnder_true {
  88. self.options.topBar.drawBehind = [[Bool alloc] initWithValue:@(1)];
  89. [[(id) self.boundViewController expect] setDrawBehindTopBar:YES];
  90. [self.uut applyOptionsOnInit:self.options];
  91. [(id)self.boundViewController verify];
  92. }
  93. -(void)testApplyOptionsOnInit_TopBarDrawUnder_false {
  94. self.options.topBar.drawBehind = [[Bool alloc] initWithValue:@(0)];
  95. [[(id) self.boundViewController expect] setDrawBehindTopBar:NO];
  96. [self.uut applyOptionsOnInit:self.options];
  97. [(id)self.boundViewController verify];
  98. }
  99. -(void)testApplyOptionsOnInit_BottomTabsDrawUnder_true {
  100. self.options.bottomTabs.drawBehind = [[Bool alloc] initWithValue:@(1)];
  101. [[(id) self.boundViewController expect] setDrawBehindTabBar:YES];
  102. [self.uut applyOptionsOnInit:self.options];
  103. [(id)self.boundViewController verify];
  104. }
  105. -(void)testApplyOptionsOnInit_BottomTabsDrawUnder_false {
  106. self.options.bottomTabs.drawBehind = [[Bool alloc] initWithValue:@(0)];
  107. [[(id) self.boundViewController expect] setDrawBehindTabBar:NO];
  108. [self.uut applyOptionsOnInit:self.options];
  109. [(id)self.boundViewController verify];
  110. }
  111. - (void)testReactViewShouldBeReleasedOnDealloc {
  112. RNNComponentViewController* bindViewController = [RNNComponentViewController new];
  113. bindViewController.layoutInfo = [self createLayoutInfoWithComponentId:@"componentId"];
  114. [self.uut boundViewController:bindViewController];
  115. self.options.topBar.title.component = [[RNNComponentOptions alloc] initWithDict:@{@"name": @"componentName"}];
  116. [[(id)self.componentRegistry expect] clearComponentsForParentId:self.uut.boundComponentId];
  117. self.uut = nil;
  118. [(id)self.componentRegistry verify];
  119. }
  120. - (void)testBindViewControllerShouldSetBoundComponentId {
  121. RNNComponentViewController* bindViewController = [RNNComponentViewController new];
  122. RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] init];
  123. layoutInfo.componentId = @"componentId";
  124. bindViewController.layoutInfo = layoutInfo;
  125. [self.uut boundViewController:bindViewController];
  126. XCTAssertEqual(self.uut.boundComponentId, @"componentId");
  127. }
  128. - (void)testRenderComponentsCreateReactViewWithBoundComponentId {
  129. RNNComponentViewController* boundViewController = [RNNComponentViewController new];
  130. RNNLayoutInfo* layoutInfo = [self createLayoutInfoWithComponentId:@"componentId"];
  131. boundViewController.layoutInfo = layoutInfo;
  132. boundViewController.defaultOptions = [[RNNNavigationOptions alloc] initEmptyOptions];
  133. [self.uut boundViewController:boundViewController];
  134. self.options.topBar.title.component = [[RNNComponentOptions alloc] initWithDict:@{@"name": @"titleComponent", @"componentId": @"id"}];
  135. [[(id)self.componentRegistry expect] createComponentIfNotExists:[OCMArg checkWithBlock:^BOOL(RNNComponentOptions* options) {
  136. return [options.name.get isEqual:@"titleComponent"] &&
  137. [options.componentId.get isEqual:@"id"];
  138. }] parentComponentId:self.uut.boundComponentId reactViewReadyBlock:[OCMArg any]];
  139. [self.uut renderComponents:self.options perform:nil];
  140. [(id)self.componentRegistry verify];
  141. XCTAssertEqual(self.uut.boundComponentId, @"componentId");
  142. }
  143. - (void)testRenderComponentsCreateReactViewFromDefaultOptions {
  144. RNNComponentViewController* boundViewController = [RNNComponentViewController new];
  145. boundViewController.layoutInfo = [self createLayoutInfoWithComponentId:@"componentId"];
  146. self.uut.defaultOptions = [[RNNNavigationOptions alloc] initEmptyOptions];
  147. [self.uut boundViewController:boundViewController];
  148. self.uut.defaultOptions.topBar.title.component = [[RNNComponentOptions alloc] initWithDict:@{@"name": @"titleComponent", @"componentId": @"id"}];
  149. [[(id)self.componentRegistry expect] createComponentIfNotExists:[OCMArg checkWithBlock:^BOOL(RNNComponentOptions* options) {
  150. return [options.name.get isEqual:@"titleComponent"] &&
  151. [options.componentId.get isEqual:@"id"];
  152. }] parentComponentId:self.uut.boundComponentId reactViewReadyBlock:[OCMArg any]];
  153. [self.uut renderComponents:self.options perform:nil];
  154. [(id)self.componentRegistry verify];
  155. XCTAssertEqual(self.uut.boundComponentId, @"componentId");
  156. }
  157. - (void)testRemoveTitleComponentIfNeeded_componentIsRemovedIfTitleTextIsDefined {
  158. id mockTitle = [OCMockObject niceMockForClass:[RNNReactView class]];
  159. OCMStub([self.componentRegistry createComponentIfNotExists:[OCMArg any] parentComponentId:[OCMArg any] reactViewReadyBlock:nil]).andReturn(mockTitle);
  160. RNNComponentOptions* component = [RNNComponentOptions new];
  161. component.name = [[Text alloc] initWithValue:@"componentName"];
  162. component.componentId = [[Text alloc] initWithValue:@"someId"];
  163. _options.topBar.title.component = component;
  164. [self.uut mergeOptions:_options resolvedOptions:[[RNNNavigationOptions alloc] initEmptyOptions]];
  165. XCTAssertNotNil(self.boundViewController.navigationItem.titleView);
  166. XCTAssertEqual(self.boundViewController.navigationItem.titleView, mockTitle);
  167. [[mockTitle expect] removeFromSuperview];
  168. _options = [[RNNNavigationOptions alloc] initEmptyOptions];
  169. _options.topBar.title.text = [[Text alloc] initWithValue:@""];
  170. [self.uut mergeOptions:_options resolvedOptions:[[RNNNavigationOptions alloc] initEmptyOptions]];
  171. XCTAssertNotEqual(self.boundViewController.navigationItem.titleView, mockTitle);
  172. [mockTitle verify];
  173. }
  174. - (void)testRemoveTitleComponentIfNeeded_componentIsNotRemovedIfMergeOptionsIsCalledWithoutTitleText {
  175. id mockTitle = [OCMockObject niceMockForClass:[RNNReactView class]];
  176. OCMStub([self.componentRegistry createComponentIfNotExists:[OCMArg any] parentComponentId:[OCMArg any] reactViewReadyBlock:nil]).andReturn(mockTitle);
  177. RNNComponentOptions* component = [RNNComponentOptions new];
  178. component.name = [[Text alloc] initWithValue:@"componentName"];
  179. component.componentId = [[Text alloc] initWithValue:@"someId"];
  180. _options.topBar.title.component = component;
  181. [self.uut mergeOptions:_options resolvedOptions:[[RNNNavigationOptions alloc] initEmptyOptions]];
  182. XCTAssertNotNil(self.boundViewController.navigationItem.titleView);
  183. XCTAssertEqual(self.boundViewController.navigationItem.titleView, mockTitle);
  184. _options = [[RNNNavigationOptions alloc] initEmptyOptions];
  185. _options.bottomTabs.visible = [[Bool alloc] initWithBOOL:NO];
  186. [self.uut mergeOptions:_options resolvedOptions:[[RNNNavigationOptions alloc] initEmptyOptions]];
  187. XCTAssertEqual(self.boundViewController.navigationItem.titleView, mockTitle);
  188. }
  189. - (RNNLayoutInfo *)createLayoutInfoWithComponentId:(NSString *)componentId {
  190. RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] init];
  191. layoutInfo.componentId = componentId;
  192. return layoutInfo;
  193. }
  194. @end