use super::*;
use cranpose_core::NodeId;
use cranpose_foundation::lazy::{remember_lazy_list_state, LazyListScope};
use cranpose_ui_graphics::Size as ViewportSize;
fn compose_lazy_swipe_rows() -> TestComposition {
run_test_composition(|| {
let list_state = remember_lazy_list_state();
LazyColumn(
Modifier::empty().fill_max_size(),
list_state,
LazyColumnSpec::default(),
|scope| {
scope.items(
5,
None::<fn(usize) -> u64>,
None::<fn(usize) -> u64>,
|index| {
SwipeToDismiss(
Modifier::empty().fill_max_width().height(48.0),
SwipeToDismissSpec::default(),
|| {},
move || {
Text(
format!("Row {index}"),
Modifier::empty(),
TextStyle::default(),
);
},
);
},
);
},
);
})
}
fn measure(composition: &mut TestComposition, root: NodeId) {
let handle = composition.runtime_handle();
let mut applier = composition.applier_mut();
applier.set_runtime_handle(handle);
measure_layout(
&mut applier,
root,
ViewportSize {
width: 320.0,
height: 480.0,
},
)
.expect("layout measurement");
applier.clear_runtime_handle();
}
fn layout_texts(tree: &crate::LayoutTree) -> Vec<String> {
fn walk(node: &crate::LayoutBox, out: &mut Vec<String>) {
if let Some(text) = node.node_data.modifier_slices().text_content() {
out.push(text.to_string());
}
for child in &node.children {
walk(child, out);
}
}
let mut out = Vec::new();
walk(tree.root(), &mut out);
out
}
fn semantics_descriptions(tree: &crate::SemanticsTree) -> Vec<String> {
fn walk(node: &crate::SemanticsNode, out: &mut Vec<String>) {
if let Some(description) = &node.description {
out.push(description.clone());
}
for child in &node.children {
walk(child, out);
}
}
let mut out = Vec::new();
walk(tree.root(), &mut out);
out
}
#[test]
fn swipe_to_dismiss_renders_content_inside_lazy_column_item() {
let mut composition = compose_lazy_swipe_rows();
let root = composition.root().expect("lazy column root");
measure(&mut composition, root);
let handle = composition.runtime_handle();
let mut applier = composition.applier_mut();
applier.set_runtime_handle(handle);
let tree = crate::build_layout_tree_from_applier(&mut applier, root)
.expect("layout tree build")
.expect("layout tree present");
applier.clear_runtime_handle();
let texts = layout_texts(&tree);
assert!(
texts.iter().any(|text| text == "Row 0"),
"SwipeToDismiss content must appear in the applier-traversal layout build, got {texts:?}"
);
}
#[test]
fn swipe_to_dismiss_exposes_semantics_inside_lazy_column_item() {
let mut composition = compose_lazy_swipe_rows();
let root = composition.root().expect("lazy column root");
measure(&mut composition, root);
let handle = composition.runtime_handle();
let mut applier = composition.applier_mut();
applier.set_runtime_handle(handle);
let tree = crate::build_semantics_tree_from_applier(&mut applier, root)
.expect("semantics tree build")
.expect("semantics tree present");
applier.clear_runtime_handle();
let descriptions = semantics_descriptions(&tree);
assert!(
descriptions
.iter()
.any(|description| description == "Row 0"),
"SwipeToDismiss semantics must appear in the applier-traversal build, got {descriptions:?}"
);
}