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>
10 #include <yoga/Yoga.h>
12 static YGSize _measure(YGNodeRef node,
14 YGMeasureMode widthMode,
16 YGMeasureMode heightMode) {
17 int* measureCount = (int*)node->getContext();
23 .width = 10, .height = 10,
27 static YGSize _simulate_wrapping_text(YGNodeRef node,
29 YGMeasureMode widthMode,
31 YGMeasureMode heightMode) {
32 if (widthMode == YGMeasureModeUndefined || width >= 68) {
33 return YGSize{.width = 68, .height = 16};
37 .width = 50, .height = 32,
41 static YGSize _measure_assert_negative(YGNodeRef node,
43 YGMeasureMode widthMode,
45 YGMeasureMode heightMode) {
50 .width = 0, .height = 0,
54 TEST(YogaTest, dont_measure_single_grow_shrink_child) {
55 const YGNodeRef root = YGNodeNew();
56 YGNodeStyleSetWidth(root, 100);
57 YGNodeStyleSetHeight(root, 100);
61 const YGNodeRef root_child0 = YGNodeNew();
62 root_child0->setContext(&measureCount);
63 root_child0->setMeasureFunc(_measure);
64 YGNodeStyleSetFlexGrow(root_child0, 1);
65 YGNodeStyleSetFlexShrink(root_child0, 1);
66 YGNodeInsertChild(root, root_child0, 0);
68 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
70 ASSERT_EQ(0, measureCount);
72 YGNodeFreeRecursive(root);
75 TEST(YogaTest, measure_absolute_child_with_no_constraints) {
76 const YGNodeRef root = YGNodeNew();
78 const YGNodeRef root_child0 = YGNodeNew();
79 YGNodeInsertChild(root, root_child0, 0);
83 const YGNodeRef root_child0_child0 = YGNodeNew();
84 YGNodeStyleSetPositionType(root_child0_child0, YGPositionTypeAbsolute);
85 root_child0_child0->setContext(&measureCount);
86 root_child0_child0->setMeasureFunc(_measure);
87 YGNodeInsertChild(root_child0, root_child0_child0, 0);
89 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
91 ASSERT_EQ(1, measureCount);
93 YGNodeFreeRecursive(root);
96 TEST(YogaTest, dont_measure_when_min_equals_max) {
97 const YGNodeRef root = YGNodeNew();
98 YGNodeStyleSetAlignItems(root, YGAlignFlexStart);
99 YGNodeStyleSetWidth(root, 100);
100 YGNodeStyleSetHeight(root, 100);
102 int measureCount = 0;
104 const YGNodeRef root_child0 = YGNodeNew();
105 root_child0->setContext(&measureCount);
106 root_child0->setMeasureFunc(_measure);
107 YGNodeStyleSetMinWidth(root_child0, 10);
108 YGNodeStyleSetMaxWidth(root_child0, 10);
109 YGNodeStyleSetMinHeight(root_child0, 10);
110 YGNodeStyleSetMaxHeight(root_child0, 10);
111 YGNodeInsertChild(root, root_child0, 0);
113 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
115 ASSERT_EQ(0, measureCount);
116 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
117 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
118 ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0));
119 ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0));
121 YGNodeFreeRecursive(root);
124 TEST(YogaTest, dont_measure_when_min_equals_max_percentages) {
125 const YGNodeRef root = YGNodeNew();
126 YGNodeStyleSetAlignItems(root, YGAlignFlexStart);
127 YGNodeStyleSetWidth(root, 100);
128 YGNodeStyleSetHeight(root, 100);
130 int measureCount = 0;
132 const YGNodeRef root_child0 = YGNodeNew();
133 root_child0->setContext(&measureCount);
134 root_child0->setMeasureFunc(_measure);
135 YGNodeStyleSetMinWidthPercent(root_child0, 10);
136 YGNodeStyleSetMaxWidthPercent(root_child0, 10);
137 YGNodeStyleSetMinHeightPercent(root_child0, 10);
138 YGNodeStyleSetMaxHeightPercent(root_child0, 10);
139 YGNodeInsertChild(root, root_child0, 0);
141 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
143 ASSERT_EQ(0, measureCount);
144 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
145 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
146 ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0));
147 ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0));
149 YGNodeFreeRecursive(root);
153 TEST(YogaTest, measure_nodes_with_margin_auto_and_stretch) {
154 const YGNodeRef root = YGNodeNew();
155 YGNodeStyleSetWidth(root, 500);
156 YGNodeStyleSetHeight(root, 500);
158 const YGNodeRef root_child0 = YGNodeNew();
159 root_child0->setMeasureFunc(_measure);
160 YGNodeStyleSetMarginAuto(root_child0, YGEdgeLeft);
161 YGNodeInsertChild(root, root_child0, 0);
163 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
165 EXPECT_EQ(490, YGNodeLayoutGetLeft(root_child0));
166 EXPECT_EQ(0, YGNodeLayoutGetTop(root_child0));
167 EXPECT_EQ(10, YGNodeLayoutGetWidth(root_child0));
168 EXPECT_EQ(10, YGNodeLayoutGetHeight(root_child0));
170 YGNodeFreeRecursive(root);
173 TEST(YogaTest, dont_measure_when_min_equals_max_mixed_width_percent) {
174 const YGNodeRef root = YGNodeNew();
175 YGNodeStyleSetAlignItems(root, YGAlignFlexStart);
176 YGNodeStyleSetWidth(root, 100);
177 YGNodeStyleSetHeight(root, 100);
179 int measureCount = 0;
181 const YGNodeRef root_child0 = YGNodeNew();
182 root_child0->setContext(&measureCount);
183 root_child0->setMeasureFunc(_measure);
184 YGNodeStyleSetMinWidthPercent(root_child0, 10);
185 YGNodeStyleSetMaxWidthPercent(root_child0, 10);
186 YGNodeStyleSetMinHeight(root_child0, 10);
187 YGNodeStyleSetMaxHeight(root_child0, 10);
188 YGNodeInsertChild(root, root_child0, 0);
190 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
192 ASSERT_EQ(0, measureCount);
193 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
194 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
195 ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0));
196 ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0));
198 YGNodeFreeRecursive(root);
201 TEST(YogaTest, dont_measure_when_min_equals_max_mixed_height_percent) {
202 const YGNodeRef root = YGNodeNew();
203 YGNodeStyleSetAlignItems(root, YGAlignFlexStart);
204 YGNodeStyleSetWidth(root, 100);
205 YGNodeStyleSetHeight(root, 100);
207 int measureCount = 0;
209 const YGNodeRef root_child0 = YGNodeNew();
210 root_child0->setContext(&measureCount);
211 root_child0->setMeasureFunc(_measure);
212 YGNodeStyleSetMinWidth(root_child0, 10);
213 YGNodeStyleSetMaxWidth(root_child0, 10);
214 YGNodeStyleSetMinHeightPercent(root_child0, 10);
215 YGNodeStyleSetMaxHeightPercent(root_child0, 10);
216 YGNodeInsertChild(root, root_child0, 0);
218 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
220 ASSERT_EQ(0, measureCount);
221 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
222 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
223 ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0));
224 ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0));
226 YGNodeFreeRecursive(root);
229 TEST(YogaTest, measure_enough_size_should_be_in_single_line) {
230 const YGNodeRef root = YGNodeNew();
231 YGNodeStyleSetWidth(root, 100);
233 const YGNodeRef root_child0 = YGNodeNew();
234 YGNodeStyleSetAlignSelf(root_child0, YGAlignFlexStart);
235 root_child0->setMeasureFunc(_simulate_wrapping_text);
237 YGNodeInsertChild(root, root_child0, 0);
239 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
241 ASSERT_FLOAT_EQ(68, YGNodeLayoutGetWidth(root_child0));
242 ASSERT_FLOAT_EQ(16, YGNodeLayoutGetHeight(root_child0));
244 YGNodeFreeRecursive(root);
247 TEST(YogaTest, measure_not_enough_size_should_wrap) {
248 const YGNodeRef root = YGNodeNew();
249 YGNodeStyleSetWidth(root, 55);
251 const YGNodeRef root_child0 = YGNodeNew();
252 YGNodeStyleSetAlignSelf(root_child0, YGAlignFlexStart);
253 // YGNodeSetMeasureFunc(root_child0, _simulate_wrapping_text);
254 root_child0->setMeasureFunc(_simulate_wrapping_text);
255 YGNodeInsertChild(root, root_child0, 0);
257 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
259 ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0));
260 ASSERT_FLOAT_EQ(32, YGNodeLayoutGetHeight(root_child0));
262 YGNodeFreeRecursive(root);
265 TEST(YogaTest, measure_zero_space_should_grow) {
266 const YGNodeRef root = YGNodeNew();
267 YGNodeStyleSetHeight(root, 200);
268 YGNodeStyleSetFlexDirection(root, YGFlexDirectionColumn);
269 YGNodeStyleSetFlexGrow(root, 0);
271 int measureCount = 0;
273 const YGNodeRef root_child0 = YGNodeNew();
274 YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionColumn);
275 YGNodeStyleSetPadding(root_child0, YGEdgeAll, 100);
276 root_child0->setContext(&measureCount);
277 root_child0->setMeasureFunc(_measure);
279 YGNodeInsertChild(root, root_child0, 0);
281 YGNodeCalculateLayout(root, 282, YGUndefined, YGDirectionLTR);
283 ASSERT_FLOAT_EQ(282, YGNodeLayoutGetWidth(root_child0));
284 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
286 YGNodeFreeRecursive(root);
289 TEST(YogaTest, measure_flex_direction_row_and_padding) {
290 const YGConfigRef config = YGConfigNew();
292 const YGNodeRef root = YGNodeNewWithConfig(config);
293 YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
294 YGNodeStyleSetPadding(root, YGEdgeLeft, 25);
295 YGNodeStyleSetPadding(root, YGEdgeTop, 25);
296 YGNodeStyleSetPadding(root, YGEdgeRight, 25);
297 YGNodeStyleSetPadding(root, YGEdgeBottom, 25);
298 YGNodeStyleSetWidth(root, 50);
299 YGNodeStyleSetHeight(root, 50);
301 const YGNodeRef root_child0 = YGNodeNewWithConfig(config);
302 root_child0->setMeasureFunc(_simulate_wrapping_text);
303 // YGNodeSetMeasureFunc(root_child0, _simulate_wrapping_text);
304 YGNodeInsertChild(root, root_child0, 0);
306 const YGNodeRef root_child1 = YGNodeNewWithConfig(config);
307 YGNodeStyleSetWidth(root_child1, 5);
308 YGNodeStyleSetHeight(root_child1, 5);
309 YGNodeInsertChild(root, root_child1, 1);
310 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
312 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
313 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
314 ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root));
315 ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root));
317 ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child0));
318 ASSERT_FLOAT_EQ(25, YGNodeLayoutGetTop(root_child0));
319 ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0));
320 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0));
322 ASSERT_FLOAT_EQ(75, YGNodeLayoutGetLeft(root_child1));
323 ASSERT_FLOAT_EQ(25, YGNodeLayoutGetTop(root_child1));
324 ASSERT_FLOAT_EQ(5, YGNodeLayoutGetWidth(root_child1));
325 ASSERT_FLOAT_EQ(5, YGNodeLayoutGetHeight(root_child1));
327 YGNodeFreeRecursive(root);
329 YGConfigFree(config);
332 TEST(YogaTest, measure_flex_direction_column_and_padding) {
333 const YGConfigRef config = YGConfigNew();
335 const YGNodeRef root = YGNodeNewWithConfig(config);
336 YGNodeStyleSetMargin(root, YGEdgeTop, 20);
337 YGNodeStyleSetPadding(root, YGEdgeAll, 25);
338 YGNodeStyleSetWidth(root, 50);
339 YGNodeStyleSetHeight(root, 50);
341 const YGNodeRef root_child0 = YGNodeNewWithConfig(config);
342 root_child0->setMeasureFunc(_simulate_wrapping_text);
343 // YGNodeSetMeasureFunc(root_child0, _simulate_wrapping_text);
344 YGNodeInsertChild(root, root_child0, 0);
346 const YGNodeRef root_child1 = YGNodeNewWithConfig(config);
347 YGNodeStyleSetWidth(root_child1, 5);
348 YGNodeStyleSetHeight(root_child1, 5);
349 YGNodeInsertChild(root, root_child1, 1);
350 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
352 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
353 ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root));
354 ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root));
355 ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root));
357 ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child0));
358 ASSERT_FLOAT_EQ(25, YGNodeLayoutGetTop(root_child0));
359 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0));
360 ASSERT_FLOAT_EQ(32, YGNodeLayoutGetHeight(root_child0));
362 ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1));
363 ASSERT_FLOAT_EQ(57, YGNodeLayoutGetTop(root_child1));
364 ASSERT_FLOAT_EQ(5, YGNodeLayoutGetWidth(root_child1));
365 ASSERT_FLOAT_EQ(5, YGNodeLayoutGetHeight(root_child1));
367 YGNodeFreeRecursive(root);
369 YGConfigFree(config);
372 TEST(YogaTest, measure_flex_direction_row_no_padding) {
373 const YGConfigRef config = YGConfigNew();
375 const YGNodeRef root = YGNodeNewWithConfig(config);
376 YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
377 YGNodeStyleSetMargin(root, YGEdgeTop, 20);
378 YGNodeStyleSetWidth(root, 50);
379 YGNodeStyleSetHeight(root, 50);
381 const YGNodeRef root_child0 = YGNodeNewWithConfig(config);
382 // YGNodeSetMeasureFunc(root_child0, _simulate_wrapping_text);
383 root_child0->setMeasureFunc(_simulate_wrapping_text);
384 YGNodeInsertChild(root, root_child0, 0);
386 const YGNodeRef root_child1 = YGNodeNewWithConfig(config);
387 YGNodeStyleSetWidth(root_child1, 5);
388 YGNodeStyleSetHeight(root_child1, 5);
389 YGNodeInsertChild(root, root_child1, 1);
390 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
392 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
393 ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root));
394 ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root));
395 ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root));
397 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
398 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
399 ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0));
400 ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0));
402 ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1));
403 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1));
404 ASSERT_FLOAT_EQ(5, YGNodeLayoutGetWidth(root_child1));
405 ASSERT_FLOAT_EQ(5, YGNodeLayoutGetHeight(root_child1));
407 YGNodeFreeRecursive(root);
409 YGConfigFree(config);
412 TEST(YogaTest, measure_flex_direction_row_no_padding_align_items_flexstart) {
413 const YGConfigRef config = YGConfigNew();
415 const YGNodeRef root = YGNodeNewWithConfig(config);
416 YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
417 YGNodeStyleSetMargin(root, YGEdgeTop, 20);
418 YGNodeStyleSetWidth(root, 50);
419 YGNodeStyleSetHeight(root, 50);
420 YGNodeStyleSetAlignItems(root, YGAlignFlexStart);
422 const YGNodeRef root_child0 = YGNodeNewWithConfig(config);
423 root_child0->setMeasureFunc(_simulate_wrapping_text);
424 YGNodeInsertChild(root, root_child0, 0);
426 const YGNodeRef root_child1 = YGNodeNewWithConfig(config);
427 YGNodeStyleSetWidth(root_child1, 5);
428 YGNodeStyleSetHeight(root_child1, 5);
429 YGNodeInsertChild(root, root_child1, 1);
430 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
432 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
433 ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root));
434 ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root));
435 ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root));
437 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
438 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
439 ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0));
440 ASSERT_FLOAT_EQ(32, YGNodeLayoutGetHeight(root_child0));
442 ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1));
443 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1));
444 ASSERT_FLOAT_EQ(5, YGNodeLayoutGetWidth(root_child1));
445 ASSERT_FLOAT_EQ(5, YGNodeLayoutGetHeight(root_child1));
447 YGNodeFreeRecursive(root);
449 YGConfigFree(config);
452 TEST(YogaTest, measure_with_fixed_size) {
453 const YGConfigRef config = YGConfigNew();
455 const YGNodeRef root = YGNodeNewWithConfig(config);
456 YGNodeStyleSetMargin(root, YGEdgeTop, 20);
457 YGNodeStyleSetPadding(root, YGEdgeAll, 25);
458 YGNodeStyleSetWidth(root, 50);
459 YGNodeStyleSetHeight(root, 50);
461 const YGNodeRef root_child0 = YGNodeNewWithConfig(config);
462 root_child0->setMeasureFunc(_simulate_wrapping_text);
463 YGNodeStyleSetWidth(root_child0, 10);
464 YGNodeStyleSetHeight(root_child0, 10);
465 YGNodeInsertChild(root, root_child0, 0);
467 const YGNodeRef root_child1 = YGNodeNewWithConfig(config);
468 YGNodeStyleSetWidth(root_child1, 5);
469 YGNodeStyleSetHeight(root_child1, 5);
470 YGNodeInsertChild(root, root_child1, 1);
471 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
473 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
474 ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root));
475 ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root));
476 ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root));
478 ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child0));
479 ASSERT_FLOAT_EQ(25, YGNodeLayoutGetTop(root_child0));
480 ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0));
481 ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0));
483 ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1));
484 ASSERT_FLOAT_EQ(35, YGNodeLayoutGetTop(root_child1));
485 ASSERT_FLOAT_EQ(5, YGNodeLayoutGetWidth(root_child1));
486 ASSERT_FLOAT_EQ(5, YGNodeLayoutGetHeight(root_child1));
488 YGNodeFreeRecursive(root);
490 YGConfigFree(config);
493 TEST(YogaTest, measure_with_flex_shrink) {
494 const YGConfigRef config = YGConfigNew();
496 const YGNodeRef root = YGNodeNewWithConfig(config);
497 YGNodeStyleSetMargin(root, YGEdgeTop, 20);
498 YGNodeStyleSetPadding(root, YGEdgeAll, 25);
499 YGNodeStyleSetWidth(root, 50);
500 YGNodeStyleSetHeight(root, 50);
502 const YGNodeRef root_child0 = YGNodeNewWithConfig(config);
503 root_child0->setMeasureFunc(_simulate_wrapping_text);
504 YGNodeStyleSetFlexShrink(root_child0, 1);
505 YGNodeInsertChild(root, root_child0, 0);
507 const YGNodeRef root_child1 = YGNodeNewWithConfig(config);
508 YGNodeStyleSetWidth(root_child1, 5);
509 YGNodeStyleSetHeight(root_child1, 5);
510 YGNodeInsertChild(root, root_child1, 1);
511 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
513 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
514 ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root));
515 ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root));
516 ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root));
518 ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child0));
519 ASSERT_FLOAT_EQ(25, YGNodeLayoutGetTop(root_child0));
520 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0));
521 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0));
523 ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1));
524 ASSERT_FLOAT_EQ(25, YGNodeLayoutGetTop(root_child1));
525 ASSERT_FLOAT_EQ(5, YGNodeLayoutGetWidth(root_child1));
526 ASSERT_FLOAT_EQ(5, YGNodeLayoutGetHeight(root_child1));
528 YGNodeFreeRecursive(root);
530 YGConfigFree(config);
533 TEST(YogaTest, measure_no_padding) {
534 const YGConfigRef config = YGConfigNew();
536 const YGNodeRef root = YGNodeNewWithConfig(config);
537 YGNodeStyleSetMargin(root, YGEdgeTop, 20);
538 YGNodeStyleSetWidth(root, 50);
539 YGNodeStyleSetHeight(root, 50);
541 const YGNodeRef root_child0 = YGNodeNewWithConfig(config);
542 root_child0->setMeasureFunc(_simulate_wrapping_text);
543 YGNodeStyleSetFlexShrink(root_child0, 1);
544 YGNodeInsertChild(root, root_child0, 0);
546 const YGNodeRef root_child1 = YGNodeNewWithConfig(config);
547 YGNodeStyleSetWidth(root_child1, 5);
548 YGNodeStyleSetHeight(root_child1, 5);
549 YGNodeInsertChild(root, root_child1, 1);
550 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
552 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
553 ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root));
554 ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root));
555 ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root));
557 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
558 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
559 ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0));
560 ASSERT_FLOAT_EQ(32, YGNodeLayoutGetHeight(root_child0));
562 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1));
563 ASSERT_FLOAT_EQ(32, YGNodeLayoutGetTop(root_child1));
564 ASSERT_FLOAT_EQ(5, YGNodeLayoutGetWidth(root_child1));
565 ASSERT_FLOAT_EQ(5, YGNodeLayoutGetHeight(root_child1));
567 YGNodeFreeRecursive(root);
569 YGConfigFree(config);
572 #if GTEST_HAS_DEATH_TEST
573 TEST(YogaDeathTest, cannot_add_child_to_node_with_measure_func) {
574 const YGNodeRef root = YGNodeNew();
575 root->setMeasureFunc(_measure);
577 const YGNodeRef root_child0 = YGNodeNew();
578 ASSERT_DEATH(YGNodeInsertChild(root, root_child0, 0), "Cannot add child.*");
579 YGNodeFree(root_child0);
580 YGNodeFreeRecursive(root);
583 TEST(YogaDeathTest, cannot_add_nonnull_measure_func_to_non_leaf_node) {
584 const YGNodeRef root = YGNodeNew();
585 const YGNodeRef root_child0 = YGNodeNew();
586 YGNodeInsertChild(root, root_child0, 0);
587 ASSERT_DEATH(root->setMeasureFunc(_measure), "Cannot set measure function.*");
588 YGNodeFreeRecursive(root);
593 TEST(YogaTest, can_nullify_measure_func_on_any_node) {
594 const YGNodeRef root = YGNodeNew();
595 YGNodeInsertChild(root, YGNodeNew(), 0);
596 root->setMeasureFunc(nullptr);
597 ASSERT_TRUE(root->getMeasure() == NULL);
598 YGNodeFreeRecursive(root);
601 TEST(YogaTest, cant_call_negative_measure) {
602 const YGConfigRef config = YGConfigNew();
604 const YGNodeRef root = YGNodeNewWithConfig(config);
605 YGNodeStyleSetFlexDirection(root, YGFlexDirectionColumn);
606 YGNodeStyleSetWidth(root, 50);
607 YGNodeStyleSetHeight(root, 10);
609 const YGNodeRef root_child0 = YGNodeNewWithConfig(config);
610 root_child0->setMeasureFunc(_measure_assert_negative);
611 YGNodeStyleSetMargin(root_child0, YGEdgeTop, 20);
612 YGNodeInsertChild(root, root_child0, 0);
614 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
616 YGNodeFreeRecursive(root);
617 YGConfigFree(config);
620 TEST(YogaTest, cant_call_negative_measure_horizontal) {
621 const YGConfigRef config = YGConfigNew();
623 const YGNodeRef root = YGNodeNewWithConfig(config);
624 YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
625 YGNodeStyleSetWidth(root, 10);
626 YGNodeStyleSetHeight(root, 20);
628 const YGNodeRef root_child0 = YGNodeNewWithConfig(config);
629 root_child0->setMeasureFunc(_measure_assert_negative);
630 YGNodeStyleSetMargin(root_child0, YGEdgeStart, 20);
631 YGNodeInsertChild(root, root_child0, 0);
633 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
635 YGNodeFreeRecursive(root);
636 YGConfigFree(config);
639 static YGSize _measure_90_10(YGNodeRef node,
641 YGMeasureMode widthMode,
643 YGMeasureMode heightMode) {
646 .width = 90, .height = 10,
650 TEST(YogaTest, percent_with_text_node) {
651 const YGConfigRef config = YGConfigNew();
653 const YGNodeRef root = YGNodeNewWithConfig(config);
654 YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
655 YGNodeStyleSetJustifyContent(root, YGJustifySpaceBetween);
656 YGNodeStyleSetAlignItems(root, YGAlignCenter);
657 YGNodeStyleSetWidth(root, 100);
658 YGNodeStyleSetHeight(root, 80);
660 const YGNodeRef root_child0 = YGNodeNewWithConfig(config);
661 YGNodeInsertChild(root, root_child0, 0);
663 const YGNodeRef root_child1 = YGNodeNewWithConfig(config);
664 root_child1->setMeasureFunc(_measure_90_10);
665 YGNodeStyleSetMaxWidthPercent(root_child1, 50);
666 YGNodeStyleSetPaddingPercent(root_child1, YGEdgeTop, 50);
667 YGNodeInsertChild(root, root_child1, 1);
669 YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
671 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
672 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
673 ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root));
674 ASSERT_FLOAT_EQ(80, YGNodeLayoutGetHeight(root));
676 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
677 ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child0));
678 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0));
679 ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0));
681 ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1));
682 ASSERT_FLOAT_EQ(15, YGNodeLayoutGetTop(root_child1));
683 ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1));
684 ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1));
686 YGNodeFreeRecursive(root);
688 YGConfigFree(config);