From 60175c38212324aef735ffe3a74fcd65d9513ee3 Mon Sep 17 00:00:00 2001 From: iris-ai <4+iris-ai@noreply.localhost> Date: Mon, 14 Sep 2026 23:51:29 -0400 Subject: [PATCH] Check that measuring a text and giving it that width is a fixed point MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A span that sizes to its children measures one, is told a length, and hands that length back -- so whether measurement is idempotent decides whether the two chase each other. Nothing checked it. It holds: a wrapping text in a `Dir::RIGHT` span, which is the wrap axis and the span's own axis together, stays at 881.84 across six repaints that change nothing. So the narrowing recorded against LAYOUT.md ยง4 is not something text does on its own, and looking for the cause there is looking in the wrong place. Co-Authored-By: Claude Opus 5 --- tests/idempotence.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 tests/idempotence.rs diff --git a/tests/idempotence.rs b/tests/idempotence.rs new file mode 100644 index 0000000..2f8423f --- /dev/null +++ b/tests/idempotence.rs @@ -0,0 +1,29 @@ +//! Whether measuring a widget and then giving it the length it reported is a +//! fixed point, which is what a span that sizes to its children needs. + +use iris::harness::Harness; +use iris::prelude::*; + +#[test] +fn a_wrapping_text_in_a_span_settles_on_one_width() { + let mut h = Harness::new((900, 600)); + let words = "the quick brown fox jumps over the lazy dog and keeps on running \ + until it reaches the end of a rather long line of text"; + let t = wtext(words).size(16).wrap(true).add(&mut h.rsc); + let filler = rect(Color::BLUE).add(&mut h.rsc); + h.set_root((t, filler).span(Dir::RIGHT)); + + let mut widths = Vec::new(); + for _ in 0..6 { + let r = h.region(&t.id()).unwrap(); + widths.push(r.bot_right.x - r.top_left.x); + // Redrawing it changes nothing about the state, so nothing may move. + h.rsc.widgets_mut().get_dyn_mut(t.id()); + h.frame(); + } + println!("widths over six frames: {widths:?}"); + assert!( + widths.windows(2).all(|w| w[0] == w[1]), + "a repaint that changed nothing moved it: {widths:?}" + ); +}