From f7782252c8e79ea996e5a6ab08aec41391a7954e Mon Sep 17 00:00:00 2001 From: Harold Hunt Date: Sun, 27 Sep 2026 09:52:45 -0400 Subject: [PATCH 1/2] test: wait for widening scans to finish before assertions Co-authored-by: Abdulwahab Isam <5349989+ai94iq@users.noreply.github.com> --- crates/disktree-app/src/tests.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/crates/disktree-app/src/tests.rs b/crates/disktree-app/src/tests.rs index 2eb15d2..d443290 100644 --- a/crates/disktree-app/src/tests.rs +++ b/crates/disktree-app/src/tests.rs @@ -1045,11 +1045,15 @@ fn finish_scan(view: &Entity, cx: &mut Window) { let epoch = read(view, cx, |app| app.scan_epoch); for _ in 0..600 { std::thread::sleep(std::time::Duration::from_millis(5)); - let ready = update(view, cx, |app, cx| { - app.poll_scan_once(epoch, cx); - app.tree().is_some() - }); - if ready { + // Widening keeps the old tree visible while the new scan runs. + // Its presence does not mean the requested scan has completed. + let running = update(view, cx, |app, cx| app.poll_scan_once(epoch, cx)); + if !running { + assert!( + read(view, cx, |app| app.scan_error.is_none()), + "the scan failed" + ); + assert!(read(view, cx, |app| app.tree().is_some())); return; } } From ddb4cea6c9f0a2ee47e8fe984e3e81345fe5f9e0 Mon Sep 17 00:00:00 2001 From: Harold Hunt Date: Wed, 30 Sep 2026 22:30:56 -0400 Subject: [PATCH 2/2] test: make finish_scan refuse to wait on no scan and report why it failed The first-scan test now uses the helper instead of its own copy of the old wait loop. --- crates/disktree-app/src/tests.rs | 38 ++++++++++++++------------------ 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/crates/disktree-app/src/tests.rs b/crates/disktree-app/src/tests.rs index d443290..38888e3 100644 --- a/crates/disktree-app/src/tests.rs +++ b/crates/disktree-app/src/tests.rs @@ -131,19 +131,7 @@ fn the_first_scan_shows_what_it_is_doing_then_the_treemap( assert!(read(&view, cx, |app| app.tree().is_none())); assert!(cx.debug_bounds("disktree-root").is_some()); - let epoch = read(&view, cx, |app| app.scan_epoch); - let mut ready = false; - for _ in 0..600 { - std::thread::sleep(std::time::Duration::from_millis(5)); - ready = update(&view, cx, |app, cx| { - app.poll_scan_once(epoch, cx); - app.tree().is_some() - }); - if ready { - break; - } - } - assert!(ready, "the scan landed"); + finish_scan(&view, cx); draw(cx); let (tiles, selected, hidden_present) = update(&view, cx, |app, _| { @@ -1040,20 +1028,28 @@ fn after_descending_every_tile_is_inside_the_directory_drawn( assert_eq!(hatched, 1, "exactly the marked tile is hatched"); } -/// Drive the scan the view started until its tree lands. +/// Drive the scan the view started until its outcome has been applied. +/// +/// The scan is what is waited on, not the tree: widening keeps the old tree +/// on screen while the wider root is read, so a tree being there does not +/// mean the requested scan has completed. fn finish_scan(view: &Entity, cx: &mut Window) { + // Without a scan in flight the poller reports "stopped" at once, and the + // wait would pass without having waited for anything. + assert!( + read(view, cx, |app| app.scan.is_some()), + "no scan to finish" + ); let epoch = read(view, cx, |app| app.scan_epoch); for _ in 0..600 { std::thread::sleep(std::time::Duration::from_millis(5)); - // Widening keeps the old tree visible while the new scan runs. - // Its presence does not mean the requested scan has completed. let running = update(view, cx, |app, cx| app.poll_scan_once(epoch, cx)); if !running { - assert!( - read(view, cx, |app| app.scan_error.is_none()), - "the scan failed" - ); - assert!(read(view, cx, |app| app.tree().is_some())); + let (error, tree) = read(view, cx, |app| { + (app.scan_error.clone(), app.tree().is_some()) + }); + assert_eq!(error, None, "the scan failed"); + assert!(tree, "the scan landed without a tree"); return; } }