From 1fb58e2b1a406ded1ea39843d0c796c43dda9e28 Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Wed, 17 Apr 2024 11:11:47 -0700 Subject: [PATCH] Fixup margin: auto and justification behavior for overflowed containers (#1646) Summary: X-link: https://github.com/facebook/react-native/pull/44069 Fixes https://github.com/facebook/yoga/issues/978 1. Don't allow auto margin spaces to become a negative length 2. Replicate fallback alignment behavior specified by box-alignment spec that we are using for align-content. Reviewed By: joevilches Differential Revision: D56091577 --- gentest/fixtures/YGJustifyContentTest.html | 54 ++ gentest/fixtures/YGMarginTest.html | 5 + .../facebook/yoga/YGJustifyContentTest.java | 623 +++++++++++++++- .../tests/com/facebook/yoga/YGMarginTest.java | 59 +- .../generated/YGJustifyContentTest.test.ts | 668 +++++++++++++++++- .../tests/generated/YGMarginTest.test.ts | 64 +- tests/generated/YGJustifyContentTest.cpp | 632 ++++++++++++++++- tests/generated/YGMarginTest.cpp | 60 +- yoga/algorithm/Align.h | 43 ++ yoga/algorithm/CalculateLayout.cpp | 56 +- yoga/algorithm/FlexLine.cpp | 17 +- yoga/algorithm/FlexLine.h | 3 + 12 files changed, 2233 insertions(+), 51 deletions(-) diff --git a/gentest/fixtures/YGJustifyContentTest.html b/gentest/fixtures/YGJustifyContentTest.html index 9cb9d2a4b4..13e9987cfa 100644 --- a/gentest/fixtures/YGJustifyContentTest.html +++ b/gentest/fixtures/YGJustifyContentTest.html @@ -120,3 +120,57 @@
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
diff --git a/gentest/fixtures/YGMarginTest.html b/gentest/fixtures/YGMarginTest.html index d95a058d7b..01a13afe79 100644 --- a/gentest/fixtures/YGMarginTest.html +++ b/gentest/fixtures/YGMarginTest.html @@ -150,3 +150,8 @@
+ +
+
+
+
diff --git a/java/tests/com/facebook/yoga/YGJustifyContentTest.java b/java/tests/com/facebook/yoga/YGJustifyContentTest.java index 638433d9f0..9f141e2afe 100644 --- a/java/tests/com/facebook/yoga/YGJustifyContentTest.java +++ b/java/tests/com/facebook/yoga/YGJustifyContentTest.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<> * generated by gentest/gentest-driver.ts from gentest/fixtures/YGJustifyContentTest.html */ @@ -1375,6 +1375,627 @@ public void test_justify_content_flex_end_row_reverse() { assertEquals(100f, root_child2.getLayoutHeight(), 0.0f); } + @Test + public void test_justify_content_overflow_row_flex_start() { + YogaConfig config = YogaConfigFactory.create(); + + final YogaNode root = createNode(config); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setPositionType(YogaPositionType.ABSOLUTE); + root.setWidth(102f); + root.setHeight(102f); + + final YogaNode root_child0 = createNode(config); + root_child0.setWidth(40f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = createNode(config); + root_child1.setWidth(40f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child2 = createNode(config); + root_child2.setWidth(40f); + 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(102f, root.getLayoutWidth(), 0.0f); + assertEquals(102f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(40f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(40f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(40f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(80f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(40f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(102f, 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(102f, root.getLayoutWidth(), 0.0f); + assertEquals(102f, root.getLayoutHeight(), 0.0f); + + assertEquals(62f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(40f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(22f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(40f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(-18f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(40f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child2.getLayoutHeight(), 0.0f); + } + + @Test + public void test_justify_content_overflow_row_flex_end() { + YogaConfig config = YogaConfigFactory.create(); + + final YogaNode root = createNode(config); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setJustifyContent(YogaJustify.FLEX_END); + root.setPositionType(YogaPositionType.ABSOLUTE); + root.setWidth(102f); + root.setHeight(102f); + + final YogaNode root_child0 = createNode(config); + root_child0.setWidth(40f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = createNode(config); + root_child1.setWidth(40f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child2 = createNode(config); + root_child2.setWidth(40f); + 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(102f, root.getLayoutWidth(), 0.0f); + assertEquals(102f, root.getLayoutHeight(), 0.0f); + + assertEquals(-18f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(40f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(22f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(40f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(62f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(40f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(102f, 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(102f, root.getLayoutWidth(), 0.0f); + assertEquals(102f, root.getLayoutHeight(), 0.0f); + + assertEquals(80f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(40f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(40f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(40f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(40f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child2.getLayoutHeight(), 0.0f); + } + + @Test + public void test_justify_content_overflow_row_center() { + YogaConfig config = YogaConfigFactory.create(); + + final YogaNode root = createNode(config); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setJustifyContent(YogaJustify.CENTER); + root.setPositionType(YogaPositionType.ABSOLUTE); + root.setWidth(102f); + root.setHeight(102f); + + final YogaNode root_child0 = createNode(config); + root_child0.setWidth(40f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = createNode(config); + root_child1.setWidth(40f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child2 = createNode(config); + root_child2.setWidth(40f); + 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(102f, root.getLayoutWidth(), 0.0f); + assertEquals(102f, root.getLayoutHeight(), 0.0f); + + assertEquals(-9f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(40f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(31f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(40f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(71f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(40f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(102f, 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(102f, root.getLayoutWidth(), 0.0f); + assertEquals(102f, root.getLayoutHeight(), 0.0f); + + assertEquals(71f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(40f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(31f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(40f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(-9f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(40f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child2.getLayoutHeight(), 0.0f); + } + + @Test + public void test_justify_content_overflow_row_space_between() { + YogaConfig config = YogaConfigFactory.create(); + + final YogaNode root = createNode(config); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setJustifyContent(YogaJustify.SPACE_BETWEEN); + root.setPositionType(YogaPositionType.ABSOLUTE); + root.setWidth(102f); + root.setHeight(102f); + + final YogaNode root_child0 = createNode(config); + root_child0.setWidth(40f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = createNode(config); + root_child1.setWidth(40f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child2 = createNode(config); + root_child2.setWidth(40f); + 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(102f, root.getLayoutWidth(), 0.0f); + assertEquals(102f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(40f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(40f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(40f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(80f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(40f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(102f, 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(102f, root.getLayoutWidth(), 0.0f); + assertEquals(102f, root.getLayoutHeight(), 0.0f); + + assertEquals(62f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(40f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(22f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(40f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(-18f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(40f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child2.getLayoutHeight(), 0.0f); + } + + @Test + public void test_justify_content_overflow_row_space_around() { + YogaConfig config = YogaConfigFactory.create(); + + final YogaNode root = createNode(config); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setJustifyContent(YogaJustify.SPACE_AROUND); + root.setPositionType(YogaPositionType.ABSOLUTE); + root.setWidth(102f); + root.setHeight(102f); + + final YogaNode root_child0 = createNode(config); + root_child0.setWidth(40f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = createNode(config); + root_child1.setWidth(40f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child2 = createNode(config); + root_child2.setWidth(40f); + 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(102f, root.getLayoutWidth(), 0.0f); + assertEquals(102f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(40f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(40f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(40f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(80f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(40f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(102f, 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(102f, root.getLayoutWidth(), 0.0f); + assertEquals(102f, root.getLayoutHeight(), 0.0f); + + assertEquals(62f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(40f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(22f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(40f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(-18f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(40f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child2.getLayoutHeight(), 0.0f); + } + + @Test + public void test_justify_content_overflow_row_space_evenly() { + YogaConfig config = YogaConfigFactory.create(); + + final YogaNode root = createNode(config); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setJustifyContent(YogaJustify.SPACE_EVENLY); + root.setPositionType(YogaPositionType.ABSOLUTE); + root.setWidth(102f); + root.setHeight(102f); + + final YogaNode root_child0 = createNode(config); + root_child0.setWidth(40f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = createNode(config); + root_child1.setWidth(40f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child2 = createNode(config); + root_child2.setWidth(40f); + 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(102f, root.getLayoutWidth(), 0.0f); + assertEquals(102f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(40f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(40f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(40f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(80f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(40f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(102f, 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(102f, root.getLayoutWidth(), 0.0f); + assertEquals(102f, root.getLayoutHeight(), 0.0f); + + assertEquals(62f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(40f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(22f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(40f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(-18f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(40f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child2.getLayoutHeight(), 0.0f); + } + + @Test + public void test_justify_content_overflow_row_reverse_space_around() { + YogaConfig config = YogaConfigFactory.create(); + + final YogaNode root = createNode(config); + root.setFlexDirection(YogaFlexDirection.ROW_REVERSE); + root.setJustifyContent(YogaJustify.SPACE_AROUND); + root.setPositionType(YogaPositionType.ABSOLUTE); + root.setWidth(102f); + root.setHeight(102f); + + final YogaNode root_child0 = createNode(config); + root_child0.setWidth(40f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = createNode(config); + root_child1.setWidth(40f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child2 = createNode(config); + root_child2.setWidth(40f); + 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(102f, root.getLayoutWidth(), 0.0f); + assertEquals(102f, root.getLayoutHeight(), 0.0f); + + assertEquals(62f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(40f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(22f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(40f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(-18f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(40f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(102f, 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(102f, root.getLayoutWidth(), 0.0f); + assertEquals(102f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(40f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(40f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(40f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(80f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(40f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child2.getLayoutHeight(), 0.0f); + } + + @Test + public void test_justify_content_overflow_row_reverse_space_evenly() { + YogaConfig config = YogaConfigFactory.create(); + + final YogaNode root = createNode(config); + root.setFlexDirection(YogaFlexDirection.ROW_REVERSE); + root.setJustifyContent(YogaJustify.SPACE_EVENLY); + root.setPositionType(YogaPositionType.ABSOLUTE); + root.setWidth(102f); + root.setHeight(102f); + + final YogaNode root_child0 = createNode(config); + root_child0.setWidth(40f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = createNode(config); + root_child1.setWidth(40f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child2 = createNode(config); + root_child2.setWidth(40f); + 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(102f, root.getLayoutWidth(), 0.0f); + assertEquals(102f, root.getLayoutHeight(), 0.0f); + + assertEquals(62f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(40f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(22f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(40f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(-18f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(40f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(102f, 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(102f, root.getLayoutWidth(), 0.0f); + assertEquals(102f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(40f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(40f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(40f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(80f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(40f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child2.getLayoutHeight(), 0.0f); + } + + @Test + public void test_justify_content_overflow_row_space_evenly_auto_margin() { + YogaConfig config = YogaConfigFactory.create(); + + final YogaNode root = createNode(config); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setJustifyContent(YogaJustify.SPACE_EVENLY); + root.setPositionType(YogaPositionType.ABSOLUTE); + root.setWidth(102f); + root.setHeight(102f); + + final YogaNode root_child0 = createNode(config); + root_child0.setMarginAuto(YogaEdge.RIGHT); + root_child0.setWidth(40f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = createNode(config); + root_child1.setWidth(40f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child2 = createNode(config); + root_child2.setWidth(40f); + 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(102f, root.getLayoutWidth(), 0.0f); + assertEquals(102f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(40f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(40f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(40f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(80f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(40f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(102f, 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(102f, root.getLayoutWidth(), 0.0f); + assertEquals(102f, root.getLayoutHeight(), 0.0f); + + assertEquals(62f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(40f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(22f, root_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1.getLayoutY(), 0.0f); + assertEquals(40f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(-18f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(40f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(102f, root_child2.getLayoutHeight(), 0.0f); + } + private YogaNode createNode(YogaConfig config) { return mNodeFactory.create(config); } diff --git a/java/tests/com/facebook/yoga/YGMarginTest.java b/java/tests/com/facebook/yoga/YGMarginTest.java index 20b0cb71c1..5b065185a2 100644 --- a/java/tests/com/facebook/yoga/YGMarginTest.java +++ b/java/tests/com/facebook/yoga/YGMarginTest.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<> * generated by gentest/gentest-driver.ts from gentest/fixtures/YGMarginTest.html */ @@ -1732,6 +1732,63 @@ public void test_margin_auto_left_stretching_child() { assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); } + @Test + public void test_margin_auto_overflowing_container() { + YogaConfig config = YogaConfigFactory.create(); + + final YogaNode root = createNode(config); + root.setAlignItems(YogaAlign.CENTER); + root.setPositionType(YogaPositionType.ABSOLUTE); + root.setWidth(200f); + root.setHeight(200f); + + final YogaNode root_child0 = createNode(config); + root_child0.setMarginAuto(YogaEdge.BOTTOM); + root_child0.setWidth(50f); + root_child0.setHeight(150f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = createNode(config); + root_child1.setWidth(50f); + root_child1.setHeight(150f); + 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(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(150f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child1.getLayoutX(), 0.0f); + assertEquals(150f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(150f, 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(200f, root.getLayoutWidth(), 0.0f); + assertEquals(200f, root.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(150f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(75f, root_child1.getLayoutX(), 0.0f); + assertEquals(150f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(150f, root_child1.getLayoutHeight(), 0.0f); + } + private YogaNode createNode(YogaConfig config) { return mNodeFactory.create(config); } diff --git a/javascript/tests/generated/YGJustifyContentTest.test.ts b/javascript/tests/generated/YGJustifyContentTest.test.ts index adf8dde330..3a376f6312 100644 --- a/javascript/tests/generated/YGJustifyContentTest.test.ts +++ b/javascript/tests/generated/YGJustifyContentTest.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<<1027a837f1935ffdea54dc3c7676c35c>> + * @generated SignedSource<> * generated by gentest/gentest-driver.ts from gentest/fixtures/YGJustifyContentTest.html */ @@ -1480,3 +1480,669 @@ test('justify_content_flex_end_row_reverse', () => { config.free(); } }); +test('justify_content_overflow_row_flex_start', () => { + const config = Yoga.Config.create(); + let root; + + try { + root = Yoga.Node.create(config); + root.setFlexDirection(FlexDirection.Row); + root.setPositionType(PositionType.Absolute); + root.setWidth(102); + root.setHeight(102); + + const root_child0 = Yoga.Node.create(config); + root_child0.setWidth(40); + root.insertChild(root_child0, 0); + + const root_child1 = Yoga.Node.create(config); + root_child1.setWidth(40); + root.insertChild(root_child1, 1); + + const root_child2 = Yoga.Node.create(config); + root_child2.setWidth(40); + 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(102); + expect(root.getComputedHeight()).toBe(102); + + expect(root_child0.getComputedLeft()).toBe(0); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(40); + expect(root_child0.getComputedHeight()).toBe(102); + + expect(root_child1.getComputedLeft()).toBe(40); + expect(root_child1.getComputedTop()).toBe(0); + expect(root_child1.getComputedWidth()).toBe(40); + expect(root_child1.getComputedHeight()).toBe(102); + + expect(root_child2.getComputedLeft()).toBe(80); + expect(root_child2.getComputedTop()).toBe(0); + expect(root_child2.getComputedWidth()).toBe(40); + expect(root_child2.getComputedHeight()).toBe(102); + + root.calculateLayout(undefined, undefined, Direction.RTL); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(102); + expect(root.getComputedHeight()).toBe(102); + + expect(root_child0.getComputedLeft()).toBe(62); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(40); + expect(root_child0.getComputedHeight()).toBe(102); + + expect(root_child1.getComputedLeft()).toBe(22); + expect(root_child1.getComputedTop()).toBe(0); + expect(root_child1.getComputedWidth()).toBe(40); + expect(root_child1.getComputedHeight()).toBe(102); + + expect(root_child2.getComputedLeft()).toBe(-18); + expect(root_child2.getComputedTop()).toBe(0); + expect(root_child2.getComputedWidth()).toBe(40); + expect(root_child2.getComputedHeight()).toBe(102); + } finally { + if (typeof root !== 'undefined') { + root.freeRecursive(); + } + + config.free(); + } +}); +test('justify_content_overflow_row_flex_end', () => { + const config = Yoga.Config.create(); + let root; + + try { + root = Yoga.Node.create(config); + root.setFlexDirection(FlexDirection.Row); + root.setJustifyContent(Justify.FlexEnd); + root.setPositionType(PositionType.Absolute); + root.setWidth(102); + root.setHeight(102); + + const root_child0 = Yoga.Node.create(config); + root_child0.setWidth(40); + root.insertChild(root_child0, 0); + + const root_child1 = Yoga.Node.create(config); + root_child1.setWidth(40); + root.insertChild(root_child1, 1); + + const root_child2 = Yoga.Node.create(config); + root_child2.setWidth(40); + 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(102); + expect(root.getComputedHeight()).toBe(102); + + expect(root_child0.getComputedLeft()).toBe(-18); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(40); + expect(root_child0.getComputedHeight()).toBe(102); + + expect(root_child1.getComputedLeft()).toBe(22); + expect(root_child1.getComputedTop()).toBe(0); + expect(root_child1.getComputedWidth()).toBe(40); + expect(root_child1.getComputedHeight()).toBe(102); + + expect(root_child2.getComputedLeft()).toBe(62); + expect(root_child2.getComputedTop()).toBe(0); + expect(root_child2.getComputedWidth()).toBe(40); + expect(root_child2.getComputedHeight()).toBe(102); + + root.calculateLayout(undefined, undefined, Direction.RTL); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(102); + expect(root.getComputedHeight()).toBe(102); + + expect(root_child0.getComputedLeft()).toBe(80); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(40); + expect(root_child0.getComputedHeight()).toBe(102); + + expect(root_child1.getComputedLeft()).toBe(40); + expect(root_child1.getComputedTop()).toBe(0); + expect(root_child1.getComputedWidth()).toBe(40); + expect(root_child1.getComputedHeight()).toBe(102); + + expect(root_child2.getComputedLeft()).toBe(0); + expect(root_child2.getComputedTop()).toBe(0); + expect(root_child2.getComputedWidth()).toBe(40); + expect(root_child2.getComputedHeight()).toBe(102); + } finally { + if (typeof root !== 'undefined') { + root.freeRecursive(); + } + + config.free(); + } +}); +test('justify_content_overflow_row_center', () => { + const config = Yoga.Config.create(); + let root; + + try { + root = Yoga.Node.create(config); + root.setFlexDirection(FlexDirection.Row); + root.setJustifyContent(Justify.Center); + root.setPositionType(PositionType.Absolute); + root.setWidth(102); + root.setHeight(102); + + const root_child0 = Yoga.Node.create(config); + root_child0.setWidth(40); + root.insertChild(root_child0, 0); + + const root_child1 = Yoga.Node.create(config); + root_child1.setWidth(40); + root.insertChild(root_child1, 1); + + const root_child2 = Yoga.Node.create(config); + root_child2.setWidth(40); + 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(102); + expect(root.getComputedHeight()).toBe(102); + + expect(root_child0.getComputedLeft()).toBe(-9); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(40); + expect(root_child0.getComputedHeight()).toBe(102); + + expect(root_child1.getComputedLeft()).toBe(31); + expect(root_child1.getComputedTop()).toBe(0); + expect(root_child1.getComputedWidth()).toBe(40); + expect(root_child1.getComputedHeight()).toBe(102); + + expect(root_child2.getComputedLeft()).toBe(71); + expect(root_child2.getComputedTop()).toBe(0); + expect(root_child2.getComputedWidth()).toBe(40); + expect(root_child2.getComputedHeight()).toBe(102); + + root.calculateLayout(undefined, undefined, Direction.RTL); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(102); + expect(root.getComputedHeight()).toBe(102); + + expect(root_child0.getComputedLeft()).toBe(71); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(40); + expect(root_child0.getComputedHeight()).toBe(102); + + expect(root_child1.getComputedLeft()).toBe(31); + expect(root_child1.getComputedTop()).toBe(0); + expect(root_child1.getComputedWidth()).toBe(40); + expect(root_child1.getComputedHeight()).toBe(102); + + expect(root_child2.getComputedLeft()).toBe(-9); + expect(root_child2.getComputedTop()).toBe(0); + expect(root_child2.getComputedWidth()).toBe(40); + expect(root_child2.getComputedHeight()).toBe(102); + } finally { + if (typeof root !== 'undefined') { + root.freeRecursive(); + } + + config.free(); + } +}); +test('justify_content_overflow_row_space_between', () => { + const config = Yoga.Config.create(); + let root; + + try { + root = Yoga.Node.create(config); + root.setFlexDirection(FlexDirection.Row); + root.setJustifyContent(Justify.SpaceBetween); + root.setPositionType(PositionType.Absolute); + root.setWidth(102); + root.setHeight(102); + + const root_child0 = Yoga.Node.create(config); + root_child0.setWidth(40); + root.insertChild(root_child0, 0); + + const root_child1 = Yoga.Node.create(config); + root_child1.setWidth(40); + root.insertChild(root_child1, 1); + + const root_child2 = Yoga.Node.create(config); + root_child2.setWidth(40); + 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(102); + expect(root.getComputedHeight()).toBe(102); + + expect(root_child0.getComputedLeft()).toBe(0); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(40); + expect(root_child0.getComputedHeight()).toBe(102); + + expect(root_child1.getComputedLeft()).toBe(40); + expect(root_child1.getComputedTop()).toBe(0); + expect(root_child1.getComputedWidth()).toBe(40); + expect(root_child1.getComputedHeight()).toBe(102); + + expect(root_child2.getComputedLeft()).toBe(80); + expect(root_child2.getComputedTop()).toBe(0); + expect(root_child2.getComputedWidth()).toBe(40); + expect(root_child2.getComputedHeight()).toBe(102); + + root.calculateLayout(undefined, undefined, Direction.RTL); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(102); + expect(root.getComputedHeight()).toBe(102); + + expect(root_child0.getComputedLeft()).toBe(62); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(40); + expect(root_child0.getComputedHeight()).toBe(102); + + expect(root_child1.getComputedLeft()).toBe(22); + expect(root_child1.getComputedTop()).toBe(0); + expect(root_child1.getComputedWidth()).toBe(40); + expect(root_child1.getComputedHeight()).toBe(102); + + expect(root_child2.getComputedLeft()).toBe(-18); + expect(root_child2.getComputedTop()).toBe(0); + expect(root_child2.getComputedWidth()).toBe(40); + expect(root_child2.getComputedHeight()).toBe(102); + } finally { + if (typeof root !== 'undefined') { + root.freeRecursive(); + } + + config.free(); + } +}); +test('justify_content_overflow_row_space_around', () => { + const config = Yoga.Config.create(); + let root; + + try { + root = Yoga.Node.create(config); + root.setFlexDirection(FlexDirection.Row); + root.setJustifyContent(Justify.SpaceAround); + root.setPositionType(PositionType.Absolute); + root.setWidth(102); + root.setHeight(102); + + const root_child0 = Yoga.Node.create(config); + root_child0.setWidth(40); + root.insertChild(root_child0, 0); + + const root_child1 = Yoga.Node.create(config); + root_child1.setWidth(40); + root.insertChild(root_child1, 1); + + const root_child2 = Yoga.Node.create(config); + root_child2.setWidth(40); + 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(102); + expect(root.getComputedHeight()).toBe(102); + + expect(root_child0.getComputedLeft()).toBe(0); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(40); + expect(root_child0.getComputedHeight()).toBe(102); + + expect(root_child1.getComputedLeft()).toBe(40); + expect(root_child1.getComputedTop()).toBe(0); + expect(root_child1.getComputedWidth()).toBe(40); + expect(root_child1.getComputedHeight()).toBe(102); + + expect(root_child2.getComputedLeft()).toBe(80); + expect(root_child2.getComputedTop()).toBe(0); + expect(root_child2.getComputedWidth()).toBe(40); + expect(root_child2.getComputedHeight()).toBe(102); + + root.calculateLayout(undefined, undefined, Direction.RTL); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(102); + expect(root.getComputedHeight()).toBe(102); + + expect(root_child0.getComputedLeft()).toBe(62); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(40); + expect(root_child0.getComputedHeight()).toBe(102); + + expect(root_child1.getComputedLeft()).toBe(22); + expect(root_child1.getComputedTop()).toBe(0); + expect(root_child1.getComputedWidth()).toBe(40); + expect(root_child1.getComputedHeight()).toBe(102); + + expect(root_child2.getComputedLeft()).toBe(-18); + expect(root_child2.getComputedTop()).toBe(0); + expect(root_child2.getComputedWidth()).toBe(40); + expect(root_child2.getComputedHeight()).toBe(102); + } finally { + if (typeof root !== 'undefined') { + root.freeRecursive(); + } + + config.free(); + } +}); +test('justify_content_overflow_row_space_evenly', () => { + const config = Yoga.Config.create(); + let root; + + try { + root = Yoga.Node.create(config); + root.setFlexDirection(FlexDirection.Row); + root.setJustifyContent(Justify.SpaceEvenly); + root.setPositionType(PositionType.Absolute); + root.setWidth(102); + root.setHeight(102); + + const root_child0 = Yoga.Node.create(config); + root_child0.setWidth(40); + root.insertChild(root_child0, 0); + + const root_child1 = Yoga.Node.create(config); + root_child1.setWidth(40); + root.insertChild(root_child1, 1); + + const root_child2 = Yoga.Node.create(config); + root_child2.setWidth(40); + 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(102); + expect(root.getComputedHeight()).toBe(102); + + expect(root_child0.getComputedLeft()).toBe(0); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(40); + expect(root_child0.getComputedHeight()).toBe(102); + + expect(root_child1.getComputedLeft()).toBe(40); + expect(root_child1.getComputedTop()).toBe(0); + expect(root_child1.getComputedWidth()).toBe(40); + expect(root_child1.getComputedHeight()).toBe(102); + + expect(root_child2.getComputedLeft()).toBe(80); + expect(root_child2.getComputedTop()).toBe(0); + expect(root_child2.getComputedWidth()).toBe(40); + expect(root_child2.getComputedHeight()).toBe(102); + + root.calculateLayout(undefined, undefined, Direction.RTL); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(102); + expect(root.getComputedHeight()).toBe(102); + + expect(root_child0.getComputedLeft()).toBe(62); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(40); + expect(root_child0.getComputedHeight()).toBe(102); + + expect(root_child1.getComputedLeft()).toBe(22); + expect(root_child1.getComputedTop()).toBe(0); + expect(root_child1.getComputedWidth()).toBe(40); + expect(root_child1.getComputedHeight()).toBe(102); + + expect(root_child2.getComputedLeft()).toBe(-18); + expect(root_child2.getComputedTop()).toBe(0); + expect(root_child2.getComputedWidth()).toBe(40); + expect(root_child2.getComputedHeight()).toBe(102); + } finally { + if (typeof root !== 'undefined') { + root.freeRecursive(); + } + + config.free(); + } +}); +test('justify_content_overflow_row_reverse_space_around', () => { + const config = Yoga.Config.create(); + let root; + + try { + root = Yoga.Node.create(config); + root.setFlexDirection(FlexDirection.RowReverse); + root.setJustifyContent(Justify.SpaceAround); + root.setPositionType(PositionType.Absolute); + root.setWidth(102); + root.setHeight(102); + + const root_child0 = Yoga.Node.create(config); + root_child0.setWidth(40); + root.insertChild(root_child0, 0); + + const root_child1 = Yoga.Node.create(config); + root_child1.setWidth(40); + root.insertChild(root_child1, 1); + + const root_child2 = Yoga.Node.create(config); + root_child2.setWidth(40); + 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(102); + expect(root.getComputedHeight()).toBe(102); + + expect(root_child0.getComputedLeft()).toBe(62); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(40); + expect(root_child0.getComputedHeight()).toBe(102); + + expect(root_child1.getComputedLeft()).toBe(22); + expect(root_child1.getComputedTop()).toBe(0); + expect(root_child1.getComputedWidth()).toBe(40); + expect(root_child1.getComputedHeight()).toBe(102); + + expect(root_child2.getComputedLeft()).toBe(-18); + expect(root_child2.getComputedTop()).toBe(0); + expect(root_child2.getComputedWidth()).toBe(40); + expect(root_child2.getComputedHeight()).toBe(102); + + root.calculateLayout(undefined, undefined, Direction.RTL); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(102); + expect(root.getComputedHeight()).toBe(102); + + expect(root_child0.getComputedLeft()).toBe(0); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(40); + expect(root_child0.getComputedHeight()).toBe(102); + + expect(root_child1.getComputedLeft()).toBe(40); + expect(root_child1.getComputedTop()).toBe(0); + expect(root_child1.getComputedWidth()).toBe(40); + expect(root_child1.getComputedHeight()).toBe(102); + + expect(root_child2.getComputedLeft()).toBe(80); + expect(root_child2.getComputedTop()).toBe(0); + expect(root_child2.getComputedWidth()).toBe(40); + expect(root_child2.getComputedHeight()).toBe(102); + } finally { + if (typeof root !== 'undefined') { + root.freeRecursive(); + } + + config.free(); + } +}); +test('justify_content_overflow_row_reverse_space_evenly', () => { + const config = Yoga.Config.create(); + let root; + + try { + root = Yoga.Node.create(config); + root.setFlexDirection(FlexDirection.RowReverse); + root.setJustifyContent(Justify.SpaceEvenly); + root.setPositionType(PositionType.Absolute); + root.setWidth(102); + root.setHeight(102); + + const root_child0 = Yoga.Node.create(config); + root_child0.setWidth(40); + root.insertChild(root_child0, 0); + + const root_child1 = Yoga.Node.create(config); + root_child1.setWidth(40); + root.insertChild(root_child1, 1); + + const root_child2 = Yoga.Node.create(config); + root_child2.setWidth(40); + 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(102); + expect(root.getComputedHeight()).toBe(102); + + expect(root_child0.getComputedLeft()).toBe(62); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(40); + expect(root_child0.getComputedHeight()).toBe(102); + + expect(root_child1.getComputedLeft()).toBe(22); + expect(root_child1.getComputedTop()).toBe(0); + expect(root_child1.getComputedWidth()).toBe(40); + expect(root_child1.getComputedHeight()).toBe(102); + + expect(root_child2.getComputedLeft()).toBe(-18); + expect(root_child2.getComputedTop()).toBe(0); + expect(root_child2.getComputedWidth()).toBe(40); + expect(root_child2.getComputedHeight()).toBe(102); + + root.calculateLayout(undefined, undefined, Direction.RTL); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(102); + expect(root.getComputedHeight()).toBe(102); + + expect(root_child0.getComputedLeft()).toBe(0); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(40); + expect(root_child0.getComputedHeight()).toBe(102); + + expect(root_child1.getComputedLeft()).toBe(40); + expect(root_child1.getComputedTop()).toBe(0); + expect(root_child1.getComputedWidth()).toBe(40); + expect(root_child1.getComputedHeight()).toBe(102); + + expect(root_child2.getComputedLeft()).toBe(80); + expect(root_child2.getComputedTop()).toBe(0); + expect(root_child2.getComputedWidth()).toBe(40); + expect(root_child2.getComputedHeight()).toBe(102); + } finally { + if (typeof root !== 'undefined') { + root.freeRecursive(); + } + + config.free(); + } +}); +test('justify_content_overflow_row_space_evenly_auto_margin', () => { + const config = Yoga.Config.create(); + let root; + + try { + root = Yoga.Node.create(config); + root.setFlexDirection(FlexDirection.Row); + root.setJustifyContent(Justify.SpaceEvenly); + root.setPositionType(PositionType.Absolute); + root.setWidth(102); + root.setHeight(102); + + const root_child0 = Yoga.Node.create(config); + root_child0.setMargin(Edge.Right, 'auto'); + root_child0.setWidth(40); + root.insertChild(root_child0, 0); + + const root_child1 = Yoga.Node.create(config); + root_child1.setWidth(40); + root.insertChild(root_child1, 1); + + const root_child2 = Yoga.Node.create(config); + root_child2.setWidth(40); + 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(102); + expect(root.getComputedHeight()).toBe(102); + + expect(root_child0.getComputedLeft()).toBe(0); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(40); + expect(root_child0.getComputedHeight()).toBe(102); + + expect(root_child1.getComputedLeft()).toBe(40); + expect(root_child1.getComputedTop()).toBe(0); + expect(root_child1.getComputedWidth()).toBe(40); + expect(root_child1.getComputedHeight()).toBe(102); + + expect(root_child2.getComputedLeft()).toBe(80); + expect(root_child2.getComputedTop()).toBe(0); + expect(root_child2.getComputedWidth()).toBe(40); + expect(root_child2.getComputedHeight()).toBe(102); + + root.calculateLayout(undefined, undefined, Direction.RTL); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(102); + expect(root.getComputedHeight()).toBe(102); + + expect(root_child0.getComputedLeft()).toBe(62); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(40); + expect(root_child0.getComputedHeight()).toBe(102); + + expect(root_child1.getComputedLeft()).toBe(22); + expect(root_child1.getComputedTop()).toBe(0); + expect(root_child1.getComputedWidth()).toBe(40); + expect(root_child1.getComputedHeight()).toBe(102); + + expect(root_child2.getComputedLeft()).toBe(-18); + expect(root_child2.getComputedTop()).toBe(0); + expect(root_child2.getComputedWidth()).toBe(40); + expect(root_child2.getComputedHeight()).toBe(102); + } finally { + if (typeof root !== 'undefined') { + root.freeRecursive(); + } + + config.free(); + } +}); diff --git a/javascript/tests/generated/YGMarginTest.test.ts b/javascript/tests/generated/YGMarginTest.test.ts index 3bc2f03e0a..41582fd5f4 100644 --- a/javascript/tests/generated/YGMarginTest.test.ts +++ b/javascript/tests/generated/YGMarginTest.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<<9da31d1df716c208b1ca30837c23f803>> + * @generated SignedSource<<71cadc40efa1ab29b1f7613c79c27d9e>> * generated by gentest/gentest-driver.ts from gentest/fixtures/YGMarginTest.html */ @@ -1897,3 +1897,65 @@ test('margin_auto_left_stretching_child', () => { config.free(); } }); +test('margin_auto_overflowing_container', () => { + const config = Yoga.Config.create(); + let root; + + try { + root = Yoga.Node.create(config); + root.setAlignItems(Align.Center); + root.setPositionType(PositionType.Absolute); + root.setWidth(200); + root.setHeight(200); + + const root_child0 = Yoga.Node.create(config); + root_child0.setMargin(Edge.Bottom, 'auto'); + root_child0.setWidth(50); + root_child0.setHeight(150); + root.insertChild(root_child0, 0); + + const root_child1 = Yoga.Node.create(config); + root_child1.setWidth(50); + root_child1.setHeight(150); + 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(200); + expect(root.getComputedHeight()).toBe(200); + + expect(root_child0.getComputedLeft()).toBe(75); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(50); + expect(root_child0.getComputedHeight()).toBe(150); + + expect(root_child1.getComputedLeft()).toBe(75); + expect(root_child1.getComputedTop()).toBe(150); + expect(root_child1.getComputedWidth()).toBe(50); + expect(root_child1.getComputedHeight()).toBe(150); + + root.calculateLayout(undefined, undefined, Direction.RTL); + + expect(root.getComputedLeft()).toBe(0); + expect(root.getComputedTop()).toBe(0); + expect(root.getComputedWidth()).toBe(200); + expect(root.getComputedHeight()).toBe(200); + + expect(root_child0.getComputedLeft()).toBe(75); + expect(root_child0.getComputedTop()).toBe(0); + expect(root_child0.getComputedWidth()).toBe(50); + expect(root_child0.getComputedHeight()).toBe(150); + + expect(root_child1.getComputedLeft()).toBe(75); + expect(root_child1.getComputedTop()).toBe(150); + expect(root_child1.getComputedWidth()).toBe(50); + expect(root_child1.getComputedHeight()).toBe(150); + } finally { + if (typeof root !== 'undefined') { + root.freeRecursive(); + } + + config.free(); + } +}); diff --git a/tests/generated/YGJustifyContentTest.cpp b/tests/generated/YGJustifyContentTest.cpp index db93eb8027..a02adfc545 100644 --- a/tests/generated/YGJustifyContentTest.cpp +++ b/tests/generated/YGJustifyContentTest.cpp @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. * * clang-format off - * @generated SignedSource<<6fd9f96e80468c69192ce2a29444b734>> + * @generated SignedSource<<144009ebd2ef6685a545b47d7f6ad8cb>> * generated by gentest/gentest-driver.ts from gentest/fixtures/YGJustifyContentTest.html */ @@ -1381,3 +1381,633 @@ TEST(YogaTest, justify_content_flex_end_row_reverse) { YGConfigFree(config); } + +TEST(YogaTest, justify_content_overflow_row_flex_start) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 40); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 40); + 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(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(62, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(-18, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, justify_content_overflow_row_flex_end) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root, YGJustifyFlexEnd); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 40); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 40); + 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(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(-18, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(62, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, justify_content_overflow_row_center) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root, YGJustifyCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 40); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 40); + 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(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(-9, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(31, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(71, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(71, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(31, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(-9, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, justify_content_overflow_row_space_between) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root, YGJustifySpaceBetween); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 40); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 40); + 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(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(62, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(-18, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, justify_content_overflow_row_space_around) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root, YGJustifySpaceAround); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 40); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 40); + 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(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(62, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(-18, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, justify_content_overflow_row_space_evenly) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root, YGJustifySpaceEvenly); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 40); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 40); + 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(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(62, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(-18, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, justify_content_overflow_row_reverse_space_around) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRowReverse); + YGNodeStyleSetJustifyContent(root, YGJustifySpaceAround); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 40); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 40); + 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(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(62, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(-18, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, justify_content_overflow_row_reverse_space_evenly) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRowReverse); + YGNodeStyleSetJustifyContent(root, YGJustifySpaceEvenly); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 40); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 40); + 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(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(62, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(-18, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST(YogaTest, justify_content_overflow_row_space_evenly_auto_margin) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root, YGJustifySpaceEvenly); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 102); + YGNodeStyleSetHeight(root, 102); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeRight); + YGNodeStyleSetWidth(root_child0, 40); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 40); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 40); + 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(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(62, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(22, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(-18, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(102, YGNodeLayoutGetHeight(root_child2)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} diff --git a/tests/generated/YGMarginTest.cpp b/tests/generated/YGMarginTest.cpp index e0f05793ca..2900aec76c 100644 --- a/tests/generated/YGMarginTest.cpp +++ b/tests/generated/YGMarginTest.cpp @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. * * clang-format off - * @generated SignedSource<<52e260344bf94a7d6afb0066b8b9e1b9>> + * @generated SignedSource<<0d39738ffc01ee67f7f2cc6fed49adf8>> * generated by gentest/gentest-driver.ts from gentest/fixtures/YGMarginTest.html */ @@ -1750,3 +1750,61 @@ TEST(YogaTest, margin_auto_left_stretching_child) { YGConfigFree(config); } + +TEST(YogaTest, margin_auto_overflowing_container) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignItems(root, YGAlignCenter); + YGNodeStyleSetPositionType(root, YGPositionTypeAbsolute); + YGNodeStyleSetWidth(root, 200); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetMarginAuto(root_child0, YGEdgeBottom); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 150); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 150); + 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(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(150, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} diff --git a/yoga/algorithm/Align.h b/yoga/algorithm/Align.h index e9ab6df3b7..ac4dfcde91 100644 --- a/yoga/algorithm/Align.h +++ b/yoga/algorithm/Align.h @@ -26,4 +26,47 @@ inline Align resolveChildAlignment( return align; } +/** + * Fallback alignment to use on overflow + * https://www.w3.org/TR/css-align-3/#distribution-values + */ +constexpr Align fallbackAlignment(Align align) { + switch (align) { + // Fallback to flex-start + case Align::SpaceBetween: + case Align::Stretch: + return Align::FlexStart; + + // Fallback to safe center. TODO: This should be aligned to Start + // instead of FlexStart (for row-reverse containers) + case Align::SpaceAround: + case Align::SpaceEvenly: + return Align::FlexStart; + default: + return align; + } +} + +/** + * Fallback alignment to use on overflow + * https://www.w3.org/TR/css-align-3/#distribution-values + */ +constexpr Justify fallbackAlignment(Justify align) { + switch (align) { + // Fallback to flex-start + case Justify::SpaceBetween: + // TODO: Support `justify-content: stretch` + // case Justify::Stretch: + return Justify::FlexStart; + + // Fallback to safe center. TODO: This should be aligned to Start + // instead of FlexStart (for row-reverse containers) + case Justify::SpaceAround: + case Justify::SpaceEvenly: + return Justify::FlexStart; + default: + return align; + } +} + } // namespace facebook::yoga diff --git a/yoga/algorithm/CalculateLayout.cpp b/yoga/algorithm/CalculateLayout.cpp index 62d8a24b76..0d34129ba0 100644 --- a/yoga/algorithm/CalculateLayout.cpp +++ b/yoga/algorithm/CalculateLayout.cpp @@ -959,27 +959,16 @@ static void justifyMainAxis( } } - int numberOfAutoMarginsOnCurrentLine = 0; - for (size_t i = startOfLineIndex; i < flexLine.endOfLineIndex; i++) { - auto child = node->getChild(i); - if (child->style().positionType() != PositionType::Absolute) { - if (child->style().flexStartMarginIsAuto(mainAxis, direction)) { - numberOfAutoMarginsOnCurrentLine++; - } - if (child->style().flexEndMarginIsAuto(mainAxis, direction)) { - numberOfAutoMarginsOnCurrentLine++; - } - } - } - // In order to position the elements in the main axis, we have two controls. // The space between the beginning and the first element and the space between // each two elements. float leadingMainDim = 0; float betweenMainDim = gap; - const Justify justifyContent = node->style().justifyContent(); + const Justify justifyContent = flexLine.layout.remainingFreeSpace >= 0 + ? node->style().justifyContent() + : fallbackAlignment(node->style().justifyContent()); - if (numberOfAutoMarginsOnCurrentLine == 0) { + if (flexLine.numberOfAutoMargins == 0) { switch (justifyContent) { case Justify::Center: leadingMainDim = flexLine.layout.remainingFreeSpace / 2; @@ -989,8 +978,7 @@ static void justifyMainAxis( break; case Justify::SpaceBetween: if (flexLine.itemsInFlow.size() > 1) { - betweenMainDim += - yoga::maxOrDefined(flexLine.layout.remainingFreeSpace, 0.0f) / + betweenMainDim += flexLine.layout.remainingFreeSpace / static_cast(flexLine.itemsInFlow.size() - 1); } break; @@ -1043,9 +1031,10 @@ static void justifyMainAxis( // We need to do that only for relative elements. Absolute elements do not // take part in that phase. if (childStyle.positionType() != PositionType::Absolute) { - if (child->style().flexStartMarginIsAuto(mainAxis, direction)) { + if (child->style().flexStartMarginIsAuto(mainAxis, direction) && + flexLine.layout.remainingFreeSpace > 0.0f) { flexLine.layout.mainDim += flexLine.layout.remainingFreeSpace / - static_cast(numberOfAutoMarginsOnCurrentLine); + static_cast(flexLine.numberOfAutoMargins); } if (performLayout) { @@ -1059,9 +1048,10 @@ static void justifyMainAxis( flexLine.layout.mainDim += betweenMainDim; } - if (child->style().flexEndMarginIsAuto(mainAxis, direction)) { + if (child->style().flexEndMarginIsAuto(mainAxis, direction) && + flexLine.layout.remainingFreeSpace > 0.0f) { flexLine.layout.mainDim += flexLine.layout.remainingFreeSpace / - static_cast(numberOfAutoMarginsOnCurrentLine); + static_cast(flexLine.numberOfAutoMargins); } bool canSkipFlex = !performLayout && sizingModeCrossDim == SizingMode::StretchFit; @@ -1749,27 +1739,11 @@ static void calculateLayoutImpl( const float remainingAlignContentDim = innerCrossDim - totalLineCrossDim; - // Apply fallback alignments on overflow - // https://www.w3.org/TR/css-align-3/#distribution-values - const auto appliedAlignContent = - remainingAlignContentDim >= 0 ? node->style().alignContent() : [&]() { - switch (node->style().alignContent()) { - // Fallback to flex-start - case Align::SpaceBetween: - case Align::Stretch: - return Align::FlexStart; - - // Fallback to safe center. TODO: This should be aligned to Start - // instead of FlexStart (for row-reverse containers) - case Align::SpaceAround: - case Align::SpaceEvenly: - return Align::FlexStart; - default: - return node->style().alignContent(); - } - }(); + const auto alignContent = remainingAlignContentDim >= 0 + ? node->style().alignContent() + : fallbackAlignment(node->style().alignContent()); - switch (appliedAlignContent) { + switch (alignContent) { case Align::FlexEnd: currentLead += remainingAlignContentDim; break; diff --git a/yoga/algorithm/FlexLine.cpp b/yoga/algorithm/FlexLine.cpp index 50cd6f0abe..d3a954caaf 100644 --- a/yoga/algorithm/FlexLine.cpp +++ b/yoga/algorithm/FlexLine.cpp @@ -27,6 +27,7 @@ FlexLine calculateFlexLine( float sizeConsumed = 0.0f; float totalFlexGrowFactors = 0.0f; float totalFlexShrinkScaledFactors = 0.0f; + size_t numberOfAutoMargins = 0; size_t endOfLineIndex = startOfLineIndex; size_t firstElementInLineIndex = startOfLineIndex; @@ -49,6 +50,13 @@ FlexLine calculateFlexLine( continue; } + if (child->style().flexStartMarginIsAuto(mainAxis, ownerDirection)) { + numberOfAutoMargins++; + } + if (child->style().flexEndMarginIsAuto(mainAxis, ownerDirection)) { + numberOfAutoMargins++; + } + const bool isFirstElementInLine = (endOfLineIndex - firstElementInLineIndex) == 0; @@ -102,10 +110,11 @@ FlexLine calculateFlexLine( } return FlexLine{ - std::move(itemsInFlow), - sizeConsumed, - endOfLineIndex, - FlexLineRunningLayout{ + .itemsInFlow = std::move(itemsInFlow), + .sizeConsumed = sizeConsumed, + .endOfLineIndex = endOfLineIndex, + .numberOfAutoMargins = numberOfAutoMargins, + .layout = FlexLineRunningLayout{ totalFlexGrowFactors, totalFlexShrinkScaledFactors, }}; diff --git a/yoga/algorithm/FlexLine.h b/yoga/algorithm/FlexLine.h index 0f888be507..3287cd6cf4 100644 --- a/yoga/algorithm/FlexLine.h +++ b/yoga/algorithm/FlexLine.h @@ -52,6 +52,9 @@ struct FlexLine { // The index of the first item beyond the current line. const size_t endOfLineIndex{0}; + // Number of edges along the line flow with an auto margin. + const size_t numberOfAutoMargins{0}; + // Layout information about the line computed in steps after line-breaking FlexLineRunningLayout layout{}; };