//! The smallest tree that lays out differently on a second frame, shrunk from //! a 402-widget one `tests/shrink.rs` grew. Both of these fail: a cold frame //! leaves a wrapping text shaped at a width it was measured in rather than the //! one it was given, and a repaint is what puts it right. So the warm-against- //! cold oracle in `generated.rs` has been comparing against a tree that had //! not settled, and some of what it called a warm defect is the cold side //! being wrong. use iris::harness::Harness; use iris::prelude::*; /// Six widgets, shrunk from a 402-widget tree the fuzzer found. Nothing about /// the tree changes -- every widget is marked for redraw and the frame is /// taken again -- so no box may move, and a warm frame has to land where a /// cold one does. fn plant(h: &mut Harness) -> Vec { let plain = wtext("Wrapping").size(16).wrap(false).add(&mut h.rsc); let wrapped = wtext("Wrapping shapes").size(16).wrap(true).add(&mut h.rsc); let sized = SetSize { inner: wrapped.add_strong(&mut h.rsc), x: Some(Len::px(76.0)), y: None, } .add(&mut h.rsc); let aligned = Aligned { inner: sized.add_strong(&mut h.rsc), align: Align { x: Some(AxisAlign::Pos), y: Some(AxisAlign::Pos), }, } .add(&mut h.rsc); let stack = Stack { children: vec![plain.add_strong(&mut h.rsc), aligned.add_strong(&mut h.rsc)], size: StackSize::Child(0), } .add(&mut h.rsc); let root = (stack,).span(Dir::RIGHT).add(&mut h.rsc); h.set_root(root); vec![ plain.id(), wrapped.id(), sized.id(), aligned.id(), stack.id(), root.id(), ] } /// The first frame does not reach the layout a second one does, so "cold" is /// not a fixed point and comparing against it compares against a tree that /// has not settled. #[test] fn one_frame_is_enough() { let mut h = Harness::new((640, 900)); let ids = plant(&mut h); let first = h.region(&ids[1]).unwrap(); for _ in 0..3 { for &id in &ids { h.rsc.widgets_mut().get_dyn_mut(id); } h.frame(); } let settled = h.region(&ids[1]).unwrap(); println!( "first frame {} tall, settled {} tall", first.bot_right.y - first.top_left.y, settled.bot_right.y - settled.top_left.y ); assert_eq!( first.bot_right.y - first.top_left.y, settled.bot_right.y - settled.top_left.y, "the first frame had not finished laying out" ); } #[test] fn repainting_everything_moves_nothing() { let mut warm = Harness::new((640, 900)); let ids = plant(&mut warm); for &id in &ids { warm.rsc.widgets_mut().get_dyn_mut(id); } warm.frame(); let mut cold = Harness::new((640, 900)); let cold_ids = plant(&mut cold); let mut wrong = Vec::new(); for (i, (&w, &c)) in ids.iter().zip(&cold_ids).enumerate() { let (got, want) = (warm.region(&w), cold.region(&c)); if got != want { wrong.push(format!("widget {i}: warm {got:?} cold {want:?}")); } } assert!(wrong.is_empty(), "{}", wrong.join("\n")); }