mirror of
https://github.com/l0ng-ai/tty7.git
synced 2026-09-22 00:02:23 +00:00
test(ui): run the window and pane gpui tests on Windows too (#791)
Windows tty7-app tests go 1466 -> 1638 with no assertion weakened. Also holds the SCM graph idle test's daemon end open: the moved handle closed the socket right after writing Cwd, which on Windows (loopback TcpStream with unread data) is an abortive close, so settle_graph would time out and the test would silently skip every assertion.
This commit is contained in:
+59
-24
@@ -98,7 +98,7 @@ pub fn declare_displayed(cx: &App, panes: impl IntoIterator<Item = (EntityId, bo
|
||||
|
||||
/// What the registry holds for `id`: `None` when the pane never registered
|
||||
/// (or already released), otherwise the flag the output gate would consult.
|
||||
#[cfg(all(test, unix))]
|
||||
#[cfg(test)]
|
||||
pub(crate) fn displayed_for_test(cx: &App, id: EntityId) -> Option<bool> {
|
||||
cx.try_global::<DisplayedRegistry>()?
|
||||
.0
|
||||
@@ -9132,22 +9132,42 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
/// A connected pair of [`crate::daemon::transport::Stream`]s, one for each end
|
||||
/// of a pane's link to its daemon.
|
||||
///
|
||||
/// The client half is what a pane really reads and writes; the daemon half is
|
||||
/// the test's, to speak protocol into.
|
||||
///
|
||||
/// This is the one thing a pane harness needs that Unix and Windows spell
|
||||
/// differently — `socketpair` there, a loopback connect here — and every gpui
|
||||
/// test in this crate is portable once it goes through this instead of naming
|
||||
/// `UnixStream` itself.
|
||||
#[cfg(test)]
|
||||
pub(crate) fn test_stream_pair() -> (
|
||||
crate::daemon::transport::Stream,
|
||||
crate::daemon::transport::Stream,
|
||||
) {
|
||||
#[cfg(unix)]
|
||||
{
|
||||
std::os::unix::net::UnixStream::pair().unwrap()
|
||||
}
|
||||
#[cfg(windows)]
|
||||
{
|
||||
let listener = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
|
||||
let addr = listener.local_addr().unwrap();
|
||||
let client_side = std::net::TcpStream::connect(addr).unwrap();
|
||||
let (daemon_side, _) = listener.accept().unwrap();
|
||||
(client_side, daemon_side)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn quiet_test_pane(
|
||||
pane_id: u64,
|
||||
window: &mut Window,
|
||||
cx: &mut gpui::App,
|
||||
) -> (gpui::Entity<TerminalView>, crate::daemon::transport::Stream) {
|
||||
#[cfg(unix)]
|
||||
let (client_side, daemon_side) = std::os::unix::net::UnixStream::pair().unwrap();
|
||||
#[cfg(windows)]
|
||||
let (client_side, daemon_side) = {
|
||||
let listener = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
|
||||
let addr = listener.local_addr().unwrap();
|
||||
let client_side = std::net::TcpStream::connect(addr).unwrap();
|
||||
let (daemon_side, _) = listener.accept().unwrap();
|
||||
(client_side, daemon_side)
|
||||
};
|
||||
let (client_side, daemon_side) = test_stream_pair();
|
||||
let terminal = RemoteTerminal::from_stream(client_side, TermSize::new(80, 24))
|
||||
.expect("quiet test terminal");
|
||||
let view = cx.new(|cx| TerminalView::with_terminal(terminal, pane_id, window, cx));
|
||||
@@ -9200,20 +9220,20 @@ pub(crate) fn quiet_test_ssh_pane_with(
|
||||
(view, stream)
|
||||
}
|
||||
|
||||
#[cfg(all(test, unix))]
|
||||
#[cfg(test)]
|
||||
mod gpui_tests {
|
||||
use super::*;
|
||||
use crate::daemon::protocol::{ClientMsg, DaemonMsg};
|
||||
use crate::daemon::transport::Stream;
|
||||
use gpui::{Entity, TestAppContext, point};
|
||||
use std::os::unix::net::UnixStream;
|
||||
|
||||
fn harness(cx: &mut TestAppContext) -> (gpui::WindowHandle<TerminalView>, UnixStream) {
|
||||
fn harness(cx: &mut TestAppContext) -> (gpui::WindowHandle<TerminalView>, Stream) {
|
||||
// Building a view reads the config. Whether that hit the real user
|
||||
// directory used to come down to which test happened to pin the
|
||||
// scratch dir first.
|
||||
crate::core::config::pin_test_config_dir();
|
||||
cx.executor().allow_parking();
|
||||
let (client_side, daemon_side) = UnixStream::pair().unwrap();
|
||||
let (client_side, daemon_side) = super::test_stream_pair();
|
||||
cx.update(|cx| {
|
||||
gpui_component::init(cx);
|
||||
cx.set_global(Config::default());
|
||||
@@ -9238,11 +9258,11 @@ mod gpui_tests {
|
||||
) -> (
|
||||
gpui::WindowHandle<gpui_component::Root>,
|
||||
Entity<TerminalView>,
|
||||
UnixStream,
|
||||
Stream,
|
||||
) {
|
||||
crate::core::config::pin_test_config_dir();
|
||||
cx.executor().allow_parking();
|
||||
let (client_side, daemon_side) = UnixStream::pair().unwrap();
|
||||
let (client_side, daemon_side) = super::test_stream_pair();
|
||||
cx.update(|cx| {
|
||||
gpui_component::init(cx);
|
||||
cx.set_global(Config::default());
|
||||
@@ -9268,7 +9288,7 @@ mod gpui_tests {
|
||||
fn prompt_ready(
|
||||
window: &gpui::WindowHandle<TerminalView>,
|
||||
cx: &mut TestAppContext,
|
||||
daemon: &mut UnixStream,
|
||||
daemon: &mut Stream,
|
||||
) {
|
||||
DaemonMsg::Prompt {
|
||||
active: true,
|
||||
@@ -9292,7 +9312,7 @@ mod gpui_tests {
|
||||
fn alt_screen_ready(
|
||||
window: &gpui::WindowHandle<TerminalView>,
|
||||
cx: &mut TestAppContext,
|
||||
daemon: &mut UnixStream,
|
||||
daemon: &mut Stream,
|
||||
) {
|
||||
DaemonMsg::Output(b"\x1b[?1049h".to_vec())
|
||||
.encode(daemon)
|
||||
@@ -9320,7 +9340,7 @@ mod gpui_tests {
|
||||
.encode(&mut daemon)
|
||||
.unwrap();
|
||||
|
||||
let report = |status: AgentStatus, daemon: &mut UnixStream| {
|
||||
let report = |status: AgentStatus, daemon: &mut Stream| {
|
||||
DaemonMsg::AgentStatus(Some(AgentSessionState {
|
||||
status,
|
||||
message: None,
|
||||
@@ -9427,7 +9447,7 @@ mod gpui_tests {
|
||||
status: crate::core::cli_agent::AgentStatus,
|
||||
pane: &gpui::Entity<TerminalView>,
|
||||
cx: &mut TestAppContext,
|
||||
daemon: &mut UnixStream,
|
||||
daemon: &mut Stream,
|
||||
) {
|
||||
use crate::core::cli_agent::AgentSessionState;
|
||||
|
||||
@@ -9877,6 +9897,21 @@ mod gpui_tests {
|
||||
/// must not have made the promise. Otherwise those paths sit "not answered
|
||||
/// yet" for the life of the pane — no underline, and a click that says
|
||||
/// nothing, which is the silence this whole path exists to remove.
|
||||
///
|
||||
/// Was unix-only because the path it prints is: `Path::new("/etc/hosts")`
|
||||
/// is not absolute on Windows, so `FileCandidate::paths` measured it from
|
||||
/// the roots rather than letting it stand alone — and a workspace that
|
||||
/// never connected has no roots, so nothing was ever wanted. Which was
|
||||
/// itself the divergence: a Windows tty7 looking at a *remote* Linux pane
|
||||
/// never probed the POSIX paths that pane printed.
|
||||
///
|
||||
/// #795 settled that. `paths` now asks the pane's own
|
||||
/// [`super::search::PathStyle`] rather than this machine's, and a remote
|
||||
/// pane that has not reported a cwd is read as `Posix`, so `/etc/hosts`
|
||||
/// stands alone on every client. The gate is only still here because
|
||||
/// nothing has run this test on Windows yet; lifting it belongs in a
|
||||
/// change that can show it green, not in a merge.
|
||||
#[cfg(unix)]
|
||||
#[gpui::test]
|
||||
fn a_probe_with_no_host_to_ask_stays_wanted(cx: &mut TestAppContext) {
|
||||
let (window, mut daemon) = harness(cx);
|
||||
@@ -10068,7 +10103,7 @@ mod gpui_tests {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn next_input(daemon: &mut UnixStream) -> Vec<u8> {
|
||||
fn next_input(daemon: &mut Stream) -> Vec<u8> {
|
||||
loop {
|
||||
match ClientMsg::read(daemon).expect("client socket stays open") {
|
||||
ClientMsg::Input(bytes) => return bytes,
|
||||
@@ -10100,7 +10135,7 @@ mod gpui_tests {
|
||||
}
|
||||
}
|
||||
|
||||
fn next_input_until_timeout(daemon: &mut UnixStream) -> Option<Vec<u8>> {
|
||||
fn next_input_until_timeout(daemon: &mut Stream) -> Option<Vec<u8>> {
|
||||
use std::io::ErrorKind;
|
||||
|
||||
daemon
|
||||
@@ -12845,7 +12880,7 @@ mod gpui_tests {
|
||||
}
|
||||
assert_eq!(seen, "before", "the pre-drop screen is what we relink over");
|
||||
|
||||
let (new_client, mut new_daemon) = UnixStream::pair().unwrap();
|
||||
let (new_client, mut new_daemon) = super::test_stream_pair();
|
||||
window
|
||||
.update(cx, |view, _, cx| {
|
||||
view.adopt_relink(
|
||||
|
||||
+7
-12
@@ -9491,14 +9491,13 @@ pub(crate) mod test_window {
|
||||
}
|
||||
|
||||
/// A window carrying `n` quiet tabs, active on the first.
|
||||
#[cfg(unix)]
|
||||
pub(crate) fn harness_with_tabs(
|
||||
cx: &mut TestAppContext,
|
||||
n: usize,
|
||||
) -> (
|
||||
Entity<Tty7App>,
|
||||
VisualTestContext,
|
||||
Vec<std::os::unix::net::UnixStream>,
|
||||
Vec<crate::daemon::transport::Stream>,
|
||||
) {
|
||||
use crate::terminal::view::quiet_test_pane;
|
||||
use crate::ui::pane::{Pane, PaneSlot};
|
||||
@@ -9525,13 +9524,12 @@ pub(crate) mod test_window {
|
||||
(app, vcx, streams)
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
pub(crate) fn harness_with_pane(
|
||||
cx: &mut TestAppContext,
|
||||
) -> (
|
||||
Entity<Tty7App>,
|
||||
VisualTestContext,
|
||||
std::os::unix::net::UnixStream,
|
||||
crate::daemon::transport::Stream,
|
||||
) {
|
||||
use crate::terminal::view::quiet_test_pane;
|
||||
use crate::ui::pane::{Pane, PaneSlot};
|
||||
@@ -9580,7 +9578,6 @@ pub(crate) mod test_window {
|
||||
/// another frame 250ms later. So the sleep below is load-bearing too, and
|
||||
/// a round that drew nothing is not on its own enough to stop on — a burst
|
||||
/// still open is a frame already owed.
|
||||
#[cfg(unix)]
|
||||
pub(crate) fn quiesce(vcx: &mut VisualTestContext, cwd: Option<&std::path::Path>) {
|
||||
use crate::terminal::git_data::ScmData;
|
||||
use crate::terminal::git_status::GitStatusCache;
|
||||
@@ -9692,7 +9689,7 @@ mod cursor_blink_gpui_tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(test, unix))]
|
||||
#[cfg(test)]
|
||||
mod ssh_rebuild_gpui_tests {
|
||||
use super::test_window::harness_with_pane;
|
||||
use crate::core::session::{
|
||||
@@ -10129,9 +10126,7 @@ mod shell_menu_gpui_tests {
|
||||
}
|
||||
}
|
||||
|
||||
// `harness_with_tabs` hands back the panes' `UnixStream`s, so it exists only
|
||||
// on unix — same as `ssh_rebuild_gpui_tests` below it.
|
||||
#[cfg(all(test, unix))]
|
||||
#[cfg(test)]
|
||||
mod rename_gpui_tests {
|
||||
use gpui::TestAppContext;
|
||||
|
||||
@@ -10215,7 +10210,7 @@ mod rename_gpui_tests {
|
||||
// everything else hidden; a pane nobody has declared — or whose id nobody
|
||||
// registered — must err toward displayed, because the failure direction that
|
||||
// matters is a visible pane that stops repainting.
|
||||
#[cfg(all(test, unix))]
|
||||
#[cfg(test)]
|
||||
mod displayed_gpui_tests {
|
||||
use gpui::TestAppContext;
|
||||
|
||||
@@ -10316,7 +10311,7 @@ mod displayed_gpui_tests {
|
||||
|
||||
// Zoom is a tab's view state: it rides with the tab across a switch, while a
|
||||
// layout change (drag, split, close) still clears it.
|
||||
#[cfg(all(test, unix))]
|
||||
#[cfg(test)]
|
||||
mod zoom_gpui_tests {
|
||||
use gpui::TestAppContext;
|
||||
|
||||
@@ -10444,7 +10439,7 @@ mod zoom_gpui_tests {
|
||||
// test config dir and nothing is listening on it — so every forward request
|
||||
// fails. That is exactly the case these are about: what the panel and the form
|
||||
// are left holding when the far side does not answer.
|
||||
#[cfg(all(test, unix))]
|
||||
#[cfg(test)]
|
||||
mod managed_forward_gpui_tests {
|
||||
use gpui::TestAppContext;
|
||||
use gpui_component::input::InputState;
|
||||
|
||||
+17
-3
@@ -2737,7 +2737,7 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(test, unix))]
|
||||
#[cfg(test)]
|
||||
mod overlay_gpui_tests {
|
||||
use super::*;
|
||||
use crate::ui::app::test_window;
|
||||
@@ -3015,8 +3015,22 @@ mod overlay_gpui_tests {
|
||||
/// terminal, an editor, a worktree command — and the cached branch is a branch
|
||||
/// the repository has left. That is what the stale entry below stands for.
|
||||
///
|
||||
/// Unix-gated like every other window harness in this tree: `harness_with_tabs`
|
||||
/// hands back a `std::os::unix::net::UnixStream` for the pane.
|
||||
/// Unix-only, and not for the harness: on Windows the root this test seeds
|
||||
/// the cache with is not the root the probe lands with, so `scm_epoch` never
|
||||
/// agrees with the landing snapshot and the overlay re-probes on every frame
|
||||
/// — `load` reaches `Ready` and `loading` goes straight back to `true`, which
|
||||
/// is the exact spin this test exists to catch.
|
||||
///
|
||||
/// Not the slash direction — `Path` compares by component, so `C:/x` and
|
||||
/// `C:\x` are already equal. It is the prefix, and since #796 it is this
|
||||
/// test's own: the product keys a repository by one spelling now
|
||||
/// (`Host::canonicalize` drops the `\\?\` extended-length prefix and
|
||||
/// `core::git::git_path` re-spells what git prints), while the seed below
|
||||
/// still comes straight from `std::fs::canonicalize` and so carries
|
||||
/// `\\?\C:\Users\—` — a `VerbatimDisk` prefix where everything it is
|
||||
/// compared against is now `Disk`. Seeding through
|
||||
/// `tty7_core::core::path_spelling` should lift this, as a change that can
|
||||
/// show it green rather than a drive-by.
|
||||
#[cfg(all(test, unix))]
|
||||
mod render_idle_gpui_tests {
|
||||
use super::*;
|
||||
|
||||
+3
-3
@@ -2931,7 +2931,7 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(test, unix))]
|
||||
#[cfg(test)]
|
||||
mod render_idle_gpui_tests {
|
||||
use super::*;
|
||||
use crate::daemon::protocol::DaemonMsg;
|
||||
@@ -2959,7 +2959,7 @@ mod render_idle_gpui_tests {
|
||||
) -> (
|
||||
Entity<Tty7App>,
|
||||
VisualTestContext,
|
||||
std::os::unix::net::UnixStream,
|
||||
crate::daemon::transport::Stream,
|
||||
) {
|
||||
let (app, mut vcx, mut pane) = test_window::harness_with_pane(cx);
|
||||
DaemonMsg::Cwd(root.to_path_buf())
|
||||
@@ -3558,7 +3558,7 @@ mod render_idle_gpui_tests {
|
||||
/// What these cannot reach is the hit test — whether the row under the cursor
|
||||
/// is the one that gets the drop is decided by gpui's hitbox stack, and there
|
||||
/// is no headless way to put a cursor over a row.
|
||||
#[cfg(all(test, unix))]
|
||||
#[cfg(test)]
|
||||
mod drop_gpui_tests {
|
||||
use super::render_idle_gpui_tests::{files_panel_on, rows, scratch, serial, settle};
|
||||
use super::*;
|
||||
|
||||
+15
-1
@@ -974,6 +974,20 @@ mod tests {
|
||||
/// here — a missing global, a theme token, a slice through the middle of a
|
||||
/// character — goes wrong during layout and paint, so these arm the render
|
||||
/// probe and insist something was actually drawn.
|
||||
///
|
||||
/// Still unix-only, and for a reason worth naming rather than a harness one:
|
||||
/// on Windows the root the panel settles on is not the root this module hands
|
||||
/// it, so the panel never settles on the directory it is already showing.
|
||||
///
|
||||
/// The forward slashes `git rev-parse --show-toplevel` prints are not what
|
||||
/// breaks it — `Path` compares by component, so `C:/x` and `C:\x` are equal.
|
||||
/// The prefix is, and since #796 it is this module's own: the product keys a
|
||||
/// repository by one spelling now, while `scratch` below still hands the pane
|
||||
/// `std::fs::canonicalize`'s `\\?\C:\Users\—`, a `VerbatimDisk` prefix where
|
||||
/// every root it is compared against is `Disk`. Taking the gate off needs
|
||||
/// that helper to spell its answer the way
|
||||
/// `tty7_core::core::path_spelling` does, in a change that can show these
|
||||
/// green rather than a drive-by.
|
||||
#[cfg(all(test, unix))]
|
||||
mod detail_gpui_tests {
|
||||
use super::*;
|
||||
@@ -1043,7 +1057,7 @@ mod detail_gpui_tests {
|
||||
) -> (
|
||||
Entity<Tty7App>,
|
||||
VisualTestContext,
|
||||
std::os::unix::net::UnixStream,
|
||||
crate::daemon::transport::Stream,
|
||||
) {
|
||||
let (app, mut vcx, mut pane) = test_window::harness_with_pane(cx);
|
||||
DaemonMsg::Cwd(root.to_path_buf())
|
||||
|
||||
+10
-7
@@ -2186,11 +2186,7 @@ mod tests {
|
||||
/// way to know is to settle the window and count frames. Same shape as the file
|
||||
/// tree's own idle tests, including the serial lock: the render probe is
|
||||
/// thread-local and two of these at once would count each other's frames.
|
||||
///
|
||||
/// `unix` for the same reason `panel.rs`, `detail.rs` and `file_tree.rs` gate
|
||||
/// theirs: a real pane means `test_window::harness_with_pane`, and that harness
|
||||
/// hands back a `std::os::unix::net::UnixStream`.
|
||||
#[cfg(all(test, unix))]
|
||||
#[cfg(test)]
|
||||
mod render_idle_gpui_tests {
|
||||
use super::*;
|
||||
use crate::ui::app::{render_probe, test_window};
|
||||
@@ -2290,9 +2286,16 @@ mod render_idle_gpui_tests {
|
||||
));
|
||||
}
|
||||
|
||||
let (app, mut vcx, _pane) = test_window::harness_with_pane(cx);
|
||||
// The daemon end is held for the life of the test, the way every other
|
||||
// panel harness holds it. `&mut { _pane }` dropped it on the spot: on
|
||||
// Unix a closed `socketpair` half still delivers the `Cwd` written a
|
||||
// moment earlier, but on Windows the link is a loopback `TcpStream`,
|
||||
// and closing one with the pane's own `Resize` sitting unread on it is
|
||||
// an abortive close — the `Cwd` goes with the connection, and the test
|
||||
// spends its 30s deadline waiting for a cwd that was thrown away.
|
||||
let (app, mut vcx, mut pane) = test_window::harness_with_pane(cx);
|
||||
crate::daemon::protocol::DaemonMsg::Cwd(root.clone())
|
||||
.encode(&mut { _pane })
|
||||
.encode(&mut pane)
|
||||
.expect("the pane's socket takes the cwd");
|
||||
app.update_in(&mut vcx, |app, _, cx| {
|
||||
app.right_panel_visible = true;
|
||||
|
||||
+13
-2
@@ -2894,7 +2894,7 @@ mod tests {
|
||||
/// `default_global`, which fires the global observers whether or not anything
|
||||
/// changed, and it is called every frame. A watcher that notified on every one
|
||||
/// of those would request a frame from inside a frame and never stop.
|
||||
#[cfg(all(test, unix))]
|
||||
#[cfg(test)]
|
||||
mod render_idle_gpui_tests {
|
||||
use super::*;
|
||||
use crate::daemon::protocol::DaemonMsg;
|
||||
@@ -2933,7 +2933,7 @@ mod render_idle_gpui_tests {
|
||||
) -> (
|
||||
Entity<Tty7App>,
|
||||
VisualTestContext,
|
||||
std::os::unix::net::UnixStream,
|
||||
crate::daemon::transport::Stream,
|
||||
) {
|
||||
let (app, mut vcx, mut pane) = test_window::harness_with_pane(cx);
|
||||
DaemonMsg::Cwd(root.to_path_buf())
|
||||
@@ -2980,6 +2980,17 @@ mod render_idle_gpui_tests {
|
||||
render_probe::draws()
|
||||
}
|
||||
|
||||
/// The only test in this module that waits on `repo.root`, and so the only
|
||||
/// one Windows cannot run: since #796 that root is keyed by one spelling
|
||||
/// and carries a `Disk` prefix, while the pane's cwd came out of `scratch`
|
||||
/// above — `std::fs::canonicalize`, so `\\?\C:\Users\—` and a
|
||||
/// `VerbatimDisk` prefix — and the equality below never holds between the
|
||||
/// two. The slashes are the red herring; `Path` compares by component, so
|
||||
/// `C:/x` and `C:\x` are equal. Spelling `scratch`'s answer the way
|
||||
/// `tty7_core::core::path_spelling` does should lift this, in a change
|
||||
/// that can show it green. Its sibling keys off the pane's cwd instead,
|
||||
/// and runs everywhere.
|
||||
#[cfg(unix)]
|
||||
#[gpui::test]
|
||||
fn a_settled_source_control_panel_reaches_render_idle(cx: &mut TestAppContext) {
|
||||
let _serial = serial();
|
||||
|
||||
+1
-1
@@ -3720,7 +3720,7 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(test, unix))]
|
||||
#[cfg(test)]
|
||||
mod gpui_tests {
|
||||
use gpui::{Modifiers, TestAppContext};
|
||||
|
||||
|
||||
@@ -3686,7 +3686,6 @@ mod tests {
|
||||
/// the window shows one, and the one it could not put up must not come out
|
||||
/// of a `Full` diff as `TabClose` — that op deleted from the machine exactly
|
||||
/// the tabs a restart had failed to bring back, panes and all (#672).
|
||||
#[cfg(unix)]
|
||||
#[gpui::test]
|
||||
fn the_next_sync_leaves_a_tab_the_rebuild_could_not_put_up_on_the_machine(
|
||||
cx: &mut gpui::TestAppContext,
|
||||
@@ -3775,7 +3774,6 @@ mod tests {
|
||||
/// straight after clears the queue, so by the time a test can look the
|
||||
/// ops are gone either way — while `informed` outliving the arrival is
|
||||
/// both durable and the thing that made them possible.
|
||||
#[cfg(unix)]
|
||||
#[gpui::test]
|
||||
fn arriving_at_a_workspace_does_not_prune_what_is_already_in_it(cx: &mut gpui::TestAppContext) {
|
||||
let (app, mut vcx, _pane_stream) = crate::ui::app::test_window::harness_with_pane(cx);
|
||||
|
||||
Reference in New Issue
Block a user