use crate::{ persistence::DebuggerPaneItem, tests::{start_debug_session, start_debug_session_with}, *,};use dap::{ ErrorResponse, Message, RunInTerminalRequestArguments, SourceBreakpoint, StartDebuggingRequestArguments, StartDebuggingRequestArgumentsRequest, adapters::DebugTaskDefinition, client::SessionId, requests::{ Continue, Disconnect, Launch, Next, RunInTerminal, SetBreakpoints, StackTrace, StartDebugging, StepBack, StepIn, StepOut, Threads, },};use editor::{ ActiveDebugLine, Editor, EditorMode, MultiBuffer, actions::{self},};use gpui::{BackgroundExecutor, TestAppContext, VisualTestContext};use project::{ FakeFs, Project, debugger::session::{ThreadId, ThreadStatus},};use serde_json::json;use std::{ path::Path, sync::{ Arc, atomic::{AtomicBool, Ordering}, },};use terminal_view::terminal_panel::TerminalPanel;use tests::{active_debug_session_panel, init_test, init_test_workspace};use util::path;use workspace::item::SaveOptions;use workspace::{Item, dock::Panel}; #[gpui::test]async fn test_basic_show_debug_panel(executor: BackgroundExecutor, cx: &mut TestAppContext) { init_test(cx); let fs = FakeFs::new(executor.clone()); fs.insert_tree( path!("/project"), json!({ "main.rs": "First line\nSecond line\nThird line\nFourth line", }), ) .await; let project = Project::test(fs, [path!("/project").as_ref()], cx).await; let workspace = init_test_workspace(&project, cx).await; let cx = &mut VisualTestContext::from_window(*workspace, cx); let session = start_debug_session(&workspace, cx, |_| {}).unwrap(); let client = session.update(cx, |session, _| session.adapter_client().unwrap()); client.on_request::<Threads, _>(move |_, _| { Ok(dap::ThreadsResponse { threads: vec![dap::Thread { id: 1, name: "Thread 1".into(), }], }) }); client.on_request::<StackTrace, _>(move |_, _| { Ok(dap::StackTraceResponse { stack_frames: Vec::default(), total_frames: None, }) }); cx.run_until_parked(); // assert we have a debug panel item before the session has stopped workspace .update(cx, |workspace, _window, cx| { let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap(); let active_session = debug_panel.update(cx, |debug_panel, _| debug_panel.active_session().unwrap()); let running_state = active_session.update(cx, |active_session, _| { active_session.running_state().clone() }); debug_panel.update(cx, |this, cx| { assert!(this.active_session().is_some()); assert!(running_state.read(cx).selected_thread_id().is_none()); }); }) .unwrap(); client .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent { reason: dap::StoppedEventReason::Pause, description: None, thread_id: Some(1), preserve_focus_hint: None, text: None, all_threads_stopped: None, hit_breakpoint_ids: None, })) .await; cx.run_until_parked(); workspace .update(cx, |workspace, _window, cx| { let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap(); let active_session = debug_panel .update(cx, |this, _| this.active_session()) .unwrap(); let running_state = active_session.update(cx, |active_session, _| { active_session.running_state().clone() }); assert_eq!(client.id(), running_state.read(cx).session_id()); assert_eq!( ThreadId(1), running_state.read(cx).selected_thread_id().unwrap() ); }) .unwrap(); let shutdown_session = project.update(cx, |project, cx| { project.dap_store().update(cx, |dap_store, cx| { dap_store.shutdown_session(session.read(cx).session_id(), cx) }) }); shutdown_session.await.unwrap(); // assert we still have a debug panel item after the client shutdown workspace .update(cx, |workspace, _window, cx| { let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap(); let active_session = debug_panel .update(cx, |this, _| this.active_session()) .unwrap(); let running_state = active_session.update(cx, |active_session, _| { active_session.running_state().clone() }); debug_panel.update(cx, |this, cx| { assert!(this.active_session().is_some()); assert_eq!( ThreadId(1), running_state.read(cx).selected_thread_id().unwrap() ); }); }) .unwrap();} #[gpui::test]async fn test_we_can_only_have_one_panel_per_debug_session( executor: BackgroundExecutor, cx: &mut TestAppContext,) { init_test(cx); let fs = FakeFs::new(executor.clone()); fs.insert_tree( path!("/project"), json!({ "main.rs": "First line\nSecond line\nThird line\nFourth line", }), ) .await; let project = Project::test(fs, [path!("/project").as_ref()], cx).await; let workspace = init_test_workspace(&project, cx).await; let cx = &mut VisualTestContext::from_window(*workspace, cx); let session = start_debug_session(&workspace, cx, |_| {}).unwrap(); let client = session.update(cx, |session, _| session.adapter_client().unwrap()); client.on_request::<Threads, _>(move |_, _| { Ok(dap::ThreadsResponse { threads: vec![dap::Thread { id: 1, name: "Thread 1".into(), }], }) }); client.on_request::<StackTrace, _>(move |_, _| { Ok(dap::StackTraceResponse { stack_frames: Vec::default(), total_frames: None, }) }); cx.run_until_parked(); // assert we have a debug panel item before the session has stopped workspace .update(cx, |workspace, _window, cx| { let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap(); debug_panel.update(cx, |this, _| { assert!(this.active_session().is_some()); }); }) .unwrap(); client .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent { reason: dap::StoppedEventReason::Pause, description: None, thread_id: Some(1), preserve_focus_hint: None, text: None, all_threads_stopped: None, hit_breakpoint_ids: None, })) .await; cx.run_until_parked(); // assert we added a debug panel item workspace .update(cx, |workspace, _window, cx| { let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap(); let active_session = debug_panel .update(cx, |this, _| this.active_session()) .unwrap(); let running_state = active_session.update(cx, |active_session, _| { active_session.running_state().clone() }); assert_eq!(client.id(), active_session.read(cx).session_id(cx)); assert_eq!( ThreadId(1), running_state.read(cx).selected_thread_id().unwrap() ); }) .unwrap(); client .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent { reason: dap::StoppedEventReason::Pause, description: None, thread_id: Some(2), preserve_focus_hint: None, text: None, all_threads_stopped: None, hit_breakpoint_ids: None, })) .await; cx.run_until_parked(); workspace .update(cx, |workspace, _window, cx| { let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap(); let active_session = debug_panel .update(cx, |this, _| this.active_session()) .unwrap(); let running_state = active_session.update(cx, |active_session, _| { active_session.running_state().clone() }); assert_eq!(client.id(), active_session.read(cx).session_id(cx)); assert_eq!( ThreadId(1), running_state.read(cx).selected_thread_id().unwrap() ); }) .unwrap(); let shutdown_session = project.update(cx, |project, cx| { project.dap_store().update(cx, |dap_store, cx| { dap_store.shutdown_session(session.read(cx).session_id(), cx) }) }); shutdown_session.await.unwrap(); // assert we still have a debug panel item after the client shutdown workspace .update(cx, |workspace, _window, cx| { let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap(); let active_session = debug_panel .update(cx, |this, _| this.active_session()) .unwrap(); let running_state = active_session.update(cx, |active_session, _| { active_session.running_state().clone() }); debug_panel.update(cx, |this, cx| { assert!(this.active_session().is_some()); assert_eq!( ThreadId(1), running_state.read(cx).selected_thread_id().unwrap() ); }); }) .unwrap();} #[gpui::test]async fn test_handle_successful_run_in_terminal_reverse_request( executor: BackgroundExecutor, cx: &mut TestAppContext,) { init_test(cx); let send_response = Arc::new(AtomicBool::new(false)); let fs = FakeFs::new(executor.clone()); fs.insert_tree( path!("/project"), json!({ "main.rs": "First line\nSecond line\nThird line\nFourth line", }), ) .await; let project = Project::test(fs, [path!("/project").as_ref()], cx).await; let workspace = init_test_workspace(&project, cx).await; let cx = &mut VisualTestContext::from_window(*workspace, cx); let session = start_debug_session(&workspace, cx, |_| {}).unwrap(); let client = session.update(cx, |session, _| session.adapter_client().unwrap()); client .on_response::<RunInTerminal, _>({ let send_response = send_response.clone(); move |response| { send_response.store(true, Ordering::SeqCst); assert!(response.success); assert!(response.body.is_some()); } }) .await; client .fake_reverse_request::<RunInTerminal>(RunInTerminalRequestArguments { kind: None, title: None, cwd: std::env::temp_dir().to_string_lossy().to_string(), args: vec![], env: None, args_can_be_interpreted_by_shell: None, }) .await; cx.run_until_parked(); assert!( send_response.load(std::sync::atomic::Ordering::SeqCst), "Expected to receive response from reverse request" ); workspace .update(cx, |workspace, _window, cx| { let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap(); let session = debug_panel.read(cx).active_session().unwrap(); let running = session.read(cx).running_state(); assert_eq!( running .read(cx) .pane_items_status(cx) .get(&DebuggerPaneItem::Terminal), Some(&true) ); assert!(running.read(cx).debug_terminal.read(cx).terminal.is_some()); }) .unwrap();} #[gpui::test]async fn test_handle_start_debugging_request( executor: BackgroundExecutor, cx: &mut TestAppContext,) { init_test(cx); let fs = FakeFs::new(executor.clone()); fs.insert_tree( path!("/project"), json!({ "main.rs": "First line\nSecond line\nThird line\nFourth line", }), ) .await; let project = Project::test(fs, [path!("/project").as_ref()], cx).await; let workspace = init_test_workspace(&project, cx).await; let cx = &mut VisualTestContext::from_window(*workspace, cx); let session = start_debug_session(&workspace, cx, |_| {}).unwrap(); let client = session.update(cx, |session, _| session.adapter_client().unwrap()); let fake_config = json!({"one": "two"}); let launched_with = Arc::new(parking_lot::Mutex::new(None)); let _subscription = project::debugger::test::intercept_debug_sessions(cx, { let launched_with = launched_with.clone(); move |client| { let launched_with = launched_with.clone(); client.on_request::<dap::requests::Launch, _>(move |_, args| { launched_with.lock().replace(args.raw); Ok(()) }); client.on_request::<dap::requests::Attach, _>(move |_, _| { assert!(false, "should not get attach request"); Ok(()) }); } }); let sessions = workspace .update(cx, |workspace, _window, cx| { let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap(); debug_panel.read(cx).sessions().collect::<Vec<_>>() }) .unwrap(); assert_eq!(sessions.len(), 1); client .fake_reverse_request::<StartDebugging>(StartDebuggingRequestArguments { request: StartDebuggingRequestArgumentsRequest::Launch, configuration: fake_config.clone(), }) .await; cx.run_until_parked(); workspace .update(cx, |workspace, _window, cx| { let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap(); // Active session changes on spawn, as the parent has never stopped. let active_session = debug_panel .read(cx) .active_session() .unwrap() .read(cx) .session(cx); let current_sessions = debug_panel.read(cx).sessions().collect::<Vec<_>>(); assert_eq!(active_session, current_sessions[1].read(cx).session(cx)); assert_eq!( active_session.read(cx).parent_session(), Some(¤t_sessions[0].read(cx).session(cx)) ); assert_eq!(current_sessions.len(), 2); assert_eq!(current_sessions[0], sessions[0]); let parent_session = current_sessions[1] .read(cx) .session(cx) .read(cx) .parent_session() .unwrap(); assert_eq!(parent_session, &sessions[0].read(cx).session(cx)); // We should preserve the original binary (params to spawn process etc.) except for launch params // (as they come from reverse spawn request). let mut original_binary = parent_session.read(cx).binary().cloned().unwrap(); original_binary.request_args = StartDebuggingRequestArguments { request: StartDebuggingRequestArgumentsRequest::Launch, configuration: fake_config.clone(), }; assert_eq!( current_sessions[1] .read(cx) .session(cx) .read(cx) .binary() .unwrap(), &original_binary ); }) .unwrap(); assert_eq!(&fake_config, launched_with.lock().as_ref().unwrap());} // // covers that we always send a response back, if something when wrong,// // while spawning the terminal#[gpui::test]async fn test_handle_error_run_in_terminal_reverse_request( executor: BackgroundExecutor, cx: &mut TestAppContext,Lines 1–500 of 1949. Load more
use crate::{ persistence::DebuggerPaneItem, tests::{start_debug_session, start_debug_session_with}, *, }; use dap::{ ErrorResponse, Message, RunInTerminalRequestArguments, SourceBreakpoint, StartDebuggingRequestArguments, StartDebuggingRequestArgumentsRequest, adapters::DebugTaskDefinition, client::SessionId, requests::{ Continue, Disconnect, Launch, Next, RunInTerminal, SetBreakpoints, StackTrace, StartDebugging, StepBack, StepIn, StepOut, Threads, }, }; use editor::{ ActiveDebugLine, Editor, EditorMode, MultiBuffer, actions::{self}, }; use gpui::{BackgroundExecutor, TestAppContext, VisualTestContext}; use project::{ FakeFs, Project, debugger::session::{ThreadId, ThreadStatus}, }; use serde_json::json; use std::{ path::Path, sync::{ Arc, atomic::{AtomicBool, Ordering}, }, }; use terminal_view::terminal_panel::TerminalPanel; use tests::{active_debug_session_panel, init_test, init_test_workspace}; use util::path; use workspace::item::SaveOptions; use workspace::{Item, dock::Panel}; #[gpui::test] async fn test_basic_show_debug_panel(executor: BackgroundExecutor, cx: &mut TestAppContext) { init_test(cx); let fs = FakeFs::new(executor.clone()); fs.insert_tree( path!("/project"), json!({ "main.rs": "First line\nSecond line\nThird line\nFourth line", }), ) .await; let project = Project::test(fs, [path!("/project").as_ref()], cx).await; let workspace = init_test_workspace(&project, cx).await; let cx = &mut VisualTestContext::from_window(*workspace, cx); let session = start_debug_session(&workspace, cx, |_| {}).unwrap(); let client = session.update(cx, |session, _| session.adapter_client().unwrap()); client.on_request::<Threads, _>(move |_, _| { Ok(dap::ThreadsResponse { threads: vec![dap::Thread { id: 1, name: "Thread 1".into(), }], }) }); client.on_request::<StackTrace, _>(move |_, _| { Ok(dap::StackTraceResponse { stack_frames: Vec::default(), total_frames: None, }) }); cx.run_until_parked(); // assert we have a debug panel item before the session has stopped workspace .update(cx, |workspace, _window, cx| { let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap(); let active_session = debug_panel.update(cx, |debug_panel, _| debug_panel.active_session().unwrap()); let running_state = active_session.update(cx, |active_session, _| { active_session.running_state().clone() }); debug_panel.update(cx, |this, cx| { assert!(this.active_session().is_some()); assert!(running_state.read(cx).selected_thread_id().is_none()); }); }) .unwrap(); client .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent { reason: dap::StoppedEventReason::Pause, description: None, thread_id: Some(1), preserve_focus_hint: None, text: None, all_threads_stopped: None, hit_breakpoint_ids: None, })) .await; cx.run_until_parked(); workspace .update(cx, |workspace, _window, cx| { let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap(); let active_session = debug_panel .update(cx, |this, _| this.active_session()) .unwrap(); let running_state = active_session.update(cx, |active_session, _| { active_session.running_state().clone() }); assert_eq!(client.id(), running_state.read(cx).session_id()); assert_eq!( ThreadId(1), running_state.read(cx).selected_thread_id().unwrap() ); }) .unwrap(); let shutdown_session = project.update(cx, |project, cx| { project.dap_store().update(cx, |dap_store, cx| { dap_store.shutdown_session(session.read(cx).session_id(), cx) }) }); shutdown_session.await.unwrap(); // assert we still have a debug panel item after the client shutdown workspace .update(cx, |workspace, _window, cx| { let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap(); let active_session = debug_panel .update(cx, |this, _| this.active_session()) .unwrap(); let running_state = active_session.update(cx, |active_session, _| { active_session.running_state().clone() }); debug_panel.update(cx, |this, cx| { assert!(this.active_session().is_some()); assert_eq!( ThreadId(1), running_state.read(cx).selected_thread_id().unwrap() ); }); }) .unwrap(); } #[gpui::test] async fn test_we_can_only_have_one_panel_per_debug_session( executor: BackgroundExecutor, cx: &mut TestAppContext, ) { init_test(cx); let fs = FakeFs::new(executor.clone()); fs.insert_tree( path!("/project"), json!({ "main.rs": "First line\nSecond line\nThird line\nFourth line", }), ) .await; let project = Project::test(fs, [path!("/project").as_ref()], cx).await; let workspace = init_test_workspace(&project, cx).await; let cx = &mut VisualTestContext::from_window(*workspace, cx); let session = start_debug_session(&workspace, cx, |_| {}).unwrap(); let client = session.update(cx, |session, _| session.adapter_client().unwrap()); client.on_request::<Threads, _>(move |_, _| { Ok(dap::ThreadsResponse { threads: vec![dap::Thread { id: 1, name: "Thread 1".into(), }], }) }); client.on_request::<StackTrace, _>(move |_, _| { Ok(dap::StackTraceResponse { stack_frames: Vec::default(), total_frames: None, }) }); cx.run_until_parked(); // assert we have a debug panel item before the session has stopped workspace .update(cx, |workspace, _window, cx| { let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap(); debug_panel.update(cx, |this, _| { assert!(this.active_session().is_some()); }); }) .unwrap(); client .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent { reason: dap::StoppedEventReason::Pause, description: None, thread_id: Some(1), preserve_focus_hint: None, text: None, all_threads_stopped: None, hit_breakpoint_ids: None, })) .await; cx.run_until_parked(); // assert we added a debug panel item workspace .update(cx, |workspace, _window, cx| { let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap(); let active_session = debug_panel .update(cx, |this, _| this.active_session()) .unwrap(); let running_state = active_session.update(cx, |active_session, _| { active_session.running_state().clone() }); assert_eq!(client.id(), active_session.read(cx).session_id(cx)); assert_eq!( ThreadId(1), running_state.read(cx).selected_thread_id().unwrap() ); }) .unwrap(); client .fake_event(dap::messages::Events::Stopped(dap::StoppedEvent { reason: dap::StoppedEventReason::Pause, description: None, thread_id: Some(2), preserve_focus_hint: None, text: None, all_threads_stopped: None, hit_breakpoint_ids: None, })) .await; cx.run_until_parked(); workspace .update(cx, |workspace, _window, cx| { let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap(); let active_session = debug_panel .update(cx, |this, _| this.active_session()) .unwrap(); let running_state = active_session.update(cx, |active_session, _| { active_session.running_state().clone() }); assert_eq!(client.id(), active_session.read(cx).session_id(cx)); assert_eq!( ThreadId(1), running_state.read(cx).selected_thread_id().unwrap() ); }) .unwrap(); let shutdown_session = project.update(cx, |project, cx| { project.dap_store().update(cx, |dap_store, cx| { dap_store.shutdown_session(session.read(cx).session_id(), cx) }) }); shutdown_session.await.unwrap(); // assert we still have a debug panel item after the client shutdown workspace .update(cx, |workspace, _window, cx| { let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap(); let active_session = debug_panel .update(cx, |this, _| this.active_session()) .unwrap(); let running_state = active_session.update(cx, |active_session, _| { active_session.running_state().clone() }); debug_panel.update(cx, |this, cx| { assert!(this.active_session().is_some()); assert_eq!( ThreadId(1), running_state.read(cx).selected_thread_id().unwrap() ); }); }) .unwrap(); } #[gpui::test] async fn test_handle_successful_run_in_terminal_reverse_request( executor: BackgroundExecutor, cx: &mut TestAppContext, ) { init_test(cx); let send_response = Arc::new(AtomicBool::new(false)); let fs = FakeFs::new(executor.clone()); fs.insert_tree( path!("/project"), json!({ "main.rs": "First line\nSecond line\nThird line\nFourth line", }), ) .await; let project = Project::test(fs, [path!("/project").as_ref()], cx).await; let workspace = init_test_workspace(&project, cx).await; let cx = &mut VisualTestContext::from_window(*workspace, cx); let session = start_debug_session(&workspace, cx, |_| {}).unwrap(); let client = session.update(cx, |session, _| session.adapter_client().unwrap()); client .on_response::<RunInTerminal, _>({ let send_response = send_response.clone(); move |response| { send_response.store(true, Ordering::SeqCst); assert!(response.success); assert!(response.body.is_some()); } }) .await; client .fake_reverse_request::<RunInTerminal>(RunInTerminalRequestArguments { kind: None, title: None, cwd: std::env::temp_dir().to_string_lossy().to_string(), args: vec![], env: None, args_can_be_interpreted_by_shell: None, }) .await; cx.run_until_parked(); assert!( send_response.load(std::sync::atomic::Ordering::SeqCst), "Expected to receive response from reverse request" ); workspace .update(cx, |workspace, _window, cx| { let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap(); let session = debug_panel.read(cx).active_session().unwrap(); let running = session.read(cx).running_state(); assert_eq!( running .read(cx) .pane_items_status(cx) .get(&DebuggerPaneItem::Terminal), Some(&true) ); assert!(running.read(cx).debug_terminal.read(cx).terminal.is_some()); }) .unwrap(); } #[gpui::test] async fn test_handle_start_debugging_request( executor: BackgroundExecutor, cx: &mut TestAppContext, ) { init_test(cx); let fs = FakeFs::new(executor.clone()); fs.insert_tree( path!("/project"), json!({ "main.rs": "First line\nSecond line\nThird line\nFourth line", }), ) .await; let project = Project::test(fs, [path!("/project").as_ref()], cx).await; let workspace = init_test_workspace(&project, cx).await; let cx = &mut VisualTestContext::from_window(*workspace, cx); let session = start_debug_session(&workspace, cx, |_| {}).unwrap(); let client = session.update(cx, |session, _| session.adapter_client().unwrap()); let fake_config = json!({"one": "two"}); let launched_with = Arc::new(parking_lot::Mutex::new(None)); let _subscription = project::debugger::test::intercept_debug_sessions(cx, { let launched_with = launched_with.clone(); move |client| { let launched_with = launched_with.clone(); client.on_request::<dap::requests::Launch, _>(move |_, args| { launched_with.lock().replace(args.raw); Ok(()) }); client.on_request::<dap::requests::Attach, _>(move |_, _| { assert!(false, "should not get attach request"); Ok(()) }); } }); let sessions = workspace .update(cx, |workspace, _window, cx| { let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap(); debug_panel.read(cx).sessions().collect::<Vec<_>>() }) .unwrap(); assert_eq!(sessions.len(), 1); client .fake_reverse_request::<StartDebugging>(StartDebuggingRequestArguments { request: StartDebuggingRequestArgumentsRequest::Launch, configuration: fake_config.clone(), }) .await; cx.run_until_parked(); workspace .update(cx, |workspace, _window, cx| { let debug_panel = workspace.panel::<DebugPanel>(cx).unwrap(); // Active session changes on spawn, as the parent has never stopped. let active_session = debug_panel .read(cx) .active_session() .unwrap() .read(cx) .session(cx); let current_sessions = debug_panel.read(cx).sessions().collect::<Vec<_>>(); assert_eq!(active_session, current_sessions[1].read(cx).session(cx)); assert_eq!( active_session.read(cx).parent_session(), Some(¤t_sessions[0].read(cx).session(cx)) ); assert_eq!(current_sessions.len(), 2); assert_eq!(current_sessions[0], sessions[0]); let parent_session = current_sessions[1] .read(cx) .session(cx) .read(cx) .parent_session() .unwrap(); assert_eq!(parent_session, &sessions[0].read(cx).session(cx)); // We should preserve the original binary (params to spawn process etc.) except for launch params // (as they come from reverse spawn request). let mut original_binary = parent_session.read(cx).binary().cloned().unwrap(); original_binary.request_args = StartDebuggingRequestArguments { request: StartDebuggingRequestArgumentsRequest::Launch, configuration: fake_config.clone(), }; assert_eq!( current_sessions[1] .read(cx) .session(cx) .read(cx) .binary() .unwrap(), &original_binary ); }) .unwrap(); assert_eq!(&fake_config, launched_with.lock().as_ref().unwrap()); } // // covers that we always send a response back, if something when wrong, // // while spawning the terminal #[gpui::test] async fn test_handle_error_run_in_terminal_reverse_request( executor: BackgroundExecutor, cx: &mut TestAppContext,