gioser

tawasuyu/llimphi

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

Rust 484Markdown 258TOML 131RON 38118 Sutichaykuna

⎇ main llimphi-voxel/tests/historia.rs Rust · 144 siq'ikuna · 5.4 KB Ñawpa willay Pi imata llamkarqan ch'uya

chore: refresco desde el monorepo — 27 crates nuevos (anim, lottie, svg, mesh, image, layer, test, wire-view, widgets rag-sidebar/router/lazy-list/rive-button) y sync de los 95 existentes 93253cc22 · Sergio ·

1// =============================================================================
2//  llimphi-voxel :: tests/historia — versiones, alternativas, dedup por contenido
3// -----------------------------------------------------------------------------
4//  El DAG sobre el que se monta todo: commitear versiones, reconstruir el
5//  proyecto de cualquiera, ramificar alternativas, seguir el linaje, y que
6//  snapshots idénticos se guarden una sola vez.
7// =============================================================================
8
9use llimphi_voxel::{Historia, Project};
10
11#[test]
12fn commitea_y_reconstruye_el_proyecto() {
13    let mut h = Historia::nueva();
14    assert!(h.is_empty());
15
16    let v1 = h.commit(&Project::nacimiento(), "el nacimiento").unwrap();
17    assert_eq!(h.len(), 1);
18    assert_eq!(h.punta(), Some(v1));
19
20    // El proyecto de la versión reconstruye el snapshot íntegro.
21    let recuperado = h.proyecto_de(&v1).expect("la versión existe");
22    assert!(recuperado.validar_referencias().is_empty());
23    assert_eq!(recuperado.escenas[0].name, "el nacimiento");
24}
25
26#[test]
27fn la_cadena_de_versiones_es_el_linaje() {
28    let mut h = Historia::nueva();
29    let mut p = Project::nacimiento();
30    let v1 = h.commit(&p, "v1: el nacimiento").unwrap();
31    // Editar y commitear otra versión.
32    if let Some(esc) = p.escenas.first_mut() {
33        if let Some(atm) = esc.atmosfera.as_mut() {
34            atm.bruma = 4.0; // más bruma
35        }
36    }
37    let v2 = h.commit(&p, "v2: más bruma").unwrap();
38
39    // El linaje de v2 = [v2, v1].
40    assert_eq!(h.linaje(&v2), vec![v2, v1]);
41    // El padre de v2 es v1.
42    assert_eq!(h.version(&v2).unwrap().padres, vec![v1]);
43    // La punta avanzó a v2.
44    assert_eq!(h.punta(), Some(v2));
45}
46
47#[test]
48fn las_ramas_son_alternativas() {
49    let mut h = Historia::nueva();
50    let base = h.commit(&Project::nacimiento(), "base").unwrap();
51
52    // Ramificar dos alternativas desde la base.
53    h.ramificar("con-montañas").unwrap();
54    h.ramificar("sin-bruma").unwrap();
55
56    // En "con-montañas": una versión con montañas.
57    assert!(h.cambiar_rama("con-montañas"));
58    let mut p = h.proyecto_actual().unwrap();
59    p.biomas[0].mountains = 0.6;
60    let alt_a = h.commit(&p, "el nacimiento con montañas").unwrap();
61
62    // En "sin-bruma": otra versión, hermana de la anterior (mismo padre `base`).
63    assert!(h.cambiar_rama("sin-bruma"));
64    let mut p = h.proyecto_actual().unwrap();
65    p.escenas[0].atmosfera = None;
66    let alt_b = h.commit(&p, "el nacimiento despejado").unwrap();
67
68    // alt_a y alt_b son ALTERNATIVAS: comparten el padre `base`.
69    assert_eq!(h.version(&alt_a).unwrap().padres, vec![base]);
70    assert_eq!(h.version(&alt_b).unwrap().padres, vec![base]);
71    assert!(h.alternativas(&alt_a).contains(&alt_b));
72    assert!(h.alternativas(&alt_b).contains(&alt_a));
73
74    // Y cada rama reconstruye SU proyecto.
75    assert_eq!(h.proyecto_de(&alt_a).unwrap().biomas[0].mountains, 0.6);
76    assert!(h.proyecto_de(&alt_b).unwrap().escenas[0].atmosfera.is_none());
77}
78
79#[test]
80fn snapshots_identicos_se_dedupean() {
81    let mut h = Historia::nueva();
82    // Dos versiones del MISMO proyecto: distinta versión (distinto orden), pero
83    // el snapshot es el mismo hash → un solo blob almacenado.
84    let p = Project::nacimiento();
85    let v1 = h.commit(&p, "una").unwrap();
86    h.ramificar("otra").unwrap();
87    h.cambiar_rama("otra");
88    let v2 = h.commit(&p, "otra").unwrap();
89
90    assert_ne!(v1, v2, "son versiones distintas");
91    // Pero apuntan al MISMO snapshot (contenido idéntico).
92    assert_eq!(h.version(&v1).unwrap().snapshot, h.version(&v2).unwrap().snapshot);
93}
94
95#[test]
96fn navegar_vuelve_a_una_version_y_bifurca_desde_ahi() {
97    let mut h = Historia::nueva();
98    let mut p = Project::nacimiento();
99    let v1 = h.commit(&p, "v1").unwrap();
100    p.biomas[0].mountains = 0.5;
101    let v2 = h.commit(&p, "v2 con montañas").unwrap();
102    assert_eq!(h.actual(), Some(v2));
103
104    // Volver (checkout) a v1: la cabeza se mueve y reconstruye ESE proyecto.
105    let vuelto = h.checkout(&v1).expect("v1 existe");
106    assert_eq!(h.actual(), Some(v1));
107    assert!(vuelto.biomas[0].mountains < 0.1, "v1 no tenía montañas");
108
109    // Bifurcar desde el pasado: un commit ahora cuelga de v1, no de v2.
110    let mut p = vuelto;
111    p.escenas[0].atmosfera = None;
112    let v3 = h.commit(&p, "v3 desde v1, despejado").unwrap();
113    assert_eq!(h.version(&v3).unwrap().padres, vec![v1]);
114    // v2 y v3 son alternativas (ambas cuelgan de v1).
115    assert!(h.alternativas(&v3).contains(&v2));
116}
117
118#[test]
119fn versiones_ordenadas_por_creacion() {
120    let mut h = Historia::nueva();
121    let a = h.commit(&Project::nacimiento(), "a").unwrap();
122    let b = h.commit(&Project::nacimiento(), "b").unwrap();
123    let orden: Vec<_> = h.versiones_ordenadas().into_iter().map(|(id, _)| id).collect();
124    assert_eq!(orden, vec![a, b], "en orden de creación");
125}
126
127#[test]
128fn la_historia_viaja_por_archivo() {
129    let mut h = Historia::nueva();
130    let v1 = h.commit(&Project::nacimiento(), "el nacimiento").unwrap();
131    h.ramificar("variante").unwrap();
132
133    let bytes = h.a_bytes().unwrap();
134    let recuperada = Historia::de_bytes(&bytes).unwrap();
135
136    assert_eq!(recuperada.len(), h.len());
137    assert_eq!(recuperada.punta(), Some(v1));
138    assert!(recuperada.ramas().contains_key("variante"));
139    // El proyecto sobrevive el round-trip de la historia.
140    assert_eq!(
141        recuperada.proyecto_de(&v1).unwrap().escenas[0].name,
142        "el nacimiento"
143    );
144}