Files
yoga/YogaKit/Tests/YogaKitTests.m
Ben Holcomb e2a7938b26 Revert D4386906: [YogaKit] Improved the objective-c and swift api
Summary: This reverts commit 05ac0e571ef3a8ff0be31469e449a7b23f102218

Differential Revision: D4386906

fbshipit-source-id: adac0d8e71ce9f3442f3bfd14b5157f88367c998
2017-01-07 10:24:37 -08:00

388 lines
13 KiB
Objective-C

/**
* Copyright (c) 2014-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 <XCTest/XCTest.h>
#import <YogaKit/UIView+Yoga.h>
@interface YogaKitTests : XCTestCase
@end
@implementation YogaKitTests
#ifndef TRAVIS_CI
- (void)testNodesAreDeallocedWithSingleView
{
XCTAssertEqual(0, YGNodeGetInstanceCount());
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
[view yg_setFlexBasis:1];
XCTAssertEqual(1, YGNodeGetInstanceCount());
view = nil;
XCTAssertEqual(0, YGNodeGetInstanceCount());
}
- (void)testNodesAreDeallocedCascade
{
XCTAssertEqual(0, YGNodeGetInstanceCount());
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
[view yg_setFlexBasis:1];
for (int i=0; i<10; i++) {
UIView *subview = [[UIView alloc] initWithFrame:CGRectZero];
[subview yg_setFlexBasis:1];
[view addSubview:subview];
}
XCTAssertEqual(11, YGNodeGetInstanceCount());
view = nil;
XCTAssertEqual(0, YGNodeGetInstanceCount());
}
#endif
- (void)testUsesYoga
{
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
XCTAssertFalse([view yg_usesYoga]);
[view yg_setUsesYoga:YES];
XCTAssertTrue([view yg_usesYoga]);
[view yg_setUsesYoga:NO];
XCTAssertFalse([view yg_usesYoga]);
}
- (void)testSizeThatFitsAsserts
{
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
dispatch_sync(dispatch_queue_create("com.facebook.Yoga.testing", DISPATCH_QUEUE_SERIAL), ^(void){
XCTAssertThrows([view yg_intrinsicSize]);
});
}
- (void)testSizeThatFitsSmoke
{
UIView *container = [[UIView alloc] initWithFrame:CGRectZero];
[container yg_setUsesYoga:YES];
[container yg_setFlexDirection:YGFlexDirectionRow];
[container yg_setAlignItems:YGAlignFlexStart];
UILabel *longTextLabel = [[UILabel alloc] initWithFrame:CGRectZero];
longTextLabel.text = @"This is a very very very very very very very very long piece of text.";
longTextLabel.lineBreakMode = NSLineBreakByTruncatingTail;
longTextLabel.numberOfLines = 1;
[longTextLabel yg_setUsesYoga:YES];
[longTextLabel yg_setFlexShrink:1];
[container addSubview:longTextLabel];
UIView *textBadgeView = [[UIView alloc] initWithFrame:CGRectZero];
[textBadgeView yg_setUsesYoga:YES];
[textBadgeView yg_setMargin:3.0 forEdge:YGEdgeLeft];
[textBadgeView yg_setWidth:10];
[textBadgeView yg_setHeight:10];
[container addSubview:textBadgeView];
const CGSize containerSize = [container yg_intrinsicSize];
XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(514,21), containerSize), @"Size is actually %@", NSStringFromCGSize(containerSize));
}
- (void)testThatMarkingLeafsAsDirtyWillTriggerASizeRecalculation
{
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 50)];
[container yg_setUsesYoga:YES];
[container yg_setFlexDirection:YGFlexDirectionRow];
[container yg_setAlignItems:YGAlignFlexStart];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
label.text = @"This is a short text.";
label.numberOfLines = 1;
[label yg_setUsesYoga:YES];
[container addSubview:label];
[container yg_applyLayout];
XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(146,21), label.bounds.size), @"Size is actually %@", NSStringFromCGSize(label.bounds.size));
label.text = @"This is a slightly longer text.";
[label yg_markDirty];
[container yg_applyLayout];
XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(213,21), label.bounds.size), @"Size is actually %@", NSStringFromCGSize(label.bounds.size));
}
- (void)testFrameAndOriginPlacement
{
const CGSize containerSize = CGSizeMake(320, 50);
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, containerSize.width, containerSize.height)];
[container yg_setUsesYoga:YES];
[container yg_setFlexDirection:YGFlexDirectionRow];
for (int i = 0; i < 3; i++) {
UIView *subview = [[UIView alloc] initWithFrame:CGRectZero];
[subview yg_setUsesYoga:YES];
[subview yg_setFlexGrow:1];
[container addSubview:subview];
}
[container yg_applyLayout];
XCTAssertFalse(CGRectIntersectsRect([container.subviews objectAtIndex:0].frame, [container.subviews objectAtIndex:1].frame));
XCTAssertFalse(CGRectIntersectsRect([container.subviews objectAtIndex:1].frame, [container.subviews objectAtIndex:2].frame));
XCTAssertFalse(CGRectIntersectsRect([container.subviews objectAtIndex:0].frame, [container.subviews objectAtIndex:2].frame));
CGFloat totalWidth = 0;
for (UIView *view in container.subviews) {
totalWidth += view.bounds.size.width;
}
XCTAssertEqual(containerSize.width, totalWidth, @"The container's width is %.6f, the subviews take up %.6f", containerSize.width, totalWidth);
}
- (void)testThatLayoutIsCorrectWhenWeSwapViewOrder
{
const CGSize containerSize = CGSizeMake(300, 50);
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, containerSize.width, containerSize.height)];
[container yg_setUsesYoga:YES];
[container yg_setFlexDirection:YGFlexDirectionRow];
UIView *subview1 = [[UIView alloc] initWithFrame:CGRectZero];
[subview1 yg_setUsesYoga:YES];
[subview1 yg_setFlexGrow:1];
[container addSubview:subview1];
UIView *subview2 = [[UIView alloc] initWithFrame:CGRectZero];
[subview2 yg_setUsesYoga:YES];
[subview2 yg_setFlexGrow:1];
[container addSubview:subview2];
UIView *subview3 = [[UIView alloc] initWithFrame:CGRectZero];
[subview3 yg_setUsesYoga:YES];
[subview3 yg_setFlexGrow:1];
[container addSubview:subview3];
[container yg_applyLayout];
XCTAssertTrue(CGRectEqualToRect(subview1.frame, CGRectMake(0, 0, 100, 50)));
XCTAssertTrue(CGRectEqualToRect(subview2.frame, CGRectMake(100, 0, 100, 50)), @"It's actually %@", NSStringFromCGRect(subview2.frame));
XCTAssertTrue(CGRectEqualToRect(subview3.frame, CGRectMake(200, 0, 100, 50)));
[container exchangeSubviewAtIndex:2 withSubviewAtIndex:0];
[subview2 yg_setIncludeInLayout:NO];
[container yg_applyLayout];
XCTAssertTrue(CGRectEqualToRect(subview3.frame, CGRectMake(0, 0, 150, 50)));
XCTAssertTrue(CGRectEqualToRect(subview1.frame, CGRectMake(150, 0, 150, 50)));
// this frame shouldn't have been modified since last time.
XCTAssertTrue(CGRectEqualToRect(subview2.frame, CGRectMake(100, 0, 100, 50)));
}
- (void)testThatWeRespectIncludeInLayoutFlag
{
const CGSize containerSize = CGSizeMake(300, 50);
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, containerSize.width, containerSize.height)];
[container yg_setUsesYoga:YES];
[container yg_setFlexDirection:YGFlexDirectionRow];
UIView *subview1 = [[UIView alloc] initWithFrame:CGRectZero];
[subview1 yg_setUsesYoga:YES];
[subview1 yg_setFlexGrow:1];
[container addSubview:subview1];
UIView *subview2 = [[UIView alloc] initWithFrame:CGRectZero];
[subview2 yg_setUsesYoga:YES];
[subview2 yg_setFlexGrow:1];
[container addSubview:subview2];
UIView *subview3 = [[UIView alloc] initWithFrame:CGRectZero];
[subview3 yg_setUsesYoga:YES];
[subview3 yg_setFlexGrow:1];
[container addSubview:subview3];
[container yg_applyLayout];
for (UIView *view in container.subviews) {
XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(100, 50), subview1.bounds.size), @"Actual size is %@", NSStringFromCGSize(view.bounds.size));
}
[subview3 yg_setIncludeInLayout:NO];
[container yg_applyLayout];
XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(150, 50), subview1.bounds.size), @"Actual size is %@", NSStringFromCGSize(subview1.bounds.size));
XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(150, 50), subview2.bounds.size), @"Actual size is %@", NSStringFromCGSize(subview2.bounds.size));
// We don't set the frame to zero, so, it should be set to what it was previously at.
XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(100, 50), subview3.bounds.size), @"Actual size is %@", NSStringFromCGSize(subview3.bounds.size));
}
- (void)testThatNumberOfChildrenIsCorrectWhenWeIgnoreSubviews
{
UIView *container = [[UIView alloc] initWithFrame:CGRectZero];
[container yg_setUsesYoga:YES];
[container yg_setFlexDirection:YGFlexDirectionRow];
UIView *subview1 = [[UIView alloc] initWithFrame:CGRectZero];
[subview1 yg_setUsesYoga:YES];
[subview1 yg_setIncludeInLayout:NO];
[container addSubview:subview1];
UIView *subview2 = [[UIView alloc] initWithFrame:CGRectZero];
[subview2 yg_setUsesYoga:YES];
[subview2 yg_setIncludeInLayout:NO];
[container addSubview:subview2];
UIView *subview3 = [[UIView alloc] initWithFrame:CGRectZero];
[subview3 yg_setUsesYoga:YES];
[subview3 yg_setIncludeInLayout:YES];
[container addSubview:subview3];
[container yg_applyLayout];
XCTAssertEqual(1, [container yg_numberOfChildren]);
[subview2 yg_setIncludeInLayout:YES];
[container yg_applyLayout];
XCTAssertEqual(2, [container yg_numberOfChildren]);
}
- (void)testThatViewNotIncludedInFirstLayoutPassAreIncludedInSecond
{
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 50)];
[container yg_setUsesYoga:YES];
[container yg_setFlexDirection:YGFlexDirectionRow];
UIView *subview1 = [[UIView alloc] initWithFrame:CGRectZero];
[subview1 yg_setUsesYoga:YES];
[subview1 yg_setFlexGrow:1];
[container addSubview:subview1];
UIView *subview2 = [[UIView alloc] initWithFrame:CGRectZero];
[subview2 yg_setUsesYoga:YES];
[subview2 yg_setFlexGrow:1];
[container addSubview:subview2];
UIView *subview3 = [[UIView alloc] initWithFrame:CGRectZero];
[subview3 yg_setUsesYoga:YES];
[subview3 yg_setFlexGrow:1];
[subview3 yg_setIncludeInLayout:NO];
[container addSubview:subview3];
[container yg_applyLayout];
XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(150, 50), subview1.bounds.size), @"Actual size is %@", NSStringFromCGSize(subview1.bounds.size));
XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(150, 50), subview2.bounds.size), @"Actual size is %@", NSStringFromCGSize(subview2.bounds.size));
XCTAssertTrue(CGSizeEqualToSize(CGSizeZero, subview3.bounds.size), @"Actual size %@", NSStringFromCGSize(subview3.bounds.size));
[subview3 yg_setIncludeInLayout:YES];
[container yg_applyLayout];
for (UIView *view in container.subviews) {
XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(100, 50), subview1.bounds.size), @"Actual size is %@", NSStringFromCGSize(view.bounds.size));
}
}
- (void)testyg_isLeafFlag
{
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
XCTAssertTrue(view.yg_isLeaf);
for (int i=0; i<10; i++) {
UIView *subview = [[UIView alloc] initWithFrame:CGRectZero];
[view addSubview:subview];
}
XCTAssertTrue(view.yg_isLeaf);
[view yg_setUsesYoga:YES];
[view yg_setWidth:50.0];
XCTAssertTrue(view.yg_isLeaf);
UIView *const subview = view.subviews[0];
[subview yg_setUsesYoga:YES];
[subview yg_setWidth:50.0];
XCTAssertFalse(view.yg_isLeaf);
}
- (void)testThatWeCorrectlyAttachNestedViews
{
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 50)];
[container yg_setUsesYoga:YES];
[container yg_setFlexDirection:YGFlexDirectionColumn];
UIView *subview1 = [[UIView alloc] initWithFrame:CGRectZero];
[subview1 yg_setUsesYoga:YES];
[subview1 yg_setWidth:100];
[subview1 yg_setFlexGrow:1];
[subview1 yg_setFlexDirection:YGFlexDirectionColumn];
[container addSubview:subview1];
UIView *subview2 = [[UIView alloc] initWithFrame:CGRectZero];
[subview2 yg_setUsesYoga:YES];
[subview2 yg_setWidth:150];
[subview2 yg_setFlexGrow:1];
[subview2 yg_setFlexDirection:YGFlexDirectionColumn];
[container addSubview:subview2];
for (UIView *view in @[subview1, subview2]) {
UIView *someView = [[UIView alloc] initWithFrame:CGRectZero];
[someView yg_setUsesYoga:YES];
[someView yg_setFlexGrow:1];
[view addSubview:someView];
}
[container yg_applyLayout];
// Add the same amount of new views, reapply layout.
for (UIView *view in @[subview1, subview2]) {
UIView *someView = [[UIView alloc] initWithFrame:CGRectZero];
[someView yg_setUsesYoga:YES];
[someView yg_setFlexGrow:1];
[view addSubview:someView];
}
[container yg_applyLayout];
XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(100, 25), subview1.bounds.size), @"Actual size is %@", NSStringFromCGSize(subview1.bounds.size));
for (UIView *subview in subview1.subviews) {
const CGSize subviewSize = subview.bounds.size;
XCTAssertFalse(CGSizeEqualToSize(CGSizeZero, subviewSize));
XCTAssertFalse(isnan(subviewSize.height));
XCTAssertFalse(isnan(subviewSize.width));
}
XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(150, 25), subview2.bounds.size), @"Actual size is %@", NSStringFromCGSize(subview2.bounds.size));
for (UIView *subview in subview2.subviews) {
const CGSize subviewSize = subview.bounds.size;
XCTAssertFalse(CGSizeEqualToSize(CGSizeZero, subview.bounds.size));
XCTAssertFalse(isnan(subviewSize.height));
XCTAssertFalse(isnan(subviewSize.width));
}
}
- (void)testThatANonLeafNodeCanBecomeALeafNode
{
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 50)];
[container yg_setUsesYoga:YES];
UIView *subview1 = [[UIView alloc] initWithFrame:CGRectZero];
[subview1 yg_setUsesYoga:YES];
[container addSubview:subview1];
UIView *subview2 = [[UIView alloc] initWithFrame:CGRectZero];
[subview2 yg_setUsesYoga:YES];
[subview1 addSubview:subview2];
[container yg_applyLayout];
[subview2 removeFromSuperview];
[container yg_applyLayout];
}
@end