azul-layout 0.0.7

Layout solver + font and image loader the Azul GUI framework
Documentation
/// Unit tests for CSS 2.2 Section 17.4 - Table Caption Positioning
///
/// Tests cover:
/// - caption-side: top (default)
/// - caption-side: bottom
/// - Caption layout with table width
/// - Y-offset adjustments for top captions
use azul_css::props::layout::StyleCaptionSide;

#[test]
fn test_caption_side_default() {
    // CSS 2.2 Section 17.4: Default value is 'top'
    let default_value = StyleCaptionSide::default();
    assert_eq!(default_value, StyleCaptionSide::Top);
}

#[test]
fn test_caption_side_top() {
    // CSS 2.2 Section 17.4: caption-side: top
    // Caption should be positioned above the table
    let caption_side = StyleCaptionSide::Top;
    assert_eq!(caption_side, StyleCaptionSide::Top);
}

#[test]
fn test_caption_side_bottom() {
    // CSS 2.2 Section 17.4: caption-side: bottom
    // Caption should be positioned below the table
    let caption_side = StyleCaptionSide::Bottom;
    assert_eq!(caption_side, StyleCaptionSide::Bottom);
}

#[test]
fn test_caption_side_equality() {
    // Ensure caption-side values can be compared
    assert_eq!(StyleCaptionSide::Top, StyleCaptionSide::Top);
    assert_eq!(StyleCaptionSide::Bottom, StyleCaptionSide::Bottom);
    assert_ne!(StyleCaptionSide::Top, StyleCaptionSide::Bottom);
}

#[test]
fn test_caption_top_positioning() {
    // CSS 2.2 Section 17.4: When caption-side is top:
    // - Caption is positioned at y=0
    // - Table content starts at y=caption_height

    let caption_side = StyleCaptionSide::Top;
    let caption_height = 50.0;
    let table_height = 200.0;

    // Caption position
    let caption_y = 0.0;
    assert_eq!(caption_y, 0.0);

    // Table content offset
    let table_y_offset = caption_height;
    assert_eq!(table_y_offset, 50.0);

    // Total height
    let total_height = table_height + caption_height;
    assert_eq!(total_height, 250.0);

    // Ensure caption-side is top
    assert_eq!(caption_side, StyleCaptionSide::Top);
}

#[test]
fn test_caption_bottom_positioning() {
    // CSS 2.2 Section 17.4: When caption-side is bottom:
    // - Table content starts at y=0
    // - Caption is positioned at y=table_height

    let caption_side = StyleCaptionSide::Bottom;
    let caption_height = 50.0;
    let table_height = 200.0;

    // Table position
    let table_y_offset = 0.0;
    assert_eq!(table_y_offset, 0.0);

    // Caption position
    let caption_y = table_height;
    assert_eq!(caption_y, 200.0);

    // Total height
    let total_height = table_height + caption_height;
    assert_eq!(total_height, 250.0);

    // Ensure caption-side is bottom
    assert_eq!(caption_side, StyleCaptionSide::Bottom);
}

#[test]
fn test_caption_width_matches_table() {
    // CSS 2.2 Section 17.4: The caption box uses the table's width
    // as its containing block width

    let table_width = 400.0;
    let caption_available_width = table_width;

    assert_eq!(caption_available_width, 400.0);
    assert_eq!(caption_available_width, table_width);
}

#[test]
fn test_caption_height_affects_total() {
    // CSS 2.2 Section 17.4: Caption height is included in total table height

    let table_height = 300.0;
    let caption_height = 60.0;

    // With top caption
    let total_with_caption = table_height + caption_height;
    assert_eq!(total_with_caption, 360.0);

    // Without caption
    let total_without_caption = table_height + 0.0;
    assert_eq!(total_without_caption, 300.0);

    // Difference is exactly caption height
    assert_eq!(total_with_caption - total_without_caption, caption_height);
}

#[test]
fn test_caption_y_offset_calculation_top() {
    // When caption is on top, all table cells need y-offset adjustment

    let caption_height = 75.0;
    let caption_side = StyleCaptionSide::Top;

    // Calculate offset
    let table_y_offset = match caption_side {
        StyleCaptionSide::Top => caption_height,
        StyleCaptionSide::Bottom => 0.0,
    };

    assert_eq!(table_y_offset, 75.0);

    // Apply offset to a cell at y=100
    let cell_y_original = 100.0;
    let cell_y_adjusted = cell_y_original + table_y_offset;
    assert_eq!(cell_y_adjusted, 175.0);
}

#[test]
fn test_caption_y_offset_calculation_bottom() {
    // When caption is on bottom, table cells don't need adjustment

    let caption_height = 75.0;
    let caption_side = StyleCaptionSide::Bottom;

    // Calculate offset
    let table_y_offset = match caption_side {
        StyleCaptionSide::Top => caption_height,
        StyleCaptionSide::Bottom => 0.0,
    };

    assert_eq!(table_y_offset, 0.0);

    // Cell positions unchanged
    let cell_y_original = 100.0;
    let cell_y_adjusted = cell_y_original + table_y_offset;
    assert_eq!(cell_y_adjusted, 100.0);
}

#[test]
fn test_multiple_captions_scenario() {
    // CSS 2.2 Section 17.4: A table may have at most one caption
    // This test verifies that only one caption is processed

    let has_caption = true;
    let caption_count = if has_caption { 1 } else { 0 };

    assert!(caption_count <= 1);
    assert_eq!(caption_count, 1);
}

#[test]
fn test_no_caption_scenario() {
    // CSS 2.2 Section 17.4: Captions are optional
    // Verify behavior when no caption exists

    let caption_index: Option<usize> = None;
    let caption_height = caption_index.map(|_| 50.0).unwrap_or(0.0);

    assert_eq!(caption_height, 0.0);

    // Table height unchanged
    let table_height = 200.0;
    let total_height = table_height + caption_height;
    assert_eq!(total_height, 200.0);
}

#[test]
fn test_caption_position_consistency() {
    // Verify caption position consistency across both sides

    let table_height = 250.0;
    let caption_height = 40.0;

    // Top caption
    let (caption_y_top, table_y_top) = (0.0, caption_height);
    assert_eq!(caption_y_top, 0.0);
    assert_eq!(table_y_top, 40.0);

    // Bottom caption
    let (table_y_bottom, caption_y_bottom) = (0.0, table_height);
    assert_eq!(table_y_bottom, 0.0);
    assert_eq!(caption_y_bottom, 250.0);

    // Total height same for both
    let total_top = table_height + caption_height;
    let total_bottom = table_height + caption_height;
    assert_eq!(total_top, total_bottom);
}

#[test]
fn test_caption_with_border_spacing() {
    // CSS 2.2 Section 17.4: Caption positioning is independent of border-spacing
    // Border-spacing affects table size, but caption uses final table width

    let table_base_width = 300.0;
    let border_spacing = 10.0;
    let num_columns = 3;

    // Table width with border-spacing
    let table_width = table_base_width + (border_spacing * (num_columns + 1) as f32);

    // Caption uses this final width
    let caption_available_width = table_width;

    assert_eq!(caption_available_width, 340.0);
}

#[test]
fn test_caption_z_ordering() {
    // CSS 2.2 Section 17.4: Caption is rendered in document order
    // Top captions appear before table content, bottom captions after

    let caption_side_top = StyleCaptionSide::Top;
    let caption_side_bottom = StyleCaptionSide::Bottom;

    // Top caption has lower y-coordinate
    let caption_y_when_top = 0.0;
    let table_y_when_top = 50.0; // Assumes 50px caption height
    assert!(caption_y_when_top < table_y_when_top);

    // Bottom caption has higher y-coordinate
    let table_y_when_bottom = 0.0;
    let caption_y_when_bottom = 200.0; // Assumes 200px table height
    assert!(caption_y_when_bottom > table_y_when_bottom);

    assert_eq!(caption_side_top, StyleCaptionSide::Top);
    assert_eq!(caption_side_bottom, StyleCaptionSide::Bottom);
}

#[test]
fn test_caption_edge_case_zero_height() {
    // Edge case: Caption with zero height (empty caption)

    let caption_height = 0.0;
    let table_height = 100.0;

    // Top caption with zero height
    let table_y_offset = caption_height;
    assert_eq!(table_y_offset, 0.0);

    // Total height
    let total_height = table_height + caption_height;
    assert_eq!(total_height, 100.0);
}

#[test]
fn test_caption_edge_case_very_tall() {
    // Edge case: Caption taller than table

    let caption_height = 500.0;
    let table_height = 100.0;

    // Total height
    let total_height = table_height + caption_height;
    assert_eq!(total_height, 600.0);

    // Caption can be taller than table
    assert!(caption_height > table_height);
}

#[test]
fn test_caption_alignment_with_table_width() {
    // CSS 2.2 Section 17.4: Caption is aligned with table
    // Caption's x-position is 0 (aligned with table left edge)

    let caption_x = 0.0;
    let table_x = 0.0;

    assert_eq!(caption_x, table_x);
    assert_eq!(caption_x, 0.0);
}

#[test]
fn test_caption_layout_independence() {
    // CSS 2.2 Section 17.4: "The caption box is a block box that retains
    // its own content, padding, border, and margin areas"

    // Caption has its own box model
    let caption_has_own_box_model = true;
    assert!(caption_has_own_box_model);

    // Caption doesn't affect table cell positioning logic
    // (except for the y-offset when on top)
    let caption_affects_table_cells_x = false;
    let caption_affects_table_cells_y_when_top = true;
    let caption_affects_table_cells_y_when_bottom = false;

    assert!(!caption_affects_table_cells_x);
    assert!(caption_affects_table_cells_y_when_top);
    assert!(!caption_affects_table_cells_y_when_bottom);
}

#[test]
fn test_caption_side_values_complete() {
    // Verify all caption-side values are covered
    let all_values = vec![StyleCaptionSide::Top, StyleCaptionSide::Bottom];

    assert_eq!(all_values.len(), 2);
    assert!(all_values.contains(&StyleCaptionSide::Top));
    assert!(all_values.contains(&StyleCaptionSide::Bottom));
}