tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 499HTML 238Markdown 7TOML 31234 Definitions

⎇ 69c1fd6e2742ecc2e3b5c16cdafd4439a91dc2df tests/measure.rs Rust · 492 lines · 18.3 KB History Who touched what raw

remove simple error 69c1fd6e2 · Emil Sjölander ·

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