From 3d45252af5ddd71edbc0dd6aa2f58b81d0b386c0 Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Fri, 15 Dec 2023 23:29:24 -0800 Subject: [PATCH] Fix sizing and alignment issues with multi-line containers (#1513) Summary: X-link: https://github.com/facebook/react-native/pull/41916 Fixes https://github.com/facebook/yoga/issues/1300 Fixes https://github.com/facebook/yoga/issues/1008 This fixes a smattering of issues related to both sizing and aligment of multi-line-containers: 1. We were previously incorrectly bounding the size of each flex line to the min/max of the entire container. 2. Per-line leads were sometimes incorrectly contributing to alignment within the line 3. The cross dim size used for multi-line alignment is not correct, or correctly clamped. If the available size comes from a max constraint, that was incorrectly used instead of a definite size, or size of content. Leads were entirely skipped for min constraint. Need to test how breaking this is, to see if it might need to go behind an errata. See related PRs: 1. https://github.com/facebook/yoga/pull/1491 2. https://github.com/facebook/yoga/pull/1493 3. https://github.com/facebook/yoga/pull/1013 Changelog: [General][Fixed] - Fix Yoga sizing and alignment issues with multi-line containers Reviewed By: joevilches Differential Revision: D52087013 --- gentest/fixtures/YGAlignContentTest.html | 55 +- gentest/fixtures/YGFlexWrapTest.html | 18 + .../com/facebook/yoga/YGAlignContentTest.java | 656 +++++++++++++++- .../com/facebook/yoga/YGFlexWrapTest.java | 203 ++++- .../generated/YGAlignContentTest.test.ts | 716 +++++++++++++++++- .../tests/generated/YGFlexWrapTest.test.ts | 227 +++++- tests/generated/YGAlignContentTest.cpp | 666 +++++++++++++++- tests/generated/YGFlexWrapTest.cpp | 207 ++++- yoga/algorithm/CalculateLayout.cpp | 138 ++-- 9 files changed, 2815 insertions(+), 71 deletions(-) diff --git a/gentest/fixtures/YGAlignContentTest.html b/gentest/fixtures/YGAlignContentTest.html index c6ff15bc8d..509649eaaa 100644 --- a/gentest/fixtures/YGAlignContentTest.html +++ b/gentest/fixtures/YGAlignContentTest.html @@ -342,4 +342,57 @@
- \ No newline at end of file + + +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
diff --git a/gentest/fixtures/YGFlexWrapTest.html b/gentest/fixtures/YGFlexWrapTest.html index 5b0bb42a48..ffb7036848 100644 --- a/gentest/fixtures/YGFlexWrapTest.html +++ b/gentest/fixtures/YGFlexWrapTest.html @@ -147,3 +147,21 @@ + +
+
+
+
+ +
+
+
+
+ +
+
+
+ +
+
+
diff --git a/java/tests/com/facebook/yoga/YGAlignContentTest.java b/java/tests/com/facebook/yoga/YGAlignContentTest.java index df8fa9ebac..1f757de2f0 100644 --- a/java/tests/com/facebook/yoga/YGAlignContentTest.java +++ b/java/tests/com/facebook/yoga/YGAlignContentTest.java @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<6f770e50100e36b1141c70bc8222c809>> + * @generated SignedSource<> * generated by gentest/gentest-driver.ts from gentest/fixtures/YGAlignContentTest.html */ @@ -3947,6 +3947,660 @@ public void test_align_content_stretch_is_not_overriding_align_items() { assertEquals(10f, root_child0_child0.getLayoutHeight(), 0.0f); } + @Test + public void test_align_content_stretch_with_min_cross_axis() { + YogaConfig config = YogaConfigFactory.create(); + config.setExperimentalFeatureEnabled(YogaExperimentalFeature.ABSOLUTE_PERCENTAGE_AGAINST_PADDING_EDGE, true); + + final YogaNode root = createNode(config); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignContent(YogaAlign.STRETCH); + root.setPositionType(YogaPositionType.ABSOLUTE); + root.setWrap(YogaWrap.WRAP); + root.setWidth(500f); + root.setMinHeight(500f); + + final YogaNode root_child0 = createNode(config); + root_child0.setWidth(400f); + root_child0.setHeight(200f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = createNode(config); + root_child1.setWidth(400f); + root_child1.setHeight(200f); + 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(500f, root.getLayoutWidth(), 0.0f); + assertEquals(500f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(400f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(200f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(250f, root_child1.getLayoutY(), 0.0f); + assertEquals(400f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(200f, 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(500f, root.getLayoutWidth(), 0.0f); + assertEquals(500f, root.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(400f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(200f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child1.getLayoutX(), 0.0f); + assertEquals(250f, root_child1.getLayoutY(), 0.0f); + assertEquals(400f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(200f, root_child1.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_content_stretch_with_max_cross_axis() { + YogaConfig config = YogaConfigFactory.create(); + config.setExperimentalFeatureEnabled(YogaExperimentalFeature.ABSOLUTE_PERCENTAGE_AGAINST_PADDING_EDGE, true); + + final YogaNode root = createNode(config); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignContent(YogaAlign.STRETCH); + root.setPositionType(YogaPositionType.ABSOLUTE); + root.setWrap(YogaWrap.WRAP); + root.setWidth(500f); + root.setMaxHeight(500f); + + final YogaNode root_child0 = createNode(config); + root_child0.setWidth(400f); + root_child0.setHeight(200f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = createNode(config); + root_child1.setWidth(400f); + root_child1.setHeight(200f); + 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(500f, root.getLayoutWidth(), 0.0f); + assertEquals(400f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(400f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(200f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(200f, root_child1.getLayoutY(), 0.0f); + assertEquals(400f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(200f, 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(500f, root.getLayoutWidth(), 0.0f); + assertEquals(400f, root.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(400f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(200f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child1.getLayoutX(), 0.0f); + assertEquals(200f, root_child1.getLayoutY(), 0.0f); + assertEquals(400f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(200f, root_child1.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_content_stretch_with_max_cross_axis_and_border_padding() { + YogaConfig config = YogaConfigFactory.create(); + config.setExperimentalFeatureEnabled(YogaExperimentalFeature.ABSOLUTE_PERCENTAGE_AGAINST_PADDING_EDGE, true); + + final YogaNode root = createNode(config); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignContent(YogaAlign.STRETCH); + root.setPositionType(YogaPositionType.ABSOLUTE); + root.setWrap(YogaWrap.WRAP); + root.setPadding(YogaEdge.LEFT, 2); + root.setPadding(YogaEdge.TOP, 2); + root.setPadding(YogaEdge.RIGHT, 2); + root.setPadding(YogaEdge.BOTTOM, 2); + root.setBorder(YogaEdge.LEFT, 5f); + root.setBorder(YogaEdge.TOP, 5f); + root.setBorder(YogaEdge.RIGHT, 5f); + root.setBorder(YogaEdge.BOTTOM, 5f); + root.setWidth(500f); + root.setMaxHeight(500f); + + final YogaNode root_child0 = createNode(config); + root_child0.setWidth(400f); + root_child0.setHeight(200f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = createNode(config); + root_child1.setWidth(400f); + root_child1.setHeight(200f); + 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(500f, root.getLayoutWidth(), 0.0f); + assertEquals(414f, root.getLayoutHeight(), 0.0f); + + assertEquals(7f, root_child0.getLayoutX(), 0.0f); + assertEquals(7f, root_child0.getLayoutY(), 0.0f); + assertEquals(400f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(200f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(7f, root_child1.getLayoutX(), 0.0f); + assertEquals(207f, root_child1.getLayoutY(), 0.0f); + assertEquals(400f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(200f, 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(500f, root.getLayoutWidth(), 0.0f); + assertEquals(414f, root.getLayoutHeight(), 0.0f); + + assertEquals(93f, root_child0.getLayoutX(), 0.0f); + assertEquals(7f, root_child0.getLayoutY(), 0.0f); + assertEquals(400f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(200f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(93f, root_child1.getLayoutX(), 0.0f); + assertEquals(207f, root_child1.getLayoutY(), 0.0f); + assertEquals(400f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(200f, root_child1.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_content_space_evenly_with_min_cross_axis() { + YogaConfig config = YogaConfigFactory.create(); + config.setExperimentalFeatureEnabled(YogaExperimentalFeature.ABSOLUTE_PERCENTAGE_AGAINST_PADDING_EDGE, true); + + final YogaNode root = createNode(config); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignContent(YogaAlign.SPACE_EVENLY); + root.setPositionType(YogaPositionType.ABSOLUTE); + root.setWrap(YogaWrap.WRAP); + root.setWidth(500f); + root.setMinHeight(500f); + + final YogaNode root_child0 = createNode(config); + root_child0.setWidth(400f); + root_child0.setHeight(200f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = createNode(config); + root_child1.setWidth(400f); + root_child1.setHeight(200f); + 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(500f, root.getLayoutWidth(), 0.0f); + assertEquals(500f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(33f, root_child0.getLayoutY(), 0.0f); + assertEquals(400f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(200f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(267f, root_child1.getLayoutY(), 0.0f); + assertEquals(400f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(200f, 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(500f, root.getLayoutWidth(), 0.0f); + assertEquals(500f, root.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child0.getLayoutX(), 0.0f); + assertEquals(33f, root_child0.getLayoutY(), 0.0f); + assertEquals(400f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(200f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child1.getLayoutX(), 0.0f); + assertEquals(267f, root_child1.getLayoutY(), 0.0f); + assertEquals(400f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(200f, root_child1.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_content_space_evenly_with_max_cross_axis() { + YogaConfig config = YogaConfigFactory.create(); + config.setExperimentalFeatureEnabled(YogaExperimentalFeature.ABSOLUTE_PERCENTAGE_AGAINST_PADDING_EDGE, true); + + final YogaNode root = createNode(config); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignContent(YogaAlign.SPACE_EVENLY); + root.setPositionType(YogaPositionType.ABSOLUTE); + root.setWrap(YogaWrap.WRAP); + root.setWidth(500f); + root.setMaxHeight(500f); + + final YogaNode root_child0 = createNode(config); + root_child0.setWidth(400f); + root_child0.setHeight(200f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = createNode(config); + root_child1.setWidth(400f); + root_child1.setHeight(200f); + 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(500f, root.getLayoutWidth(), 0.0f); + assertEquals(400f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(400f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(200f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(200f, root_child1.getLayoutY(), 0.0f); + assertEquals(400f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(200f, 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(500f, root.getLayoutWidth(), 0.0f); + assertEquals(400f, root.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(400f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(200f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child1.getLayoutX(), 0.0f); + assertEquals(200f, root_child1.getLayoutY(), 0.0f); + assertEquals(400f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(200f, root_child1.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_content_space_evenly_with_max_cross_axis_violated() { + YogaConfig config = YogaConfigFactory.create(); + config.setExperimentalFeatureEnabled(YogaExperimentalFeature.ABSOLUTE_PERCENTAGE_AGAINST_PADDING_EDGE, true); + + final YogaNode root = createNode(config); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignContent(YogaAlign.SPACE_EVENLY); + root.setPositionType(YogaPositionType.ABSOLUTE); + root.setWrap(YogaWrap.WRAP); + root.setWidth(500f); + root.setMaxHeight(300f); + + final YogaNode root_child0 = createNode(config); + root_child0.setWidth(400f); + root_child0.setHeight(200f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = createNode(config); + root_child1.setWidth(400f); + root_child1.setHeight(200f); + 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(500f, root.getLayoutWidth(), 0.0f); + assertEquals(300f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(-50f, root_child0.getLayoutY(), 0.0f); + assertEquals(400f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(200f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(150f, root_child1.getLayoutY(), 0.0f); + assertEquals(400f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(200f, 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(500f, root.getLayoutWidth(), 0.0f); + assertEquals(300f, root.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child0.getLayoutX(), 0.0f); + assertEquals(-50f, root_child0.getLayoutY(), 0.0f); + assertEquals(400f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(200f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child1.getLayoutX(), 0.0f); + assertEquals(150f, root_child1.getLayoutY(), 0.0f); + assertEquals(400f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(200f, root_child1.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_content_space_evenly_with_max_cross_axis_violated_padding_and_border() { + YogaConfig config = YogaConfigFactory.create(); + config.setExperimentalFeatureEnabled(YogaExperimentalFeature.ABSOLUTE_PERCENTAGE_AGAINST_PADDING_EDGE, true); + + final YogaNode root = createNode(config); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignContent(YogaAlign.SPACE_EVENLY); + root.setPositionType(YogaPositionType.ABSOLUTE); + root.setWrap(YogaWrap.WRAP); + root.setPadding(YogaEdge.LEFT, 2); + root.setPadding(YogaEdge.TOP, 2); + root.setPadding(YogaEdge.RIGHT, 2); + root.setPadding(YogaEdge.BOTTOM, 2); + root.setBorder(YogaEdge.LEFT, 5f); + root.setBorder(YogaEdge.TOP, 5f); + root.setBorder(YogaEdge.RIGHT, 5f); + root.setBorder(YogaEdge.BOTTOM, 5f); + root.setWidth(500f); + root.setMaxHeight(300f); + + final YogaNode root_child0 = createNode(config); + root_child0.setWidth(400f); + root_child0.setHeight(200f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = createNode(config); + root_child1.setWidth(400f); + root_child1.setHeight(200f); + 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(500f, root.getLayoutWidth(), 0.0f); + assertEquals(300f, root.getLayoutHeight(), 0.0f); + + assertEquals(7f, root_child0.getLayoutX(), 0.0f); + assertEquals(-50f, root_child0.getLayoutY(), 0.0f); + assertEquals(400f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(200f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(7f, root_child1.getLayoutX(), 0.0f); + assertEquals(150f, root_child1.getLayoutY(), 0.0f); + assertEquals(400f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(200f, 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(500f, root.getLayoutWidth(), 0.0f); + assertEquals(300f, root.getLayoutHeight(), 0.0f); + + assertEquals(93f, root_child0.getLayoutX(), 0.0f); + assertEquals(-50f, root_child0.getLayoutY(), 0.0f); + assertEquals(400f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(200f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(93f, root_child1.getLayoutX(), 0.0f); + assertEquals(150f, root_child1.getLayoutY(), 0.0f); + assertEquals(400f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(200f, root_child1.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_content_space_around_and_align_items_flex_end_with_flex_wrap() { + YogaConfig config = YogaConfigFactory.create(); + config.setExperimentalFeatureEnabled(YogaExperimentalFeature.ABSOLUTE_PERCENTAGE_AGAINST_PADDING_EDGE, true); + + final YogaNode root = createNode(config); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignContent(YogaAlign.SPACE_AROUND); + root.setAlignItems(YogaAlign.FLEX_END); + root.setPositionType(YogaPositionType.ABSOLUTE); + root.setWrap(YogaWrap.WRAP); + root.setWidth(300f); + root.setHeight(300f); + + final YogaNode root_child0 = createNode(config); + root_child0.setWidth(150f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = createNode(config); + root_child1.setWidth(120f); + root_child1.setHeight(100f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child2 = createNode(config); + root_child2.setWidth(120f); + root_child2.setHeight(50f); + root.addChildAt(root_child2, 2); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(300f, root.getLayoutWidth(), 0.0f); + assertEquals(300f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(88f, root_child0.getLayoutY(), 0.0f); + assertEquals(150f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(150f, root_child1.getLayoutX(), 0.0f); + assertEquals(38f, root_child1.getLayoutY(), 0.0f); + assertEquals(120f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child2.getLayoutX(), 0.0f); + assertEquals(213f, root_child2.getLayoutY(), 0.0f); + assertEquals(120f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child2.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(300f, root.getLayoutWidth(), 0.0f); + assertEquals(300f, root.getLayoutHeight(), 0.0f); + + assertEquals(150f, root_child0.getLayoutX(), 0.0f); + assertEquals(88f, root_child0.getLayoutY(), 0.0f); + assertEquals(150f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(30f, root_child1.getLayoutX(), 0.0f); + assertEquals(38f, root_child1.getLayoutY(), 0.0f); + assertEquals(120f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(180f, root_child2.getLayoutX(), 0.0f); + assertEquals(213f, root_child2.getLayoutY(), 0.0f); + assertEquals(120f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child2.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_content_space_around_and_align_items_center_with_flex_wrap() { + YogaConfig config = YogaConfigFactory.create(); + config.setExperimentalFeatureEnabled(YogaExperimentalFeature.ABSOLUTE_PERCENTAGE_AGAINST_PADDING_EDGE, true); + + final YogaNode root = createNode(config); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignContent(YogaAlign.SPACE_AROUND); + root.setAlignItems(YogaAlign.CENTER); + root.setPositionType(YogaPositionType.ABSOLUTE); + root.setWrap(YogaWrap.WRAP); + root.setWidth(300f); + root.setHeight(300f); + + final YogaNode root_child0 = createNode(config); + root_child0.setWidth(150f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = createNode(config); + root_child1.setWidth(120f); + root_child1.setHeight(100f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child2 = createNode(config); + root_child2.setWidth(120f); + root_child2.setHeight(50f); + root.addChildAt(root_child2, 2); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(300f, root.getLayoutWidth(), 0.0f); + assertEquals(300f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(63f, root_child0.getLayoutY(), 0.0f); + assertEquals(150f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(150f, root_child1.getLayoutX(), 0.0f); + assertEquals(38f, root_child1.getLayoutY(), 0.0f); + assertEquals(120f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child2.getLayoutX(), 0.0f); + assertEquals(213f, root_child2.getLayoutY(), 0.0f); + assertEquals(120f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child2.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(300f, root.getLayoutWidth(), 0.0f); + assertEquals(300f, root.getLayoutHeight(), 0.0f); + + assertEquals(150f, root_child0.getLayoutX(), 0.0f); + assertEquals(63f, root_child0.getLayoutY(), 0.0f); + assertEquals(150f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(30f, root_child1.getLayoutX(), 0.0f); + assertEquals(38f, root_child1.getLayoutY(), 0.0f); + assertEquals(120f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(180f, root_child2.getLayoutX(), 0.0f); + assertEquals(213f, root_child2.getLayoutY(), 0.0f); + assertEquals(120f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child2.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_content_space_around_and_align_items_flex_start_with_flex_wrap() { + YogaConfig config = YogaConfigFactory.create(); + config.setExperimentalFeatureEnabled(YogaExperimentalFeature.ABSOLUTE_PERCENTAGE_AGAINST_PADDING_EDGE, true); + + final YogaNode root = createNode(config); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignContent(YogaAlign.SPACE_AROUND); + root.setAlignItems(YogaAlign.FLEX_START); + root.setPositionType(YogaPositionType.ABSOLUTE); + root.setWrap(YogaWrap.WRAP); + root.setWidth(300f); + root.setHeight(300f); + + final YogaNode root_child0 = createNode(config); + root_child0.setWidth(150f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = createNode(config); + root_child1.setWidth(120f); + root_child1.setHeight(100f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child2 = createNode(config); + root_child2.setWidth(120f); + root_child2.setHeight(50f); + root.addChildAt(root_child2, 2); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(300f, root.getLayoutWidth(), 0.0f); + assertEquals(300f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(38f, root_child0.getLayoutY(), 0.0f); + assertEquals(150f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(150f, root_child1.getLayoutX(), 0.0f); + assertEquals(38f, root_child1.getLayoutY(), 0.0f); + assertEquals(120f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child2.getLayoutX(), 0.0f); + assertEquals(213f, root_child2.getLayoutY(), 0.0f); + assertEquals(120f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child2.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(300f, root.getLayoutWidth(), 0.0f); + assertEquals(300f, root.getLayoutHeight(), 0.0f); + + assertEquals(150f, root_child0.getLayoutX(), 0.0f); + assertEquals(38f, root_child0.getLayoutY(), 0.0f); + assertEquals(150f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(30f, root_child1.getLayoutX(), 0.0f); + assertEquals(38f, root_child1.getLayoutY(), 0.0f); + assertEquals(120f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(100f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(180f, root_child2.getLayoutX(), 0.0f); + assertEquals(213f, root_child2.getLayoutY(), 0.0f); + assertEquals(120f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child2.getLayoutHeight(), 0.0f); + } + private YogaNode createNode(YogaConfig config) { return mNodeFactory.create(config); } diff --git a/java/tests/com/facebook/yoga/YGFlexWrapTest.java b/java/tests/com/facebook/yoga/YGFlexWrapTest.java index a873cb938b..dda5c2ec70 100644 --- a/java/tests/com/facebook/yoga/YGFlexWrapTest.java +++ b/java/tests/com/facebook/yoga/YGFlexWrapTest.java @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<93ab380c6f5ff231f719234272a2d11f>> * generated by gentest/gentest-driver.ts from gentest/fixtures/YGFlexWrapTest.html */ @@ -1770,6 +1770,207 @@ public void test_wrap_nodes_with_content_sizing_margin_cross() { assertEquals(40f, root_child0_child1_child0.getLayoutHeight(), 0.0f); } + @Test + public void test_wrap_with_min_cross_axis() { + YogaConfig config = YogaConfigFactory.create(); + config.setExperimentalFeatureEnabled(YogaExperimentalFeature.ABSOLUTE_PERCENTAGE_AGAINST_PADDING_EDGE, true); + + final YogaNode root = createNode(config); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setPositionType(YogaPositionType.ABSOLUTE); + root.setWrap(YogaWrap.WRAP); + root.setWidth(500f); + root.setMinHeight(500f); + + final YogaNode root_child0 = createNode(config); + root_child0.setWidth(400f); + root_child0.setHeight(200f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = createNode(config); + root_child1.setWidth(400f); + root_child1.setHeight(200f); + 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(500f, root.getLayoutWidth(), 0.0f); + assertEquals(500f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(400f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(200f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(200f, root_child1.getLayoutY(), 0.0f); + assertEquals(400f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(200f, 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(500f, root.getLayoutWidth(), 0.0f); + assertEquals(500f, root.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(400f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(200f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child1.getLayoutX(), 0.0f); + assertEquals(200f, root_child1.getLayoutY(), 0.0f); + assertEquals(400f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(200f, root_child1.getLayoutHeight(), 0.0f); + } + + @Test + public void test_wrap_with_max_cross_axis() { + YogaConfig config = YogaConfigFactory.create(); + config.setExperimentalFeatureEnabled(YogaExperimentalFeature.ABSOLUTE_PERCENTAGE_AGAINST_PADDING_EDGE, true); + + final YogaNode root = createNode(config); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setPositionType(YogaPositionType.ABSOLUTE); + root.setWrap(YogaWrap.WRAP); + root.setWidth(500f); + root.setMaxHeight(500f); + + final YogaNode root_child0 = createNode(config); + root_child0.setWidth(400f); + root_child0.setHeight(200f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = createNode(config); + root_child1.setWidth(400f); + root_child1.setHeight(200f); + 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(500f, root.getLayoutWidth(), 0.0f); + assertEquals(400f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(400f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(200f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(200f, root_child1.getLayoutY(), 0.0f); + assertEquals(400f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(200f, 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(500f, root.getLayoutWidth(), 0.0f); + assertEquals(400f, root.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(400f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(200f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(100f, root_child1.getLayoutX(), 0.0f); + assertEquals(200f, root_child1.getLayoutY(), 0.0f); + assertEquals(400f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(200f, root_child1.getLayoutHeight(), 0.0f); + } + + @Test + public void test_nowrap_expands_flexline_box_to_min_cross() { + YogaConfig config = YogaConfigFactory.create(); + config.setExperimentalFeatureEnabled(YogaExperimentalFeature.ABSOLUTE_PERCENTAGE_AGAINST_PADDING_EDGE, true); + + final YogaNode root = createNode(config); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setPositionType(YogaPositionType.ABSOLUTE); + root.setMinHeight(400f); + + final YogaNode root_child0 = createNode(config); + root_child0.setFlexGrow(1f); + root_child0.setFlexShrink(1f); + root_child0.setFlexBasisPercent(0f); + root.addChildAt(root_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(0f, root.getLayoutWidth(), 0.0f); + assertEquals(400f, 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(400f, root_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(0f, root.getLayoutWidth(), 0.0f); + assertEquals(400f, 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(400f, root_child0.getLayoutHeight(), 0.0f); + } + + @Test + public void test_wrap_does_not_impose_min_cross_onto_single_flexline() { + YogaConfig config = YogaConfigFactory.create(); + config.setExperimentalFeatureEnabled(YogaExperimentalFeature.ABSOLUTE_PERCENTAGE_AGAINST_PADDING_EDGE, true); + + final YogaNode root = createNode(config); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setPositionType(YogaPositionType.ABSOLUTE); + root.setWrap(YogaWrap.WRAP); + root.setMinHeight(400f); + + final YogaNode root_child0 = createNode(config); + root_child0.setFlexGrow(1f); + root_child0.setFlexShrink(1f); + root_child0.setFlexBasisPercent(0f); + root.addChildAt(root_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(0f, root.getLayoutWidth(), 0.0f); + assertEquals(400f, 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); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(0f, root.getLayoutWidth(), 0.0f); + assertEquals(400f, 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); + } + private YogaNode createNode(YogaConfig config) { return mNodeFactory.create(config); } diff --git a/javascript/tests/generated/YGAlignContentTest.test.ts b/javascript/tests/generated/YGAlignContentTest.test.ts index 7af52ee1e8..c67e5db60b 100644 --- a/javascript/tests/generated/YGAlignContentTest.test.ts +++ b/javascript/tests/generated/YGAlignContentTest.test.ts @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<7f941503c4fed45ffd7c07f713d691bb>> + * @generated SignedSource<<90f151e3c55d956805a9f44153f87ad0>> * generated by gentest/gentest-driver.ts from gentest/fixtures/YGAlignContentTest.html */ @@ -4217,3 +4217,717 @@ test('align_content_stretch_is_not_overriding_align_items', () => { config.free(); } }); +test('align_content_stretch_with_min_cross_axis', () => { + const config = Yoga.Config.create(); + let root; + + config.setExperimentalFeatureEnabled(ExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true); + + try { + root = Yoga.Node.create(config); + root.setFlexDirection(FlexDirection.Row); + root.setAlignContent(Align.Stretch); + root.setPositionType(PositionType.Absolute); + root.setFlexWrap(Wrap.Wrap); + root.setWidth(500); + root.setMinHeight(500); + + const root_child0 = Yoga.Node.create(config); + root_child0.setWidth(400); + root_child0.setHeight(200); + root.insertChild(root_child0, 0); + + const root_child1 = Yoga.Node.create(config); + root_child1.setWidth(400); + root_child1.setHeight(200); + root.insertChild(root_child1, 1); + root.calculateLayout(undefined, undefined, Direction.LTR); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(500); + expect(root.getComputedHeight()).toBe(500); + + expect(root_child0.getComputedLeft()).toBe(0); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(400); + expect(root_child0.getComputedHeight()).toBe(200); + + expect(root_child1.getComputedLeft()).toBe(0); + expect(root_child1.getComputedTop()).toBe(250); + expect(root_child1.getComputedWidth()).toBe(400); + expect(root_child1.getComputedHeight()).toBe(200); + + root.calculateLayout(undefined, undefined, Direction.RTL); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(500); + expect(root.getComputedHeight()).toBe(500); + + expect(root_child0.getComputedLeft()).toBe(100); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(400); + expect(root_child0.getComputedHeight()).toBe(200); + + expect(root_child1.getComputedLeft()).toBe(100); + expect(root_child1.getComputedTop()).toBe(250); + expect(root_child1.getComputedWidth()).toBe(400); + expect(root_child1.getComputedHeight()).toBe(200); + } finally { + if (typeof root !== 'undefined') { + root.freeRecursive(); + } + + config.free(); + } +}); +test('align_content_stretch_with_max_cross_axis', () => { + const config = Yoga.Config.create(); + let root; + + config.setExperimentalFeatureEnabled(ExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true); + + try { + root = Yoga.Node.create(config); + root.setFlexDirection(FlexDirection.Row); + root.setAlignContent(Align.Stretch); + root.setPositionType(PositionType.Absolute); + root.setFlexWrap(Wrap.Wrap); + root.setWidth(500); + root.setMaxHeight(500); + + const root_child0 = Yoga.Node.create(config); + root_child0.setWidth(400); + root_child0.setHeight(200); + root.insertChild(root_child0, 0); + + const root_child1 = Yoga.Node.create(config); + root_child1.setWidth(400); + root_child1.setHeight(200); + root.insertChild(root_child1, 1); + root.calculateLayout(undefined, undefined, Direction.LTR); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(500); + expect(root.getComputedHeight()).toBe(400); + + expect(root_child0.getComputedLeft()).toBe(0); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(400); + expect(root_child0.getComputedHeight()).toBe(200); + + expect(root_child1.getComputedLeft()).toBe(0); + expect(root_child1.getComputedTop()).toBe(200); + expect(root_child1.getComputedWidth()).toBe(400); + expect(root_child1.getComputedHeight()).toBe(200); + + root.calculateLayout(undefined, undefined, Direction.RTL); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(500); + expect(root.getComputedHeight()).toBe(400); + + expect(root_child0.getComputedLeft()).toBe(100); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(400); + expect(root_child0.getComputedHeight()).toBe(200); + + expect(root_child1.getComputedLeft()).toBe(100); + expect(root_child1.getComputedTop()).toBe(200); + expect(root_child1.getComputedWidth()).toBe(400); + expect(root_child1.getComputedHeight()).toBe(200); + } finally { + if (typeof root !== 'undefined') { + root.freeRecursive(); + } + + config.free(); + } +}); +test('align_content_stretch_with_max_cross_axis_and_border_padding', () => { + const config = Yoga.Config.create(); + let root; + + config.setExperimentalFeatureEnabled(ExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true); + + try { + root = Yoga.Node.create(config); + root.setFlexDirection(FlexDirection.Row); + root.setAlignContent(Align.Stretch); + root.setPositionType(PositionType.Absolute); + root.setFlexWrap(Wrap.Wrap); + root.setPadding(Edge.Left, 2); + root.setPadding(Edge.Top, 2); + root.setPadding(Edge.Right, 2); + root.setPadding(Edge.Bottom, 2); + root.setBorder(Edge.Left, 5); + root.setBorder(Edge.Top, 5); + root.setBorder(Edge.Right, 5); + root.setBorder(Edge.Bottom, 5); + root.setWidth(500); + root.setMaxHeight(500); + + const root_child0 = Yoga.Node.create(config); + root_child0.setWidth(400); + root_child0.setHeight(200); + root.insertChild(root_child0, 0); + + const root_child1 = Yoga.Node.create(config); + root_child1.setWidth(400); + root_child1.setHeight(200); + root.insertChild(root_child1, 1); + root.calculateLayout(undefined, undefined, Direction.LTR); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(500); + expect(root.getComputedHeight()).toBe(414); + + expect(root_child0.getComputedLeft()).toBe(7); + expect(root_child0.getComputedTop()).toBe(7); + expect(root_child0.getComputedWidth()).toBe(400); + expect(root_child0.getComputedHeight()).toBe(200); + + expect(root_child1.getComputedLeft()).toBe(7); + expect(root_child1.getComputedTop()).toBe(207); + expect(root_child1.getComputedWidth()).toBe(400); + expect(root_child1.getComputedHeight()).toBe(200); + + root.calculateLayout(undefined, undefined, Direction.RTL); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(500); + expect(root.getComputedHeight()).toBe(414); + + expect(root_child0.getComputedLeft()).toBe(93); + expect(root_child0.getComputedTop()).toBe(7); + expect(root_child0.getComputedWidth()).toBe(400); + expect(root_child0.getComputedHeight()).toBe(200); + + expect(root_child1.getComputedLeft()).toBe(93); + expect(root_child1.getComputedTop()).toBe(207); + expect(root_child1.getComputedWidth()).toBe(400); + expect(root_child1.getComputedHeight()).toBe(200); + } finally { + if (typeof root !== 'undefined') { + root.freeRecursive(); + } + + config.free(); + } +}); +test('align_content_space_evenly_with_min_cross_axis', () => { + const config = Yoga.Config.create(); + let root; + + config.setExperimentalFeatureEnabled(ExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true); + + try { + root = Yoga.Node.create(config); + root.setFlexDirection(FlexDirection.Row); + root.setAlignContent(Align.SpaceEvenly); + root.setPositionType(PositionType.Absolute); + root.setFlexWrap(Wrap.Wrap); + root.setWidth(500); + root.setMinHeight(500); + + const root_child0 = Yoga.Node.create(config); + root_child0.setWidth(400); + root_child0.setHeight(200); + root.insertChild(root_child0, 0); + + const root_child1 = Yoga.Node.create(config); + root_child1.setWidth(400); + root_child1.setHeight(200); + root.insertChild(root_child1, 1); + root.calculateLayout(undefined, undefined, Direction.LTR); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(500); + expect(root.getComputedHeight()).toBe(500); + + expect(root_child0.getComputedLeft()).toBe(0); + expect(root_child0.getComputedTop()).toBe(33); + expect(root_child0.getComputedWidth()).toBe(400); + expect(root_child0.getComputedHeight()).toBe(200); + + expect(root_child1.getComputedLeft()).toBe(0); + expect(root_child1.getComputedTop()).toBe(267); + expect(root_child1.getComputedWidth()).toBe(400); + expect(root_child1.getComputedHeight()).toBe(200); + + root.calculateLayout(undefined, undefined, Direction.RTL); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(500); + expect(root.getComputedHeight()).toBe(500); + + expect(root_child0.getComputedLeft()).toBe(100); + expect(root_child0.getComputedTop()).toBe(33); + expect(root_child0.getComputedWidth()).toBe(400); + expect(root_child0.getComputedHeight()).toBe(200); + + expect(root_child1.getComputedLeft()).toBe(100); + expect(root_child1.getComputedTop()).toBe(267); + expect(root_child1.getComputedWidth()).toBe(400); + expect(root_child1.getComputedHeight()).toBe(200); + } finally { + if (typeof root !== 'undefined') { + root.freeRecursive(); + } + + config.free(); + } +}); +test('align_content_space_evenly_with_max_cross_axis', () => { + const config = Yoga.Config.create(); + let root; + + config.setExperimentalFeatureEnabled(ExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true); + + try { + root = Yoga.Node.create(config); + root.setFlexDirection(FlexDirection.Row); + root.setAlignContent(Align.SpaceEvenly); + root.setPositionType(PositionType.Absolute); + root.setFlexWrap(Wrap.Wrap); + root.setWidth(500); + root.setMaxHeight(500); + + const root_child0 = Yoga.Node.create(config); + root_child0.setWidth(400); + root_child0.setHeight(200); + root.insertChild(root_child0, 0); + + const root_child1 = Yoga.Node.create(config); + root_child1.setWidth(400); + root_child1.setHeight(200); + root.insertChild(root_child1, 1); + root.calculateLayout(undefined, undefined, Direction.LTR); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(500); + expect(root.getComputedHeight()).toBe(400); + + expect(root_child0.getComputedLeft()).toBe(0); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(400); + expect(root_child0.getComputedHeight()).toBe(200); + + expect(root_child1.getComputedLeft()).toBe(0); + expect(root_child1.getComputedTop()).toBe(200); + expect(root_child1.getComputedWidth()).toBe(400); + expect(root_child1.getComputedHeight()).toBe(200); + + root.calculateLayout(undefined, undefined, Direction.RTL); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(500); + expect(root.getComputedHeight()).toBe(400); + + expect(root_child0.getComputedLeft()).toBe(100); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(400); + expect(root_child0.getComputedHeight()).toBe(200); + + expect(root_child1.getComputedLeft()).toBe(100); + expect(root_child1.getComputedTop()).toBe(200); + expect(root_child1.getComputedWidth()).toBe(400); + expect(root_child1.getComputedHeight()).toBe(200); + } finally { + if (typeof root !== 'undefined') { + root.freeRecursive(); + } + + config.free(); + } +}); +test('align_content_space_evenly_with_max_cross_axis_violated', () => { + const config = Yoga.Config.create(); + let root; + + config.setExperimentalFeatureEnabled(ExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true); + + try { + root = Yoga.Node.create(config); + root.setFlexDirection(FlexDirection.Row); + root.setAlignContent(Align.SpaceEvenly); + root.setPositionType(PositionType.Absolute); + root.setFlexWrap(Wrap.Wrap); + root.setWidth(500); + root.setMaxHeight(300); + + const root_child0 = Yoga.Node.create(config); + root_child0.setWidth(400); + root_child0.setHeight(200); + root.insertChild(root_child0, 0); + + const root_child1 = Yoga.Node.create(config); + root_child1.setWidth(400); + root_child1.setHeight(200); + root.insertChild(root_child1, 1); + root.calculateLayout(undefined, undefined, Direction.LTR); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(500); + expect(root.getComputedHeight()).toBe(300); + + expect(root_child0.getComputedLeft()).toBe(0); + expect(root_child0.getComputedTop()).toBe(-50); + expect(root_child0.getComputedWidth()).toBe(400); + expect(root_child0.getComputedHeight()).toBe(200); + + expect(root_child1.getComputedLeft()).toBe(0); + expect(root_child1.getComputedTop()).toBe(150); + expect(root_child1.getComputedWidth()).toBe(400); + expect(root_child1.getComputedHeight()).toBe(200); + + root.calculateLayout(undefined, undefined, Direction.RTL); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(500); + expect(root.getComputedHeight()).toBe(300); + + expect(root_child0.getComputedLeft()).toBe(100); + expect(root_child0.getComputedTop()).toBe(-50); + expect(root_child0.getComputedWidth()).toBe(400); + expect(root_child0.getComputedHeight()).toBe(200); + + expect(root_child1.getComputedLeft()).toBe(100); + expect(root_child1.getComputedTop()).toBe(150); + expect(root_child1.getComputedWidth()).toBe(400); + expect(root_child1.getComputedHeight()).toBe(200); + } finally { + if (typeof root !== 'undefined') { + root.freeRecursive(); + } + + config.free(); + } +}); +test('align_content_space_evenly_with_max_cross_axis_violated_padding_and_border', () => { + const config = Yoga.Config.create(); + let root; + + config.setExperimentalFeatureEnabled(ExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true); + + try { + root = Yoga.Node.create(config); + root.setFlexDirection(FlexDirection.Row); + root.setAlignContent(Align.SpaceEvenly); + root.setPositionType(PositionType.Absolute); + root.setFlexWrap(Wrap.Wrap); + root.setPadding(Edge.Left, 2); + root.setPadding(Edge.Top, 2); + root.setPadding(Edge.Right, 2); + root.setPadding(Edge.Bottom, 2); + root.setBorder(Edge.Left, 5); + root.setBorder(Edge.Top, 5); + root.setBorder(Edge.Right, 5); + root.setBorder(Edge.Bottom, 5); + root.setWidth(500); + root.setMaxHeight(300); + + const root_child0 = Yoga.Node.create(config); + root_child0.setWidth(400); + root_child0.setHeight(200); + root.insertChild(root_child0, 0); + + const root_child1 = Yoga.Node.create(config); + root_child1.setWidth(400); + root_child1.setHeight(200); + root.insertChild(root_child1, 1); + root.calculateLayout(undefined, undefined, Direction.LTR); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(500); + expect(root.getComputedHeight()).toBe(300); + + expect(root_child0.getComputedLeft()).toBe(7); + expect(root_child0.getComputedTop()).toBe(-50); + expect(root_child0.getComputedWidth()).toBe(400); + expect(root_child0.getComputedHeight()).toBe(200); + + expect(root_child1.getComputedLeft()).toBe(7); + expect(root_child1.getComputedTop()).toBe(150); + expect(root_child1.getComputedWidth()).toBe(400); + expect(root_child1.getComputedHeight()).toBe(200); + + root.calculateLayout(undefined, undefined, Direction.RTL); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(500); + expect(root.getComputedHeight()).toBe(300); + + expect(root_child0.getComputedLeft()).toBe(93); + expect(root_child0.getComputedTop()).toBe(-50); + expect(root_child0.getComputedWidth()).toBe(400); + expect(root_child0.getComputedHeight()).toBe(200); + + expect(root_child1.getComputedLeft()).toBe(93); + expect(root_child1.getComputedTop()).toBe(150); + expect(root_child1.getComputedWidth()).toBe(400); + expect(root_child1.getComputedHeight()).toBe(200); + } finally { + if (typeof root !== 'undefined') { + root.freeRecursive(); + } + + config.free(); + } +}); +test('align_content_space_around_and_align_items_flex_end_with_flex_wrap', () => { + const config = Yoga.Config.create(); + let root; + + config.setExperimentalFeatureEnabled(ExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true); + + try { + root = Yoga.Node.create(config); + root.setFlexDirection(FlexDirection.Row); + root.setAlignContent(Align.SpaceAround); + root.setAlignItems(Align.FlexEnd); + root.setPositionType(PositionType.Absolute); + root.setFlexWrap(Wrap.Wrap); + root.setWidth(300); + root.setHeight(300); + + const root_child0 = Yoga.Node.create(config); + root_child0.setWidth(150); + root_child0.setHeight(50); + root.insertChild(root_child0, 0); + + const root_child1 = Yoga.Node.create(config); + root_child1.setWidth(120); + root_child1.setHeight(100); + root.insertChild(root_child1, 1); + + const root_child2 = Yoga.Node.create(config); + root_child2.setWidth(120); + root_child2.setHeight(50); + root.insertChild(root_child2, 2); + root.calculateLayout(undefined, undefined, Direction.LTR); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(300); + expect(root.getComputedHeight()).toBe(300); + + expect(root_child0.getComputedLeft()).toBe(0); + expect(root_child0.getComputedTop()).toBe(88); + expect(root_child0.getComputedWidth()).toBe(150); + expect(root_child0.getComputedHeight()).toBe(50); + + expect(root_child1.getComputedLeft()).toBe(150); + expect(root_child1.getComputedTop()).toBe(38); + expect(root_child1.getComputedWidth()).toBe(120); + expect(root_child1.getComputedHeight()).toBe(100); + + expect(root_child2.getComputedLeft()).toBe(0); + expect(root_child2.getComputedTop()).toBe(213); + expect(root_child2.getComputedWidth()).toBe(120); + expect(root_child2.getComputedHeight()).toBe(50); + + root.calculateLayout(undefined, undefined, Direction.RTL); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(300); + expect(root.getComputedHeight()).toBe(300); + + expect(root_child0.getComputedLeft()).toBe(150); + expect(root_child0.getComputedTop()).toBe(88); + expect(root_child0.getComputedWidth()).toBe(150); + expect(root_child0.getComputedHeight()).toBe(50); + + expect(root_child1.getComputedLeft()).toBe(30); + expect(root_child1.getComputedTop()).toBe(38); + expect(root_child1.getComputedWidth()).toBe(120); + expect(root_child1.getComputedHeight()).toBe(100); + + expect(root_child2.getComputedLeft()).toBe(180); + expect(root_child2.getComputedTop()).toBe(213); + expect(root_child2.getComputedWidth()).toBe(120); + expect(root_child2.getComputedHeight()).toBe(50); + } finally { + if (typeof root !== 'undefined') { + root.freeRecursive(); + } + + config.free(); + } +}); +test('align_content_space_around_and_align_items_center_with_flex_wrap', () => { + const config = Yoga.Config.create(); + let root; + + config.setExperimentalFeatureEnabled(ExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true); + + try { + root = Yoga.Node.create(config); + root.setFlexDirection(FlexDirection.Row); + root.setAlignContent(Align.SpaceAround); + root.setAlignItems(Align.Center); + root.setPositionType(PositionType.Absolute); + root.setFlexWrap(Wrap.Wrap); + root.setWidth(300); + root.setHeight(300); + + const root_child0 = Yoga.Node.create(config); + root_child0.setWidth(150); + root_child0.setHeight(50); + root.insertChild(root_child0, 0); + + const root_child1 = Yoga.Node.create(config); + root_child1.setWidth(120); + root_child1.setHeight(100); + root.insertChild(root_child1, 1); + + const root_child2 = Yoga.Node.create(config); + root_child2.setWidth(120); + root_child2.setHeight(50); + root.insertChild(root_child2, 2); + root.calculateLayout(undefined, undefined, Direction.LTR); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(300); + expect(root.getComputedHeight()).toBe(300); + + expect(root_child0.getComputedLeft()).toBe(0); + expect(root_child0.getComputedTop()).toBe(63); + expect(root_child0.getComputedWidth()).toBe(150); + expect(root_child0.getComputedHeight()).toBe(50); + + expect(root_child1.getComputedLeft()).toBe(150); + expect(root_child1.getComputedTop()).toBe(38); + expect(root_child1.getComputedWidth()).toBe(120); + expect(root_child1.getComputedHeight()).toBe(100); + + expect(root_child2.getComputedLeft()).toBe(0); + expect(root_child2.getComputedTop()).toBe(213); + expect(root_child2.getComputedWidth()).toBe(120); + expect(root_child2.getComputedHeight()).toBe(50); + + root.calculateLayout(undefined, undefined, Direction.RTL); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(300); + expect(root.getComputedHeight()).toBe(300); + + expect(root_child0.getComputedLeft()).toBe(150); + expect(root_child0.getComputedTop()).toBe(63); + expect(root_child0.getComputedWidth()).toBe(150); + expect(root_child0.getComputedHeight()).toBe(50); + + expect(root_child1.getComputedLeft()).toBe(30); + expect(root_child1.getComputedTop()).toBe(38); + expect(root_child1.getComputedWidth()).toBe(120); + expect(root_child1.getComputedHeight()).toBe(100); + + expect(root_child2.getComputedLeft()).toBe(180); + expect(root_child2.getComputedTop()).toBe(213); + expect(root_child2.getComputedWidth()).toBe(120); + expect(root_child2.getComputedHeight()).toBe(50); + } finally { + if (typeof root !== 'undefined') { + root.freeRecursive(); + } + + config.free(); + } +}); +test('align_content_space_around_and_align_items_flex_start_with_flex_wrap', () => { + const config = Yoga.Config.create(); + let root; + + config.setExperimentalFeatureEnabled(ExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true); + + try { + root = Yoga.Node.create(config); + root.setFlexDirection(FlexDirection.Row); + root.setAlignContent(Align.SpaceAround); + root.setAlignItems(Align.FlexStart); + root.setPositionType(PositionType.Absolute); + root.setFlexWrap(Wrap.Wrap); + root.setWidth(300); + root.setHeight(300); + + const root_child0 = Yoga.Node.create(config); + root_child0.setWidth(150); + root_child0.setHeight(50); + root.insertChild(root_child0, 0); + + const root_child1 = Yoga.Node.create(config); + root_child1.setWidth(120); + root_child1.setHeight(100); + root.insertChild(root_child1, 1); + + const root_child2 = Yoga.Node.create(config); + root_child2.setWidth(120); + root_child2.setHeight(50); + root.insertChild(root_child2, 2); + root.calculateLayout(undefined, undefined, Direction.LTR); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(300); + expect(root.getComputedHeight()).toBe(300); + + expect(root_child0.getComputedLeft()).toBe(0); + expect(root_child0.getComputedTop()).toBe(38); + expect(root_child0.getComputedWidth()).toBe(150); + expect(root_child0.getComputedHeight()).toBe(50); + + expect(root_child1.getComputedLeft()).toBe(150); + expect(root_child1.getComputedTop()).toBe(38); + expect(root_child1.getComputedWidth()).toBe(120); + expect(root_child1.getComputedHeight()).toBe(100); + + expect(root_child2.getComputedLeft()).toBe(0); + expect(root_child2.getComputedTop()).toBe(213); + expect(root_child2.getComputedWidth()).toBe(120); + expect(root_child2.getComputedHeight()).toBe(50); + + root.calculateLayout(undefined, undefined, Direction.RTL); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(300); + expect(root.getComputedHeight()).toBe(300); + + expect(root_child0.getComputedLeft()).toBe(150); + expect(root_child0.getComputedTop()).toBe(38); + expect(root_child0.getComputedWidth()).toBe(150); + expect(root_child0.getComputedHeight()).toBe(50); + + expect(root_child1.getComputedLeft()).toBe(30); + expect(root_child1.getComputedTop()).toBe(38); + expect(root_child1.getComputedWidth()).toBe(120); + expect(root_child1.getComputedHeight()).toBe(100); + + expect(root_child2.getComputedLeft()).toBe(180); + expect(root_child2.getComputedTop()).toBe(213); + expect(root_child2.getComputedWidth()).toBe(120); + expect(root_child2.getComputedHeight()).toBe(50); + } finally { + if (typeof root !== 'undefined') { + root.freeRecursive(); + } + + config.free(); + } +}); diff --git a/javascript/tests/generated/YGFlexWrapTest.test.ts b/javascript/tests/generated/YGFlexWrapTest.test.ts index ccae33d810..d50942ec28 100644 --- a/javascript/tests/generated/YGFlexWrapTest.test.ts +++ b/javascript/tests/generated/YGFlexWrapTest.test.ts @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<6ec020ec4e84b8a877a84ce11981f7b3>> * generated by gentest/gentest-driver.ts from gentest/fixtures/YGFlexWrapTest.html */ @@ -1890,3 +1890,228 @@ test('wrap_nodes_with_content_sizing_margin_cross', () => { config.free(); } }); +test('wrap_with_min_cross_axis', () => { + const config = Yoga.Config.create(); + let root; + + config.setExperimentalFeatureEnabled(ExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true); + + try { + root = Yoga.Node.create(config); + root.setFlexDirection(FlexDirection.Row); + root.setPositionType(PositionType.Absolute); + root.setFlexWrap(Wrap.Wrap); + root.setWidth(500); + root.setMinHeight(500); + + const root_child0 = Yoga.Node.create(config); + root_child0.setWidth(400); + root_child0.setHeight(200); + root.insertChild(root_child0, 0); + + const root_child1 = Yoga.Node.create(config); + root_child1.setWidth(400); + root_child1.setHeight(200); + root.insertChild(root_child1, 1); + root.calculateLayout(undefined, undefined, Direction.LTR); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(500); + expect(root.getComputedHeight()).toBe(500); + + expect(root_child0.getComputedLeft()).toBe(0); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(400); + expect(root_child0.getComputedHeight()).toBe(200); + + expect(root_child1.getComputedLeft()).toBe(0); + expect(root_child1.getComputedTop()).toBe(200); + expect(root_child1.getComputedWidth()).toBe(400); + expect(root_child1.getComputedHeight()).toBe(200); + + root.calculateLayout(undefined, undefined, Direction.RTL); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(500); + expect(root.getComputedHeight()).toBe(500); + + expect(root_child0.getComputedLeft()).toBe(100); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(400); + expect(root_child0.getComputedHeight()).toBe(200); + + expect(root_child1.getComputedLeft()).toBe(100); + expect(root_child1.getComputedTop()).toBe(200); + expect(root_child1.getComputedWidth()).toBe(400); + expect(root_child1.getComputedHeight()).toBe(200); + } finally { + if (typeof root !== 'undefined') { + root.freeRecursive(); + } + + config.free(); + } +}); +test('wrap_with_max_cross_axis', () => { + const config = Yoga.Config.create(); + let root; + + config.setExperimentalFeatureEnabled(ExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true); + + try { + root = Yoga.Node.create(config); + root.setFlexDirection(FlexDirection.Row); + root.setPositionType(PositionType.Absolute); + root.setFlexWrap(Wrap.Wrap); + root.setWidth(500); + root.setMaxHeight(500); + + const root_child0 = Yoga.Node.create(config); + root_child0.setWidth(400); + root_child0.setHeight(200); + root.insertChild(root_child0, 0); + + const root_child1 = Yoga.Node.create(config); + root_child1.setWidth(400); + root_child1.setHeight(200); + root.insertChild(root_child1, 1); + root.calculateLayout(undefined, undefined, Direction.LTR); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(500); + expect(root.getComputedHeight()).toBe(400); + + expect(root_child0.getComputedLeft()).toBe(0); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(400); + expect(root_child0.getComputedHeight()).toBe(200); + + expect(root_child1.getComputedLeft()).toBe(0); + expect(root_child1.getComputedTop()).toBe(200); + expect(root_child1.getComputedWidth()).toBe(400); + expect(root_child1.getComputedHeight()).toBe(200); + + root.calculateLayout(undefined, undefined, Direction.RTL); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(500); + expect(root.getComputedHeight()).toBe(400); + + expect(root_child0.getComputedLeft()).toBe(100); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(400); + expect(root_child0.getComputedHeight()).toBe(200); + + expect(root_child1.getComputedLeft()).toBe(100); + expect(root_child1.getComputedTop()).toBe(200); + expect(root_child1.getComputedWidth()).toBe(400); + expect(root_child1.getComputedHeight()).toBe(200); + } finally { + if (typeof root !== 'undefined') { + root.freeRecursive(); + } + + config.free(); + } +}); +test('nowrap_expands_flexline_box_to_min_cross', () => { + const config = Yoga.Config.create(); + let root; + + config.setExperimentalFeatureEnabled(ExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true); + + try { + root = Yoga.Node.create(config); + root.setFlexDirection(FlexDirection.Row); + root.setPositionType(PositionType.Absolute); + root.setMinHeight(400); + + const root_child0 = Yoga.Node.create(config); + root_child0.setFlexGrow(1); + root_child0.setFlexShrink(1); + root_child0.setFlexBasis("0%"); + root.insertChild(root_child0, 0); + root.calculateLayout(undefined, undefined, Direction.LTR); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(0); + expect(root.getComputedHeight()).toBe(400); + + expect(root_child0.getComputedLeft()).toBe(0); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(0); + expect(root_child0.getComputedHeight()).toBe(400); + + root.calculateLayout(undefined, undefined, Direction.RTL); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(0); + expect(root.getComputedHeight()).toBe(400); + + expect(root_child0.getComputedLeft()).toBe(0); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(0); + expect(root_child0.getComputedHeight()).toBe(400); + } finally { + if (typeof root !== 'undefined') { + root.freeRecursive(); + } + + config.free(); + } +}); +test('wrap_does_not_impose_min_cross_onto_single_flexline', () => { + const config = Yoga.Config.create(); + let root; + + config.setExperimentalFeatureEnabled(ExperimentalFeature.AbsolutePercentageAgainstPaddingEdge, true); + + try { + root = Yoga.Node.create(config); + root.setFlexDirection(FlexDirection.Row); + root.setPositionType(PositionType.Absolute); + root.setFlexWrap(Wrap.Wrap); + root.setMinHeight(400); + + const root_child0 = Yoga.Node.create(config); + root_child0.setFlexGrow(1); + root_child0.setFlexShrink(1); + root_child0.setFlexBasis("0%"); + root.insertChild(root_child0, 0); + root.calculateLayout(undefined, undefined, Direction.LTR); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(0); + expect(root.getComputedHeight()).toBe(400); + + expect(root_child0.getComputedLeft()).toBe(0); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(0); + expect(root_child0.getComputedHeight()).toBe(0); + + root.calculateLayout(undefined, undefined, Direction.RTL); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(0); + expect(root.getComputedHeight()).toBe(400); + + expect(root_child0.getComputedLeft()).toBe(0); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(0); + expect(root_child0.getComputedHeight()).toBe(0); + } finally { + if (typeof root !== 'undefined') { + root.freeRecursive(); + } + + config.free(); + } +}); diff --git a/tests/generated/YGAlignContentTest.cpp b/tests/generated/YGAlignContentTest.cpp index 77f617c373..22792c5242 100644 --- a/tests/generated/YGAlignContentTest.cpp +++ b/tests/generated/YGAlignContentTest.cpp @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. * * clang-format off - * @generated SignedSource<<77bb645e5cc31f4a2a6805afbb9c795f>> + * @generated SignedSource<> * generated by gentest/gentest-driver.ts from gentest/fixtures/YGAlignContentTest.html */ @@ -3977,3 +3977,667 @@ TEST(YogaTest, align_content_stretch_is_not_overriding_align_items) { YGConfigFree(config); } + +TEST(YogaTest, align_content_stretch_with_min_cross_axis) { + const YGConfigRef config = YGConfigNew(); + YGConfigSetExperimentalFeatureEnabled(config, YGExperimentalFeatureAbsolutePercentageAgainstPaddingEdge, true); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetMinHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 400); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 400); + YGNodeStyleSetHeight(root_child1, 200); + 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(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(250, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_stretch_with_max_cross_axis) { + const YGConfigRef config = YGConfigNew(); + YGConfigSetExperimentalFeatureEnabled(config, YGExperimentalFeatureAbsolutePercentageAgainstPaddingEdge, true); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetMaxHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 400); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 400); + YGNodeStyleSetHeight(root_child1, 200); + 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(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_stretch_with_max_cross_axis_and_border_padding) { + const YGConfigRef config = YGConfigNew(); + YGConfigSetExperimentalFeatureEnabled(config, YGExperimentalFeatureAbsolutePercentageAgainstPaddingEdge, true); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetPadding(root, YGEdgeLeft, 2); + YGNodeStyleSetPadding(root, YGEdgeTop, 2); + YGNodeStyleSetPadding(root, YGEdgeRight, 2); + YGNodeStyleSetPadding(root, YGEdgeBottom, 2); + YGNodeStyleSetBorder(root, YGEdgeLeft, 5); + YGNodeStyleSetBorder(root, YGEdgeTop, 5); + YGNodeStyleSetBorder(root, YGEdgeRight, 5); + YGNodeStyleSetBorder(root, YGEdgeBottom, 5); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetMaxHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 400); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 400); + YGNodeStyleSetHeight(root_child1, 200); + 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(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(414, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(7, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(7, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(7, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(207, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(414, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(93, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(7, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(93, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(207, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_evenly_with_min_cross_axis) { + const YGConfigRef config = YGConfigNew(); + YGConfigSetExperimentalFeatureEnabled(config, YGExperimentalFeatureAbsolutePercentageAgainstPaddingEdge, true); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceEvenly); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetMinHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 400); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 400); + YGNodeStyleSetHeight(root_child1, 200); + 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(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(33, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(267, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(33, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(267, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_evenly_with_max_cross_axis) { + const YGConfigRef config = YGConfigNew(); + YGConfigSetExperimentalFeatureEnabled(config, YGExperimentalFeatureAbsolutePercentageAgainstPaddingEdge, true); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceEvenly); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetMaxHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 400); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 400); + YGNodeStyleSetHeight(root_child1, 200); + 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(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_evenly_with_max_cross_axis_violated) { + const YGConfigRef config = YGConfigNew(); + YGConfigSetExperimentalFeatureEnabled(config, YGExperimentalFeatureAbsolutePercentageAgainstPaddingEdge, true); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceEvenly); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetMaxHeight(root, 300); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 400); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 400); + YGNodeStyleSetHeight(root_child1, 200); + 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(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(-50, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(-50, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_evenly_with_max_cross_axis_violated_padding_and_border) { + const YGConfigRef config = YGConfigNew(); + YGConfigSetExperimentalFeatureEnabled(config, YGExperimentalFeatureAbsolutePercentageAgainstPaddingEdge, true); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceEvenly); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetPadding(root, YGEdgeLeft, 2); + YGNodeStyleSetPadding(root, YGEdgeTop, 2); + YGNodeStyleSetPadding(root, YGEdgeRight, 2); + YGNodeStyleSetPadding(root, YGEdgeBottom, 2); + YGNodeStyleSetBorder(root, YGEdgeLeft, 5); + YGNodeStyleSetBorder(root, YGEdgeTop, 5); + YGNodeStyleSetBorder(root, YGEdgeRight, 5); + YGNodeStyleSetBorder(root, YGEdgeBottom, 5); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetMaxHeight(root, 300); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 400); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 400); + YGNodeStyleSetHeight(root_child1, 200); + 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(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(7, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(-50, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(7, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(93, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(-50, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(93, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_around_and_align_items_flex_end_with_flex_wrap) { + const YGConfigRef config = YGConfigNew(); + YGConfigSetExperimentalFeatureEnabled(config, YGExperimentalFeatureAbsolutePercentageAgainstPaddingEdge, true); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceAround); + YGNodeStyleSetAlignItems(root, YGAlignFlexEnd); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 300); + YGNodeStyleSetHeight(root, 300); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 150); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 120); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 120); + YGNodeStyleSetHeight(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(88, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(38, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(213, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(88, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(38, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(180, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(213, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_around_and_align_items_center_with_flex_wrap) { + const YGConfigRef config = YGConfigNew(); + YGConfigSetExperimentalFeatureEnabled(config, YGExperimentalFeatureAbsolutePercentageAgainstPaddingEdge, true); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceAround); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 300); + YGNodeStyleSetHeight(root, 300); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 150); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 120); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 120); + YGNodeStyleSetHeight(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(63, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(38, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(213, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(63, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(38, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(180, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(213, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, align_content_space_around_and_align_items_flex_start_with_flex_wrap) { + const YGConfigRef config = YGConfigNew(); + YGConfigSetExperimentalFeatureEnabled(config, YGExperimentalFeatureAbsolutePercentageAgainstPaddingEdge, true); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root, YGAlignSpaceAround); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 300); + YGNodeStyleSetHeight(root, 300); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 150); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 120); + YGNodeStyleSetHeight(root_child1, 100); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 120); + YGNodeStyleSetHeight(root_child2, 50); + YGNodeInsertChild(root, root_child2, 2); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(38, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(38, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(213, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(38, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(38, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(180, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(213, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(120, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} diff --git a/tests/generated/YGFlexWrapTest.cpp b/tests/generated/YGFlexWrapTest.cpp index daf6e110ff..1c31573689 100644 --- a/tests/generated/YGFlexWrapTest.cpp +++ b/tests/generated/YGFlexWrapTest.cpp @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. * * clang-format off - * @generated SignedSource<> + * @generated SignedSource<> * generated by gentest/gentest-driver.ts from gentest/fixtures/YGFlexWrapTest.html */ @@ -1775,3 +1775,208 @@ TEST(YogaTest, wrap_nodes_with_content_sizing_margin_cross) { YGConfigFree(config); } + +TEST(YogaTest, wrap_with_min_cross_axis) { + const YGConfigRef config = YGConfigNew(); + YGConfigSetExperimentalFeatureEnabled(config, YGExperimentalFeatureAbsolutePercentageAgainstPaddingEdge, true); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetMinHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 400); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 400); + YGNodeStyleSetHeight(root_child1, 200); + 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(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, wrap_with_max_cross_axis) { + const YGConfigRef config = YGConfigNew(); + YGConfigSetExperimentalFeatureEnabled(config, YGExperimentalFeatureAbsolutePercentageAgainstPaddingEdge, true); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 500); + YGNodeStyleSetMaxHeight(root, 500); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 400); + YGNodeStyleSetHeight(root_child0, 200); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 400); + YGNodeStyleSetHeight(root_child1, 200); + 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(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, nowrap_expands_flexline_box_to_min_cross) { + const YGConfigRef config = YGConfigNew(); + YGConfigSetExperimentalFeatureEnabled(config, YGExperimentalFeatureAbsolutePercentageAgainstPaddingEdge, true); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetMinHeight(root, 400); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0, 0); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, 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(400, YGNodeLayoutGetHeight(root_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, 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(400, YGNodeLayoutGetHeight(root_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, wrap_does_not_impose_min_cross_onto_single_flexline) { + const YGConfigRef config = YGConfigNew(); + YGConfigSetExperimentalFeatureEnabled(config, YGExperimentalFeatureAbsolutePercentageAgainstPaddingEdge, true); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetMinHeight(root, 400); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexGrow(root_child0, 1); + YGNodeStyleSetFlexShrink(root_child0, 1); + YGNodeStyleSetFlexBasisPercent(root_child0, 0); + YGNodeInsertChild(root, root_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, 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)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(400, 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)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} diff --git a/yoga/algorithm/CalculateLayout.cpp b/yoga/algorithm/CalculateLayout.cpp index 25665dafc5..8b645b9971 100644 --- a/yoga/algorithm/CalculateLayout.cpp +++ b/yoga/algorithm/CalculateLayout.cpp @@ -1569,15 +1569,20 @@ static void calculateLayoutImpl( flexLine.layout.crossDim = availableInnerCrossDim; } - // Clamp to the min/max size specified on the container. - flexLine.layout.crossDim = - boundAxis( - node, - crossAxis, - flexLine.layout.crossDim + paddingAndBorderAxisCross, - crossAxisownerSize, - ownerWidth) - - paddingAndBorderAxisCross; + // As-per https://www.w3.org/TR/css-flexbox-1/#cross-sizing, the + // cross-size of the line within a single-line container should be bound to + // min/max constraints before alignment within the line. In a multi-line + // container, affecting alignment between the lines. + if (!isNodeFlexWrap) { + flexLine.layout.crossDim = + boundAxis( + node, + crossAxis, + flexLine.layout.crossDim + paddingAndBorderAxisCross, + crossAxisownerSize, + ownerWidth) - + paddingAndBorderAxisCross; + } // STEP 7: CROSS-AXIS ALIGNMENT // We can skip child alignment if we're just measuring the container. @@ -1735,59 +1740,65 @@ static void calculateLayoutImpl( // STEP 8: MULTI-LINE CONTENT ALIGNMENT // currentLead stores the size of the cross dim if (performLayout && (isNodeFlexWrap || isBaselineLayout(node))) { - float crossDimLead = 0; + float leadPerLine = 0; float currentLead = leadingPaddingAndBorderCross; - if (yoga::isDefined(availableInnerCrossDim)) { - const float remainingAlignContentDim = - availableInnerCrossDim - totalLineCrossDim; - switch (node->getStyle().alignContent()) { - case Align::FlexEnd: - currentLead += remainingAlignContentDim; - break; - case Align::Center: + + const float unclampedCrossDim = + node->styleDefinesDimension(crossAxis, crossAxisownerSize) + ? yoga::resolveValue( + node->getResolvedDimension(dimension(crossAxis)), + crossAxisownerSize) + .unwrap() + : totalLineCrossDim + paddingAndBorderAxisCross; + + const float innerCrossDim = + boundAxis(node, crossAxis, unclampedCrossDim, ownerHeight, ownerWidth) - + paddingAndBorderAxisCross; + + const float remainingAlignContentDim = innerCrossDim - totalLineCrossDim; + switch (node->getStyle().alignContent()) { + case Align::FlexEnd: + currentLead += remainingAlignContentDim; + break; + case Align::Center: + currentLead += remainingAlignContentDim / 2; + break; + case Align::Stretch: + if (innerCrossDim > totalLineCrossDim) { + leadPerLine = + remainingAlignContentDim / static_cast(lineCount); + } + break; + case Align::SpaceAround: + if (innerCrossDim > totalLineCrossDim) { + currentLead += + remainingAlignContentDim / (2 * static_cast(lineCount)); + leadPerLine = + remainingAlignContentDim / static_cast(lineCount); + } else { currentLead += remainingAlignContentDim / 2; - break; - case Align::Stretch: - if (availableInnerCrossDim > totalLineCrossDim) { - crossDimLead = - remainingAlignContentDim / static_cast(lineCount); - } - break; - case Align::SpaceAround: - if (availableInnerCrossDim > totalLineCrossDim) { - currentLead += - remainingAlignContentDim / (2 * static_cast(lineCount)); - if (lineCount > 1) { - crossDimLead = - remainingAlignContentDim / static_cast(lineCount); - } - } else { - currentLead += remainingAlignContentDim / 2; - } - break; - case Align::SpaceEvenly: - if (availableInnerCrossDim > totalLineCrossDim) { - currentLead += - remainingAlignContentDim / static_cast(lineCount + 1); - if (lineCount > 1) { - crossDimLead = - remainingAlignContentDim / static_cast(lineCount + 1); - } - } else { - currentLead += remainingAlignContentDim / 2; - } - break; - case Align::SpaceBetween: - if (availableInnerCrossDim > totalLineCrossDim && lineCount > 1) { - crossDimLead = - remainingAlignContentDim / static_cast(lineCount - 1); - } - break; - case Align::Auto: - case Align::FlexStart: - case Align::Baseline: - break; - } + } + break; + case Align::SpaceEvenly: + if (innerCrossDim > totalLineCrossDim) { + currentLead += + remainingAlignContentDim / static_cast(lineCount + 1); + leadPerLine = + remainingAlignContentDim / static_cast(lineCount + 1); + } else { + currentLead += remainingAlignContentDim / 2; + } + break; + case Align::SpaceBetween: + if (innerCrossDim > totalLineCrossDim && lineCount > 1) { + leadPerLine = + remainingAlignContentDim / static_cast(lineCount - 1); + } + break; + case Align::Auto: + case Align::FlexStart: + case Align::Baseline: + break; } size_t endIndex = 0; for (size_t i = 0; i < lineCount; i++) { @@ -1832,7 +1843,6 @@ static void calculateLayoutImpl( } } endIndex = ii; - lineHeight += crossDimLead; currentLead += i != 0 ? crossAxisGap : 0; if (performLayout) { @@ -1885,14 +1895,14 @@ static void calculateLayoutImpl( ? (child->getLayout().measuredDimension( Dimension::Width) + child->getMarginForAxis(mainAxis, availableInnerWidth)) - : lineHeight; + : leadPerLine + lineHeight; const float childHeight = !isMainAxisRow ? (child->getLayout().measuredDimension( Dimension::Height) + child->getMarginForAxis( crossAxis, availableInnerWidth)) - : lineHeight; + : leadPerLine + lineHeight; if (!(yoga::inexactEquals( childWidth, @@ -1941,7 +1951,7 @@ static void calculateLayoutImpl( } } } - currentLead += lineHeight; + currentLead = currentLead + leadPerLine + lineHeight; } }