1#[cfg(test)]
2mod measure {
3 use taffy::node::MeasureFunc;
4 use taffy::number::OrElse;
5
6 #[test]
7 fn measure_root() {
8 let mut taffy = taffy::node::Taffy::new();
9 let node = taffy
10 .new_leaf(
11 taffy::style::Style { ..Default::default() },
12 MeasureFunc::Raw(|constraint| taffy::geometry::Size {
13 width: constraint.width.or_else(100.0),
14 height: constraint.height.or_else(100.0),
15 }),
16 )
17 .unwrap();
18
19 taffy.compute_layout(node, taffy::geometry::Size::undefined()).unwrap();
20
21 assert_eq!(taffy.layout(node).unwrap().size.width, 100.0);
22 assert_eq!(taffy.layout(node).unwrap().size.height, 100.0);
23 }
24
25 #[test]
26 fn measure_child() {
27 let mut taffy = taffy::node::Taffy::new();
28
29 let child = taffy
30 .new_leaf(
31 taffy::style::Style { ..Default::default() },
32 MeasureFunc::Raw(|constraint| taffy::geometry::Size {
33 width: constraint.width.or_else(100.0),
34 height: constraint.height.or_else(100.0),
35 }),
36 )
37 .unwrap();
38
39 let node = taffy.new_node(taffy::style::Style { ..Default::default() }, &[child]).unwrap();
40 taffy.compute_layout(node, taffy::geometry::Size::undefined()).unwrap();
41
42 assert_eq!(taffy.layout(node).unwrap().size.width, 100.0);
43 assert_eq!(taffy.layout(node).unwrap().size.height, 100.0);
44
45 assert_eq!(taffy.layout(child).unwrap().size.width, 100.0);
46 assert_eq!(taffy.layout(child).unwrap().size.height, 100.0);
47 }
48
49 #[test]
50 fn measure_child_constraint() {
51 let mut taffy = taffy::node::Taffy::new();
52 let child = taffy
53 .new_leaf(
54 taffy::style::Style { ..Default::default() },
55 MeasureFunc::Raw(|constraint| taffy::geometry::Size {
56 width: constraint.width.or_else(100.0),
57 height: constraint.height.or_else(100.0),
58 }),
59 )
60 .unwrap();
61
62 let node = taffy
63 .new_node(
64 taffy::style::Style {
65 size: taffy::geometry::Size { width: taffy::style::Dimension::Points(50.0), ..Default::default() },
66 ..Default::default()
67 },
68 &[child],
69 )
70 .unwrap();
71
72 taffy.compute_layout(node, taffy::geometry::Size::undefined()).unwrap();
73
74 assert_eq!(taffy.layout(node).unwrap().size.width, 50.0);
75 assert_eq!(taffy.layout(node).unwrap().size.height, 100.0);
76
77 assert_eq!(taffy.layout(child).unwrap().size.width, 50.0);
78 assert_eq!(taffy.layout(child).unwrap().size.height, 100.0);
79 }
80
81 #[test]
82 fn measure_child_constraint_padding_parent() {
83 let mut taffy = taffy::node::Taffy::new();
84 let child = taffy
85 .new_leaf(
86 taffy::style::Style { ..Default::default() },
87 MeasureFunc::Raw(|constraint| taffy::geometry::Size {
88 width: constraint.width.or_else(100.0),
89 height: constraint.height.or_else(100.0),
90 }),
91 )
92 .unwrap();
93
94 let node = taffy
95 .new_node(
96 taffy::style::Style {
97 size: taffy::geometry::Size { width: taffy::style::Dimension::Points(50.0), ..Default::default() },
98 padding: taffy::geometry::Rect {
99 start: taffy::style::Dimension::Points(10.0),
100 end: taffy::style::Dimension::Points(10.0),
101 top: taffy::style::Dimension::Points(10.0),
102 bottom: taffy::style::Dimension::Points(10.0),
103 },
104 ..Default::default()
105 },
106 &[child],
107 )
108 .unwrap();
109 taffy.compute_layout(node, taffy::geometry::Size::undefined()).unwrap();
110
111 assert_eq!(taffy.layout(node).unwrap().size.width, 50.0);
112 assert_eq!(taffy.layout(node).unwrap().size.height, 120.0);
113
114 assert_eq!(taffy.layout(child).unwrap().size.width, 30.0);
115 assert_eq!(taffy.layout(child).unwrap().size.height, 100.0);
116 }
117
118 #[test]
119 fn measure_child_with_flex_grow() {
120 let mut taffy = taffy::node::Taffy::new();
121 let child0 = taffy
122 .new_node(
123 taffy::style::Style {
124 size: taffy::geometry::Size {
125 width: taffy::style::Dimension::Points(50.0),
126 height: taffy::style::Dimension::Points(50.0),
127 },
128 ..Default::default()
129 },
130 &[],
131 )
132 .unwrap();
133
134 let child1 = taffy
135 .new_leaf(
136 taffy::style::Style { flex_grow: 1.0, ..Default::default() },
137 MeasureFunc::Raw(|constraint| taffy::geometry::Size {
138 width: constraint.width.or_else(10.0),
139 height: constraint.height.or_else(50.0),
140 }),
141 )
142 .unwrap();
143
144 let node = taffy
145 .new_node(
146 taffy::style::Style {
147 size: taffy::geometry::Size { width: taffy::style::Dimension::Points(100.0), ..Default::default() },
148 ..Default::default()
149 },
150 &[child0, child1],
151 )
152 .unwrap();
153
154 taffy.compute_layout(node, taffy::geometry::Size::undefined()).unwrap();
155
156 assert_eq!(taffy.layout(child1).unwrap().size.width, 50.0);
157 assert_eq!(taffy.layout(child1).unwrap().size.height, 50.0);
158 }
159
160 #[test]
161 fn measure_child_with_flex_shrink() {
162 let mut taffy = taffy::node::Taffy::new();
163 let child0 = taffy
164 .new_node(
165 taffy::style::Style {
166 size: taffy::geometry::Size {
167 width: taffy::style::Dimension::Points(50.0),
168 height: taffy::style::Dimension::Points(50.0),
169 },
170 flex_shrink: 0.0,
171 ..Default::default()
172 },
173 &[],
174 )
175 .unwrap();
176
177 let child1 = taffy
178 .new_leaf(
179 taffy::style::Style { ..Default::default() },
180 MeasureFunc::Raw(|constraint| taffy::geometry::Size {
181 width: constraint.width.or_else(100.0),
182 height: constraint.height.or_else(50.0),
183 }),
184 )
185 .unwrap();
186
187 let node = taffy
188 .new_node(
189 taffy::style::Style {
190 size: taffy::geometry::Size { width: taffy::style::Dimension::Points(100.0), ..Default::default() },
191 ..Default::default()
192 },
193 &[child0, child1],
194 )
195 .unwrap();
196
197 taffy.compute_layout(node, taffy::geometry::Size::undefined()).unwrap();
198
199 assert_eq!(taffy.layout(child1).unwrap().size.width, 50.0);
200 assert_eq!(taffy.layout(child1).unwrap().size.height, 50.0);
201 }
202
203 #[test]
204 fn remeasure_child_after_growing() {
205 let mut taffy = taffy::node::Taffy::new();
206 let child0 = taffy
207 .new_node(
208 taffy::style::Style {
209 size: taffy::geometry::Size {
210 width: taffy::style::Dimension::Points(50.0),
211 height: taffy::style::Dimension::Points(50.0),
212 },
213 ..Default::default()
214 },
215 &[],
216 )
217 .unwrap();
218
219 let child1 = taffy
220 .new_leaf(
221 taffy::style::Style { flex_grow: 1.0, ..Default::default() },
222 MeasureFunc::Raw(|constraint| {
223 let width = constraint.width.or_else(10.0);
224 let height = constraint.height.or_else(width * 2.0);
225 taffy::geometry::Size { width, height }
226 }),
227 )
228 .unwrap();
229
230 let node = taffy
231 .new_node(
232 taffy::style::Style {
233 size: taffy::geometry::Size { width: taffy::style::Dimension::Points(100.0), ..Default::default() },
234 align_items: taffy::style::AlignItems::FlexStart,
235 ..Default::default()
236 },
237 &[child0, child1],
238 )
239 .unwrap();
240
241 taffy.compute_layout(node, taffy::geometry::Size::undefined()).unwrap();
242
243 assert_eq!(taffy.layout(child1).unwrap().size.width, 50.0);
244 assert_eq!(taffy.layout(child1).unwrap().size.height, 100.0);
245 }
246
247 #[test]
248 fn remeasure_child_after_shrinking() {
249 let mut taffy = taffy::node::Taffy::new();
250
251 let child0 = taffy
252 .new_node(
253 taffy::style::Style {
254 size: taffy::geometry::Size {
255 width: taffy::style::Dimension::Points(50.0),
256 height: taffy::style::Dimension::Points(50.0),
257 },
258 flex_shrink: 0.0,
259 ..Default::default()
260 },
261 &[],
262 )
263 .unwrap();
264
265 let child1 = taffy
266 .new_leaf(
267 taffy::style::Style { ..Default::default() },
268 MeasureFunc::Raw(|constraint| {
269 let width = constraint.width.or_else(100.0);
270 let height = constraint.height.or_else(width * 2.0);
271 taffy::geometry::Size { width, height }
272 }),
273 )
274 .unwrap();
275
276 let node = taffy
277 .new_node(
278 taffy::style::Style {
279 size: taffy::geometry::Size { width: taffy::style::Dimension::Points(100.0), ..Default::default() },
280 align_items: taffy::style::AlignItems::FlexStart,
281 ..Default::default()
282 },
283 &[child0, child1],
284 )
285 .unwrap();
286
287 taffy.compute_layout(node, taffy::geometry::Size::undefined()).unwrap();
288
289 assert_eq!(taffy.layout(child1).unwrap().size.width, 50.0);
290 assert_eq!(taffy.layout(child1).unwrap().size.height, 100.0);
291 }
292
293 #[test]
294 fn remeasure_child_after_stretching() {
295 let mut taffy = taffy::node::Taffy::new();
296
297 let child = taffy
298 .new_leaf(
299 taffy::style::Style { ..Default::default() },
300 MeasureFunc::Raw(|constraint| {
301 let height = constraint.height.or_else(50.0);
302 let width = constraint.width.or_else(height);
303 taffy::geometry::Size { width, height }
304 }),
305 )
306 .unwrap();
307
308 let node = taffy
309 .new_node(
310 taffy::style::Style {
311 size: taffy::geometry::Size {
312 width: taffy::style::Dimension::Points(100.0),
313 height: taffy::style::Dimension::Points(100.0),
314 },
315 ..Default::default()
316 },
317 &[child],
318 )
319 .unwrap();
320
321 taffy.compute_layout(node, taffy::geometry::Size::undefined()).unwrap();
322
323 assert_eq!(taffy.layout(child).unwrap().size.width, 100.0);
324 assert_eq!(taffy.layout(child).unwrap().size.height, 100.0);
325 }
326
327 #[test]
328 fn width_overrides_measure() {
329 let mut taffy = taffy::node::Taffy::new();
330 let child = taffy
331 .new_leaf(
332 taffy::style::Style {
333 size: taffy::geometry::Size { width: taffy::style::Dimension::Points(50.0), ..Default::default() },
334 ..Default::default()
335 },
336 MeasureFunc::Raw(|constraint| taffy::geometry::Size {
337 width: constraint.width.or_else(100.0),
338 height: constraint.height.or_else(100.0),
339 }),
340 )
341 .unwrap();
342
343 let node = taffy.new_node(taffy::style::Style { ..Default::default() }, &[child]).unwrap();
344 taffy.compute_layout(node, taffy::geometry::Size::undefined()).unwrap();
345
346 assert_eq!(taffy.layout(child).unwrap().size.width, 50.0);
347 assert_eq!(taffy.layout(child).unwrap().size.height, 100.0);
348 }
349
350 #[test]
351 fn height_overrides_measure() {
352 let mut taffy = taffy::node::Taffy::new();
353 let child = taffy
354 .new_leaf(
355 taffy::style::Style {
356 size: taffy::geometry::Size { height: taffy::style::Dimension::Points(50.0), ..Default::default() },
357 ..Default::default()
358 },
359 MeasureFunc::Raw(|constraint| taffy::geometry::Size {
360 width: constraint.width.or_else(100.0),
361 height: constraint.height.or_else(100.0),
362 }),
363 )
364 .unwrap();
365
366 let node = taffy.new_node(taffy::style::Style { ..Default::default() }, &[child]).unwrap();
367 taffy.compute_layout(node, taffy::geometry::Size::undefined()).unwrap();
368
369 assert_eq!(taffy.layout(child).unwrap().size.width, 100.0);
370 assert_eq!(taffy.layout(child).unwrap().size.height, 50.0);
371 }
372
373 #[test]
374 fn flex_basis_overrides_measure() {
375 let mut taffy = taffy::node::Taffy::new();
376 let child0 = taffy
377 .new_node(
378 taffy::style::Style {
379 flex_basis: taffy::style::Dimension::Points(50.0),
380 flex_grow: 1.0,
381 ..Default::default()
382 },
383 &[],
384 )
385 .unwrap();
386
387 let child1 = taffy
388 .new_leaf(
389 taffy::style::Style {
390 flex_basis: taffy::style::Dimension::Points(50.0),
391 flex_grow: 1.0,
392 ..Default::default()
393 },
394 MeasureFunc::Raw(|constraint| taffy::geometry::Size {
395 width: constraint.width.or_else(100.0),
396 height: constraint.height.or_else(100.0),
397 }),
398 )
399 .unwrap();
400
401 let node = taffy
402 .new_node(
403 taffy::style::Style {
404 size: taffy::geometry::Size {
405 width: taffy::style::Dimension::Points(200.0),
406 height: taffy::style::Dimension::Points(100.0),
407 },
408 ..Default::default()
409 },
410 &[child0, child1],
411 )
412 .unwrap();
413
414 taffy.compute_layout(node, taffy::geometry::Size::undefined()).unwrap();
415
416 assert_eq!(taffy.layout(child0).unwrap().size.width, 100.0);
417 assert_eq!(taffy.layout(child0).unwrap().size.height, 100.0);
418 assert_eq!(taffy.layout(child1).unwrap().size.width, 100.0);
419 assert_eq!(taffy.layout(child1).unwrap().size.height, 100.0);
420 }
421
422 #[test]
423 fn stretch_overrides_measure() {
424 let mut taffy = taffy::node::Taffy::new();
425 let child = taffy
426 .new_leaf(
427 taffy::style::Style { ..Default::default() },
428 MeasureFunc::Raw(|constraint| taffy::geometry::Size {
429 width: constraint.width.or_else(50.0),
430 height: constraint.height.or_else(50.0),
431 }),
432 )
433 .unwrap();
434
435 let node = taffy
436 .new_node(
437 taffy::style::Style {
438 size: taffy::geometry::Size {
439 width: taffy::style::Dimension::Points(100.0),
440 height: taffy::style::Dimension::Points(100.0),
441 },
442 ..Default::default()
443 },
444 &[child],
445 )
446 .unwrap();
447
448 taffy.compute_layout(node, taffy::geometry::Size::undefined()).unwrap();
449
450 assert_eq!(taffy.layout(child).unwrap().size.width, 50.0);
451 assert_eq!(taffy.layout(child).unwrap().size.height, 100.0);
452 }
453
454 #[test]
455 fn measure_absolute_child() {
456 let mut taffy = taffy::node::Taffy::new();
457 let child = taffy
458 .new_leaf(
459 taffy::style::Style { position_type: taffy::style::PositionType::Absolute, ..Default::default() },
460 MeasureFunc::Raw(|constraint| taffy::geometry::Size {
461 width: constraint.width.or_else(50.0),
462 height: constraint.height.or_else(50.0),
463 }),
464 )
465 .unwrap();
466
467 let node = taffy
468 .new_node(
469 taffy::style::Style {
470 size: taffy::geometry::Size {
471 width: taffy::style::Dimension::Points(100.0),
472 height: taffy::style::Dimension::Points(100.0),
473 },
474 ..Default::default()
475 },
476 &[child],
477 )
478 .unwrap();
479
480 taffy.compute_layout(node, taffy::geometry::Size::undefined()).unwrap();
481
482 assert_eq!(taffy.layout(child).unwrap().size.width, 50.0);
483 assert_eq!(taffy.layout(child).unwrap().size.height, 50.0);
484 }
485
486 #[test]
487 fn ignore_invalid_measure() {
488 let mut taffy = taffy::node::Taffy::new();
489 let child = taffy
490 .new_leaf(
491 taffy::style::Style { flex_grow: 1.0, ..Default::default() },
492 MeasureFunc::Raw(|_| taffy::geometry::Size { width: 200.0, height: 200.0 }),
493 )
494 .unwrap();
495
496 let node = taffy
497 .new_node(
498 taffy::style::Style {
499 size: taffy::geometry::Size {
500 width: taffy::style::Dimension::Points(100.0),
501 height: taffy::style::Dimension::Points(100.0),
502 },
503 ..Default::default()
504 },
505 &[child],
506 )
507 .unwrap();
508
509 taffy.compute_layout(node, taffy::geometry::Size::undefined()).unwrap();
510
511 assert_eq!(taffy.layout(child).unwrap().size.width, 100.0);
512 assert_eq!(taffy.layout(child).unwrap().size.height, 100.0);
513 }
514
515 #[test]
516 fn only_measure_once() {
517 use std::sync::atomic;
518
519 let mut taffy = taffy::node::Taffy::new();
520 static NUM_MEASURES: atomic::AtomicU32 = atomic::AtomicU32::new(0);
521
522 let grandchild = taffy
523 .new_leaf(
524 taffy::style::Style { ..Default::default() },
525 MeasureFunc::Raw(|constraint| {
526 NUM_MEASURES.fetch_add(1, atomic::Ordering::Relaxed);
527 taffy::geometry::Size {
528 width: constraint.width.or_else(50.0),
529 height: constraint.height.or_else(50.0),
530 }
531 }),
532 )
533 .unwrap();
534
535 let child = taffy.new_node(taffy::style::Style { ..Default::default() }, &[grandchild]).unwrap();
536
537 let node = taffy.new_node(taffy::style::Style { ..Default::default() }, &[child]).unwrap();
538 taffy.compute_layout(node, taffy::geometry::Size::undefined()).unwrap();
539
540 assert_eq!(NUM_MEASURES.load(atomic::Ordering::Relaxed), 2);
541 }
542}