+TEST(MaxContentAspectRatio, no_transfer_from_max_content_axis) {
+ YGConfigRef config = YGConfigNew();
+
+ YGNodeRef root = YGNodeNewWithConfig(config);
+ YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
+ YGNodeStyleSetWidth(root, 300);
+ YGNodeStyleSetHeight(root, 150);
+
+ YGNodeRef root_child0 = YGNodeNewWithConfig(config);
+ YGNodeStyleSetHeightMaxContent(root_child0);
+ YGNodeStyleSetAspectRatio(root_child0, 2.0f);
+ YGNodeInsertChild(root, root_child0, 0);
+
+ YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config);
+ YGNodeStyleSetWidth(root_child0_child0, 10);
+ YGNodeStyleSetHeight(root_child0_child0, 40);
+ YGNodeInsertChild(root_child0, root_child0_child0, 0);
+
+ YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
+
+ ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0));
+
+ YGNodeFreeRecursive(root);
+ YGConfigFree(config);
+}
diff --git a/tests/YGMaxContentRootTest.cpp b/tests/YGMaxContentRootTest.cpp
new file mode 100644
index 0000000000..278f08e20d
--- /dev/null
+++ b/tests/YGMaxContentRootTest.cpp
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+#include
+#include
+
+// TODO: move these to fixture based tests once gentest supports passing an
+// owner size to YGNodeCalculateLayout. With an undefined owner size,
+// max-content on the root is indistinguishable from auto, so only these
+// hand-written tests can pin the root keyword branches.
+
+// Equivalent fixture, laid out with an owner size of 500x500 (the part
+// gentest cannot express):
+//
+//
+//
+//
+//
+//
+TEST(MaxContentRoot, width_max_content_with_definite_owner_size) {
+ YGConfigRef config = YGConfigNew();
+
+ YGNodeRef root = YGNodeNewWithConfig(config);
+ YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
+ YGNodeStyleSetWidthMaxContent(root);
+
+ YGNodeRef root_child0 = YGNodeNewWithConfig(config);
+ YGNodeStyleSetWidth(root_child0, 50);
+ YGNodeStyleSetHeight(root_child0, 50);
+ YGNodeInsertChild(root, root_child0, 0);
+
+ YGNodeRef root_child1 = YGNodeNewWithConfig(config);
+ YGNodeStyleSetWidth(root_child1, 100);
+ YGNodeStyleSetHeight(root_child1, 50);
+ YGNodeInsertChild(root, root_child1, 1);
+
+ YGNodeRef root_child2 = YGNodeNewWithConfig(config);
+ YGNodeStyleSetWidth(root_child2, 25);
+ YGNodeStyleSetHeight(root_child2, 50);
+ YGNodeInsertChild(root, root_child2, 2);
+
+ YGNodeCalculateLayout(root, 500, 500, YGDirectionLTR);
+
+ // The max-content axis measures content instead of filling the owner.
+ ASSERT_FLOAT_EQ(175, YGNodeLayoutGetWidth(root));
+ // The auto axis still fills the owner.
+ ASSERT_FLOAT_EQ(500, YGNodeLayoutGetHeight(root));
+
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
+ ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1));
+ ASSERT_FLOAT_EQ(150, YGNodeLayoutGetLeft(root_child2));
+
+ YGNodeFreeRecursive(root);
+ YGConfigFree(config);
+}
+
+// A numeric max-width clamps the root's max-content size, and the content
+// must lay out (wrap) within the clamped size, not just report it.
+//
+// Equivalent fixture, laid out with an owner size of 500x500:
+//
+//
+//
+//
+//
+TEST(MaxContentRoot, width_max_content_wraps_within_numeric_max_width) {
+ YGConfigRef config = YGConfigNew();
+
+ YGNodeRef root = YGNodeNewWithConfig(config);
+ YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
+ YGNodeStyleSetFlexWrap(root, YGWrapWrap);
+ YGNodeStyleSetWidthMaxContent(root);
+ YGNodeStyleSetMaxWidth(root, 100);
+
+ YGNodeRef root_child0 = YGNodeNewWithConfig(config);
+ YGNodeStyleSetWidth(root_child0, 80);
+ YGNodeStyleSetHeight(root_child0, 10);
+ YGNodeInsertChild(root, root_child0, 0);
+
+ YGNodeRef root_child1 = YGNodeNewWithConfig(config);
+ YGNodeStyleSetWidth(root_child1, 80);
+ YGNodeStyleSetHeight(root_child1, 10);
+ YGNodeInsertChild(root, root_child1, 1);
+
+ YGNodeCalculateLayout(root, 500, 500, YGDirectionLTR);
+
+ ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1));
+ ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child1));
+
+ YGNodeFreeRecursive(root);
+ YGConfigFree(config);
+}
+
+// Percentages inside a max-content root are cyclic: they contribute nothing
+// to the measurement, then resolve against the resolved size — the same
+// two-pass contract the flex-item path guarantees.
+//
+// Equivalent fixture, laid out with an owner size of 500x500:
+//
+//