tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

HTML 5544Rust 89Markdown 11TOML 91930 Definitions

⎇ rayon tests/measure.rs Rust · 413 lines · 15.2 KB History Who touched what raw

Call measure function on leaf nodes even if the node does not have context (#598) 563d5dcee · Nico Burns ·

1#[cfg(test)]
2mod measure {
3    use taffy::prelude::*;
4
5    #[derive(Debug, Clone, Copy)]
6    struct FixedMeasure {
7        width: f32,
8        height: f32,
9    }
10    fn fixed_measure_function(
11        known_dimensions: Size<Option<f32>>,
12        _available_space: Size<AvailableSpace>,
13        _node_id: NodeId,
14        node_context: Option<&mut FixedMeasure>,
15    ) -> taffy::geometry::Size<f32> {
16        let size = node_context.copied().unwrap_or(FixedMeasure { width: 0.0, height: 0.0 });
17        Size {
18            width: known_dimensions.width.unwrap_or(size.width),
19            height: known_dimensions.height.unwrap_or(size.height),
20        }
21    }
22
23    struct AspectRatioMeasure {
24        width: f32,
25        height_ratio: f32,
26    }
27    fn aspect_ratio_measure_function(
28        known_dimensions: Size<Option<f32>>,
29        _available_space: Size<AvailableSpace>,
30        _node_id: NodeId,
31        node_context: Option<&mut AspectRatioMeasure>,
32    ) -> taffy::geometry::Size<f32> {
33        let Some(node_context) = node_context else { return Size::ZERO };
34        let width = known_dimensions.width.unwrap_or(node_context.width);
35        let height = known_dimensions.height.unwrap_or(width * node_context.height_ratio);
36        Size { width, height }
37    }
38
39    #[test]
40    fn measure_root() {
41        let mut taffy: TaffyTree<FixedMeasure> = TaffyTree::new();
42        let node = taffy.new_leaf_with_context(Style::default(), FixedMeasure { width: 100.0, height: 100.0 }).unwrap();
43        taffy.compute_layout_with_measure(node, Size::MAX_CONTENT, fixed_measure_function).unwrap();
44
45        assert_eq!(taffy.layout(node).unwrap().size.width, 100.0);
46        assert_eq!(taffy.layout(node).unwrap().size.height, 100.0);
47    }
48
49    #[test]
50    fn measure_child() {
51        let mut taffy: TaffyTree<FixedMeasure> = TaffyTree::new();
52
53        let child =
54            taffy.new_leaf_with_context(Style::default(), FixedMeasure { width: 100.0, height: 100.0 }).unwrap();
55
56        let node = taffy.new_with_children(Style::default(), &[child]).unwrap();
57        taffy.compute_layout_with_measure(node, Size::MAX_CONTENT, fixed_measure_function).unwrap();
58
59        assert_eq!(taffy.layout(node).unwrap().size.width, 100.0);
60        assert_eq!(taffy.layout(node).unwrap().size.height, 100.0);
61
62        assert_eq!(taffy.layout(child).unwrap().size.width, 100.0);
63        assert_eq!(taffy.layout(child).unwrap().size.height, 100.0);
64    }
65
66    #[test]
67    fn measure_child_constraint() {
68        let mut taffy: TaffyTree<FixedMeasure> = TaffyTree::new();
69        let child =
70            taffy.new_leaf_with_context(Style::default(), FixedMeasure { width: 100.0, height: 100.0 }).unwrap();
71
72        let node = taffy
73            .new_with_children(
74                Style { size: Size { width: Dimension::Length(50.0), height: auto() }, ..Default::default() },
75                &[child],
76            )
77            .unwrap();
78
79        taffy.compute_layout_with_measure(node, Size::MAX_CONTENT, fixed_measure_function).unwrap();
80
81        // Parent
82        assert_eq!(taffy.layout(node).unwrap().size.width, 50.0);
83        assert_eq!(taffy.layout(node).unwrap().size.height, 100.0);
84        // Child
85        assert_eq!(taffy.layout(child).unwrap().size.width, 100.0);
86        assert_eq!(taffy.layout(child).unwrap().size.height, 100.0);
87    }
88
89    #[test]
90    fn measure_child_constraint_padding_parent() {
91        let mut taffy: TaffyTree<FixedMeasure> = TaffyTree::new();
92        let child =
93            taffy.new_leaf_with_context(Style::default(), FixedMeasure { width: 100.0, height: 100.0 }).unwrap();
94
95        let node = taffy
96            .new_with_children(
97                Style {
98                    size: Size { width: Dimension::Length(50.0), height: auto() },
99                    padding: Rect {
100                        left: LengthPercentage::Length(10.0),
101                        right: LengthPercentage::Length(10.0),
102                        top: LengthPercentage::Length(10.0),
103                        bottom: LengthPercentage::Length(10.0),
104                    },
105                    ..Default::default()
106                },
107                &[child],
108            )
109            .unwrap();
110        taffy.compute_layout_with_measure(node, Size::MAX_CONTENT, fixed_measure_function).unwrap();
111
112        assert_eq!(taffy.layout(node).unwrap().location.x, 0.0);
113        assert_eq!(taffy.layout(node).unwrap().location.y, 0.0);
114        assert_eq!(taffy.layout(node).unwrap().size.width, 50.0);
115        assert_eq!(taffy.layout(node).unwrap().size.height, 120.0);
116
117        assert_eq!(taffy.layout(child).unwrap().location.x, 10.0);
118        assert_eq!(taffy.layout(child).unwrap().location.y, 10.0);
119        assert_eq!(taffy.layout(child).unwrap().size.width, 100.0);
120        assert_eq!(taffy.layout(child).unwrap().size.height, 100.0);
121    }
122
123    #[test]
124    fn measure_child_with_flex_grow() {
125        let mut taffy: TaffyTree<FixedMeasure> = TaffyTree::new();
126        let child0 = taffy
127            .new_leaf(Style {
128                size: Size { width: Dimension::Length(50.0), height: Dimension::Length(50.0) },
129                ..Default::default()
130            })
131            .unwrap();
132
133        let child1 = taffy
134            .new_leaf_with_context(
135                Style { flex_grow: 1.0, ..Default::default() },
136                FixedMeasure { width: 10.0, height: 50.0 },
137            )
138            .unwrap();
139
140        let node = taffy
141            .new_with_children(
142                Style { size: Size { width: Dimension::Length(100.0), height: auto() }, ..Default::default() },
143                &[child0, child1],
144            )
145            .unwrap();
146
147        taffy.compute_layout_with_measure(node, Size::MAX_CONTENT, fixed_measure_function).unwrap();
148
149        assert_eq!(taffy.layout(child1).unwrap().size.width, 50.0);
150        assert_eq!(taffy.layout(child1).unwrap().size.height, 50.0);
151    }
152
153    #[test]
154    fn measure_child_with_flex_shrink() {
155        let mut taffy: TaffyTree<FixedMeasure> = TaffyTree::new();
156        let child0 = taffy
157            .new_leaf(Style {
158                size: Size { width: Dimension::Length(50.0), height: Dimension::Length(50.0) },
159                flex_shrink: 0.0,
160                ..Default::default()
161            })
162            .unwrap();
163
164        let child1 =
165            taffy.new_leaf_with_context(Style::default(), FixedMeasure { width: 100.0, height: 50.0 }).unwrap();
166
167        let node = taffy
168            .new_with_children(
169                Style { size: Size { width: Dimension::Length(100.0), height: auto() }, ..Default::default() },
170                &[child0, child1],
171            )
172            .unwrap();
173
174        taffy.compute_layout_with_measure(node, Size::MAX_CONTENT, fixed_measure_function).unwrap();
175
176        assert_eq!(taffy.layout(child1).unwrap().size.width, 100.0);
177        assert_eq!(taffy.layout(child1).unwrap().size.height, 50.0);
178    }
179
180    #[test]
181    fn remeasure_child_after_growing() {
182        let mut taffy: TaffyTree<AspectRatioMeasure> = TaffyTree::new();
183        let child0 = taffy
184            .new_leaf(Style {
185                size: Size { width: Dimension::Length(50.0), height: Dimension::Length(50.0) },
186                ..Default::default()
187            })
188            .unwrap();
189
190        let child1 = taffy
191            .new_leaf_with_context(
192                Style { flex_grow: 1.0, ..Default::default() },
193                AspectRatioMeasure { width: 10.0, height_ratio: 2.0 },
194            )
195            .unwrap();
196
197        let node = taffy
198            .new_with_children(
199                Style {
200                    size: Size { width: Dimension::Length(100.0), height: auto() },
201                    align_items: Some(AlignItems::Start),
202                    ..Default::default()
203                },
204                &[child0, child1],
205            )
206            .unwrap();
207
208        taffy.compute_layout_with_measure(node, Size::MAX_CONTENT, aspect_ratio_measure_function).unwrap();
209
210        assert_eq!(taffy.layout(child1).unwrap().size.width, 50.0);
211        assert_eq!(taffy.layout(child1).unwrap().size.height, 100.0);
212    }
213
214    #[test]
215    fn remeasure_child_after_shrinking() {
216        let mut taffy: TaffyTree<AspectRatioMeasure> = TaffyTree::new();
217
218        let child0 = taffy
219            .new_leaf(Style {
220                size: Size { width: Dimension::Length(50.0), height: Dimension::Length(50.0) },
221                flex_shrink: 0.0,
222                ..Default::default()
223            })
224            .unwrap();
225
226        let child1 = taffy
227            .new_leaf_with_context(Style::default(), AspectRatioMeasure { width: 100.0, height_ratio: 2.0 })
228            .unwrap();
229
230        let node = taffy
231            .new_with_children(
232                Style {
233                    size: Size { width: Dimension::Length(100.0), height: auto() },
234                    align_items: Some(AlignItems::Start),
235                    ..Default::default()
236                },
237                &[child0, child1],
238            )
239            .unwrap();
240
241        taffy.compute_layout_with_measure(node, Size::MAX_CONTENT, aspect_ratio_measure_function).unwrap();
242
243        assert_eq!(taffy.layout(child1).unwrap().size.width, 100.0);
244        assert_eq!(taffy.layout(child1).unwrap().size.height, 200.0);
245    }
246
247    #[test]
248    fn remeasure_child_after_stretching() {
249        let mut taffy: TaffyTree<()> = TaffyTree::new();
250
251        fn custom_measure_function(
252            known_dimensions: Size<Option<f32>>,
253            _available_space: Size<AvailableSpace>,
254            _node_id: NodeId,
255            _node_context: Option<&mut ()>,
256        ) -> taffy::geometry::Size<f32> {
257            let height = known_dimensions.height.unwrap_or(50.0);
258            let width = known_dimensions.width.unwrap_or(height);
259            Size { width, height }
260        }
261
262        let child = taffy.new_leaf_with_context(Style::default(), ()).unwrap();
263
264        let node = taffy
265            .new_with_children(
266                Style {
267                    size: Size { width: Dimension::Length(100.0), height: Dimension::Length(100.0) },
268                    ..Default::default()
269                },
270                &[child],
271            )
272            .unwrap();
273
274        taffy.compute_layout_with_measure(node, Size::MAX_CONTENT, custom_measure_function).unwrap();
275
276        assert_eq!(taffy.layout(child).unwrap().size.width, 100.0);
277        assert_eq!(taffy.layout(child).unwrap().size.height, 100.0);
278    }
279
280    #[test]
281    fn width_overrides_measure() {
282        let mut taffy: TaffyTree<FixedMeasure> = TaffyTree::new();
283        let child = taffy
284            .new_leaf_with_context(
285                Style { size: Size { width: Dimension::Length(50.0), height: auto() }, ..Default::default() },
286                FixedMeasure { width: 100.0, height: 100.0 },
287            )
288            .unwrap();
289
290        let node = taffy.new_with_children(Style::default(), &[child]).unwrap();
291        taffy.compute_layout_with_measure(node, Size::MAX_CONTENT, fixed_measure_function).unwrap();
292
293        assert_eq!(taffy.layout(child).unwrap().size.width, 50.0);
294        assert_eq!(taffy.layout(child).unwrap().size.height, 100.0);
295    }
296
297    #[test]
298    fn height_overrides_measure() {
299        let mut taffy: TaffyTree<FixedMeasure> = TaffyTree::new();
300        let child = taffy
301            .new_leaf_with_context(
302                Style { size: Size { width: auto(), height: Dimension::Length(50.0) }, ..Default::default() },
303                FixedMeasure { width: 100.0, height: 100.0 },
304            )
305            .unwrap();
306
307        let node = taffy.new_with_children(Style::default(), &[child]).unwrap();
308        taffy.compute_layout_with_measure(node, Size::MAX_CONTENT, fixed_measure_function).unwrap();
309
310        assert_eq!(taffy.layout(child).unwrap().size.width, 100.0);
311        assert_eq!(taffy.layout(child).unwrap().size.height, 50.0);
312    }
313
314    #[test]
315    fn flex_basis_overrides_measure() {
316        let mut taffy: TaffyTree<FixedMeasure> = TaffyTree::new();
317        let child0 = taffy
318            .new_leaf(Style { flex_basis: Dimension::Length(50.0), flex_grow: 1.0, ..Default::default() })
319            .unwrap();
320
321        let child1 = taffy
322            .new_leaf_with_context(
323                Style { flex_basis: Dimension::Length(50.0), flex_grow: 1.0, ..Default::default() },
324                FixedMeasure { width: 100.0, height: 100.0 },
325            )
326            .unwrap();
327
328        let node = taffy
329            .new_with_children(
330                Style {
331                    size: Size { width: Dimension::Length(200.0), height: Dimension::Length(100.0) },
332                    ..Default::default()
333                },
334                &[child0, child1],
335            )
336            .unwrap();
337
338        taffy.compute_layout_with_measure(node, Size::MAX_CONTENT, fixed_measure_function).unwrap();
339
340        assert_eq!(taffy.layout(child0).unwrap().size.width, 100.0);
341        assert_eq!(taffy.layout(child0).unwrap().size.height, 100.0);
342        assert_eq!(taffy.layout(child1).unwrap().size.width, 100.0);
343        assert_eq!(taffy.layout(child1).unwrap().size.height, 100.0);
344    }
345
346    #[test]
347    fn stretch_overrides_measure() {
348        let mut taffy: TaffyTree<FixedMeasure> = TaffyTree::new();
349        let child = taffy.new_leaf_with_context(Style::default(), FixedMeasure { width: 50.0, height: 50.0 }).unwrap();
350
351        let node = taffy
352            .new_with_children(
353                Style {
354                    size: Size { width: Dimension::Length(100.0), height: Dimension::Length(100.0) },
355                    ..Default::default()
356                },
357                &[child],
358            )
359            .unwrap();
360
361        taffy.compute_layout_with_measure(node, Size::MAX_CONTENT, fixed_measure_function).unwrap();
362
363        assert_eq!(taffy.layout(child).unwrap().size.width, 50.0);
364        assert_eq!(taffy.layout(child).unwrap().size.height, 100.0);
365    }
366
367    #[test]
368    fn measure_absolute_child() {
369        let mut taffy: TaffyTree<FixedMeasure> = TaffyTree::new();
370        let child = taffy
371            .new_leaf_with_context(
372                Style { position: Position::Absolute, ..Default::default() },
373                FixedMeasure { width: 50.0, height: 50.0 },
374            )
375            .unwrap();
376
377        let node = taffy
378            .new_with_children(
379                Style {
380                    size: Size { width: Dimension::Length(100.0), height: Dimension::Length(100.0) },
381                    ..Default::default()
382                },
383                &[child],
384            )
385            .unwrap();
386
387        taffy.compute_layout_with_measure(node, Size::MAX_CONTENT, fixed_measure_function).unwrap();
388
389        assert_eq!(taffy.layout(child).unwrap().size.width, 50.0);
390        assert_eq!(taffy.layout(child).unwrap().size.height, 50.0);
391    }
392
393    #[test]
394    fn ignore_invalid_measure() {
395        let mut taffy: TaffyTree<FixedMeasure> = TaffyTree::new();
396        let child = taffy.new_leaf(Style { flex_grow: 1.0, ..Default::default() }).unwrap();
397
398        let node = taffy
399            .new_with_children(
400                Style {
401                    size: Size { width: Dimension::Length(100.0), height: Dimension::Length(100.0) },
402                    ..Default::default()
403                },
404                &[child],
405            )
406            .unwrap();
407
408        taffy.compute_layout_with_measure(node, Size::MAX_CONTENT, fixed_measure_function).unwrap();
409
410        assert_eq!(taffy.layout(child).unwrap().size.width, 100.0);
411        assert_eq!(taffy.layout(child).unwrap().size.height, 100.0);
412    }
413}