Yoga test failure for flexing with min stack dimension

Summary: Test fails when we have flexible child and min/max layout dimension. Yoga should flex the child to minimal size, while in reality Yoga flexes it to maximal size

Reviewed By: emilsjolander

Differential Revision: D4558653

fbshipit-source-id: 06b38d7ed43aee063cc881f38b84558641f043f3
This commit is contained in:
Georgiy Kassabli
2017-02-28 16:27:18 -08:00
committed by Facebook Github Bot
parent 4372aa16d3
commit 3ef2970032
11 changed files with 485 additions and 7 deletions

View File

@@ -13,5 +13,6 @@ namespace Facebook.Yoga
{ {
Rounding, Rounding,
WebFlexBasis, WebFlexBasis,
MinFlexFix,
} }
} }

View File

@@ -348,6 +348,121 @@ namespace Facebook.Yoga
Assert.AreEqual(50f, root_child2.LayoutHeight); Assert.AreEqual(50f, root_child2.LayoutHeight);
} }
[Test]
public void Test_flex_grow_to_min()
{
YogaNode.SetExperimentalFeatureEnabled(YogaExperimentalFeature.MinFlexFix, true);
YogaNode root = new YogaNode();
root.Width = 100;
root.MinHeight = 100;
root.MaxHeight = 500;
YogaNode root_child0 = new YogaNode();
root_child0.FlexGrow = 1;
root_child0.FlexShrink = 1;
root.Insert(0, root_child0);
YogaNode root_child1 = new YogaNode();
root_child1.Height = 50;
root.Insert(1, root_child1);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(100f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child1.LayoutX);
Assert.AreEqual(50f, root_child1.LayoutY);
Assert.AreEqual(100f, root_child1.LayoutWidth);
Assert.AreEqual(50f, root_child1.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(100f, root_child0.LayoutWidth);
Assert.AreEqual(50f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child1.LayoutX);
Assert.AreEqual(50f, root_child1.LayoutY);
Assert.AreEqual(100f, root_child1.LayoutWidth);
Assert.AreEqual(50f, root_child1.LayoutHeight);
YogaNode.SetExperimentalFeatureEnabled(YogaExperimentalFeature.MinFlexFix, false);
}
[Test]
public void Test_flex_grow_in_at_most_container()
{
YogaNode.SetExperimentalFeatureEnabled(YogaExperimentalFeature.MinFlexFix, true);
YogaNode root = new YogaNode();
root.FlexDirection = YogaFlexDirection.Row;
root.AlignItems = YogaAlign.FlexStart;
root.Width = 100;
root.Height = 100;
YogaNode root_child0 = new YogaNode();
root_child0.FlexDirection = YogaFlexDirection.Row;
root.Insert(0, root_child0);
YogaNode root_child0_child0 = new YogaNode();
root_child0_child0.FlexGrow = 1;
root_child0_child0.FlexBasis = 0;
root_child0.Insert(0, root_child0_child0);
root.StyleDirection = YogaDirection.LTR;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
Assert.AreEqual(0f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(0f, root_child0.LayoutWidth);
Assert.AreEqual(0f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0.LayoutY);
Assert.AreEqual(0f, root_child0_child0.LayoutWidth);
Assert.AreEqual(0f, root_child0_child0.LayoutHeight);
root.StyleDirection = YogaDirection.RTL;
root.CalculateLayout();
Assert.AreEqual(0f, root.LayoutX);
Assert.AreEqual(0f, root.LayoutY);
Assert.AreEqual(100f, root.LayoutWidth);
Assert.AreEqual(100f, root.LayoutHeight);
Assert.AreEqual(100f, root_child0.LayoutX);
Assert.AreEqual(0f, root_child0.LayoutY);
Assert.AreEqual(0f, root_child0.LayoutWidth);
Assert.AreEqual(0f, root_child0.LayoutHeight);
Assert.AreEqual(0f, root_child0_child0.LayoutX);
Assert.AreEqual(0f, root_child0_child0.LayoutY);
Assert.AreEqual(0f, root_child0_child0.LayoutWidth);
Assert.AreEqual(0f, root_child0_child0.LayoutHeight);
YogaNode.SetExperimentalFeatureEnabled(YogaExperimentalFeature.MinFlexFix, false);
}
[Test] [Test]
public void Test_flex_grow_within_max_width() public void Test_flex_grow_within_max_width()
{ {

View File

@@ -95,6 +95,7 @@ ENUMS = {
'Rounding', 'Rounding',
# Mimic web flex-basis behavior. # Mimic web flex-basis behavior.
'WebFlexBasis', 'WebFlexBasis',
'MinFlexFix'
], ],
'PrintOptions': [ 'PrintOptions': [
('Layout', 1), ('Layout', 1),

View File

@@ -30,6 +30,17 @@
<div style="width: 50px; height: 50px;"></div> <div style="width: 50px; height: 50px;"></div>
</div> </div>
<div id="flex_grow_to_min" experiments="MinFlexFix" style="min-height: 100px; max-height: 500px; width: 100px;">
<div style="flex-grow: 1; flex-shrink: 1;"></div>
<div style="height: 50px;"></div>
</div>
<div id="flex_grow_in_at_most_container" experiments="MinFlexFix" style="width: 100px; height: 100px; background-color: white; flex-direction: row; align-items: flex-start;">
<div style="flex-direction: row;">
<div style="flex-grow: 1; flex-basis: 0px;"></div>
</div>
</div>
<div id="flex_grow_within_max_width" style="width: 200px; height: 100px;"> <div id="flex_grow_within_max_width" style="width: 200px; height: 100px;">
<div style="flex-direction: row; max-width: 100px;"> <div style="flex-direction: row; max-width: 100px;">
<div style="height: 20px; flex-grow: 1;"></div> <div style="height: 20px; flex-grow: 1;"></div>

View File

@@ -14,7 +14,8 @@ import com.facebook.proguard.annotations.DoNotStrip;
@DoNotStrip @DoNotStrip
public enum YogaExperimentalFeature { public enum YogaExperimentalFeature {
ROUNDING(0), ROUNDING(0),
WEB_FLEX_BASIS(1); WEB_FLEX_BASIS(1),
MIN_FLEX_FIX(2);
private int mIntValue; private int mIntValue;
@@ -30,6 +31,7 @@ public enum YogaExperimentalFeature {
switch (value) { switch (value) {
case 0: return ROUNDING; case 0: return ROUNDING;
case 1: return WEB_FLEX_BASIS; case 1: return WEB_FLEX_BASIS;
case 2: return MIN_FLEX_FIX;
default: throw new IllegalArgumentException("Unknown enum value: " + value); default: throw new IllegalArgumentException("Unknown enum value: " + value);
} }
} }

View File

@@ -340,6 +340,119 @@ public class YGMinMaxDimensionTest {
assertEquals(50f, root_child2.getLayoutHeight(), 0.0f); assertEquals(50f, root_child2.getLayoutHeight(), 0.0f);
} }
@Test
public void test_flex_grow_to_min() {
YogaNode.setExperimentalFeatureEnabled(YogaExperimentalFeature.MIN_FLEX_FIX, true);
final YogaNode root = new YogaNode();
root.setWidth(100f);
root.setMinHeight(100f);
root.setMaxHeight(500f);
final YogaNode root_child0 = new YogaNode();
root_child0.setFlexGrow(1f);
root_child0.setFlexShrink(1f);
root.addChildAt(root_child0, 0);
final YogaNode root_child1 = new YogaNode();
root_child1.setHeight(50f);
root.addChildAt(root_child1, 1);
root.setDirection(YogaDirection.LTR);
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(100f, root.getLayoutWidth(), 0.0f);
assertEquals(100f, root.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0.getLayoutY(), 0.0f);
assertEquals(100f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(50f, root_child0.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child1.getLayoutX(), 0.0f);
assertEquals(50f, root_child1.getLayoutY(), 0.0f);
assertEquals(100f, root_child1.getLayoutWidth(), 0.0f);
assertEquals(50f, root_child1.getLayoutHeight(), 0.0f);
root.setDirection(YogaDirection.RTL);
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(100f, root.getLayoutWidth(), 0.0f);
assertEquals(100f, root.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0.getLayoutY(), 0.0f);
assertEquals(100f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(50f, root_child0.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child1.getLayoutX(), 0.0f);
assertEquals(50f, root_child1.getLayoutY(), 0.0f);
assertEquals(100f, root_child1.getLayoutWidth(), 0.0f);
assertEquals(50f, root_child1.getLayoutHeight(), 0.0f);
YogaNode.setExperimentalFeatureEnabled(YogaExperimentalFeature.MIN_FLEX_FIX, false);
}
@Test
public void test_flex_grow_in_at_most_container() {
YogaNode.setExperimentalFeatureEnabled(YogaExperimentalFeature.MIN_FLEX_FIX, true);
final YogaNode root = new YogaNode();
root.setFlexDirection(YogaFlexDirection.ROW);
root.setAlignItems(YogaAlign.FLEX_START);
root.setWidth(100f);
root.setHeight(100f);
final YogaNode root_child0 = new YogaNode();
root_child0.setFlexDirection(YogaFlexDirection.ROW);
root.addChildAt(root_child0, 0);
final YogaNode root_child0_child0 = new YogaNode();
root_child0_child0.setFlexGrow(1f);
root_child0_child0.setFlexBasis(0f);
root_child0.addChildAt(root_child0_child0, 0);
root.setDirection(YogaDirection.LTR);
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(100f, root.getLayoutWidth(), 0.0f);
assertEquals(100f, root.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0.getLayoutY(), 0.0f);
assertEquals(0f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(0f, root_child0.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutWidth(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutHeight(), 0.0f);
root.setDirection(YogaDirection.RTL);
root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED);
assertEquals(0f, root.getLayoutX(), 0.0f);
assertEquals(0f, root.getLayoutY(), 0.0f);
assertEquals(100f, root.getLayoutWidth(), 0.0f);
assertEquals(100f, root.getLayoutHeight(), 0.0f);
assertEquals(100f, root_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0.getLayoutY(), 0.0f);
assertEquals(0f, root_child0.getLayoutWidth(), 0.0f);
assertEquals(0f, root_child0.getLayoutHeight(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutX(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutWidth(), 0.0f);
assertEquals(0f, root_child0_child0.getLayoutHeight(), 0.0f);
YogaNode.setExperimentalFeatureEnabled(YogaExperimentalFeature.MIN_FLEX_FIX, false);
}
@Test @Test
public void test_flex_grow_within_max_width() { public void test_flex_grow_within_max_width() {
final YogaNode root = new YogaNode(); final YogaNode root = new YogaNode();

View File

@@ -43,9 +43,10 @@ module.exports = {
EDGE_VERTICAL: 7, EDGE_VERTICAL: 7,
EDGE_ALL: 8, EDGE_ALL: 8,
EXPERIMENTAL_FEATURE_COUNT: 2, EXPERIMENTAL_FEATURE_COUNT: 3,
EXPERIMENTAL_FEATURE_ROUNDING: 0, EXPERIMENTAL_FEATURE_ROUNDING: 0,
EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS: 1, EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS: 1,
EXPERIMENTAL_FEATURE_MIN_FLEX_FIX: 2,
FLEX_DIRECTION_COUNT: 4, FLEX_DIRECTION_COUNT: 4,
FLEX_DIRECTION_COLUMN: 0, FLEX_DIRECTION_COLUMN: 0,

View File

@@ -349,6 +349,123 @@ it("justify_content_overflow_min_max", function () {
} }
} }
}); });
it("flex_grow_to_min", function () {
Yoga.setExperimentalFeatureEnabled(Yoga.EXPERIMENTAL_FEATURE_MIN_FLEX_FIX, true);
try {
var root = Yoga.Node.create();
root.setWidth(100);
root.setMinHeight(100);
root.setMaxHeight(500);
var root_child0 = Yoga.Node.create();
root_child0.setFlexGrow(1);
root_child0.setFlexShrink(1);
root.insertChild(root_child0, 0);
var root_child1 = Yoga.Node.create();
root_child1.setHeight(50);
root.insertChild(root_child1, 1);
root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR);
console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")");
console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")");
console.assert(100 === root.getComputedWidth(), "100 === root.getComputedWidth() (" + root.getComputedWidth() + ")");
console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")");
console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")");
console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")");
console.assert(100 === root_child0.getComputedWidth(), "100 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")");
console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")");
console.assert(0 === root_child1.getComputedLeft(), "0 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")");
console.assert(50 === root_child1.getComputedTop(), "50 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")");
console.assert(100 === root_child1.getComputedWidth(), "100 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")");
console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")");
root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL);
console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")");
console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")");
console.assert(100 === root.getComputedWidth(), "100 === root.getComputedWidth() (" + root.getComputedWidth() + ")");
console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")");
console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")");
console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")");
console.assert(100 === root_child0.getComputedWidth(), "100 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")");
console.assert(50 === root_child0.getComputedHeight(), "50 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")");
console.assert(0 === root_child1.getComputedLeft(), "0 === root_child1.getComputedLeft() (" + root_child1.getComputedLeft() + ")");
console.assert(50 === root_child1.getComputedTop(), "50 === root_child1.getComputedTop() (" + root_child1.getComputedTop() + ")");
console.assert(100 === root_child1.getComputedWidth(), "100 === root_child1.getComputedWidth() (" + root_child1.getComputedWidth() + ")");
console.assert(50 === root_child1.getComputedHeight(), "50 === root_child1.getComputedHeight() (" + root_child1.getComputedHeight() + ")");
} finally {
if (typeof root !== "undefined") {
root.freeRecursive();
}
Yoga.setExperimentalFeatureEnabled(Yoga.EXPERIMENTAL_FEATURE_MIN_FLEX_FIX, false);
}
});
it("flex_grow_in_at_most_container", function () {
Yoga.setExperimentalFeatureEnabled(Yoga.EXPERIMENTAL_FEATURE_MIN_FLEX_FIX, true);
try {
var root = Yoga.Node.create();
root.setFlexDirection(Yoga.FLEX_DIRECTION_ROW);
root.setAlignItems(Yoga.ALIGN_FLEX_START);
root.setWidth(100);
root.setHeight(100);
var root_child0 = Yoga.Node.create();
root_child0.setFlexDirection(Yoga.FLEX_DIRECTION_ROW);
root.insertChild(root_child0, 0);
var root_child0_child0 = Yoga.Node.create();
root_child0_child0.setFlexGrow(1);
root_child0_child0.setFlexBasis(0);
root_child0.insertChild(root_child0_child0, 0);
root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR);
console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")");
console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")");
console.assert(100 === root.getComputedWidth(), "100 === root.getComputedWidth() (" + root.getComputedWidth() + ")");
console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")");
console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")");
console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")");
console.assert(0 === root_child0.getComputedWidth(), "0 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")");
console.assert(0 === root_child0.getComputedHeight(), "0 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")");
console.assert(0 === root_child0_child0.getComputedLeft(), "0 === root_child0_child0.getComputedLeft() (" + root_child0_child0.getComputedLeft() + ")");
console.assert(0 === root_child0_child0.getComputedTop(), "0 === root_child0_child0.getComputedTop() (" + root_child0_child0.getComputedTop() + ")");
console.assert(0 === root_child0_child0.getComputedWidth(), "0 === root_child0_child0.getComputedWidth() (" + root_child0_child0.getComputedWidth() + ")");
console.assert(0 === root_child0_child0.getComputedHeight(), "0 === root_child0_child0.getComputedHeight() (" + root_child0_child0.getComputedHeight() + ")");
root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL);
console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")");
console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")");
console.assert(100 === root.getComputedWidth(), "100 === root.getComputedWidth() (" + root.getComputedWidth() + ")");
console.assert(100 === root.getComputedHeight(), "100 === root.getComputedHeight() (" + root.getComputedHeight() + ")");
console.assert(100 === root_child0.getComputedLeft(), "100 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")");
console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")");
console.assert(0 === root_child0.getComputedWidth(), "0 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")");
console.assert(0 === root_child0.getComputedHeight(), "0 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")");
console.assert(0 === root_child0_child0.getComputedLeft(), "0 === root_child0_child0.getComputedLeft() (" + root_child0_child0.getComputedLeft() + ")");
console.assert(0 === root_child0_child0.getComputedTop(), "0 === root_child0_child0.getComputedTop() (" + root_child0_child0.getComputedTop() + ")");
console.assert(0 === root_child0_child0.getComputedWidth(), "0 === root_child0_child0.getComputedWidth() (" + root_child0_child0.getComputedWidth() + ")");
console.assert(0 === root_child0_child0.getComputedHeight(), "0 === root_child0_child0.getComputedHeight() (" + root_child0_child0.getComputedHeight() + ")");
} finally {
if (typeof root !== "undefined") {
root.freeRecursive();
}
Yoga.setExperimentalFeatureEnabled(Yoga.EXPERIMENTAL_FEATURE_MIN_FLEX_FIX, false);
}
});
it("flex_grow_within_max_width", function () { it("flex_grow_within_max_width", function () {
try { try {
var root = Yoga.Node.create(); var root = Yoga.Node.create();

View File

@@ -329,6 +329,117 @@ TEST(YogaTest, justify_content_overflow_min_max) {
YGNodeFreeRecursive(root); YGNodeFreeRecursive(root);
} }
TEST(YogaTest, flex_grow_to_min) {
YGSetExperimentalFeatureEnabled(YGExperimentalFeatureMinFlexFix, true);
const YGNodeRef root = YGNodeNew();
YGNodeStyleSetWidth(root, 100);
YGNodeStyleSetMinHeight(root, 100);
YGNodeStyleSetMaxHeight(root, 500);
const YGNodeRef root_child0 = YGNodeNew();
YGNodeStyleSetFlexGrow(root_child0, 1);
YGNodeStyleSetFlexShrink(root_child0, 1);
YGNodeInsertChild(root, root_child0, 0);
const YGNodeRef root_child1 = YGNodeNew();
YGNodeStyleSetHeight(root_child1, 50);
YGNodeInsertChild(root, root_child1, 1);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1));
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1));
ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1));
YGNodeFreeRecursive(root);
YGSetExperimentalFeatureEnabled(YGExperimentalFeatureMinFlexFix, false);
}
TEST(YogaTest, flex_grow_in_at_most_container) {
YGSetExperimentalFeatureEnabled(YGExperimentalFeatureMinFlexFix, true);
const YGNodeRef root = YGNodeNew();
YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
YGNodeStyleSetAlignItems(root, YGAlignFlexStart);
YGNodeStyleSetWidth(root, 100);
YGNodeStyleSetHeight(root, 100);
const YGNodeRef root_child0 = YGNodeNew();
YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow);
YGNodeInsertChild(root, root_child0, 0);
const YGNodeRef root_child0_child0 = YGNodeNew();
YGNodeStyleSetFlexGrow(root_child0_child0, 1);
YGNodeStyleSetFlexBasis(root_child0_child0, 0);
YGNodeInsertChild(root_child0, root_child0_child0, 0);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child0));
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root));
ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0_child0));
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0_child0));
YGNodeFreeRecursive(root);
YGSetExperimentalFeatureEnabled(YGExperimentalFeatureMinFlexFix, false);
}
TEST(YogaTest, flex_grow_within_max_width) { TEST(YogaTest, flex_grow_within_max_width) {
const YGNodeRef root = YGNodeNew(); const YGNodeRef root = YGNodeNew();
YGNodeStyleSetWidth(root, 200); YGNodeStyleSetWidth(root, 200);

View File

@@ -57,10 +57,11 @@ typedef YG_ENUM_BEGIN(YGEdge) {
YGEdgeAll, YGEdgeAll,
} YG_ENUM_END(YGEdge); } YG_ENUM_END(YGEdge);
#define YGExperimentalFeatureCount 2 #define YGExperimentalFeatureCount 3
typedef YG_ENUM_BEGIN(YGExperimentalFeature) { typedef YG_ENUM_BEGIN(YGExperimentalFeature) {
YGExperimentalFeatureRounding, YGExperimentalFeatureRounding,
YGExperimentalFeatureWebFlexBasis, YGExperimentalFeatureWebFlexBasis,
YGExperimentalFeatureMinFlexFix,
} YG_ENUM_END(YGExperimentalFeature); } YG_ENUM_END(YGExperimentalFeature);
#define YGFlexDirectionCount 4 #define YGFlexDirectionCount 4

View File

@@ -1960,11 +1960,13 @@ static void YGNodelayoutImpl(const YGNodeRef node,
// above // above
float availableInnerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow; float availableInnerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow;
if (!YGFloatIsUndefined(availableInnerWidth)) { if (!YGFloatIsUndefined(availableInnerWidth)) {
// We want to make sure our available width does not violate min and max constraints
availableInnerWidth = fmaxf(fminf(availableInnerWidth, maxInnerWidth), minInnerWidth); availableInnerWidth = fmaxf(fminf(availableInnerWidth, maxInnerWidth), minInnerWidth);
} }
float availableInnerHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn; float availableInnerHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn;
if (!YGFloatIsUndefined(availableInnerHeight)) { if (!YGFloatIsUndefined(availableInnerHeight)) {
// We want to make sure our available height does not violate min and max constraints
availableInnerHeight = fmaxf(fminf(availableInnerHeight, maxInnerHeight), minInnerHeight); availableInnerHeight = fmaxf(fminf(availableInnerHeight, maxInnerHeight), minInnerHeight);
} }
@@ -2149,13 +2151,16 @@ static void YGNodelayoutImpl(const YGNodeRef node,
// If the main dimension size isn't known, it is computed based on // If the main dimension size isn't known, it is computed based on
// the line length, so there's no more space left to distribute. // the line length, so there's no more space left to distribute.
// We resolve main dimension to fit minimum and maximum values // If we don't measure with exact main dimension we want to ensure we don't violate min and max
if (YGFloatIsUndefined(availableInnerMainDim)) { if (measureModeMainDim != YGMeasureModeExactly) {
if (!YGFloatIsUndefined(minInnerMainDim) && sizeConsumedOnCurrentLine < minInnerMainDim) { if (!YGFloatIsUndefined(minInnerMainDim) && sizeConsumedOnCurrentLine < minInnerMainDim) {
availableInnerMainDim = minInnerMainDim; availableInnerMainDim = minInnerMainDim;
} else if (!YGFloatIsUndefined(maxInnerMainDim) && } else if (!YGFloatIsUndefined(maxInnerMainDim) && sizeConsumedOnCurrentLine > maxInnerMainDim) {
sizeConsumedOnCurrentLine > maxInnerMainDim) {
availableInnerMainDim = maxInnerMainDim; availableInnerMainDim = maxInnerMainDim;
} else if (YGIsExperimentalFeatureEnabled(YGExperimentalFeatureMinFlexFix)) {
// TODO: this needs to be moved out of experimental feature, as this is legitimate fix
// If the measurement isn't exact, we want to use as little space as possible
availableInnerMainDim = sizeConsumedOnCurrentLine;
} }
} }