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