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