gioser

tawasuyu/taffy

A high performance rust-powered UI layout library

HTML 5364Rust 86Markdown 12TOML 91841 Sutichaykuna

⎇ 09c7a718b2eaee87aa9d0505d5a98bd1d33a32db tests/measure.rs Rust · 416 siq'ikuna · 15.3 KB Ñawpa willay Pi imata llamkarqan ch'uya

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