This commit is contained in:
Antonio Scandurra 2021-09-01 13:50:39 +02:00
parent c7a8972a57
commit c8d67f428d
2 changed files with 110 additions and 2 deletions

View File

@ -567,7 +567,13 @@ impl<'a> sum_tree::SeekDimension<'a, ListItemSummary> for Height {
#[cfg(test)]
mod tests {
use super::*;
use crate::{elements::*, geometry::vector::vec2f, Entity, RenderContext, View};
use crate::{
elements::{ConstrainedBox, Empty},
geometry::vector::vec2f,
Entity, RenderContext, View,
};
use rand::prelude::*;
use std::env;
#[crate::test(self)]
fn test_layout(cx: &mut crate::MutableAppContext) {
@ -653,6 +659,106 @@ mod tests {
assert_eq!(state.0.borrow().scroll_top(size.y()), 114.);
}
#[crate::test(self, iterations = 10000, seed = 2515)]
fn test_random(cx: &mut crate::MutableAppContext, mut rng: StdRng) {
let operations = env::var("OPERATIONS")
.map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
.unwrap_or(10);
let mut presenter = cx.build_presenter(0, 0.);
let elements = Rc::new(RefCell::new(
(0..rng.gen_range(0..=20))
.map(|_| rng.gen_range(0_f32..=100_f32))
.collect::<Vec<_>>(),
));
let orientation = *[Orientation::Top, Orientation::Bottom]
.choose(&mut rng)
.unwrap();
let min_overdraw = rng.gen_range(0..=20);
let state = ListState::new(elements.borrow().len(), orientation, min_overdraw, {
let elements = elements.clone();
move |ix, _| item(elements.borrow()[ix])
});
let mut width = rng.gen_range(0_f32..=1000_f32);
let mut height = rng.gen_range(0_f32..=1000_f32);
log::info!("orientation: {:?}", orientation);
log::info!("min_overdraw: {}", min_overdraw);
log::info!("elements: {:?}", elements.borrow());
log::info!("size: ({:?}, {:?})", width, height);
log::info!("==================");
let mut scroll_top = None;
for _ in 0..operations {
match rng.gen_range(0..=100) {
0..=29 if scroll_top.is_some() => {
let delta = vec2f(0., rng.gen_range(-100_f32..=100_f32));
log::info!(
"Scrolling by {:?}, previous scroll top: {:?}",
delta,
scroll_top.unwrap()
);
state.0.borrow_mut().scroll(
scroll_top.as_ref().unwrap(),
height,
delta,
true,
&mut presenter.build_event_context(cx),
);
}
30..=34 => {
width = rng.gen_range(0_f32..=1000_f32);
log::info!("changing width: {:?}", width);
}
35..=54 => {
height = rng.gen_range(0_f32..=1000_f32);
log::info!("changing height: {:?}", height);
}
_ => {
let mut elements = elements.borrow_mut();
let end_ix = rng.gen_range(0..=elements.len());
let start_ix = rng.gen_range(0..=end_ix);
let new_elements = (0..rng.gen_range(0..10))
.map(|_| rng.gen_range(0_f32..=100_f32))
.collect::<Vec<_>>();
log::info!("splice({:?}, {:?})", start_ix..end_ix, new_elements);
state.splice(start_ix..end_ix, new_elements.len());
elements.splice(start_ix..end_ix, new_elements);
}
}
let mut list = List::new(state.clone());
let (size, new_scroll_top) = list.layout(
SizeConstraint::new(vec2f(0., 0.), vec2f(width, height)),
&mut presenter.build_layout_context(cx),
);
assert_eq!(size, vec2f(width, height));
scroll_top = Some(new_scroll_top);
let state = state.0.borrow();
let visible_range = state.visible_range(height, &new_scroll_top);
let rendered_range =
visible_range.start.saturating_sub(min_overdraw)..visible_range.end + min_overdraw;
log::info!("visible range {:?}", visible_range);
log::info!("items {:?}", state.items.items(&()));
for (ix, item) in state.items.cursor::<Count, ()>().enumerate() {
if rendered_range.contains(&ix) {
assert!(
matches!(item, ListItem::Rendered(_)),
"item {:?} was not rendered",
ix
);
} else {
assert!(
!matches!(item, ListItem::Rendered(_)),
"item {:?} was incorrectly rendered",
ix
);
}
}
}
}
fn item(height: f32) -> ElementBox {
ConstrainedBox::new(Empty::new().boxed())
.with_height(height)

View File

@ -2,5 +2,7 @@ use ctor::ctor;
#[ctor]
fn init_logger() {
env_logger::init();
env_logger::builder()
.filter_level(log::LevelFilter::Info)
.init();
}