fission-ir 0.14.1

Intermediate representation and display-list primitives for Fission rendering
Documentation
use crate::op::{
    decode_inline_widget_marker, decode_text_paragraph_style, encode_inline_widget_marker,
    encode_text_paragraph_style, HttpHeader, ImageCachePolicy, ImageRequest, ImageSource,
    InlineWidgetMarker, TextAlign, TextDirection, TextHeightBehavior, TextOverflow,
    TextParagraphStyle, TextWidthBasis, TEXT_PARAGRAPH_MAX_ENCODED_LINES,
};

#[test]
fn paragraph_style_round_trips_alignment_overflow_and_line_cap() {
    let style = TextParagraphStyle {
        text_align: TextAlign::Justify,
        max_lines: Some(3),
        overflow: TextOverflow::Fade,
        text_direction: TextDirection::Auto,
        text_width_basis: TextWidthBasis::Parent,
        strut_line_height: None,
        text_height_behavior: TextHeightBehavior::default(),
    };

    let encoded = encode_text_paragraph_style(style);
    assert_eq!(decode_text_paragraph_style(encoded), Some(style));
}

#[test]
fn paragraph_style_clamps_line_count_to_precise_encoding_budget() {
    let encoded = encode_text_paragraph_style(TextParagraphStyle {
        text_align: TextAlign::End,
        max_lines: Some(TEXT_PARAGRAPH_MAX_ENCODED_LINES + 99),
        overflow: TextOverflow::Ellipsis,
        text_direction: TextDirection::Auto,
        text_width_basis: TextWidthBasis::Parent,
        strut_line_height: None,
        text_height_behavior: TextHeightBehavior::default(),
    });

    assert_eq!(
        decode_text_paragraph_style(encoded),
        Some(TextParagraphStyle {
            text_align: TextAlign::End,
            max_lines: Some(TEXT_PARAGRAPH_MAX_ENCODED_LINES),
            overflow: TextOverflow::Ellipsis,
            text_direction: TextDirection::Auto,
            text_width_basis: TextWidthBasis::Parent,
            strut_line_height: None,
            text_height_behavior: TextHeightBehavior::default(),
        })
    );
}

#[test]
fn image_request_cache_key_is_stable_and_dimension_sensitive() {
    let request = ImageRequest {
        source: ImageSource::Network {
            url: "https://cdn.example.com/image.webp".into(),
            headers: vec![HttpHeader {
                name: "Accept".into(),
                value: "image/webp".into(),
            }],
            cache_policy: ImageCachePolicy::Default,
        },
        cache_width: Some(320),
        cache_height: Some(180),
        ..Default::default()
    };

    let same = request.clone();
    let mut resized = request.clone();
    resized.cache_width = Some(640);

    assert_eq!(request.stable_cache_key(), same.stable_cache_key());
    assert_ne!(request.stable_cache_key(), resized.stable_cache_key());
}

#[test]
fn image_source_helpers_report_path_and_network_sources() {
    assert_eq!(
        ImageSource::Asset {
            path: "assets/logo.png".into()
        }
        .local_path(),
        Some("assets/logo.png")
    );
    assert_eq!(
        ImageSource::Network {
            url: "https://example.com/logo.png".into(),
            headers: Vec::new(),
            cache_policy: ImageCachePolicy::Default,
        }
        .network_url(),
        Some("https://example.com/logo.png")
    );
}

#[test]
fn paragraph_style_compact_encoding_rejects_extended_fields() {
    assert_eq!(
        encode_text_paragraph_style(TextParagraphStyle {
            text_align: TextAlign::Start,
            max_lines: Some(2),
            overflow: TextOverflow::Visible,
            text_direction: TextDirection::Rtl,
            text_width_basis: TextWidthBasis::LongestLine,
            strut_line_height: Some(24.0),
            text_height_behavior: TextHeightBehavior {
                apply_height_to_first_ascent: false,
                apply_height_to_last_descent: true,
            },
        }),
        None
    );
}

#[test]
fn inline_widget_marker_round_trips() {
    let encoded = encode_inline_widget_marker(7, 24.5, 12.0);
    assert_eq!(
        decode_inline_widget_marker(Some(encoded.as_str())),
        Some(InlineWidgetMarker {
            id: 7,
            width: 24.5,
            height: 12.0,
        })
    );
}