2 * Copyright (c) 2014-present, Facebook, Inc.
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
8 #include <gtest/gtest.h>
9 #include <yoga/YGNode.h>
11 TEST(YogaTest, dirty_propagation) {
12 const YGNodeRef root = YGNodeNew();
13 YGNodeStyleSetAlignItems(root, YGAlignFlexStart);
14 YGNodeStyleSetWidth(root, 100);
15 YGNodeStyleSetHeight(root, 100);
17 const YGNodeRef root_child0 = YGNodeNew();
18 YGNodeStyleSetWidth(root_child0, 50);
19 YGNodeStyleSetHeight(root_child0, 20);
20 YGNodeInsertChild(root, root_child0, 0);
22 const YGNodeRef root_child1 = YGNodeNew();
23 YGNodeStyleSetWidth(root_child1, 50);
24 YGNodeStyleSetHeight(root_child1, 20);
25 YGNodeInsertChild(root, root_child1, 1);
27 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
29 YGNodeStyleSetWidth(root_child0, 20);
31 EXPECT_TRUE(root_child0->isDirty());
32 EXPECT_FALSE(root_child1->isDirty());
33 EXPECT_TRUE(root->isDirty());
35 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
37 EXPECT_FALSE(root_child0->isDirty());
38 EXPECT_FALSE(root_child1->isDirty());
39 EXPECT_FALSE(root->isDirty());
41 YGNodeFreeRecursive(root);
44 TEST(YogaTest, dirty_propagation_only_if_prop_changed) {
45 const YGNodeRef root = YGNodeNew();
46 YGNodeStyleSetAlignItems(root, YGAlignFlexStart);
47 YGNodeStyleSetWidth(root, 100);
48 YGNodeStyleSetHeight(root, 100);
50 const YGNodeRef root_child0 = YGNodeNew();
51 YGNodeStyleSetWidth(root_child0, 50);
52 YGNodeStyleSetHeight(root_child0, 20);
53 YGNodeInsertChild(root, root_child0, 0);
55 const YGNodeRef root_child1 = YGNodeNew();
56 YGNodeStyleSetWidth(root_child1, 50);
57 YGNodeStyleSetHeight(root_child1, 20);
58 YGNodeInsertChild(root, root_child1, 1);
60 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
62 YGNodeStyleSetWidth(root_child0, 50);
64 EXPECT_FALSE(root_child0->isDirty());
65 EXPECT_FALSE(root_child1->isDirty());
66 EXPECT_FALSE(root->isDirty());
68 YGNodeFreeRecursive(root);
71 TEST(YogaTest, dirty_mark_all_children_as_dirty_when_display_changes) {
72 const YGNodeRef root = YGNodeNew();
73 YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
74 YGNodeStyleSetHeight(root, 100);
76 const YGNodeRef child0 = YGNodeNew();
77 YGNodeStyleSetFlexGrow(child0, 1);
78 const YGNodeRef child1 = YGNodeNew();
79 YGNodeStyleSetFlexGrow(child1, 1);
81 const YGNodeRef child1_child0 = YGNodeNew();
82 const YGNodeRef child1_child0_child0 = YGNodeNew();
83 YGNodeStyleSetWidth(child1_child0_child0, 8);
84 YGNodeStyleSetHeight(child1_child0_child0, 16);
86 YGNodeInsertChild(child1_child0, child1_child0_child0, 0);
88 YGNodeInsertChild(child1, child1_child0, 0);
89 YGNodeInsertChild(root, child0, 0);
90 YGNodeInsertChild(root, child1, 0);
92 YGNodeStyleSetDisplay(child0, YGDisplayFlex);
93 YGNodeStyleSetDisplay(child1, YGDisplayNone);
94 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
95 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(child1_child0_child0));
96 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(child1_child0_child0));
98 YGNodeStyleSetDisplay(child0, YGDisplayNone);
99 YGNodeStyleSetDisplay(child1, YGDisplayFlex);
100 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
101 ASSERT_FLOAT_EQ(8, YGNodeLayoutGetWidth(child1_child0_child0));
102 ASSERT_FLOAT_EQ(16, YGNodeLayoutGetHeight(child1_child0_child0));
104 YGNodeStyleSetDisplay(child0, YGDisplayFlex);
105 YGNodeStyleSetDisplay(child1, YGDisplayNone);
106 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
107 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(child1_child0_child0));
108 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(child1_child0_child0));
110 YGNodeStyleSetDisplay(child0, YGDisplayNone);
111 YGNodeStyleSetDisplay(child1, YGDisplayFlex);
112 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
113 ASSERT_FLOAT_EQ(8, YGNodeLayoutGetWidth(child1_child0_child0));
114 ASSERT_FLOAT_EQ(16, YGNodeLayoutGetHeight(child1_child0_child0));
116 YGNodeFreeRecursive(root);
119 TEST(YogaTest, dirty_node_only_if_children_are_actually_removed) {
120 const YGNodeRef root = YGNodeNew();
121 YGNodeStyleSetAlignItems(root, YGAlignFlexStart);
122 YGNodeStyleSetWidth(root, 50);
123 YGNodeStyleSetHeight(root, 50);
125 const YGNodeRef child0 = YGNodeNew();
126 YGNodeStyleSetWidth(child0, 50);
127 YGNodeStyleSetHeight(child0, 25);
128 YGNodeInsertChild(root, child0, 0);
130 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
132 const YGNodeRef child1 = YGNodeNew();
133 YGNodeRemoveChild(root, child1);
134 EXPECT_FALSE(root->isDirty());
137 YGNodeRemoveChild(root, child0);
138 EXPECT_TRUE(root->isDirty());
141 YGNodeFreeRecursive(root);
144 TEST(YogaTest, dirty_node_only_if_undefined_values_gets_set_to_undefined) {
145 const YGNodeRef root = YGNodeNew();
146 YGNodeStyleSetWidth(root, 50);
147 YGNodeStyleSetHeight(root, 50);
148 YGNodeStyleSetMinWidth(root, YGUndefined);
150 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
152 EXPECT_FALSE(root->isDirty());
154 YGNodeStyleSetMinWidth(root, YGUndefined);
156 EXPECT_FALSE(root->isDirty());
158 YGNodeFreeRecursive(root);