From 16732d10af04f3b3bc20208ee182c6920a8819ff Mon Sep 17 00:00:00 2001 From: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com> Date: Sun, 16 Aug 2026 14:09:53 +0800 Subject: [PATCH] test(daemon): hold two more calls that nothing was holding Same shape as the last commit, found the same way -- delete a call and count what notices. Both were zero. `restored_screen` drops the snapshot it hands out, which the privacy page states and the function's own comment explains: a copy left behind could only ever put the same screen into a second pane. The test covers both branches, because that comment is careful about the difference -- an empty snapshot is not a screen worth restoring, but its file still goes, and only the return value turns on emptiness. The startup sweep is the one that cost something already: without it, 4,457 shell-integration directories piled up in TMPDIR, and the three tests beside the new one hold what the sweep does rather than that anyone runs it. Its only caller binds a listener and then serves forever, which no unit test can enter and which the e2e harness starts before a test body can plant anything. So that guard reads the source, and its comment says what that is worth: it proves the call is written, not that it is reached. A sweep moved somewhere unreachable would still pass. It catches deletion, which is how it broke. --- crates/tty7-core/src/daemon/server.rs | 55 +++++++++++++++++++ .../tty7-core/src/daemon/shell_integration.rs | 21 +++++++ 2 files changed, 76 insertions(+) diff --git a/crates/tty7-core/src/daemon/server.rs b/crates/tty7-core/src/daemon/server.rs index 96db5fd6..df7d5ff8 100644 --- a/crates/tty7-core/src/daemon/server.rs +++ b/crates/tty7-core/src/daemon/server.rs @@ -1257,6 +1257,61 @@ fn spawn_writer( #[cfg(test)] mod tests { + /// A restore consumes the snapshot it was handed, either way. + /// + /// The privacy page says a restore consumes the file, and + /// [`restored_screen`]'s comment says why: a copy left behind could only + /// ever put the same screen into a second pane. Deleting the `forget` call + /// there left the suite green, so this holds the call rather than the + /// function. + /// + /// Both branches, because the comment is careful about the difference: an + /// empty snapshot is not a screen worth handing over, but the file still + /// goes. Only the return value turns on emptiness. + #[test] + fn a_restore_consumes_the_snapshot_even_when_it_holds_nothing() { + let dir = std::env::temp_dir().join(format!("tty7-restore-{}", std::process::id())); + std::fs::create_dir_all(&dir).ok(); + crate::core::config::set_config_dir(dir); + + let size = crate::daemon::protocol::WinSize { + cols: 80, + rows: 24, + cell_w: 8, + cell_h: 16, + }; + let request = |pane_id| crate::daemon::protocol::RestoreFrom { + pane_id, + banner: None, + }; + + let held = 92_001; + crate::daemon::scrollback::save( + held, + &[crate::daemon::scrollback::Segment { + size, + bytes: b"what the dead pane had on it".to_vec(), + }], + ); + let restored = restored_screen(request(held)).expect("a screen to hand over"); + assert_eq!(restored.segments.len(), 1, "the screen came back"); + assert!( + crate::daemon::scrollback::load(held).is_none(), + "the snapshot outlived the restore that consumed it" + ); + + let empty = 92_002; + crate::daemon::scrollback::save(empty, &[]); + assert!( + restored_screen(request(empty)).is_none(), + "an empty snapshot is not a screen to restore" + ); + assert!( + crate::daemon::scrollback::load(empty).is_none(), + "a file nobody will read again was left on disk" + ); + } + /// Closing a pane takes its stored screen with it. /// /// The privacy page promises the file goes "at once", and [`kill_pane`]'s diff --git a/crates/tty7-core/src/daemon/shell_integration.rs b/crates/tty7-core/src/daemon/shell_integration.rs index 8db829f1..662ec073 100644 --- a/crates/tty7-core/src/daemon/shell_integration.rs +++ b/crates/tty7-core/src/daemon/shell_integration.rs @@ -2853,6 +2853,27 @@ mod tests { /// The sweep deletes, so what it declines to match matters more than what /// it matches. `tty7-zdotdir-wsl` is a real name this module writes, and a /// pid is the one thing that makes a directory safe to judge. + /// The daemon still calls the sweep on startup. + /// + /// The three tests below hold what [`sweep_dead_zdotdirs`] does; none of + /// them holds that anyone runs it, and deleting the call from the daemon's + /// startup left the whole suite green. That is how the directories piled + /// up in the first place — 4,457 of them — so the call is worth a guard of + /// its own. + /// + /// It reads the source because the only caller binds a listener and then + /// serves forever, which no unit test can enter. So this proves the call + /// is written, not that it is reached: a sweep moved somewhere that never + /// runs would still pass. It catches deletion, which is the way it broke. + #[test] + fn the_daemon_startup_still_calls_the_sweep() { + const STARTUP: &str = include_str!("server.rs"); + assert!( + STARTUP.contains("shell_integration::sweep_dead_zdotdirs()"), + "nothing in the daemon calls the sweep any more" + ); + } + #[test] fn only_a_named_pid_makes_a_directory_ours_to_sweep() { // Every shell that takes a scratch directory, not just zsh: bash's had