use super::*;
use crate::{
device_scale, resolve_fit_or_stretch, set_device_scale, HAnchor, Insets, Padding, Spacer,
VAnchor, WidgetBase,
};
#[test]
fn test_insets_all() {
let i = Insets::all(5.0);
assert_eq!(i.left, 5.0);
assert_eq!(i.right, 5.0);
assert_eq!(i.top, 5.0);
assert_eq!(i.bottom, 5.0);
}
#[test]
fn test_insets_symmetric() {
let i = Insets::symmetric(10.0, 4.0);
assert_eq!(i.horizontal(), 20.0);
assert_eq!(i.vertical(), 8.0);
}
#[test]
fn test_insets_scale() {
let i = Insets::all(3.0).scale(2.0);
assert_eq!(i.left, 6.0);
assert_eq!(i.top, 6.0);
}
#[test]
fn test_hanchor_stretch_contains_left_and_right() {
assert!(HAnchor::STRETCH.contains(HAnchor::LEFT));
assert!(HAnchor::STRETCH.contains(HAnchor::RIGHT));
assert!(HAnchor::STRETCH.is_stretch());
}
#[test]
fn test_hanchor_left_not_stretch() {
assert!(!HAnchor::LEFT.is_stretch());
}
#[test]
fn test_hanchor_max_fit_or_stretch_contains_stretch() {
assert!(HAnchor::MAX_FIT_OR_STRETCH.contains(HAnchor::LEFT));
assert!(HAnchor::MAX_FIT_OR_STRETCH.contains(HAnchor::RIGHT));
assert!(HAnchor::MAX_FIT_OR_STRETCH.contains(HAnchor::FIT));
}
#[test]
fn test_vanchor_stretch() {
assert!(VAnchor::STRETCH.is_stretch());
assert!(VAnchor::STRETCH.contains(VAnchor::BOTTOM));
assert!(VAnchor::STRETCH.contains(VAnchor::TOP));
}
#[test]
fn test_resolve_max_fit_or_stretch_prefers_larger() {
assert_eq!(resolve_fit_or_stretch(100.0, 60.0, true), 100.0);
assert_eq!(resolve_fit_or_stretch(40.0, 80.0, true), 80.0);
}
#[test]
fn test_resolve_min_fit_or_stretch_prefers_smaller() {
assert_eq!(resolve_fit_or_stretch(100.0, 60.0, false), 60.0);
assert_eq!(resolve_fit_or_stretch(40.0, 80.0, false), 40.0);
}
#[test]
fn test_widget_base_clamp_size() {
let mut base = WidgetBase::new();
base.min_size = Size::new(50.0, 30.0);
base.max_size = Size::new(200.0, 100.0);
let clamped = base.clamp_size(Size::new(10.0, 150.0));
assert_eq!(clamped.width, 50.0, "below min should clamp to min_w");
assert_eq!(clamped.height, 100.0, "above max should clamp to max_h");
}
#[test]
fn test_device_scale_default_is_one() {
set_device_scale(1.0);
assert_eq!(device_scale(), 1.0);
}
#[test]
fn test_padding_asymmetric_layout() {
let child = Box::new(Spacer::new());
let mut w = Padding::new(
Insets::from_sides(10.0, 20.0, 5.0, 15.0), child,
);
let outer = w.layout(Size::new(100.0, 80.0));
assert_eq!(
outer.width, 100.0,
"outer width should equal available.width"
);
assert_eq!(
outer.height, 80.0,
"outer height should equal available.height"
);
let cb = w.children()[0].bounds();
assert_eq!(cb.x, 10.0, "child x should be left inset");
assert_eq!(cb.y, 15.0, "child y should be bottom inset (Y-up)");
assert_eq!(cb.width, 70.0, "child width = available.width - h_insets");
assert_eq!(
cb.height, 60.0,
"child height = available.height - v_insets"
);
}
#[test]
fn test_padding_uniform_alias() {
let mut w = Padding::uniform(8.0, Box::new(Spacer::new()));
let outer = w.layout(Size::new(50.0, 40.0));
assert_eq!(outer.width, 50.0);
assert_eq!(outer.height, 40.0);
let cb = w.children()[0].bounds();
assert_eq!(cb.x, 8.0);
assert_eq!(cb.y, 8.0);
}
#[test]
fn test_sized_box_child_right_anchor() {
let child = Box::new(SizedBox::fixed(30.0, 20.0).with_h_anchor(HAnchor::RIGHT));
let mut outer = SizedBox::new()
.with_width(100.0)
.with_height(50.0)
.with_child(child);
outer.layout(Size::new(100.0, 50.0));
let cb = outer.children()[0].bounds();
assert_eq!(cb.x, 70.0, "right-anchor child x should be box_w - child_w");
assert_eq!(cb.width, 30.0);
}
#[test]
fn test_sized_box_child_top_anchor() {
let child = Box::new(SizedBox::fixed(20.0, 15.0).with_v_anchor(VAnchor::TOP));
let mut outer = SizedBox::new()
.with_width(50.0)
.with_height(60.0)
.with_child(child);
outer.layout(Size::new(50.0, 60.0));
let cb = outer.children()[0].bounds();
assert_eq!(
cb.y, 45.0,
"top-anchor child y should be box_h - child_h (Y-up)"
);
assert_eq!(cb.height, 15.0);
}
#[test]
fn test_sized_box_child_center_h_anchor() {
let child = Box::new(SizedBox::fixed(20.0, 10.0).with_h_anchor(HAnchor::CENTER));
let mut outer = SizedBox::new()
.with_width(100.0)
.with_height(50.0)
.with_child(child);
outer.layout(Size::new(100.0, 50.0));
let cb = outer.children()[0].bounds();
assert_eq!(
cb.x, 40.0,
"center-h child x should be (box_w - child_w) / 2"
);
}
#[test]
fn test_sized_box_child_stretch() {
let child = Box::new(SizedBox::fixed(20.0, 10.0).with_h_anchor(HAnchor::STRETCH));
let mut outer = SizedBox::new()
.with_width(100.0)
.with_height(50.0)
.with_child(child);
outer.layout(Size::new(100.0, 50.0));
let cb = outer.children()[0].bounds();
assert_eq!(cb.x, 0.0, "stretched child should start at x=0");
assert_eq!(cb.width, 100.0, "stretched child should fill box width");
}
#[test]
fn test_flex_column_cross_axis_anchors() {
let left_child = Box::new(SizedBox::fixed(30.0, 10.0).with_h_anchor(HAnchor::LEFT));
let center_child = Box::new(SizedBox::fixed(30.0, 10.0).with_h_anchor(HAnchor::CENTER));
let right_child = Box::new(SizedBox::fixed(30.0, 10.0).with_h_anchor(HAnchor::RIGHT));
let stretch_child = Box::new(SizedBox::fixed(30.0, 10.0).with_h_anchor(HAnchor::STRETCH));
let mut col = FlexColumn::new()
.with_gap(0.0)
.add(left_child)
.add(center_child)
.add(right_child)
.add(stretch_child);
col.layout(Size::new(100.0, 80.0));
let children = col.children();
assert_eq!(children[0].bounds().x, 0.0, "LEFT child x");
let center_x = children[1].bounds().x;
assert!(
(center_x - 35.0).abs() < 0.5,
"CENTER child x ≈ 35, got {center_x}"
);
assert_eq!(children[2].bounds().x, 70.0, "RIGHT child x");
assert_eq!(children[3].bounds().x, 0.0, "STRETCH child x");
assert_eq!(children[3].bounds().width, 100.0, "STRETCH child width");
}
#[test]
fn test_flex_column_child_margin_spacing() {
set_device_scale(1.0);
let top_child = Box::new(
SizedBox::fixed(50.0, 10.0).with_margin(Insets::from_sides(0.0, 0.0, 0.0, 5.0)), );
let bot_child = Box::new(
SizedBox::fixed(50.0, 10.0).with_margin(Insets::from_sides(0.0, 0.0, 3.0, 0.0)), );
let mut col = FlexColumn::new()
.with_gap(0.0)
.add(top_child)
.add(bot_child);
col.layout(Size::new(100.0, 100.0));
let children = col.children();
let top_bounds = children[0].bounds();
let bot_bounds = children[1].bounds();
let gap_between = top_bounds.y - (bot_bounds.y + bot_bounds.height);
assert!(
(gap_between - 8.0).abs() < 0.5,
"gap between children should equal 5+3=8 (additive margins), got {gap_between}"
);
}
#[test]
fn test_flex_row_cross_axis_anchors() {
let bot_child = Box::new(SizedBox::fixed(20.0, 15.0).with_v_anchor(VAnchor::BOTTOM));
let center_child = Box::new(SizedBox::fixed(20.0, 15.0).with_v_anchor(VAnchor::CENTER));
let top_child = Box::new(SizedBox::fixed(20.0, 15.0).with_v_anchor(VAnchor::TOP));
let mut row = FlexRow::new()
.with_gap(0.0)
.add(bot_child)
.add(center_child)
.add(top_child);
row.layout(Size::new(200.0, 60.0));
let children = row.children();
assert_eq!(children[0].bounds().y, 0.0, "BOTTOM child y");
let cy = children[1].bounds().y;
assert_eq!(cy, 23.0, "CENTER child y rounded to integer, got {cy}");
assert_eq!(children[2].bounds().y, 45.0, "TOP child y (Y-up)");
}
#[test]
fn test_flex_column_respects_child_min_size() {
let tiny = Box::new(SizedBox::fixed(50.0, 5.0).with_min_size(Size::new(50.0, 20.0)));
let mut col = FlexColumn::new().add(tiny);
col.layout(Size::new(100.0, 200.0));
assert_eq!(
col.children()[0].bounds().height,
20.0,
"fixed child height must respect min_size"
);
}
#[test]
fn test_flex_column_respects_child_max_size() {
let big = Box::new(SizedBox::fixed(50.0, 50.0).with_max_size(Size::new(50.0, 30.0)));
let mut col = FlexColumn::new().add_flex(big, 1.0);
col.layout(Size::new(100.0, 200.0));
assert_eq!(
col.children()[0].bounds().height,
30.0,
"flex child height must respect max_size"
);
}
#[test]
fn test_min_fit_or_stretch_uses_fit_when_smaller() {
let child = Box::new(SizedBox::fixed(40.0, 10.0).with_h_anchor(HAnchor::MIN_FIT_OR_STRETCH));
let mut col = FlexColumn::new().add(child);
col.layout(Size::new(100.0, 50.0));
assert_eq!(
col.children()[0].bounds().width,
40.0,
"MIN_FIT_OR_STRETCH should use fit (40) when fit < stretch (100)"
);
}
#[test]
fn test_max_fit_or_stretch_uses_stretch_when_larger() {
let child = Box::new(SizedBox::fixed(40.0, 10.0).with_h_anchor(HAnchor::MAX_FIT_OR_STRETCH));
let mut col = FlexColumn::new().add(child);
col.layout(Size::new(100.0, 50.0));
assert_eq!(
col.children()[0].bounds().width,
100.0,
"MAX_FIT_OR_STRETCH should use stretch (100) when stretch > fit (40)"
);
}