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