tawasuyu

tawasuyu/llimphi

Sovereign retained-mode GPU UI framework in Rust (wgpu+vello+taffy+parley), Elm loop, 40+ widgets.

Rust 660Markdown 302TOML 157RON 312382 Sutichaykuna

⎇ main llimphi-compositor/tests/intrinsic_measure.rs Rust · 89 siq'ikuna · 3.7 KB Ñawpa willay Pi imata llamkarqan ch'uya

chore: refresco desde el monorepo — vello 0.9 / wgpu 29, 120 miembros d251eb32b · Sergio ·

1//! Verifica el contrato de [`measure_intrinsic_node`]: una hoja de contenido
2//! REEMPLAZADO (una imagen) aporta **0 a min-content y su tamaño natural a
3//! max-content**.
4//!
5//! No es una sutileza: es lo único que un `Style` no puede expresar, y cada
6//! forma de escribirlo con `Style` solo rompe una punta distinta —medidas las
7//! dos sobre el corpus de puriy antes de llegar acá—:
8//!   - tamaño DEFINIDO → aporta el natural a las dos, y un contenedor con
9//!     `max-width` no puede encoger por debajo del ancho de su imagen.
10//!   - tamaño en PORCENTAJE → aporta 0 a las dos, y adentro de un padre
11//!     shrink-to-fit (un `float`) la imagen DESAPARECE.
12use llimphi_compositor::{measure_intrinsic_node, mount, IntrinsicSize, View};
13use llimphi_layout::taffy::prelude::*;
14use llimphi_layout::taffy::{AvailableSpace, Size as TSize};
15use llimphi_layout::LayoutTree;
16
17const NAT: IntrinsicSize = IntrinsicSize { width: 600.0, height: 300.0 };
18
19fn medir(w: AvailableSpace) -> TSize<f32> {
20    measure_intrinsic_node(
21        &NAT,
22        TSize { width: None, height: None },
23        TSize { width: w, height: AvailableSpace::MaxContent },
24    )
25}
26
27#[test]
28fn min_content_es_cero_y_max_content_es_el_natural() {
29    assert_eq!(medir(AvailableSpace::MaxContent).width, 600.0, "max-content = ancho natural");
30    assert_eq!(medir(AvailableSpace::MinContent).width, 0.0, "min-content = 0: puede encoger");
31}
32
33#[test]
34fn con_ancho_definido_nunca_pasa_del_natural_ni_del_disponible() {
35    assert_eq!(medir(AvailableSpace::Definite(200.0)).width, 200.0, "más chico: se adapta");
36    assert_eq!(medir(AvailableSpace::Definite(900.0)).width, 600.0, "más grande: no se estira");
37}
38
39#[test]
40fn el_alto_sigue_la_proporcion() {
41    let m = medir(AvailableSpace::Definite(300.0));
42    assert_eq!((m.width, m.height), (300.0, 150.0), "600x300 a la mitad = 300x150");
43    // Con el alto ya decidido por el layout, se respeta.
44    let fijo = measure_intrinsic_node(
45        &NAT,
46        TSize { width: None, height: Some(90.0) },
47        TSize { width: AvailableSpace::Definite(300.0), height: AvailableSpace::MaxContent },
48    );
49    assert_eq!(fijo.height, 90.0, "un alto conocido manda sobre la proporción");
50}
51
52/// Un natural degenerado (0 en un eje) no debe dividir por cero.
53#[test]
54fn un_natural_degenerado_no_rompe() {
55    let cero = IntrinsicSize { width: 0.0, height: 0.0 };
56    let m = measure_intrinsic_node(
57        &cero,
58        TSize { width: None, height: None },
59        TSize { width: AvailableSpace::MaxContent, height: AvailableSpace::MaxContent },
60    );
61    assert!(m.width.is_finite() && m.height.is_finite(), "sin NaN ni infinito: {m:?}");
62}
63
64/// Extremo a extremo: la medida se registra en el `mount` y el layout la usa.
65/// Una imagen de 600px dentro de un contenedor de 200 se adapta a 200 (no
66/// desborda) y conserva la proporción.
67#[test]
68fn el_mount_registra_la_medida_y_el_layout_la_usa() {
69    let mut lt = LayoutTree::new();
70    let vista: View<()> = View::new(Style {
71        size: TSize { width: length(200.0), height: auto() },
72        ..Default::default()
73    })
74    .children(vec![View::new(Style::default()).intrinsic(600.0, 300.0)]);
75    let m = mount(&mut lt, vista);
76    assert_eq!(m.intrinsic_measures.len(), 1, "la hoja quedó registrada para medir");
77
78    lt.compute_with_measure(m.root, (1000.0, 1000.0), |nid, known, avail| {
79        match m.intrinsic_measures.get(&nid) {
80            Some(nat) => measure_intrinsic_node(nat, known, avail),
81            None => TSize::ZERO,
82        }
83    })
84    .expect("layout");
85    let hoja = lt.inner().children(m.root).unwrap()[0];
86    let l = lt.inner().layout(hoja).unwrap();
87    assert_eq!(l.size.width, 200.0, "se adapta al contenedor en vez de desbordarlo");
88    assert_eq!(l.size.height, 100.0, "y conserva la proporción 2:1");
89}