2015-07-13 15:42:32 +00:00
|
|
|
/**
|
|
|
|
* The examples provided by Facebook are for non-commercial testing and
|
|
|
|
* evaluation purposes only.
|
|
|
|
*
|
|
|
|
* Facebook reserves all rights not expressly granted.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
|
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
|
|
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
*/
|
2015-06-24 08:19:26 +00:00
|
|
|
|
|
|
|
#import <XCTest/XCTest.h>
|
|
|
|
|
2016-11-24 17:44:51 +00:00
|
|
|
#import <React/RCTRootShadowView.h>
|
|
|
|
#import <React/RCTShadowView.h>
|
2016-03-21 10:20:49 +00:00
|
|
|
|
2015-06-24 08:19:26 +00:00
|
|
|
|
|
|
|
@interface RCTShadowViewTests : XCTestCase
|
2016-03-21 10:20:49 +00:00
|
|
|
@property (nonatomic, strong) RCTRootShadowView *parentView;
|
2015-06-24 08:19:26 +00:00
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation RCTShadowViewTests
|
|
|
|
|
2016-03-01 18:13:22 +00:00
|
|
|
- (void)setUp
|
|
|
|
{
|
|
|
|
[super setUp];
|
2016-03-21 10:20:49 +00:00
|
|
|
|
2016-07-20 15:46:00 +00:00
|
|
|
self.parentView = [self _shadowViewWithConfig:^(CSSNodeRef node) {
|
2016-12-02 13:47:43 +00:00
|
|
|
CSSNodeStyleSetFlexDirection(node, YGFlexDirectionColumn);
|
2016-07-20 15:46:00 +00:00
|
|
|
CSSNodeStyleSetWidth(node, 440);
|
|
|
|
CSSNodeStyleSetHeight(node, 440);
|
2016-03-01 18:13:22 +00:00
|
|
|
}];
|
|
|
|
self.parentView.reactTag = @1; // must be valid rootView tag
|
|
|
|
}
|
|
|
|
|
2015-06-24 08:19:26 +00:00
|
|
|
// Just a basic sanity test to ensure css-layout is applied correctly in the context of our shadow view hierarchy.
|
|
|
|
//
|
|
|
|
// ====================================
|
|
|
|
// || header ||
|
|
|
|
// ====================================
|
|
|
|
// || || || ||
|
|
|
|
// || left || center || right ||
|
|
|
|
// || || || ||
|
|
|
|
// ====================================
|
|
|
|
// || footer ||
|
|
|
|
// ====================================
|
|
|
|
//
|
|
|
|
- (void)testApplyingLayoutRecursivelyToShadowView
|
|
|
|
{
|
2016-07-20 15:46:00 +00:00
|
|
|
RCTShadowView *leftView = [self _shadowViewWithConfig:^(CSSNodeRef node) {
|
|
|
|
CSSNodeStyleSetFlex(node, 1);
|
2015-06-24 08:19:26 +00:00
|
|
|
}];
|
|
|
|
|
2016-07-20 15:46:00 +00:00
|
|
|
RCTShadowView *centerView = [self _shadowViewWithConfig:^(CSSNodeRef node) {
|
|
|
|
CSSNodeStyleSetFlex(node, 2);
|
2016-12-02 13:47:43 +00:00
|
|
|
CSSNodeStyleSetMargin(node, YGEdgeLeft, 10);
|
|
|
|
CSSNodeStyleSetMargin(node, YGEdgeRight, 10);
|
2015-06-24 08:19:26 +00:00
|
|
|
}];
|
|
|
|
|
2016-07-20 15:46:00 +00:00
|
|
|
RCTShadowView *rightView = [self _shadowViewWithConfig:^(CSSNodeRef node) {
|
|
|
|
CSSNodeStyleSetFlex(node, 1);
|
2015-06-24 08:19:26 +00:00
|
|
|
}];
|
|
|
|
|
2016-07-20 15:46:00 +00:00
|
|
|
RCTShadowView *mainView = [self _shadowViewWithConfig:^(CSSNodeRef node) {
|
2016-12-02 13:47:43 +00:00
|
|
|
CSSNodeStyleSetFlexDirection(node, YGFlexDirectionRow);
|
2016-07-20 15:46:00 +00:00
|
|
|
CSSNodeStyleSetFlex(node, 2);
|
2016-12-02 13:47:43 +00:00
|
|
|
CSSNodeStyleSetMargin(node, YGEdgeTop, 10);
|
|
|
|
CSSNodeStyleSetMargin(node, YGEdgeBottom, 10);
|
2015-06-24 08:19:26 +00:00
|
|
|
}];
|
|
|
|
|
|
|
|
[mainView insertReactSubview:leftView atIndex:0];
|
|
|
|
[mainView insertReactSubview:centerView atIndex:1];
|
|
|
|
[mainView insertReactSubview:rightView atIndex:2];
|
|
|
|
|
2016-07-20 15:46:00 +00:00
|
|
|
RCTShadowView *headerView = [self _shadowViewWithConfig:^(CSSNodeRef node) {
|
|
|
|
CSSNodeStyleSetFlex(node, 1);
|
2015-06-24 08:19:26 +00:00
|
|
|
}];
|
|
|
|
|
2016-07-20 15:46:00 +00:00
|
|
|
RCTShadowView *footerView = [self _shadowViewWithConfig:^(CSSNodeRef node) {
|
|
|
|
CSSNodeStyleSetFlex(node, 1);
|
2015-06-24 08:19:26 +00:00
|
|
|
}];
|
|
|
|
|
2016-12-02 13:47:43 +00:00
|
|
|
CSSNodeStyleSetPadding(self.parentView.cssNode, YGEdgeLeft, 10);
|
|
|
|
CSSNodeStyleSetPadding(self.parentView.cssNode, YGEdgeTop, 10);
|
|
|
|
CSSNodeStyleSetPadding(self.parentView.cssNode, YGEdgeRight, 10);
|
|
|
|
CSSNodeStyleSetPadding(self.parentView.cssNode, YGEdgeBottom, 10);
|
2016-03-01 18:13:22 +00:00
|
|
|
|
|
|
|
[self.parentView insertReactSubview:headerView atIndex:0];
|
|
|
|
[self.parentView insertReactSubview:mainView atIndex:1];
|
|
|
|
[self.parentView insertReactSubview:footerView atIndex:2];
|
2015-06-24 08:19:26 +00:00
|
|
|
|
2016-03-21 10:20:49 +00:00
|
|
|
[self.parentView collectViewsWithUpdatedFrames];
|
2015-06-24 08:19:26 +00:00
|
|
|
|
2016-03-01 18:13:22 +00:00
|
|
|
XCTAssertTrue(CGRectEqualToRect([self.parentView measureLayoutRelativeToAncestor:self.parentView], CGRectMake(0, 0, 440, 440)));
|
|
|
|
XCTAssertTrue(UIEdgeInsetsEqualToEdgeInsets([self.parentView paddingAsInsets], UIEdgeInsetsMake(10, 10, 10, 10)));
|
2015-06-24 08:19:26 +00:00
|
|
|
|
2016-03-01 18:13:22 +00:00
|
|
|
XCTAssertTrue(CGRectEqualToRect([headerView measureLayoutRelativeToAncestor:self.parentView], CGRectMake(10, 10, 420, 100)));
|
|
|
|
XCTAssertTrue(CGRectEqualToRect([mainView measureLayoutRelativeToAncestor:self.parentView], CGRectMake(10, 120, 420, 200)));
|
|
|
|
XCTAssertTrue(CGRectEqualToRect([footerView measureLayoutRelativeToAncestor:self.parentView], CGRectMake(10, 330, 420, 100)));
|
2015-06-24 08:19:26 +00:00
|
|
|
|
2016-03-01 18:13:22 +00:00
|
|
|
XCTAssertTrue(CGRectEqualToRect([leftView measureLayoutRelativeToAncestor:self.parentView], CGRectMake(10, 120, 100, 200)));
|
|
|
|
XCTAssertTrue(CGRectEqualToRect([centerView measureLayoutRelativeToAncestor:self.parentView], CGRectMake(120, 120, 200, 200)));
|
|
|
|
XCTAssertTrue(CGRectEqualToRect([rightView measureLayoutRelativeToAncestor:self.parentView], CGRectMake(330, 120, 100, 200)));
|
|
|
|
}
|
2015-06-24 08:19:26 +00:00
|
|
|
|
2016-08-03 11:01:45 +00:00
|
|
|
- (void)testAncestorCheck
|
|
|
|
{
|
|
|
|
RCTShadowView *centerView = [self _shadowViewWithConfig:^(CSSNodeRef node) {
|
|
|
|
CSSNodeStyleSetFlex(node, 1);
|
|
|
|
}];
|
2016-08-15 16:15:10 +00:00
|
|
|
|
2016-08-03 11:01:45 +00:00
|
|
|
RCTShadowView *mainView = [self _shadowViewWithConfig:^(CSSNodeRef node) {
|
|
|
|
CSSNodeStyleSetFlex(node, 1);
|
|
|
|
}];
|
2016-08-15 16:15:10 +00:00
|
|
|
|
2016-08-03 11:01:45 +00:00
|
|
|
[mainView insertReactSubview:centerView atIndex:0];
|
|
|
|
|
|
|
|
RCTShadowView *footerView = [self _shadowViewWithConfig:^(CSSNodeRef node) {
|
|
|
|
CSSNodeStyleSetFlex(node, 1);
|
|
|
|
}];
|
2016-08-15 16:15:10 +00:00
|
|
|
|
2016-08-03 11:01:45 +00:00
|
|
|
[self.parentView insertReactSubview:mainView atIndex:0];
|
|
|
|
[self.parentView insertReactSubview:footerView atIndex:1];
|
2016-08-15 16:15:10 +00:00
|
|
|
|
2016-08-03 11:01:45 +00:00
|
|
|
XCTAssertTrue([centerView viewIsDescendantOf:mainView]);
|
|
|
|
XCTAssertFalse([footerView viewIsDescendantOf:mainView]);
|
|
|
|
}
|
|
|
|
|
2016-03-01 18:13:22 +00:00
|
|
|
- (void)testAssignsSuggestedWidthDimension
|
|
|
|
{
|
2016-07-20 15:46:00 +00:00
|
|
|
[self _withShadowViewWithStyle:^(CSSNodeRef node) {
|
2016-12-02 13:47:43 +00:00
|
|
|
CSSNodeStyleSetPosition(node, YGEdgeLeft, 0);
|
|
|
|
CSSNodeStyleSetPosition(node, YGEdgeTop, 0);
|
2016-07-20 15:46:00 +00:00
|
|
|
CSSNodeStyleSetHeight(node, 10);
|
2016-03-01 18:13:22 +00:00
|
|
|
}
|
|
|
|
assertRelativeLayout:CGRectMake(0, 0, 3, 10)
|
|
|
|
withIntrinsicContentSize:CGSizeMake(3, UIViewNoIntrinsicMetric)];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)testAssignsSuggestedHeightDimension
|
|
|
|
{
|
2016-07-20 15:46:00 +00:00
|
|
|
[self _withShadowViewWithStyle:^(CSSNodeRef node) {
|
2016-12-02 13:47:43 +00:00
|
|
|
CSSNodeStyleSetPosition(node, YGEdgeLeft, 0);
|
|
|
|
CSSNodeStyleSetPosition(node, YGEdgeTop, 0);
|
2016-07-20 15:46:00 +00:00
|
|
|
CSSNodeStyleSetWidth(node, 10);
|
2016-03-01 18:13:22 +00:00
|
|
|
}
|
|
|
|
assertRelativeLayout:CGRectMake(0, 0, 10, 4)
|
|
|
|
withIntrinsicContentSize:CGSizeMake(UIViewNoIntrinsicMetric, 4)];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)testDoesNotOverrideDimensionStyleWithSuggestedDimensions
|
|
|
|
{
|
2016-07-20 15:46:00 +00:00
|
|
|
[self _withShadowViewWithStyle:^(CSSNodeRef node) {
|
2016-12-02 13:47:43 +00:00
|
|
|
CSSNodeStyleSetPosition(node, YGEdgeLeft, 0);
|
|
|
|
CSSNodeStyleSetPosition(node, YGEdgeTop, 0);
|
2016-07-20 15:46:00 +00:00
|
|
|
CSSNodeStyleSetWidth(node, 10);
|
|
|
|
CSSNodeStyleSetHeight(node, 10);
|
2016-03-01 18:13:22 +00:00
|
|
|
}
|
|
|
|
assertRelativeLayout:CGRectMake(0, 0, 10, 10)
|
|
|
|
withIntrinsicContentSize:CGSizeMake(3, 4)];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)testDoesNotAssignSuggestedDimensionsWhenStyledWithFlexAttribute
|
|
|
|
{
|
2016-07-20 15:46:00 +00:00
|
|
|
float parentWidth = CSSNodeStyleGetWidth(self.parentView.cssNode);
|
|
|
|
float parentHeight = CSSNodeStyleGetHeight(self.parentView.cssNode);
|
|
|
|
[self _withShadowViewWithStyle:^(CSSNodeRef node) {
|
|
|
|
CSSNodeStyleSetFlex(node, 1);
|
2016-03-01 18:13:22 +00:00
|
|
|
}
|
|
|
|
assertRelativeLayout:CGRectMake(0, 0, parentWidth, parentHeight)
|
|
|
|
withIntrinsicContentSize:CGSizeMake(3, 4)];
|
|
|
|
}
|
|
|
|
|
2016-07-20 15:46:00 +00:00
|
|
|
- (void)_withShadowViewWithStyle:(void(^)(CSSNodeRef node))configBlock
|
2016-03-01 18:13:22 +00:00
|
|
|
assertRelativeLayout:(CGRect)expectedRect
|
|
|
|
withIntrinsicContentSize:(CGSize)contentSize
|
|
|
|
{
|
2016-07-20 15:46:00 +00:00
|
|
|
RCTShadowView *view = [self _shadowViewWithConfig:configBlock];
|
2016-03-01 18:13:22 +00:00
|
|
|
[self.parentView insertReactSubview:view atIndex:0];
|
|
|
|
view.intrinsicContentSize = contentSize;
|
2016-03-21 10:20:49 +00:00
|
|
|
[self.parentView collectViewsWithUpdatedFrames];
|
2016-03-01 18:13:22 +00:00
|
|
|
CGRect actualRect = [view measureLayoutRelativeToAncestor:self.parentView];
|
|
|
|
XCTAssertTrue(CGRectEqualToRect(expectedRect, actualRect),
|
|
|
|
@"Expected layout to be %@, got %@",
|
|
|
|
NSStringFromCGRect(expectedRect),
|
|
|
|
NSStringFromCGRect(actualRect));
|
2015-06-24 08:19:26 +00:00
|
|
|
}
|
|
|
|
|
2016-07-20 15:46:00 +00:00
|
|
|
- (RCTRootShadowView *)_shadowViewWithConfig:(void(^)(CSSNodeRef node))configBlock
|
2015-06-24 08:19:26 +00:00
|
|
|
{
|
2016-03-21 10:20:49 +00:00
|
|
|
RCTRootShadowView *shadowView = [RCTRootShadowView new];
|
2016-07-20 15:46:00 +00:00
|
|
|
configBlock(shadowView.cssNode);
|
2015-06-24 08:19:26 +00:00
|
|
|
return shadowView;
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|