1pub mod alignment;
11pub mod constraints;
12pub mod flexure;
13pub mod layout_result;
14pub mod sizing;
15pub mod widgets;
16
17pub use alignment::{CrossAxisAlignment, MainAxisAlignment};
18pub use constraints::{AxisBound, Constraints};
19pub use flexure::Flexure;
20pub use layout_result::LayoutResult;
21pub use sizing::{Height, Width};
22pub use widgets::flex::{layout_column, layout_row};
23pub use widgets::{
24 aspect_ratio::AspectRatio,
25 flex::{Flex, FlexDirection},
26 grid::Grid,
27 wrap::Wrap,
28};
29
30#[cfg(test)]
31mod tests {
32 use rosace_core::types::Size;
33
34 use crate::{
35 alignment::{CrossAxisAlignment, MainAxisAlignment},
36 constraints::Constraints,
37 sizing::Width,
38 widgets::{flex::{layout_column, layout_row}, grid::Grid, wrap::Wrap},
39 };
40
41 #[test]
42 fn column_stacks_children_vertically() {
43 let child_sizes = vec![
44 Size { width: 100.0, height: 30.0 },
45 Size { width: 80.0, height: 40.0 },
46 ];
47 let result = layout_column(
48 Constraints::loose(400.0, 600.0), &child_sizes,
49 MainAxisAlignment::Start, CrossAxisAlignment::Start, 8.0,
50 );
51 assert_eq!(result.child_positions[1].y, 30.0 + 8.0);
53 }
54
55 #[test]
56 fn row_stacks_children_horizontally() {
57 let child_sizes = vec![
58 Size { width: 50.0, height: 20.0 },
59 Size { width: 60.0, height: 20.0 },
60 ];
61 let result = layout_row(
62 Constraints::loose(400.0, 100.0), &child_sizes,
63 MainAxisAlignment::Start, CrossAxisAlignment::Start, 4.0,
64 );
65 assert_eq!(result.child_positions[1].x, 50.0 + 4.0);
66 }
67
68 #[test]
69 fn constraints_constrain_clamps_correctly() {
70 let c = Constraints::loose(100.0, 100.0);
71 let big = Size { width: 200.0, height: 200.0 };
72 let clamped = c.constrain(big);
73 assert_eq!(clamped.width, 100.0);
74 assert_eq!(clamped.height, 100.0);
75 }
76
77 #[test]
78 fn constraints_loose_has_zero_min() {
79 let c = Constraints::loose(800.0, 600.0);
80 assert_eq!(c.min_width, 0.0);
81 assert_eq!(c.min_height, 0.0);
82 }
83
84 #[test]
85 fn fraction_width_is_of_available_space() {
86 let w = Width::Fraction(0.5);
87 let bound = w.to_axis_bound(200.0);
88 assert!(
89 matches!(bound, rosace_core::render_object::AxisBound::Bounded(v) if (v - 100.0).abs() < 0.001)
90 );
91 }
92
93 #[test]
94 fn grid_positions_children_in_rows() {
95 let grid = Grid::new(3).spacing(0.0);
96 let sizes = vec![Size { width: 50.0, height: 50.0 }; 6];
97 let result = grid.layout(Constraints::loose(200.0, 400.0), &sizes);
98 assert_eq!(result.child_positions[3].x, 0.0);
100 assert!(result.child_positions[3].y > 0.0);
101 }
102
103 #[test]
104 fn wrap_wraps_to_next_line_when_full() {
105 let wrap = Wrap::new().spacing(0.0);
106 let sizes = vec![Size { width: 60.0, height: 30.0 }; 4];
107 let result = wrap.layout(Constraints::loose(150.0, 400.0), &sizes);
108 assert!(result.child_positions[2].y > 0.0);
110 }
111}