Files
yoga/tests/CSSLayoutFlexTest.cpp
Emil Sjolander a253c6fbb7 Dont measure single flex grow+shrink child
Summary:
If there is a single child which is flex grow and flex shrink then instead of measuring and then shrinking we can just set the flex basis to zero as we know the final result will be that the child take up all remaining space.

This is a re-land of D4147298. I have updated the diff to check explicitly for exact measure mode to also handle at_most case correctly.

Reviewed By: gkassabli

Differential Revision: D4153133

fbshipit-source-id: 2333150a83857cc30078cc8d52761cbd00652830
2016-11-09 11:37:48 -08:00

439 lines
16 KiB
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.
*/
/**
* @Generated by gentest/gentest.sh with the following input
*
<div id="flex_basis_flex_grow_column" style="width: 100px; height: 100px;">
<div style="flex-basis: 50px; flex-grow: 1;"></div>
<div style="flex-grow: 1;"></div>
</div>
<div id="flex_basis_flex_grow_row" style="width: 100px; height: 100px; flex-direction: row;">
<div style="flex-basis: 50px; flex-grow: 1;"></div>
<div style="flex-grow: 1;"></div>
</div>
<div id="flex_basis_flex_shrink_column" style="width: 100px; height: 100px;">
<div style="flex-basis: 100px; flex-shrink: 1;"></div>
<div style="flex-basis: 50px;"></div>
</div>
<div id="flex_basis_flex_shrink_row" style="width: 100px; height: 100px; flex-direction: row;">
<div style="flex-basis: 100px; flex-shrink: 1;"></div>
<div style="flex-basis: 50px;"></div>
</div>
<div id="flex_shrink_to_zero" style="height: 75px;">
<div style="width: 50px; height: 50px; flex-shrink:0;"></div>
<div style="width: 50px; height: 50px; flex-shrink:1;"></div>
<div style="width: 50px; height: 50px; flex-shrink:0;"></div>
</div>
<div id="flex_basis_overrides_main_size" style="height: 100px; width: 100px;">
<div style="height: 20px; flex-grow:1; flex-basis:50px;"></div>
<div style="height: 10px; flex-grow:1;"></div>
<div style="height: 10px; flex-grow:1;"></div>
</div>
<div id="flex_grow_shrink_at_most" style="height: 100px; width: 100px;">
<div>
<div style="flex-grow:1; flex-shrink:1;"></div>
</div>
</div>
*
*/
#include <CSSLayout/CSSLayout.h>
#include <gtest/gtest.h>
TEST(CSSLayoutTest, flex_basis_flex_grow_column) {
const CSSNodeRef root = CSSNodeNew();
CSSNodeStyleSetWidth(root, 100);
CSSNodeStyleSetHeight(root, 100);
const CSSNodeRef root_child0 = CSSNodeNew();
CSSNodeStyleSetFlexGrow(root_child0, 1);
CSSNodeStyleSetFlexBasis(root_child0, 50);
CSSNodeInsertChild(root, root_child0, 0);
const CSSNodeRef root_child1 = CSSNodeNew();
CSSNodeStyleSetFlexGrow(root_child1, 1);
CSSNodeInsertChild(root, root_child1, 1);
CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR);
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root));
ASSERT_EQ(100, CSSNodeLayoutGetHeight(root));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child0));
ASSERT_EQ(75, CSSNodeLayoutGetHeight(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child1));
ASSERT_EQ(75, CSSNodeLayoutGetTop(root_child1));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child1));
ASSERT_EQ(25, CSSNodeLayoutGetHeight(root_child1));
CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionRTL);
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root));
ASSERT_EQ(100, CSSNodeLayoutGetHeight(root));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child0));
ASSERT_EQ(75, CSSNodeLayoutGetHeight(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child1));
ASSERT_EQ(75, CSSNodeLayoutGetTop(root_child1));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child1));
ASSERT_EQ(25, CSSNodeLayoutGetHeight(root_child1));
CSSNodeFreeRecursive(root);
}
TEST(CSSLayoutTest, flex_basis_flex_grow_row) {
const CSSNodeRef root = CSSNodeNew();
CSSNodeStyleSetFlexDirection(root, CSSFlexDirectionRow);
CSSNodeStyleSetWidth(root, 100);
CSSNodeStyleSetHeight(root, 100);
const CSSNodeRef root_child0 = CSSNodeNew();
CSSNodeStyleSetFlexGrow(root_child0, 1);
CSSNodeStyleSetFlexBasis(root_child0, 50);
CSSNodeInsertChild(root, root_child0, 0);
const CSSNodeRef root_child1 = CSSNodeNew();
CSSNodeStyleSetFlexGrow(root_child1, 1);
CSSNodeInsertChild(root, root_child1, 1);
CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR);
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root));
ASSERT_EQ(100, CSSNodeLayoutGetHeight(root));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0));
ASSERT_EQ(75, CSSNodeLayoutGetWidth(root_child0));
ASSERT_EQ(100, CSSNodeLayoutGetHeight(root_child0));
ASSERT_EQ(75, CSSNodeLayoutGetLeft(root_child1));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child1));
ASSERT_EQ(25, CSSNodeLayoutGetWidth(root_child1));
ASSERT_EQ(100, CSSNodeLayoutGetHeight(root_child1));
CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionRTL);
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root));
ASSERT_EQ(100, CSSNodeLayoutGetHeight(root));
ASSERT_EQ(25, CSSNodeLayoutGetLeft(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0));
ASSERT_EQ(75, CSSNodeLayoutGetWidth(root_child0));
ASSERT_EQ(100, CSSNodeLayoutGetHeight(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child1));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child1));
ASSERT_EQ(25, CSSNodeLayoutGetWidth(root_child1));
ASSERT_EQ(100, CSSNodeLayoutGetHeight(root_child1));
CSSNodeFreeRecursive(root);
}
TEST(CSSLayoutTest, flex_basis_flex_shrink_column) {
const CSSNodeRef root = CSSNodeNew();
CSSNodeStyleSetWidth(root, 100);
CSSNodeStyleSetHeight(root, 100);
const CSSNodeRef root_child0 = CSSNodeNew();
CSSNodeStyleSetFlexShrink(root_child0, 1);
CSSNodeStyleSetFlexBasis(root_child0, 100);
CSSNodeInsertChild(root, root_child0, 0);
const CSSNodeRef root_child1 = CSSNodeNew();
CSSNodeStyleSetFlexBasis(root_child1, 50);
CSSNodeInsertChild(root, root_child1, 1);
CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR);
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root));
ASSERT_EQ(100, CSSNodeLayoutGetHeight(root));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child0));
ASSERT_EQ(50, CSSNodeLayoutGetHeight(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child1));
ASSERT_EQ(50, CSSNodeLayoutGetTop(root_child1));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child1));
ASSERT_EQ(50, CSSNodeLayoutGetHeight(root_child1));
CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionRTL);
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root));
ASSERT_EQ(100, CSSNodeLayoutGetHeight(root));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child0));
ASSERT_EQ(50, CSSNodeLayoutGetHeight(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child1));
ASSERT_EQ(50, CSSNodeLayoutGetTop(root_child1));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child1));
ASSERT_EQ(50, CSSNodeLayoutGetHeight(root_child1));
CSSNodeFreeRecursive(root);
}
TEST(CSSLayoutTest, flex_basis_flex_shrink_row) {
const CSSNodeRef root = CSSNodeNew();
CSSNodeStyleSetFlexDirection(root, CSSFlexDirectionRow);
CSSNodeStyleSetWidth(root, 100);
CSSNodeStyleSetHeight(root, 100);
const CSSNodeRef root_child0 = CSSNodeNew();
CSSNodeStyleSetFlexShrink(root_child0, 1);
CSSNodeStyleSetFlexBasis(root_child0, 100);
CSSNodeInsertChild(root, root_child0, 0);
const CSSNodeRef root_child1 = CSSNodeNew();
CSSNodeStyleSetFlexBasis(root_child1, 50);
CSSNodeInsertChild(root, root_child1, 1);
CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR);
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root));
ASSERT_EQ(100, CSSNodeLayoutGetHeight(root));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0));
ASSERT_EQ(50, CSSNodeLayoutGetWidth(root_child0));
ASSERT_EQ(100, CSSNodeLayoutGetHeight(root_child0));
ASSERT_EQ(50, CSSNodeLayoutGetLeft(root_child1));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child1));
ASSERT_EQ(50, CSSNodeLayoutGetWidth(root_child1));
ASSERT_EQ(100, CSSNodeLayoutGetHeight(root_child1));
CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionRTL);
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root));
ASSERT_EQ(100, CSSNodeLayoutGetHeight(root));
ASSERT_EQ(50, CSSNodeLayoutGetLeft(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0));
ASSERT_EQ(50, CSSNodeLayoutGetWidth(root_child0));
ASSERT_EQ(100, CSSNodeLayoutGetHeight(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child1));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child1));
ASSERT_EQ(50, CSSNodeLayoutGetWidth(root_child1));
ASSERT_EQ(100, CSSNodeLayoutGetHeight(root_child1));
CSSNodeFreeRecursive(root);
}
TEST(CSSLayoutTest, flex_shrink_to_zero) {
const CSSNodeRef root = CSSNodeNew();
CSSNodeStyleSetHeight(root, 75);
const CSSNodeRef root_child0 = CSSNodeNew();
CSSNodeStyleSetWidth(root_child0, 50);
CSSNodeStyleSetHeight(root_child0, 50);
CSSNodeInsertChild(root, root_child0, 0);
const CSSNodeRef root_child1 = CSSNodeNew();
CSSNodeStyleSetFlexShrink(root_child1, 1);
CSSNodeStyleSetWidth(root_child1, 50);
CSSNodeStyleSetHeight(root_child1, 50);
CSSNodeInsertChild(root, root_child1, 1);
const CSSNodeRef root_child2 = CSSNodeNew();
CSSNodeStyleSetWidth(root_child2, 50);
CSSNodeStyleSetHeight(root_child2, 50);
CSSNodeInsertChild(root, root_child2, 2);
CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR);
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root));
ASSERT_EQ(50, CSSNodeLayoutGetWidth(root));
ASSERT_EQ(75, CSSNodeLayoutGetHeight(root));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0));
ASSERT_EQ(50, CSSNodeLayoutGetWidth(root_child0));
ASSERT_EQ(50, CSSNodeLayoutGetHeight(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child1));
ASSERT_EQ(50, CSSNodeLayoutGetTop(root_child1));
ASSERT_EQ(50, CSSNodeLayoutGetWidth(root_child1));
ASSERT_EQ(0, CSSNodeLayoutGetHeight(root_child1));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child2));
ASSERT_EQ(50, CSSNodeLayoutGetTop(root_child2));
ASSERT_EQ(50, CSSNodeLayoutGetWidth(root_child2));
ASSERT_EQ(50, CSSNodeLayoutGetHeight(root_child2));
CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionRTL);
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root));
ASSERT_EQ(50, CSSNodeLayoutGetWidth(root));
ASSERT_EQ(75, CSSNodeLayoutGetHeight(root));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0));
ASSERT_EQ(50, CSSNodeLayoutGetWidth(root_child0));
ASSERT_EQ(50, CSSNodeLayoutGetHeight(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child1));
ASSERT_EQ(50, CSSNodeLayoutGetTop(root_child1));
ASSERT_EQ(50, CSSNodeLayoutGetWidth(root_child1));
ASSERT_EQ(0, CSSNodeLayoutGetHeight(root_child1));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child2));
ASSERT_EQ(50, CSSNodeLayoutGetTop(root_child2));
ASSERT_EQ(50, CSSNodeLayoutGetWidth(root_child2));
ASSERT_EQ(50, CSSNodeLayoutGetHeight(root_child2));
CSSNodeFreeRecursive(root);
}
TEST(CSSLayoutTest, flex_basis_overrides_main_size) {
const CSSNodeRef root = CSSNodeNew();
CSSNodeStyleSetWidth(root, 100);
CSSNodeStyleSetHeight(root, 100);
const CSSNodeRef root_child0 = CSSNodeNew();
CSSNodeStyleSetFlexGrow(root_child0, 1);
CSSNodeStyleSetFlexBasis(root_child0, 50);
CSSNodeStyleSetHeight(root_child0, 20);
CSSNodeInsertChild(root, root_child0, 0);
const CSSNodeRef root_child1 = CSSNodeNew();
CSSNodeStyleSetFlexGrow(root_child1, 1);
CSSNodeStyleSetHeight(root_child1, 10);
CSSNodeInsertChild(root, root_child1, 1);
const CSSNodeRef root_child2 = CSSNodeNew();
CSSNodeStyleSetFlexGrow(root_child2, 1);
CSSNodeStyleSetHeight(root_child2, 10);
CSSNodeInsertChild(root, root_child2, 2);
CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR);
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root));
ASSERT_EQ(100, CSSNodeLayoutGetHeight(root));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child0));
ASSERT_EQ(60, CSSNodeLayoutGetHeight(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child1));
ASSERT_EQ(60, CSSNodeLayoutGetTop(root_child1));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child1));
ASSERT_EQ(20, CSSNodeLayoutGetHeight(root_child1));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child2));
ASSERT_EQ(80, CSSNodeLayoutGetTop(root_child2));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child2));
ASSERT_EQ(20, CSSNodeLayoutGetHeight(root_child2));
CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionRTL);
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root));
ASSERT_EQ(100, CSSNodeLayoutGetHeight(root));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child0));
ASSERT_EQ(60, CSSNodeLayoutGetHeight(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child1));
ASSERT_EQ(60, CSSNodeLayoutGetTop(root_child1));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child1));
ASSERT_EQ(20, CSSNodeLayoutGetHeight(root_child1));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child2));
ASSERT_EQ(80, CSSNodeLayoutGetTop(root_child2));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child2));
ASSERT_EQ(20, CSSNodeLayoutGetHeight(root_child2));
CSSNodeFreeRecursive(root);
}
TEST(CSSLayoutTest, flex_grow_shrink_at_most) {
const CSSNodeRef root = CSSNodeNew();
CSSNodeStyleSetWidth(root, 100);
CSSNodeStyleSetHeight(root, 100);
const CSSNodeRef root_child0 = CSSNodeNew();
CSSNodeInsertChild(root, root_child0, 0);
const CSSNodeRef root_child0_child0 = CSSNodeNew();
CSSNodeStyleSetFlexGrow(root_child0_child0, 1);
CSSNodeStyleSetFlexShrink(root_child0_child0, 1);
CSSNodeInsertChild(root_child0, root_child0_child0, 0);
CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR);
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root));
ASSERT_EQ(100, CSSNodeLayoutGetHeight(root));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetHeight(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0_child0));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0_child0));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child0_child0));
ASSERT_EQ(0, CSSNodeLayoutGetHeight(root_child0_child0));
CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionRTL);
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root));
ASSERT_EQ(100, CSSNodeLayoutGetHeight(root));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetHeight(root_child0));
ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0_child0));
ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0_child0));
ASSERT_EQ(100, CSSNodeLayoutGetWidth(root_child0_child0));
ASSERT_EQ(0, CSSNodeLayoutGetHeight(root_child0_child0));
CSSNodeFreeRecursive(root);
}