tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

HTML 5364Rust 86Markdown 12TOML 91822 Definitions

⎇ c2db86dfc600067c6f4d70c8ea398cbcc5d42dbd tests/relayout.rs Rust · 393 lines · 13.4 KB History Who touched what raw

Fix rounding accumulation bug (#521) b2a38dafc · Nico Burns ·

1use taffy::prelude::*;
2
3#[test]
4fn relayout() {
5    let mut taffy = taffy::Taffy::new();
6    let node1 = taffy
7        .new_leaf(taffy::style::Style {
8            size: taffy::geometry::Size { width: points(8.0), height: points(80.0) },
9            ..Default::default()
10        })
11        .unwrap();
12    let node0 = taffy
13        .new_with_children(
14            taffy::style::Style {
15                align_self: Some(taffy::prelude::AlignSelf::Center),
16                size: taffy::geometry::Size { width: Dimension::Auto, height: Dimension::Auto },
17                // size: taffy::geometry::Size { width: Dimension::Percent(1.0), height: Dimension::Percent(1.0) },
18                ..Default::default()
19            },
20            &[node1],
21        )
22        .unwrap();
23    let node = taffy
24        .new_with_children(
25            taffy::style::Style {
26                size: taffy::geometry::Size { width: Dimension::Percent(1f32), height: Dimension::Percent(1f32) },
27                ..Default::default()
28            },
29            &[node0],
30        )
31        .unwrap();
32    println!("0:");
33    taffy
34        .compute_layout(
35            node,
36            taffy::geometry::Size { width: AvailableSpace::Definite(100f32), height: AvailableSpace::Definite(100f32) },
37        )
38        .unwrap();
39    let initial = taffy.layout(node).unwrap().location;
40    let initial0 = taffy.layout(node0).unwrap().location;
41    let initial1 = taffy.layout(node1).unwrap().location;
42    for i in 1..10 {
43        println!("\n\n{i}:");
44        taffy
45            .compute_layout(
46                node,
47                taffy::geometry::Size {
48                    width: AvailableSpace::Definite(100f32),
49                    height: AvailableSpace::Definite(100f32),
50                },
51            )
52            .unwrap();
53        assert_eq!(taffy.layout(node).unwrap().location, initial);
54        assert_eq!(taffy.layout(node0).unwrap().location, initial0);
55        assert_eq!(taffy.layout(node1).unwrap().location, initial1);
56    }
57}
58
59#[test]
60fn toggle_root_display_none() {
61    let hidden_style = Style {
62        display: Display::None,
63        size: Size { width: points(100.0), height: points(100.0) },
64        ..Default::default()
65    };
66
67    let flex_style = Style {
68        display: Display::Flex,
69        size: Size { width: points(100.0), height: points(100.0) },
70        ..Default::default()
71    };
72
73    // Setup
74    let mut taffy = taffy::Taffy::new();
75    let node = taffy.new_leaf(hidden_style.clone()).unwrap();
76
77    // Layout 1 (None)
78    taffy.compute_layout(node, Size::MAX_CONTENT).unwrap();
79    let layout = taffy.layout(node).unwrap();
80    assert_eq!(layout.location.x, 0.0);
81    assert_eq!(layout.location.y, 0.0);
82    assert_eq!(layout.size.width, 0.0);
83    assert_eq!(layout.size.height, 0.0);
84
85    // Layout 2 (Flex)
86    taffy.set_style(node, flex_style).unwrap();
87    taffy.compute_layout(node, Size::MAX_CONTENT).unwrap();
88    let layout = taffy.layout(node).unwrap();
89    assert_eq!(layout.location.x, 0.0);
90    assert_eq!(layout.location.y, 0.0);
91    assert_eq!(layout.size.width, 100.0);
92    assert_eq!(layout.size.height, 100.0);
93
94    // Layout 3 (None)
95    taffy.set_style(node, hidden_style).unwrap();
96    taffy.compute_layout(node, Size::MAX_CONTENT).unwrap();
97    let layout = taffy.layout(node).unwrap();
98    assert_eq!(layout.location.x, 0.0);
99    assert_eq!(layout.location.y, 0.0);
100    assert_eq!(layout.size.width, 0.0);
101    assert_eq!(layout.size.height, 0.0);
102}
103
104#[test]
105fn toggle_root_display_none_with_children() {
106    use taffy::prelude::*;
107
108    let mut taffy = taffy::Taffy::new();
109
110    let child = taffy
111        .new_leaf(Style { size: Size { width: points(800.0), height: points(100.0) }, ..Default::default() })
112        .unwrap();
113
114    let parent = taffy
115        .new_with_children(
116            Style { size: Size { width: points(800.0), height: points(100.0) }, ..Default::default() },
117            &[child],
118        )
119        .unwrap();
120
121    let root = taffy.new_with_children(Style::default(), &[parent]).unwrap();
122    taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
123    assert_eq!(taffy.layout(child).unwrap().size.width, 800.0);
124    assert_eq!(taffy.layout(child).unwrap().size.height, 100.0);
125
126    taffy.set_style(root, Style { display: Display::None, ..Default::default() }).unwrap();
127    taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
128    assert_eq!(taffy.layout(child).unwrap().size.width, 0.0);
129    assert_eq!(taffy.layout(child).unwrap().size.height, 0.0);
130
131    taffy.set_style(root, Style::default()).unwrap();
132    taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
133    assert_eq!(taffy.layout(parent).unwrap().size.width, 800.0);
134    assert_eq!(taffy.layout(parent).unwrap().size.height, 100.0);
135    assert_eq!(taffy.layout(child).unwrap().size.width, 800.0);
136    assert_eq!(taffy.layout(child).unwrap().size.height, 100.0);
137}
138
139#[test]
140fn toggle_flex_child_display_none() {
141    let hidden_style = Style {
142        display: Display::None,
143        size: Size { width: points(100.0), height: points(100.0) },
144        ..Default::default()
145    };
146
147    let flex_style = Style {
148        display: Display::Flex,
149        size: Size { width: points(100.0), height: points(100.0) },
150        ..Default::default()
151    };
152
153    // Setup
154    let mut taffy = taffy::Taffy::new();
155    let node = taffy.new_leaf(hidden_style.clone()).unwrap();
156    let root = taffy.new_with_children(flex_style.clone(), &[node]).unwrap();
157
158    // Layout 1 (None)
159    taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
160    let layout = taffy.layout(node).unwrap();
161    assert_eq!(layout.location.x, 0.0);
162    assert_eq!(layout.location.y, 0.0);
163    assert_eq!(layout.size.width, 0.0);
164    assert_eq!(layout.size.height, 0.0);
165
166    // Layout 2 (Flex)
167    taffy.set_style(node, flex_style).unwrap();
168    taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
169    let layout = taffy.layout(node).unwrap();
170    assert_eq!(layout.location.x, 0.0);
171    assert_eq!(layout.location.y, 0.0);
172    assert_eq!(layout.size.width, 100.0);
173    assert_eq!(layout.size.height, 100.0);
174
175    // Layout 3 (None)
176    taffy.set_style(node, hidden_style).unwrap();
177    taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
178    let layout = taffy.layout(node).unwrap();
179    assert_eq!(layout.location.x, 0.0);
180    assert_eq!(layout.location.y, 0.0);
181    assert_eq!(layout.size.width, 0.0);
182    assert_eq!(layout.size.height, 0.0);
183}
184
185#[test]
186fn toggle_flex_container_display_none() {
187    let hidden_style = Style {
188        display: Display::None,
189        size: Size { width: points(100.0), height: points(100.0) },
190        ..Default::default()
191    };
192
193    let flex_style = Style {
194        display: Display::Flex,
195        size: Size { width: points(100.0), height: points(100.0) },
196        ..Default::default()
197    };
198
199    // Setup
200    let mut taffy = taffy::Taffy::new();
201    let node = taffy.new_leaf(hidden_style.clone()).unwrap();
202    let root = taffy.new_with_children(hidden_style.clone(), &[node]).unwrap();
203
204    // Layout 1 (None)
205    taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
206    let layout = taffy.layout(root).unwrap();
207    assert_eq!(layout.location.x, 0.0);
208    assert_eq!(layout.location.y, 0.0);
209    assert_eq!(layout.size.width, 0.0);
210    assert_eq!(layout.size.height, 0.0);
211
212    // Layout 2 (Flex)
213    taffy.set_style(root, flex_style).unwrap();
214    taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
215    let layout = taffy.layout(root).unwrap();
216    assert_eq!(layout.location.x, 0.0);
217    assert_eq!(layout.location.y, 0.0);
218    assert_eq!(layout.size.width, 100.0);
219    assert_eq!(layout.size.height, 100.0);
220
221    // Layout 3 (None)
222    taffy.set_style(root, hidden_style).unwrap();
223    taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
224    let layout = taffy.layout(root).unwrap();
225    assert_eq!(layout.location.x, 0.0);
226    assert_eq!(layout.location.y, 0.0);
227    assert_eq!(layout.size.width, 0.0);
228    assert_eq!(layout.size.height, 0.0);
229}
230
231#[test]
232fn toggle_grid_child_display_none() {
233    let hidden_style = Style {
234        display: Display::None,
235        size: Size { width: points(100.0), height: points(100.0) },
236        ..Default::default()
237    };
238
239    let grid_style = Style {
240        display: Display::Grid,
241        size: Size { width: points(100.0), height: points(100.0) },
242        ..Default::default()
243    };
244
245    // Setup
246    let mut taffy = taffy::Taffy::new();
247    let node = taffy.new_leaf(hidden_style.clone()).unwrap();
248    let root = taffy.new_with_children(grid_style.clone(), &[node]).unwrap();
249
250    // Layout 1 (None)
251    taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
252    let layout = taffy.layout(node).unwrap();
253    assert_eq!(layout.location.x, 0.0);
254    assert_eq!(layout.location.y, 0.0);
255    assert_eq!(layout.size.width, 0.0);
256    assert_eq!(layout.size.height, 0.0);
257
258    // Layout 2 (Flex)
259    taffy.set_style(node, grid_style).unwrap();
260    taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
261    let layout = taffy.layout(node).unwrap();
262    assert_eq!(layout.location.x, 0.0);
263    assert_eq!(layout.location.y, 0.0);
264    assert_eq!(layout.size.width, 100.0);
265    assert_eq!(layout.size.height, 100.0);
266
267    // Layout 3 (None)
268    taffy.set_style(node, hidden_style).unwrap();
269    taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
270    let layout = taffy.layout(node).unwrap();
271    assert_eq!(layout.location.x, 0.0);
272    assert_eq!(layout.location.y, 0.0);
273    assert_eq!(layout.size.width, 0.0);
274    assert_eq!(layout.size.height, 0.0);
275}
276
277#[test]
278fn toggle_grid_container_display_none() {
279    let hidden_style = Style {
280        display: Display::None,
281        size: Size { width: points(100.0), height: points(100.0) },
282        ..Default::default()
283    };
284
285    let grid_style = Style {
286        display: Display::Grid,
287        size: Size { width: points(100.0), height: points(100.0) },
288        ..Default::default()
289    };
290
291    // Setup
292    let mut taffy = taffy::Taffy::new();
293    let node = taffy.new_leaf(hidden_style.clone()).unwrap();
294    let root = taffy.new_with_children(hidden_style.clone(), &[node]).unwrap();
295
296    // Layout 1 (None)
297    taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
298    let layout = taffy.layout(root).unwrap();
299    assert_eq!(layout.location.x, 0.0);
300    assert_eq!(layout.location.y, 0.0);
301    assert_eq!(layout.size.width, 0.0);
302    assert_eq!(layout.size.height, 0.0);
303
304    // Layout 2 (Flex)
305    taffy.set_style(root, grid_style).unwrap();
306    taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
307    let layout = taffy.layout(root).unwrap();
308    assert_eq!(layout.location.x, 0.0);
309    assert_eq!(layout.location.y, 0.0);
310    assert_eq!(layout.size.width, 100.0);
311    assert_eq!(layout.size.height, 100.0);
312
313    // Layout 3 (None)
314    taffy.set_style(root, hidden_style).unwrap();
315    taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
316    let layout = taffy.layout(root).unwrap();
317    assert_eq!(layout.location.x, 0.0);
318    assert_eq!(layout.location.y, 0.0);
319    assert_eq!(layout.size.width, 0.0);
320    assert_eq!(layout.size.height, 0.0);
321}
322
323#[test]
324fn relayout_is_stable_with_rounding() {
325    let mut taffy = Taffy::new();
326    taffy.enable_rounding();
327
328    // <div style="width: 1920px; height: 1080px">
329    //     <div style="width: 100%; left: 1.5px">
330    //         <div style="width: 150px; justify-content: end">
331    //             <div style="min-width: 300px" />
332    //         </div>
333    //     </div>
334    // </div>
335
336    let inner =
337        taffy.new_leaf(Style { min_size: Size { width: points(300.), height: auto() }, ..Default::default() }).unwrap();
338    let wrapper = taffy
339        .new_with_children(
340            Style {
341                size: Size { width: points(150.), height: auto() },
342                justify_content: Some(JustifyContent::End),
343                ..Default::default()
344            },
345            &[inner],
346        )
347        .unwrap();
348    let outer = taffy
349        .new_with_children(
350            Style {
351                size: Size { width: percent(1.), height: auto() },
352                inset: Rect { left: points(1.5), right: auto(), top: auto(), bottom: auto() },
353                ..Default::default()
354            },
355            &[wrapper],
356        )
357        .unwrap();
358    let root = taffy
359        .new_with_children(
360            Style { size: Size { width: points(1920.), height: points(1080.) }, ..Default::default() },
361            &[outer],
362        )
363        .unwrap();
364    for _ in 0..5 {
365        taffy.mark_dirty(root).ok();
366        taffy.compute_layout(root, Size::MAX_CONTENT).ok();
367        taffy::debug::print_tree(&taffy, root);
368
369        let root_layout = taffy.layout(root).unwrap();
370        assert_eq!(root_layout.location.x, 0.0);
371        assert_eq!(root_layout.location.y, 0.0);
372        assert_eq!(root_layout.size.width, 1920.0);
373        assert_eq!(root_layout.size.height, 1080.0);
374
375        let outer_layout = taffy.layout(outer).unwrap();
376        assert_eq!(outer_layout.location.x, 2.0);
377        assert_eq!(outer_layout.location.y, 0.0);
378        assert_eq!(outer_layout.size.width, 1920.0);
379        assert_eq!(outer_layout.size.height, 1080.0);
380
381        let wrapper_layout = taffy.layout(wrapper).unwrap();
382        assert_eq!(wrapper_layout.location.x, 0.0);
383        assert_eq!(wrapper_layout.location.y, 0.0);
384        assert_eq!(wrapper_layout.size.width, 150.0);
385        assert_eq!(wrapper_layout.size.height, 1080.0);
386
387        let inner_layout = taffy.layout(inner).unwrap();
388        assert_eq!(inner_layout.location.x, -150.0);
389        assert_eq!(inner_layout.location.y, 0.0);
390        assert_eq!(inner_layout.size.width, 301.0);
391        assert_eq!(inner_layout.size.height, 1080.0);
392    }
393}