presentar_widgets/
row.rs

1//! Row widget for horizontal layout.
2
3use presentar_core::{
4    widget::{Brick, BrickAssertion, BrickBudget, BrickVerification, LayoutResult},
5    Canvas, Constraints, Event, Rect, Size, TypeId, Widget,
6};
7use serde::{Deserialize, Serialize};
8use std::any::Any;
9use std::time::Duration;
10
11/// Horizontal alignment options.
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
13pub enum MainAxisAlignment {
14    /// Pack children at the start
15    #[default]
16    Start,
17    /// Pack children at the end
18    End,
19    /// Center children
20    Center,
21    /// Distribute space evenly between children
22    SpaceBetween,
23    /// Distribute space evenly around children
24    SpaceAround,
25    /// Distribute space evenly, including edges
26    SpaceEvenly,
27}
28
29/// Vertical alignment options for row children.
30#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
31pub enum CrossAxisAlignment {
32    /// Align to the start (top)
33    Start,
34    /// Align to the end (bottom)
35    End,
36    /// Center vertically
37    #[default]
38    Center,
39    /// Stretch to fill
40    Stretch,
41}
42
43/// Row widget for horizontal layout of children.
44#[derive(Serialize, Deserialize)]
45pub struct Row {
46    /// Main axis (horizontal) alignment
47    main_axis_alignment: MainAxisAlignment,
48    /// Cross axis (vertical) alignment
49    cross_axis_alignment: CrossAxisAlignment,
50    /// Gap between children
51    gap: f32,
52    /// Children widgets
53    #[serde(skip)]
54    children: Vec<Box<dyn Widget>>,
55    /// Test ID
56    test_id_value: Option<String>,
57    /// Cached bounds
58    #[serde(skip)]
59    bounds: Rect,
60    /// Cached child positions
61    #[serde(skip)]
62    child_bounds: Vec<Rect>,
63}
64
65impl Default for Row {
66    fn default() -> Self {
67        Self::new()
68    }
69}
70
71impl Row {
72    /// Create a new empty row.
73    #[must_use]
74    pub fn new() -> Self {
75        Self {
76            main_axis_alignment: MainAxisAlignment::Start,
77            cross_axis_alignment: CrossAxisAlignment::Center,
78            gap: 0.0,
79            children: Vec::new(),
80            test_id_value: None,
81            bounds: Rect::default(),
82            child_bounds: Vec::new(),
83        }
84    }
85
86    /// Set main axis alignment.
87    #[must_use]
88    pub const fn main_axis_alignment(mut self, alignment: MainAxisAlignment) -> Self {
89        self.main_axis_alignment = alignment;
90        self
91    }
92
93    /// Set cross axis alignment.
94    #[must_use]
95    pub const fn cross_axis_alignment(mut self, alignment: CrossAxisAlignment) -> Self {
96        self.cross_axis_alignment = alignment;
97        self
98    }
99
100    /// Set gap between children.
101    #[must_use]
102    pub const fn gap(mut self, gap: f32) -> Self {
103        self.gap = gap;
104        self
105    }
106
107    /// Add a child widget.
108    pub fn child(mut self, widget: impl Widget + 'static) -> Self {
109        self.children.push(Box::new(widget));
110        self
111    }
112
113    /// Set test ID.
114    #[must_use]
115    pub fn with_test_id(mut self, id: impl Into<String>) -> Self {
116        self.test_id_value = Some(id.into());
117        self
118    }
119}
120
121impl Widget for Row {
122    fn type_id(&self) -> TypeId {
123        TypeId::of::<Self>()
124    }
125
126    fn measure(&self, constraints: Constraints) -> Size {
127        if self.children.is_empty() {
128            return Size::ZERO;
129        }
130
131        let mut total_width = 0.0f32;
132        let mut max_height = 0.0f32;
133
134        // Measure all children
135        for (i, child) in self.children.iter().enumerate() {
136            let child_constraints = Constraints::new(
137                0.0,
138                (constraints.max_width - total_width).max(0.0),
139                0.0,
140                constraints.max_height,
141            );
142
143            let child_size = child.measure(child_constraints);
144            total_width += child_size.width;
145            max_height = max_height.max(child_size.height);
146
147            if i < self.children.len() - 1 {
148                total_width += self.gap;
149            }
150        }
151
152        constraints.constrain(Size::new(total_width, max_height))
153    }
154
155    fn layout(&mut self, bounds: Rect) -> LayoutResult {
156        self.bounds = bounds;
157        self.child_bounds.clear();
158
159        if self.children.is_empty() {
160            return LayoutResult { size: Size::ZERO };
161        }
162
163        // First pass: measure children
164        let mut child_sizes: Vec<Size> = Vec::with_capacity(self.children.len());
165        let mut total_width = 0.0f32;
166
167        for child in &self.children {
168            let child_constraints = Constraints::loose(bounds.size());
169            let size = child.measure(child_constraints);
170            total_width += size.width;
171            child_sizes.push(size);
172        }
173
174        let gaps_width = self.gap * (self.children.len() - 1).max(0) as f32;
175        let content_width = total_width + gaps_width;
176        let remaining_space = (bounds.width - content_width).max(0.0);
177
178        // Calculate starting position based on alignment
179        let (mut x, extra_gap) = match self.main_axis_alignment {
180            MainAxisAlignment::Start => (bounds.x, 0.0),
181            MainAxisAlignment::End => (bounds.x + remaining_space, 0.0),
182            MainAxisAlignment::Center => (bounds.x + remaining_space / 2.0, 0.0),
183            MainAxisAlignment::SpaceBetween => {
184                if self.children.len() > 1 {
185                    (bounds.x, remaining_space / (self.children.len() - 1) as f32)
186                } else {
187                    (bounds.x, 0.0)
188                }
189            }
190            MainAxisAlignment::SpaceAround => {
191                let gap = remaining_space / self.children.len() as f32;
192                (bounds.x + gap / 2.0, gap)
193            }
194            MainAxisAlignment::SpaceEvenly => {
195                let gap = remaining_space / (self.children.len() + 1) as f32;
196                (bounds.x + gap, gap)
197            }
198        };
199
200        // Second pass: position children
201        let num_children = self.children.len();
202        for (i, (child, size)) in self.children.iter_mut().zip(child_sizes.iter()).enumerate() {
203            let y = match self.cross_axis_alignment {
204                CrossAxisAlignment::Start | CrossAxisAlignment::Stretch => bounds.y,
205                CrossAxisAlignment::End => bounds.y + bounds.height - size.height,
206                CrossAxisAlignment::Center => bounds.y + (bounds.height - size.height) / 2.0,
207            };
208
209            let height = if self.cross_axis_alignment == CrossAxisAlignment::Stretch {
210                bounds.height
211            } else {
212                size.height
213            };
214
215            let child_bounds = Rect::new(x, y, size.width, height);
216            child.layout(child_bounds);
217            self.child_bounds.push(child_bounds);
218
219            // Move x for next child
220            if i < num_children - 1 {
221                x += size.width;
222                if self.main_axis_alignment == MainAxisAlignment::SpaceBetween {
223                    // SpaceBetween uses only extra_gap (no regular gap)
224                    x += extra_gap;
225                } else {
226                    x += self.gap + extra_gap;
227                }
228            }
229        }
230
231        LayoutResult {
232            size: bounds.size(),
233        }
234    }
235
236    fn paint(&self, canvas: &mut dyn Canvas) {
237        for child in &self.children {
238            child.paint(canvas);
239        }
240    }
241
242    fn event(&mut self, event: &Event) -> Option<Box<dyn Any + Send>> {
243        for child in &mut self.children {
244            if let Some(msg) = child.event(event) {
245                return Some(msg);
246            }
247        }
248        None
249    }
250
251    fn children(&self) -> &[Box<dyn Widget>] {
252        &self.children
253    }
254
255    fn children_mut(&mut self) -> &mut [Box<dyn Widget>] {
256        &mut self.children
257    }
258
259    fn test_id(&self) -> Option<&str> {
260        self.test_id_value.as_deref()
261    }
262}
263
264// PROBAR-SPEC-009: Brick Architecture - Tests define interface
265impl Brick for Row {
266    fn brick_name(&self) -> &'static str {
267        "Row"
268    }
269
270    fn assertions(&self) -> &[BrickAssertion] {
271        &[BrickAssertion::MaxLatencyMs(16)]
272    }
273
274    fn budget(&self) -> BrickBudget {
275        BrickBudget::uniform(16)
276    }
277
278    fn verify(&self) -> BrickVerification {
279        BrickVerification {
280            passed: self.assertions().to_vec(),
281            failed: vec![],
282            verification_time: Duration::from_micros(10),
283        }
284    }
285
286    fn to_html(&self) -> String {
287        r#"<div class="brick-row"></div>"#.to_string()
288    }
289
290    fn to_css(&self) -> String {
291        ".brick-row { display: flex; flex-direction: row; }".to_string()
292    }
293}
294
295#[cfg(test)]
296mod tests {
297    use super::*;
298    use presentar_core::widget::AccessibleRole;
299    use presentar_core::{Brick, BrickBudget, BrickVerification, Widget};
300    use std::time::Duration;
301
302    // Test widget with fixed size for layout testing
303    struct FixedWidget {
304        size: Size,
305    }
306
307    impl FixedWidget {
308        fn new(width: f32, height: f32) -> Self {
309            Self {
310                size: Size::new(width, height),
311            }
312        }
313    }
314
315    impl Brick for FixedWidget {
316        fn brick_name(&self) -> &'static str {
317            "FixedWidget"
318        }
319
320        fn assertions(&self) -> &[presentar_core::BrickAssertion] {
321            &[]
322        }
323
324        fn budget(&self) -> BrickBudget {
325            BrickBudget::uniform(16)
326        }
327
328        fn verify(&self) -> BrickVerification {
329            BrickVerification {
330                passed: vec![],
331                failed: vec![],
332                verification_time: Duration::from_micros(1),
333            }
334        }
335
336        fn to_html(&self) -> String {
337            String::new()
338        }
339
340        fn to_css(&self) -> String {
341            String::new()
342        }
343    }
344
345    impl Widget for FixedWidget {
346        fn type_id(&self) -> TypeId {
347            TypeId::of::<Self>()
348        }
349
350        fn measure(&self, constraints: Constraints) -> Size {
351            constraints.constrain(self.size)
352        }
353
354        fn layout(&mut self, _bounds: Rect) -> LayoutResult {
355            LayoutResult { size: self.size }
356        }
357
358        fn paint(&self, _canvas: &mut dyn Canvas) {}
359
360        fn event(&mut self, _event: &Event) -> Option<Box<dyn Any + Send>> {
361            None
362        }
363
364        fn children(&self) -> &[Box<dyn Widget>] {
365            &[]
366        }
367
368        fn children_mut(&mut self) -> &mut [Box<dyn Widget>] {
369            &mut []
370        }
371
372        fn accessible_role(&self) -> AccessibleRole {
373            AccessibleRole::Generic
374        }
375    }
376
377    // ===== Basic Tests =====
378
379    #[test]
380    fn test_row_empty() {
381        let row = Row::new();
382        let size = row.measure(Constraints::loose(Size::new(100.0, 100.0)));
383        assert_eq!(size, Size::ZERO);
384    }
385
386    #[test]
387    fn test_row_builder() {
388        let row = Row::new()
389            .gap(10.0)
390            .main_axis_alignment(MainAxisAlignment::Center)
391            .cross_axis_alignment(CrossAxisAlignment::Start)
392            .with_test_id("my-row");
393
394        assert_eq!(row.gap, 10.0);
395        assert_eq!(row.main_axis_alignment, MainAxisAlignment::Center);
396        assert_eq!(row.cross_axis_alignment, CrossAxisAlignment::Start);
397        assert_eq!(Widget::test_id(&row), Some("my-row"));
398    }
399
400    #[test]
401    fn test_row_default() {
402        let row = Row::default();
403        assert_eq!(row.main_axis_alignment, MainAxisAlignment::Start);
404        assert_eq!(row.cross_axis_alignment, CrossAxisAlignment::Center);
405        assert_eq!(row.gap, 0.0);
406    }
407
408    #[test]
409    fn test_row_type_id() {
410        let row = Row::new();
411        assert_eq!(Widget::type_id(&row), TypeId::of::<Row>());
412    }
413
414    #[test]
415    fn test_row_children() {
416        let row = Row::new()
417            .child(FixedWidget::new(50.0, 30.0))
418            .child(FixedWidget::new(50.0, 30.0));
419        assert_eq!(row.children().len(), 2);
420    }
421
422    // ===== Measure Tests =====
423
424    #[test]
425    fn test_row_measure_single_child() {
426        let row = Row::new().child(FixedWidget::new(50.0, 30.0));
427        let size = row.measure(Constraints::loose(Size::new(200.0, 100.0)));
428        assert_eq!(size, Size::new(50.0, 30.0));
429    }
430
431    #[test]
432    fn test_row_measure_multiple_children() {
433        let row = Row::new()
434            .child(FixedWidget::new(50.0, 30.0))
435            .child(FixedWidget::new(60.0, 40.0));
436        let size = row.measure(Constraints::loose(Size::new(200.0, 100.0)));
437        assert_eq!(size, Size::new(110.0, 40.0));
438    }
439
440    #[test]
441    fn test_row_measure_with_gap() {
442        let row = Row::new()
443            .gap(10.0)
444            .child(FixedWidget::new(50.0, 30.0))
445            .child(FixedWidget::new(50.0, 30.0));
446        let size = row.measure(Constraints::loose(Size::new(200.0, 100.0)));
447        assert_eq!(size, Size::new(110.0, 30.0)); // 50 + 10 + 50
448    }
449
450    #[test]
451    fn test_row_measure_constrained() {
452        let row = Row::new()
453            .child(FixedWidget::new(100.0, 50.0))
454            .child(FixedWidget::new(100.0, 50.0));
455        let size = row.measure(Constraints::tight(Size::new(150.0, 40.0)));
456        assert_eq!(size, Size::new(150.0, 40.0)); // Constrained to tight
457    }
458
459    // ===== MainAxisAlignment Tests =====
460
461    #[test]
462    fn test_row_alignment_start() {
463        let mut row = Row::new()
464            .main_axis_alignment(MainAxisAlignment::Start)
465            .child(FixedWidget::new(30.0, 20.0))
466            .child(FixedWidget::new(30.0, 20.0));
467
468        row.layout(Rect::new(0.0, 0.0, 200.0, 50.0));
469
470        assert_eq!(row.child_bounds.len(), 2);
471        assert_eq!(row.child_bounds[0].x, 0.0);
472        assert_eq!(row.child_bounds[1].x, 30.0);
473    }
474
475    #[test]
476    fn test_row_alignment_end() {
477        let mut row = Row::new()
478            .main_axis_alignment(MainAxisAlignment::End)
479            .child(FixedWidget::new(30.0, 20.0))
480            .child(FixedWidget::new(30.0, 20.0));
481
482        row.layout(Rect::new(0.0, 0.0, 200.0, 50.0));
483
484        // 200 - 60 = 140 remaining, children at 140 and 170
485        assert_eq!(row.child_bounds[0].x, 140.0);
486        assert_eq!(row.child_bounds[1].x, 170.0);
487    }
488
489    #[test]
490    fn test_row_alignment_center() {
491        let mut row = Row::new()
492            .main_axis_alignment(MainAxisAlignment::Center)
493            .child(FixedWidget::new(30.0, 20.0))
494            .child(FixedWidget::new(30.0, 20.0));
495
496        row.layout(Rect::new(0.0, 0.0, 200.0, 50.0));
497
498        // 200 - 60 = 140 remaining, offset = 70
499        assert_eq!(row.child_bounds[0].x, 70.0);
500        assert_eq!(row.child_bounds[1].x, 100.0);
501    }
502
503    #[test]
504    fn test_row_alignment_space_between() {
505        let mut row = Row::new()
506            .main_axis_alignment(MainAxisAlignment::SpaceBetween)
507            .child(FixedWidget::new(30.0, 20.0))
508            .child(FixedWidget::new(30.0, 20.0));
509
510        row.layout(Rect::new(0.0, 0.0, 200.0, 50.0));
511
512        // First at start, last at end
513        assert_eq!(row.child_bounds[0].x, 0.0);
514        assert_eq!(row.child_bounds[1].x, 170.0); // 200 - 30
515    }
516
517    #[test]
518    fn test_row_alignment_space_between_single_child() {
519        let mut row = Row::new()
520            .main_axis_alignment(MainAxisAlignment::SpaceBetween)
521            .child(FixedWidget::new(30.0, 20.0));
522
523        row.layout(Rect::new(0.0, 0.0, 200.0, 50.0));
524
525        // Single child should be at start
526        assert_eq!(row.child_bounds[0].x, 0.0);
527    }
528
529    #[test]
530    fn test_row_alignment_space_between_three_children() {
531        let mut row = Row::new()
532            .main_axis_alignment(MainAxisAlignment::SpaceBetween)
533            .child(FixedWidget::new(30.0, 20.0))
534            .child(FixedWidget::new(30.0, 20.0))
535            .child(FixedWidget::new(30.0, 20.0));
536
537        row.layout(Rect::new(0.0, 0.0, 200.0, 50.0));
538
539        // 200 - 90 = 110 remaining, gap = 55
540        assert_eq!(row.child_bounds[0].x, 0.0);
541        assert_eq!(row.child_bounds[1].x, 85.0); // 30 + 55
542        assert_eq!(row.child_bounds[2].x, 170.0); // 200 - 30
543    }
544
545    #[test]
546    fn test_row_alignment_space_around() {
547        let mut row = Row::new()
548            .main_axis_alignment(MainAxisAlignment::SpaceAround)
549            .child(FixedWidget::new(40.0, 20.0))
550            .child(FixedWidget::new(40.0, 20.0));
551
552        row.layout(Rect::new(0.0, 0.0, 200.0, 50.0));
553
554        // 200 - 80 = 120 remaining, gap = 60, half-gap = 30
555        // First at 30, second at 30 + 40 + 60 = 130
556        assert_eq!(row.child_bounds[0].x, 30.0);
557        assert_eq!(row.child_bounds[1].x, 130.0);
558    }
559
560    #[test]
561    fn test_row_alignment_space_evenly() {
562        let mut row = Row::new()
563            .main_axis_alignment(MainAxisAlignment::SpaceEvenly)
564            .child(FixedWidget::new(40.0, 20.0))
565            .child(FixedWidget::new(40.0, 20.0));
566
567        row.layout(Rect::new(0.0, 0.0, 200.0, 50.0));
568
569        // 200 - 80 = 120 remaining, 3 gaps (n+1), gap = 40
570        // First at 40, second at 40 + 40 + 40 = 120
571        assert_eq!(row.child_bounds[0].x, 40.0);
572        assert_eq!(row.child_bounds[1].x, 120.0);
573    }
574
575    // ===== CrossAxisAlignment Tests =====
576
577    #[test]
578    fn test_row_cross_alignment_start() {
579        let mut row = Row::new()
580            .cross_axis_alignment(CrossAxisAlignment::Start)
581            .child(FixedWidget::new(30.0, 20.0));
582
583        row.layout(Rect::new(0.0, 0.0, 200.0, 100.0));
584
585        assert_eq!(row.child_bounds[0].y, 0.0);
586        assert_eq!(row.child_bounds[0].height, 20.0);
587    }
588
589    #[test]
590    fn test_row_cross_alignment_end() {
591        let mut row = Row::new()
592            .cross_axis_alignment(CrossAxisAlignment::End)
593            .child(FixedWidget::new(30.0, 20.0));
594
595        row.layout(Rect::new(0.0, 0.0, 200.0, 100.0));
596
597        assert_eq!(row.child_bounds[0].y, 80.0); // 100 - 20
598        assert_eq!(row.child_bounds[0].height, 20.0);
599    }
600
601    #[test]
602    fn test_row_cross_alignment_center() {
603        let mut row = Row::new()
604            .cross_axis_alignment(CrossAxisAlignment::Center)
605            .child(FixedWidget::new(30.0, 20.0));
606
607        row.layout(Rect::new(0.0, 0.0, 200.0, 100.0));
608
609        assert_eq!(row.child_bounds[0].y, 40.0); // (100 - 20) / 2
610        assert_eq!(row.child_bounds[0].height, 20.0);
611    }
612
613    #[test]
614    fn test_row_cross_alignment_stretch() {
615        let mut row = Row::new()
616            .cross_axis_alignment(CrossAxisAlignment::Stretch)
617            .child(FixedWidget::new(30.0, 20.0));
618
619        row.layout(Rect::new(0.0, 0.0, 200.0, 100.0));
620
621        assert_eq!(row.child_bounds[0].y, 0.0);
622        assert_eq!(row.child_bounds[0].height, 100.0); // Stretched to container
623    }
624
625    // ===== Gap Tests =====
626
627    #[test]
628    fn test_row_gap_single_child() {
629        let mut row = Row::new().gap(20.0).child(FixedWidget::new(30.0, 20.0));
630
631        row.layout(Rect::new(0.0, 0.0, 200.0, 50.0));
632
633        // Single child: no gap applied
634        assert_eq!(row.child_bounds[0].x, 0.0);
635    }
636
637    #[test]
638    fn test_row_gap_multiple_children() {
639        let mut row = Row::new()
640            .gap(15.0)
641            .child(FixedWidget::new(30.0, 20.0))
642            .child(FixedWidget::new(30.0, 20.0))
643            .child(FixedWidget::new(30.0, 20.0));
644
645        row.layout(Rect::new(0.0, 0.0, 200.0, 50.0));
646
647        assert_eq!(row.child_bounds[0].x, 0.0);
648        assert_eq!(row.child_bounds[1].x, 45.0); // 30 + 15
649        assert_eq!(row.child_bounds[2].x, 90.0); // 45 + 30 + 15
650    }
651
652    #[test]
653    fn test_row_gap_with_alignment_center() {
654        let mut row = Row::new()
655            .gap(10.0)
656            .main_axis_alignment(MainAxisAlignment::Center)
657            .child(FixedWidget::new(30.0, 20.0))
658            .child(FixedWidget::new(30.0, 20.0));
659
660        row.layout(Rect::new(0.0, 0.0, 200.0, 50.0));
661
662        // Total: 30 + 10 + 30 = 70, remaining = 130, offset = 65
663        assert_eq!(row.child_bounds[0].x, 65.0);
664        assert_eq!(row.child_bounds[1].x, 105.0); // 65 + 30 + 10
665    }
666
667    // ===== Edge Cases =====
668
669    #[test]
670    fn test_row_layout_empty() {
671        let mut row = Row::new();
672        let result = row.layout(Rect::new(0.0, 0.0, 200.0, 50.0));
673        assert_eq!(result.size, Size::ZERO);
674    }
675
676    #[test]
677    fn test_row_content_larger_than_bounds() {
678        let mut row = Row::new()
679            .child(FixedWidget::new(100.0, 30.0))
680            .child(FixedWidget::new(100.0, 30.0))
681            .child(FixedWidget::new(100.0, 30.0));
682
683        // Container only 200 wide, content is 300
684        row.layout(Rect::new(0.0, 0.0, 200.0, 50.0));
685
686        // Children still placed sequentially (overflow)
687        assert_eq!(row.child_bounds[0].x, 0.0);
688        assert_eq!(row.child_bounds[1].x, 100.0);
689        assert_eq!(row.child_bounds[2].x, 200.0);
690    }
691
692    #[test]
693    fn test_row_with_offset_bounds() {
694        let mut row = Row::new()
695            .child(FixedWidget::new(30.0, 20.0))
696            .child(FixedWidget::new(30.0, 20.0));
697
698        row.layout(Rect::new(50.0, 25.0, 200.0, 50.0));
699
700        // Children should be offset by bounds origin
701        assert_eq!(row.child_bounds[0].x, 50.0);
702        assert_eq!(row.child_bounds[0].y, 40.0); // 25 + (50-20)/2
703        assert_eq!(row.child_bounds[1].x, 80.0);
704    }
705
706    #[test]
707    fn test_row_varying_child_heights() {
708        let mut row = Row::new()
709            .cross_axis_alignment(CrossAxisAlignment::Center)
710            .child(FixedWidget::new(30.0, 20.0))
711            .child(FixedWidget::new(30.0, 60.0))
712            .child(FixedWidget::new(30.0, 40.0));
713
714        row.layout(Rect::new(0.0, 0.0, 200.0, 100.0));
715
716        // All centered differently based on their heights
717        assert_eq!(row.child_bounds[0].y, 40.0); // (100-20)/2
718        assert_eq!(row.child_bounds[1].y, 20.0); // (100-60)/2
719        assert_eq!(row.child_bounds[2].y, 30.0); // (100-40)/2
720    }
721
722    // ===== Enum Default Tests =====
723
724    #[test]
725    fn test_main_axis_alignment_default() {
726        assert_eq!(MainAxisAlignment::default(), MainAxisAlignment::Start);
727    }
728
729    #[test]
730    fn test_cross_axis_alignment_default() {
731        assert_eq!(CrossAxisAlignment::default(), CrossAxisAlignment::Center);
732    }
733}