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 // @Generated by gentest/gentest.rb from gentest/fixtures/YGPercentageTest.html
10 #include <gtest/gtest.h>
11 #include <yoga/Yoga.h>
13 TEST(YogaTest, cloning_shared_root) {
14 const YGConfigRef config = YGConfigNew();
16 const YGNodeRef root = YGNodeNewWithConfig(config);
17 YGNodeStyleSetWidth(root, 100);
18 YGNodeStyleSetHeight(root, 100);
20 const YGNodeRef root_child0 = YGNodeNewWithConfig(config);
21 YGNodeStyleSetFlexGrow(root_child0, 1);
22 YGNodeStyleSetFlexBasis(root_child0, 50);
23 YGNodeInsertChild(root, root_child0, 0);
25 const YGNodeRef root_child1 = YGNodeNewWithConfig(config);
26 YGNodeStyleSetFlexGrow(root_child1, 1);
27 YGNodeInsertChild(root, root_child1, 1);
28 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
30 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
31 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
32 ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root));
33 ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root));
35 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
36 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
37 ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0));
38 ASSERT_FLOAT_EQ(75, YGNodeLayoutGetHeight(root_child0));
40 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1));
41 ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child1));
42 ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1));
43 ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1));
45 const YGNodeRef root2 = YGNodeClone(root);
46 YGNodeStyleSetWidth(root2, 100);
48 ASSERT_EQ(2, YGNodeGetChildCount(root2));
49 // The children should have referential equality at this point.
50 ASSERT_EQ(root_child0, YGNodeGetChild(root2, 0));
51 ASSERT_EQ(root_child1, YGNodeGetChild(root2, 1));
53 YGNodeCalculateLayout(root2, YGUndefined, YGUndefined, YGDirectionLTR);
55 ASSERT_EQ(2, YGNodeGetChildCount(root2));
56 // Relayout with no changed input should result in referential equality.
57 ASSERT_EQ(root_child0, YGNodeGetChild(root2, 0));
58 ASSERT_EQ(root_child1, YGNodeGetChild(root2, 1));
60 YGNodeStyleSetWidth(root2, 150);
61 YGNodeStyleSetHeight(root2, 200);
62 YGNodeCalculateLayout(root2, YGUndefined, YGUndefined, YGDirectionLTR);
64 ASSERT_EQ(2, YGNodeGetChildCount(root2));
65 // Relayout with changed input should result in cloned children.
66 const YGNodeRef root2_child0 = YGNodeGetChild(root2, 0);
67 const YGNodeRef root2_child1 = YGNodeGetChild(root2, 1);
68 ASSERT_NE(root_child0, root2_child0);
69 ASSERT_NE(root_child1, root2_child1);
71 // Everything in the root should remain unchanged.
72 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
73 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
74 ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root));
75 ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root));
77 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
78 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
79 ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0));
80 ASSERT_FLOAT_EQ(75, YGNodeLayoutGetHeight(root_child0));
82 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1));
83 ASSERT_FLOAT_EQ(75, YGNodeLayoutGetTop(root_child1));
84 ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child1));
85 ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1));
87 // The new root now has new layout.
88 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root2));
89 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root2));
90 ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root2));
91 ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root2));
93 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root2_child0));
94 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root2_child0));
95 ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root2_child0));
96 ASSERT_FLOAT_EQ(125, YGNodeLayoutGetHeight(root2_child0));
98 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root2_child1));
99 ASSERT_FLOAT_EQ(125, YGNodeLayoutGetTop(root2_child1));
100 ASSERT_FLOAT_EQ(150, YGNodeLayoutGetWidth(root2_child1));
101 ASSERT_FLOAT_EQ(75, YGNodeLayoutGetHeight(root2_child1));
103 YGNodeFreeRecursive(root2);
105 YGNodeFreeRecursive(root);
107 YGConfigFree(config);
110 TEST(YogaTest, mutating_children_of_a_clone_clones) {
111 const YGConfigRef config = YGConfigNew();
113 const YGNodeRef root = YGNodeNewWithConfig(config);
114 ASSERT_EQ(0, YGNodeGetChildCount(root));
116 const YGNodeRef root2 = YGNodeClone(root);
117 ASSERT_EQ(0, YGNodeGetChildCount(root2));
119 const YGNodeRef root2_child0 = YGNodeNewWithConfig(config);
120 YGNodeInsertChild(root2, root2_child0, 0);
122 ASSERT_EQ(0, YGNodeGetChildCount(root));
123 ASSERT_EQ(1, YGNodeGetChildCount(root2));
125 const YGNodeRef root3 = YGNodeClone(root2);
126 ASSERT_EQ(1, YGNodeGetChildCount(root2));
127 ASSERT_EQ(1, YGNodeGetChildCount(root3));
128 ASSERT_EQ(YGNodeGetChild(root2, 0), YGNodeGetChild(root3, 0));
130 const YGNodeRef root3_child1 = YGNodeNewWithConfig(config);
131 YGNodeInsertChild(root3, root3_child1, 1);
132 ASSERT_EQ(1, YGNodeGetChildCount(root2));
133 ASSERT_EQ(2, YGNodeGetChildCount(root3));
134 ASSERT_EQ(root3_child1, YGNodeGetChild(root3, 1));
135 ASSERT_NE(YGNodeGetChild(root2, 0), YGNodeGetChild(root3, 0));
137 const YGNodeRef root4 = YGNodeClone(root3);
138 ASSERT_EQ(root3_child1, YGNodeGetChild(root4, 1));
140 YGNodeRemoveChild(root4, root3_child1);
141 ASSERT_EQ(2, YGNodeGetChildCount(root3));
142 ASSERT_EQ(1, YGNodeGetChildCount(root4));
143 ASSERT_NE(YGNodeGetChild(root3, 0), YGNodeGetChild(root4, 0));
145 YGNodeFreeRecursive(root4);
146 YGNodeFreeRecursive(root3);
147 YGNodeFreeRecursive(root2);
148 YGNodeFreeRecursive(root);
150 YGConfigFree(config);
153 TEST(YogaTest, cloning_two_levels) {
154 const YGConfigRef config = YGConfigNew();
156 const YGNodeRef root = YGNodeNewWithConfig(config);
157 YGNodeStyleSetWidth(root, 100);
158 YGNodeStyleSetHeight(root, 100);
160 const YGNodeRef root_child0 = YGNodeNewWithConfig(config);
161 YGNodeStyleSetFlexGrow(root_child0, 1);
162 YGNodeStyleSetFlexBasis(root_child0, 15);
163 YGNodeInsertChild(root, root_child0, 0);
165 const YGNodeRef root_child1 = YGNodeNewWithConfig(config);
166 YGNodeStyleSetFlexGrow(root_child1, 1);
167 YGNodeInsertChild(root, root_child1, 1);
169 const YGNodeRef root_child1_0 = YGNodeNewWithConfig(config);
170 YGNodeStyleSetFlexBasis(root_child1_0, 10);
171 YGNodeStyleSetFlexGrow(root_child1_0, 1);
172 YGNodeInsertChild(root_child1, root_child1_0, 0);
174 const YGNodeRef root_child1_1 = YGNodeNewWithConfig(config);
175 YGNodeStyleSetFlexBasis(root_child1_1, 25);
176 YGNodeInsertChild(root_child1, root_child1_1, 1);
178 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
180 ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0));
181 ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child1));
182 ASSERT_FLOAT_EQ(35, YGNodeLayoutGetHeight(root_child1_0));
183 ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1_1));
185 const YGNodeRef root2_child0 = YGNodeClone(root_child0);
186 const YGNodeRef root2_child1 = YGNodeClone(root_child1);
187 const YGNodeRef root2 = YGNodeClone(root);
189 YGNodeStyleSetFlexGrow(root2_child0, 0);
190 YGNodeStyleSetFlexBasis(root2_child0, 40);
192 YGNodeRemoveAllChildren(root2);
193 YGNodeInsertChild(root2, root2_child0, 0);
194 YGNodeInsertChild(root2, root2_child1, 1);
195 ASSERT_EQ(2, YGNodeGetChildCount(root2));
197 YGNodeCalculateLayout(root2, YGUndefined, YGUndefined, YGDirectionLTR);
199 // Original root is unchanged
200 ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root_child0));
201 ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child1));
202 ASSERT_FLOAT_EQ(35, YGNodeLayoutGetHeight(root_child1_0));
203 ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1_1));
205 // New root has new layout at the top
206 ASSERT_FLOAT_EQ(40, YGNodeLayoutGetHeight(root2_child0));
207 ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root2_child1));
209 // The deeper children are untouched.
210 ASSERT_EQ(YGNodeGetChild(root2_child1, 0), root_child1_0);
211 ASSERT_EQ(YGNodeGetChild(root2_child1, 1), root_child1_1);
213 YGNodeFreeRecursive(root2);
214 YGNodeFreeRecursive(root);
216 YGConfigFree(config);
219 TEST(YogaTest, cloning_and_freeing) {
220 const int32_t initialInstanceCount = YGNodeGetInstanceCount();
222 const YGConfigRef config = YGConfigNew();
224 const YGNodeRef root = YGNodeNewWithConfig(config);
225 YGNodeStyleSetWidth(root, 100);
226 YGNodeStyleSetHeight(root, 100);
227 const YGNodeRef root_child0 = YGNodeNewWithConfig(config);
228 YGNodeInsertChild(root, root_child0, 0);
229 const YGNodeRef root_child1 = YGNodeNewWithConfig(config);
230 YGNodeInsertChild(root, root_child1, 1);
232 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
234 const YGNodeRef root2 = YGNodeClone(root);
236 // Freeing the original root should be safe as long as we don't free its
240 YGNodeCalculateLayout(root2, YGUndefined, YGUndefined, YGDirectionLTR);
242 YGNodeFreeRecursive(root2);
244 YGNodeFree(root_child0);
245 YGNodeFree(root_child1);
247 YGConfigFree(config);
249 ASSERT_EQ(initialInstanceCount, YGNodeGetInstanceCount());